summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2012-05-25 12:40:42 -0400
committerDavid Zeuthen <davidz@redhat.com>2012-05-25 12:40:42 -0400
commit8e0383cb9972f5b3b86e64f9b015f53671ce0323 (patch)
tree4696f1d0071ed0abe27287a14907a42f7af9d147 /src
parente5dafb816bcefdceb617e32fbfb527f865c8879c (diff)
downloadpolkit-8e0383cb9972f5b3b86e64f9b015f53671ce0323.tar.gz
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@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/polkitbackend/Makefile.am4
-rw-r--r--src/polkitbackend/polkitd.c73
2 files changed, 76 insertions, 1 deletions
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);