From f09ea26e6580b2c339c4de9374e024182fa9ca82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Jan 2021 14:29:08 -0800 Subject: [PATCH] s3: smbd: Change smb_set_file_unix_link() to use a real directory fsp for SMB_VFS_SYMLINKAT(). New VFS change. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- source3/smbd/trans2.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 3c1df4ca3ac..f3a0d7da75f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7009,6 +7009,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, TALLOC_CTX *ctx = talloc_tos(); NTSTATUS status; int ret; + struct smb_filename *parent_fname = NULL; + struct smb_filename *base_name = NULL; + bool ok; /* Set a symbolic link. */ /* Don't allow this if follow links is false. */ @@ -7041,14 +7044,38 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n", new_smb_fname->base_name, link_target )); + ok = parent_smb_fname(ctx, + new_smb_fname, + &parent_fname, + &base_name); + if (!ok) { + return NT_STATUS_NO_MEMORY; + } + + ret = vfs_stat(conn, parent_fname); + if (ret == -1) { + TALLOC_FREE(parent_fname); + return map_nt_error_from_unix(errno); + } + status = openat_pathref_fsp(conn->cwd_fsp, parent_fname); + if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(parent_fname); + return status; + } + ret = SMB_VFS_SYMLINKAT(conn, &target_fname, - conn->cwd_fsp, - new_smb_fname); + parent_fname->fsp, + base_name); if (ret != 0) { + TALLOC_FREE(parent_fname); return map_nt_error_from_unix(errno); } + TALLOC_FREE(parent_fname); return NT_STATUS_OK; }