From 84958d3707ff43e8b8bda3fc0f669966db683f67 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Fri, 11 Dec 2009 12:29:45 -0500 Subject: Run the open_session part of the PAM stack in pkexec(1) This was pointed out in http://lists.freedesktop.org/archives/polkit-devel/2009-December/000276.html We already run the authentication and acct_mgmt parts in the authentication agent. Signed-off-by: David Zeuthen --- src/programs/Makefile.am | 1 + src/programs/pkexec.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am index 6f78c49..5c8a26f 100644 --- a/src/programs/Makefile.am +++ b/src/programs/Makefile.am @@ -25,6 +25,7 @@ pkexec_SOURCES = pkexec.c pkexec_CFLAGS = \ $(GLIB_CFLAGS) \ + $(AUTH_LIBS) \ $(NULL) pkexec_LDADD = \ diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c index 4eeb55f..2ce8064 100644 --- a/src/programs/pkexec.c +++ b/src/programs/pkexec.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -59,6 +60,61 @@ usage (int argc, char *argv[]) /* ---------------------------------------------------------------------------------------------------- */ +static int +pam_conversation_function (int n, + const struct pam_message **msg, + struct pam_response **resp, + void *data) +{ + g_assert_not_reached (); + return PAM_CONV_ERR; +} + +static gboolean +open_session (const gchar *user_to_auth) +{ + gboolean ret; + gint rc; + pam_handle_t *pam_h; + struct pam_conv conversation; + + ret = FALSE; + + pam_h = NULL; + + conversation.conv = pam_conversation_function; + conversation.appdata_ptr = NULL; + + /* start the pam stack */ + rc = pam_start ("polkit-1", + user_to_auth, + &conversation, + &pam_h); + if (rc != PAM_SUCCESS) + { + g_printerr ("pam_start() failed: %s\n", pam_strerror (pam_h, rc)); + goto out; + } + + /* open a session */ + rc = pam_open_session (pam_h, + 0); /* flags */ + if (rc != PAM_SUCCESS) + { + g_printerr ("pam_open_session() failed: %s\n", pam_strerror (pam_h, rc)); + goto out; + } + + ret = TRUE; + +out: + if (pam_h != NULL) + pam_end (pam_h, rc); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + typedef gboolean (*FdCallback) (gint fd, gpointer user_data); static gboolean @@ -464,7 +520,7 @@ main (int argc, char *argv[]) } /* if not changing to uid 0, become uid 0 before changing to the user */ - if (pw->pw_uid) + if (pw->pw_uid != 0) { setreuid (0, 0); if ((geteuid () != 0) || (getuid () != 0)) @@ -474,6 +530,37 @@ main (int argc, char *argv[]) } } + /* open session - with PAM enabled, this runs the open_session() part of the PAM + * stack - this includes applying limits via pam_limits.so but also other things + * requested via the current PAM configuration. + * + * NOTE NOTE NOTE: pam_limits.so doesn't seem to clear existing limits - e.g. + * + * $ ulimit -t + * unlimited + * + * $ su - + * Password: + * # ulimit -t + * 1000 + * # logout + * + * $ ulimit -t 1000 + * $ ulimit -t + * 1000 + * $ su - + * Password: + * # ulimit -t + * 1000 + * + * 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. + */ + if (!open_session (pw->pw_name)) + { + goto out; + } + /* become the user */ if (setgroups (0, NULL) != 0) { -- cgit v1.2.1