diff options
author | Ondrej Holy <oholy@redhat.com> | 2019-05-24 09:43:43 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2019-05-31 13:52:13 +0200 |
commit | 409619412e11be146a31b9a99ed965925f1aabb8 (patch) | |
tree | 1c31e4eef0914ee6b3c8c55284c49ecd3ae31e98 | |
parent | d7d362995aa0cb8905c8d5c2a2a4c305d2ffff80 (diff) | |
download | gvfs-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.c | 46 |
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; } |