summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2009-12-11 12:29:45 -0500
committerDavid Zeuthen <davidz@redhat.com>2009-12-11 12:29:45 -0500
commit84958d3707ff43e8b8bda3fc0f669966db683f67 (patch)
treea162783a0e8bf89168f1ce17ce671e1a855d880b
parent3e82e172f295f4d5ac4ea97b114f19999d69235e (diff)
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 <davidz@redhat.com>
-rw-r--r--src/programs/Makefile.am1
-rw-r--r--src/programs/pkexec.c89
2 files changed, 89 insertions, 1 deletions
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 <grp.h>
#include <pwd.h>
#include <errno.h>
+#include <security/pam_appl.h>
#include <polkit/polkit.h>
@@ -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)
{