PolicyKit: Branch 'wip/js-rule-files'
David Zeuthen
david at kemper.freedesktop.org
Fri May 25 09:41:28 PDT 2012
configure.ac | 25 ++++++++--
data/Makefile.am | 21 +++++++--
data/org.freedesktop.PolicyKit1.conf | 20 --------
data/org.freedesktop.PolicyKit1.conf.in | 20 ++++++++
docs/man/polkit.xml | 17 ++++++-
docs/man/polkitd.xml | 6 ++
src/polkitbackend/Makefile.am | 4 +
src/polkitbackend/polkitd.c | 73 ++++++++++++++++++++++++++++++++
8 files changed, 154 insertions(+), 32 deletions(-)
New commits:
commit 8e0383cb9972f5b3b86e64f9b015f53671ce0323
Author: David Zeuthen <davidz at redhat.com>
Date: Fri May 25 12:40:42 2012 -0400
Run polkitd as an unprivileged user
There's really no reason to run all this code as uid 0.
Signed-off-by: David Zeuthen <davidz at redhat.com>
diff --git a/configure.ac b/configure.ac
index d9559cc..b26b333 100644
--- a/configure.ac
+++ b/configure.ac
@@ -194,6 +194,20 @@ fi
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$systemdsystemunitdir"])
dnl ---------------------------------------------------------------------------
+dnl - User for running polkitd
+dnl ---------------------------------------------------------------------------
+
+AC_ARG_WITH(polkitd_user, AS_HELP_STRING([--with-polkitd-user=<user>],[User for running polkitd (polkitd)]))
+
+if test -z "$with_polkitd_user" ; then
+ POLKITD_USER=polkitd
+else
+ POLKITD_USER=$with_polkitd_user
+fi
+AC_SUBST(POLKITD_USER)
+AC_DEFINE_UNQUOTED(POLKITD_USER,"$POLKITD_USER", [User for running polkitd])
+
+dnl ---------------------------------------------------------------------------
dnl - Select which authentication framework to use
dnl ---------------------------------------------------------------------------
@@ -496,7 +510,8 @@ echo "
Authentication framework: ${POLKIT_AUTHFW}
Session tracking: ${SESSION_TRACKING}
PAM support: ${have_pam}
- systemdsystemunitdir: ${systemdsystemunitdir}"
+ systemdsystemunitdir: ${systemdsystemunitdir}
+ polkitd user: ${POLKITD_USER}"
if test "$have_pam" = yes ; then
echo "
@@ -522,10 +537,10 @@ echo "NOTE: The file ${bindir}/pkexec must be owned by root and"
echo " have mode 4755 (setuid root binary)"
echo
-echo "NOTE: The directory ${sysconfdir}/polkit-1/rules.d"
-echo " should have mode 700"
+echo "NOTE: The directory ${sysconfdir}/polkit-1/rules.d must be owned"
+echo " by user '$POLKITD_USER' and have mode 700"
echo
-echo "NOTE: The directory ${datadir}/polkit-1/rules.d"
-echo " should have mode 700"
+echo "NOTE: The directory ${datadir}/polkit-1/rules.d must be owned"
+echo " by user '$POLKITD_USER' and have mode 700"
echo
diff --git a/data/Makefile.am b/data/Makefile.am
index 6623286..b2d0cde 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -4,6 +4,8 @@ NULL =
libprivdir = $(prefix)/lib/polkit-1
+# ----------------------------------------------------------------------------------------------------
+
servicedir = $(datadir)/dbus-1/system-services
service_in_files = org.freedesktop.PolicyKit1.service.in
service_DATA = $(service_in_files:.service.in=.service)
@@ -11,17 +13,28 @@ service_DATA = $(service_in_files:.service.in=.service)
$(service_DATA): $(service_in_files) Makefile
@sed -e "s|\@libprivdir\@|$(libprivdir)|" $< > $@
+# ----------------------------------------------------------------------------------------------------
+
dbusconfdir = $(sysconfdir)/dbus-1/system.d
-dbusconf_DATA = org.freedesktop.PolicyKit1.conf
+dbusconf_in_files = org.freedesktop.PolicyKit1.conf.in
+dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf)
+
+$(dbusconf_DATA): $(dbusconf_in_files) Makefile
+ @sed -e "s|\@polkitd_user\@|$(POLKITD_USER)|" $< > $@
+
+# ----------------------------------------------------------------------------------------------------
if POLKIT_AUTHFW_PAM
pamdir = $(sysconfdir)/pam.d
pam_DATA = polkit-1
endif
+# ----------------------------------------------------------------------------------------------------
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = polkit-gobject-1.pc polkit-backend-1.pc polkit-agent-1.pc
+# ----------------------------------------------------------------------------------------------------
systemdservice_in_files = polkit.service.in
@@ -32,16 +45,18 @@ $(systemdservice_DATA): $(systemdservice_in_files) Makefile
@sed -e "s|\@libprivdir\@|$(libprivdir)|" $< > $@
endif
+# ----------------------------------------------------------------------------------------------------
+
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = \
org.freedesktop.PolicyKit1.Authority.xml \
org.freedesktop.PolicyKit1.AuthenticationAgent.xml \
$(service_in_files) \
+ $(dbusconf_in_files) \
$(systemdservice_in_files) \
- $(dbusconf_DATA) \
$(NULL)
clean-local :
- rm -f *~ $(service_DATA) $(systemdservice_DATA)
+ rm -f *~ $(service_DATA) $(dbusconf_DATA) $(systemdservice_DATA)
diff --git a/data/org.freedesktop.PolicyKit1.conf b/data/org.freedesktop.PolicyKit1.conf
deleted file mode 100644
index c8ef513..0000000
--- a/data/org.freedesktop.PolicyKit1.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
-
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
- <policy user="root">
- <allow own="org.freedesktop.PolicyKit1"/>
- </policy>
-
- <policy context="default">
- <allow send_destination="org.freedesktop.PolicyKit1"/>
- </policy>
-
- <!-- Allow uid 0 to send messages on the org.freedesktop.PolicyKit1.AuthenticationAgent interface -->
- <policy user="root">
- <allow send_interface="org.freedesktop.PolicyKit1.AuthenticationAgent"/>
- </policy>
-
-</busconfig>
diff --git a/data/org.freedesktop.PolicyKit1.conf.in b/data/org.freedesktop.PolicyKit1.conf.in
new file mode 100644
index 0000000..c749207
--- /dev/null
+++ b/data/org.freedesktop.PolicyKit1.conf.in
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="@polkitd_user@">
+ <allow own="org.freedesktop.PolicyKit1"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_destination="org.freedesktop.PolicyKit1"/>
+ </policy>
+
+ <!-- Allow uid 0 to send messages on the org.freedesktop.PolicyKit1.AuthenticationAgent interface -->
+ <policy user="@polkitd_user@">
+ <allow send_interface="org.freedesktop.PolicyKit1.AuthenticationAgent"/>
+ </policy>
+
+</busconfig>
diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml
index bd39299..b19b92c 100644
--- a/docs/man/polkit.xml
+++ b/docs/man/polkit.xml
@@ -31,7 +31,16 @@
untrusted. For every request from a subject, the mechanism needs
to determine if the request is authorized or if it should refuse
to service the subject. Using the polkit APIs, a mechanism can
- offload this decision to a trusted party: The polkit Authority.
+ offload this decision to a trusted party: The polkit authority.
+ </para>
+
+ <para>
+ The polkit authority is implemented as an system daemon,
+ <link linkend="polkitd.8"><citerefentry><refentrytitle>polkitd</refentrytitle><manvolnum>8</manvolnum></citerefentry></link>,
+ which itself has little privilege as it is running as the
+ <emphasis>polkitd</emphasis> system user. Mechanisms, subjects
+ and authentication agents communicate with the authority using
+ the system message bus.
</para>
<para>
@@ -204,7 +213,7 @@ System Context | |
<refsect1 id="polkit-declaring-actions"><title>DECLARING ACTIONS</title>
<para>
- A mechanism need to declare a set of <quote>ACTIONS</quote> in
+ A mechanism need to declare a set of <emphasis>actions</emphasis> in
order to use polkit. Actions correspond to operations that
clients can request the mechanism to carry out and are defined
in XML files that the mechanism installs into the <filename
@@ -591,7 +600,9 @@ System Context | |
The <function>spawn()</function> method should be used sparingly
as helpers may take a very long or indeterminate amount of time
to complete and no other authorization check can be handled
- while the helper is running.
+ while the helper is running. Note that the spawned programs
+ will run as the unprivileged <emphasis>polkitd</emphasis> system
+ user.
</para>
<para>
diff --git a/docs/man/polkitd.xml b/docs/man/polkitd.xml
index 879da2d..5fee8d4 100644
--- a/docs/man/polkitd.xml
+++ b/docs/man/polkitd.xml
@@ -41,6 +41,12 @@
</para>
<para>
+ <command>polkitd</command> must be started with superuser
+ privileges but drops privileges early by switching to the
+ unprivileged <emphasis>polkitd</emphasis> system user.
+ </para>
+
+ <para>
See the <link
linkend="polkit.8"><citerefentry><refentrytitle>polkit</refentrytitle><manvolnum>8</manvolnum></citerefentry></link>
man page for more information.
diff --git a/src/polkitbackend/Makefile.am b/src/polkitbackend/Makefile.am
index a173125..9f430d0 100644
--- a/src/polkitbackend/Makefile.am
+++ b/src/polkitbackend/Makefile.am
@@ -103,8 +103,10 @@ dist-hook :
clean-local :
rm -f *~ $(BUILT_SOURCES)
-install-exec-hook:
+install-data-hook:
mkdir -p $(DESTDIR)$(sysconfdir)/polkit-1/rules.d
-chmod 700 $(DESTDIR)$(sysconfdir)/polkit-1/rules.d
+ -chown $(POLKITD_USER) $(DESTDIR)$(sysconfdir)/polkit-1/rules.d
mkdir -p $(DESTDIR)$(datadir)/polkit-1/rules.d
-chmod 700 $(DESTDIR)$(datadir)/polkit-1/rules.d
+ -chown $(POLKITD_USER) $(DESTDIR)$(datadir)/polkit-1/rules.d
diff --git a/src/polkitbackend/polkitd.c b/src/polkitbackend/polkitd.c
index 0bb3f32..6a1bfb0 100644
--- a/src/polkitbackend/polkitd.c
+++ b/src/polkitbackend/polkitd.c
@@ -25,6 +25,9 @@
#include <glib-unix.h>
+#include <pwd.h>
+#include <grp.h>
+
#include <polkit/polkit.h>
#include <polkitbackend/polkitbackend.h>
@@ -94,6 +97,63 @@ on_sigint (gpointer user_data)
return FALSE;
}
+static gboolean
+become_user (const gchar *user,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ struct passwd *pw;
+
+ g_return_val_if_fail (user != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ pw = getpwnam (user);
+ if (pw == NULL)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error calling getpwnam(): %m");
+ goto out;
+ }
+
+ if (setgroups (0, NULL) != 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error clearing groups: %m");
+ goto out;
+ }
+ if (initgroups (pw->pw_name, pw->pw_gid) != 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error initializing groups: %m");
+ goto out;
+ }
+
+ setregid (pw->pw_gid, pw->pw_gid);
+ setreuid (pw->pw_uid, pw->pw_uid);
+ if ((geteuid () != pw->pw_uid) || (getuid () != pw->pw_uid) ||
+ (getegid () != pw->pw_gid) || (getgid () != pw->pw_gid))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error becoming real+effective uid %d and gid %d: %m",
+ (int) pw->pw_uid, (int) pw->pw_gid);
+ goto out;
+ }
+
+ if (chdir (pw->pw_dir) != 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error changing to home directory %s: %m",
+ pw->pw_dir);
+ goto out;
+ }
+
+
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
int
main (int argc,
char **argv)
@@ -142,6 +202,19 @@ main (int argc,
}
}
+ error = NULL;
+ if (!become_user (POLKITD_USER, &error))
+ {
+ g_printerr ("Error switcing to user %s: %s\n",
+ POLKITD_USER, error->message);
+ g_clear_error (&error);
+ goto out;
+ }
+
+ g_print ("Successfully changed to user %s\n", POLKITD_USER);
+
+ if (g_getenv ("PATH") == NULL)
+ g_setenv ("PATH", "/usr/bin:/bin:/usr/sbin:/sbin", TRUE);
loop = g_main_loop_new (NULL, FALSE);
More information about the hal-commit
mailing list