s3: Add some debugs to streams_xattr
[ira/wip.git] / source3 / modules / vfs_shadow_copy2.c
index 7b5b85d4beece91f8321583dc16ec0c5aeb150c3..eac83fca7499e01d7be883a0ecbe953919aee2f7 100644 (file)
@@ -176,6 +176,16 @@ static inline bool shadow_copy2_match_name(const char *name)
        } \
 } while (0)
 
+#define SHADOW2_NEXT2_SMB_FNAME(op, args) do { \
+       if (shadow_copy2_match_name(smb_fname_src->base_name) || \
+           shadow_copy2_match_name(smb_fname_dst->base_name)) { \
+               errno = EROFS; \
+               return -1; \
+       } else { \
+               return SMB_VFS_NEXT_ ## op args; \
+       } \
+} while (0)
+
 
 /*
   find the mount point of a filesystem
@@ -343,9 +353,11 @@ static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUC
 }
 
 static int shadow_copy2_rename(vfs_handle_struct *handle,
-                       const char *oldname, const char *newname)
+                              const struct smb_filename *smb_fname_src,
+                              const struct smb_filename *smb_fname_dst)
 {
-       SHADOW2_NEXT2(RENAME, (handle, oldname, newname));
+       SHADOW2_NEXT2_SMB_FNAME(RENAME,
+                               (handle, smb_fname_src, smb_fname_dst));
 }
 
 static int shadow_copy2_symlink(vfs_handle_struct *handle,
@@ -376,29 +388,43 @@ static SMB_STRUCT_DIR *shadow_copy2_opendir(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_stat(vfs_handle_struct *handle,
-                     const char *fname, SMB_STRUCT_STAT *sbuf)
+                            struct smb_filename *smb_fname)
 {
-        _SHADOW2_NEXT(STAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
+        _SHADOW2_NEXT_SMB_FNAME(STAT, (handle, smb_fname), int, -1,
+                               convert_sbuf(handle, smb_fname->base_name,
+                                            &smb_fname->st));
 }
 
 static int shadow_copy2_lstat(vfs_handle_struct *handle,
-                      const char *fname, SMB_STRUCT_STAT *sbuf)
+                             struct smb_filename *smb_fname)
 {
-        _SHADOW2_NEXT(LSTAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
+        _SHADOW2_NEXT_SMB_FNAME(LSTAT, (handle, smb_fname), int, -1,
+                               convert_sbuf(handle, smb_fname->base_name,
+                                            &smb_fname->st));
 }
 
 static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
 {
        int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
-       if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
-               convert_sbuf(handle, fsp->fsp_name, sbuf);
+       if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) {
+               convert_sbuf(handle, fsp->fsp_name->base_name, sbuf);
        }
        return ret;
 }
 
-static int shadow_copy2_unlink(vfs_handle_struct *handle, const char *fname)
+static int shadow_copy2_unlink(vfs_handle_struct *handle,
+                              const struct smb_filename *smb_fname_in)
 {
-        SHADOW2_NEXT(UNLINK, (handle, name), int, -1);
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
+       status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+        SHADOW2_NEXT_SMB_FNAME(UNLINK, (handle, smb_fname), int, -1);
 }
 
 static int shadow_copy2_chmod(vfs_handle_struct *handle,
@@ -420,9 +446,19 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_ntimes(vfs_handle_struct *handle,
-                      const char *fname, struct smb_file_time *ft)
+                              const struct smb_filename *smb_fname_in,
+                              struct smb_file_time *ft)
 {
-        SHADOW2_NEXT(NTIMES, (handle, name, ft), int, -1);
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
+       status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+        SHADOW2_NEXT_SMB_FNAME(NTIMES, (handle, smb_fname, ft), int, -1);
 }
 
 static int shadow_copy2_readlink(vfs_handle_struct *handle,
@@ -440,6 +476,9 @@ static int shadow_copy2_mknod(vfs_handle_struct *handle,
 static char *shadow_copy2_realpath(vfs_handle_struct *handle,
                            const char *fname, char *resolved_path)
 {
+       if (shadow_copy2_match_name(fname) && (fname[GMT_NAME_LEN] == '\0')) {
+               return SMB_VFS_NEXT_REALPATH(handle, ".", resolved_path);
+       }
         SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, NULL);
 }
 
@@ -513,7 +552,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle,  const char *fname)
         SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
 }
 
-static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags)
+static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
+                               unsigned int flags)
 {
         SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
 }
@@ -563,11 +603,6 @@ static int shadow_copy2_lsetxattr(struct vfs_handle_struct *handle, const char *
 static int shadow_copy2_chmod_acl(vfs_handle_struct *handle,
                           const char *fname, mode_t mode)
 {
-        /* If the underlying VFS doesn't have ACL support... */
-        if (!handle->vfs_next.ops.chmod_acl) {
-                errno = ENOSYS;
-                return -1;
-        }
         SHADOW2_NEXT(CHMOD_ACL, (handle, name, mode), int, -1);
 }
 
@@ -637,54 +672,37 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
        return 0;
 }
 
-/* VFS operations structure */
-
-static vfs_op_tuple shadow_copy2_ops[] = {
-        {SMB_VFS_OP(shadow_copy2_opendir),  SMB_VFS_OP_OPENDIR,  SMB_VFS_LAYER_TRANSPARENT},
-
-       /* directory operations */
-        {SMB_VFS_OP(shadow_copy2_mkdir),       SMB_VFS_OP_MKDIR,       SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_rmdir),       SMB_VFS_OP_RMDIR,       SMB_VFS_LAYER_TRANSPARENT},
-
-       /* xattr and flags operations */
-        {SMB_VFS_OP(shadow_copy2_chflags),     SMB_VFS_OP_CHFLAGS,     SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_getxattr),    SMB_VFS_OP_GETXATTR,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_lgetxattr),   SMB_VFS_OP_LGETXATTR,   SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_listxattr),   SMB_VFS_OP_LISTXATTR,   SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_lremovexattr),SMB_VFS_OP_LREMOVEXATTR,SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_setxattr),    SMB_VFS_OP_SETXATTR,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_lsetxattr),   SMB_VFS_OP_LSETXATTR,   SMB_VFS_LAYER_TRANSPARENT},
-
-        /* File operations */
-        {SMB_VFS_OP(shadow_copy2_open),       SMB_VFS_OP_OPEN,     SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_rename),     SMB_VFS_OP_RENAME,   SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_stat),       SMB_VFS_OP_STAT,     SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_lstat),      SMB_VFS_OP_LSTAT,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_fstat),      SMB_VFS_OP_FSTAT,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_unlink),     SMB_VFS_OP_UNLINK,   SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_chmod),      SMB_VFS_OP_CHMOD,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_chown),      SMB_VFS_OP_CHOWN,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_chdir),      SMB_VFS_OP_CHDIR,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_ntimes),     SMB_VFS_OP_NTIMES,   SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_symlink),    SMB_VFS_OP_SYMLINK,  SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_readlink),   SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_link),       SMB_VFS_OP_LINK,     SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_mknod),      SMB_VFS_OP_MKNOD,    SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_realpath),   SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(shadow_copy2_connectpath), SMB_VFS_OP_CONNECTPATH, SMB_VFS_LAYER_OPAQUE},
-
-        /* NT File ACL operations */
-        {SMB_VFS_OP(shadow_copy2_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
-        /* POSIX ACL operations */
-        {SMB_VFS_OP(shadow_copy2_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
-       /* special shadown copy op */
-       {SMB_VFS_OP(shadow_copy2_get_shadow_copy2_data), 
-        SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
-
-       {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
+        .opendir = shadow_copy2_opendir,
+        .mkdir = shadow_copy2_mkdir,
+        .rmdir = shadow_copy2_rmdir,
+        .chflags = shadow_copy2_chflags,
+        .getxattr = shadow_copy2_getxattr,
+        .lgetxattr = shadow_copy2_lgetxattr,
+        .listxattr = shadow_copy2_listxattr,
+        .removexattr = shadow_copy2_removexattr,
+        .lremovexattr = shadow_copy2_lremovexattr,
+        .setxattr = shadow_copy2_setxattr,
+        .lsetxattr = shadow_copy2_lsetxattr,
+        .open = shadow_copy2_open,
+        .rename = shadow_copy2_rename,
+        .stat = shadow_copy2_stat,
+        .lstat = shadow_copy2_lstat,
+        .fstat = shadow_copy2_fstat,
+        .unlink = shadow_copy2_unlink,
+        .chmod = shadow_copy2_chmod,
+        .chown = shadow_copy2_chown,
+        .chdir = shadow_copy2_chdir,
+        .ntimes = shadow_copy2_ntimes,
+        .symlink = shadow_copy2_symlink,
+        .vfs_readlink = shadow_copy2_readlink,
+        .link = shadow_copy2_link,
+        .mknod = shadow_copy2_mknod,
+        .realpath = shadow_copy2_realpath,
+        .connectpath = shadow_copy2_connectpath,
+        .get_nt_acl = shadow_copy2_get_nt_acl,
+        .chmod_acl = shadow_copy2_chmod_acl,
+       .get_shadow_copy_data = shadow_copy2_get_shadow_copy2_data,
 };
 
 NTSTATUS vfs_shadow_copy2_init(void);
@@ -692,7 +710,8 @@ NTSTATUS vfs_shadow_copy2_init(void)
 {
        NTSTATUS ret;
 
-       ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy2", shadow_copy2_ops);
+       ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy2",
+                              &vfs_shadow_copy2_fns);
 
        if (!NT_STATUS_IS_OK(ret))
                return ret;