summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2019-05-24 09:43:43 +0200
committerOndrej Holy <oholy@redhat.com>2019-05-31 13:52:13 +0200
commit409619412e11be146a31b9a99ed965925f1aabb8 (patch)
tree1c31e4eef0914ee6b3c8c55284c49ecd3ae31e98
parentd7d362995aa0cb8905c8d5c2a2a4c305d2ffff80 (diff)
downloadgvfs-409619412e11be146a31b9a99ed965925f1aabb8.tar.gz
admin: Ensure correct ownership when moving to file:// uri
User and group is not restored properly when moving (or copying with G_FILE_COPY_ALL_METADATA) from admin:// to file://, because it is handled by GIO fallback code, which doesn't run with root permissions. Let's handle this case with pull method to ensure correct ownership.
-rw-r--r--daemon/gvfsbackendadmin.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c
index 32b51b1a..9a7e8295 100644
--- a/daemon/gvfsbackendadmin.c
+++ b/daemon/gvfsbackendadmin.c
@@ -808,6 +808,51 @@ do_move (GVfsBackend *backend,
}
static void
+do_pull (GVfsBackend *backend,
+ GVfsJobPull *pull_job,
+ const char *source,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data)
+{
+ GVfsBackendAdmin *self = G_VFS_BACKEND_ADMIN (backend);
+ GVfsJob *job = G_VFS_JOB (pull_job);
+ GError *error = NULL;
+ GFile *src_file, *dst_file;
+
+ /* Pull method is necessary when user/group needs to be restored, return
+ * G_IO_ERROR_NOT_SUPPORTED in other cases to proceed with the fallback code.
+ */
+ if (!(flags & G_FILE_COPY_ALL_METADATA))
+ {
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported"));
+ return;
+ }
+
+ if (!check_permission (self, job))
+ return;
+
+ src_file = g_file_new_for_path (source);
+ dst_file = g_file_new_for_path (local_path);
+
+ if (remove_source)
+ g_file_move (src_file, dst_file, flags, job->cancellable,
+ progress_callback, progress_callback_data, &error);
+ else
+ g_file_copy (src_file, dst_file, flags, job->cancellable,
+ progress_callback, progress_callback_data, &error);
+
+ g_object_unref (src_file);
+ g_object_unref (dst_file);
+
+ complete_job (job, error);
+}
+
+static void
do_query_settable_attributes (GVfsBackend *backend,
GVfsJobQueryAttributes *query_job,
const char *filename)
@@ -927,6 +972,7 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass)
backend_class->set_attribute = do_set_attribute;
backend_class->delete = do_delete;
backend_class->move = do_move;
+ backend_class->pull = do_pull;
backend_class->query_settable_attributes = do_query_settable_attributes;
backend_class->query_writable_namespaces = do_query_writable_namespaces;
}