Changes in samba vxfs plugin.
authorPooja Mahadik <pooja.mahadik@veritas.com>
Sun, 27 Aug 2017 11:54:32 +0000 (17:24 +0530)
committerJeremy Allison <jra@samba.org>
Sat, 30 Sep 2017 04:42:10 +0000 (06:42 +0200)
Implemented two VFS operations(set/fset dos attribute) for vxfs plugin.

Trapping set/clear of read-only attribute.

Signed-off-by: Pooja Mahadik <pooja.mahadik@veritas.com>
Reviewed-by: Ralph Böhme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Sep 30 06:42:10 CEST 2017 on sn-devel-144

source3/modules/lib_vxfs.c
source3/modules/vfs_vxfs.c
source3/modules/vfs_vxfs.h

index 0d5ea607f2738d7a58b55838c28dcb8b27781fd4..f9394d6ed331513aa0fdc8bd2c59261723a4f349 100644 (file)
@@ -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");
 
 }
index f1f61f18578401e1328639a1a6e08f455c4cf2c1..335fd18d9b990e9b7a1d683ac47249370f07337f 100644 (file)
@@ -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,
index 55a4daefb01c057a34928fe2554f2b1404d2ac11..f438bad3d9103a72e4d3ad357ca5abc6c31b245d 100644 (file)
@@ -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);