From 7638c874792f726166cc73931eb193fbc17c8cdd Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 3 Aug 2011 03:14:56 +0200
Subject: [PATCH] welcome: register in PAM in addition to ConsoleKit
systemd needs to be able to track the gdm welcome pseudo-session, hence
call into the PAM session hooks for it. This is necessary to get
systemd-style ACL management right, but is otherwise nicer too, since it
applies all PAM session limits to the welcome session, too.
---
daemon/Makefile.am | 1 +
daemon/gdm-welcome-session.c | 114 ++++++++++++++++++++++++++++++++++++++++++
data/Makefile.am | 7 ++-
data/gdm-welcome | 5 ++
4 files changed, 126 insertions(+), 1 deletions(-)
create mode 100644 data/gdm-welcome
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 5b4796a..40b5944 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -241,6 +241,7 @@ gdm_xdmcp_chooser_slave_SOURCES = \
gdm_xdmcp_chooser_slave_LDADD = \
$(XLIB_LIBS) \
$(DAEMON_LIBS) \
+ $(PAM_LIBS) \
$(EXTRA_DAEMON_LIBS) \
$(top_builddir)/common/libgdmcommon.la \
$(NULL)
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
index 04b3d07..a6f42eb 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -33,6 +33,9 @@
#include <grp.h>
#include <signal.h>
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
@@ -61,6 +64,8 @@ struct GdmWelcomeSessionPrivate
CkConnector *ckc;
+ pam_handle_t *pam_handle;
+
char *user_name;
char *group_name;
char *runtime_dir;
@@ -240,6 +245,105 @@ close_welcome_session (GdmWelcomeSession *welcome_session)
return ret;
}
+static int null_conv(
+ int num_msg,
+ const struct pam_message **msg,
+ struct pam_response **resp,
+ void *appdata_ptr) {
+
+ /* We don't support conversations */
+
+ return PAM_CONV_ERR;
+}
+
+static gboolean
+open_pam_session (GdmWelcomeSession *welcome_session)
+{
+ static const struct pam_conv conv = {
+ .conv = null_conv,
+ .appdata_ptr = NULL
+ };
+
+ int r;
+
+ if (welcome_session->priv->pam_handle != NULL)
+ return FALSE;
+
+ r = pam_start ("gdm-welcome",
+ welcome_session->priv->user_name,
+ &conv,
+ &welcome_session->priv->pam_handle);
+
+ if (r != PAM_SUCCESS) {
+ g_debug ("GdmWelcomeSession: pam_start() failed: %s", pam_strerror (welcome_session->priv->pam_handle, r));
+ goto fail;
+ }
+
+ /* set RHOST */
+ if (welcome_session->priv->x11_display_hostname != NULL &&
+ welcome_session->priv->x11_display_hostname[0] != '\0') {
+
+ r = pam_set_item (welcome_session->priv->pam_handle, PAM_RHOST, welcome_session->priv->x11_display_hostname);
+
+ if (r != PAM_SUCCESS) {
+ g_debug ("GdmWelcomeSession: setting PAM host name failed: %s", pam_strerror (welcome_session->priv->pam_handle, r));
+ goto fail;
+ }
+ }
+
+ /* set TTY */
+ if (welcome_session->priv->x11_display_name) {
+ r = pam_set_item (welcome_session->priv->pam_handle, PAM_TTY, welcome_session->priv->x11_display_name);
+
+ if (r != PAM_SUCCESS) {
+ g_debug ("GdmWelcomeSession: setting PAM tty name failed: %s", pam_strerror (welcome_session->priv->pam_handle, r));
+ goto fail;
+ }
+ }
+
+#ifdef PAM_XDISPLAY
+ /* set XDISPLAY */
+ if (welcome_session->priv->x11_display_name != NULL) {
+ r = pam_set_item (welcome_session->priv->pam_handle, PAM_XDISPLAY, welcome_session->priv->x11_display_name);
+
+ if (r != PAM_SUCCESS) {
+ g_debug ("GdmWelcomeSession: setting PAM display name failed: %s", pam_strerror (welcome_session->priv->pam_handle, r));
+ goto fail;
+ }
+ }
+#endif
+
+ r = pam_open_session (welcome_session->priv->pam_handle, PAM_SILENT);
+ if (r != PAM_SUCCESS) {
+ g_debug ("GdmWelcomeSession: opening session failed: %s", pam_strerror (welcome_session->priv->pam_handle, r));
+ goto fail;
+ }
+
+ return TRUE;
+
+fail:
+ if (welcome_session->priv->pam_handle != NULL) {
+ pam_end (welcome_session->priv->pam_handle, r);
+ welcome_session->priv->pam_handle = NULL;
+ }
+
+ return FALSE;
+}
+
+static void
+close_pam_session (GdmWelcomeSession *welcome_session)
+{
+ int r;
+
+ if (welcome_session->priv->pam_handle == NULL)
+ return;
+
+ r = pam_close_session (welcome_session->priv->pam_handle, PAM_DATA_SILENT);
+
+ pam_end (welcome_session->priv->pam_handle, r);
+ welcome_session->priv->pam_handle = NULL;
+}
+
static void
load_lang_config_file (const char *config_file,
const char **str_array)
@@ -499,6 +603,9 @@ welcome_session_child_watch (GPid pid,
if (session->priv->ckc != NULL) {
close_welcome_session (session);
}
+
+ close_pam_session (session);
+
stop_dbus_daemon (session);
}
@@ -913,6 +1020,8 @@ gdm_welcome_session_spawn (GdmWelcomeSession *welcome_session)
open_welcome_session (welcome_session);
}
+ open_pam_session (welcome_session);
+
res = start_dbus_daemon (welcome_session);
if (! res) {
/* FIXME: */
@@ -1031,6 +1140,8 @@ gdm_welcome_session_stop (GdmWelcomeSession *welcome_session)
close_welcome_session (welcome_session);
}
+ close_pam_session (welcome_session);
+
stop_dbus_daemon (welcome_session);
return TRUE;
@@ -1470,6 +1581,9 @@ gdm_welcome_session_finalize (GObject *object)
ck_connector_unref (welcome_session->priv->ckc);
}
+ if (welcome_session->priv->pam_handle != NULL)
+ pam_end (welcome_session->priv->pam_handle, PAM_SUCCESS);
+
g_free (welcome_session->priv->command);
g_free (welcome_session->priv->user_name);
g_free (welcome_session->priv->group_name);
diff --git a/data/Makefile.am b/data/Makefile.am
index 67c97b4..3a7a4ae 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -90,6 +90,7 @@ EXTRA_DIST = \
Xsession.in \
gdm \
gdm-autologin \
+ gdm-welcome \
Init.in \
PreSession.in \
PostSession.in \
@@ -136,6 +137,7 @@ uninstall-hook:
$(DESTDIR)$(postdir)/Default \
$(DESTDIR)$(PAM_PREFIX)/pam.d/gdm \
$(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-autologin \
+ $(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-welcome \
$(DESTDIR)$(workingdir)/.gconf.path \
$(DESTDIR)$(sysconfdir)/dconf/db/gdm \
$(DESTDIR)$(sysconfdir)/dconf/profile/gdm \
@@ -218,8 +220,11 @@ install-data-hook: gdm.conf-custom Xsession Init PostSession PreSession gconf.pa
if test $$system = Linux && test '!' -f $(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-autologin; then \
$(INSTALL_DATA) $(srcdir)/gdm-autologin $(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-autologin; \
fi; \
+ if test $$system = Linux && test '!' -f $(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-welcome; then \
+ $(INSTALL_DATA) $(srcdir)/gdm-welcome $(DESTDIR)$(PAM_PREFIX)/pam.d/gdm-welcome; \
+ fi; \
if test $$system = SunOS; then \
- echo "Please add PAM authentication for gdm and gdm-autologin in $(PAM_PREFIX)/pam.conf!"; \
+ echo "Please add PAM authentication for gdm, gdm-autologin and gdm-welcome in $(PAM_PREFIX)/pam.conf!"; \
fi; \
fi
diff --git a/data/gdm-welcome b/data/gdm-welcome
new file mode 100644
index 0000000..8d2ea85
--- /dev/null
+++ b/data/gdm-welcome
@@ -0,0 +1,5 @@
+#%PAM-1.0
+session optional pam_keyinit.so force revoke
+session include system-auth
+session required pam_loginuid.so
+session optional pam_console.so
--
1.7.6