From 42414b5bfc8f9e36d684b45997a5e9170b633220 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Aug 2019 12:01:13 -0700 Subject: s3: VFS: Add SMB_VFS_SYMLINKAT(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently identical to SMB_VFS_SYMLINK(). Next, add to all VFS modules that implement symlink and eventually remove symlink. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Böhme --- examples/VFS/skel_opaque.c | 10 ++++++++++ examples/VFS/skel_transparent.c | 12 ++++++++++++ source3/include/smbprofile.h | 1 + source3/include/vfs.h | 13 +++++++++++++ source3/include/vfs_macros.h | 5 +++++ source3/modules/vfs_default.c | 19 +++++++++++++++++++ source3/modules/vfs_not_implemented.c | 10 ++++++++++ source3/smbd/vfs.c | 14 +++++++++++++- 8 files changed, 83 insertions(+), 1 deletion(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index ecc1c920c92..96661857b4c 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -464,6 +464,15 @@ static int skel_symlink(vfs_handle_struct *handle, return -1; } +static int skel_symlinkat(vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname) +{ + errno = ENOSYS; + return -1; +} + static int skel_vfs_readlinkat(vfs_handle_struct *handle, files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1090,6 +1099,7 @@ static struct vfs_fn_pointers skel_opaque_fns = { .linux_setlease_fn = skel_linux_setlease, .getlock_fn = skel_getlock, .symlink_fn = skel_symlink, + .symlinkat_fn = skel_symlinkat, .readlinkat_fn = skel_vfs_readlinkat, .linkat_fn = skel_linkat, .mknodat_fn = skel_mknodat, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 63cf4a4369a..493c18a5417 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -563,6 +563,17 @@ static int skel_symlink(vfs_handle_struct *handle, return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname); } +static int skel_symlinkat(vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname) +{ + return SMB_VFS_NEXT_SYMLINKAT(handle, + link_contents, + dirfsp, + new_smb_fname); +} + static int skel_vfs_readlinkat(vfs_handle_struct *handle, files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1369,6 +1380,7 @@ static struct vfs_fn_pointers skel_transparent_fns = { .linux_setlease_fn = skel_linux_setlease, .getlock_fn = skel_getlock, .symlink_fn = skel_symlink, + .symlinkat_fn = skel_symlinkat, .readlinkat_fn = skel_vfs_readlinkat, .linkat_fn = skel_linkat, .mknodat_fn = skel_mknodat, diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index b6c9002973e..51761e11040 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -84,6 +84,7 @@ struct tevent_context; SMBPROFILE_STATS_BASIC(syscall_fcntl_getlock) \ SMBPROFILE_STATS_BASIC(syscall_readlinkat) \ SMBPROFILE_STATS_BASIC(syscall_symlink) \ + SMBPROFILE_STATS_BASIC(syscall_symlinkat) \ SMBPROFILE_STATS_BASIC(syscall_linkat) \ SMBPROFILE_STATS_BASIC(syscall_mknodat) \ SMBPROFILE_STATS_BASIC(syscall_realpath) \ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 126ba32aa36..6970be1fb5e 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -276,6 +276,7 @@ /* Version 42 - Move SMB_VFS_LINK -> SMB_VFS_LINKAT. */ /* Version 42 - Move SMB_VFS_MKNOD -> SMB_VFS_MKDNODAT. */ /* Version 42 - Move SMB_VFS_READLINK -> SMB_VFS_READLINKAT. */ +/* Version 42 - Add SMB_VFS_SYMLINKAT. */ #define SMB_VFS_INTERFACE_VERSION 42 @@ -798,6 +799,10 @@ struct vfs_fn_pointers { int (*symlink_fn)(struct vfs_handle_struct *handle, const char *link_contents, const struct smb_filename *new_smb_fname); + int (*symlinkat_fn)(struct vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname); int (*readlinkat_fn)(struct vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1332,6 +1337,10 @@ bool smb_vfs_call_getlock(struct vfs_handle_struct *handle, int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *link_contents, const struct smb_filename *new_smb_fname); +int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname); int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1763,6 +1772,10 @@ bool vfs_not_implemented_getlock(vfs_handle_struct *handle, files_struct *fsp, int vfs_not_implemented_symlink(vfs_handle_struct *handle, const char *link_contents, const struct smb_filename *new_smb_fname); +int vfs_not_implemented_symlinkat(vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname); int vfs_not_implemented_vfs_readlinkat(vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *smb_fname, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 247e9c286c7..f34becaadfa 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -301,6 +301,11 @@ #define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) \ smb_vfs_call_symlink((handle)->next, (oldpath), (newpath)) +#define SMB_VFS_SYMLINKAT(conn, oldpath, dirfsp, newpath) \ + smb_vfs_call_symlinkat((conn)->vfs_handles, (oldpath), (dirfsp), (newpath)) +#define SMB_VFS_NEXT_SYMLINKAT(handle, oldpath, dirfsp, newpath) \ + smb_vfs_call_symlinkat((handle)->next, (oldpath), (dirfsp), (newpath)) + #define SMB_VFS_READLINKAT(conn, dirfsp, smb_fname, buf, bufsiz) \ smb_vfs_call_readlinkat((conn)->vfs_handles, (dirfsp), (smb_fname), (buf), (bufsiz)) #define SMB_VFS_NEXT_READLINKAT(handle, dirfsp, smb_fname, buf, bufsiz) \ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 289ceab4266..4b4d7884694 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2650,6 +2650,24 @@ static int vfswrap_symlink(vfs_handle_struct *handle, return result; } +static int vfswrap_symlinkat(vfs_handle_struct *handle, + const char *link_target, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname) +{ + int result; + + START_PROFILE(syscall_symlinkat); + + SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp); + + result = symlinkat(link_target, + dirfsp->fh->fd, + new_smb_fname->base_name); + END_PROFILE(syscall_symlinkat); + return result; +} + static int vfswrap_readlinkat(vfs_handle_struct *handle, files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -3494,6 +3512,7 @@ static struct vfs_fn_pointers vfs_default_fns = { .linux_setlease_fn = vfswrap_linux_setlease, .getlock_fn = vfswrap_getlock, .symlink_fn = vfswrap_symlink, + .symlinkat_fn = vfswrap_symlinkat, .readlinkat_fn = vfswrap_readlinkat, .linkat_fn = vfswrap_linkat, .mknodat_fn = vfswrap_mknodat, diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index 34b84287d07..b8b5f77b36f 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -462,6 +462,15 @@ int vfs_not_implemented_symlink(vfs_handle_struct *handle, return -1; } +int vfs_not_implemented_symlinkat(vfs_handle_struct *handle, + const char *link_contents, + struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname) +{ + errno = ENOSYS; + return -1; +} + int vfs_not_implemented_vfs_readlinkat(vfs_handle_struct *handle, files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1094,6 +1103,7 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = { .linux_setlease_fn = vfs_not_implemented_linux_setlease, .getlock_fn = vfs_not_implemented_getlock, .symlink_fn = vfs_not_implemented_symlink, + .symlinkat_fn = vfs_not_implemented_symlinkat, .readlinkat_fn = vfs_not_implemented_vfs_readlinkat, .linkat_fn = vfs_not_implemented_linkat, .mknodat_fn = vfs_not_implemented_mknodat, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 4366e2df0c4..e8fdb728ad5 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2201,8 +2201,20 @@ int smb_vfs_call_symlink(struct vfs_handle_struct *handle, return handle->fns->symlink_fn(handle, link_target, new_smb_fname); } -int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle, +int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle, + const char *link_target, struct files_struct *dirfsp, + const struct smb_filename *new_smb_fname) +{ + VFS_FIND(symlinkat); + return handle->fns->symlinkat_fn(handle, + link_target, + dirfsp, + new_smb_fname); +} + +int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle, + files_struct *dirfsp, const struct smb_filename *smb_fname, char *buf, size_t bufsiz) -- cgit v1.2.1