udisksd: work if polkitd is not available
authorDavid Zeuthen <zeuthen@gmail.com>
Thu, 7 Jun 2012 15:45:02 +0000 (11:45 -0400)
committerDavid Zeuthen <zeuthen@gmail.com>
Thu, 7 Jun 2012 15:46:30 +0000 (11:46 -0400)
Upstream polkit now recommends this, see

http://cgit.freedesktop.org/polkit/commit/?id=84e42887d413cba0039f92f0c56a25c70c20fe6e

Signed-off-by: David Zeuthen <zeuthen@gmail.com>
src/udisksdaemon.c
src/udisksdaemonutil.c

index 6ddd3ac..2929ee7 100644 (file)
@@ -67,6 +67,7 @@ struct _UDisksDaemon
 
   UDisksLinuxProvider *linux_provider;
 
+  /* may be NULL if polkit is masked */
   PolkitAuthority *authority;
 
   UDisksCleanup *cleanup;
@@ -101,7 +102,7 @@ udisks_daemon_finalize (GObject *object)
   udisks_cleanup_stop (daemon->cleanup);
   g_object_unref (daemon->cleanup);
 
-  g_object_unref (daemon->authority);
+  g_clear_object (&daemon->authority);
   g_object_unref (daemon->persistent_store);
   g_object_unref (daemon->object_manager);
   g_object_unref (daemon->linux_provider);
@@ -195,7 +196,7 @@ udisks_daemon_constructed (GObject *object)
   daemon->authority = polkit_authority_get_sync (NULL, &error);
   if (daemon->authority == NULL)
     {
-      udisks_error ("Error initializing PolicyKit authority: %s (%s, %d)",
+      udisks_error ("Error initializing polkit authority: %s (%s, %d)",
                     error->message, g_quark_to_string (error->domain), error->code);
       g_error_free (error);
     }
@@ -433,7 +434,9 @@ udisks_daemon_get_persistent_store (UDisksDaemon *daemon)
  *
  * Gets the PolicyKit authority used by @daemon.
  *
- * Returns: A #PolkitAuthority instance. Do not free, the object is owned by @daemon.
+ * Returns: A #PolkitAuthority instance or %NULL if the polkit
+ * authority is not available. Do not free, the object is owned by
+ * @daemon.
  */
 PolkitAuthority *
 udisks_daemon_get_authority (UDisksDaemon *daemon)
index 89698d4..9a2e601 100644 (file)
@@ -427,6 +427,53 @@ _safe_polkit_details_insert_uint64 (PolkitDetails *details, const gchar *key, gu
   polkit_details_insert (details, key, buf);
 }
 
+static gboolean
+check_authorization_no_polkit (UDisksDaemon          *daemon,
+                               UDisksObject          *object,
+                               const gchar           *action_id,
+                               GVariant              *options,
+                               const gchar           *message,
+                               GDBusMethodInvocation *invocation)
+{
+  gboolean ret = FALSE;
+  uid_t caller_uid = -1;
+  GError *error = NULL;
+
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL,         /* GCancellable* */
+                                               &caller_uid,
+                                               NULL,         /* gid_t *out_gid */
+                                               NULL,         /* gchar **out_user_name */
+                                               &error))
+    {
+      g_dbus_method_invocation_return_error (invocation,
+                                             UDISKS_ERROR,
+                                             UDISKS_ERROR_FAILED,
+                                             "Error getting uid for caller with bus name %s: %s (%s, %d)",
+                                             g_dbus_method_invocation_get_sender (invocation),
+                                             error->message, g_quark_to_string (error->domain), error->code);
+      g_clear_error (&error);
+      goto out;
+    }
+
+  /* only allow root */
+  if (caller_uid == 0)
+    {
+      ret = TRUE;
+    }
+  else
+    {
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     UDISKS_ERROR,
+                                                     UDISKS_ERROR_NOT_AUTHORIZED,
+                                                     "Not authorized to perform operation (polkit authority not available and caller is not uid 0)");
+    }
+
+ out:
+  return ret;
+}
+
 /**
  * udisks_daemon_util_check_authorization_sync:
  * @daemon: A #UDisksDaemon.
@@ -471,6 +518,7 @@ udisks_daemon_util_check_authorization_sync (UDisksDaemon          *daemon,
                                              const gchar           *message,
                                              GDBusMethodInvocation *invocation)
 {
+  PolkitAuthority *authority = NULL;
   PolkitSubject *subject = NULL;
   PolkitDetails *details = NULL;
   PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
@@ -486,6 +534,13 @@ udisks_daemon_util_check_authorization_sync (UDisksDaemon          *daemon,
   const gchar *details_device = NULL;
   gchar *details_drive = NULL;
 
+  authority = udisks_daemon_get_authority (daemon);
+  if (authority == NULL)
+    {
+      ret = check_authorization_no_polkit (daemon, object, action_id, options, message, invocation);
+      goto out;
+    }
+
   subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
   if (options != NULL)
     {
@@ -588,7 +643,7 @@ udisks_daemon_util_check_authorization_sync (UDisksDaemon          *daemon,
     polkit_details_insert (details, "drive", details_drive);
 
   error = NULL;
-  result = polkit_authority_check_authorization_sync (udisks_daemon_get_authority (daemon),
+  result = polkit_authority_check_authorization_sync (authority,
                                                       subject,
                                                       action_id,
                                                       details,