summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2021-01-15 14:29:08 -0800
committerJeremy Allison <jra@samba.org>2021-01-17 04:43:31 +0000
commitf09ea26e6580b2c339c4de9374e024182fa9ca82 (patch)
tree10278c9aab508a79d5806e2f70a410d1db4ad362
parent35f2c7641e6235fdad492f47b0685e89016a9cb1 (diff)
downloadsamba-f09ea26e6580b2c339c4de9374e024182fa9ca82.tar.gz
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 <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
-rw-r--r--source3/smbd/trans2.c31
1 files 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;
}