From 6f4a013677d499b91a103c4f33d8f200e27e44aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Jan 2021 12:57:51 -0800 Subject: [PATCH] s3: smbd: Change hardlink_internals() to use a real directory fsp for SMB_VFS_LINKAT(). MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit New VFS change. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Böhme --- source3/smbd/trans2.c | 72 ++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index a869d034f9f..92856163ac5 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6466,6 +6466,10 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, NTSTATUS status = NT_STATUS_OK; int ret; bool ok; + struct smb_filename *parent_fname_old = NULL; + struct smb_filename *base_name_old = NULL; + struct smb_filename *parent_fname_new = NULL; + struct smb_filename *base_name_new = NULL; /* source must already exist. */ if (!VALID_STAT(smb_fname_old->st)) { @@ -6473,6 +6477,44 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, goto out; } + /* No links from a directory. */ + if (S_ISDIR(smb_fname_old->st.st_ex_mode)) { + status = NT_STATUS_FILE_IS_A_DIRECTORY; + goto out; + } + + /* Setting a hardlink to/from a stream isn't currently supported. */ + ok = is_ntfs_stream_smb_fname(smb_fname_old); + if (ok) { + DBG_DEBUG("Old name has streams\n"); + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + ok = is_ntfs_stream_smb_fname(smb_fname_new); + if (ok) { + DBG_DEBUG("New name has streams\n"); + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + status = parent_pathref(talloc_tos(), + conn->cwd_fsp, + smb_fname_old, + &parent_fname_old, + &base_name_old); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + status = parent_pathref(talloc_tos(), + conn->cwd_fsp, + smb_fname_new, + &parent_fname_new, + &base_name_new); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + if (VALID_STAT(smb_fname_new->st)) { if (overwrite_if_exists) { if (S_ISDIR(smb_fname_new->st.st_ex_mode)) { @@ -6494,34 +6536,14 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, } } - /* No links from a directory. */ - if (S_ISDIR(smb_fname_old->st.st_ex_mode)) { - status = NT_STATUS_FILE_IS_A_DIRECTORY; - goto out; - } - - /* Setting a hardlink to/from a stream isn't currently supported. */ - ok = is_ntfs_stream_smb_fname(smb_fname_old); - if (ok) { - DBG_DEBUG("Old name has streams\n"); - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - ok = is_ntfs_stream_smb_fname(smb_fname_new); - if (ok) { - DBG_DEBUG("New name has streams\n"); - status = NT_STATUS_INVALID_PARAMETER; - goto out; - } - DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", smb_fname_old->base_name, smb_fname_new->base_name)); ret = SMB_VFS_LINKAT(conn, - conn->cwd_fsp, - smb_fname_old, - conn->cwd_fsp, - smb_fname_new, + parent_fname_old->fsp, + base_name_old, + parent_fname_new->fsp, + base_name_new, 0); if (ret != 0) { @@ -6533,6 +6555,8 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, out: + TALLOC_FREE(parent_fname_old); + TALLOC_FREE(parent_fname_new); return status; } -- 2.47.3