PolicyKit: Branch 'master' - 4 commits

Colin Walters walters at kemper.freedesktop.org
Mon Nov 11 16:01:53 PST 2013


 src/polkit/polkitpermission.c                           |    2 
 src/polkit/polkitsubject.c                              |    4 
 src/polkit/polkitsystembusname.c                        |  171 +++++++++++-----
 src/polkitbackend/polkitbackendsessionmonitor-systemd.c |   63 ++---
 src/programs/pkcheck.c                                  |    4 
 src/programs/pkttyagent.c                               |   12 -
 test/polkitbackend/test-polkitbackendjsauthority.c      |    8 
 7 files changed, 163 insertions(+), 101 deletions(-)

New commits:
commit a4f1c2a546f3685121418a040081f0bac220fd94
Author: Colin Walters <walters at verbum.org>
Date:   Thu Nov 7 17:24:30 2013 -0500

    Use G_GNUC_BEGIN_IGNORE_DEPRECATIONS to avoid warning spam
    
    In these cases, we can't every drop use of our API which we deprecated
    for external callers; for example where a (deprecated) command line is
    invoking the deprecated API.
    
    This patch avoids having polkit developers get spammed by unfixable
    warnings.

diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c
index aed5795..b86e0b9 100644
--- a/src/polkit/polkitsubject.c
+++ b/src/polkit/polkitsubject.c
@@ -247,11 +247,15 @@ polkit_subject_from_string  (const gchar   *str,
         }
       else if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2)
         {
+	  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
           subject = polkit_unix_process_new_full (scanned_pid, scanned_starttime);
+	  G_GNUC_END_IGNORE_DEPRECATIONS
         }
       else if (sscanf (str, "unix-process:%d", &scanned_pid) == 1)
         {
+	  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
           subject = polkit_unix_process_new (scanned_pid);
+	  G_GNUC_END_IGNORE_DEPRECATIONS
           if (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) == 0)
             {
               g_object_unref (subject);
diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c
index 11b2e26..5781893 100644
--- a/src/programs/pkcheck.c
+++ b/src/programs/pkcheck.c
@@ -399,11 +399,15 @@ main (int argc, char *argv[])
             }
           else if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time) == 2)
             {
+	      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
               subject = polkit_unix_process_new_full (pid, pid_start_time);
+	      G_GNUC_END_IGNORE_DEPRECATIONS
             }
           else if (sscanf (argv[n], "%i", &pid) == 1)
             {
+	      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
               subject = polkit_unix_process_new (pid);
+	      G_GNUC_END_IGNORE_DEPRECATIONS
             }
           else
             {
diff --git a/src/programs/pkttyagent.c b/src/programs/pkttyagent.c
index e5088bb..423b728 100644
--- a/src/programs/pkttyagent.c
+++ b/src/programs/pkttyagent.c
@@ -111,9 +111,17 @@ main (int argc, char *argv[])
 
       if (sscanf (opt_process, "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time)
 	  == 2)
-	subject = polkit_unix_process_new_full (pid, pid_start_time);
+	{
+	  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+          subject = polkit_unix_process_new_full (pid, pid_start_time);
+	  G_GNUC_END_IGNORE_DEPRECATIONS
+	}
       else if (sscanf (opt_process, "%i", &pid) == 1)
-	subject = polkit_unix_process_new (pid);
+	{
+	  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+	  subject = polkit_unix_process_new (pid);
+	  G_GNUC_END_IGNORE_DEPRECATIONS
+	}
       else
 	{
 	  g_printerr (_("%s: Invalid process specifier `%s'\n"),
commit 6d3d0a8ffb0fd8ae59eb35593b305ec87da8858d
Author: Colin Walters <walters at verbum.org>
Date:   Sat Nov 9 13:48:21 2013 -0500

    Port internals non-deprecated PolkitProcess API where possible
    
    We can't port everything, but in PolkitPermission and these test
    cases, we can use _for_owner() with the right information.

diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c
index 22d195f..f8a666e 100644
--- a/src/polkit/polkitpermission.c
+++ b/src/polkit/polkitpermission.c
@@ -122,7 +122,7 @@ polkit_permission_constructed (GObject *object)
   PolkitPermission *permission = POLKIT_PERMISSION (object);
 
   if (permission->subject == NULL)
-    permission->subject = polkit_unix_process_new (getpid ());
+    permission->subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
 
   if (G_OBJECT_CLASS (polkit_permission_parent_class)->constructed != NULL)
     G_OBJECT_CLASS (polkit_permission_parent_class)->constructed (object);
diff --git a/test/polkitbackend/test-polkitbackendjsauthority.c b/test/polkitbackend/test-polkitbackendjsauthority.c
index a4de6b1..dfb894f 100644
--- a/test/polkitbackend/test-polkitbackendjsauthority.c
+++ b/test/polkitbackend/test-polkitbackendjsauthority.c
@@ -74,8 +74,8 @@ test_get_admin_identities_for_action_id (const gchar         *action_id,
 
   authority = get_authority ();
 
-  caller = polkit_unix_process_new (getpid ());
-  subject = polkit_unix_process_new (getpid ());
+  caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
+  subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
   user_for_subject = polkit_identity_from_string ("unix-user:root", &error);
   g_assert_no_error (error);
 
@@ -340,8 +340,8 @@ rules_test_func (gconstpointer user_data)
 
   authority = get_authority ();
 
-  caller = polkit_unix_process_new (getpid ());
-  subject = polkit_unix_process_new (getpid ());
+  caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
+  subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
   user_for_subject = polkit_identity_from_string (tc->identity, &error);
   g_assert_no_error (error);
 
commit bfa5036bfb93582c5a87c44b847957479d911e38
Author: Colin Walters <walters at verbum.org>
Date:   Sat Nov 9 09:32:52 2013 -0500

    PolkitSystemBusName: Retrieve both pid and uid
    
    For polkit_system_bus_name_get_process_sync(), as pointed out by
    Miloslav Trmac, we can securely retrieve the owner uid as well from
    the system bus, rather than (racily) looking it up internally.
    
    This avoids use of a deprecated API.
    
    However, this is not a security fix because nothing in the polkit
    codebase itself actually retrieves the uid from the result of this API
    call.  But, it might be useful in the future.

diff --git a/src/polkit/polkitsystembusname.c b/src/polkit/polkitsystembusname.c
index 51e4a69..8daa12c 100644
--- a/src/polkit/polkitsystembusname.c
+++ b/src/polkit/polkitsystembusname.c
@@ -341,6 +341,116 @@ subject_iface_init (PolkitSubjectIface *subject_iface)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+typedef struct {
+  GError **error;
+  guint retrieved_uid : 1;
+  guint retrieved_pid : 1;
+  guint caught_error : 1;
+
+  guint32 uid;
+  guint32 pid;
+} AsyncGetBusNameCredsData;
+
+static void
+on_retrieved_unix_uid_pid (GObject              *src,
+			   GAsyncResult         *res,
+			   gpointer              user_data)
+{
+  AsyncGetBusNameCredsData *data = user_data;
+  GVariant *v;
+
+  v = g_dbus_connection_call_finish ((GDBusConnection*)src, res,
+				     data->caught_error ? NULL : data->error);
+  if (!v)
+    {
+      data->caught_error = TRUE;
+    }
+  else
+    {
+      guint32 value;
+      g_variant_get (v, "(u)", &value);
+      g_variant_unref (v);
+      if (!data->retrieved_uid)
+	{
+	  data->retrieved_uid = TRUE;
+	  data->uid = value;
+	}
+      else
+	{
+	  g_assert (!data->retrieved_pid);
+	  data->retrieved_pid = TRUE;
+	  data->pid = value;
+	}
+    }
+}
+
+static gboolean
+polkit_system_bus_name_get_creds_sync (PolkitSystemBusName           *system_bus_name,
+				       guint32                       *out_uid,
+				       guint32                       *out_pid,
+				       GCancellable                  *cancellable,
+				       GError                       **error)
+{
+  gboolean ret = FALSE;
+  AsyncGetBusNameCredsData data = { 0, };
+  GDBusConnection *connection = NULL;
+  GMainContext *tmp_context = NULL;
+
+  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
+  if (connection == NULL)
+    goto out;
+
+  data.error = error;
+
+  tmp_context = g_main_context_new ();
+  g_main_context_push_thread_default (tmp_context);
+
+  /* Do two async calls as it's basically as fast as one sync call.
+   */
+  g_dbus_connection_call (connection,
+			  "org.freedesktop.DBus",       /* name */
+			  "/org/freedesktop/DBus",      /* object path */
+			  "org.freedesktop.DBus",       /* interface name */
+			  "GetConnectionUnixUser",      /* method */
+			  g_variant_new ("(s)", system_bus_name->name),
+			  G_VARIANT_TYPE ("(u)"),
+			  G_DBUS_CALL_FLAGS_NONE,
+			  -1,
+			  cancellable,
+			  on_retrieved_unix_uid_pid,
+			  &data);
+  g_dbus_connection_call (connection,
+			  "org.freedesktop.DBus",       /* name */
+			  "/org/freedesktop/DBus",      /* object path */
+			  "org.freedesktop.DBus",       /* interface name */
+			  "GetConnectionUnixProcessID", /* method */
+			  g_variant_new ("(s)", system_bus_name->name),
+			  G_VARIANT_TYPE ("(u)"),
+			  G_DBUS_CALL_FLAGS_NONE,
+			  -1,
+			  cancellable,
+			  on_retrieved_unix_uid_pid,
+			  &data);
+
+  while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
+    g_main_context_iteration (tmp_context, TRUE);
+
+  if (out_uid)
+    *out_uid = data.uid;
+  if (out_pid)
+    *out_pid = data.pid;
+  ret = TRUE;
+ out:
+  if (tmp_context)
+    {
+      g_main_context_pop_thread_default (tmp_context);
+      g_main_context_unref (tmp_context);
+    }
+  if (connection != NULL)
+    g_object_unref (connection);
+  return ret;
+}
+
 /**
  * polkit_system_bus_name_get_process_sync:
  * @system_bus_name: A #PolkitSystemBusName.
@@ -357,43 +467,21 @@ polkit_system_bus_name_get_process_sync (PolkitSystemBusName  *system_bus_name,
                                          GCancellable         *cancellable,
                                          GError              **error)
 {
-  GDBusConnection *connection;
-  PolkitSubject *ret;
-  GVariant *result;
+  PolkitSubject *ret = NULL;
   guint32 pid;
+  guint32 uid;
 
   g_return_val_if_fail (POLKIT_IS_SYSTEM_BUS_NAME (system_bus_name), NULL);
   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  ret = NULL;
-
-  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
-  if (connection == NULL)
+  if (!polkit_system_bus_name_get_creds_sync (system_bus_name, &uid, &pid,
+					      cancellable, error))
     goto out;
 
-  result = g_dbus_connection_call_sync (connection,
-                                        "org.freedesktop.DBus",       /* name */
-                                        "/org/freedesktop/DBus",      /* object path */
-                                        "org.freedesktop.DBus",       /* interface name */
-                                        "GetConnectionUnixProcessID", /* method */
-                                        g_variant_new ("(s)", system_bus_name->name),
-                                        G_VARIANT_TYPE ("(u)"),
-                                        G_DBUS_CALL_FLAGS_NONE,
-                                        -1,
-                                        cancellable,
-                                        error);
-  if (result == NULL)
-    goto out;
-
-  g_variant_get (result, "(u)", &pid);
-  g_variant_unref (result);
-
-  ret = polkit_unix_process_new (pid);
+  ret = polkit_unix_process_new_for_owner (pid, 0, uid);
 
  out:
-  if (connection != NULL)
-    g_object_unref (connection);
   return ret;
 }
 
@@ -413,42 +501,19 @@ polkit_system_bus_name_get_user_sync (PolkitSystemBusName  *system_bus_name,
 				      GCancellable         *cancellable,
 				      GError              **error)
 {
-  GDBusConnection *connection;
-  PolkitUnixUser *ret;
-  GVariant *result;
+  PolkitUnixUser *ret = NULL;
   guint32 uid;
 
   g_return_val_if_fail (POLKIT_IS_SYSTEM_BUS_NAME (system_bus_name), NULL);
   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  ret = NULL;
-
-  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
-  if (connection == NULL)
-    goto out;
-
-  result = g_dbus_connection_call_sync (connection,
-                                        "org.freedesktop.DBus",       /* name */
-                                        "/org/freedesktop/DBus",      /* object path */
-                                        "org.freedesktop.DBus",       /* interface name */
-                                        "GetConnectionUnixUser",      /* method */
-                                        g_variant_new ("(s)", system_bus_name->name),
-                                        G_VARIANT_TYPE ("(u)"),
-                                        G_DBUS_CALL_FLAGS_NONE,
-                                        -1,
-                                        cancellable,
-                                        error);
-  if (result == NULL)
+  if (!polkit_system_bus_name_get_creds_sync (system_bus_name, &uid, NULL,
+					      cancellable, error))
     goto out;
 
-  g_variant_get (result, "(u)", &uid);
-  g_variant_unref (result);
-
   ret = (PolkitUnixUser*)polkit_unix_user_new (uid);
 
  out:
-  if (connection != NULL)
-    g_object_unref (connection);
   return ret;
 }
commit 26d0c0578211fb96fc8fe75572aa11ad6ecbf9b8
Author: Colin Walters <walters at verbum.org>
Date:   Thu Nov 7 15:57:50 2013 -0500

    sessionmonitor-systemd: Deduplicate code paths
    
    We had the code to go from pid -> session duplicated.  If we have a
    PolkitSystemBusName, convert it to a PolkitUnixProcess.
    Then we can do PolkitUnixProcess -> pid -> session in one place.
    
    This is just a code cleanup.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=69538

diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
index 0185310..756b728 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
+++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
@@ -313,61 +313,42 @@ polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMoni
                                                         PolkitSubject               *subject,
                                                         GError                     **error)
 {
-  PolkitSubject *session;
-
-  session = NULL;
+  PolkitUnixProcess *tmp_process = NULL;
+  PolkitUnixProcess *process = NULL;
+  PolkitSubject *session = NULL;
+  char *session_id = NULL;
+  pid_t pid;
 
   if (POLKIT_IS_UNIX_PROCESS (subject))
-    {
-      gchar *session_id;
-      pid_t pid;
-
-      pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject));
-      if (sd_pid_get_session (pid, &session_id) < 0)
-        goto out;
-
-      session = polkit_unix_session_new (session_id);
-      free (session_id);
-    }
+    process = POLKIT_UNIX_PROCESS (subject); /* We already have a process */
   else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
     {
-      guint32 pid;
-      gchar *session_id;
-      GVariant *result;
-
-      result = g_dbus_connection_call_sync (monitor->system_bus,
-                                            "org.freedesktop.DBus",
-                                            "/org/freedesktop/DBus",
-                                            "org.freedesktop.DBus",
-                                            "GetConnectionUnixProcessID",
-                                            g_variant_new ("(s)", polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject))),
-                                            G_VARIANT_TYPE ("(u)"),
-                                            G_DBUS_CALL_FLAGS_NONE,
-                                            -1, /* timeout_msec */
-                                            NULL, /* GCancellable */
-                                            error);
-      if (result == NULL)
-        goto out;
-      g_variant_get (result, "(u)", &pid);
-      g_variant_unref (result);
-
-      if (sd_pid_get_session (pid, &session_id) < 0)
-        goto out;
-
-      session = polkit_unix_session_new (session_id);
-      free (session_id);
+      /* Convert bus name to process */
+      tmp_process = (PolkitUnixProcess*)polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error);
+      if (!tmp_process)
+	goto out;
+      process = tmp_process;
     }
   else
     {
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_NOT_SUPPORTED,
-                   "Cannot get user for subject of type %s",
+                   "Cannot get session for subject of type %s",
                    g_type_name (G_TYPE_FROM_INSTANCE (subject)));
     }
 
- out:
+  /* Now do process -> pid -> session */
+  g_assert (process != NULL);
+  pid = polkit_unix_process_get_pid (process);
 
+  if (sd_pid_get_session (pid, &session_id) < 0)
+    goto out;
+  
+  session = polkit_unix_session_new (session_id);
+  free (session_id);
+ out:
+  if (tmp_process) g_object_unref (tmp_process);
   return session;
 }
 


More information about the hal-commit mailing list