From 606398a3a6da349877eb1d6f585e3f58778624b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Aug 2019 15:22:31 -0700 Subject: [PATCH] s3: VFS: Add SMB_VFS_RENAMEAT(). Currently identical to SMB_VFS_RENAME() - uses AT_FDCWD for both src and dst directories. Next, move add to all VFS modules that implement rename and eventually remove rename. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- examples/VFS/skel_opaque.c | 11 +++++++++++ examples/VFS/skel_transparent.c | 14 ++++++++++++++ source3/include/smbprofile.h | 2 +- source3/include/vfs.h | 16 ++++++++++++++++ source3/include/vfs_macros.h | 5 +++++ source3/modules/vfs_default.c | 26 ++++++++++++++++++++++++++ source3/modules/vfs_fake_dfq.c | 2 +- source3/modules/vfs_not_implemented.c | 11 +++++++++++ source3/smbd/vfs.c | 14 ++++++++++++++ 9 files changed, 99 insertions(+), 2 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 55b576302a1..fa0de6680d6 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -298,6 +298,16 @@ static int skel_rename(vfs_handle_struct *handle, return -1; } +static int skel_renameat(vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst) +{ + errno = ENOSYS; + return -1; +} + static struct tevent_req *skel_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -1061,6 +1071,7 @@ static struct vfs_fn_pointers skel_opaque_fns = { .sendfile_fn = skel_sendfile, .recvfile_fn = skel_recvfile, .rename_fn = skel_rename, + .renameat_fn = skel_renameat, .fsync_send_fn = skel_fsync_send, .fsync_recv_fn = skel_fsync_recv, .stat_fn = skel_stat, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index eae2e9d5027..82ba5525d42 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -376,6 +376,19 @@ static int skel_rename(vfs_handle_struct *handle, return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst); } +static int skel_renameat(vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst) +{ + return SMB_VFS_NEXT_RENAMEAT(handle, + srcfsp, + smb_fname_src, + dstfsp, + smb_fname_dst); +} + struct skel_fsync_state { int ret; struct vfs_aio_state vfs_aio_state; @@ -1323,6 +1336,7 @@ static struct vfs_fn_pointers skel_transparent_fns = { .sendfile_fn = skel_sendfile, .recvfile_fn = skel_recvfile, .rename_fn = skel_rename, + .renameat_fn = skel_renameat, .fsync_send_fn = skel_fsync_send, .fsync_recv_fn = skel_fsync_recv, .stat_fn = skel_stat, diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 8888ae3eaa8..44335070b3c 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -62,7 +62,7 @@ struct tevent_context; SMBPROFILE_STATS_BYTES(syscall_sendfile) \ SMBPROFILE_STATS_BYTES(syscall_recvfile) \ SMBPROFILE_STATS_BASIC(syscall_rename) \ - SMBPROFILE_STATS_BASIC(syscall_rename_at) \ + SMBPROFILE_STATS_BASIC(syscall_renameat) \ SMBPROFILE_STATS_BYTES(syscall_asys_fsync) \ SMBPROFILE_STATS_BASIC(syscall_stat) \ SMBPROFILE_STATS_BASIC(syscall_fstat) \ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d3e6ec258c3..2111173a772 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -272,6 +272,7 @@ /* Bump to version 42, Samba 4.12 will ship with that */ /* Version 42 - Remove share_access member from struct files_struct */ /* Version 42 - Make "lease" a const* in create_file_fn */ +/* Version 42 - Add SMB_VFS_RENAMEAT. */ #define SMB_VFS_INTERFACE_VERSION 42 @@ -747,6 +748,11 @@ struct vfs_fn_pointers { int (*rename_fn)(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname_src, const struct smb_filename *smb_fname_dst); + int (*renameat_fn)(struct vfs_handle_struct *handle, + struct files_struct *srcdir_fsp, + const struct smb_filename *smb_fname_src, + struct files_struct *dstdir_fsp, + const struct smb_filename *smb_fname_dst); struct tevent_req *(*fsync_send_fn)(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -1257,6 +1263,11 @@ ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd, int smb_vfs_call_rename(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname_src, const struct smb_filename *smb_fname_dst); +int smb_vfs_call_renameat(struct vfs_handle_struct *handle, + struct files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + struct files_struct *dstfsp, + const struct smb_filename *smb_fname_dst); struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -1688,6 +1699,11 @@ ssize_t vfs_not_implemented_recvfile(vfs_handle_struct *handle, int fromfd, int vfs_not_implemented_rename(vfs_handle_struct *handle, const struct smb_filename *smb_fname_src, const struct smb_filename *smb_fname_dst); +int vfs_not_implemented_renameat(vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst); struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index fd0d9681084..d124b928f44 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -190,6 +190,11 @@ #define SMB_VFS_NEXT_RENAME(handle, old, new) \ smb_vfs_call_rename((handle)->next, (old), (new)) +#define SMB_VFS_RENAMEAT(conn, oldfsp, old, newfsp, new) \ + smb_vfs_call_renameat((conn)->vfs_handles, (oldfsp), (old), (newfsp), (new)) +#define SMB_VFS_NEXT_RENAMEAT(handle, oldfsp, old, newfsp, new) \ + smb_vfs_call_renameat((handle)->next, (oldfsp), (old), (newfsp), (new)) + #define SMB_VFS_FSYNC(fsp) \ smb_vfs_call_fsync((fsp)->conn->vfs_handles, (fsp)) #define SMB_VFS_NEXT_FSYNC(handle, fsp) \ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 213c6ddd9cd..dee8ac39a71 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1087,6 +1087,31 @@ static int vfswrap_rename(vfs_handle_struct *handle, return result; } +static int vfswrap_renameat(vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst) +{ + int result = -1; + + START_PROFILE(syscall_renameat); + + SMB_ASSERT(srcfsp->fh->fd == AT_FDCWD); + SMB_ASSERT(dstfsp->fh->fd == AT_FDCWD); + + if (smb_fname_src->stream_name || smb_fname_dst->stream_name) { + errno = ENOENT; + goto out; + } + + result = rename(smb_fname_src->base_name, smb_fname_dst->base_name); + + out: + END_PROFILE(syscall_renameat); + return result; +} + static int vfswrap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { @@ -3439,6 +3464,7 @@ static struct vfs_fn_pointers vfs_default_fns = { .sendfile_fn = vfswrap_sendfile, .recvfile_fn = vfswrap_recvfile, .rename_fn = vfswrap_rename, + .renameat_fn = vfswrap_renameat, .fsync_send_fn = vfswrap_fsync_send, .fsync_recv_fn = vfswrap_fsync_recv, .stat_fn = vfswrap_stat, diff --git a/source3/modules/vfs_fake_dfq.c b/source3/modules/vfs_fake_dfq.c index 5347d7500af..47c0b0714cc 100644 --- a/source3/modules/vfs_fake_dfq.c +++ b/source3/modules/vfs_fake_dfq.c @@ -198,7 +198,7 @@ static void dfq_fake_stat(struct vfs_handle_struct *handle, int len; gid_t gid; - len = full_path_tos(handle->conn->cwd_fname->base_name, + len = full_path_tos(handle->conn->cwd_fsp->fsp_name->base_name, smb_fname->base_name, path, sizeof(path), &full_path, &to_free); diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index a29ce9c3353..1117032c242 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -296,6 +296,16 @@ int vfs_not_implemented_rename(vfs_handle_struct *handle, return -1; } +int vfs_not_implemented_renameat(vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst) +{ + errno = ENOSYS; + return -1; +} + struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -1065,6 +1075,7 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = { .sendfile_fn = vfs_not_implemented_sendfile, .recvfile_fn = vfs_not_implemented_recvfile, .rename_fn = vfs_not_implemented_rename, + .renameat_fn = vfs_not_implemented_renameat, .fsync_send_fn = vfs_not_implemented_fsync_send, .fsync_recv_fn = vfs_not_implemented_fsync_recv, .stat_fn = vfs_not_implemented_stat, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 467c3e39db1..5acdb74aa76 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1831,6 +1831,20 @@ int smb_vfs_call_rename(struct vfs_handle_struct *handle, return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst); } +int smb_vfs_call_renameat(struct vfs_handle_struct *handle, + files_struct *srcfsp, + const struct smb_filename *smb_fname_src, + files_struct *dstfsp, + const struct smb_filename *smb_fname_dst) +{ + VFS_FIND(renameat); + return handle->fns->renameat_fn(handle, + srcfsp, + smb_fname_src, + dstfsp, + smb_fname_dst); +} + struct smb_vfs_call_fsync_state { int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state); int retval;