diff options
-rw-r--r-- | examples/VFS/skel_opaque.c | 10 | ||||
-rw-r--r-- | examples/VFS/skel_transparent.c | 12 | ||||
-rw-r--r-- | source3/include/smbprofile.h | 1 | ||||
-rw-r--r-- | source3/include/vfs.h | 13 | ||||
-rw-r--r-- | source3/include/vfs_macros.h | 5 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 25 | ||||
-rw-r--r-- | source3/modules/vfs_not_implemented.c | 10 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 12 |
8 files changed, 88 insertions, 0 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index c03a42fee04..2695b82ab45 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -351,6 +351,15 @@ static int skel_unlink(vfs_handle_struct *handle, return -1; } +static int skel_unlinkat(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + errno = ENOSYS; + return -1; +} + static int skel_chmod(vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) @@ -1077,6 +1086,7 @@ static struct vfs_fn_pointers skel_opaque_fns = { .lstat_fn = skel_lstat, .get_alloc_size_fn = skel_get_alloc_size, .unlink_fn = skel_unlink, + .unlinkat_fn = skel_unlinkat, .chmod_fn = skel_chmod, .fchmod_fn = skel_fchmod, .chown_fn = skel_chown, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 656c933338a..f760730400b 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -468,6 +468,17 @@ static int skel_unlink(vfs_handle_struct *handle, return SMB_VFS_NEXT_UNLINK(handle, smb_fname); } +static int skel_unlinkat(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + return SMB_VFS_NEXT_UNLINKAT(handle, + dirfsp, + smb_fname, + flags); +} + static int skel_chmod(vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) @@ -1362,6 +1373,7 @@ static struct vfs_fn_pointers skel_transparent_fns = { .lstat_fn = skel_lstat, .get_alloc_size_fn = skel_get_alloc_size, .unlink_fn = skel_unlink, + .unlinkat_fn = skel_unlinkat, .chmod_fn = skel_chmod, .fchmod_fn = skel_fchmod, .chown_fn = skel_chown, diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 489a613e3df..cc54669c772 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -68,6 +68,7 @@ struct tevent_context; SMBPROFILE_STATS_BASIC(syscall_lstat) \ SMBPROFILE_STATS_BASIC(syscall_get_alloc_size) \ SMBPROFILE_STATS_BASIC(syscall_unlink) \ + SMBPROFILE_STATS_BASIC(syscall_unlinkat) \ SMBPROFILE_STATS_BASIC(syscall_chmod) \ SMBPROFILE_STATS_BASIC(syscall_fchmod) \ SMBPROFILE_STATS_BASIC(syscall_chown) \ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 47147821ffd..883989c82ad 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -281,6 +281,7 @@ /* Version 42 - Move change_to_user() -> change_to_user_and_service() */ /* Version 42 - Move change_to_user_by_fsp() -> change_to_user_and_service_by_fsp() */ /* Version 42 - Move [un]become_user*() -> [un]become_user_without_service*() */ +/* Version 42 - Add SMB_VFS_UNLINKAT. */ #define SMB_VFS_INTERFACE_VERSION 42 @@ -778,6 +779,10 @@ struct vfs_fn_pointers { uint64_t (*get_alloc_size_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_STAT *sbuf); int (*unlink_fn)(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname); + int (*unlinkat_fn)(struct vfs_handle_struct *handle, + struct files_struct *srcdir_fsp, + const struct smb_filename *smb_fname, + int flags); int (*chmod_fn)(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode); @@ -1305,6 +1310,10 @@ uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle, const SMB_STRUCT_STAT *sbuf); int smb_vfs_call_unlink(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname); +int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags); int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode); @@ -1742,6 +1751,10 @@ uint64_t vfs_not_implemented_get_alloc_size(struct vfs_handle_struct *handle, const SMB_STRUCT_STAT *sbuf); int vfs_not_implemented_unlink(vfs_handle_struct *handle, const struct smb_filename *smb_fname); +int vfs_not_implemented_unlinkat(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags); int vfs_not_implemented_chmod(vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 6d95d840e25..055555a4b07 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -226,6 +226,11 @@ #define SMB_VFS_NEXT_UNLINK(handle, path) \ smb_vfs_call_unlink((handle)->next, (path)) +#define SMB_VFS_UNLINKAT(conn, dirfsp, path, flags) \ + smb_vfs_call_unlinkat((conn)->vfs_handles, (dirfsp), (path), (flags)) +#define SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, path, flags) \ + smb_vfs_call_unlinkat((handle)->next, (dirfsp), (path), (flags)) + #define SMB_VFS_CHMOD(conn, smb_fname, mode) \ smb_vfs_call_chmod((conn)->vfs_handles, (smb_fname), (mode)) #define SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode) \ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index f48a590e5e7..de6d7892d5e 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2222,6 +2222,30 @@ static int vfswrap_unlink(vfs_handle_struct *handle, return result; } +static int vfswrap_unlinkat(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + int result = -1; + + START_PROFILE(syscall_unlinkat); + + SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp); + + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; + } + result = unlinkat(dirfsp->fh->fd, + smb_fname->base_name, + flags); + + out: + END_PROFILE(syscall_unlinkat); + return result; +} + static int vfswrap_chmod(vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) @@ -3488,6 +3512,7 @@ static struct vfs_fn_pointers vfs_default_fns = { .lstat_fn = vfswrap_lstat, .get_alloc_size_fn = vfswrap_get_alloc_size, .unlink_fn = vfswrap_unlink, + .unlinkat_fn = vfswrap_unlinkat, .chmod_fn = vfswrap_chmod, .fchmod_fn = vfswrap_fchmod, .chown_fn = vfswrap_chown, diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index e0f36b9a632..0c7a8e686f0 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -349,6 +349,15 @@ int vfs_not_implemented_unlink(vfs_handle_struct *handle, return -1; } +int vfs_not_implemented_unlinkat(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + errno = ENOSYS; + return -1; +} + int vfs_not_implemented_chmod(vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) @@ -1081,6 +1090,7 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = { .lstat_fn = vfs_not_implemented_lstat, .get_alloc_size_fn = vfs_not_implemented_get_alloc_size, .unlink_fn = vfs_not_implemented_unlink, + .unlinkat_fn = vfs_not_implemented_unlinkat, .chmod_fn = vfs_not_implemented_chmod, .fchmod_fn = vfs_not_implemented_fchmod, .chown_fn = vfs_not_implemented_chown, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 20f3d34965f..4a0c375e48e 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1981,6 +1981,18 @@ int smb_vfs_call_unlink(struct vfs_handle_struct *handle, return handle->fns->unlink_fn(handle, smb_fname); } +int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + VFS_FIND(unlinkat); + return handle->fns->unlinkat_fn(handle, + dirfsp, + smb_fname, + flags); +} + int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode) |