From 1286c7f751a1a20d08b1a85445b4757c712b203b Mon Sep 17 00:00:00 2001
From: James Meyer <james.meyer@operamail.com>
Date: Tue, 7 Aug 2012 15:44:06 -0500
Subject: polkit .105

---
 abs/extra/polkit/CVE-2011-1485.patch    |  908 ------------------
 abs/extra/polkit/PKGBUILD               |   23 +-
 abs/extra/polkit/systemd-fallback.patch | 1571 +++++++++++++++++++++++++++++++
 3 files changed, 1583 insertions(+), 919 deletions(-)
 delete mode 100644 abs/extra/polkit/CVE-2011-1485.patch
 create mode 100644 abs/extra/polkit/systemd-fallback.patch

diff --git a/abs/extra/polkit/CVE-2011-1485.patch b/abs/extra/polkit/CVE-2011-1485.patch
deleted file mode 100644
index f7054a6..0000000
--- a/abs/extra/polkit/CVE-2011-1485.patch
+++ /dev/null
@@ -1,908 +0,0 @@
-From dd848a42a64a3b22a0cc60f6657b56ce9b6010ae Mon Sep 17 00:00:00 2001
-From: David Zeuthen <davidz@redhat.com>
-Date: Thu, 31 Mar 2011 16:59:09 +0000
-Subject: PolkitUnixProcess: Clarify that the real uid is returned, not the effective one
-
-On Linux, also switch to parsing /proc/<pid>/status instead of relying
-on the st_uid returned by stat(2) to be the uid we want.
-
-This was pointed out by Neel Mehta <nmehta@google.com>. Thanks!
-
-Signed-off-by: David Zeuthen <davidz@redhat.com>
----
-diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
-index d95a1d4..876da69 100644
---- a/src/polkit/polkitunixprocess.c
-+++ b/src/polkit/polkitunixprocess.c
-@@ -24,9 +24,7 @@
- #endif
- 
- #include <sys/types.h>
--#ifndef HAVE_FREEBSD
--#include <sys/stat.h>
--#else
-+#ifdef HAVE_FREEBSD
- #include <sys/param.h>
- #include <sys/sysctl.h>
- #include <sys/user.h>
-@@ -34,6 +32,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-+#include <stdio.h>
- 
- #include "polkitunixprocess.h"
- #include "polkitsubject.h"
-@@ -208,6 +207,8 @@ polkit_unix_process_get_pid (PolkitUnixProcess *process)
-  *
-  * Gets the uid of the owner of @process.
-  *
-+ * Note that this returns the real user-id (not the effective user-id) of @process.
-+ *
-  * Returns: The UNIX user id of the owner for @process or 0 if @error is set.
-  **/
- gint
-@@ -215,17 +216,21 @@ polkit_unix_process_get_owner (PolkitUnixProcess  *process,
-                                GError            **error)
- {
-   gint result;
-+  gchar *contents;
-+  gchar **lines;
- #ifdef HAVE_FREEBSD
-   struct kinfo_proc p;
- #else
--  struct stat statbuf;
--  char procbuf[32];
-+  gchar filename[64];
-+  guint n;
- #endif
- 
-   g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
-   g_return_val_if_fail (error == NULL || *error == NULL, 0);
- 
-   result = 0;
-+  lines = NULL;
-+  contents = NULL;
- 
- #ifdef HAVE_FREEBSD
-   if (get_kinfo_proc (process->pid, &p) == 0)
-@@ -241,23 +246,52 @@ polkit_unix_process_get_owner (PolkitUnixProcess  *process,
- 
-   result = p.ki_uid;
- #else
--  g_snprintf (procbuf, sizeof procbuf, "/proc/%d", process->pid);
--  if (stat (procbuf, &statbuf) != 0)
-+
-+  /* see 'man proc' for layout of the status file
-+   *
-+   * Uid, Gid: Real, effective, saved set,  and  file  system  UIDs (GIDs).
-+   */
-+  g_snprintf (filename, sizeof filename, "/proc/%d/status", process->pid);
-+  if (!g_file_get_contents (filename,
-+                            &contents,
-+                            NULL,
-+                            error))
-     {
--      g_set_error (error,
--                   POLKIT_ERROR,
--                   POLKIT_ERROR_FAILED,
--                   "stat() failed for /proc/%d: %s",
--                   process->pid,
--                   g_strerror (errno));
-       goto out;
-     }
-+  lines = g_strsplit (contents, "\n", -1);
-+  for (n = 0; lines != NULL && lines[n] != NULL; n++)
-+    {
-+      gint real_uid, effective_uid;
-+      if (!g_str_has_prefix (lines[n], "Uid:"))
-+        continue;
-+      if (sscanf (lines[n] + 4, "%d %d", &real_uid, &effective_uid) != 2)
-+        {
-+          g_set_error (error,
-+                       POLKIT_ERROR,
-+                       POLKIT_ERROR_FAILED,
-+                       "Unexpected line `%s' in file %s",
-+                       lines[n],
-+                       filename);
-+          goto out;
-+        }
-+      else
-+        {
-+          result = real_uid;
-+          goto out;
-+        }
-+    }
- 
--  result = statbuf.st_uid;
-+  g_set_error (error,
-+               POLKIT_ERROR,
-+               POLKIT_ERROR_FAILED,
-+               "Didn't find any line starting with `Uid:' in file %s",
-+               filename);
- #endif
- 
-- out:
--
-+out:
-+  g_strfreev (lines);
-+  g_free (contents);
-   return result;
- }
- 
---
-cgit v0.8.3-6-g21f6
-From 129b6223a19e7fb2753f8cad7957ac5402394076 Mon Sep 17 00:00:00 2001
-From: David Zeuthen <davidz@redhat.com>
-Date: Fri, 01 Apr 2011 16:09:45 +0000
-Subject: Make PolkitUnixProcess also record the uid of the process
-
-This is needed to avoid possible TOCTTOU issues since a process can
-change both its real uid and effective uid.
-
-Signed-off-by: David Zeuthen <davidz@redhat.com>
----
-diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
-index 12141e3..9f4fcf8 100644
---- a/docs/polkit/polkit-1-sections.txt
-+++ b/docs/polkit/polkit-1-sections.txt
-@@ -145,10 +145,13 @@ POLKIT_UNIX_SESSION_GET_CLASS
- PolkitUnixProcess
- polkit_unix_process_new
- polkit_unix_process_new_full
-+polkit_unix_process_new_for_owner
-+polkit_unix_process_set_pid
- polkit_unix_process_get_pid
-+polkit_unix_process_set_start_time
- polkit_unix_process_get_start_time
--polkit_unix_process_set_pid
--polkit_unix_process_get_owner
-+polkit_unix_process_set_uid
-+polkit_unix_process_get_uid
- <SUBSECTION Standard>
- PolkitUnixProcessClass
- POLKIT_UNIX_PROCESS
-diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c
-index 577afec..d2c4c20 100644
---- a/src/polkit/polkitsubject.c
-+++ b/src/polkit/polkitsubject.c
-@@ -238,13 +238,18 @@ polkit_subject_from_string  (const gchar   *str,
-     {
-       gint scanned_pid;
-       guint64 scanned_starttime;
--      if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2)
-+      gint scanned_uid;
-+      if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT ":%d", &scanned_pid, &scanned_starttime, &scanned_uid) == 3)
-+        {
-+          subject = polkit_unix_process_new_for_owner (scanned_pid, scanned_starttime, scanned_uid);
-+        }
-+      else if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2)
-         {
-           subject = polkit_unix_process_new_full (scanned_pid, scanned_starttime);
-         }
-       else if (sscanf (str, "unix-process:%d", &scanned_pid) == 1)
-         {
--          subject = polkit_unix_process_new_full (scanned_pid, 0);
-+          subject = polkit_unix_process_new (scanned_pid);
-           if (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) == 0)
-             {
-               g_object_unref (subject);
-@@ -297,6 +302,8 @@ polkit_subject_to_gvariant (PolkitSubject *subject)
-                              g_variant_new_uint32 (polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject))));
-       g_variant_builder_add (&builder, "{sv}", "start-time",
-                              g_variant_new_uint64 (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject))));
-+      g_variant_builder_add (&builder, "{sv}", "uid",
-+                             g_variant_new_int32 (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject))));
-     }
-   else if (POLKIT_IS_UNIX_SESSION (subject))
-     {
-@@ -395,6 +402,7 @@ polkit_subject_new_for_gvariant (GVariant  *variant,
-       GVariant *v;
-       guint32 pid;
-       guint64 start_time;
-+      gint32 uid;
- 
-       v = lookup_asv (details_gvariant, "pid", G_VARIANT_TYPE_UINT32, error);
-       if (v == NULL)
-@@ -414,7 +422,18 @@ polkit_subject_new_for_gvariant (GVariant  *variant,
-       start_time = g_variant_get_uint64 (v);
-       g_variant_unref (v);
- 
--      ret = polkit_unix_process_new_full (pid, start_time);
-+      v = lookup_asv (details_gvariant, "uid", G_VARIANT_TYPE_INT32, error);
-+      if (v != NULL)
-+        {
-+          uid = g_variant_get_int32 (v);
-+          g_variant_unref (v);
-+        }
-+      else
-+        {
-+          uid = -1;
-+        }
-+
-+      ret = polkit_unix_process_new_for_owner (pid, start_time, uid);
-     }
-   else if (g_strcmp0 (kind, "unix-session") == 0)
-     {
-diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
-index 876da69..913be3a 100644
---- a/src/polkit/polkitunixprocess.c
-+++ b/src/polkit/polkitunixprocess.c
-@@ -62,6 +62,7 @@ struct _PolkitUnixProcess
- 
-   gint pid;
-   guint64 start_time;
-+  gint uid;
- };
- 
- struct _PolkitUnixProcessClass
-@@ -74,6 +75,7 @@ enum
-   PROP_0,
-   PROP_PID,
-   PROP_START_TIME,
-+  PROP_UID
- };
- 
- static void subject_iface_init (PolkitSubjectIface *subject_iface);
-@@ -81,6 +83,9 @@ static void subject_iface_init (PolkitSubjectIface *subject_iface);
- static guint64 get_start_time_for_pid (gint    pid,
-                                        GError **error);
- 
-+static gint _polkit_unix_process_get_owner (PolkitUnixProcess  *process,
-+                                            GError            **error);
-+
- #ifdef HAVE_FREEBSD
- static gboolean get_kinfo_proc (gint pid, struct kinfo_proc *p);
- #endif
-@@ -92,6 +97,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixProcess, polkit_unix_process, G_TYPE_OBJECT,
- static void
- polkit_unix_process_init (PolkitUnixProcess *unix_process)
- {
-+  unix_process->uid = -1;
- }
- 
- static void
-@@ -108,6 +114,10 @@ polkit_unix_process_get_property (GObject    *object,
-       g_value_set_int (value, unix_process->pid);
-       break;
- 
-+    case PROP_UID:
-+      g_value_set_int (value, unix_process->uid);
-+      break;
-+
-     case PROP_START_TIME:
-       g_value_set_uint64 (value, unix_process->start_time);
-       break;
-@@ -132,6 +142,14 @@ polkit_unix_process_set_property (GObject      *object,
-       polkit_unix_process_set_pid (unix_process, g_value_get_int (value));
-       break;
- 
-+    case PROP_UID:
-+      polkit_unix_process_set_uid (unix_process, g_value_get_int (value));
-+      break;
-+
-+    case PROP_START_TIME:
-+      polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value));
-+      break;
-+
-     default:
-       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-       break;
-@@ -139,12 +157,39 @@ polkit_unix_process_set_property (GObject      *object,
- }
- 
- static void
-+polkit_unix_process_constructed (GObject *object)
-+{
-+  PolkitUnixProcess *process = POLKIT_UNIX_PROCESS (object);
-+
-+  /* sets start_time and uid in case they are unset */
-+
-+  if (process->start_time == 0)
-+    process->start_time = get_start_time_for_pid (process->pid, NULL);
-+
-+  if (process->uid == -1)
-+    {
-+      GError *error;
-+      error = NULL;
-+      process->uid = _polkit_unix_process_get_owner (process, &error);
-+      if (error != NULL)
-+        {
-+          process->uid = -1;
-+          g_error_free (error);
-+        }
-+    }
-+
-+  if (G_OBJECT_CLASS (polkit_unix_process_parent_class)->constructed != NULL)
-+    G_OBJECT_CLASS (polkit_unix_process_parent_class)->constructed (object);
-+}
-+
-+static void
- polkit_unix_process_class_init (PolkitUnixProcessClass *klass)
- {
-   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- 
-   gobject_class->get_property = polkit_unix_process_get_property;
-   gobject_class->set_property = polkit_unix_process_set_property;
-+  gobject_class->constructed =  polkit_unix_process_constructed;
- 
-   /**
-    * PolkitUnixProcess:pid:
-@@ -156,7 +201,7 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass)
-                                    g_param_spec_int ("pid",
-                                                      "Process ID",
-                                                      "The UNIX process ID",
--                                                     -1,
-+                                                     0,
-                                                      G_MAXINT,
-                                                      0,
-                                                      G_PARAM_CONSTRUCT |
-@@ -166,6 +211,27 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass)
-                                                      G_PARAM_STATIC_NICK));
- 
-   /**
-+   * PolkitUnixProcess:uid:
-+   *
-+   * The UNIX user id of the process or -1 if unknown.
-+   *
-+   * Note that this is the real user-id, not the effective user-id.
-+   */
-+  g_object_class_install_property (gobject_class,
-+                                   PROP_UID,
-+                                   g_param_spec_int ("uid",
-+                                                     "User ID",
-+                                                     "The UNIX user ID",
-+                                                     -1,
-+                                                     G_MAXINT,
-+                                                     -1,
-+                                                     G_PARAM_CONSTRUCT |
-+                                                     G_PARAM_READWRITE |
-+                                                     G_PARAM_STATIC_NAME |
-+                                                     G_PARAM_STATIC_BLURB |
-+                                                     G_PARAM_STATIC_NICK));
-+
-+  /**
-    * PolkitUnixProcess:start-time:
-    *
-    * The start time of the process.
-@@ -178,7 +244,8 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass)
-                                                         0,
-                                                         G_MAXUINT64,
-                                                         0,
--                                                        G_PARAM_READABLE |
-+                                                        G_PARAM_CONSTRUCT |
-+                                                        G_PARAM_READWRITE |
-                                                         G_PARAM_STATIC_NAME |
-                                                         G_PARAM_STATIC_BLURB |
-                                                         G_PARAM_STATIC_NICK));
-@@ -186,113 +253,50 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass)
- }
- 
- /**
-- * polkit_unix_process_get_pid:
-+ * polkit_unix_process_get_uid:
-  * @process: A #PolkitUnixProcess.
-  *
-- * Gets the process id for @process.
-+ * Gets the user id for @process. Note that this is the real user-id,
-+ * not the effective user-id.
-  *
-- * Returns: The process id for @process.
-+ * Returns: The user id for @process or -1 if unknown.
-  */
- gint
--polkit_unix_process_get_pid (PolkitUnixProcess *process)
-+polkit_unix_process_get_uid (PolkitUnixProcess *process)
- {
--  g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
--  return process->pid;
-+  g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), -1);
-+  return process->uid;
- }
- 
- /**
-- * polkit_unix_process_get_owner:
-+ * polkit_unix_process_set_uid:
-  * @process: A #PolkitUnixProcess.
-- * @error: (allow-none): Return location for error or %NULL.
-+ * @uid: The user id to set for @process or -1 to unset it.
-  *
-- * Gets the uid of the owner of @process.
-+ * Sets the (real, not effective) user id for @process.
-+ */
-+void
-+polkit_unix_process_set_uid (PolkitUnixProcess *process,
-+                             gint               uid)
-+{
-+  g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process));
-+  g_return_if_fail (uid >= -1);
-+  process->uid = uid;
-+}
-+
-+/**
-+ * polkit_unix_process_get_pid:
-+ * @process: A #PolkitUnixProcess.
-  *
-- * Note that this returns the real user-id (not the effective user-id) of @process.
-+ * Gets the process id for @process.
-  *
-- * Returns: The UNIX user id of the owner for @process or 0 if @error is set.
-- **/
-+ * Returns: The process id for @process.
-+ */
- gint
--polkit_unix_process_get_owner (PolkitUnixProcess  *process,
--                               GError            **error)
-+polkit_unix_process_get_pid (PolkitUnixProcess *process)
- {
--  gint result;
--  gchar *contents;
--  gchar **lines;
--#ifdef HAVE_FREEBSD
--  struct kinfo_proc p;
--#else
--  gchar filename[64];
--  guint n;
--#endif
--
-   g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
--  g_return_val_if_fail (error == NULL || *error == NULL, 0);
--
--  result = 0;
--  lines = NULL;
--  contents = NULL;
--
--#ifdef HAVE_FREEBSD
--  if (get_kinfo_proc (process->pid, &p) == 0)
--    {
--      g_set_error (error,
--                   POLKIT_ERROR,
--                   POLKIT_ERROR_FAILED,
--                   "get_kinfo_proc() failed for pid %d: %s",
--                   process->pid,
--                   g_strerror (errno));
--      goto out;
--    }
--
--  result = p.ki_uid;
--#else
--
--  /* see 'man proc' for layout of the status file
--   *
--   * Uid, Gid: Real, effective, saved set,  and  file  system  UIDs (GIDs).
--   */
--  g_snprintf (filename, sizeof filename, "/proc/%d/status", process->pid);
--  if (!g_file_get_contents (filename,
--                            &contents,
--                            NULL,
--                            error))
--    {
--      goto out;
--    }
--  lines = g_strsplit (contents, "\n", -1);
--  for (n = 0; lines != NULL && lines[n] != NULL; n++)
--    {
--      gint real_uid, effective_uid;
--      if (!g_str_has_prefix (lines[n], "Uid:"))
--        continue;
--      if (sscanf (lines[n] + 4, "%d %d", &real_uid, &effective_uid) != 2)
--        {
--          g_set_error (error,
--                       POLKIT_ERROR,
--                       POLKIT_ERROR_FAILED,
--                       "Unexpected line `%s' in file %s",
--                       lines[n],
--                       filename);
--          goto out;
--        }
--      else
--        {
--          result = real_uid;
--          goto out;
--        }
--    }
--
--  g_set_error (error,
--               POLKIT_ERROR,
--               POLKIT_ERROR_FAILED,
--               "Didn't find any line starting with `Uid:' in file %s",
--               filename);
--#endif
--
--out:
--  g_strfreev (lines);
--  g_free (contents);
--  return result;
-+  return process->pid;
- }
- 
- /**
-@@ -311,6 +315,21 @@ polkit_unix_process_get_start_time (PolkitUnixProcess *process)
- }
- 
- /**
-+ * polkit_unix_process_set_start_time:
-+ * @process: A #PolkitUnixProcess.
-+ * @start_time: The start time for @pid.
-+ *
-+ * Set the start time of @process.
-+ */
-+void
-+polkit_unix_process_set_start_time (PolkitUnixProcess *process,
-+                                    guint64            start_time)
-+{
-+  g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process));
-+  process->start_time = start_time;
-+}
-+
-+/**
-  * polkit_unix_process_set_pid:
-  * @process: A #PolkitUnixProcess.
-  * @pid: A process id.
-@@ -323,18 +342,17 @@ polkit_unix_process_set_pid (PolkitUnixProcess *process,
- {
-   g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process));
-   process->pid = pid;
--  if (pid != (gint) -1)
--    process->start_time = get_start_time_for_pid (pid, NULL);
- }
- 
- /**
-  * polkit_unix_process_new:
-  * @pid: The process id.
-  *
-- * Creates a new #PolkitUnixProcess for @pid. The start time of the
-- * process will be looked up in using e.g. the
-- * <filename>/proc</filename> filesystem depending on the platform in
-- * use.
-+ * Creates a new #PolkitUnixProcess for @pid.
-+ *
-+ * The uid and start time of the process will be looked up in using
-+ * e.g. the <filename>/proc</filename> filesystem depending on the
-+ * platform in use.
-  *
-  * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref().
-  */
-@@ -353,22 +371,42 @@ polkit_unix_process_new (gint pid)
-  *
-  * Creates a new #PolkitUnixProcess object for @pid and @start_time.
-  *
-+ * The uid of the process will be looked up in using e.g. the
-+ * <filename>/proc</filename> filesystem depending on the platform in
-+ * use.
-+ *
-  * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref().
-  */
- PolkitSubject *
- polkit_unix_process_new_full (gint pid,
-                               guint64 start_time)
- {
--  PolkitUnixProcess *process;
--
--  process = POLKIT_UNIX_PROCESS (polkit_unix_process_new ((gint) -1));
--  process->pid = pid;
--  if (start_time != 0)
--    process->start_time = start_time;
--  else
--    process->start_time = get_start_time_for_pid (pid, NULL);
-+  return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_UNIX_PROCESS,
-+                                       "pid", pid,
-+                                       "start_time", start_time,
-+                                       NULL));
-+}
- 
--  return POLKIT_SUBJECT (process);
-+/**
-+ * polkit_unix_process_new_for_owner:
-+ * @pid: The process id.
-+ * @start_time: The start time for @pid or 0 to look it up in e.g. <filename>/proc</filename>.
-+ * @uid: The (real, not effective) uid of the owner of @pid or -1 to look it up in e.g. <filename>/proc</filename>.
-+ *
-+ * Creates a new #PolkitUnixProcess object for @pid, @start_time and @uid.
-+ *
-+ * Returns: (transfer full): A #PolkitSubject. Free with g_object_unref().
-+ */
-+PolkitSubject *
-+polkit_unix_process_new_for_owner (gint    pid,
-+                                   guint64 start_time,
-+                                   gint    uid)
-+{
-+  return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_UNIX_PROCESS,
-+                                       "pid", pid,
-+                                       "start_time", start_time,
-+                                       "uid", uid,
-+                                       NULL));
- }
- 
- static guint
-@@ -616,3 +654,95 @@ out:
- 
-   return start_time;
- }
-+
-+static gint
-+_polkit_unix_process_get_owner (PolkitUnixProcess  *process,
-+                                GError            **error)
-+{
-+  gint result;
-+  gchar *contents;
-+  gchar **lines;
-+#ifdef HAVE_FREEBSD
-+  struct kinfo_proc p;
-+#else
-+  gchar filename[64];
-+  guint n;
-+#endif
-+
-+  g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
-+  g_return_val_if_fail (error == NULL || *error == NULL, 0);
-+
-+  result = 0;
-+  lines = NULL;
-+  contents = NULL;
-+
-+#ifdef HAVE_FREEBSD
-+  if (get_kinfo_proc (process->pid, &p) == 0)
-+    {
-+      g_set_error (error,
-+                   POLKIT_ERROR,
-+                   POLKIT_ERROR_FAILED,
-+                   "get_kinfo_proc() failed for pid %d: %s",
-+                   process->pid,
-+                   g_strerror (errno));
-+      goto out;
-+    }
-+
-+  result = p.ki_uid;
-+#else
-+
-+  /* see 'man proc' for layout of the status file
-+   *
-+   * Uid, Gid: Real, effective, saved set,  and  file  system  UIDs (GIDs).
-+   */
-+  g_snprintf (filename, sizeof filename, "/proc/%d/status", process->pid);
-+  if (!g_file_get_contents (filename,
-+                            &contents,
-+                            NULL,
-+                            error))
-+    {
-+      goto out;
-+    }
-+  lines = g_strsplit (contents, "\n", -1);
-+  for (n = 0; lines != NULL && lines[n] != NULL; n++)
-+    {
-+      gint real_uid, effective_uid;
-+      if (!g_str_has_prefix (lines[n], "Uid:"))
-+        continue;
-+      if (sscanf (lines[n] + 4, "%d %d", &real_uid, &effective_uid) != 2)
-+        {
-+          g_set_error (error,
-+                       POLKIT_ERROR,
-+                       POLKIT_ERROR_FAILED,
-+                       "Unexpected line `%s' in file %s",
-+                       lines[n],
-+                       filename);
-+          goto out;
-+        }
-+      else
-+        {
-+          result = real_uid;
-+          goto out;
-+        }
-+    }
-+
-+  g_set_error (error,
-+               POLKIT_ERROR,
-+               POLKIT_ERROR_FAILED,
-+               "Didn't find any line starting with `Uid:' in file %s",
-+               filename);
-+#endif
-+
-+out:
-+  g_strfreev (lines);
-+  g_free (contents);
-+  return result;
-+}
-+
-+/* deprecated public method */
-+gint
-+polkit_unix_process_get_owner (PolkitUnixProcess  *process,
-+                               GError            **error)
-+{
-+  return _polkit_unix_process_get_owner (process, error);
-+}
-diff --git a/src/polkit/polkitunixprocess.h b/src/polkit/polkitunixprocess.h
-index b88cd03..531a57d 100644
---- a/src/polkit/polkitunixprocess.h
-+++ b/src/polkit/polkitunixprocess.h
-@@ -47,16 +47,24 @@ typedef struct _PolkitUnixProcess PolkitUnixProcess;
- typedef struct _PolkitUnixProcessClass PolkitUnixProcessClass;
- 
- GType           polkit_unix_process_get_type       (void) G_GNUC_CONST;
--PolkitSubject  *polkit_unix_process_new            (gint pid);
--PolkitSubject  *polkit_unix_process_new_full       (gint pid,
--                                                    guint64 start_time);
--
-+PolkitSubject  *polkit_unix_process_new            (gint               pid);
-+PolkitSubject  *polkit_unix_process_new_full       (gint               pid,
-+                                                    guint64            start_time);
-+PolkitSubject  *polkit_unix_process_new_for_owner  (gint               pid,
-+                                                    guint64            start_time,
-+                                                    gint               uid);
- gint            polkit_unix_process_get_pid        (PolkitUnixProcess *process);
- guint64         polkit_unix_process_get_start_time (PolkitUnixProcess *process);
-+gint            polkit_unix_process_get_uid        (PolkitUnixProcess *process);
- void            polkit_unix_process_set_pid        (PolkitUnixProcess *process,
-                                                     gint               pid);
-+void            polkit_unix_process_set_uid        (PolkitUnixProcess *process,
-+                                                    gint               uid);
-+void            polkit_unix_process_set_start_time (PolkitUnixProcess *process,
-+                                                    guint64            start_time);
-+
- gint            polkit_unix_process_get_owner      (PolkitUnixProcess  *process,
--                                                    GError            **error);
-+                                                    GError            **error) G_GNUC_DEPRECATED_FOR (polkit_unix_process_get_uid);
- 
- G_END_DECLS
- 
---
-cgit v0.8.3-6-g21f6
-From c23d74447c7615dc74dae259f0fc3688ec988867 Mon Sep 17 00:00:00 2001
-From: David Zeuthen <davidz@redhat.com>
-Date: Fri, 01 Apr 2011 16:12:27 +0000
-Subject: Use polkit_unix_process_get_uid() to get the owner of a process
-
-This avoids a TOCTTOU problem.
-
-Signed-off-by: David Zeuthen <davidz@redhat.com>
----
-diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c
-index 495f752..9c331b6 100644
---- a/src/polkitbackend/polkitbackendsessionmonitor.c
-+++ b/src/polkitbackend/polkitbackendsessionmonitor.c
-@@ -293,14 +293,15 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor
- 
-   if (POLKIT_IS_UNIX_PROCESS (subject))
-     {
--      local_error = NULL;
--      uid = polkit_unix_process_get_owner (POLKIT_UNIX_PROCESS (subject), &local_error);
--      if (local_error != NULL)
-+      uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject));
-+      if ((gint) uid == -1)
-         {
--          g_propagate_prefixed_error (error, local_error, "Error getting user for process: ");
-+          g_set_error (error,
-+                       POLKIT_ERROR,
-+                       POLKIT_ERROR_FAILED,
-+                       "Unix process subject does not have uid set");
-           goto out;
-         }
--
-       ret = polkit_unix_user_new (uid);
-     }
-   else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
---
-cgit v0.8.3-6-g21f6
-From 3b12cfac29dddd27f1f166a7574d8374cc1dccf2 Mon Sep 17 00:00:00 2001
-From: David Zeuthen <davidz@redhat.com>
-Date: Fri, 01 Apr 2011 16:13:15 +0000
-Subject: pkexec: Avoid TOCTTOU problems with parent process
-
-In a nutshell, the parent process may change its uid (either real- or
-effective uid) after launching pkexec. It can do this by exec()'ing
-e.g. a setuid root program.
-
-To avoid this problem, just use the uid the parent process had when it
-executed pkexec. This happens to be the same uid of the pkexec process
-itself.
-
-Additionally, remove some dubious code that allowed pkexec to continue
-when the parent process died as there is no reason to support
-something like that. Also ensure that the pkexec process is killed if
-the parent process dies.
-
-This problem was pointed out by Neel Mehta <nmehta@google.com>.
-
-Signed-off-by: David Zeuthen <davidz@redhat.com>
----
-diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
-index 9217954..3e656be 100644
---- a/src/programs/pkexec.c
-+++ b/src/programs/pkexec.c
-@@ -35,6 +35,10 @@
- #include <pwd.h>
- #include <errno.h>
- 
-+#ifdef __linux__
-+#include <sys/prctl.h>
-+#endif
-+
- #include <glib/gi18n.h>
- 
- #ifdef POLKIT_AUTHFW_PAM
-@@ -423,7 +427,6 @@ main (int argc, char *argv[])
-   GPtrArray *saved_env;
-   gchar *opt_user;
-   pid_t pid_of_caller;
--  uid_t uid_of_caller;
-   gpointer local_agent_handle;
- 
-   ret = 127;
-@@ -598,40 +601,49 @@ main (int argc, char *argv[])
-    */
-   g_type_init ();
- 
--  /* now check if the program that invoked us is authorized */
-+  /* make sure we are nuked if the parent process dies */
-+#ifdef __linux__
-+  if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0)
-+    {
-+      g_printerr ("prctl(PR_SET_PDEATHSIG, SIGTERM) failed: %s\n", g_strerror (errno));
-+      goto out;
-+    }
-+#else
-+#warning "Please add OS specific code to catch when the parent dies"
-+#endif
-+
-+  /* Figure out the parent process */
-   pid_of_caller = getppid ();
-   if (pid_of_caller == 1)
-     {
-       /* getppid() can return 1 if the parent died (meaning that we are reaped
--       * by /sbin/init); get process group leader instead - for example, this
--       * happens when launching via gnome-panel (alt+f2, then 'pkexec gedit').
-+       * by /sbin/init); In that case we simpy bail.
-        */
--      pid_of_caller = getpgrp ();
--    }
--
--  subject = polkit_unix_process_new (pid_of_caller);
--  if (subject == NULL)
--    {
--      g_printerr ("No such process for pid %d: %s\n", (gint) pid_of_caller, error->message);
--      g_error_free (error);
-+      g_printerr ("Refusing to render service to dead parents.\n");
-       goto out;
-     }
- 
--  /* paranoia: check that the uid of pid_of_caller matches getuid() */
--  error = NULL;
--  uid_of_caller = polkit_unix_process_get_owner (POLKIT_UNIX_PROCESS (subject),
--                                                 &error);
--  if (error != NULL)
--    {
--      g_printerr ("Error determing pid of caller (pid %d): %s\n", (gint) pid_of_caller, error->message);
--      g_error_free (error);
--      goto out;
--    }
--  if (uid_of_caller != getuid ())
--    {
--      g_printerr ("User of caller (%d) does not match our uid (%d)\n", uid_of_caller, getuid ());
--      goto out;
--    }
-+  /* This process we want to check an authorization for is the process
-+   * that launched us - our parent process.
-+   *
-+   * At the time the parent process fork()'ed and exec()'ed us, the
-+   * process had the same real-uid that we have now. So we use this
-+   * real-uid instead of of looking it up to avoid TOCTTOU issues
-+   * (consider the parent process exec()'ing a setuid helper).
-+   *
-+   * On the other hand, the monotonic process start-time is guaranteed
-+   * to never change so it's safe to look that up given only the PID
-+   * since we are guaranteed to be nuked if the parent goes away
-+   * (cf. the prctl(2) call above).
-+   */
-+  subject = polkit_unix_process_new_for_owner (pid_of_caller,
-+                                               0, /* 0 means "look up start-time in /proc" */
-+                                               getuid ());
-+  /* really double-check the invariants guaranteed by the PolkitUnixProcess class */
-+  g_assert (subject != NULL);
-+  g_assert (polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)) == pid_of_caller);
-+  g_assert (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0);
-+  g_assert (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) > 0);
- 
-   error = NULL;
-   authority = polkit_authority_get_sync (NULL /* GCancellable* */, &error);
---
-cgit v0.8.3-6-g21f6
diff --git a/abs/extra/polkit/PKGBUILD b/abs/extra/polkit/PKGBUILD
index 3a55ddc..e86dbbc 100644
--- a/abs/extra/polkit/PKGBUILD
+++ b/abs/extra/polkit/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id$
+# $Id: PKGBUILD 158972 2012-05-13 21:06:37Z jgc $
 # Maintainer: Jan de Groot <jgc@archlinux.org>
 
 pkgname=polkit
-pkgver=0.101
-pkgrel=2
+pkgver=0.105
+pkgrel=1
 pkgdesc="Application development toolkit for controlling system-wide privileges"
 arch=(i686 x86_64)
 license=('LGPL')
@@ -12,21 +12,22 @@ depends=('glib2' 'pam' 'expat')
 makedepends=('intltool' 'gtk-doc' 'gobject-introspection')
 replaces=('policykit')
 options=('!libtool')
-source=(http://hal.freedesktop.org/releases/${pkgname}-${pkgver}.tar.gz
-        CVE-2011-1485.patch
+source=(http://www.freedesktop.org/software/polkit/releases/$pkgname-$pkgver.tar.gz
         polkit.pam)
-md5sums=('f925ac93aba3c072977370c1e27feb7f'
-         '4d858b8ab602614d7db2bc8574f6fd29'
+md5sums=('9c29e1b6c214f0bd6f1d4ee303dfaed9'
          '6564f95878297b954f0572bc1610dd15')
 
 build() {
-  cd "${srcdir}/${pkgname}-${pkgver}"
-  patch -Np1 -i "${srcdir}/CVE-2011-1485.patch"
+  cd $pkgname-$pkgver
   ./configure --prefix=/usr --sysconfdir=/etc \
       --localstatedir=/var --libexecdir=/usr/lib/polkit-1 \
       --disable-static --enable-gtk-doc
   make
-  make DESTDIR="${pkgdir}" install
+}
+
+package() {
+  cd $pkgname-$pkgver
+  make DESTDIR="$pkgdir" install
 
-  install -m644 "${srcdir}/polkit.pam" "${pkgdir}/etc/pam.d/polkit-1"
+  install -m644 "$srcdir/polkit.pam" "$pkgdir/etc/pam.d/polkit-1"
 }
diff --git a/abs/extra/polkit/systemd-fallback.patch b/abs/extra/polkit/systemd-fallback.patch
new file mode 100644
index 0000000..f89ce10
--- /dev/null
+++ b/abs/extra/polkit/systemd-fallback.patch
@@ -0,0 +1,1571 @@
+diff -u -rN polkit-0.104/configure.ac polkit-0.104-systemd-fallback/configure.ac
+--- polkit-0.104/configure.ac	2012-01-03 17:25:49.000000000 +0100
++++ polkit-0.104-systemd-fallback/configure.ac	2012-03-06 15:45:55.275860194 +0100
+@@ -160,14 +160,14 @@
+               [enable_systemd=auto])
+ if test "$enable_systemd" != "no"; then
+   PKG_CHECK_MODULES(SYSTEMD,
+-                    [libsystemd-login],
++                    [libsystemd-login libsystemd-daemon],
+                     have_systemd=yes,
+                     have_systemd=no)
+   if test "$have_systemd" = "yes"; then
+     SESSION_TRACKING=systemd
+   else
+     if test "$enable_systemd" = "yes"; then
+-      AC_MSG_ERROR([systemd support requested but libsystemd-login1 library not found])
++      AC_MSG_ERROR([systemd support requested but systemd libraries not found])
+     fi
+   fi
+ fi
+diff -u -rN polkit-0.104/src/polkit/Makefile.am polkit-0.104-systemd-fallback/src/polkit/Makefile.am
+--- polkit-0.104/src/polkit/Makefile.am	2012-01-03 16:03:47.000000000 +0100
++++ polkit-0.104-systemd-fallback/src/polkit/Makefile.am	2012-03-06 15:19:25.108853325 +0100
+@@ -79,15 +79,8 @@
+ 	polkitimplicitauthorization.c		polkitimplicitauthorization.h		\
+ 	polkittemporaryauthorization.c		polkittemporaryauthorization.h		\
+ 	polkitpermission.c			polkitpermission.h			\
+-        $(NULL)
+-
+-if HAVE_SYSTEMD
+-libpolkit_gobject_1_la_SOURCES += \
+-	polkitunixsession-systemd.c		polkitunixsession.h
+-else
+-libpolkit_gobject_1_la_SOURCES += \
+ 	polkitunixsession.c			polkitunixsession.h
+-endif
++        $(NULL)
+ 
+ libpolkit_gobject_1_la_CFLAGS =                                        	\
+         -D_POLKIT_COMPILATION                                  		\
+diff -u -rN polkit-0.104/src/polkit/polkitunixsession.c polkit-0.104-systemd-fallback/src/polkit/polkitunixsession.c
+--- polkit-0.104/src/polkit/polkitunixsession.c	2011-10-18 19:02:27.000000000 +0200
++++ polkit-0.104-systemd-fallback/src/polkit/polkitunixsession.c	2012-03-06 15:17:29.829788021 +0100
+@@ -23,12 +23,18 @@
+ #  include "config.h"
+ #endif
+ 
++#include <stdlib.h>
+ #include <string.h>
+ #include "polkitunixsession.h"
+ #include "polkitsubject.h"
+ #include "polkiterror.h"
+ #include "polkitprivate.h"
+ 
++#ifdef HAVE_SYSTEMD
++#  include <systemd/sd-daemon.h>
++#  include <systemd/sd-login.h>
++#endif
++
+ /**
+  * SECTION:polkitunixsession
+  * @title: PolkitUnixSession
+@@ -364,34 +370,44 @@
+   PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+   GDBusConnection *connection;
+   GVariant *result;
+-  gboolean ret;
+-
+-  ret = FALSE;
++  gboolean ret = FALSE;
+ 
+-  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.ConsoleKit",           /* name */
+-                                        session->session_id,                    /* object path */
+-                                        "org.freedesktop.ConsoleKit.Session",   /* interface name */
+-                                        "GetUser",                              /* method */
+-                                        NULL, /* parameters */
+-                                        G_VARIANT_TYPE ("(u)"),
+-                                        G_DBUS_CALL_FLAGS_NONE,
+-                                        -1,
+-                                        cancellable,
+-                                        error);
+-  if (result == NULL)
+-    goto out;
++#ifdef HAVE_SYSTEMD
++  uid_t uid;
++  
++  if (sd_booted () > 0)
++    {
++      if (sd_session_get_uid (session->session_id, &uid) == 0)
++        ret = TRUE;
++    }
++  else
++#endif
++    {
++      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.ConsoleKit",           /* name */
++                                            session->session_id,                    /* object path */
++                                            "org.freedesktop.ConsoleKit.Session",   /* interface name */
++                                            "GetUser",                              /* method */
++                                            NULL, /* parameters */
++                                            G_VARIANT_TYPE ("(u)"),
++                                            G_DBUS_CALL_FLAGS_NONE,
++                                            -1,
++                                            cancellable,
++                                            error);
++      if (result == NULL)
++        goto out;
+ 
+-  ret = TRUE;
+-  g_variant_unref (result);
++      ret = TRUE;
++      g_variant_unref (result);
+ 
+- out:
+-  if (connection != NULL)
+-    g_object_unref (connection);
++     out:
++      if (connection != NULL)
++        g_object_unref (connection);
++    }
+   return ret;
+ }
+ 
+@@ -470,12 +486,9 @@
+                                    GError       **error)
+ {
+   PolkitUnixSession *session = POLKIT_UNIX_SESSION (initable);
+-  GDBusConnection *connection;
++  GDBusConnection *connection = NULL;
+   GVariant *result;
+-  gboolean ret;
+-
+-  connection = NULL;
+-  ret = FALSE;
++  gboolean ret = FALSE;
+ 
+   if (session->session_id != NULL)
+     {
+@@ -484,33 +497,56 @@
+       goto out;
+     }
+ 
+-  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
+-  if (connection == NULL)
+-    goto out;
++#ifdef HAVE_SYSTEMD
++  char *s;
++  
++  if (sd_booted () > 0)
++    {
++      if (sd_pid_get_session (session->pid, &s) == 0)
++        {
++          session->session_id = g_strdup (s);
++          free (s);
++          ret = TRUE;
++          goto out;
++        }
++      
++      g_set_error (error,
++                   POLKIT_ERROR,
++                   POLKIT_ERROR_FAILED,
++                   "No session for pid %d",
++                   (gint) session->pid);
++    }
++  else
++#endif
++    { 
++      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.ConsoleKit",           /* name */
++                                            "/org/freedesktop/ConsoleKit/Manager",  /* object path */
++                                            "org.freedesktop.ConsoleKit.Manager",   /* interface name */
++                                            "GetSessionForUnixProcess",             /* method */
++                                            g_variant_new ("(u)", session->pid),    /* parameters */
++                                            G_VARIANT_TYPE ("(o)"),
++                                            G_DBUS_CALL_FLAGS_NONE,
++                                            -1,
++                                            cancellable,
++                                            error);
++      if (result == NULL)
++        goto out;
+ 
+-  result = g_dbus_connection_call_sync (connection,
+-                                        "org.freedesktop.ConsoleKit",           /* name */
+-                                        "/org/freedesktop/ConsoleKit/Manager",  /* object path */
+-                                        "org.freedesktop.ConsoleKit.Manager",   /* interface name */
+-                                        "GetSessionForUnixProcess",             /* method */
+-                                        g_variant_new ("(u)", session->pid),    /* parameters */
+-                                        G_VARIANT_TYPE ("(o)"),
+-                                        G_DBUS_CALL_FLAGS_NONE,
+-                                        -1,
+-                                        cancellable,
+-                                        error);
+-  if (result == NULL)
+-    goto out;
++      g_variant_get (result, "(o)", &session->session_id);
++      g_variant_unref (result);
+ 
+-  g_variant_get (result, "(o)", &session->session_id);
+-  g_variant_unref (result);
++      ret = TRUE;
++    }
+ 
+-  ret = TRUE;
+ 
+  out:
+   if (connection != NULL)
+     g_object_unref (connection);
+-
+   return ret;
+ }
+ 
+diff -u -rN polkit-0.104/src/polkit/polkitunixsession-systemd.c polkit-0.104-systemd-fallback/src/polkit/polkitunixsession-systemd.c
+--- polkit-0.104/src/polkit/polkitunixsession-systemd.c	2012-01-03 16:03:47.000000000 +0100
++++ polkit-0.104-systemd-fallback/src/polkit/polkitunixsession-systemd.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,481 +0,0 @@
+-/*
+- * Copyright (C) 2011 Red Hat, Inc.
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Lesser General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General
+- * Public License along with this library; if not, write to the
+- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- * Boston, MA 02111-1307, USA.
+- *
+- * Author: Matthias Clasen
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#  include "config.h"
+-#endif
+-
+-#include <string.h>
+-#include "polkitunixsession.h"
+-#include "polkitsubject.h"
+-#include "polkiterror.h"
+-#include "polkitprivate.h"
+-
+-#include <systemd/sd-login.h>
+-
+-/**
+- * SECTION:polkitunixsession
+- * @title: PolkitUnixSession
+- * @short_description: Unix sessions
+- *
+- * An object that represents an user session.
+- *
+- * The session id is an opaque string obtained from ConsoleKit.
+- */
+-
+-/**
+- * PolkitUnixSession:
+- *
+- * The #PolkitUnixSession struct should not be accessed directly.
+- */
+-struct _PolkitUnixSession
+-{
+-  GObject parent_instance;
+-
+-  gchar *session_id;
+-
+-  gint pid;
+-};
+-
+-struct _PolkitUnixSessionClass
+-{
+-  GObjectClass parent_class;
+-};
+-
+-enum
+-{
+-  PROP_0,
+-  PROP_SESSION_ID,
+-  PROP_PID,
+-};
+-
+-static void subject_iface_init        (PolkitSubjectIface *subject_iface);
+-static void initable_iface_init       (GInitableIface *initable_iface);
+-static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
+-
+-G_DEFINE_TYPE_WITH_CODE (PolkitUnixSession, polkit_unix_session, G_TYPE_OBJECT,
+-                         G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, subject_iface_init)
+-                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
+-                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
+-                         );
+-
+-static void
+-polkit_unix_session_init (PolkitUnixSession *session)
+-{
+-}
+-
+-static void
+-polkit_unix_session_finalize (GObject *object)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (object);
+-
+-  g_free (session->session_id);
+-
+-  if (G_OBJECT_CLASS (polkit_unix_session_parent_class)->finalize != NULL)
+-    G_OBJECT_CLASS (polkit_unix_session_parent_class)->finalize (object);
+-}
+-
+-static void
+-polkit_unix_session_get_property (GObject    *object,
+-                                  guint       prop_id,
+-                                  GValue     *value,
+-                                  GParamSpec *pspec)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (object);
+-
+-  switch (prop_id)
+-    {
+-    case PROP_SESSION_ID:
+-      g_value_set_string (value, session->session_id);
+-      break;
+-
+-    default:
+-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+-      break;
+-    }
+-}
+-
+-static void
+-polkit_unix_session_set_property (GObject      *object,
+-                                  guint         prop_id,
+-                                  const GValue *value,
+-                                  GParamSpec   *pspec)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (object);
+-
+-  switch (prop_id)
+-    {
+-    case PROP_SESSION_ID:
+-      polkit_unix_session_set_session_id (session, g_value_get_string (value));
+-      break;
+-
+-    case PROP_PID:
+-      session->pid = g_value_get_int (value);
+-      break;
+-
+-    default:
+-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+-      break;
+-    }
+-}
+-
+-static void
+-polkit_unix_session_class_init (PolkitUnixSessionClass *klass)
+-{
+-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+-
+-  gobject_class->finalize     = polkit_unix_session_finalize;
+-  gobject_class->get_property = polkit_unix_session_get_property;
+-  gobject_class->set_property = polkit_unix_session_set_property;
+-
+-  /**
+-   * PolkitUnixSession:session-id:
+-   *
+-   * The UNIX session id.
+-   */
+-  g_object_class_install_property (gobject_class,
+-                                   PROP_SESSION_ID,
+-                                   g_param_spec_string ("session-id",
+-                                                        "Session ID",
+-                                                        "The UNIX session ID",
+-                                                        NULL,
+-                                                        G_PARAM_CONSTRUCT |
+-                                                        G_PARAM_READWRITE |
+-                                                        G_PARAM_STATIC_NAME |
+-                                                        G_PARAM_STATIC_BLURB |
+-                                                        G_PARAM_STATIC_NICK));
+-
+-
+-  /**
+-   * PolkitUnixSession:pid:
+-   *
+-   * The UNIX process id to look up the session.
+-   */
+-  g_object_class_install_property (gobject_class,
+-                                   PROP_PID,
+-                                   g_param_spec_int ("pid",
+-                                                     "Process ID",
+-                                                     "Process ID to use for looking up the session",
+-                                                     0,
+-                                                     G_MAXINT,
+-                                                     0,
+-                                                     G_PARAM_CONSTRUCT_ONLY |
+-                                                     G_PARAM_WRITABLE |
+-                                                     G_PARAM_STATIC_NAME |
+-                                                     G_PARAM_STATIC_BLURB |
+-                                                     G_PARAM_STATIC_NICK));
+-
+-}
+-
+-/**
+- * polkit_unix_session_get_session_id:
+- * @session: A #PolkitUnixSession.
+- *
+- * Gets the session id for @session.
+- *
+- * Returns: The session id for @session. Do not free this string, it
+- * is owned by @session.
+- **/
+-const gchar *
+-polkit_unix_session_get_session_id (PolkitUnixSession *session)
+-{
+-  g_return_val_if_fail (POLKIT_IS_UNIX_SESSION (session), NULL);
+-  return session->session_id;
+-}
+-
+-/**
+- * polkit_unix_session_set_session_id:
+- * @session: A #PolkitUnixSession.
+- * @session_id: The session id.
+- *
+- * Sets the session id for @session to @session_id.
+- **/
+-void
+-polkit_unix_session_set_session_id (PolkitUnixSession *session,
+-                                    const gchar       *session_id)
+-{
+-  g_return_if_fail (POLKIT_IS_UNIX_SESSION (session));
+-  /*g_return_if_fail (session_id != NULL);*/
+-  g_free (session->session_id);
+-  session->session_id = g_strdup (session_id);
+-}
+-
+-/**
+- * polkit_unix_session_new:
+- * @session_id: The session id.
+- *
+- * Creates a new #PolkitUnixSession for @session_id.
+- *
+- * Returns: (transfer full): A #PolkitUnixSession. Free with g_object_unref().
+- **/
+-PolkitSubject *
+-polkit_unix_session_new (const gchar *session_id)
+-{
+-  return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_UNIX_SESSION,
+-                                       "session-id", session_id,
+-                                       NULL));
+-}
+-
+-/**
+- * polkit_unix_session_new_for_process:
+- * @pid: The process id of the process to get the session for.
+- * @cancellable: (allow-none): A #GCancellable or %NULL.
+- * @callback: A #GAsyncReadyCallback to call when the request is satisfied
+- * @user_data: The data to pass to @callback.
+- *
+- * Asynchronously creates a new #PolkitUnixSession object for the
+- * process with process id @pid.
+- *
+- * When the operation is finished, @callback will be invoked in the
+- * <link linkend="g-main-context-push-thread-default">thread-default
+- * main loop</link> of the thread you are calling this method
+- * from. You can then call
+- * polkit_unix_session_new_for_process_finish() to get the result of
+- * the operation.
+- *
+- * This method constructs the object asynchronously, for the synchronous and blocking version
+- * use polkit_unix_session_new_for_process_sync().
+- **/
+-void
+-polkit_unix_session_new_for_process (gint                pid,
+-                                     GCancellable       *cancellable,
+-                                     GAsyncReadyCallback callback,
+-                                     gpointer            user_data)
+-{
+-  g_async_initable_new_async (POLKIT_TYPE_UNIX_SESSION,
+-                              G_PRIORITY_DEFAULT,
+-                              cancellable,
+-                              callback,
+-                              user_data,
+-                              "pid", pid,
+-                              NULL);
+-}
+-
+-/**
+- * polkit_unix_session_new_for_process_finish:
+- * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to polkit_unix_session_new_for_process().
+- * @error: (allow-none): Return location for error.
+- *
+- * Finishes constructing a #PolkitSubject for a process id.
+- *
+- * Returns: (transfer full) (allow-none): A #PolkitUnixSession for the @pid passed to
+- *     polkit_unix_session_new_for_process() or %NULL if @error is
+- *     set. Free with g_object_unref().
+- **/
+-PolkitSubject *
+-polkit_unix_session_new_for_process_finish (GAsyncResult   *res,
+-                                            GError        **error)
+-{
+-  GObject *object;
+-  GObject *source_object;
+-
+-  source_object = g_async_result_get_source_object (res);
+-  g_assert (source_object != NULL);
+-
+-  object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
+-                                        res,
+-                                        error);
+-  g_object_unref (source_object);
+-
+-  if (object != NULL)
+-    return POLKIT_SUBJECT (object);
+-  else
+-    return NULL;
+-}
+-
+-
+-/**
+- * polkit_unix_session_new_for_process_sync:
+- * @pid: The process id of the process to get the session for.
+- * @cancellable: (allow-none): A #GCancellable or %NULL.
+- * @error: (allow-none): Return location for error.
+- *
+- * Creates a new #PolkitUnixSession for the process with process id @pid.
+- *
+- * This is a synchronous call - the calling thread is blocked until a
+- * reply is received. For the asynchronous version, see
+- * polkit_unix_session_new_for_process().
+- *
+- * Returns: (allow-none) (transfer full): A #PolkitUnixSession for
+- * @pid or %NULL if @error is set. Free with g_object_unref().
+- **/
+-PolkitSubject *
+-polkit_unix_session_new_for_process_sync (gint           pid,
+-                                          GCancellable  *cancellable,
+-                                          GError       **error)
+-{
+-  return POLKIT_SUBJECT (g_initable_new (POLKIT_TYPE_UNIX_SESSION,
+-                                         cancellable,
+-                                         error,
+-                                         "pid", pid,
+-                                         NULL));
+-}
+-
+-static guint
+-polkit_unix_session_hash (PolkitSubject *subject)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+-
+-  return g_str_hash (session->session_id);
+-}
+-
+-static gboolean
+-polkit_unix_session_equal (PolkitSubject *a,
+-                           PolkitSubject *b)
+-{
+-  PolkitUnixSession *session_a;
+-  PolkitUnixSession *session_b;
+-
+-  session_a = POLKIT_UNIX_SESSION (a);
+-  session_b = POLKIT_UNIX_SESSION (b);
+-
+-  return g_strcmp0 (session_a->session_id, session_b->session_id) == 0;
+-}
+-
+-static gchar *
+-polkit_unix_session_to_string (PolkitSubject *subject)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+-
+-  return g_strdup_printf ("unix-session:%s", session->session_id);
+-}
+-
+-static gboolean
+-polkit_unix_session_exists_sync (PolkitSubject   *subject,
+-                                    GCancellable    *cancellable,
+-                                    GError         **error)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+-  gboolean ret;
+-  uid_t uid;
+-
+-  ret = FALSE;
+-
+-  if (!sd_session_get_uid (session->session_id, &uid))
+-    ret = FALSE;
+-
+-  return ret;
+-}
+-
+-static void
+-exists_in_thread_func (GSimpleAsyncResult *res,
+-                       GObject            *object,
+-                       GCancellable       *cancellable)
+-{
+-  GError *error;
+-  error = NULL;
+-  if (!polkit_unix_session_exists_sync (POLKIT_SUBJECT (object),
+-                                        cancellable,
+-                                        &error))
+-    {
+-      g_simple_async_result_set_from_error (res, error);
+-      g_error_free (error);
+-    }
+-}
+-
+-static void
+-polkit_unix_session_exists (PolkitSubject       *subject,
+-                            GCancellable        *cancellable,
+-                            GAsyncReadyCallback  callback,
+-                            gpointer             user_data)
+-{
+-  GSimpleAsyncResult *simple;
+-
+-  g_return_if_fail (POLKIT_IS_UNIX_SESSION (subject));
+-
+-  simple = g_simple_async_result_new (G_OBJECT (subject),
+-                                      callback,
+-                                      user_data,
+-                                      polkit_unix_session_exists);
+-  g_simple_async_result_run_in_thread (simple,
+-                                       exists_in_thread_func,
+-                                       G_PRIORITY_DEFAULT,
+-                                       cancellable);
+-  g_object_unref (simple);
+-}
+-
+-static gboolean
+-polkit_unix_session_exists_finish (PolkitSubject  *subject,
+-                                      GAsyncResult   *res,
+-                                      GError        **error)
+-{
+-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+-  gboolean ret;
+-
+-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_unix_session_exists);
+-
+-  ret = FALSE;
+-
+-  if (g_simple_async_result_propagate_error (simple, error))
+-    goto out;
+-
+-  ret = g_simple_async_result_get_op_res_gboolean (simple);
+-
+- out:
+-  return ret;
+-}
+-
+-static void
+-subject_iface_init (PolkitSubjectIface *subject_iface)
+-{
+-  subject_iface->hash          = polkit_unix_session_hash;
+-  subject_iface->equal         = polkit_unix_session_equal;
+-  subject_iface->to_string     = polkit_unix_session_to_string;
+-  subject_iface->exists        = polkit_unix_session_exists;
+-  subject_iface->exists_finish = polkit_unix_session_exists_finish;
+-  subject_iface->exists_sync   = polkit_unix_session_exists_sync;
+-}
+-
+-static gboolean
+-polkit_unix_session_initable_init (GInitable     *initable,
+-                                   GCancellable  *cancellable,
+-                                   GError       **error)
+-{
+-  PolkitUnixSession *session = POLKIT_UNIX_SESSION (initable);
+-  gboolean ret;
+-
+-  ret = FALSE;
+-
+-  if (session->session_id != NULL)
+-    {
+-      /* already set, nothing to do */
+-      ret = TRUE;
+-      goto out;
+-    }
+-
+-  if (!sd_pid_get_session (session->pid, &session->session_id))
+-    ret = TRUE;
+-
+-out:
+-  return ret;
+-}
+-
+-static void
+-initable_iface_init (GInitableIface *initable_iface)
+-{
+-  initable_iface->init = polkit_unix_session_initable_init;
+-}
+-
+-static void
+-async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
+-{
+-  /* use default implementation to run GInitable code in a thread */
+-}
+diff -u -rN polkit-0.104/src/polkitbackend/Makefile.am polkit-0.104-systemd-fallback/src/polkitbackend/Makefile.am
+--- polkit-0.104/src/polkitbackend/Makefile.am	2012-01-03 16:03:47.000000000 +0100
++++ polkit-0.104-systemd-fallback/src/polkitbackend/Makefile.am	2012-03-06 15:44:15.380014886 +0100
+@@ -41,15 +41,8 @@
+ 	polkitbackendconfigsource.h		polkitbackendconfigsource.c		\
+ 	polkitbackendactionlookup.h		polkitbackendactionlookup.c		\
+ 	polkitbackendlocalauthorizationstore.h	polkitbackendlocalauthorizationstore.c	\
+-        $(NULL)
+-
+-if HAVE_SYSTEMD
+-libpolkit_backend_1_la_SOURCES += \
+-	polkitbackendsessionmonitor.h		polkitbackendsessionmonitor-systemd.c
+-else
+-libpolkit_backend_1_la_SOURCES += \
+ 	polkitbackendsessionmonitor.h		polkitbackendsessionmonitor.c
+-endif
++        $(NULL)
+ 
+ libpolkit_backend_1_la_CFLAGS =                                        	\
+         -D_POLKIT_COMPILATION                                  		\
+diff -u -rN polkit-0.104/src/polkitbackend/polkitbackendsessionmonitor.c polkit-0.104-systemd-fallback/src/polkitbackend/polkitbackendsessionmonitor.c
+--- polkit-0.104/src/polkitbackend/polkitbackendsessionmonitor.c	2011-10-18 19:02:27.000000000 +0200
++++ polkit-0.104-systemd-fallback/src/polkitbackend/polkitbackendsessionmonitor.c	2012-03-06 15:43:49.353562242 +0100
+@@ -26,6 +26,12 @@
+ #include <string.h>
+ #include <glib/gstdio.h>
+ 
++#ifdef HAVE_SYSTEMD
++#  include <systemd/sd-daemon.h>
++#  include <systemd/sd-login.h>
++#  include <stdlib.h>
++#endif
++
+ #include <polkit/polkit.h>
+ #include "polkitbackendsessionmonitor.h"
+ 
+@@ -39,6 +45,88 @@
+  * The #PolkitBackendSessionMonitor class is a utility class to track and monitor sessions.
+  */
+ 
++#ifdef HAVE_SYSTEMD
++typedef struct
++{
++  GSource source;
++  GPollFD pollfd;
++  sd_login_monitor *monitor;
++} SdSource;
++
++static gboolean
++sd_source_prepare (GSource *source,
++                   gint    *timeout)
++{
++  *timeout = -1;
++  return FALSE;
++}
++
++static gboolean
++sd_source_check (GSource *source)
++{
++  SdSource *sd_source = (SdSource *)source;
++
++  return sd_source->pollfd.revents != 0;
++}
++
++static gboolean
++sd_source_dispatch (GSource     *source,
++                    GSourceFunc  callback,
++                    gpointer     user_data)
++
++{
++  SdSource *sd_source = (SdSource *)source;
++  gboolean ret;
++
++  g_warn_if_fail (callback != NULL);
++
++  ret = (*callback) (user_data);
++
++  sd_login_monitor_flush (sd_source->monitor);
++
++  return ret;
++}
++
++static void
++sd_source_finalize (GSource *source)
++{
++  SdSource *sd_source = (SdSource*)source;
++
++  sd_login_monitor_unref (sd_source->monitor);
++}
++
++static GSourceFuncs sd_source_funcs = {
++  sd_source_prepare,
++  sd_source_check,
++  sd_source_dispatch,
++  sd_source_finalize
++};
++
++static GSource *
++sd_source_new (void)
++{
++  GSource *source;
++  SdSource *sd_source;
++  int ret;
++
++  source = g_source_new (&sd_source_funcs, sizeof (SdSource));
++  sd_source = (SdSource *)source;
++
++  if ((ret = sd_login_monitor_new (NULL, &sd_source->monitor)) < 0)
++    {
++      g_printerr ("Error getting login monitor: %d", ret);
++    }
++  else
++    {
++      sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor);
++      sd_source->pollfd.events = G_IO_IN;
++      g_source_add_poll (source, &sd_source->pollfd);
++    }
++
++  return source;
++}
++#endif /* HAVE_SYSTEMD */
++
+ struct _PolkitBackendSessionMonitor
+ {
+   GObject parent_instance;
+@@ -48,6 +136,10 @@
+   GKeyFile *database;
+   GFileMonitor *database_monitor;
+   time_t database_mtime;
++  
++#ifdef HAVE_SYSTEMD
++  GSource *sd_source;
++#endif
+ };
+ 
+ struct _PolkitBackendSessionMonitorClass
+@@ -162,6 +254,18 @@
+   g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0);
+ }
+ 
++#ifdef HAVE_SYSTEMD
++static gboolean
++sessions_changed (gpointer user_data)
++{
++  PolkitBackendSessionMonitor *monitor = POLKIT_BACKEND_SESSION_MONITOR (user_data);
++
++  g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0);
++
++  return TRUE;
++}
++#endif
++
+ static void
+ polkit_backend_session_monitor_init (PolkitBackendSessionMonitor *monitor)
+ {
+@@ -176,31 +280,47 @@
+       g_error_free (error);
+     }
+ 
+-  error = NULL;
+-  if (!ensure_database (monitor, &error))
+-    {
+-      g_printerr ("Error loading " CKDB_PATH ": %s", error->message);
+-      g_error_free (error);
+-    }
++#ifdef HAVE_SYSTEMD
++  monitor->sd_source = NULL;
++  
++  if (sd_booted () > 0)
++    {
++      monitor->sd_source = sd_source_new ();
++      g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL);
++      g_source_attach (monitor->sd_source, NULL);
+ 
+-  error = NULL;
+-  file = g_file_new_for_path (CKDB_PATH);
+-  monitor->database_monitor = g_file_monitor_file (file,
+-                                                   G_FILE_MONITOR_NONE,
+-                                                   NULL,
+-                                                   &error);
+-  g_object_unref (file);
+-  if (monitor->database_monitor == NULL)
+-    {
+-      g_printerr ("Error monitoring " CKDB_PATH ": %s", error->message);
+-      g_error_free (error);
++      monitor->database = NULL;
++      monitor->database_monitor = NULL;
+     }
+   else
++#endif
+     {
+-      g_signal_connect (monitor->database_monitor,
+-                        "changed",
+-                        G_CALLBACK (on_file_monitor_changed),
+-                        monitor);
++      error = NULL;
++      if (!ensure_database (monitor, &error))
++        {
++          g_printerr ("Error loading " CKDB_PATH ": %s", error->message);
++          g_error_free (error);
++        }
++
++      error = NULL;
++      file = g_file_new_for_path (CKDB_PATH);
++      monitor->database_monitor = g_file_monitor_file (file,
++                                                       G_FILE_MONITOR_NONE,
++                                                       NULL,
++                                                       &error);
++      g_object_unref (file);
++      if (monitor->database_monitor == NULL)
++        {
++          g_printerr ("Error monitoring " CKDB_PATH ": %s", error->message);
++          g_error_free (error);
++        }
++      else
++        {
++          g_signal_connect (monitor->database_monitor,
++                            "changed",
++                            G_CALLBACK (on_file_monitor_changed),
++                            monitor);
++        }
+     }
+ }
+ 
+@@ -212,6 +332,14 @@
+   if (monitor->system_bus != NULL)
+     g_object_unref (monitor->system_bus);
+ 
++#ifdef HAVE_SYSTEMD
++  if (monitor->sd_source != NULL)
++    {
++      g_source_destroy (monitor->sd_source);
++      g_source_unref (monitor->sd_source);
++    }
++#endif
++
+   if (monitor->database_monitor != NULL)
+     g_object_unref (monitor->database_monitor);
+ 
+@@ -328,22 +456,38 @@
+     }
+   else if (POLKIT_IS_UNIX_SESSION (subject))
+     {
+-      if (!ensure_database (monitor, error))
++#ifdef HAVE_SYSTEMD
++      if (monitor->sd_source != NULL)
+         {
+-          g_prefix_error (error, "Error getting user for session: Error ensuring CK database at " CKDB_PATH ": ");
+-          goto out;
++          if (sd_session_get_uid (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)), &uid) < 0)
++            {
++              g_set_error (error,
++                           POLKIT_ERROR,
++                           POLKIT_ERROR_FAILED,
++                           "Error getting uid for session");
++              goto out;
++            }
+         }
+-
+-      group = g_strdup_printf ("Session %s", polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)));
+-      local_error = NULL;
+-      uid = g_key_file_get_integer (monitor->database, group, "uid", &local_error);
+-      if (local_error != NULL)
++      else
++#endif
+         {
+-          g_propagate_prefixed_error (error, local_error, "Error getting uid using " CKDB_PATH ": ");
++          if (!ensure_database (monitor, error))
++            {
++              g_prefix_error (error, "Error getting user for session: Error ensuring CK database at " CKDB_PATH ": ");
++              goto out;
++            }
++
++          group = g_strdup_printf ("Session %s", polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)));
++          local_error = NULL;
++          uid = g_key_file_get_integer (monitor->database, group, "uid", &local_error);
++          if (local_error != NULL)
++            {
++              g_propagate_prefixed_error (error, local_error, "Error getting uid using " CKDB_PATH ": ");
++              g_free (group);
++              goto out;
++            }
+           g_free (group);
+-          goto out;
+         }
+-      g_free (group);
+ 
+       ret = polkit_unix_user_new (uid);
+     }
+@@ -373,29 +517,46 @@
+ 
+   if (POLKIT_IS_UNIX_PROCESS (subject))
+     {
+-      const gchar *session_id;
+-      GVariant *result;
+-      result = g_dbus_connection_call_sync (monitor->system_bus,
+-                                            "org.freedesktop.ConsoleKit",
+-                                            "/org/freedesktop/ConsoleKit/Manager",
+-                                            "org.freedesktop.ConsoleKit.Manager",
+-                                            "GetSessionForUnixProcess",
+-                                            g_variant_new ("(u)", polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject))),
+-                                            G_VARIANT_TYPE ("(o)"),
+-                                            G_DBUS_CALL_FLAGS_NONE,
+-                                            -1, /* timeout_msec */
+-                                            NULL, /* GCancellable */
+-                                            error);
+-      if (result == NULL)
+-        goto out;
+-      g_variant_get (result, "(&o)", &session_id);
+-      session = polkit_unix_session_new (session_id);
+-      g_variant_unref (result);
++#ifdef HAVE_SYSTEMD
++      if (monitor->sd_source != NULL)
++        {
++          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);
++        }
++      else
++#endif
++        {
++          const gchar *session_id;
++          GVariant *result;
++          result = g_dbus_connection_call_sync (monitor->system_bus,
++                                                "org.freedesktop.ConsoleKit",
++                                                "/org/freedesktop/ConsoleKit/Manager",
++                                                "org.freedesktop.ConsoleKit.Manager",
++                                                "GetSessionForUnixProcess",
++                                                g_variant_new ("(u)", polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject))),
++                                                G_VARIANT_TYPE ("(o)"),
++                                                G_DBUS_CALL_FLAGS_NONE,
++                                                -1, /* timeout_msec */
++                                                NULL, /* GCancellable */
++                                                error);
++          if (result == NULL)
++            goto out;
++          g_variant_get (result, "(&o)", &session_id);
++          session = polkit_unix_session_new (session_id);
++          g_variant_unref (result);
++        }
+     }
+   else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
+     {
+       guint32 pid;
+-      const gchar *session_id;
++      gchar *session_id;
+       GVariant *result;
+ 
+       result = g_dbus_connection_call_sync (monitor->system_bus,
+@@ -414,22 +575,35 @@
+       g_variant_get (result, "(u)", &pid);
+       g_variant_unref (result);
+ 
+-      result = g_dbus_connection_call_sync (monitor->system_bus,
+-                                            "org.freedesktop.ConsoleKit",
+-                                            "/org/freedesktop/ConsoleKit/Manager",
+-                                            "org.freedesktop.ConsoleKit.Manager",
+-                                            "GetSessionForUnixProcess",
+-                                            g_variant_new ("(u)", pid),
+-                                            G_VARIANT_TYPE ("(o)"),
+-                                            G_DBUS_CALL_FLAGS_NONE,
+-                                            -1, /* timeout_msec */
+-                                            NULL, /* GCancellable */
+-                                            error);
+-      if (result == NULL)
+-        goto out;
+-      g_variant_get (result, "(&o)", &session_id);
+-      session = polkit_unix_session_new (session_id);
+-      g_variant_unref (result);
++#ifdef HAVE_SYSTEMD
++      if (monitor->sd_source != NULL)
++        {
++          if (sd_pid_get_session (pid, &session_id) < 0)
++            goto out;
++
++          session = polkit_unix_session_new (session_id);
++          free (session_id);
++        }
++      else
++#endif
++        {
++          result = g_dbus_connection_call_sync (monitor->system_bus,
++                                                "org.freedesktop.ConsoleKit",
++                                                "/org/freedesktop/ConsoleKit/Manager",
++                                                "org.freedesktop.ConsoleKit.Manager",
++                                                "GetSessionForUnixProcess",
++                                                g_variant_new ("(u)", pid),
++                                                G_VARIANT_TYPE ("(o)"),
++                                                G_DBUS_CALL_FLAGS_NONE,
++                                                -1, /* timeout_msec */
++                                                NULL, /* GCancellable */
++                                                error);
++          if (result == NULL)
++            goto out;
++          g_variant_get (result, "(&o)", &session_id);
++          session = polkit_unix_session_new (session_id);
++          g_variant_unref (result);
++        }
+     }
+   else
+     {
+@@ -490,7 +664,22 @@
+ polkit_backend_session_monitor_is_session_local  (PolkitBackendSessionMonitor *monitor,
+                                                   PolkitSubject               *session)
+ {
+-  return get_boolean (monitor, session, "is_local");
++#ifdef HAVE_SYSTEMD
++  if (monitor->sd_source != NULL)
++    {
++      char *seat;
++
++      if (!sd_session_get_seat (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session)), &seat))
++        {
++          free (seat);
++          return TRUE;
++        }
++
++      return FALSE;
++    }
++  else
++#endif
++    return get_boolean (monitor, session, "is_local");
+ }
+ 
+ 
+@@ -498,6 +687,11 @@
+ polkit_backend_session_monitor_is_session_active (PolkitBackendSessionMonitor *monitor,
+                                                   PolkitSubject               *session)
+ {
+-  return get_boolean (monitor, session, "is_active");
++#ifdef HAVE_SYSTEMD
++  if (monitor->sd_source != NULL)
++    return sd_session_is_active (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session)));
++  else
++#endif
++    return get_boolean (monitor, session, "is_active");
+ }
+ 
+diff -u -rN polkit-0.104/src/polkitbackend/polkitbackendsessionmonitor-systemd.c polkit-0.104-systemd-fallback/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
+--- polkit-0.104/src/polkitbackend/polkitbackendsessionmonitor-systemd.c	2012-01-03 16:03:47.000000000 +0100
++++ polkit-0.104-systemd-fallback/src/polkitbackend/polkitbackendsessionmonitor-systemd.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,414 +0,0 @@
+-/*
+- * Copyright (C) 2011 Red Hat, Inc.
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Lesser General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General
+- * Public License along with this library; if not, write to the
+- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- * Boston, MA 02111-1307, USA.
+- *
+- * Author: Matthias Clasen
+- */
+-
+-#include "config.h"
+-#include <errno.h>
+-#include <pwd.h>
+-#include <grp.h>
+-#include <string.h>
+-#include <glib/gstdio.h>
+-#include <systemd/sd-login.h>
+-#include <stdlib.h>
+-
+-#include <polkit/polkit.h>
+-#include "polkitbackendsessionmonitor.h"
+-
+-/* <internal>
+- * SECTION:polkitbackendsessionmonitor
+- * @title: PolkitBackendSessionMonitor
+- * @short_description: Monitor sessions
+- *
+- * The #PolkitBackendSessionMonitor class is a utility class to track and monitor sessions.
+- */
+-
+-typedef struct
+-{
+-  GSource source;
+-  GPollFD pollfd;
+-  sd_login_monitor *monitor;
+-} SdSource;
+-
+-static gboolean
+-sd_source_prepare (GSource *source,
+-                   gint    *timeout)
+-{
+-  *timeout = -1;
+-  return FALSE;
+-}
+-
+-static gboolean
+-sd_source_check (GSource *source)
+-{
+-  SdSource *sd_source = (SdSource *)source;
+-
+-  return sd_source->pollfd.revents != 0;
+-}
+-
+-static gboolean
+-sd_source_dispatch (GSource     *source,
+-                    GSourceFunc  callback,
+-                    gpointer     user_data)
+-
+-{
+-  SdSource *sd_source = (SdSource *)source;
+-  gboolean ret;
+-
+-  g_warn_if_fail (callback != NULL);
+-
+-  ret = (*callback) (user_data);
+-
+-  sd_login_monitor_flush (sd_source->monitor);
+-
+-  return ret;
+-}
+-
+-static void
+-sd_source_finalize (GSource *source)
+-{
+-  SdSource *sd_source = (SdSource*)source;
+-
+-  sd_login_monitor_unref (sd_source->monitor);
+-}
+-
+-static GSourceFuncs sd_source_funcs = {
+-  sd_source_prepare,
+-  sd_source_check,
+-  sd_source_dispatch,
+-  sd_source_finalize
+-};
+-
+-static GSource *
+-sd_source_new (void)
+-{
+-  GSource *source;
+-  SdSource *sd_source;
+-  int ret;
+-
+-  source = g_source_new (&sd_source_funcs, sizeof (SdSource));
+-  sd_source = (SdSource *)source;
+-
+-  if ((ret = sd_login_monitor_new (NULL, &sd_source->monitor)) < 0)
+-    {
+-      g_printerr ("Error getting login monitor: %d", ret);
+-    }
+-  else
+-    {
+-      sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor);
+-      sd_source->pollfd.events = G_IO_IN;
+-      g_source_add_poll (source, &sd_source->pollfd);
+-    }
+-
+-  return source;
+-}
+-
+-struct _PolkitBackendSessionMonitor
+-{
+-  GObject parent_instance;
+-
+-  GDBusConnection *system_bus;
+-
+-  GSource *sd_source;
+-};
+-
+-struct _PolkitBackendSessionMonitorClass
+-{
+-  GObjectClass parent_class;
+-
+-  void (*changed) (PolkitBackendSessionMonitor *monitor);
+-};
+-
+-
+-enum
+-{
+-  CHANGED_SIGNAL,
+-  LAST_SIGNAL,
+-};
+-
+-static guint signals[LAST_SIGNAL] = {0};
+-
+-G_DEFINE_TYPE (PolkitBackendSessionMonitor, polkit_backend_session_monitor, G_TYPE_OBJECT);
+-
+-/* ---------------------------------------------------------------------------------------------------- */
+-
+-static gboolean
+-sessions_changed (gpointer user_data)
+-{
+-  PolkitBackendSessionMonitor *monitor = POLKIT_BACKEND_SESSION_MONITOR (user_data);
+-
+-  g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0);
+-
+-  return TRUE;
+-}
+-
+-
+-static void
+-polkit_backend_session_monitor_init (PolkitBackendSessionMonitor *monitor)
+-{
+-  GError *error;
+-
+-  error = NULL;
+-  monitor->system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+-  if (monitor->system_bus == NULL)
+-    {
+-      g_printerr ("Error getting system bus: %s", error->message);
+-      g_error_free (error);
+-    }
+-
+-  monitor->sd_source = sd_source_new ();
+-  g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL);
+-  g_source_attach (monitor->sd_source, NULL);
+-}
+-
+-static void
+-polkit_backend_session_monitor_finalize (GObject *object)
+-{
+-  PolkitBackendSessionMonitor *monitor = POLKIT_BACKEND_SESSION_MONITOR (object);
+-
+-  if (monitor->system_bus != NULL)
+-    g_object_unref (monitor->system_bus);
+-
+-  if (monitor->sd_source != NULL)
+-    {
+-      g_source_destroy (monitor->sd_source);
+-      g_source_unref (monitor->sd_source);
+-    }
+-
+-  if (G_OBJECT_CLASS (polkit_backend_session_monitor_parent_class)->finalize != NULL)
+-    G_OBJECT_CLASS (polkit_backend_session_monitor_parent_class)->finalize (object);
+-}
+-
+-static void
+-polkit_backend_session_monitor_class_init (PolkitBackendSessionMonitorClass *klass)
+-{
+-  GObjectClass *gobject_class;
+-
+-  gobject_class = G_OBJECT_CLASS (klass);
+-
+-  gobject_class->finalize = polkit_backend_session_monitor_finalize;
+-
+-  /**
+-   * PolkitBackendSessionMonitor::changed:
+-   * @monitor: A #PolkitBackendSessionMonitor
+-   *
+-   * Emitted when something changes.
+-   */
+-  signals[CHANGED_SIGNAL] = g_signal_new ("changed",
+-                                          POLKIT_BACKEND_TYPE_SESSION_MONITOR,
+-                                          G_SIGNAL_RUN_LAST,
+-                                          G_STRUCT_OFFSET (PolkitBackendSessionMonitorClass, changed),
+-                                          NULL,                   /* accumulator      */
+-                                          NULL,                   /* accumulator data */
+-                                          g_cclosure_marshal_VOID__VOID,
+-                                          G_TYPE_NONE,
+-                                          0);
+-}
+-
+-PolkitBackendSessionMonitor *
+-polkit_backend_session_monitor_new (void)
+-{
+-  PolkitBackendSessionMonitor *monitor;
+-
+-  monitor = POLKIT_BACKEND_SESSION_MONITOR (g_object_new (POLKIT_BACKEND_TYPE_SESSION_MONITOR, NULL));
+-
+-  return monitor;
+-}
+-
+-/* ---------------------------------------------------------------------------------------------------- */
+-
+-GList *
+-polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monitor)
+-{
+-  /* TODO */
+-  return NULL;
+-}
+-
+-/* ---------------------------------------------------------------------------------------------------- */
+-
+-/**
+- * polkit_backend_session_monitor_get_user:
+- * @monitor: A #PolkitBackendSessionMonitor.
+- * @subject: A #PolkitSubject.
+- * @error: Return location for error.
+- *
+- * Gets the user corresponding to @subject or %NULL if no user exists.
+- *
+- * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref().
+- */
+-PolkitIdentity *
+-polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor  *monitor,
+-                                                     PolkitSubject                *subject,
+-                                                     GError                      **error)
+-{
+-  PolkitIdentity *ret;
+-  guint32 uid;
+-
+-  ret = NULL;
+-
+-  if (POLKIT_IS_UNIX_PROCESS (subject))
+-    {
+-      uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject));
+-      if ((gint) uid == -1)
+-        {
+-          g_set_error (error,
+-                       POLKIT_ERROR,
+-                       POLKIT_ERROR_FAILED,
+-                       "Unix process subject does not have uid set");
+-          goto out;
+-        }
+-      ret = polkit_unix_user_new (uid);
+-    }
+-  else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
+-    {
+-      GVariant *result;
+-
+-      result = g_dbus_connection_call_sync (monitor->system_bus,
+-                                            "org.freedesktop.DBus",
+-                                            "/org/freedesktop/DBus",
+-                                            "org.freedesktop.DBus",
+-                                            "GetConnectionUnixUser",
+-                                            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)", &uid);
+-      g_variant_unref (result);
+-
+-      ret = polkit_unix_user_new (uid);
+-    }
+-  else if (POLKIT_IS_UNIX_SESSION (subject))
+-    {
+-
+-      if (sd_session_get_uid (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)), &uid) < 0)
+-        {
+-          g_set_error (error,
+-                       POLKIT_ERROR,
+-                       POLKIT_ERROR_FAILED,
+-                       "Error getting uid for session");
+-          goto out;
+-        }
+-
+-      ret = polkit_unix_user_new (uid);
+-    }
+-
+- out:
+-  return ret;
+-}
+-
+-/**
+- * polkit_backend_session_monitor_get_session_for_subject:
+- * @monitor: A #PolkitBackendSessionMonitor.
+- * @subject: A #PolkitSubject.
+- * @error: Return location for error.
+- *
+- * Gets the session corresponding to @subject or %NULL if no session exists.
+- *
+- * Returns: %NULL if @error is set otherwise a #PolkitUnixSession that should be freed with g_object_unref().
+- */
+-PolkitSubject *
+-polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor,
+-                                                        PolkitSubject               *subject,
+-                                                        GError                     **error)
+-{
+-  PolkitSubject *session;
+-
+-  session = NULL;
+-
+-  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);
+-    }
+-  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);
+-    }
+-  else
+-    {
+-      g_set_error (error,
+-                   POLKIT_ERROR,
+-                   POLKIT_ERROR_NOT_SUPPORTED,
+-                   "Cannot get user for subject of type %s",
+-                   g_type_name (G_TYPE_FROM_INSTANCE (subject)));
+-    }
+-
+- out:
+-
+-  return session;
+-}
+-
+-gboolean
+-polkit_backend_session_monitor_is_session_local (PolkitBackendSessionMonitor *monitor,
+-                                                 PolkitSubject               *session)
+-{
+-  char *seat;
+-
+-  if (!sd_session_get_seat (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session)), &seat))
+-    {
+-      free (seat);
+-      return TRUE;
+-    }
+-
+-  return FALSE;
+-}
+-
+-
+-gboolean
+-polkit_backend_session_monitor_is_session_active (PolkitBackendSessionMonitor *monitor,
+-                                                  PolkitSubject               *session)
+-{
+-  return sd_session_is_active (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session)));
+-}
+-
-- 
cgit v0.12

