diff options
author | David Zeuthen <davidz@redhat.com> | 2012-05-25 12:40:42 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2012-05-25 12:40:42 -0400 |
commit | 8e0383cb9972f5b3b86e64f9b015f53671ce0323 (patch) | |
tree | 4696f1d0071ed0abe27287a14907a42f7af9d147 /src | |
parent | e5dafb816bcefdceb617e32fbfb527f865c8879c (diff) | |
download | polkit-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.am | 4 | ||||
-rw-r--r-- | src/polkitbackend/polkitd.c | 73 |
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); |