1a0d93
From d5dfd823c94045488aef8727c553f1e0f7666b90 Mon Sep 17 00:00:00 2001
1a0d93
From: Ondrej Holy <oholy@redhat.com>
1a0d93
Date: Fri, 24 May 2019 09:43:43 +0200
1a0d93
Subject: [PATCH] admin: Ensure correct ownership when moving to file:// uri
1a0d93
1a0d93
User and group is not restored properly when moving (or copying with
1a0d93
G_FILE_COPY_ALL_METADATA) from admin:// to file://, because it is handled
1a0d93
by GIO fallback code, which doesn't run with root permissions. Let's
1a0d93
handle this case with pull method to ensure correct ownership.
1a0d93
---
1a0d93
 daemon/gvfsbackendadmin.c | 46 +++++++++++++++++++++++++++++++++++++++
1a0d93
 1 file changed, 46 insertions(+)
1a0d93
1a0d93
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c
1a0d93
index 32b51b1a..9a7e8295 100644
1a0d93
--- a/daemon/gvfsbackendadmin.c
1a0d93
+++ b/daemon/gvfsbackendadmin.c
1a0d93
@@ -807,6 +807,51 @@ do_move (GVfsBackend *backend,
1a0d93
   complete_job (job, error);
1a0d93
 }
1a0d93
 
1a0d93
+static void
1a0d93
+do_pull (GVfsBackend *backend,
1a0d93
+         GVfsJobPull *pull_job,
1a0d93
+         const char *source,
1a0d93
+         const char *local_path,
1a0d93
+         GFileCopyFlags flags,
1a0d93
+         gboolean remove_source,
1a0d93
+         GFileProgressCallback progress_callback,
1a0d93
+         gpointer progress_callback_data)
1a0d93
+{
1a0d93
+  GVfsBackendAdmin *self = G_VFS_BACKEND_ADMIN (backend);
1a0d93
+  GVfsJob *job = G_VFS_JOB (pull_job);
1a0d93
+  GError *error = NULL;
1a0d93
+  GFile *src_file, *dst_file;
1a0d93
+
1a0d93
+  /* Pull method is necessary when user/group needs to be restored, return
1a0d93
+   * G_IO_ERROR_NOT_SUPPORTED in other cases to proceed with the fallback code.
1a0d93
+   */
1a0d93
+  if (!(flags & G_FILE_COPY_ALL_METADATA))
1a0d93
+    {
1a0d93
+      g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
1a0d93
+                                G_IO_ERROR_NOT_SUPPORTED,
1a0d93
+                                _("Operation not supported"));
1a0d93
+      return;
1a0d93
+    }
1a0d93
+
1a0d93
+  if (!check_permission (self, job))
1a0d93
+    return;
1a0d93
+
1a0d93
+  src_file = g_file_new_for_path (source);
1a0d93
+  dst_file = g_file_new_for_path (local_path);
1a0d93
+
1a0d93
+  if (remove_source)
1a0d93
+    g_file_move (src_file, dst_file, flags, job->cancellable,
1a0d93
+                 progress_callback, progress_callback_data, &error);
1a0d93
+  else
1a0d93
+    g_file_copy (src_file, dst_file, flags, job->cancellable,
1a0d93
+                 progress_callback, progress_callback_data, &error);
1a0d93
+
1a0d93
+  g_object_unref (src_file);
1a0d93
+  g_object_unref (dst_file);
1a0d93
+
1a0d93
+  complete_job (job, error);
1a0d93
+}
1a0d93
+
1a0d93
 static void
1a0d93
 do_query_settable_attributes (GVfsBackend *backend,
1a0d93
                               GVfsJobQueryAttributes *query_job,
1a0d93
@@ -927,6 +972,7 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass)
1a0d93
   backend_class->set_attribute = do_set_attribute;
1a0d93
   backend_class->delete = do_delete;
1a0d93
   backend_class->move = do_move;
1a0d93
+  backend_class->pull = do_pull;
1a0d93
   backend_class->query_settable_attributes = do_query_settable_attributes;
1a0d93
   backend_class->query_writable_namespaces = do_query_writable_namespaces;
1a0d93
 }
1a0d93
-- 
1a0d93
2.23.0
1a0d93