diff --git a/gdm.spec b/gdm.spec index 97463ce..78862ac 100644 --- a/gdm.spec +++ b/gdm.spec @@ -8,14 +8,13 @@ %define desktop_file_utils_version 0.2.90 %define gail_version 1.2.0 %define nss_version 3.11.1 -%define consolekit_version 0.3.0-9 %define fontconfig_version 2.6.0 %define _default_patch_fuzz 999 Summary: The GNOME Display Manager Name: gdm Version: 3.2.1.1 -Release: 10%{?dist} +Release: 11%{?dist} Epoch: 1 License: GPLv2+ Group: User Interface/X @@ -42,7 +41,7 @@ Requires: system-logos Requires: xorg-x11-server-utils Requires: setxkbmap Requires: xorg-x11-xinit -Requires: ConsoleKit >= %{consolekit_version} +Requires: systemd >= 39 Requires: accountsservice Requires: gnome-settings-daemon >= 2.21.92 Requires: iso-codes @@ -104,6 +103,9 @@ Provides: gdm-plugin-fingerprint = %{epoch}:%{version}-%{release} # already upstream Patch0: auth-fixes.patch +# Multi-seat stuff +Patch50: multi-seat.patch + # Fedora-specific Patch98: plymouth.patch Patch99: gdm-3.0.0-fedora-logo.patch @@ -136,6 +138,7 @@ Development files and headers for writing GDM greeters. %prep %setup -q %patch0 -p1 -b .auth-fixes +%patch50 -p1 -b .multi-seat %patch98 -p1 -b .plymouth %patch99 -p1 -b .fedora-logo @@ -387,6 +390,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_libdir}/girepository-1.0/GdmGreeter-1.0.typelib %changelog +* Tue Feb 7 2012 Lennart Poettering - 1:3.2.1.1-11 +- Add multi-seat patch from gdm git master + * Thu Jan 26 2012 Ray Strode 3.2.1.1-10 - Drop system-icon-theme requirement since we don't depend on it anymore @@ -860,7 +866,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : - Rework "force X on vt1" code to work after the user logs out * Wed Oct 15 2008 Matthias Clasen - 1:2.24.0-9 -- Save some space +- Save some space * Fri Oct 3 2008 Matthias Clasen - 1:2.24.0-8 - Don't show a non-functional help menuitem @@ -1186,7 +1192,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : * Fri Nov 30 2007 Matthias Clasen - 1:2.21.2-0.2007.11.20.4 - Use the new "substack" support in pam to make keyring unlocking work - + * Tue Nov 20 2007 Ray Strode - 1:2.21.2-0.2007.11.20.3 - use metacity for now @@ -1244,7 +1250,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : * Mon Oct 1 2007 Ray Strode - 1:2.20.0-10 - apply upstream patch from Brady Anderson - to fix writing out .dmrc file when setting default language + to fix writing out .dmrc file when setting default language (upstream bug 453916) * Fri Sep 28 2007 Ray Strode - 1:2.20.0-9 @@ -1324,7 +1330,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : - Require gnome-keyring-pam * Mon Aug 6 2007 Ray Strode - 1:2.19.5-5 -- change previous patch to drop even more code +- change previous patch to drop even more code * Mon Aug 6 2007 Ray Strode - 1:2.19.5-4 - turn off dwellmouselistener if devices don't send core events. @@ -1506,7 +1512,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : in gdmsetup * Tue Sep 19 2006 Ray Strode - 1:2.16.0-8.fc6 -- Add as_IN, si_LK to language list (bug 203917) +- Add as_IN, si_LK to language list (bug 203917) * Mon Sep 18 2006 Ray Strode - 1:2.16.0-7.fc6 - fix a problem recently introduced in the smart card forking @@ -1676,7 +1682,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : * Tue Feb 28 2006 Ray Strode - 1:2.13.0.9-1 - Update to 2.13.0.9 -- Use new %%post section, written by +- Use new %%post section, written by Michal Jaegermann (bug 183082) * Sat Feb 25 2006 Ray Strode - 1:2.13.0.8-6 @@ -1732,7 +1738,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : - add new theme by Diana Fong, Máirín Duffy, and me * Mon Jan 16 2006 Ray Strode - 1:2.13.0.4-4 -- improve migration snippet (bug 177443). +- improve migration snippet (bug 177443). * Fri Jan 13 2006 Ray Strode - 1:2.13.0.4-3 - migrate X server configuration for pre-modular X configurations. @@ -1818,7 +1824,7 @@ p * Mon May 23 2005 Ray Strode 1:2.6.0.8-16 - Make sure username/password incorrect message gets displayed (bug 158127). -- reread system locale before starting gdm in early login mode +- reread system locale before starting gdm in early login mode (bug 158376). * Thu May 19 2005 Ray Strode 1:2.6.0.8-15 @@ -1842,7 +1848,7 @@ p - silence %%postun * Tue Apr 26 2005 Ray Strode 1:2.6.0.8-9 -- Change default standard greeter theme to clearlooks and +- Change default standard greeter theme to clearlooks and default graphical greeter theme to Bluecurve specifically. - Change default path values (bug 154280) @@ -1898,7 +1904,7 @@ p user's home directory (fixes bug 149899) * Thu Feb 10 2005 Ray Strode 1:2.6.0.7-2 -- Turn off "switchdesk" mode by default which accidentally got +- Turn off "switchdesk" mode by default which accidentally got turned on by default in 2.6.0.5-4 * Wed Feb 2 2005 Matthias Clasen 1:2.6.0.7-1 @@ -1911,28 +1917,28 @@ p * Thu Dec 9 2004 Dan Walsh 1:2.6.0.5-10 - Remove pam_selinux from gdmsetup pam file -* Wed Dec 1 2004 Ray Strode 1:2.6.0.5-9 -- Look up and use username instead of assuming that user entered +* Wed Dec 1 2004 Ray Strode 1:2.6.0.5-9 +- Look up and use username instead of assuming that user entered login is cannonical. Patch from Mike Patnode (fixes bug 141380). -* Thu Nov 11 2004 Ray Strode 1:2.6.0.5-8 +* Thu Nov 11 2004 Ray Strode 1:2.6.0.5-8 - Sort session list so that default session comes out on top (fixes bug 107324) -* Wed Nov 10 2004 Ray Strode 1:2.6.0.5-7 +* Wed Nov 10 2004 Ray Strode 1:2.6.0.5-7 - Make desktop file symlink instead of absolute (bug 104390) - Add flexiserver back to menus -* Wed Oct 20 2004 Ray Strode 1:2.6.0.5-6 +* Wed Oct 20 2004 Ray Strode 1:2.6.0.5-6 - Clean up xses if the session was successfullly completed. (fixes bug #136382) -* Tue Oct 19 2004 Ray Strode 1:2.6.0.5-5 +* Tue Oct 19 2004 Ray Strode 1:2.6.0.5-5 - Prefer nb_NO over no_NO for Norwegian (fixes bug #136033) * Thu Oct 7 2004 Alexander Larsson - 1:2.6.0.5-4 -- Change default greeter theme to "Default", require +- Change default greeter theme to "Default", require redhat-artwork with Default symlink. * Wed Sep 29 2004 Ray Strode 1:2.6.0.5-3 @@ -2171,14 +2177,14 @@ p * Wed Aug 28 2002 Havoc Pennington - put /usr/X11R6/bin in path for now fixes #72781 - use proper i18n algorithm for word wrap, #71937 -- remove greek text from language picker due to lack +- remove greek text from language picker due to lack of greek font - reorder PAM config file #72657 * Wed Aug 28 2002 Havoc Pennington - improve gdmsetup icon - remove GNOME session, we will instead put it in gnome-session -- apply patch from george to make gdmphotosetup file selector +- apply patch from george to make gdmphotosetup file selector work * Mon Aug 26 2002 Elliot Lee 2.4.0.7-6 @@ -2198,7 +2204,7 @@ p - rename Gnome session to GNOME, this was just bugging me * Thu Aug 8 2002 Havoc Pennington -- 2.4.0.7 with bugfixes George kindly did for me, +- 2.4.0.7 with bugfixes George kindly did for me, including mnemonics for the graphical greeter - use Wonderland gtk theme for the nongraphical greeter - remove patches that are now upstream @@ -2213,7 +2219,7 @@ p * Tue Jun 25 2002 Owen Taylor - Require redhat-artwork, make the default greeter theme Wonderland -- Look for all configuration in .gnome2 not .gnome. This avoids problems +- Look for all configuration in .gnome2 not .gnome. This avoids problems with changes in the set of session/lang. - Remove English from locale.alias, make most locales UTF-8 - Call find_lang with the right name @@ -2295,7 +2301,7 @@ p * Thu Jul 19 2001 Havoc Pennington - depend on usermode, xinitrc - + * Thu Jul 19 2001 Havoc Pennington - build requires pam-devel, should fix #49448 @@ -2315,7 +2321,7 @@ p - upgrade to 2.2.3.1, pray this fixes more than it breaks * Thu Jul 05 2001 Havoc Pennington -- add "rpm" user to those not to show in greeter +- add "rpm" user to those not to show in greeter * Tue Jul 03 2001 Havoc Pennington - Upgrade to 2.2.3 @@ -2325,7 +2331,7 @@ p - Prereq for scrollkeeper-update * Thu May 30 2001 Havoc Pennington -- New CVS snap with the "no weird sessions" options; +- New CVS snap with the "no weird sessions" options; more default settings changes * Wed May 30 2001 Havoc Pennington @@ -2334,8 +2340,8 @@ p * Wed May 30 2001 Havoc Pennington - After, oh, 2 years or so, finally upgrade version and set release to 1. Remove all hacks and patches, pretty much; - this will break a few things, will be putting them back - via GNOME CVS. All changes should go in 'gdm2' module in + this will break a few things, will be putting them back + via GNOME CVS. All changes should go in 'gdm2' module in CVS for now. This RPM enables all kinds of features that I'm going to turn @@ -2371,7 +2377,7 @@ p * Sun Aug 13 2000 Owen Taylor - Return to toplevel main loop and start Xdcmp if enabled - (Bug #16106) + (Bug #16106) * Fri Aug 11 2000 Jonathan Blandford - Up Epoch and release @@ -2417,7 +2423,7 @@ p * Fri Feb 04 2000 Havoc Pennington - Modify Default.session and Failsafe.session not to add -login option to bash - exec the session scripts with the user's shell with a hyphen prepended -- doesn't seem to actually work yet with tcsh, but it doesn't seem to +- doesn't seem to actually work yet with tcsh, but it doesn't seem to break anything. needs a look to see why it doesn't work * Fri Feb 04 2000 Havoc Pennington @@ -2429,12 +2435,12 @@ p - remove docs/gdm-manual.txt which doesn't seem to exist from %doc * Fri Feb 04 2000 Havoc Pennington -- Enhance 8877 fix by not deleting the "Please login" +- Enhance 8877 fix by not deleting the "Please login" message * Fri Feb 04 2000 Havoc Pennington -- Try to fix bug 8877 by clearing the message below - the entry box when the prompt changes. may turn +- Try to fix bug 8877 by clearing the message below + the entry box when the prompt changes. may turn out to be a bad idea. * Mon Jan 17 2000 Elliot Lee @@ -2474,10 +2480,10 @@ p * Mon Apr 19 1999 Michael Fulbright - fix to handling ancient gdm config files with non-standard language specs - dont close display connection for xdmcp connections, else we die if remote - end dies. + end dies. * Fri Apr 16 1999 Michael Fulbright -- fix language handling to set GDM_LANG variable so gnome-session +- fix language handling to set GDM_LANG variable so gnome-session can pick it up * Wed Apr 14 1999 Michael Fulbright diff --git a/multi-seat.patch b/multi-seat.patch new file mode 100644 index 0000000..b966da6 --- /dev/null +++ b/multi-seat.patch @@ -0,0 +1,2372 @@ +From 3ed96cac0c49d0687fc273d11bad51772d8233ed Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 24 Jan 2012 04:16:24 +0100 +Subject: [PATCH 01/11] slave: whitespace cleanup + +--- + daemon/gdm-slave.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c +index 787ef89..c0705fd 100644 +--- a/daemon/gdm-slave.c ++++ b/daemon/gdm-slave.c +@@ -541,8 +541,8 @@ gdm_slave_set_windowpath (GdmSlave *slave) + return; + } + if (XGetWindowProperty (slave->priv->server_display, +- DefaultRootWindow (slave->priv->server_display), prop, 0, 1, +- False, AnyPropertyType, &actualtype, &actualformat, ++ DefaultRootWindow (slave->priv->server_display), prop, 0, 1, ++ False, AnyPropertyType, &actualtype, &actualformat, + &nitems, &bytes_after, &buf)) { + g_debug ("no XFree86_VT property\n"); + return; +-- +1.7.9 + + +From 1a5f9a0f7a65e796e044ff2f3f793e8268d31623 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 13 Jan 2012 03:53:15 +0100 +Subject: [PATCH 02/11] welcome-session: get rid of register-ck-session + property since it is unused + +Nothing was using register-ck-session and it has no effect, hence let's +get rid of this dead code. +--- + daemon/Makefile.am | 6 ------ + daemon/gdm-chooser-session.c | 1 - + daemon/gdm-greeter-session.c | 1 - + daemon/gdm-welcome-session.c | 25 +------------------------ + 4 files changed, 1 insertions(+), 32 deletions(-) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 65e82b8..a153c43 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -115,8 +115,6 @@ gdm_simple_slave_SOURCES = \ + simple-slave-main.c \ + gdm-greeter-server.c \ + gdm-greeter-server.h \ +- ck-connector.h \ +- ck-connector.c \ + gdm-welcome-session.c \ + gdm-welcome-session.h \ + gdm-greeter-session.c \ +@@ -156,8 +154,6 @@ gdm_factory_slave_SOURCES = \ + factory-slave-main.c \ + gdm-greeter-server.c \ + gdm-greeter-server.h \ +- ck-connector.h \ +- ck-connector.c \ + gdm-welcome-session.c \ + gdm-welcome-session.h \ + gdm-greeter-session.c \ +@@ -232,8 +228,6 @@ gdm_xdmcp_chooser_slave_SOURCES = \ + xdmcp-chooser-slave-main.c \ + gdm-chooser-server.c \ + gdm-chooser-server.h \ +- ck-connector.h \ +- ck-connector.c \ + gdm-session.c \ + gdm-session.h \ + gdm-session-direct.c \ +diff --git a/daemon/gdm-chooser-session.c b/daemon/gdm-chooser-session.c +index da0f2ab..6aa60a6 100644 +--- a/daemon/gdm-chooser-session.c ++++ b/daemon/gdm-chooser-session.c +@@ -81,7 +81,6 @@ gdm_chooser_session_new (const char *display_name, + "server-dbus-path", GDM_CHOOSER_SERVER_DBUS_PATH, + "server-dbus-interface", GDM_CHOOSER_SERVER_DBUS_INTERFACE, + "server-env-var-name", "GDM_CHOOSER_DBUS_ADDRESS", +- "register-ck-session", FALSE, + "x11-display-name", display_name, + "x11-display-device", display_device, + "x11-display-hostname", display_hostname, +diff --git a/daemon/gdm-greeter-session.c b/daemon/gdm-greeter-session.c +index 8032065..44259ab 100644 +--- a/daemon/gdm-greeter-session.c ++++ b/daemon/gdm-greeter-session.c +@@ -82,7 +82,6 @@ gdm_greeter_session_new (const char *display_name, + "server-dbus-path", GDM_GREETER_SERVER_DBUS_PATH, + "server-dbus-interface", GDM_GREETER_SERVER_DBUS_INTERFACE, + "server-env-var-name", "GDM_GREETER_DBUS_ADDRESS", +- "register-ck-session", TRUE, + "x11-display-name", display_name, + "x11-display-seat-id", seat_id, + "x11-display-device", display_device, +diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c +index 41144a8..8721fe7 100644 +--- a/daemon/gdm-welcome-session.c ++++ b/daemon/gdm-welcome-session.c +@@ -42,7 +42,6 @@ + #include + + #include "gdm-common.h" +-#include "ck-connector.h" + + #include "gdm-session.h" + #include "gdm-session-direct.h" +@@ -78,7 +77,6 @@ struct GdmWelcomeSessionPrivate + char *server_dbus_path; + char *server_dbus_interface; + char *server_env_var_name; +- gboolean register_ck_session; + + char *server_address; + }; +@@ -98,8 +96,7 @@ enum { + PROP_COMMAND, + PROP_SERVER_DBUS_PATH, + PROP_SERVER_DBUS_INTERFACE, +- PROP_SERVER_ENV_VAR_NAME, +- PROP_REGISTER_CK_SESSION, ++ PROP_SERVER_ENV_VAR_NAME + }; + + enum { +@@ -1040,13 +1037,6 @@ _gdm_welcome_session_set_server_env_var_name (GdmWelcomeSession *welcome_session + } + + static void +-_gdm_welcome_session_set_register_ck_session (GdmWelcomeSession *welcome_session, +- gboolean val) +-{ +- welcome_session->priv->register_ck_session = val; +-} +- +-static void + gdm_welcome_session_set_property (GObject *object, + guint prop_id, + const GValue *value, +@@ -1093,9 +1083,6 @@ gdm_welcome_session_set_property (GObject *object, + case PROP_SERVER_DBUS_INTERFACE: + _gdm_welcome_session_set_server_dbus_interface (self, g_value_get_string (value)); + break; +- case PROP_REGISTER_CK_SESSION: +- _gdm_welcome_session_set_register_ck_session (self, g_value_get_boolean (value)); +- break; + case PROP_SERVER_ENV_VAR_NAME: + _gdm_welcome_session_set_server_env_var_name (self, g_value_get_string (value)); + break; +@@ -1155,9 +1142,6 @@ gdm_welcome_session_get_property (GObject *object, + case PROP_SERVER_DBUS_INTERFACE: + g_value_set_string (value, self->priv->server_dbus_interface); + break; +- case PROP_REGISTER_CK_SESSION: +- g_value_set_boolean (value, self->priv->register_ck_session); +- break; + case PROP_SERVER_ENV_VAR_NAME: + g_value_set_string (value, self->priv->server_env_var_name); + break; +@@ -1279,13 +1263,6 @@ gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass) + "command", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +- g_object_class_install_property (object_class, +- PROP_REGISTER_CK_SESSION, +- g_param_spec_boolean ("register-ck-session", +- NULL, +- NULL, +- FALSE, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + signals [STARTED] = + g_signal_new ("started", + G_OBJECT_CLASS_TYPE (object_class), +-- +1.7.9 + + +From 02697e774c2f669d1d4109fc1de975407740409b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 01:18:55 +0200 +Subject: [PATCH 03/11] build-sys: add configure option --with-systemd + +--- + configure.ac | 25 +++++++++++++++++++++++++ + 1 files changed, 25 insertions(+), 0 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 30397c5..dec31a9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -272,6 +272,11 @@ AC_ARG_WITH(console-kit, + [Add ConsoleKit support @<:@default=auto@:>@]),, + with_console_kit=auto) + ++AC_ARG_WITH(systemd, ++ AS_HELP_STRING([--with-systemd], ++ [Add systemd support @<:@default=auto@:>@]),, ++ with_systemd=auto) ++ + AC_ARG_WITH(at-spi-registryd-directory, + AS_HELP_STRING([--with-at-spi-registryd-directory], + [Specify the directory of at-spi-registryd @<:@default=libexecdir@:>@])],, +@@ -927,6 +932,25 @@ AM_CONDITIONAL(WITH_CONSOLE_KIT, test x$use_console_kit = xyes) + AC_SUBST(WITH_CONSOLE_KIT) + + dnl --------------------------------------------------------------------------- ++dnl - Check for systemd support ++dnl --------------------------------------------------------------------------- ++ ++use_systemd=no ++if test "x$with_systemd" != "xno" ; then ++ PKG_CHECK_MODULES(SYSTEMD, ++ libsystemd-daemon ++ libsystemd-login ++ ) ++ AC_SUBST(SYSTEMD_CFLAGS) ++ AC_SUBST(SYSTEMD_LIBS) ++ ++ use_systemd=yes ++ AC_DEFINE(WITH_SYSTEMD, 1, [Define to enable systemd support]) ++fi ++AM_CONDITIONAL(WITH_SYSTEMD, test x$use_systemd = xyes) ++AC_SUBST(WITH_SYSTEMD) ++ ++dnl --------------------------------------------------------------------------- + dnl - Check for D-Bus + dnl --------------------------------------------------------------------------- + +@@ -1511,6 +1535,7 @@ echo \ + XDMCP support: ${XDMCP_SUPPORT} + SELinux support: ${with_selinux} + ConsoleKit support: ${use_console_kit} ++ systemd support: ${use_systemd} + UPower support: ${have_upower} + Build with RBAC: ${msg_rbac_shutdown} + " +-- +1.7.9 + + +From a58b27ff573109f0d9a8971fbc80e797d6cc2733 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 24 Jan 2012 04:15:26 +0100 +Subject: [PATCH 04/11] slave: add native systemd implementations of + locking/session activation + +--- + daemon/Makefile.am | 5 + + daemon/gdm-slave.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 242 insertions(+), 14 deletions(-) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index a153c43..43d416e 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -24,6 +24,7 @@ AM_CPPFLAGS = \ + $(XLIB_CFLAGS) \ + $(WARN_CFLAGS) \ + $(DEBUG_CFLAGS) \ ++ $(SYSTEMD_CFLAGS) \ + -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ + $(NULL) + +@@ -148,6 +149,7 @@ gdm_simple_slave_LDADD = \ + $(DAEMON_LIBS) \ + $(EXTRA_DAEMON_LIBS) \ + $(LIBXKLAVIER_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + gdm_factory_slave_SOURCES = \ +@@ -188,6 +190,7 @@ gdm_factory_slave_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(XLIB_LIBS) \ + $(DAEMON_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + gdm_product_slave_SOURCES = \ +@@ -222,6 +225,7 @@ gdm_product_slave_LDADD = \ + $(DAEMON_LIBS) \ + $(EXTRA_DAEMON_LIBS) \ + $(LIBXKLAVIER_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + gdm_xdmcp_chooser_slave_SOURCES = \ +@@ -254,6 +258,7 @@ gdm_xdmcp_chooser_slave_LDADD = \ + $(DAEMON_LIBS) \ + $(EXTRA_DAEMON_LIBS) \ + $(LIBXKLAVIER_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(top_builddir)/common/libgdmcommon.la \ + $(NULL) + +diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c +index c0705fd..371b9bd 100644 +--- a/daemon/gdm-slave.c ++++ b/daemon/gdm-slave.c +@@ -51,6 +51,11 @@ + #include + #endif + ++#ifdef WITH_SYSTEMD ++#include ++#include ++#endif ++ + #include "gdm-common.h" + #include "gdm-xerrors.h" + +@@ -1198,6 +1203,8 @@ _get_uid_and_gid_for_user (const char *username, + return TRUE; + } + ++#ifdef WITH_CONSOLE_KIT ++ + static gboolean + x11_session_is_on_seat (GdmSlave *slave, + const char *session_id, +@@ -1295,9 +1302,63 @@ x11_session_is_on_seat (GdmSlave *slave, + return ret; + } + +-char * +-gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, +- const char *username) ++#endif ++ ++#ifdef WITH_SYSTEMD ++static char* ++gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave *slave, ++ const char *username) ++{ ++ int res, i; ++ char **sessions; ++ uid_t uid; ++ char *primary_ssid; ++ ++ primary_ssid = NULL; ++ ++ res = sd_seat_can_multi_session (slave->priv->display_seat_id); ++ if (res < 0) { ++ g_warning ("GdmSlave: Failed to determine whether seat is multi-session capable: %s", strerror (-res)); ++ return NULL; ++ } else if (res == 0) { ++ g_debug ("GdmSlave: seat is unable to activate sessions"); ++ return NULL; ++ } ++ ++ if (! _get_uid_and_gid_for_user (username, &uid, NULL)) { ++ g_debug ("GdmSlave: unable to determine uid for user: %s", username); ++ return NULL; ++ } ++ ++ res = sd_seat_get_sessions (slave->priv->display_seat_id, &sessions, NULL, NULL); ++ if (res < 0) { ++ g_warning ("GdmSlave: Failed to get sessions on seat: %s", strerror (-res)); ++ return NULL; ++ } ++ ++ for (i = 0; sessions[i] != NULL; i++) { ++ ++ if (primary_ssid == NULL) { ++ uid_t other; ++ ++ res = sd_session_get_uid (sessions[i], &other); ++ if (res > 0 && other == uid) { ++ primary_ssid = g_strdup (sessions[i]); ++ } ++ } ++ ++ free (sessions[i]); ++ } ++ ++ free (sessions); ++ return primary_ssid; ++} ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static char * ++gdm_slave_get_primary_session_id_for_user_from_ck (GdmSlave *slave, ++ const char *username) + { + gboolean res; + gboolean can_activate_sessions; +@@ -1309,11 +1370,6 @@ gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, + int i; + uid_t uid; + +- if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') { +- g_debug ("GdmSlave: display seat ID is not set; can't switch sessions"); +- return NULL; +- } +- + manager_proxy = NULL; + primary_ssid = NULL; + sessions = NULL; +@@ -1396,11 +1452,91 @@ gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, + + return primary_ssid; + } ++#endif ++ ++char * ++gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, ++ const char *username) ++{ ++ ++ if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') { ++ g_debug ("GdmSlave: display seat ID is not set; can't switch sessions"); ++ return NULL; ++ } + ++#ifdef WITH_SYSTEMD ++ if (sd_booted () > 0) { ++ return gdm_slave_get_primary_session_id_for_user_from_systemd (slave, username); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return gdm_slave_get_primary_session_id_for_user_from_ck (slave, username); ++#else ++ return NULL; ++#endif ++} ++ ++#ifdef WITH_SYSTEMD + static gboolean +-activate_session_id (GdmSlave *slave, +- const char *seat_id, +- const char *session_id) ++activate_session_id_for_systemd (GdmSlave *slave, ++ const char *seat_id, ++ const char *session_id) ++{ ++ DBusError local_error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ gboolean ret; ++ ++ ret = FALSE; ++ reply = NULL; ++ ++ dbus_error_init (&local_error); ++ ++ message = dbus_message_new_method_call ("org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "ActivateSessionOnSeat"); ++ if (message == NULL) { ++ goto out; ++ } ++ ++ if (! dbus_message_append_args (message, ++ DBUS_TYPE_STRING, &session_id, ++ DBUS_TYPE_STRING, &seat_id, ++ DBUS_TYPE_INVALID)) { ++ goto out; ++ } ++ ++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (slave->priv->connection), ++ message, ++ -1, ++ &local_error); ++ if (dbus_error_is_set (&local_error)) { ++ g_warning ("GdmSlave: Unable to activate session: %s", local_error.message); ++ dbus_error_free (&local_error); ++ goto out; ++ } ++ ++ ret = TRUE; ++ ++ out: ++ if (message != NULL) { ++ dbus_message_unref (message); ++ } ++ if (reply != NULL) { ++ dbus_message_unref (reply); ++ } ++ ++ return ret; ++} ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++activate_session_id_for_ck (GdmSlave *slave, ++ const char *seat_id, ++ const char *session_id) + { + DBusError local_error; + DBusMessage *message; +@@ -1448,16 +1584,82 @@ activate_session_id (GdmSlave *slave, + + return ret; + } ++#endif ++ ++static gboolean ++activate_session_id (GdmSlave *slave, ++ const char *seat_id, ++ const char *session_id) ++{ ++ ++#ifdef WITH_SYSTEMD ++ if (sd_booted () > 0) { ++ return activate_session_id_for_systemd (slave, seat_id, session_id); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return activate_session_id_for_ck (slave, seat_id, session_id); ++#else ++ return FALSE; ++#endif ++} + ++#ifdef WITH_SYSTEMD + static gboolean +-session_unlock (GdmSlave *slave, +- const char *ssid) ++session_unlock_for_systemd (GdmSlave *slave, ++ const char *ssid) ++{ ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ ++ dbus_error_init (&error); ++ ++ message = dbus_message_new_method_call ("org.freedesktop.login", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "UnlockSession"); ++ ++ if (message == NULL) { ++ g_debug ("GdmSlave: couldn't allocate the D-Bus message"); ++ return FALSE; ++ } ++ ++ if (! dbus_message_append_args (message, ++ DBUS_TYPE_STRING, &ssid, ++ DBUS_TYPE_INVALID)) { ++ g_debug ("GdmSlave: couldn't attach the D-Bus message data"); ++ return FALSE; ++ } ++ ++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (slave->priv->connection), ++ message, ++ -1, &error); ++ dbus_message_unref(message); ++ if (reply != NULL) { ++ dbus_message_unref(reply); ++ } ++ ++ if (dbus_error_is_set (&error)) { ++ g_warning ("GdmSlave: Unable to unlock session: %s", error.message); ++ dbus_error_free (&error); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++session_unlock_for_ck (GdmSlave *slave, ++ const char *ssid) + { + DBusError error; + DBusMessage *message; + DBusMessage *reply; + +- g_debug ("ConsoleKit: Unlocking session %s", ssid); + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, +@@ -1485,6 +1687,27 @@ session_unlock (GdmSlave *slave, + + return TRUE; + } ++#endif ++ ++static gboolean ++session_unlock (GdmSlave *slave, ++ const char *ssid) ++{ ++ ++ g_debug ("ConsoleKit: Unlocking session %s", ssid); ++ ++#ifdef WITH_SYSTEMD ++ if (sd_booted () > 0) { ++ return session_unlock_for_systemd (slave, ssid); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return session_unlock_for_ck (slave, ssid); ++#else ++ return TRUE; ++#endif ++} + + gboolean + gdm_slave_switch_to_user_session (GdmSlave *slave, +-- +1.7.9 + + +From c77c03e6ca67ea670de89babbbfd9648b2fec9bd Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 01:27:22 +0200 +Subject: [PATCH 05/11] build-sys: make CK support optional + +--- + daemon/Makefile.am | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 43d416e..b228fea 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -264,8 +264,6 @@ gdm_xdmcp_chooser_slave_LDADD = \ + + gdm_session_worker_SOURCES = \ + session-worker-main.c \ +- ck-connector.h \ +- ck-connector.c \ + gdm-session-settings.h \ + gdm-session-settings.c \ + gdm-session-auditor.h \ +@@ -274,6 +272,12 @@ gdm_session_worker_SOURCES = \ + gdm-session-worker.c \ + $(NULL) + ++if WITH_CONSOLE_KIT ++gdm_session_worker_SOURCES += \ ++ ck-connector.h \ ++ ck-connector.c ++endif ++ + if HAVE_LIBAUDIT + gdm_session_worker_SOURCES += gdm-session-linux-auditor.h \ + gdm-session-linux-auditor.c +-- +1.7.9 + + +From 54abef19f0b338d7c57c4629f6ca2cf441bcb553 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 01:30:09 +0200 +Subject: [PATCH 06/11] slave: pass seat id from product/simple slave to + worker, via the direct session +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Pass seat id from product and simple slave to the direct sessions +created by it (along with the other display meta data we pass already). + +Pass seat id from session to worker (via D-Bus) along with the other +display meta data. + +We need the seat information for the PAM conversation (later patch) +hence we need to pass it from the slaves down to the workers. + +(Note that the seat ID has always been passed from the display to the +slave, we just need to pass it on the worker now, so that the chain is +complete: display → slave → session → worker) +--- + daemon/gdm-product-slave.c | 3 ++ + daemon/gdm-session-direct.c | 60 ++++++++++++++++++++++++++++++++++++++++++ + daemon/gdm-session-direct.h | 2 + + daemon/gdm-session-worker.c | 12 +++++++- + daemon/gdm-simple-slave.c | 3 ++ + daemon/gdm-welcome-session.c | 1 + + daemon/test-session.c | 1 + + 7 files changed, 81 insertions(+), 1 deletions(-) + +diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c +index d56a74b..629c6e7 100644 +--- a/daemon/gdm-product-slave.c ++++ b/daemon/gdm-product-slave.c +@@ -998,6 +998,7 @@ create_new_session (GdmProductSlave *slave) + char *display_name; + char *display_hostname; + char *display_device; ++ char *display_seat_id; + char *display_x11_authority_file; + + g_debug ("GdmProductSlave: Creating new session"); +@@ -1008,6 +1009,7 @@ create_new_session (GdmProductSlave *slave) + "display-hostname", &display_hostname, + "display-is-local", &display_is_local, + "display-x11-authority-file", &display_x11_authority_file, ++ "display-seat-id", &display_seat_id, + NULL); + + /* FIXME: we don't yet have a display device! */ +@@ -1017,6 +1019,7 @@ create_new_session (GdmProductSlave *slave) + display_name, + display_hostname, + display_device, ++ display_seat_id, + display_x11_authority_file, + display_is_local); + g_free (display_id); +diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c +index bb2bff8..9f750f2 100644 +--- a/daemon/gdm-session-direct.c ++++ b/daemon/gdm-session-direct.c +@@ -103,6 +103,7 @@ struct _GdmSessionDirectPrivate + char *display_name; + char *display_hostname; + char *display_device; ++ char *display_seat_id; + char *display_x11_authority_file; + gboolean display_is_local; + +@@ -121,6 +122,7 @@ enum { + PROP_DISPLAY_HOSTNAME, + PROP_DISPLAY_IS_LOCAL, + PROP_DISPLAY_DEVICE, ++ PROP_DISPLAY_SEAT_ID, + PROP_DISPLAY_X11_AUTHORITY_FILE, + PROP_USER_X11_AUTHORITY_FILE, + }; +@@ -1389,6 +1391,7 @@ do_introspect (DBusConnection *connection, + " \n" + " \n" + " \n" ++ " \n" + " \n" + " \n" + " \n" +@@ -1396,6 +1399,7 @@ do_introspect (DBusConnection *connection, + " \n" + " \n" + " \n" ++ " \n" + " \n" + " \n" + " \n" +@@ -1404,6 +1408,7 @@ do_introspect (DBusConnection *connection, + " \n" + " \n" + " \n" ++ " \n" + " \n" + " \n" + " \n" +@@ -1975,6 +1980,7 @@ send_setup (GdmSessionDirect *session, + DBusMessageIter iter; + const char *display_name; + const char *display_device; ++ const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + GdmSessionConversation *conversation; +@@ -1996,6 +2002,11 @@ send_setup (GdmSessionDirect *session, + } else { + display_device = ""; + } ++ if (session->priv->display_seat_id != NULL) { ++ display_seat_id = session->priv->display_seat_id; ++ } else { ++ display_seat_id = ""; ++ } + if (session->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = session->priv->display_x11_authority_file; + } else { +@@ -2012,6 +2023,7 @@ send_setup (GdmSessionDirect *session, + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); ++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + +@@ -2031,6 +2043,7 @@ send_setup_for_user (GdmSessionDirect *session, + DBusMessageIter iter; + const char *display_name; + const char *display_device; ++ const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + const char *selected_user; +@@ -2053,6 +2066,11 @@ send_setup_for_user (GdmSessionDirect *session, + } else { + display_device = ""; + } ++ if (session->priv->display_seat_id != NULL) { ++ display_seat_id = session->priv->display_seat_id; ++ } else { ++ display_seat_id = ""; ++ } + if (session->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = session->priv->display_x11_authority_file; + } else { +@@ -2074,6 +2092,7 @@ send_setup_for_user (GdmSessionDirect *session, + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); ++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user); +@@ -2095,6 +2114,7 @@ send_setup_for_program (GdmSessionDirect *session, + DBusMessageIter iter; + const char *display_name; + const char *display_device; ++ const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + GdmSessionConversation *conversation; +@@ -2116,6 +2136,11 @@ send_setup_for_program (GdmSessionDirect *session, + } else { + display_device = ""; + } ++ if (session->priv->display_seat_id != NULL) { ++ display_seat_id = session->priv->display_seat_id; ++ } else { ++ display_seat_id = ""; ++ } + if (session->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = session->priv->display_x11_authority_file; + } else { +@@ -2132,6 +2157,7 @@ send_setup_for_program (GdmSessionDirect *session, + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); ++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &log_file); +@@ -2587,6 +2613,14 @@ gdm_session_direct_get_display_device (GdmSessionDirect *session) + return g_strdup (session->priv->display_device); + } + ++char * ++gdm_session_direct_get_display_seat_id (GdmSessionDirect *session) ++{ ++ g_return_val_if_fail (session != NULL, NULL); ++ ++ return g_strdup (session->priv->display_seat_id); ++} ++ + gboolean + gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct) + { +@@ -2754,6 +2788,14 @@ _gdm_session_direct_set_display_device (GdmSessionDirect *session, + } + + static void ++_gdm_session_direct_set_display_seat_id (GdmSessionDirect *session, ++ const char *name) ++{ ++ g_free (session->priv->display_seat_id); ++ session->priv->display_seat_id = g_strdup (name); ++} ++ ++static void + _gdm_session_direct_set_user_x11_authority_file (GdmSessionDirect *session, + const char *name) + { +@@ -2799,6 +2841,9 @@ gdm_session_direct_set_property (GObject *object, + case PROP_DISPLAY_DEVICE: + _gdm_session_direct_set_display_device (self, g_value_get_string (value)); + break; ++ case PROP_DISPLAY_SEAT_ID: ++ _gdm_session_direct_set_display_seat_id (self, g_value_get_string (value)); ++ break; + case PROP_USER_X11_AUTHORITY_FILE: + _gdm_session_direct_set_user_x11_authority_file (self, g_value_get_string (value)); + break; +@@ -2837,6 +2882,9 @@ gdm_session_direct_get_property (GObject *object, + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, self->priv->display_device); + break; ++ case PROP_DISPLAY_SEAT_ID: ++ g_value_set_string (value, self->priv->display_seat_id); ++ break; + case PROP_USER_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->user_x11_authority_file); + break; +@@ -2875,6 +2923,9 @@ gdm_session_direct_dispose (GObject *object) + g_free (session->priv->display_device); + session->priv->display_device = NULL; + ++ g_free (session->priv->display_seat_id); ++ session->priv->display_seat_id = NULL; ++ + g_free (session->priv->display_x11_authority_file); + session->priv->display_x11_authority_file = NULL; + +@@ -3063,6 +3114,13 @@ gdm_session_direct_class_init (GdmSessionDirectClass *session_class) + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + ++ g_object_class_install_property (object_class, ++ PROP_DISPLAY_SEAT_ID, ++ g_param_spec_string ("display-seat-id", ++ "display seat id", ++ "display seat id", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + dbus_g_object_type_install_info (GDM_TYPE_SESSION_DIRECT, &dbus_glib_gdm_session_direct_object_info); + } +@@ -3072,6 +3130,7 @@ gdm_session_direct_new (const char *display_id, + const char *display_name, + const char *display_hostname, + const char *display_device, ++ const char *display_seat_id, + const char *display_x11_authority_file, + gboolean display_is_local) + { +@@ -3082,6 +3141,7 @@ gdm_session_direct_new (const char *display_id, + "display-name", display_name, + "display-hostname", display_hostname, + "display-device", display_device, ++ "display-seat-id", display_seat_id, + "display-x11-authority-file", display_x11_authority_file, + "display-is-local", display_is_local, + NULL); +diff --git a/daemon/gdm-session-direct.h b/daemon/gdm-session-direct.h +index 8023bf9..e35fa35 100644 +--- a/daemon/gdm-session-direct.h ++++ b/daemon/gdm-session-direct.h +@@ -52,11 +52,13 @@ GdmSessionDirect * gdm_session_direct_new (const char *disp + const char *display_name, + const char *display_hostname, + const char *display_device, ++ const char *display_seat_id, + const char *display_x11_authority_file, + gboolean display_is_local) G_GNUC_MALLOC; + + char * gdm_session_direct_get_username (GdmSessionDirect *session_direct); + char * gdm_session_direct_get_display_device (GdmSessionDirect *session_direct); ++char * gdm_session_direct_get_display_seat_id (GdmSessionDirect *session_direct); + gboolean gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct); + + /* Exported methods */ +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index c402e6c..1fe0aaf 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -118,6 +118,7 @@ struct GdmSessionWorkerPrivate + char *x11_display_name; + char *x11_authority_file; + char *display_device; ++ char *display_seat_id; + char *hostname; + char *username; + char *log_file; +@@ -2494,6 +2495,7 @@ on_setup (GdmSessionWorker *worker, + const char *x11_display_name; + const char *x11_authority_file; + const char *console; ++ const char *seat_id; + const char *hostname; + dbus_bool_t res; + +@@ -2508,6 +2510,7 @@ on_setup (GdmSessionWorker *worker, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &x11_display_name, + DBUS_TYPE_STRING, &console, ++ DBUS_TYPE_STRING, &seat_id, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_STRING, &x11_authority_file, + DBUS_TYPE_INVALID); +@@ -2516,6 +2519,7 @@ on_setup (GdmSessionWorker *worker, + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); ++ worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->username = NULL; + +@@ -2536,6 +2540,7 @@ on_setup_for_user (GdmSessionWorker *worker, + const char *x11_display_name; + const char *x11_authority_file; + const char *console; ++ const char *seat_id; + const char *hostname; + const char *username; + dbus_bool_t res; +@@ -2551,6 +2556,7 @@ on_setup_for_user (GdmSessionWorker *worker, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &x11_display_name, + DBUS_TYPE_STRING, &console, ++ DBUS_TYPE_STRING, &seat_id, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_STRING, &x11_authority_file, + DBUS_TYPE_STRING, &username, +@@ -2560,6 +2566,7 @@ on_setup_for_user (GdmSessionWorker *worker, + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); ++ worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->username = g_strdup (username); + +@@ -2598,6 +2605,7 @@ on_setup_for_program (GdmSessionWorker *worker, + char *service; + char *x11_display_name; + char *console; ++ char *seat_id; + char *hostname; + char *x11_authority_file; + char *log_file; +@@ -2614,6 +2622,7 @@ on_setup_for_program (GdmSessionWorker *worker, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &x11_display_name, + DBUS_TYPE_STRING, &console, ++ DBUS_TYPE_STRING, &seat_id, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_STRING, &x11_authority_file, + DBUS_TYPE_STRING, &log_file, +@@ -2627,6 +2636,7 @@ on_setup_for_program (GdmSessionWorker *worker, + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->hostname = g_strdup (hostname); + worker->priv->display_device = g_strdup (console); ++ worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->log_file = g_strdup (log_file); + worker->priv->is_program_session = TRUE; +@@ -2945,6 +2955,7 @@ gdm_session_worker_finalize (GObject *object) + g_free (worker->priv->x11_display_name); + g_free (worker->priv->x11_authority_file); + g_free (worker->priv->display_device); ++ g_free (worker->priv->display_seat_id); + g_free (worker->priv->hostname); + g_free (worker->priv->username); + g_free (worker->priv->server_address); +@@ -2964,4 +2975,3 @@ gdm_session_worker_new (const char *address) + + return GDM_SESSION_WORKER (object); + } +- +diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c +index b9165fd..873b7f9 100644 +--- a/daemon/gdm-simple-slave.c ++++ b/daemon/gdm-simple-slave.c +@@ -750,6 +750,7 @@ create_new_session (GdmSimpleSlave *slave) + char *display_name; + char *display_hostname; + char *display_device; ++ char *display_seat_id; + char *display_x11_authority_file; + + g_debug ("GdmSimpleSlave: Creating new session"); +@@ -760,6 +761,7 @@ create_new_session (GdmSimpleSlave *slave) + "display-hostname", &display_hostname, + "display-is-local", &display_is_local, + "display-x11-authority-file", &display_x11_authority_file, ++ "display-seat-id", &display_seat_id, + NULL); + + display_device = NULL; +@@ -771,6 +773,7 @@ create_new_session (GdmSimpleSlave *slave) + display_name, + display_hostname, + display_device, ++ display_seat_id, + display_x11_authority_file, + display_is_local); + g_free (display_id); +diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c +index 8721fe7..26af552 100644 +--- a/daemon/gdm-welcome-session.c ++++ b/daemon/gdm-welcome-session.c +@@ -849,6 +849,7 @@ gdm_welcome_session_start (GdmWelcomeSession *welcome_session) + welcome_session->priv->x11_display_name, + welcome_session->priv->x11_display_hostname, + welcome_session->priv->x11_display_device, ++ welcome_session->priv->x11_display_seat_id, + welcome_session->priv->x11_authority_file, + welcome_session->priv->x11_display_is_local)); + +diff --git a/daemon/test-session.c b/daemon/test-session.c +index fe78230..f75d5ed 100644 +--- a/daemon/test-session.c ++++ b/daemon/test-session.c +@@ -268,6 +268,7 @@ main (int argc, + ":0", + g_get_host_name (), + ttyname (STDIN_FILENO), ++ "", + getenv("XAUTHORITY"), + TRUE); + g_debug ("GdmSessionDirect object created successfully"); +-- +1.7.9 + + +From 69a8b09c993669e324c785be463136313be2cdb4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 01:31:16 +0200 +Subject: [PATCH 07/11] pam: pass XDG_SEAT env var into PAM to inform PAM + modules about seat id + +This optionally replaces the current CK session registration logic with +support for passing seat information to pam_systemd (and hence rely on +pam_systemd's session registration). + +With this patch applied we can register sessions in systemd and in CK +with the same binary. +--- + daemon/Makefile.am | 1 + + daemon/gdm-session-worker.c | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+), 0 deletions(-) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index b228fea..8f8eedf 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -296,6 +296,7 @@ gdm_session_worker_LDFLAGS = \ + gdm_session_worker_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(DAEMON_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + sbin_PROGRAMS = \ +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index 1fe0aaf..acf820c 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -46,7 +46,13 @@ + + #include + ++#ifdef WITH_SYSTEMD ++#include ++#endif ++ ++#ifdef WITH_CONSOLE_KIT + #include "ck-connector.h" ++#endif + + #include "gdm-common.h" + #include "gdm-log.h" +@@ -107,7 +113,9 @@ struct GdmSessionWorkerPrivate + + int exit_code; + ++#ifdef WITH_CONSOLE_KIT + CkConnector *ckc; ++#endif + pam_handle_t *pam_handle; + + GPid child_pid; +@@ -151,8 +159,13 @@ static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass); + static void gdm_session_worker_init (GdmSessionWorker *session_worker); + static void gdm_session_worker_finalize (GObject *object); + ++static void gdm_session_worker_set_environment_variable (GdmSessionWorker *worker, ++ const char *key, ++ const char *value); ++ + static void queue_state_change (GdmSessionWorker *worker); + ++ + typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int, + const struct pam_message **, + struct pam_response **, +@@ -171,6 +184,7 @@ gdm_session_worker_error_quark (void) + return error_quark; + } + ++#ifdef WITH_CONSOLE_KIT + static gboolean + open_ck_session (GdmSessionWorker *worker) + { +@@ -257,6 +271,7 @@ open_ck_session (GdmSessionWorker *worker) + out: + return ret; + } ++#endif + + /* adapted from glib script_execute */ + static void +@@ -1057,6 +1072,7 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + const char *x11_display_name, + const char *x11_authority_file, + const char *display_device, ++ const char *seat_id, + GError **error) + { + struct pam_conv pam_conversation; +@@ -1138,6 +1154,13 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + goto out; + } + ++#ifdef WITH_SYSTEMD ++ /* set seat ID */ ++ if (seat_id != NULL && seat_id[0] != '\0' && sd_booted() > 0) { ++ gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id); ++ } ++#endif ++ + #ifdef PAM_XDISPLAY + /* set XDISPLAY */ + error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name); +@@ -1571,6 +1594,13 @@ register_ck_session (GdmSessionWorker *worker) + const char *session_cookie; + gboolean res; + ++#ifdef WITH_SYSTEMD ++ if (sd_booted() > 0) { ++ return; ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT + session_cookie = NULL; + res = open_ck_session (worker); + if (res) { +@@ -1581,6 +1611,7 @@ register_ck_session (GdmSessionWorker *worker) + "XDG_SESSION_COOKIE", + session_cookie); + } ++#endif + } + + static void +@@ -1611,11 +1642,13 @@ session_worker_child_watch (GPid pid, + num); + } + ++#ifdef WITH_CONSOLE_KIT + if (worker->priv->ckc != NULL) { + ck_connector_close_session (worker->priv->ckc, NULL); + ck_connector_unref (worker->priv->ckc); + worker->priv->ckc = NULL; + } ++#endif + + gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); + +@@ -2140,6 +2173,7 @@ do_setup (GdmSessionWorker *worker) + worker->priv->x11_display_name, + worker->priv->x11_authority_file, + worker->priv->display_device, ++ worker->priv->display_seat_id, + &error); + if (! res) { + if (g_error_matches (error, +-- +1.7.9 + + +From 6e9fb3fb4df7d05c803cc01fe638eb9cf88c4beb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 01:32:54 +0200 +Subject: [PATCH 08/11] local-display-factory: subscribe to new seats being + created and removed + +logind will notify us when ever a new seat becomes available in the +system, or an existing seat is removed. We simply create a new display +for each seat showing up and remove a display when a seat goes away. +--- + daemon/Makefile.am | 1 + + daemon/gdm-local-display-factory.c | 239 +++++++++++++++++++++++++++++++++--- + 2 files changed, 224 insertions(+), 16 deletions(-) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 8f8eedf..ffbaf9b 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -363,6 +363,7 @@ gdm_binary_LDADD = \ + $(DAEMON_LIBS) \ + $(XDMCP_LIBS) \ + $(LIBWRAP_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + if WITH_CONSOLE_KIT +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 349c7b2..988b2ff 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -27,6 +27,13 @@ + #include + #include + ++#include ++#include ++ ++#ifdef WITH_SYSTEMD ++#include ++#endif ++ + #include "gdm-display-factory.h" + #include "gdm-local-display-factory.h" + #include "gdm-local-display-factory-glue.h" +@@ -64,7 +71,8 @@ static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryC + static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); + static void gdm_local_display_factory_finalize (GObject *object); + +-static GdmDisplay *create_display (GdmLocalDisplayFactory *factory); ++static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, ++ const char *seat_id); + + static gpointer local_display_factory_object = NULL; + +@@ -282,6 +290,7 @@ on_static_display_status_changed (GdmDisplay *display, + int status; + GdmDisplayStore *store; + int num; ++ char *seat_id = NULL; + + num = -1; + gdm_display_get_x11_display_number (display, &num, NULL); +@@ -289,6 +298,8 @@ on_static_display_status_changed (GdmDisplay *display, + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + ++ g_object_get (display, "seat-id", &seat_id, NULL); ++ + status = gdm_display_get_status (display); + + g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status); +@@ -300,7 +311,7 @@ on_static_display_status_changed (GdmDisplay *display, + gdm_display_store_remove (store, display); + /* reset num failures */ + factory->priv->num_failures = 0; +- create_display (factory); ++ create_display (factory, seat_id); + break; + case GDM_DISPLAY_FAILED: + /* leave the display number in factory->priv->displays +@@ -313,7 +324,7 @@ on_static_display_status_changed (GdmDisplay *display, + /* FIXME: should monitor hardware changes to + try again when seats change */ + } else { +- create_display (factory); ++ create_display (factory, seat_id); + } + break; + case GDM_DISPLAY_UNMANAGED: +@@ -326,13 +337,44 @@ on_static_display_status_changed (GdmDisplay *display, + g_assert_not_reached (); + break; + } ++ ++ g_free (seat_id); ++} ++ ++static gboolean ++lookup_by_seat_id (const char *id, ++ GdmDisplay *display, ++ gpointer user_data) ++{ ++ const char *looking_for = user_data; ++ char *current; ++ gboolean res; ++ ++ g_object_get (G_OBJECT (display), "seat-id", ¤t, NULL); ++ ++ res = g_strcmp0 (current, looking_for) == 0; ++ ++ g_free(current); ++ ++ return res; + } + + static GdmDisplay * +-create_display (GdmLocalDisplayFactory *factory) ++create_display (GdmLocalDisplayFactory *factory, ++ const char *seat_id) + { +- GdmDisplay *display; +- guint32 num; ++ GdmDisplayStore *store; ++ GdmDisplay *display; ++ guint32 num; ++ ++ /* Ensure we don't create the same display more than once */ ++ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); ++ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); ++ if (display != NULL) { ++ return NULL; ++ } ++ ++ g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); + + num = take_next_display_number (factory); + +@@ -342,8 +384,7 @@ create_display (GdmLocalDisplayFactory *factory) + display = gdm_static_display_new (num); + #endif + +- /* FIXME: don't hardcode seat1? */ +- g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL); ++ g_object_set (display, "seat-id", seat_id, NULL); + + g_signal_connect (display, + "notify::status", +@@ -362,24 +403,182 @@ create_display (GdmLocalDisplayFactory *factory) + return display; + } + ++#ifdef WITH_SYSTEMD ++ ++static void ++delete_display (GdmLocalDisplayFactory *factory, ++ const char *seat_id) { ++ ++ GdmDisplayStore *store; ++ ++ g_debug ("GdmLocalDisplayFactory: Removing displays on seat %s", seat_id); ++ ++ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); ++ gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); ++} ++ ++static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory) ++{ ++ DBusError error; ++ DBusMessage *message, *reply; ++ DBusMessageIter iter, sub, sub2; ++ ++ dbus_error_init (&error); ++ ++ message = dbus_message_new_method_call ( ++ "org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "ListSeats"); ++ if (message == NULL) { ++ g_warning ("GdmLocalDisplayFactory: Failed to allocate message"); ++ return FALSE; ++ } ++ ++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (factory->priv->connection), message, -1, &error); ++ dbus_message_unref (message); ++ ++ if (reply == NULL) { ++ g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error.message); ++ dbus_error_free (&error); ++ return FALSE; ++ } ++ ++ if (!dbus_message_iter_init (reply, &iter) || ++ dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY || ++ dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRUCT) { ++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply."); ++ dbus_message_unref (reply); ++ return FALSE; ++ } ++ ++ dbus_message_iter_recurse (&iter, &sub); ++ ++ while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) { ++ const char *seat; ++ ++ if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_STRUCT) { ++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply."); ++ dbus_message_unref (reply); ++ return FALSE; ++ } ++ ++ dbus_message_iter_recurse (&sub, &sub2); ++ ++ if (dbus_message_iter_get_arg_type (&sub2) != DBUS_TYPE_STRING) { ++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply."); ++ dbus_message_unref (reply); ++ return FALSE; ++ } ++ ++ dbus_message_iter_get_basic (&sub2, &seat); ++ create_display (factory, seat); ++ ++ dbus_message_iter_next (&sub); ++ } ++ ++ dbus_message_unref (reply); ++ return TRUE; ++} ++ ++static DBusHandlerResult ++on_seat_signal (DBusConnection *connection, ++ DBusMessage *message, ++ void *user_data) ++{ ++ GdmLocalDisplayFactory *factory = user_data; ++ DBusError error; ++ ++ dbus_error_init (&error); ++ ++ if (dbus_message_is_signal (message, "org.freedesktop.login1.Manager", "SeatNew") || ++ dbus_message_is_signal (message, "org.freedesktop.login1.Manager", "SeatRemoved")) { ++ const char *seat; ++ ++ dbus_message_get_args (message, ++ &error, ++ DBUS_TYPE_STRING, &seat, ++ DBUS_TYPE_INVALID); ++ ++ if (dbus_error_is_set (&error)) { ++ g_warning ("GdmLocalDisplayFactory: Failed to decode seat message: %s", error.message); ++ dbus_error_free (&error); ++ } else { ++ ++ if (strcmp (dbus_message_get_member (message), "SeatNew") == 0) { ++ create_display (factory, seat); ++ } else { ++ delete_display (factory, seat); ++ } ++ } ++ } ++ ++ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; ++} ++ ++static void ++gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) ++{ ++ DBusError error; ++ ++ dbus_error_init (&error); ++ ++ dbus_bus_add_match (dbus_g_connection_get_connection (factory->priv->connection), ++ "type='signal'," ++ "sender='org.freedesktop.login1'," ++ "path='/org/freedesktop/login1'," ++ "interface='org.freedesktop.login1.Manager'," ++ "member='SeatNew'", ++ &error); ++ ++ if (dbus_error_is_set (&error)) { ++ g_warning ("GdmLocalDisplayFactory: Failed to add match for SeatNew: %s", error.message); ++ dbus_error_free (&error); ++ } ++ ++ dbus_bus_add_match (dbus_g_connection_get_connection (factory->priv->connection), ++ "type='signal'," ++ "sender='org.freedesktop.login1'," ++ "path='/org/freedesktop/login1'," ++ "interface='org.freedesktop.login1.Manager'," ++ "member='SeatRemoved'", ++ &error); ++ ++ if (dbus_error_is_set (&error)) { ++ g_warning ("GdmLocalDisplayFactory: Failed to add match for SeatNew: %s", error.message); ++ dbus_error_free (&error); ++ } ++ ++ dbus_connection_add_filter (dbus_g_connection_get_connection (factory->priv->connection), on_seat_signal, factory, NULL); ++} ++ ++static void ++gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) ++{ ++ dbus_connection_remove_filter (dbus_g_connection_get_connection (factory->priv->connection), on_seat_signal, factory); ++} ++ ++#endif ++ + static gboolean + gdm_local_display_factory_start (GdmDisplayFactory *base_factory) + { +- gboolean ret; + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); + GdmDisplay *display; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + +- ret = TRUE; +- +- /* FIXME: use seat configuration */ +- display = create_display (factory); +- if (display == NULL) { +- ret = FALSE; ++#ifdef WITH_SYSTEMD ++ if (sd_booted () > 0) { ++ gdm_local_display_factory_start_monitor (factory); ++ return gdm_local_display_factory_sync_seats (factory); + } ++#endif + +- return ret; ++ /* On ConsoleKit just create Seat1, and that's it. */ ++ display = create_display (factory, CK_SEAT1_PATH); ++ ++ return display != NULL; + } + + static gboolean +@@ -389,6 +588,10 @@ gdm_local_display_factory_stop (GdmDisplayFactory *base_factory) + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + ++#ifdef WITH_SYSTEMD ++ gdm_local_display_factory_stop_monitor (factory); ++#endif ++ + return TRUE; + } + +@@ -499,6 +702,10 @@ gdm_local_display_factory_finalize (GObject *object) + + g_hash_table_destroy (factory->priv->displays); + ++#ifdef WITH_SYSTEMD ++ gdm_local_display_factory_stop_monitor (factory); ++#endif ++ + G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object); + } + +-- +1.7.9 + + +From 51a27a199e36fcb5e90e8332c1f025e8a282fbd5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 Jul 2011 04:06:10 +0200 +Subject: [PATCH 09/11] server: pass seat id to server + +When we spawn a new X server, let's pass the seat id to it via the +"-seat" parameter, which has been available since a while in upstream +Xorg. + +-seat causes the X server to only make use of hardware that is assigned +to the seat specified, and leave all other hardware untouched. +--- + daemon/gdm-factory-slave.c | 4 +++- + daemon/gdm-product-slave.c | 4 +++- + daemon/gdm-server.c | 37 ++++++++++++++++++++++++++++++++++++- + daemon/gdm-server.h | 1 + + daemon/gdm-simple-slave.c | 4 +++- + 5 files changed, 46 insertions(+), 4 deletions(-) + +diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c +index 6154cd3..3538627 100644 +--- a/daemon/gdm-factory-slave.c ++++ b/daemon/gdm-factory-slave.c +@@ -674,12 +674,14 @@ static gboolean + gdm_factory_slave_run (GdmFactorySlave *slave) + { + char *display_name; ++ char *seat_id; + char *auth_file; + gboolean display_is_local; + + g_object_get (slave, + "display-is-local", &display_is_local, + "display-name", &display_name, ++ "display-seat-id", &seat_id, + "display-x11-authority-file", &auth_file, + NULL); + +@@ -688,7 +690,7 @@ gdm_factory_slave_run (GdmFactorySlave *slave) + if (display_is_local) { + gboolean res; + +- slave->priv->server = gdm_server_new (display_name, auth_file); ++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file); + g_signal_connect (slave->priv->server, + "exited", + G_CALLBACK (on_server_exited), +diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c +index 629c6e7..844af48 100644 +--- a/daemon/gdm-product-slave.c ++++ b/daemon/gdm-product-slave.c +@@ -479,11 +479,13 @@ gdm_product_slave_create_server (GdmProductSlave *slave) + { + char *display_name; + char *auth_file; ++ char *seat_id; + gboolean display_is_local; + + g_object_get (slave, + "display-is-local", &display_is_local, + "display-name", &display_name, ++ "display-seat-id", &seat_id, + "display-x11-authority-file", &auth_file, + NULL); + +@@ -492,7 +494,7 @@ gdm_product_slave_create_server (GdmProductSlave *slave) + if (display_is_local) { + gboolean res; + +- slave->priv->server = gdm_server_new (display_name, auth_file); ++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file); + g_signal_connect (slave->priv->server, + "exited", + G_CALLBACK (on_server_exited), +diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c +index 62ffca1..9a11ba0 100644 +--- a/daemon/gdm-server.c ++++ b/daemon/gdm-server.c +@@ -38,6 +38,10 @@ + #include + #endif + ++#ifdef WITH_SYSTEMD ++#include ++#endif ++ + #include + #include + #include +@@ -77,6 +81,7 @@ struct GdmServerPrivate + char *log_dir; + char *display_name; + char *display_device; ++ char *display_seat_id; + char *auth_file; + + gboolean is_parented; +@@ -90,6 +95,7 @@ struct GdmServerPrivate + enum { + PROP_0, + PROP_DISPLAY_NAME, ++ PROP_DISPLAY_SEAT_ID, + PROP_DISPLAY_DEVICE, + PROP_AUTH_FILE, + PROP_IS_PARENTED, +@@ -284,7 +290,7 @@ gdm_server_resolve_command_line (GdmServer *server, + query_in_arglist = TRUE; + } + +- argv = g_renew (char *, argv, len + 10); ++ argv = g_renew (char *, argv, len + 12); + /* shift args down one */ + for (i = len - 1; i >= 1; i--) { + argv[i+1] = argv[i]; +@@ -299,6 +305,11 @@ gdm_server_resolve_command_line (GdmServer *server, + argv[len++] = g_strdup (server->priv->auth_file); + } + ++ if (sd_booted () > 0 && server->priv->display_seat_id != NULL) { ++ argv[len++] = g_strdup ("-seat"); ++ argv[len++] = g_strdup (server->priv->display_seat_id); ++ } ++ + if (server->priv->chosen_hostname) { + /* run just one session */ + argv[len++] = g_strdup ("-terminate"); +@@ -753,6 +764,14 @@ _gdm_server_set_display_name (GdmServer *server, + } + + static void ++_gdm_server_set_display_seat_id (GdmServer *server, ++ const char *name) ++{ ++ g_free (server->priv->display_seat_id); ++ server->priv->display_seat_id = g_strdup (name); ++} ++ ++static void + _gdm_server_set_auth_file (GdmServer *server, + const char *auth_file) + { +@@ -789,6 +808,9 @@ gdm_server_set_property (GObject *object, + case PROP_DISPLAY_NAME: + _gdm_server_set_display_name (self, g_value_get_string (value)); + break; ++ case PROP_DISPLAY_SEAT_ID: ++ _gdm_server_set_display_seat_id (self, g_value_get_string (value)); ++ break; + case PROP_AUTH_FILE: + _gdm_server_set_auth_file (self, g_value_get_string (value)); + break; +@@ -818,6 +840,9 @@ gdm_server_get_property (GObject *object, + case PROP_DISPLAY_NAME: + g_value_set_string (value, self->priv->display_name); + break; ++ case PROP_DISPLAY_SEAT_ID: ++ g_value_set_string (value, self->priv->display_seat_id); ++ break; + case PROP_DISPLAY_DEVICE: + g_value_take_string (value, + gdm_server_get_display_device (self)); +@@ -889,6 +914,13 @@ gdm_server_class_init (GdmServerClass *klass) + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, ++ PROP_DISPLAY_SEAT_ID, ++ g_param_spec_string ("display-seat-id", ++ "Seat ID", ++ "ID of the seat this display is running on", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (object_class, + PROP_DISPLAY_DEVICE, + g_param_spec_string ("display-device", + "Display Device", +@@ -954,6 +986,7 @@ gdm_server_finalize (GObject *object) + g_free (server->priv->session_args); + g_free (server->priv->log_dir); + g_free (server->priv->display_name); ++ g_free (server->priv->display_seat_id); + g_free (server->priv->display_device); + g_free (server->priv->auth_file); + g_free (server->priv->parent_display_name); +@@ -965,12 +998,14 @@ gdm_server_finalize (GObject *object) + + GdmServer * + gdm_server_new (const char *display_name, ++ const char *seat_id, + const char *auth_file) + { + GObject *object; + + object = g_object_new (GDM_TYPE_SERVER, + "display-name", display_name, ++ "display-seat-id", seat_id, + "auth-file", auth_file, + NULL); + +diff --git a/daemon/gdm-server.h b/daemon/gdm-server.h +index 535a69a..b53d68e 100644 +--- a/daemon/gdm-server.h ++++ b/daemon/gdm-server.h +@@ -54,6 +54,7 @@ typedef struct + + GType gdm_server_get_type (void); + GdmServer * gdm_server_new (const char *display_id, ++ const char *seat_id, + const char *auth_file); + gboolean gdm_server_start (GdmServer *server); + gboolean gdm_server_stop (GdmServer *server); +diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c +index 873b7f9..9d1347a 100644 +--- a/daemon/gdm-simple-slave.c ++++ b/daemon/gdm-simple-slave.c +@@ -1437,11 +1437,13 @@ gdm_simple_slave_run (GdmSimpleSlave *slave) + { + char *display_name; + char *auth_file; ++ char *seat_id; + gboolean display_is_local; + + g_object_get (slave, + "display-is-local", &display_is_local, + "display-name", &display_name, ++ "display-seat-id", &seat_id, + "display-x11-authority-file", &auth_file, + NULL); + +@@ -1451,7 +1453,7 @@ gdm_simple_slave_run (GdmSimpleSlave *slave) + gboolean res; + gboolean disable_tcp; + +- slave->priv->server = gdm_server_new (display_name, auth_file); ++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file); + + disable_tcp = TRUE; + if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP, +-- +1.7.9 + + +From 2b24451c3816ecea30fdbfff2c249a6ac527e1b6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 24 Jan 2012 00:03:10 +0100 +Subject: [PATCH 10/11] server: invoke X with the systemd multi seat X wrapper + if necessary + +systemd 39 and newer provide a small wrapper for X which works around +the fact that XOrg upstream currently support multi-seat hotplug for +displays. Let's make use of this as a stop-gap until this feature is +added to XOrg upstream. + +This code tries to be as defensive as possible and makes use of the +wrapper only if the system as actually booted with systemd, the wrapper +is available and we actually use a seat != "seat0". +--- + configure.ac | 6 +++++- + daemon/gdm-server.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 54 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index dec31a9..855948d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -939,7 +939,7 @@ use_systemd=no + if test "x$with_systemd" != "xno" ; then + PKG_CHECK_MODULES(SYSTEMD, + libsystemd-daemon +- libsystemd-login ++ libsystemd-login >= 39 + ) + AC_SUBST(SYSTEMD_CFLAGS) + AC_SUBST(SYSTEMD_LIBS) +@@ -950,6 +950,10 @@ fi + AM_CONDITIONAL(WITH_SYSTEMD, test x$use_systemd = xyes) + AC_SUBST(WITH_SYSTEMD) + ++AC_PATH_PROG(SYSTEMD_X_SERVER, systemd-multi-seat-x, [/lib/systemd/systemd-multi-seat-x], [/lib/systemd:/usr/lib/systemd:$PATH]) ++AC_SUBST(SYSTEMD_X_SERVER) ++AC_DEFINE_UNQUOTED(SYSTEMD_X_SERVER,"$SYSTEMD_X_SERVER",[Path to systemd X server wrapper]) ++ + dnl --------------------------------------------------------------------------- + dnl - Check for D-Bus + dnl --------------------------------------------------------------------------- +diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c +index 9a11ba0..54bf8b3 100644 +--- a/daemon/gdm-server.c ++++ b/daemon/gdm-server.c +@@ -260,6 +260,52 @@ connect_to_parent (GdmServer *server) + } + #endif + ++static void ++gdm_server_init_command (GdmServer *server) ++{ ++ ++ if (server->priv->command != NULL) { ++ return; ++ } ++ ++#ifdef WITH_SYSTEMD ++ ++ /* This is a temporary hack to work around the fact that XOrg ++ * currently lacks support for multi-seat hotplugging for ++ * display devices. This bit should be removed as soon as XOrg ++ * gains native support for automatically enumerating usb ++ * based graphics adapters at start-up via udev. */ ++ ++ /* systemd ships an X server wrapper tool which simply invokes ++ * the usual X but ensures it only uses the display devices of ++ * the seat. */ ++ ++ /* We do not rely on this wrapper server if, a) the machine ++ * wasn't booted using systemd, or b) the wrapper tool is ++ * missing, or c) we are running for the main seat 'seat0'. */ ++ ++ if (sd_booted () <= 0) { ++ goto fallback; ++ } ++ ++ if (g_access (SYSTEMD_X_SERVER, X_OK) < 0) { ++ goto fallback; ++ } ++ ++ if (server->priv->display_seat_id == NULL || ++ strcmp (server->priv->display_seat_id, "seat0") == 0) { ++ goto fallback; ++ } ++ ++ server->priv->command = g_strdup (SYSTEMD_X_SERVER " -br -verbose -logverbose 7"); ++ return; ++ ++fallback: ++#endif ++ ++ server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7"); ++} ++ + static gboolean + gdm_server_resolve_command_line (GdmServer *server, + const char *vtarg, +@@ -273,6 +319,8 @@ gdm_server_resolve_command_line (GdmServer *server, + gboolean gotvtarg = FALSE; + gboolean query_in_arglist = FALSE; + ++ gdm_server_init_command (server); ++ + g_shell_parse_argv (server->priv->command, &argc, &argv, NULL); + + for (len = 0; argv != NULL && argv[len] != NULL; len++) { +@@ -959,7 +1007,7 @@ gdm_server_init (GdmServer *server) + server->priv = GDM_SERVER_GET_PRIVATE (server); + + server->priv->pid = -1; +- server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7"); ++ + server->priv->log_dir = g_strdup (LOGDIR); + + add_ready_handler (server); +-- +1.7.9 + + +From 28c7f9e6d875076bfe0c79cdee98fc6aefc29874 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 7 Feb 2012 22:48:40 +0100 +Subject: [PATCH 11/11] gdmflexiserver: port gdmflexiserver to + libsystemd-logind + +Port over gdmflexiserver to use native systemd calls with a fallback on +CK. +--- + utils/Makefile.am | 3 +- + utils/gdmflexiserver.c | 256 ++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 239 insertions(+), 20 deletions(-) + +diff --git a/utils/Makefile.am b/utils/Makefile.am +index 379c3d5..1cda413 100644 +--- a/utils/Makefile.am ++++ b/utils/Makefile.am +@@ -10,6 +10,7 @@ AM_CPPFLAGS = \ + $(CANBERRA_GTK_CFLAGS) \ + $(GTK_CFLAGS) \ + $(XLIB_CFLAGS) \ ++ $(SYSTEMD_CFLAGS) \ + $(COMMON_CFLAGS) \ + $(NULL) + +@@ -31,6 +32,7 @@ gdmflexiserver_SOURCES = \ + gdmflexiserver_LDADD = \ + $(GTK_LIBS) \ + $(COMMON_LIBS) \ ++ $(SYSTEMD_LIBS) \ + $(NULL) + + gdm_screenshot_SOURCES = \ +@@ -49,4 +51,3 @@ CLEANFILES = \ + + DISTCLEANFILES = \ + $(NULL) +- +diff --git a/utils/gdmflexiserver.c b/utils/gdmflexiserver.c +index f7fac33..59bccd1 100644 +--- a/utils/gdmflexiserver.c ++++ b/utils/gdmflexiserver.c +@@ -29,6 +29,11 @@ + #include + #include + ++#ifdef WITH_SYSTEMD ++#include ++#include ++#endif ++ + #define DBUS_API_SUBJECT_TO_CHANGE + #include + #include +@@ -37,6 +42,7 @@ + #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH "/org/gnome/DisplayManager/LocalDisplayFactory" + #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory" + ++#ifdef WITH_CONSOLE_KIT + #define CK_NAME "org.freedesktop.ConsoleKit" + #define CK_PATH "/org/freedesktop/ConsoleKit" + #define CK_INTERFACE "org.freedesktop.ConsoleKit" +@@ -45,6 +51,7 @@ + #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" + #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" + #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" ++#endif + + static const char *send_command = NULL; + static gboolean use_xnest = FALSE; +@@ -206,6 +213,8 @@ create_transient_display (DBusConnection *connection, + return ret; + } + ++#ifdef WITH_CONSOLE_KIT ++ + static gboolean + get_current_session_id (DBusConnection *connection, + char **session_id) +@@ -335,9 +344,9 @@ get_current_seat_id (DBusConnection *connection) + } + + static gboolean +-activate_session_id (DBusConnection *connection, +- const char *seat_id, +- const char *session_id) ++activate_session_id_for_ck (DBusConnection *connection, ++ const char *seat_id, ++ const char *session_id) + { + DBusError local_error; + DBusMessage *message; +@@ -609,9 +618,9 @@ seat_get_sessions (DBusConnection *connection, + } + + static gboolean +-get_login_window_session_id (DBusConnection *connection, +- const char *seat_id, +- char **session_id) ++get_login_window_session_id_for_ck (DBusConnection *connection, ++ const char *seat_id, ++ char **session_id) + { + gboolean can_activate_sessions; + char **sessions; +@@ -645,46 +654,225 @@ get_login_window_session_id (DBusConnection *connection, + } + + static gboolean +-goto_login_session (GError **error) ++goto_login_session_for_ck (DBusConnection *connection, ++ GError **error) + { + gboolean ret; + gboolean res; + char *session_id; + char *seat_id; +- DBusError local_error; +- DBusConnection *connection; + + ret = FALSE; + ++ /* First look for any existing LoginWindow sessions on the seat. ++ If none are found, create a new one. */ ++ ++ seat_id = get_current_seat_id (connection); ++ if (seat_id == NULL || seat_id[0] == '\0') { ++ g_debug ("seat id is not set; can't switch sessions"); ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current session.")); ++ ++ return FALSE; ++ } ++ ++ res = get_login_window_session_id_for_ck (connection, seat_id, &session_id); ++ if (! res) { ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to switch sessions.")); ++ return FALSE; ++ } ++ ++ if (session_id != NULL) { ++ res = activate_session_id_for_ck (connection, seat_id, session_id); ++ if (res) { ++ ret = TRUE; ++ } ++ } ++ ++ if (! ret) { ++ res = create_transient_display (connection, error); ++ if (res) { ++ ret = TRUE; ++ } ++ } ++ ++ return ret; ++} ++#endif ++ ++#ifdef WITH_SYSTEMD ++ ++static gboolean ++activate_session_id_for_systemd (DBusConnection *connection, ++ const char *seat_id, ++ const char *session_id) ++{ ++ DBusError local_error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ gboolean ret; ++ ++ ret = FALSE; ++ reply = NULL; ++ ++ g_debug ("Switching to session %s", session_id); ++ ++ message = dbus_message_new_method_call ("org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "ActivateSessionOnSeat"); ++ if (message == NULL) { ++ goto out; ++ } ++ ++ if (! dbus_message_append_args (message, ++ DBUS_TYPE_STRING, &session_id, ++ DBUS_TYPE_STRING, &seat_id, ++ DBUS_TYPE_INVALID)) { ++ goto out; ++ } ++ + dbus_error_init (&local_error); +- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &local_error); +- if (connection == NULL) { +- g_debug ("Failed to connect to the D-Bus daemon: %s", local_error.message); +- g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "%s", local_error.message); ++ reply = dbus_connection_send_with_reply_and_block (connection, ++ message, ++ -1, ++ &local_error); ++ if (dbus_error_is_set (&local_error)) { ++ g_warning ("Unable to activate session: %s", local_error.message); + dbus_error_free (&local_error); ++ goto out; ++ } ++ ++ ret = TRUE; ++out: ++ if (message != NULL) { ++ dbus_message_unref (message); ++ } ++ if (reply != NULL) { ++ dbus_message_unref (reply); ++ } ++ ++ return ret; ++} ++ ++static gboolean ++get_login_window_session_id_for_systemd (const char *seat_id, ++ char **session_id) ++{ ++ gboolean ret; ++ int res, i; ++ char **sessions; ++ char *service_id; ++ ++ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); ++ if (res < 0) { ++ g_debug ("Failed to determine sessions: %s", strerror (-res)); + return FALSE; + } + ++ if (sessions == NULL || sessions[0] == NULL) { ++ *session_id = NULL; ++ ret = TRUE; ++ goto out; ++ } ++ ++ for (i = 0; sessions[i]; i ++) { ++ ++ res = sd_session_get_service (sessions[i], &service_id); ++ if (res < 0) { ++ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (strcmp (service_id, "gdm-welcome") == 0) { ++ *session_id = g_strdup (sessions[i]); ++ ret = TRUE; ++ ++ free (service_id); ++ goto out; ++ } ++ ++ free (service_id); ++ } ++ ++ *session_id = NULL; ++ ret = TRUE; ++ ++out: ++ for (i = 0; sessions[i]; i ++) { ++ free (sessions[i]); ++ } ++ ++ free (sessions); ++ ++ return ret; ++} ++ ++static gboolean ++goto_login_session_for_systemd (DBusConnection *connection, ++ GError **error) ++{ ++ gboolean ret; ++ int res; ++ char *our_session; ++ char *session_id; ++ char *seat_id; ++ ++ ret = FALSE; ++ + /* First look for any existing LoginWindow sessions on the seat. + If none are found, create a new one. */ + +- seat_id = get_current_seat_id (connection); +- if (seat_id == NULL || seat_id[0] == '\0') { +- g_debug ("seat id is not set; can't switch sessions"); ++ /* Note that we mostly use free () here, instead of g_free () ++ * since the data allocated is from libsystemd-logind, which ++ * does not use GLib's g_malloc (). */ ++ ++ res = sd_pid_get_session (0, &our_session); ++ if (res < 0) { ++ g_debug ("failed to determine own session: %s", strerror (-res)); + g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current session.")); + + return FALSE; + } + +- res = get_login_window_session_id (connection, seat_id, &session_id); ++ res = sd_session_get_seat (our_session, &seat_id); ++ free (our_session); ++ if (res < 0) { ++ g_debug ("failed to determine own seat: %s", strerror (-res)); ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current seat.")); ++ ++ return FALSE; ++ } ++ ++ res = sd_seat_can_multi_session (seat_id); ++ if (res < 0) { ++ free (seat_id); ++ ++ g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res)); ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify multi session property.")); ++ ++ return FALSE; ++ } ++ ++ if (res == 0) { ++ free (seat_id); + ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Seat can't do multi session")); ++ ++ return FALSE; ++ } ++ ++ res = get_login_window_session_id_for_systemd (seat_id, &session_id); + if (! res) { +- g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to switch sessions.")); ++ free (seat_id); ++ ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to determine login session.")); + return FALSE; + } + + if (session_id != NULL) { +- res = activate_session_id (connection, seat_id, session_id); ++ res = activate_session_id_for_systemd (connection, seat_id, session_id); ++ + if (res) { + ret = TRUE; + } +@@ -697,8 +885,38 @@ goto_login_session (GError **error) + } + } + ++ free (seat_id); ++ g_free (session_id); ++ + return ret; + } ++#endif ++ ++static gboolean ++goto_login_session (GError **error) ++{ ++ DBusError local_error; ++ DBusConnection *connection; ++ ++ dbus_error_init (&local_error); ++ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &local_error); ++ if (connection == NULL) { ++ g_debug ("Failed to connect to the D-Bus daemon: %s", local_error.message); ++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "%s", local_error.message); ++ dbus_error_free (&local_error); ++ return FALSE; ++ } ++ ++#ifdef WITH_SYSTEMD ++ if (sd_booted () > 0) { ++ return goto_login_session_for_systemd (connection, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return goto_login_session_for_ck (connection, error); ++#endif ++} + + int + main (int argc, char *argv[]) +-- +1.7.9 +