diff options
author | Jeremy Allison <jra@samba.org> | 2021-01-15 14:29:08 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2021-01-17 04:43:31 +0000 |
commit | f09ea26e6580b2c339c4de9374e024182fa9ca82 (patch) | |
tree | 10278c9aab508a79d5806e2f70a410d1db4ad362 | |
parent | 35f2c7641e6235fdad492f47b0685e89016a9cb1 (diff) | |
download | samba-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.c | 31 |
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; } |