Blame SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch

0b0087
From af4d0d88604af7c196e461a743f2d1e81239d76a Mon Sep 17 00:00:00 2001
0b0087
From: Ondrej Holy <oholy@redhat.com>
0b0087
Date: Tue, 14 May 2019 09:31:37 +0200
0b0087
Subject: [PATCH 2/3] daemon: Handle lockdown option to disable writing
0b0087
0b0087
Handle the new mount-removable-storage-devices-as-read-only option of
0b0087
org.gnome.desktop.lockdown schema and present AFC, MTP, GPhoto2 devices
0b0087
as read-only if enabled.
0b0087
---
0b0087
 daemon/gvfsbackend.c           | 62 ++++++++++++++++++++++++++++++++--
0b0087
 daemon/gvfsbackend.h           |  6 ++++
0b0087
 daemon/gvfsbackendafc.c        |  2 ++
0b0087
 daemon/gvfsbackendgphoto2.c    |  1 +
0b0087
 daemon/gvfsbackendmtp.c        |  1 +
0b0087
 daemon/gvfsjobcopy.c           |  7 ++++
0b0087
 daemon/gvfsjobdelete.c         |  7 ++++
0b0087
 daemon/gvfsjobmakedirectory.c  |  7 ++++
0b0087
 daemon/gvfsjobmakesymlink.c    |  7 ++++
0b0087
 daemon/gvfsjobmove.c           |  7 ++++
0b0087
 daemon/gvfsjobopenforwrite.c   |  7 ++++
0b0087
 daemon/gvfsjobpush.c           |  7 ++++
0b0087
 daemon/gvfsjobqueryfsinfo.c    | 11 ++----
0b0087
 daemon/gvfsjobsetattribute.c   |  7 ++++
0b0087
 daemon/gvfsjobsetdisplayname.c |  7 ++++
0b0087
 daemon/gvfsjobtrash.c          |  7 ++++
0b0087
 16 files changed, 143 insertions(+), 10 deletions(-)
0b0087
0b0087
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
0b0087
index 4fd3455c..599733ef 100644
0b0087
--- a/daemon/gvfsbackend.c
0b0087
+++ b/daemon/gvfsbackend.c
0b0087
@@ -80,6 +80,9 @@ struct _GVfsBackendPrivate
0b0087
   char *default_location;
0b0087
   GMountSpec *mount_spec;
0b0087
   gboolean block_requests;
0b0087
+
0b0087
+  GSettings *lockdown_settings;
0b0087
+  gboolean readonly_lockdown;
0b0087
 };
0b0087
 
0b0087
 
0b0087
@@ -155,7 +158,9 @@ g_vfs_backend_finalize (GObject *object)
0b0087
   g_free (backend->priv->default_location);
0b0087
   if (backend->priv->mount_spec)
0b0087
     g_mount_spec_unref (backend->priv->mount_spec);
0b0087
-  
0b0087
+
0b0087
+  g_clear_object (&backend->priv->lockdown_settings);
0b0087
+
0b0087
   if (G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize)
0b0087
     (*G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) (object);
0b0087
 }
0b0087
@@ -587,7 +592,29 @@ g_vfs_backend_add_auto_info (GVfsBackend *backend,
0b0087
        g_file_attribute_matcher_matches (matcher,
0b0087
                                          G_FILE_ATTRIBUTE_THUMBNAILING_FAILED)))
0b0087
     get_thumbnail_attributes (uri, info);
0b0087
-  
0b0087
+
0b0087
+  if (backend->priv->readonly_lockdown)
0b0087
+    {
0b0087
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
0b0087
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE);
0b0087
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
0b0087
+      g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
0b0087
+    }
0b0087
+}
0b0087
+
0b0087
+void
0b0087
+g_vfs_backend_add_auto_fs_info (GVfsBackend *backend,
0b0087
+                                GFileAttributeMatcher *matcher,
0b0087
+                                GFileInfo *info)
0b0087
+{
0b0087
+  const char *type;
0b0087
+
0b0087
+  type = g_vfs_backend_get_backend_type (backend);
0b0087
+  if (type)
0b0087
+    g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_GVFS_BACKEND, type);
0b0087
+
0b0087
+  if (backend->priv->readonly_lockdown)
0b0087
+    g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE);
0b0087
 }
0b0087
 
0b0087
 void
0b0087
@@ -1047,3 +1074,34 @@ g_vfs_backend_force_unmount (GVfsBackend *backend)
0b0087
                                   (GAsyncReadyCallback) forced_unregister_mount_callback,
0b0087
                                   NULL);
0b0087
 }
0b0087
+
0b0087
+static void
0b0087
+lockdown_settings_changed (GSettings *settings,
0b0087
+                           gchar     *key,
0b0087
+                           gpointer   user_data)
0b0087
+{
0b0087
+  GVfsBackend *backend = G_VFS_BACKEND (user_data);
0b0087
+
0b0087
+  backend->priv->readonly_lockdown = g_settings_get_boolean (settings,
0b0087
+                                                             "mount-removable-storage-devices-as-read-only");
0b0087
+}
0b0087
+
0b0087
+
0b0087
+void
0b0087
+g_vfs_backend_handle_readonly_lockdown (GVfsBackend *backend)
0b0087
+{
0b0087
+  backend->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown");
0b0087
+  backend->priv->readonly_lockdown = g_settings_get_boolean (backend->priv->lockdown_settings,
0b0087
+                                                             "mount-removable-storage-devices-as-read-only");
0b0087
+  g_signal_connect_object (backend->priv->lockdown_settings,
0b0087
+                           "changed",
0b0087
+                           G_CALLBACK (lockdown_settings_changed),
0b0087
+                           backend,
0b0087
+                           0);
0b0087
+}
0b0087
+
0b0087
+gboolean
0b0087
+g_vfs_backend_get_readonly_lockdown (GVfsBackend *backend)
0b0087
+{
0b0087
+  return backend->priv->readonly_lockdown;
0b0087
+}
0b0087
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
0b0087
index 9c7476cf..431dd290 100644
0b0087
--- a/daemon/gvfsbackend.h
0b0087
+++ b/daemon/gvfsbackend.h
0b0087
@@ -516,6 +516,9 @@ void        g_vfs_backend_add_auto_info                  (GVfsBackend
0b0087
 							  GFileAttributeMatcher *matcher,
0b0087
 							  GFileInfo             *info,
0b0087
 							  const char            *uri);
0b0087
+void        g_vfs_backend_add_auto_fs_info               (GVfsBackend           *backend,
0b0087
+                                                          GFileAttributeMatcher *matcher,
0b0087
+                                                          GFileInfo             *info);
0b0087
 
0b0087
 void        g_vfs_backend_set_block_requests             (GVfsBackend           *backend,
0b0087
                                                           gboolean               value);
0b0087
@@ -534,6 +537,9 @@ gboolean    g_vfs_backend_invocation_first_handler       (GVfsDBusMount *object,
0b0087
                                                           GDBusMethodInvocation *invocation,
0b0087
                                                           GVfsBackend *backend);
0b0087
 
0b0087
+void        g_vfs_backend_handle_readonly_lockdown       (GVfsBackend *backend);
0b0087
+gboolean    g_vfs_backend_get_readonly_lockdown          (GVfsBackend *backend);
0b0087
+
0b0087
 G_END_DECLS
0b0087
 
0b0087
 #endif /* __G_VFS_BACKEND_H__ */
0b0087
diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c
0b0087
index b6e6a106..ce68aa45 100644
0b0087
--- a/daemon/gvfsbackendafc.c
0b0087
+++ b/daemon/gvfsbackendafc.c
0b0087
@@ -2760,6 +2760,8 @@ g_vfs_backend_afc_init (GVfsBackendAfc *self)
0b0087
     }
0b0087
 
0b0087
   g_mutex_init (&self->apps_lock);
0b0087
+
0b0087
+  g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (self));
0b0087
 }
0b0087
 
0b0087
 static void
0b0087
diff --git a/daemon/gvfsbackendgphoto2.c b/daemon/gvfsbackendgphoto2.c
0b0087
index 51e9a3bd..7e50194a 100644
0b0087
--- a/daemon/gvfsbackendgphoto2.c
0b0087
+++ b/daemon/gvfsbackendgphoto2.c
0b0087
@@ -614,6 +614,7 @@ g_vfs_backend_gphoto2_init (GVfsBackendGphoto2 *gphoto2_backend)
0b0087
   g_mutex_init (&gphoto2_backend->lock);
0b0087
 
0b0087
   g_vfs_backend_set_display_name (backend, "gphoto2");
0b0087
+  g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend));
0b0087
 
0b0087
   mount_spec = g_mount_spec_new ("gphoto2");
0b0087
   g_vfs_backend_set_mount_spec (backend, mount_spec);
0b0087
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
0b0087
index e3a25ef2..c4f1e855 100644
0b0087
--- a/daemon/gvfsbackendmtp.c
0b0087
+++ b/daemon/gvfsbackendmtp.c
0b0087
@@ -379,6 +379,7 @@ g_vfs_backend_mtp_init (GVfsBackendMtp *backend)
0b0087
   g_mutex_init (&backend->mutex);
0b0087
   g_vfs_backend_set_display_name (G_VFS_BACKEND (backend), "mtp");
0b0087
   g_vfs_backend_set_icon_name (G_VFS_BACKEND (backend), "multimedia-player");
0b0087
+  g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend));
0b0087
 
0b0087
   mount_spec = g_mount_spec_new ("mtp");
0b0087
   g_vfs_backend_set_mount_spec (G_VFS_BACKEND (backend), mount_spec);
0b0087
diff --git a/daemon/gvfsjobcopy.c b/daemon/gvfsjobcopy.c
0b0087
index 785d7480..cf33da56 100644
0b0087
--- a/daemon/gvfsjobcopy.c
0b0087
+++ b/daemon/gvfsjobcopy.c
0b0087
@@ -141,6 +141,13 @@ try (GVfsJob *job)
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
   gboolean res;
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_copy == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobdelete.c b/daemon/gvfsjobdelete.c
0b0087
index 92892f15..8d5e5b8e 100644
0b0087
--- a/daemon/gvfsjobdelete.c
0b0087
+++ b/daemon/gvfsjobdelete.c
0b0087
@@ -120,6 +120,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobDelete *op_job = G_VFS_JOB_DELETE (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_delete == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobmakedirectory.c b/daemon/gvfsjobmakedirectory.c
0b0087
index 98bb28d5..56a9c42a 100644
0b0087
--- a/daemon/gvfsjobmakedirectory.c
0b0087
+++ b/daemon/gvfsjobmakedirectory.c
0b0087
@@ -120,6 +120,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobMakeDirectory *op_job = G_VFS_JOB_MAKE_DIRECTORY (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_make_directory == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobmakesymlink.c b/daemon/gvfsjobmakesymlink.c
0b0087
index 2c55e26b..2684b6fd 100644
0b0087
--- a/daemon/gvfsjobmakesymlink.c
0b0087
+++ b/daemon/gvfsjobmakesymlink.c
0b0087
@@ -124,6 +124,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobMakeSymlink *op_job = G_VFS_JOB_MAKE_SYMLINK (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_make_symlink == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobmove.c b/daemon/gvfsjobmove.c
0b0087
index cc4ad220..5903d17a 100644
0b0087
--- a/daemon/gvfsjobmove.c
0b0087
+++ b/daemon/gvfsjobmove.c
0b0087
@@ -141,6 +141,13 @@ try (GVfsJob *job)
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
   gboolean res;
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_move == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c
0b0087
index 68eae532..60ce64f9 100644
0b0087
--- a/daemon/gvfsjobopenforwrite.c
0b0087
+++ b/daemon/gvfsjobopenforwrite.c
0b0087
@@ -230,6 +230,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (op_job->mode == OPEN_FOR_WRITE_CREATE)
0b0087
     {
0b0087
       if (class->try_create == NULL)
0b0087
diff --git a/daemon/gvfsjobpush.c b/daemon/gvfsjobpush.c
0b0087
index d7e48d86..a8df73a8 100644
0b0087
--- a/daemon/gvfsjobpush.c
0b0087
+++ b/daemon/gvfsjobpush.c
0b0087
@@ -146,6 +146,13 @@ try (GVfsJob *job)
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
   gboolean res;
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_push == NULL)
0b0087
     return FALSE;
0b0087
 
0b0087
diff --git a/daemon/gvfsjobqueryfsinfo.c b/daemon/gvfsjobqueryfsinfo.c
0b0087
index 898052ea..3363311a 100644
0b0087
--- a/daemon/gvfsjobqueryfsinfo.c
0b0087
+++ b/daemon/gvfsjobqueryfsinfo.c
0b0087
@@ -147,15 +147,10 @@ create_reply (GVfsJob *job,
0b0087
               GDBusMethodInvocation *invocation)
0b0087
 {
0b0087
   GVfsJobQueryFsInfo *op_job = G_VFS_JOB_QUERY_FS_INFO (job);
0b0087
-  const char *type;
0b0087
-
0b0087
-  type = g_vfs_backend_get_backend_type (op_job->backend);
0b0087
-
0b0087
-  if (type)
0b0087
-    g_file_info_set_attribute_string (op_job->file_info,
0b0087
-				      G_FILE_ATTRIBUTE_GVFS_BACKEND,
0b0087
-				      type);
0b0087
 
0b0087
+  g_vfs_backend_add_auto_fs_info (op_job->backend,
0b0087
+                                  op_job->attribute_matcher,
0b0087
+                                  op_job->file_info);
0b0087
   g_file_info_set_attribute_mask (op_job->file_info,
0b0087
                                   op_job->attribute_matcher);
0b0087
 
0b0087
diff --git a/daemon/gvfsjobsetattribute.c b/daemon/gvfsjobsetattribute.c
0b0087
index 1efe7c94..ac7618a4 100644
0b0087
--- a/daemon/gvfsjobsetattribute.c
0b0087
+++ b/daemon/gvfsjobsetattribute.c
0b0087
@@ -146,6 +146,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobSetAttribute *op_job = G_VFS_JOB_SET_ATTRIBUTE (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_set_attribute == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobsetdisplayname.c b/daemon/gvfsjobsetdisplayname.c
0b0087
index badb10dd..e12ae879 100644
0b0087
--- a/daemon/gvfsjobsetdisplayname.c
0b0087
+++ b/daemon/gvfsjobsetdisplayname.c
0b0087
@@ -124,6 +124,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_set_display_name == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
diff --git a/daemon/gvfsjobtrash.c b/daemon/gvfsjobtrash.c
0b0087
index 1738f8a2..5234ebf8 100644
0b0087
--- a/daemon/gvfsjobtrash.c
0b0087
+++ b/daemon/gvfsjobtrash.c
0b0087
@@ -119,6 +119,13 @@ try (GVfsJob *job)
0b0087
   GVfsJobTrash *op_job = G_VFS_JOB_TRASH (job);
0b0087
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
0b0087
 
0b0087
+  if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
0b0087
+    {
0b0087
+      g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
0b0087
+                        _("Filesystem is read-only"));
0b0087
+      return TRUE;
0b0087
+    }
0b0087
+
0b0087
   if (class->try_trash == NULL)
0b0087
     return FALSE;
0b0087
   
0b0087
-- 
0b0087
2.21.0
0b0087