summaryrefslogtreecommitdiffstats
path: root/abs/extra/polkit
diff options
context:
space:
mode:
authorJames Meyer <james.meyer@operamail.com>2013-02-19 21:10:18 (GMT)
committerJames Meyer <james.meyer@operamail.com>2013-02-19 21:10:18 (GMT)
commit2648e999d277eac5c3d331a3609bcc73fafbea71 (patch)
tree40951fb8e7fdbe28a0baa324ae615055203f1e2e /abs/extra/polkit
parentc759b5e0c4aa6fc37412b4dee2cf9ad993fd376d (diff)
parent7e6f7ca174e1af67178dc5293a312a4a733eb095 (diff)
downloadlinhes_pkgbuild-2648e999d277eac5c3d331a3609bcc73fafbea71.zip
linhes_pkgbuild-2648e999d277eac5c3d331a3609bcc73fafbea71.tar.gz
linhes_pkgbuild-2648e999d277eac5c3d331a3609bcc73fafbea71.tar.bz2
Merge branch 'testing'
# By James Meyer (1091) and others # Via James Meyer (5) and others * testing: (1148 commits) LinHES-config: during install don't kill off lirc. This keeps the remote active all the way to the finish Change version numbers to 8.0 to match the release number. LinHES-conifg LinHES-system mythdb-initial runit-scripts supplemental-web LinHES-conifig: mv_install.py for the last partition don't go all the way to the end. Gotta leave room for gpt tables. xf86-video-ati: xorg ati driver. LinHES-config: timezip.py add syncing up of parental lvl passwords and starting level with MBE. LinHES-system: correct the logic for breaking out of the wmctrl loop. As written it would break out of the inner loop..but not the 60 iteration loop. e16_theme_settings: remove slide-in prop for new windows. For whatever reason this was preventing mplayer from being positioned correctly for appletrailers. LinHES-config, mythinstall: change case of hd_pvr and serial to all lower refs #902 zilog-firmware: firmware for TX support of the hdpvr and pvr-150 In general I can't recommend anybody using these transmitters but including the firmware just in case someone really wants to linhes-udev-rules: added hdprv_lirc rule. All of these lirc rules are limited to exactly one device. If more then one device is present then only the last device in init will get the symlink runit-scripts: fix logging for igdeamon, add support to remote init script so that the blaster is always the first device in the chain. added support specificly for hd_pvr LinHES-system: add lh_system_restore and lh_system_backup. These scripts are called from the mythmenu. refs #900 iguanair: rebuild with python 2.7 LinHES-system: msg_daemon.py fix init and nasty bug related to timeout. In a nutshell timeout wouldn't work unless a msg without a timeout was called first. linhes-udev-rules: add rules for mce,streamzap,serial lirc devices. mythinstall: recompile for matching libs mythtv: latest .25-fixes and change mythbackup/restore call lh_system_$op to replace mythbackup/mythrestore. mythbackup no longer works correctly with the new windowmanager linhes-scripts: myth2mp3, myth2x264, myth2xvid: use mythutil to get cutlist LinHES-config, supplimental-web: Fix proxy numbering for Ceton infiniTV linhes-system: add additional stuff to the system backup and also introduced an exclude file. The exclude/include files are locate in /home/mythtv/backup_config/ ...
Diffstat (limited to 'abs/extra/polkit')
-rw-r--r--abs/extra/polkit/CVE-2011-1485.patch908
-rw-r--r--abs/extra/polkit/PKGBUILD23
-rw-r--r--abs/extra/polkit/systemd-fallback.patch1571
3 files changed, 1583 insertions, 919 deletions
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)));
+-}
+-