Blob Blame History Raw
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