s3: VFS: Change SMB_VFS_MKNOD to use const struct smb_filename * instead of const...
[nivanova/samba-autobuild/.git] / source3 / modules / vfs_shadow_copy2.c
index 2afc5954e7d26f5a4cc8b681c378e8f87d89e263..1fb492ba71eb7aaf1bbbd8deaa121ba93a43d6f0 100644 (file)
@@ -444,7 +444,11 @@ static bool make_relative_path(const char *cwd, char *abs_path)
        if (memcmp(abs_path, cwd, cwd_len) != 0) {
                return false;
        }
-       if (abs_path[cwd_len] != '/' && abs_path[cwd_len] != '\0') {
+       /* The cwd_len != 1 case is for $cwd == '/' */
+       if (cwd_len != 1 &&
+           abs_path[cwd_len] != '/' &&
+           abs_path[cwd_len] != '\0')
+       {
                return false;
        }
        if (abs_path[cwd_len] == '/') {
@@ -667,10 +671,11 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
                 * with a path prefix.
                 */
                if (pstripped != NULL) {
-                       if (len_before_gmt > 0) {
+                       if (len_before_gmt > 1) {
                                /*
-                                * There is a slash before
-                                * the @GMT-. Remove it.
+                                * There is a path (and not only a slash)
+                                * before the @GMT-. Remove the trailing
+                                * slash character.
                                 */
                                len_before_gmt -= 1;
                        }
@@ -684,7 +689,7 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
                                if (make_relative_path(priv->shadow_cwd,
                                                stripped) == false) {
                                        DEBUG(10, (__location__ ": path '%s' "
-                                               "doesn't start with cwd '%s\n",
+                                               "doesn't start with cwd '%s'\n",
                                                stripped, priv->shadow_cwd));
                                                ret = false;
                                        errno = ENOENT;
@@ -726,7 +731,7 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
                        if (make_relative_path(priv->shadow_cwd,
                                        stripped) == false) {
                                DEBUG(10, (__location__ ": path '%s' "
-                                       "doesn't start with cwd '%s\n",
+                                       "doesn't start with cwd '%s'\n",
                                        stripped, priv->shadow_cwd));
                                ret = false;
                                errno = ENOENT;
@@ -1651,24 +1656,33 @@ static int shadow_copy2_readlink(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_mknod(vfs_handle_struct *handle,
-                             const char *fname, mode_t mode, SMB_DEV_T dev)
+                               const struct smb_filename *smb_fname,
+                               mode_t mode,
+                               SMB_DEV_T dev)
 {
        time_t timestamp = 0;
        char *stripped = NULL;
        int saved_errno = 0;
        int ret;
-       char *conv;
+       struct smb_filename *conv = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
+       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+                                        smb_fname->base_name,
                                         &timestamp, &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_MKNOD(handle, fname, mode, dev);
+               return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
        }
-       conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
-       TALLOC_FREE(stripped);
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
        if (conv == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+       conv->base_name = shadow_copy2_convert(
+               conv, handle, stripped, timestamp);
+       TALLOC_FREE(stripped);
+       if (conv->base_name == NULL) {
                return -1;
        }
        ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev);
@@ -2328,21 +2342,27 @@ static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
 }
 
 static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
-                                    const char *fname, const char *aname,
-                                    void *value, size_t size)
+                               const struct smb_filename *smb_fname,
+                               const char *aname,
+                               void *value,
+                               size_t size)
 {
        time_t timestamp = 0;
        char *stripped = NULL;
        ssize_t ret;
        int saved_errno = 0;
        char *conv;
+       struct smb_filename *conv_smb_fname = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-                                        &timestamp, &stripped)) {
+       if (!shadow_copy2_strip_snapshot(talloc_tos(),
+                               handle,
+                               smb_fname->base_name,
+                               &timestamp,
+                               &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_GETXATTR(handle, fname, aname, value,
+               return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, aname, value,
                                             size);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
@@ -2350,10 +2370,22 @@ static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
        if (conv == NULL) {
                return -1;
        }
-       ret = SMB_VFS_NEXT_GETXATTR(handle, conv, aname, value, size);
+
+       conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+                                       conv,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->flags);
+       if (conv_smb_fname == NULL) {
+               TALLOC_FREE(conv);
+               return -1;
+       }
+
+       ret = SMB_VFS_NEXT_GETXATTR(handle, conv_smb_fname, aname, value, size);
        if (ret == -1) {
                saved_errno = errno;
        }
+       TALLOC_FREE(conv_smb_fname);
        TALLOC_FREE(conv);
        if (saved_errno != 0) {
                errno = saved_errno;
@@ -2362,7 +2394,7 @@ static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
 }
 
 static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
-                                     const char *fname,
+                                     const struct smb_filename *smb_fname,
                                      char *list, size_t size)
 {
        time_t timestamp = 0;
@@ -2370,23 +2402,37 @@ static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
        ssize_t ret;
        int saved_errno = 0;
        char *conv;
+       struct smb_filename *conv_smb_fname = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-                                        &timestamp, &stripped)) {
+       if (!shadow_copy2_strip_snapshot(talloc_tos(),
+                               handle,
+                               smb_fname->base_name,
+                               &timestamp,
+                               &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_LISTXATTR(handle, fname, list, size);
+               return SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
        TALLOC_FREE(stripped);
        if (conv == NULL) {
                return -1;
        }
-       ret = SMB_VFS_NEXT_LISTXATTR(handle, conv, list, size);
+       conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+                                       conv,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->flags);
+       if (conv_smb_fname == NULL) {
+               TALLOC_FREE(conv);
+               return -1;
+       }
+       ret = SMB_VFS_NEXT_LISTXATTR(handle, conv_smb_fname, list, size);
        if (ret == -1) {
                saved_errno = errno;
        }
+       TALLOC_FREE(conv_smb_fname);
        TALLOC_FREE(conv);
        if (saved_errno != 0) {
                errno = saved_errno;
@@ -2395,30 +2441,45 @@ static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_removexattr(vfs_handle_struct *handle,
-                                   const char *fname, const char *aname)
+                               const struct smb_filename *smb_fname,
+                               const char *aname)
 {
        time_t timestamp = 0;
        char *stripped = NULL;
        int saved_errno = 0;
        int ret;
        char *conv;
+       struct smb_filename *conv_smb_fname = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-                                        &timestamp, &stripped)) {
+       if (!shadow_copy2_strip_snapshot(talloc_tos(),
+                               handle,
+                               smb_fname->base_name,
+                               &timestamp,
+                               &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_REMOVEXATTR(handle, fname, aname);
+               return SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, aname);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
        TALLOC_FREE(stripped);
        if (conv == NULL) {
                return -1;
        }
-       ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv, aname);
+       conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+                                       conv,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->flags);
+       if (conv_smb_fname == NULL) {
+               TALLOC_FREE(conv);
+               return -1;
+       }
+       ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv_smb_fname, aname);
        if (ret == -1) {
                saved_errno = errno;
        }
+       TALLOC_FREE(conv_smb_fname);
        TALLOC_FREE(conv);
        if (saved_errno != 0) {
                errno = saved_errno;
@@ -2427,7 +2488,7 @@ static int shadow_copy2_removexattr(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_setxattr(struct vfs_handle_struct *handle,
-                                const char *fname,
+                                const struct smb_filename *smb_fname,
                                 const char *aname, const void *value,
                                 size_t size, int flags)
 {
@@ -2436,24 +2497,39 @@ static int shadow_copy2_setxattr(struct vfs_handle_struct *handle,
        ssize_t ret;
        int saved_errno = 0;
        char *conv;
+       struct smb_filename *conv_smb_fname = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-                                        &timestamp, &stripped)) {
+       if (!shadow_copy2_strip_snapshot(talloc_tos(),
+                               handle,
+                               smb_fname->base_name,
+                               &timestamp,
+                               &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_SETXATTR(handle, fname, aname, value, size,
-                                            flags);
+               return SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+                                       aname, value, size, flags);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
        TALLOC_FREE(stripped);
        if (conv == NULL) {
                return -1;
        }
-       ret = SMB_VFS_NEXT_SETXATTR(handle, conv, aname, value, size, flags);
+       conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+                                       conv,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->flags);
+       if (conv_smb_fname == NULL) {
+               TALLOC_FREE(conv);
+               return -1;
+       }
+       ret = SMB_VFS_NEXT_SETXATTR(handle, conv_smb_fname,
+                               aname, value, size, flags);
        if (ret == -1) {
                saved_errno = errno;
        }
+       TALLOC_FREE(conv_smb_fname);
        TALLOC_FREE(conv);
        if (saved_errno != 0) {
                errno = saved_errno;
@@ -3099,8 +3175,8 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
        .connectpath_fn = shadow_copy2_connectpath,
 };
 
-NTSTATUS vfs_shadow_copy2_init(void);
-NTSTATUS vfs_shadow_copy2_init(void)
+NTSTATUS vfs_shadow_copy2_init(TALLOC_CTX *);
+NTSTATUS vfs_shadow_copy2_init(TALLOC_CTX *ctx)
 {
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
                                "shadow_copy2", &vfs_shadow_copy2_fns);