summaryrefslogtreecommitdiff
path: root/patches/source/polkit
diff options
context:
space:
mode:
authorPatrick J Volkerding <volkerdi@slackware.com>2018-05-25 23:29:36 +0000
committerEric Hameleers <alien@slackware.com>2018-05-31 15:10:50 -0700
commit329684b59b8d55dd403c2c59f76d37210ba2f517 (patch)
tree10421c6ee3bf179d50915cc00d4c15c1b83cb77a /patches/source/polkit
parentb76270bf9e6dd375e495fec92140a79a79415d27 (diff)
downloadcurrent-329684b59b8d55dd403c2c59f76d37210ba2f517.tar.gz
Fri May 25 23:29:36 UTC 201813.1
patches/packages/glibc-zoneinfo-2018e-noarch-2_slack13.1.txz: Rebuilt. Handle removal of US/Pacific-New timezone. If we see that the machine is using this, it will be automatically switched to US/Pacific.
Diffstat (limited to 'patches/source/polkit')
-rw-r--r--patches/source/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch122
-rw-r--r--patches/source/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch666
-rw-r--r--patches/source/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch41
-rw-r--r--patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch97
-rw-r--r--patches/source/polkit/polkit-1-shadow.diff1030
-rwxr-xr-xpatches/source/polkit/polkit.SlackBuild149
-rw-r--r--patches/source/polkit/slack-desc19
7 files changed, 2124 insertions, 0 deletions
diff --git a/patches/source/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch b/patches/source/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch
new file mode 100644
index 00000000..e448ce95
--- /dev/null
+++ b/patches/source/polkit/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch
@@ -0,0 +1,122 @@
+From 83a65f1255fc3eebfb4be1f80a5ab0b5f98eef7c Mon Sep 17 00:00:00 2001
+From: David Zeuthen <davidz@redhat.com>
+Date: Mon, 11 Apr 2011 11:38:22 -0400
+Subject: [PATCH 1/6] 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>
+---
+ src/polkit/polkitunixprocess.c | 58 ++++++++++++++++++++++++++++++++-------
+ 1 files changed, 47 insertions(+), 11 deletions(-)
+
+diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
+index e132387..868e3c5 100644
+--- a/src/polkit/polkitunixprocess.c
++++ b/src/polkit/polkitunixprocess.c
+@@ -34,6 +34,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
++#include <stdio.h>
+
+ #include "polkitunixprocess.h"
+ #include "polkitsubject.h"
+@@ -207,6 +208,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
+@@ -214,14 +217,18 @@ 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
+
+ result = 0;
++ lines = NULL;
++ contents = NULL;
+
+ #ifdef HAVE_FREEBSD
+ if (get_kinfo_proc (process->pid, &p) == 0)
+@@ -237,22 +244,51 @@ 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:
++ g_strfreev (lines);
++ g_free (contents);
+
+ return result;
+ }
+--
+1.7.4.4
+
diff --git a/patches/source/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch b/patches/source/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch
new file mode 100644
index 00000000..5c70a71e
--- /dev/null
+++ b/patches/source/polkit/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch
@@ -0,0 +1,666 @@
+From 9a44af8ab67d09a2c08be29428b8fe32da809e99 Mon Sep 17 00:00:00 2001
+From: David Zeuthen <davidz@redhat.com>
+Date: Mon, 11 Apr 2011 12:41:00 -0400
+Subject: [PATCH 2/6] 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>
+---
+ docs/polkit/polkit-1-sections.txt | 7 +-
+ src/polkit/polkitsubject.c | 51 ++++--
+ src/polkit/polkitunixprocess.c | 350 +++++++++++++++++++++++++-----------
+ src/polkit/polkitunixprocess.h | 10 +
+ 4 files changed, 296 insertions(+), 122 deletions(-)
+
+diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
+index ac902b6..7f42cd2 100644
+--- a/docs/polkit/polkit-1-sections.txt
++++ b/docs/polkit/polkit-1-sections.txt
+@@ -148,10 +148,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 d5039a5..02c707b 100644
+--- a/src/polkit/polkitsubject.c
++++ b/src/polkit/polkitsubject.c
+@@ -24,6 +24,7 @@
+ #endif
+
+ #include <string.h>
++#include <stdio.h>
+
+ #include "polkitsubject.h"
+ #include "polkitunixprocess.h"
+@@ -209,8 +210,6 @@ polkit_subject_from_string (const gchar *str,
+ GError **error)
+ {
+ PolkitSubject *subject;
+- guint64 val;
+- gchar *endptr;
+
+ g_return_val_if_fail (str != NULL, NULL);
+
+@@ -220,12 +219,20 @@ polkit_subject_from_string (const gchar *str,
+
+ if (g_str_has_prefix (str, "unix-process:"))
+ {
+- val = g_ascii_strtoull (str + sizeof "unix-process:" - 1,
+- &endptr,
+- 10);
+- if (*endptr == '\0')
++ gint scanned_pid;
++ guint64 scanned_starttime;
++ 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 ((gint) val);
++ 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 (scanned_pid);
+ if (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) == 0)
+ {
+ g_object_unref (subject);
+@@ -233,8 +240,8 @@ polkit_subject_from_string (const gchar *str,
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+- "No process with pid %" G_GUINT64_FORMAT,
+- val);
++ "Unable to determine start time for process with pid %d",
++ scanned_pid);
+ }
+ }
+ }
+@@ -268,6 +275,7 @@ polkit_subject_new_for_real (_PolkitSubject *real)
+ EggDBusHashMap *details;
+ EggDBusVariant *variant;
+ EggDBusVariant *variant2;
++ EggDBusVariant *variant3;
+
+ s = NULL;
+
+@@ -281,10 +289,24 @@ polkit_subject_new_for_real (_PolkitSubject *real)
+ else if (strcmp (kind, "unix-process") == 0)
+ {
+ variant = egg_dbus_hash_map_lookup (details, "pid");
+- variant2 = egg_dbus_hash_map_lookup (details, "start-time");
+- if (variant != NULL && variant2 != NULL)
+- s = polkit_unix_process_new_full (egg_dbus_variant_get_uint (variant),
+- egg_dbus_variant_get_uint64 (variant2));
++ if (variant != NULL && egg_dbus_variant_is_uint (variant))
++ {
++ gint pid;
++ guint64 start_time;
++ gint uid;
++ variant2 = egg_dbus_hash_map_lookup (details, "start-time");
++ pid = egg_dbus_variant_get_uint (variant);
++ if (variant2 != NULL && egg_dbus_variant_is_uint64 (variant2))
++ start_time = egg_dbus_variant_get_uint64 (variant2);
++ else
++ start_time = 0;
++ variant3 = egg_dbus_hash_map_lookup (details, "uid");
++ if (variant3 != NULL && egg_dbus_variant_is_int (variant3))
++ uid = egg_dbus_variant_get_int (variant3);
++ else
++ uid = -1;
++ s = polkit_unix_process_new_for_owner (pid, start_time, uid);
++ }
+ }
+ else if (strcmp (kind, "unix-session") == 0)
+ {
+@@ -330,6 +352,9 @@ polkit_subject_get_real (PolkitSubject *subject)
+ egg_dbus_hash_map_insert (details,
+ "start-time",
+ egg_dbus_variant_new_for_uint64 (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject))));
++ egg_dbus_hash_map_insert (details,
++ "uid",
++ egg_dbus_variant_new_for_int (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject))));
+ }
+ else if (POLKIT_IS_UNIX_SESSION (subject))
+ {
+diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
+index 868e3c5..eb455f6 100644
+--- a/src/polkit/polkitunixprocess.c
++++ b/src/polkit/polkitunixprocess.c
+@@ -64,6 +64,7 @@ struct _PolkitUnixProcess
+
+ gint pid;
+ guint64 start_time;
++ gint uid;
+ };
+
+ struct _PolkitUnixProcessClass
+@@ -76,6 +77,7 @@ enum
+ PROP_0,
+ PROP_PID,
+ PROP_START_TIME,
++ PROP_UID
+ };
+
+ static void subject_iface_init (PolkitSubjectIface *subject_iface);
+@@ -83,6 +85,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
+@@ -94,6 +99,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
+@@ -110,6 +116,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;
+@@ -134,6 +144,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;
+@@ -141,12 +159,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:
+@@ -158,7 +203,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 |
+@@ -168,6 +213,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.
+@@ -180,7 +246,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));
+@@ -188,109 +255,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)
+ {
+- 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: 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
+-
+- 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;
++ g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
++ return process->pid;
+ }
+
+ /**
+@@ -304,10 +312,26 @@ polkit_unix_process_get_owner (PolkitUnixProcess *process,
+ guint64
+ polkit_unix_process_get_start_time (PolkitUnixProcess *process)
+ {
++ g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0);
+ return process->start_time;
+ }
+
+ /**
++ * 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.
+@@ -318,21 +342,21 @@ void
+ polkit_unix_process_set_pid (PolkitUnixProcess *process,
+ gint pid)
+ {
++ 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.
+ *
+- * Returns: A #PolkitSubject. Free with g_object_unref().
++ * 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().
+ */
+ PolkitSubject *
+ polkit_unix_process_new (gint pid)
+@@ -349,22 +373,42 @@ polkit_unix_process_new (gint pid)
+ *
+ * Creates a new #PolkitUnixProcess object for @pid and @start_time.
+ *
+- * Returns: A #PolkitSubject. Free with g_object_unref().
++ * 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
+@@ -612,3 +656,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..68c7fd7 100644
+--- a/src/polkit/polkitunixprocess.h
++++ b/src/polkit/polkitunixprocess.h
+@@ -50,11 +50,21 @@ 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_for_owner (gint pid,
++ guint64 start_time,
++ gint uid);
+
+ gint polkit_unix_process_get_pid (PolkitUnixProcess *process);
++gint polkit_unix_process_get_uid (PolkitUnixProcess *process);
+ guint64 polkit_unix_process_get_start_time (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);
++
++G_GNUC_DEPRECATED
+ gint polkit_unix_process_get_owner (PolkitUnixProcess *process,
+ GError **error);
+
+--
+1.7.4.4
+
diff --git a/patches/source/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch b/patches/source/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch
new file mode 100644
index 00000000..b7d53752
--- /dev/null
+++ b/patches/source/polkit/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch
@@ -0,0 +1,41 @@
+From 55e6f92e7340d57a66f83bd69bdf26454fdf7533 Mon Sep 17 00:00:00 2001
+From: David Zeuthen <davidz@redhat.com>
+Date: Mon, 11 Apr 2011 12:41:35 -0400
+Subject: [PATCH 3/6] 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>
+---
+ src/polkitbackend/polkitbackendsessionmonitor.c | 13 ++++++-------
+ 1 files changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c
+index 2028250..d976514 100644
+--- a/src/polkitbackend/polkitbackendsessionmonitor.c
++++ b/src/polkitbackend/polkitbackendsessionmonitor.c
+@@ -418,14 +418,13 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor
+
+ if (POLKIT_IS_UNIX_PROCESS (subject))
+ {
+- GError *local_error;
+-
+- 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_error (error, local_error);
+- g_error_free (local_error);
++ g_set_error (error,
++ POLKIT_ERROR,
++ POLKIT_ERROR_FAILED,
++ "Unix process subject does not have uid set");
+ goto out;
+ }
+ user = polkit_unix_user_new (uid);
+--
+1.7.4.4
+
diff --git a/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch b/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch
new file mode 100644
index 00000000..e17947a9
--- /dev/null
+++ b/patches/source/polkit/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch
@@ -0,0 +1,97 @@
+--- ./src/programs/pkexec.c.orig 2010-03-10 11:46:19.000000000 -0600
++++ ./src/programs/pkexec.c 2011-04-19 23:14:40.505000017 -0500
+@@ -38,6 +38,10 @@
+ #include <syslog.h>
+ #include <stdarg.h>
+
++#ifdef __linux__
++#include <sys/prctl.h>
++#endif
++
+ #include <polkit/polkit.h>
+
+ static gchar *original_user_name = NULL;
+@@ -410,7 +414,6 @@
+ GPtrArray *saved_env;
+ gchar *opt_user;
+ pid_t pid_of_caller;
+- uid_t uid_of_caller;
+
+ ret = 127;
+ authority = NULL;
+@@ -578,40 +581,49 @@
+ */
+ 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);
+
+ authority = polkit_authority_get ();
+
diff --git a/patches/source/polkit/polkit-1-shadow.diff b/patches/source/polkit/polkit-1-shadow.diff
new file mode 100644
index 00000000..56e24277
--- /dev/null
+++ b/patches/source/polkit/polkit-1-shadow.diff
@@ -0,0 +1,1030 @@
+diff --git a/src/polkitagent/Makefile.am b/src/polkitagent/Makefile.am
+index 3f38329..e114d01 100644
+--- a/src/polkitagent/Makefile.am
++++ b/src/polkitagent/Makefile.am
+@@ -68,8 +68,15 @@ libpolkit_agent_1_la_LDFLAGS = -export-symbols-regex '(^polkit_.*)'
+ libexec_PROGRAMS = polkit-agent-helper-1
+
+ polkit_agent_helper_1_SOURCES = \
+- polkitagenthelper.c \
+- $(NULL)
++ polkitagenthelperprivate.c polkitagenthelperprivate.h
++
++if POLKIT_AUTHFW_PAM
++polkit_agent_helper_1_SOURCES += polkitagenthelper-pam.c
++endif
++if POLKIT_AUTHFW_SHADOW
++polkit_agent_helper_1_SOURCES += polkitagenthelper-shadow.c
++endif
++polkit_agent_helper_1_SOURCES += $(NULL)
+
+ polkit_agent_helper_1_CFLAGS = \
+ -D_POLKIT_COMPILATION \
+diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c
+new file mode 100644
+index 0000000..4c6c6fb
+--- /dev/null
++++ b/src/polkitagent/polkitagenthelper-pam.c
+@@ -0,0 +1,264 @@
++/*
++ * Copyright (C) 2008, 2010 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: David Zeuthen <davidz@redhat.com>
++ */
++
++#include "config.h"
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <syslog.h>
++#include <security/pam_appl.h>
++
++#include <polkit/polkit.h>
++#include "polkitagenthelperprivate.h"
++
++static int conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data);
++
++int
++main (int argc, char *argv[])
++{
++ int rc;
++ const char *user_to_auth;
++ const char *cookie;
++ struct pam_conv pam_conversation;
++ pam_handle_t *pam_h;
++ const void *authed_user;
++
++ rc = 0;
++ pam_h = NULL;
++
++ /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
++ if (clearenv () != 0)
++ goto error;
++
++ /* set a minimal environment */
++ setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
++
++ /* check that we are setuid root */
++ if (geteuid () != 0)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: needs to be setuid root\n");
++ goto error;
++ }
++
++ openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
++
++ /* check for correct invocation */
++ if (argc != 3)
++ {
++ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
++ fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
++ goto error;
++ }
++
++ user_to_auth = argv[1];
++ cookie = argv[2];
++
++ if (getuid () != 0)
++ {
++ /* check we're running with a non-tty stdin */
++ if (isatty (STDIN_FILENO) != 0)
++ {
++ syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
++ fprintf (stderr, "polkit-agent-helper-1: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
++ goto error;
++ }
++ }
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
++#endif /* PAH_DEBUG */
++
++ pam_conversation.conv = conversation_function;
++ pam_conversation.appdata_ptr = NULL;
++
++ /* start the pam stack */
++ rc = pam_start ("polkit-1",
++ user_to_auth,
++ &pam_conversation,
++ &pam_h);
++ if (rc != PAM_SUCCESS)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: pam_start failed: %s\n", pam_strerror (pam_h, rc));
++ goto error;
++ }
++
++ /* set the requesting user */
++ rc = pam_set_item (pam_h, PAM_RUSER, user_to_auth);
++ if (rc != PAM_SUCCESS)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: pam_set_item failed: %s\n", pam_strerror (pam_h, rc));
++ goto error;
++ }
++
++ /* is user really user? */
++ rc = pam_authenticate (pam_h, 0);
++ if (rc != PAM_SUCCESS)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: pam_authenticated failed: %s\n", pam_strerror (pam_h, rc));
++ goto error;
++ }
++
++ /* permitted access? */
++ rc = pam_acct_mgmt (pam_h, 0);
++ if (rc != PAM_SUCCESS)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: pam_acct_mgmt failed: %s\n", pam_strerror (pam_h, rc));
++ goto error;
++ }
++
++ /* did we auth the right user? */
++ rc = pam_get_item (pam_h, PAM_USER, &authed_user);
++ if (rc != PAM_SUCCESS)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: pam_get_item failed: %s\n", pam_strerror (pam_h, rc));
++ goto error;
++ }
++
++ if (strcmp (authed_user, user_to_auth) != 0)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: Tried to auth user '%s' but we got auth for user '%s' instead",
++ user_to_auth, (const char *) authed_user);
++ goto error;
++ }
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: successfully authenticated user '%s'.\n", user_to_auth);
++#endif /* PAH_DEBUG */
++
++ pam_end (pam_h, rc);
++ pam_h = NULL;
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: sending D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++
++ /* now send a D-Bus message to the PolicyKit daemon that
++ * includes a) the cookie; and b) the user we authenticated
++ */
++ if (!send_dbus_message (cookie, user_to_auth))
++ {
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: error sending D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++ goto error;
++ }
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++
++ fprintf (stdout, "SUCCESS\n");
++ flush_and_wait();
++ return 0;
++
++error:
++ if (pam_h != NULL)
++ pam_end (pam_h, rc);
++
++ fprintf (stdout, "FAILURE\n");
++ flush_and_wait();
++ return 1;
++}
++
++static int
++conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data)
++{
++ struct pam_response *aresp;
++ char buf[PAM_MAX_RESP_SIZE];
++ int i;
++
++ data = data;
++ if (n <= 0 || n > PAM_MAX_NUM_MSG)
++ return PAM_CONV_ERR;
++
++ if ((aresp = calloc(n, sizeof *aresp)) == NULL)
++ return PAM_BUF_ERR;
++
++ for (i = 0; i < n; ++i)
++ {
++ aresp[i].resp_retcode = 0;
++ aresp[i].resp = NULL;
++ switch (msg[i]->msg_style)
++ {
++
++ case PAM_PROMPT_ECHO_OFF:
++ fprintf (stdout, "PAM_PROMPT_ECHO_OFF ");
++ goto conv1;
++
++ case PAM_PROMPT_ECHO_ON:
++ fprintf (stdout, "PAM_PROMPT_ECHO_ON ");
++ conv1:
++ fputs (msg[i]->msg, stdout);
++ if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
++ fputc ('\n', stdout);
++ fflush (stdout);
++
++ if (fgets (buf, sizeof buf, stdin) == NULL)
++ goto error;
++
++ if (strlen (buf) > 0 &&
++ buf[strlen (buf) - 1] == '\n')
++ buf[strlen (buf) - 1] = '\0';
++
++ aresp[i].resp = strdup (buf);
++ if (aresp[i].resp == NULL)
++ goto error;
++ break;
++
++ case PAM_ERROR_MSG:
++ fprintf (stdout, "PAM_ERROR_MSG ");
++ goto conv2;
++
++ case PAM_TEXT_INFO:
++ fprintf (stdout, "PAM_TEXT_INFO ");
++ conv2:
++ fputs (msg[i]->msg, stdout);
++ if (strlen (msg[i]->msg) > 0 &&
++ msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
++ fputc ('\n', stdout);
++ fflush (stdout);
++ break;
++
++ default:
++ goto error;
++ }
++ }
++
++ *resp = aresp;
++ return PAM_SUCCESS;
++
++error:
++
++ for (i = 0; i < n; ++i)
++ {
++ if (aresp[i].resp != NULL) {
++ memset (aresp[i].resp, 0, strlen(aresp[i].resp));
++ free (aresp[i].resp);
++ }
++ }
++ memset (aresp, 0, n * sizeof *aresp);
++ *resp = NULL;
++ return PAM_CONV_ERR;
++}
++
+diff --git a/src/polkitagent/polkitagenthelper-shadow.c b/src/polkitagent/polkitagenthelper-shadow.c
+new file mode 100644
+index 0000000..7435533
+--- /dev/null
++++ b/src/polkitagent/polkitagenthelper-shadow.c
+@@ -0,0 +1,189 @@
++/*
++ * Copyright (C) 2008 Red Hat, Inc.
++ * Copyright (C) 2009-2010 Andrew Psaltis <ampsaltis@gmail.com>
++ *
++ * 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.
++ *
++ * Authors: Andrew Psaltis <ampsaltis@gmail.com>, based on
++ * polkitagenthelper.c which was written by
++ * David Zeuthen <davidz@redhat.com>
++ */
++
++#include "config.h"
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <syslog.h>
++#include <shadow.h>
++#include <grp.h>
++#include <pwd.h>
++#include <time.h>
++
++#include <polkit/polkit.h>
++#include "polkitagenthelperprivate.h"
++
++
++extern char *crypt ();
++static int shadow_authenticate (struct spwd *shadow);
++
++int
++main (int argc, char *argv[])
++{
++ struct spwd *shadow;
++ const char *user_to_auth;
++ const char *cookie;
++ time_t tm;
++
++ /* clear the entire environment to avoid attacks with
++ libraries honoring environment variables */
++ if (clearenv () != 0)
++ goto error;
++
++ /* set a minimal environment */
++ setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
++
++ /* check that we are setuid root */
++ if (geteuid () != 0)
++ {
++ fprintf (stderr, "polkit-agent-helper-1: needs to be setuid root\n");
++ goto error;
++ }
++
++ openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
++
++ /* check for correct invocation */
++ if (argc != 3)
++ {
++ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
++ fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
++ goto error;
++ }
++
++ if (getuid () != 0)
++ {
++ /* check we're running with a non-tty stdin */
++ if (isatty (STDIN_FILENO) != 0)
++ {
++ syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
++ fprintf (stderr, "polkit-agent-helper-1: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
++ goto error;
++ }
++ }
++
++ user_to_auth = argv[1];
++ cookie = argv[2];
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
++#endif /* PAH_DEBUG */
++
++ /* Ask shadow about the user requesting authentication */
++ if ((shadow = getspnam (user_to_auth)) == NULL)
++ {
++ syslog (LOG_NOTICE, "shadow file data information request for user %s [uid=%d] failed", user_to_auth, getuid());
++ fprintf(stderr, "polkit-agent-helper-1: could not get shadow information for%.100s", user_to_auth);
++ goto error;
++ }
++
++ /* Check the user's identity */
++ if(!shadow_authenticate (shadow))
++ {
++ syslog (LOG_NOTICE, "authentication failure [uid=%d] trying to authenticate '%s'", getuid (), user_to_auth);
++ fprintf (stderr, "polkit-agent-helper-1: authentication failure. This incident has been logged.\n");
++ goto error;
++ }
++
++ /* Check whether the user's password has expired */
++ time(&tm);
++ if( shadow->sp_max >= 0 && (shadow->sp_lstchg + shadow->sp_max) * 60 * 60 * 24 <= tm)
++ {
++ syslog (LOG_NOTICE, "password expired for user '%s' [uid=%d] trying to authenticate", user_to_auth, getuid () );
++ fprintf (stderr, "polkit-agent-helper-1: authorization failure. This incident has been logged.\n");
++ goto error;
++ }
++
++ /* Check whether the user's password has aged (and account expired along
++ * with it)
++ */
++ if( shadow->sp_inact >= 0 && (shadow->sp_lstchg + shadow->sp_max + shadow->sp_inact) * 60 * 60 * 24 <= tm)
++ {
++ syslog (LOG_NOTICE, "password aged for user '%s' [uid=%d] trying to authenticate", user_to_auth, getuid () );
++ fprintf (stderr, "polkit-agent-helper-1: authorization failure. This incident has been logged.\n");
++ goto error;
++ }
++
++ /* Check whether the user's account has expired */
++ if(shadow->sp_expire >= 0 && shadow->sp_expire * 60 * 60 * 24 <= tm)
++ {
++ syslog (LOG_NOTICE, "account expired for user '%s' [uid=%d] trying to authenticate", user_to_auth, getuid () );
++ fprintf (stderr, "polkit-agent-helper-1: authorization failure. This incident has been logged.\n");
++ goto error;
++ }
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: sending D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++
++ /* now send a D-Bus message to the PolicyKit daemon that
++ * includes a) the cookie; and b) the user we authenticated
++ */
++ if (!send_dbus_message (cookie, user_to_auth))
++ {
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: error sending D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++ goto error;
++ }
++
++#ifdef PAH_DEBUG
++ fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
++#endif /* PAH_DEBUG */
++
++ fprintf (stdout, "SUCCESS\n");
++ flush_and_wait();
++ return 0;
++
++error:
++ fprintf (stdout, "FAILURE\n");
++ flush_and_wait();
++ return 1;
++}
++
++static int
++shadow_authenticate(struct spwd *shadow)
++{
++ /* Speak PAM to the daemon, thanks to David Zeuthen for the idea. */
++ char passwd[512];
++ fprintf(stdout, "PAM_PROMPT_ECHO_OFF password:\n");
++ fflush(stdout);
++ usleep (10 * 1000); /* since fflush(3) seems buggy */
++
++ if (fgets (passwd, sizeof (passwd), stdin) == NULL)
++ goto error;
++
++ if (strlen (passwd) > 0 && passwd[strlen (passwd) - 1] == '\n')
++ passwd[strlen (passwd) - 1] = '\0';
++
++ if (strcmp (shadow->sp_pwdp, crypt (passwd, shadow->sp_pwdp)) != 0)
++ goto error;
++ return 1;
++error:
++ return 0;
++}
++
+diff --git a/src/polkitagent/polkitagenthelper.c b/src/polkitagent/polkitagenthelper.c
+deleted file mode 100644
+index cca86db..0000000
+--- a/src/polkitagent/polkitagenthelper.c
++++ /dev/null
+@@ -1,339 +0,0 @@
+-/*
+- * Copyright (C) 2008 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: David Zeuthen <davidz@redhat.com>
+- */
+-
+-#include "config.h"
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <unistd.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <syslog.h>
+-#include <security/pam_appl.h>
+-
+-#include <polkit/polkit.h>
+-
+-#ifdef HAVE_SOLARIS
+-# define LOG_AUTHPRIV (10<<3)
+-#endif
+-
+-#ifndef HAVE_CLEARENV
+-extern char **environ;
+-
+-static int
+-clearenv (void)
+-{
+- if (environ != NULL)
+- environ[0] = NULL;
+- return 0;
+-}
+-#endif
+-
+-/* Development aid: define PAH_DEBUG to get debugging output. Do _NOT_
+- * enable this in production builds; it may leak passwords and other
+- * sensitive information.
+- */
+-#undef PAH_DEBUG
+-// #define PAH_DEBUG
+-
+-static gboolean send_dbus_message (const char *cookie, const char *user);
+-
+-static int conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data);
+-
+-int
+-main (int argc, char *argv[])
+-{
+- int rc;
+- const char *user_to_auth;
+- const char *cookie;
+- struct pam_conv pam_conversation;
+- pam_handle_t *pam_h;
+- const void *authed_user;
+-
+- rc = 0;
+- pam_h = NULL;
+-
+- /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
+- if (clearenv () != 0)
+- goto error;
+-
+- /* set a minimal environment */
+- setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
+-
+- /* check that we are setuid root */
+- if (geteuid () != 0)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: needs to be setuid root\n");
+- goto error;
+- }
+-
+- openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+-
+- /* check for correct invocation */
+- if (argc != 3)
+- {
+- syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
+- fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
+- goto error;
+- }
+-
+- user_to_auth = argv[1];
+- cookie = argv[2];
+-
+- if (getuid () != 0)
+- {
+- /* check we're running with a non-tty stdin */
+- if (isatty (STDIN_FILENO) != 0)
+- {
+- syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
+- fprintf (stderr, "polkit-agent-helper-1: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
+- goto error;
+- }
+- }
+-
+-#ifdef PAH_DEBUG
+- fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
+-#endif /* PAH_DEBUG */
+-
+- pam_conversation.conv = conversation_function;
+- pam_conversation.appdata_ptr = NULL;
+-
+- /* start the pam stack */
+- rc = pam_start ("polkit-1",
+- user_to_auth,
+- &pam_conversation,
+- &pam_h);
+- if (rc != PAM_SUCCESS)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: pam_start failed: %s\n", pam_strerror (pam_h, rc));
+- goto error;
+- }
+-
+- /* set the requesting user */
+- rc = pam_set_item (pam_h, PAM_RUSER, user_to_auth);
+- if (rc != PAM_SUCCESS)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: pam_set_item failed: %s\n", pam_strerror (pam_h, rc));
+- goto error;
+- }
+-
+- /* is user really user? */
+- rc = pam_authenticate (pam_h, 0);
+- if (rc != PAM_SUCCESS)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: pam_authenticated failed: %s\n", pam_strerror (pam_h, rc));
+- goto error;
+- }
+-
+- /* permitted access? */
+- rc = pam_acct_mgmt (pam_h, 0);
+- if (rc != PAM_SUCCESS)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: pam_acct_mgmt failed: %s\n", pam_strerror (pam_h, rc));
+- goto error;
+- }
+-
+- /* did we auth the right user? */
+- rc = pam_get_item (pam_h, PAM_USER, &authed_user);
+- if (rc != PAM_SUCCESS)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: pam_get_item failed: %s\n", pam_strerror (pam_h, rc));
+- goto error;
+- }
+-
+- if (strcmp (authed_user, user_to_auth) != 0)
+- {
+- fprintf (stderr, "polkit-agent-helper-1: Tried to auth user '%s' but we got auth for user '%s' instead",
+- user_to_auth, (const char *) authed_user);
+- goto error;
+- }
+-
+-#ifdef PAH_DEBUG
+- fprintf (stderr, "polkit-agent-helper-1: successfully authenticated user '%s'.\n", user_to_auth);
+-#endif /* PAH_DEBUG */
+-
+- pam_end (pam_h, rc);
+- pam_h = NULL;
+-
+-#ifdef PAH_DEBUG
+- fprintf (stderr, "polkit-agent-helper-1: sending D-Bus message to PolicyKit daemon\n");
+-#endif /* PAH_DEBUG */
+-
+- /* now send a D-Bus message to the PolicyKit daemon that
+- * includes a) the cookie; and b) the user we authenticated
+- */
+- if (!send_dbus_message (cookie, user_to_auth))
+- {
+-#ifdef PAH_DEBUG
+- fprintf (stderr, "polkit-agent-helper-1: error sending D-Bus message to PolicyKit daemon\n");
+-#endif /* PAH_DEBUG */
+- goto error;
+- }
+-
+-#ifdef PAH_DEBUG
+- fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
+-#endif /* PAH_DEBUG */
+-
+- fprintf (stdout, "SUCCESS\n");
+- fflush (stdout);
+- fflush (stderr);
+- usleep (10 * 1000); /* since fflush(3) seems buggy */
+- return 0;
+-
+-error:
+- if (pam_h != NULL)
+- pam_end (pam_h, rc);
+-
+- fprintf (stdout, "FAILURE\n");
+- fflush (stdout);
+- fflush (stderr);
+- usleep (10 * 1000); /* since fflush(3) seems buggy */
+- return 1;
+-}
+-
+-static int
+-conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data)
+-{
+- struct pam_response *aresp;
+- char buf[PAM_MAX_RESP_SIZE];
+- int i;
+-
+- data = data;
+- if (n <= 0 || n > PAM_MAX_NUM_MSG)
+- return PAM_CONV_ERR;
+-
+- if ((aresp = calloc(n, sizeof *aresp)) == NULL)
+- return PAM_BUF_ERR;
+-
+- for (i = 0; i < n; ++i)
+- {
+- aresp[i].resp_retcode = 0;
+- aresp[i].resp = NULL;
+- switch (msg[i]->msg_style)
+- {
+-
+- case PAM_PROMPT_ECHO_OFF:
+- fprintf (stdout, "PAM_PROMPT_ECHO_OFF ");
+- goto conv1;
+-
+- case PAM_PROMPT_ECHO_ON:
+- fprintf (stdout, "PAM_PROMPT_ECHO_ON ");
+- conv1:
+- fputs (msg[i]->msg, stdout);
+- if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+- fputc ('\n', stdout);
+- fflush (stdout);
+-
+- if (fgets (buf, sizeof buf, stdin) == NULL)
+- goto error;
+-
+- if (strlen (buf) > 0 &&
+- buf[strlen (buf) - 1] == '\n')
+- buf[strlen (buf) - 1] = '\0';
+-
+- aresp[i].resp = strdup (buf);
+- if (aresp[i].resp == NULL)
+- goto error;
+- break;
+-
+- case PAM_ERROR_MSG:
+- fprintf (stdout, "PAM_ERROR_MSG ");
+- goto conv2;
+-
+- case PAM_TEXT_INFO:
+- fprintf (stdout, "PAM_TEXT_INFO ");
+- conv2:
+- fputs (msg[i]->msg, stdout);
+- if (strlen (msg[i]->msg) > 0 &&
+- msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+- fputc ('\n', stdout);
+- fflush (stdout);
+- break;
+-
+- default:
+- goto error;
+- }
+- }
+-
+- *resp = aresp;
+- return PAM_SUCCESS;
+-
+-error:
+-
+- for (i = 0; i < n; ++i)
+- {
+- if (aresp[i].resp != NULL) {
+- memset (aresp[i].resp, 0, strlen(aresp[i].resp));
+- free (aresp[i].resp);
+- }
+- }
+- memset (aresp, 0, n * sizeof *aresp);
+- *resp = NULL;
+- return PAM_CONV_ERR;
+-}
+-
+-static gboolean
+-send_dbus_message (const char *cookie, const char *user)
+-{
+- PolkitAuthority *authority;
+- PolkitIdentity *identity;
+- GError *error;
+- gboolean ret;
+-
+- ret = FALSE;
+-
+- error = NULL;
+-
+- g_type_init ();
+-
+- authority = polkit_authority_get ();
+-
+- identity = polkit_unix_user_new_for_name (user, &error);
+- if (identity == NULL)
+- {
+- g_printerr ("Error constructing identity: %s\n", error->message);
+- g_error_free (error);
+- goto out;
+- }
+-
+- if (!polkit_authority_authentication_agent_response_sync (authority,
+- cookie,
+- identity,
+- NULL,
+- &error))
+- {
+- g_printerr ("polkit-agent-helper-1: error response to PolicyKit daemon: %s\n", error->message);
+- g_error_free (error);
+- goto out;
+- }
+-
+- ret = TRUE;
+-
+- out:
+-
+- if (identity != NULL)
+- g_object_unref (identity);
+-
+- if (authority != NULL)
+- g_object_unref (authority);
+-
+- return ret;
+-}
+diff --git a/src/polkitagent/polkitagenthelperprivate.c b/src/polkitagent/polkitagenthelperprivate.c
+new file mode 100644
+index 0000000..abf5524
+--- /dev/null
++++ b/src/polkitagent/polkitagenthelperprivate.c
+@@ -0,0 +1,97 @@
++/*
++ * Copyright (C) 2009-2010 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., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ *
++ * Authors: David Zeuthen <davidz@redhat.com>,
++ * Andrew Psaltis <ampsaltis@gmail.com>
++ */
++
++#include "polkitagenthelperprivate.h"
++#include <stdio.h>
++
++#ifndef HAVE_CLEARENV
++extern char **environ;
++
++static int
++clearenv (void)
++{
++ if (environ != NULL)
++ environ[0] = NULL;
++ return 0;
++}
++#endif
++
++
++gboolean
++send_dbus_message (const char *cookie, const char *user)
++{
++ PolkitAuthority *authority;
++ PolkitIdentity *identity;
++ GError *error;
++ gboolean ret;
++
++ ret = FALSE;
++
++ error = NULL;
++
++ g_type_init ();
++
++ authority = polkit_authority_get ();
++
++ identity = polkit_unix_user_new_for_name (user, &error);
++ if (identity == NULL)
++ {
++ g_printerr ("Error constructing identity: %s\n", error->message);
++ g_error_free (error);
++ goto out;
++ }
++
++ if (!polkit_authority_authentication_agent_response_sync (authority,
++ cookie,
++ identity,
++ NULL,
++ &error))
++ {
++ g_printerr ("polkit-agent-helper-1: error response to PolicyKit daemon: %s\n", error->message);
++ g_error_free (error);
++ goto out;
++ }
++
++ ret = TRUE;
++
++ out:
++
++ if (identity != NULL)
++ g_object_unref (identity);
++
++ if (authority != NULL)
++ g_object_unref (authority);
++
++ return ret;
++}
++
++/* fflush(3) stdin and stdout and wait a little bit.
++ * This replaces the three-line commands at the bottom of
++ * polkit-agent-helper-1's main() function.
++ */
++void
++flush_and_wait ()
++{
++ fflush (stdout);
++ fflush (stderr);
++ usleep (10 * 1000); /* since fflush(3) seems buggy */
++}
+diff --git a/src/polkitagent/polkitagenthelperprivate.h b/src/polkitagent/polkitagenthelperprivate.h
+new file mode 100644
+index 0000000..16f7ba4
+--- /dev/null
++++ b/src/polkitagent/polkitagenthelperprivate.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (C) 2009-2010 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., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ *
++ * Authors: David Zeuthen <davidz@redhat.com>,
++ * Andrew Psaltis <ampsalits@gmail.com>
++ */
++#ifndef __POLKIT_AGENT_HELPER_PRIVATE_H
++#define __POLKIT_AGENT_HELPER_PRIVATE_H
++
++#include <polkit/polkit.h>
++
++/* Development aid: define PAH_DEBUG to get debugging output. Do _NOT_
++ * enable this in production builds; it may leak passwords and other
++ * sensitive information.
++ */
++#undef PAH_DEBUG
++// #define PAH_DEBUG
++
++#ifdef HAVE_SOLARIS
++# define LOG_AUTHPRIV (10<<3)
++#endif
++
++gboolean send_dbus_message (const char *cookie, const char *user);
++
++void flush_and_wait ();
++
++#endif /* __POLKIT_AGENT_HELPER_PRIVATE_H */
+diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
+index 17c191e..3e096bf 100644
+--- a/src/programs/pkexec.c
++++ b/src/programs/pkexec.c
+@@ -34,7 +34,11 @@
+ #include <grp.h>
+ #include <pwd.h>
+ #include <errno.h>
++
++#ifdef POLKIT_AUTHFW_PAM
+ #include <security/pam_appl.h>
++#endif /* POLKIT_AUTHFW_PAM */
++
+ #include <syslog.h>
+ #include <stdarg.h>
+
+@@ -115,6 +119,7 @@ log_message (gint level,
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
++#ifdef POLKIT_AUTHFW_PAM
+ static int
+ pam_conversation_function (int n,
+ const struct pam_message **msg,
+@@ -167,6 +172,7 @@ out:
+ pam_end (pam_h, rc);
+ return ret;
+ }
++#endif /* POLKIT_AUTHFW_PAM */
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+@@ -741,11 +747,13 @@ main (int argc, char *argv[])
+ * TODO: The question here is whether we should clear the limits before applying them?
+ * As evident above, neither su(1) (and, for that matter, nor sudo(8)) does this.
+ */
++#ifdef POLKIT_AUTHW_PAM
+ if (!open_session (pw->pw_name))
+ {
+ goto out;
+ }
+-
++#endif /* POLKIT_AUTHFW_PAM */
++
+ /* become the user */
+ if (setgroups (0, NULL) != 0)
+ {
diff --git a/patches/source/polkit/polkit.SlackBuild b/patches/source/polkit/polkit.SlackBuild
new file mode 100755
index 00000000..3a4f6ca8
--- /dev/null
+++ b/patches/source/polkit/polkit.SlackBuild
@@ -0,0 +1,149 @@
+#!/bin/sh
+
+# Copyright 2009 Robby Workman, Northport, Alabama, USA
+# Copyright 2010 Eric Hameleers, Eindhoven, NL
+# Copyright 2009, 2010, 2011 Patrick J. Volkerding, Sebeka, MN, USA
+# All rights reserved.
+
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+PKGNAM=polkit
+VERSION=${VERSION:-1_14bdfd8}
+BUILD=${BUILD:-2_slack13.1}
+NUMJOBS=${NUMJOBS:--j6}
+
+# Automatically determine the architecture we're building on:
+if [ -z "$ARCH" ]; then
+ case "$( uname -m )" in
+ i?86) export ARCH=i486 ;;
+ arm*) export ARCH=arm ;;
+ # Unless $ARCH is already set, use uname -m for all other archs:
+ *) export ARCH=$( uname -m ) ;;
+ esac
+fi
+
+CWD=$(pwd)
+TMP=${TMP:-/tmp}
+PKG=$TMP/package-$PKGNAM
+
+if [ "$ARCH" = "i486" ]; then
+ SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "s390" ]; then
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -fPIC"
+ LIBDIRSUFFIX="64"
+else
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+fi
+
+rm -rf $PKG
+mkdir -p $TMP $PKG
+cd $TMP
+rm -rf $PKGNAM-$VERSION
+tar xvf $CWD/$PKGNAM-$VERSION.tar.bz2 || exit 1
+cd $PKGNAM-$VERSION || exit 1
+
+# Apply the patch that makes --with-authfw=shadow work
+cat $CWD/polkit-1-shadow.diff | patch -p1 --verbose || exit 1
+
+cat $CWD/CVE-2011-1485/0001-PolkitUnixProcess-Clarify-that-the-real-uid-is-retur.patch | patch -p1 || exit 1
+cat $CWD/CVE-2011-1485/0002-Make-PolkitUnixProcess-also-record-the-uid-of-the-pr.patch | patch -p1 || exit 1
+cat $CWD/CVE-2011-1485/0003-Use-polkit_unix_process_get_uid-to-get-the-owner-of-.patch | patch -p1 || exit 1
+cat $CWD/CVE-2011-1485/0004-pkexec-Avoid-TOCTTOU-problems-with-parent-process.patch | patch -p1 || exit 1
+
+# Make sure ownerships and permissions are sane:
+chown -R root:root .
+find . \
+ \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \
+ -exec chmod 755 {} \; -o \
+ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
+ -exec chmod 644 {} \;
+
+# Configure:
+# Using polkit-user=hald for now for easier transition; I don't think the
+# separate user account is actually required any more, but I could be wrong
+CFLAGS="$SLKCFLAGS" \
+CXXFLAGS="$SLKCFLAGS" \
+./autogen.sh \
+ --prefix=/usr \
+ --libdir=/usr/lib${LIBDIRSUFFIX} \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --enable-gtk-doc \
+ --docdir=/usr/doc/$PKGNAM-$VERSION \
+ --enable-man-pages \
+ --mandir=/usr/man \
+ --disable-static \
+ --disable-introspection \
+ --with-authfw=shadow \
+ --enable-verbose-mode \
+ --build=$ARCH-slackware-linux
+ # Deprecated:
+ #--with-polkit-user=hald \
+
+#NOTE: The directory /etc/polkit-1/localauthority must be owned
+# by root and have mode 700
+#NOTE: The directory /var/lib/polkit-1 must be owned
+# by root and have mode 700
+#NOTE: The file ${exec_prefix}/libexec/polkit-agent-helper-1 must be owned
+# by root and have mode 4755 (setuid root binary)
+#NOTE: The file ${exec_prefix}/bin/pkexec must be owned by root and
+# have mode 4755 (setuid root binary)
+
+# Build and install:
+make $NUMJOBS || make || exit 1
+make install DESTDIR=$PKG || exit 1
+
+# Strip binaries:
+find $PKG | xargs file | grep -e "executable" -e "shared object" \
+ | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
+
+# Compress and link manpages, if any:
+if [ -d $PKG/usr/man ]; then
+ ( cd $PKG/usr/man
+ for manpagedir in $(find . -type d -name "man*") ; do
+ ( cd $manpagedir
+ for eachpage in $( find . -type l -maxdepth 1) ; do
+ ln -s $( readlink $eachpage ).gz $eachpage.gz
+ rm $eachpage
+ done
+ gzip -9 *.*
+ )
+ done
+ )
+fi
+
+# Add a documentation directory:
+mkdir -p $PKG/usr/doc/$PKGNAM-$VERSION
+cp -a \
+ AUTHORS COPYING ChangeLog HACKING INSTALL NEWS README \
+ $PKG/usr/doc/$PKGNAM-$VERSION
+( cd $PKG/usr/doc/$PKGNAM-$VERSION; ln -s ../../share/gtk-doc/html/polkit-1 html
+)
+
+mkdir -p $PKG/install
+cat $CWD/slack-desc > $PKG/install/slack-desc
+
+cd $PKG
+/sbin/makepkg -l y -c n $TMP/$PKGNAM-$VERSION-$ARCH-$BUILD.txz
+
diff --git a/patches/source/polkit/slack-desc b/patches/source/polkit/slack-desc
new file mode 100644
index 00000000..006d8a8e
--- /dev/null
+++ b/patches/source/polkit/slack-desc
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description. Line
+# up the first '|' above the ':' following the base package name, and the '|'
+# on the right side marks the last column you can put a character in. You must
+# make exactly 11 lines for the formatting to be correct. It's also
+# customary to leave one space after the ':'.
+
+ |-----handy-ruler-----------------------------------------------------|
+polkit: polkit (authentication framework)
+polkit:
+polkit: PolicyKit is an application-level toolkit for defining and handling
+polkit: the policy that allows unprivileged processes to speak to privileged
+polkit: processes. PolicyKit is specifically targeting applications in rich
+polkit: desktop environments on multi-user UNIX-like operating systems.
+polkit:
+polkit:
+polkit:
+polkit: Home: http://www.freedesktop.org/wiki/Software/PolicyKit
+polkit: