]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Change smb_set_file_unix_link() to use a real directory fsp for SMB_VFS_SYM...
authorJeremy Allison <jra@samba.org>
Fri, 15 Jan 2021 22:29:08 +0000 (14:29 -0800)
committerJeremy Allison <jra@samba.org>
Sun, 17 Jan 2021 04:43:31 +0000 (04:43 +0000)
New VFS change.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/trans2.c

index 3c1df4ca3acd15efa4c035924d5d3761e56efddb..f3a0d7da75f522763e8ab4df766693e5b3cb6ecd 100644 (file)
@@ -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;
 }