From 3794fa0a9833665492952680a2ffac6653eed5e0 Mon Sep 17 00:00:00 2001 From: Pooja Mahadik Date: Sun, 27 Aug 2017 17:24:32 +0530 Subject: [PATCH] Changes in samba vxfs plugin. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Implemented two VFS operations(set/fset dos attribute) for vxfs plugin. Trapping set/clear of read-only attribute. Signed-off-by: Pooja Mahadik Reviewed-by: Ralph Böhme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Sat Sep 30 06:42:10 CEST 2017 on sn-devel-144 --- source3/modules/lib_vxfs.c | 113 +++++++++++++++++++++++++++++++++++++ source3/modules/vfs_vxfs.c | 89 +++++++++++++++++++++++++++++ source3/modules/vfs_vxfs.h | 9 +++ 3 files changed, 211 insertions(+) diff --git a/source3/modules/lib_vxfs.c b/source3/modules/lib_vxfs.c index 0d5ea607f27..f9394d6ed33 100644 --- a/source3/modules/lib_vxfs.c +++ b/source3/modules/lib_vxfs.c @@ -22,6 +22,7 @@ #include "smbd/smbd.h" #include "system/filesys.h" #include "string.h" +#include "vfs_vxfs.h" /* * Available under GPL at @@ -36,6 +37,9 @@ static int (*vxfs_getxattr_fd_func) (int fd, const char *name, void *value, size_t *len); static int (*vxfs_removexattr_fd_func) (int fd, const char *name); static int (*vxfs_listxattr_fd_func) (int fd, void *value, size_t *len); +static int (*vxfs_setwxattr_fd_func) (int fd); +static int (*vxfs_clearwxattr_fd_func) (int fd); +static int (*vxfs_checkwxattr_fd_func) (int fd); int vxfs_setxattr_fd(int fd, const char *name, const void *value, size_t len, int flags) @@ -202,6 +206,109 @@ int vxfs_listxattr_path(const char *path, char *list, size_t size) return ret; } +int vxfs_setwxattr_fd(int fd) +{ + int ret = 0; + + if (vxfs_setwxattr_fd_func == NULL) { + errno = ENOSYS; + return -1; + } + ret = vxfs_setwxattr_fd_func(fd); + DBG_DEBUG("ret = %d\n", ret); + if (ret != 0) { + errno = ret; + ret = -1; + } + + return ret; +} + +int vxfs_setwxattr_path(const char *path) +{ + int ret, fd = -1; + + fd = open(path, O_WRONLY); + if (fd == -1) { + DBG_DEBUG("file %s not opened, errno:%s\n", + path, strerror(errno)); + return -1; + } + + ret = vxfs_setwxattr_fd(fd); + DBG_DEBUG("ret = %d\n", ret); + close(fd); + + return ret; +} + +int vxfs_clearwxattr_fd(int fd) +{ + int ret; + if (vxfs_clearwxattr_fd_func == NULL) { + errno = ENOSYS; + return -1; + } + ret = vxfs_clearwxattr_fd_func(fd); + DBG_DEBUG("ret = %d\n", ret); + if (ret != 0) { + errno = ret; + ret = -1; + } + + return ret; +} + +int vxfs_clearwxattr_path(const char *path) +{ + int ret, fd = -1; + + fd = open(path, O_WRONLY); + if (fd == -1) { + DBG_DEBUG("file %s not opened, errno:%s\n", + path, strerror(errno)); + return -1; + } + ret = vxfs_clearwxattr_fd(fd); + DBG_DEBUG("ret = %d\n", ret); + close(fd); + + return ret; +} + +int vxfs_checkwxattr_fd(int fd) +{ + int ret; + + if (vxfs_checkwxattr_fd_func == NULL) { + errno = ENOSYS; + return -1; + } + ret = vxfs_checkwxattr_fd_func(fd); + DBG_DEBUG("ret = %d\n", ret); + if (ret != 0) { + errno = ret; + ret = -1; + } + return ret; +} + +int vxfs_checkwxattr_path(const char *path) +{ + int ret, fd = -1; + + fd = open(path, O_WRONLY); + if (fd == -1) { + DBG_DEBUG("file %s not opened, errno:%s\n", + path, strerror(errno)); + return -1; + } + ret = vxfs_checkwxattr_fd(fd); + close(fd); + + return ret; +} + static bool load_lib_vxfs_function(void *lib_handle, void *fn_ptr, const char *fnc_name) { @@ -240,5 +347,11 @@ void vxfs_init() "vxfs_nxattr_remove"); load_lib_vxfs_function(&lib_handle, &vxfs_listxattr_fd_func, "vxfs_nxattr_list"); + load_lib_vxfs_function(&lib_handle, &vxfs_setwxattr_fd_func, + "vxfs_wattr_set"); + load_lib_vxfs_function(&lib_handle, &vxfs_clearwxattr_fd_func, + "vxfs_wattr_clear"); + load_lib_vxfs_function(&lib_handle, &vxfs_checkwxattr_fd_func, + "vxfs_wattr_check"); } diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c index f1f61f18578..335fd18d9b9 100644 --- a/source3/modules/vfs_vxfs.c +++ b/source3/modules/vfs_vxfs.c @@ -828,6 +828,93 @@ static ssize_t vxfs_flistxattr(struct vfs_handle_struct *handle, return result; } +static NTSTATUS vxfs_set_ea_dos_attributes(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + uint32_t dosmode) +{ + NTSTATUS err; + int ret = 0; + bool attrset = false; + + DBG_DEBUG("Entered function\n"); + + if (!(dosmode & FILE_ATTRIBUTE_READONLY)) { + ret = vxfs_checkwxattr_path(smb_fname->base_name); + if (ret == -1) { + DBG_DEBUG("ret:%d\n", ret); + if ((errno != EOPNOTSUPP) && (errno != ENOENT)) { + return map_nt_error_from_unix(errno); + } + } + } + if (dosmode & FILE_ATTRIBUTE_READONLY) { + ret = vxfs_setwxattr_path(smb_fname->base_name); + DBG_DEBUG("ret:%d\n", ret); + if (ret == -1) { + if ((errno != EOPNOTSUPP) && (errno != EINVAL)) { + return map_nt_error_from_unix(errno); + } + } else { + attrset = true; + } + } + err = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle, smb_fname, dosmode); + if (!NT_STATUS_IS_OK(err)) { + if (attrset) { + ret = vxfs_clearwxattr_path(smb_fname->base_name); + DBG_DEBUG("ret:%d\n", ret); + if ((ret == -1) && (errno != ENOENT)) { + return map_nt_error_from_unix(errno); + } + } + } + + return err; +} + +static NTSTATUS vxfs_fset_ea_dos_attributes(struct vfs_handle_struct *handle, + struct files_struct *fsp, + uint32_t dosmode) +{ + NTSTATUS err; + int ret = 0; + bool attrset = false; + + DBG_DEBUG("Entered function\n"); + + if (!(dosmode & FILE_ATTRIBUTE_READONLY)) { + ret = vxfs_checkwxattr_fd(fsp->fh->fd); + if (ret == -1) { + DBG_DEBUG("ret:%d\n", ret); + if ((errno != EOPNOTSUPP) && (errno != ENOENT)) { + return map_nt_error_from_unix(errno); + } + } + } + if (dosmode & FILE_ATTRIBUTE_READONLY) { + ret = vxfs_setwxattr_fd(fsp->fh->fd); + DBG_DEBUG("ret:%d\n", ret); + if (ret == -1) { + if ((errno != EOPNOTSUPP) && (errno != EINVAL)) { + return map_nt_error_from_unix(errno); + } + } else { + attrset = true; + } + } + err = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode); + if (!NT_STATUS_IS_OK(err)) { + if (attrset) { + ret = vxfs_clearwxattr_fd(fsp->fh->fd); + DBG_DEBUG("ret:%d\n", ret); + if ((ret == -1) && (errno != ENOENT)) { + return map_nt_error_from_unix(errno); + } + } + } + return err; +} + static int vfs_vxfs_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { @@ -852,6 +939,8 @@ static struct vfs_fn_pointers vfs_vxfs_fns = { .sys_acl_set_fd_fn = vxfs_sys_acl_set_fd, #endif + .set_dos_attributes_fn = vxfs_set_ea_dos_attributes, + .fset_dos_attributes_fn = vxfs_fset_ea_dos_attributes, .getxattr_fn = vxfs_get_xattr, .fgetxattr_fn = vxfs_fget_xattr, .listxattr_fn = vxfs_listxattr, diff --git a/source3/modules/vfs_vxfs.h b/source3/modules/vfs_vxfs.h index 55a4daefb01..f438bad3d91 100644 --- a/source3/modules/vfs_vxfs.h +++ b/source3/modules/vfs_vxfs.h @@ -31,4 +31,13 @@ int vxfs_removexattr_fd(int, const char *); int vxfs_listxattr_path(const char *, char *, size_t); int vxfs_listxattr_fd(int, char *, size_t); +int vxfs_setwxattr_path(const char *); +int vxfs_setwxattr_fd(int); + +int vxfs_clearwxattr_path(const char *); +int vxfs_clearwxattr_fd(int); + +int vxfs_checkwxattr_path(const char *); +int vxfs_checkwxattr_fd(int); + void vxfs_init(void); -- 2.34.1