Commit 8e0383cb authored by David Zeuthen's avatar David Zeuthen
Browse files

Run polkitd as an unprivileged user



There's really no reason to run all this code as uid 0.
Signed-off-by: default avatarDavid Zeuthen <davidz@redhat.com>
parent e5dafb81
......@@ -193,6 +193,20 @@ if test "x$with_systemdsystemunitdir" != "xno"; then
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
......@@ -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)
......@@ -4,7 +4,7 @@
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<policy user="@polkitd_user@">
<allow own="org.freedesktop.PolicyKit1"/>
</policy>
......@@ -13,7 +13,7 @@
</policy>
<!-- Allow uid 0 to send messages on the org.freedesktop.PolicyKit1.AuthenticationAgent interface -->
<policy user="root">
<policy user="@polkitd_user@">
<allow send_interface="org.freedesktop.PolicyKit1.AuthenticationAgent"/>
</policy>
......
......@@ -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>
......
......@@ -40,6 +40,12 @@
whenever an application calls into the service.
</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>
......
......@@ -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
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment