From f25f0efdfce3e8ca39ba2d3f3f1a7e83bee5cc81 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 6 Jun 2017 00:45:41 +0000 Subject: testing/gdm: new aport --- .../gdm/0003-reintroduce-ConsoleKit-support.patch | 2816 ++++++++++++++++++++ 1 file changed, 2816 insertions(+) create mode 100644 testing/gdm/0003-reintroduce-ConsoleKit-support.patch (limited to 'testing/gdm/0003-reintroduce-ConsoleKit-support.patch') diff --git a/testing/gdm/0003-reintroduce-ConsoleKit-support.patch b/testing/gdm/0003-reintroduce-ConsoleKit-support.patch new file mode 100644 index 0000000000..c110517ac0 --- /dev/null +++ b/testing/gdm/0003-reintroduce-ConsoleKit-support.patch @@ -0,0 +1,2816 @@ +From f4a1a8c560796804e0ec763ab50f5e56e2ff05c4 Mon Sep 17 00:00:00 2001 +From: William Pitcock +Date: Tue, 6 Jun 2017 00:29:44 +0000 +Subject: [PATCH 3/3] reintroduce ConsoleKit support + +--- + common/gdm-common.c | 335 +++++++++++++++++- + common/gdm-common.h | 3 + + common/gdm-log.c | 22 ++ + configure.ac | 64 +++- + daemon/Makefile.am | 10 + + daemon/gdm-launch-environment.c | 7 +- + daemon/gdm-local-display-factory.c | 35 +- + daemon/gdm-manager.c | 679 +++++++++++++++++++++++++++---------- + daemon/gdm-server.c | 69 +++- + daemon/gdm-session-worker-job.c | 2 + + daemon/gdm-session-worker.c | 314 +++++++++++++++-- + daemon/gdm-session-worker.xml | 3 + + daemon/gdm-session.c | 25 ++ + daemon/gdm-session.h | 2 + + libgdm/gdm-user-switching.c | 349 ++++++++++++++++++- + 15 files changed, 1653 insertions(+), 266 deletions(-) + +diff --git a/common/gdm-common.c b/common/gdm-common.c +index 31fc810a..2ad134a6 100644 +--- a/common/gdm-common.c ++++ b/common/gdm-common.c +@@ -39,12 +39,25 @@ + #include "mkdtemp.h" + #endif + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #define GDM_DBUS_NAME "org.gnome.DisplayManager" + #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" ++ ++#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" ++#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 ++ + G_DEFINE_QUARK (gdm-common-error, gdm_common_error); + + const char * +@@ -343,10 +356,301 @@ create_transient_display (GDBusConnection *connection, + return TRUE; + } + ++#ifdef WITH_CONSOLE_KIT ++ ++static gboolean ++get_current_session_id (GDBusConnection *connection, ++ char **session_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ CK_MANAGER_PATH, ++ CK_MANAGER_INTERFACE, ++ "GetCurrentSession", ++ NULL, /* parameters */ ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine session: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(o)", session_id); ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static gboolean ++get_seat_id_for_session (GDBusConnection *connection, ++ const char *session_id, ++ char **seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ session_id, ++ CK_SESSION_INTERFACE, ++ "GetSeatId", ++ NULL, /* parameters */ ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine seat: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(o)", seat_id); ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static char * ++get_current_seat_id (GDBusConnection *connection) ++{ ++ gboolean res; ++ char *session_id; ++ char *seat_id; ++ ++ session_id = NULL; ++ seat_id = NULL; ++ ++ res = get_current_session_id (connection, &session_id); ++ if (res) { ++ res = get_seat_id_for_session (connection, session_id, &seat_id); ++ } ++ g_free (session_id); ++ ++ return seat_id; ++} ++ ++static gboolean ++activate_session_id_for_ck (GDBusConnection *connection, ++ const char *seat_id, ++ const char *session_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "ActivateSession", ++ g_variant_new ("(o)", session_id), ++ NULL, ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to activate session: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static gboolean ++session_is_login_window (GDBusConnection *connection, ++ const char *session_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ const char *value; ++ gboolean ret; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ session_id, ++ CK_SESSION_INTERFACE, ++ "GetSessionType", ++ NULL, ++ G_VARIANT_TYPE ("(s)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine session type: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(&s)", &value); ++ ++ if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) { ++ ret = FALSE; ++ } else { ++ ret = TRUE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return ret; ++} ++ ++static gboolean ++seat_can_activate_sessions (GDBusConnection *connection, ++ const char *seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ gboolean ret; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "CanActivateSessions", ++ NULL, ++ G_VARIANT_TYPE ("(b)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine if can activate sessions: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(b)", &ret); ++ g_variant_unref (reply); ++ ++ return ret; ++} ++ ++static const char ** ++seat_get_sessions (GDBusConnection *connection, ++ const char *seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ const char **value; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "GetSessions", ++ NULL, ++ G_VARIANT_TYPE ("(ao)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to list sessions: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(^ao)", &value); ++ g_variant_unref (reply); ++ ++ return value; ++} ++ ++static gboolean ++get_login_window_session_id_for_ck (GDBusConnection *connection, ++ const char *seat_id, ++ char **session_id) ++{ ++ gboolean can_activate_sessions; ++ const char **sessions; ++ int i; ++ ++ *session_id = NULL; ++ sessions = NULL; ++ ++ g_debug ("checking if seat can activate sessions"); ++ ++ can_activate_sessions = seat_can_activate_sessions (connection, seat_id); ++ if (! can_activate_sessions) { ++ g_debug ("seat is unable to activate sessions"); ++ return FALSE; ++ } ++ ++ sessions = seat_get_sessions (connection, seat_id); ++ for (i = 0; sessions [i] != NULL; i++) { ++ const char *ssid; ++ ++ ssid = sessions [i]; ++ ++ if (session_is_login_window (connection, ssid)) { ++ *session_id = g_strdup (ssid); ++ break; ++ } ++ } ++ g_free (sessions); ++ ++ return TRUE; ++} ++ ++static gboolean ++goto_login_session_for_ck (GDBusConnection *connection, ++ GError **error) ++{ ++ gboolean ret; ++ gboolean res; ++ 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"); ++ g_set_error (error, GDM_COMMON_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_COMMON_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 && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) { ++ res = create_transient_display (connection, error); ++ if (res) { ++ ret = TRUE; ++ } ++ } ++ ++ return ret; ++} ++#endif ++ ++#ifdef WITH_SYSTEMD ++ + static gboolean +-activate_session_id (GDBusConnection *connection, +- const char *seat_id, +- const char *session_id) ++activate_session_id_for_systemd (GDBusConnection *connection, ++ const char *seat_id, ++ const char *session_id) + { + GError *local_error = NULL; + GVariant *reply; +@@ -373,8 +677,8 @@ activate_session_id (GDBusConnection *connection, + } + + static gboolean +-get_login_window_session_id (const char *seat_id, +- char **session_id) ++get_login_window_session_id_for_systemd (const char *seat_id, ++ char **session_id) + { + gboolean ret; + int res, i; +@@ -442,8 +746,8 @@ out: + } + + static gboolean +-goto_login_session (GDBusConnection *connection, +- GError **error) ++goto_login_session_for_systemd (GDBusConnection *connection, ++ GError **error) + { + gboolean ret; + int res; +@@ -497,9 +801,9 @@ goto_login_session (GDBusConnection *connection, + return FALSE; + } + +- res = get_login_window_session_id (seat_id, &session_id); ++ res = get_login_window_session_id_for_systemd (seat_id, &session_id); + if (res && 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; +@@ -518,6 +822,7 @@ goto_login_session (GDBusConnection *connection, + + return ret; + } ++#endif + + gboolean + gdm_goto_login_session (GError **error) +@@ -533,7 +838,17 @@ gdm_goto_login_session (GError **error) + return FALSE; + } + +- return goto_login_session (connection, error); ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return goto_login_session_for_systemd (connection, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return goto_login_session_for_ck (connection, error); ++#else ++ return FALSE; ++#endif + } + + static void +diff --git a/common/gdm-common.h b/common/gdm-common.h +index 8d83a124..4ffb9a25 100644 +--- a/common/gdm-common.h ++++ b/common/gdm-common.h +@@ -31,6 +31,9 @@ + expr; \ + } while G_UNLIKELY (errno == EINTR); + ++/* check if logind is running */ ++#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0) ++ + GQuark gdm_common_error_quark (void); + #define GDM_COMMON_ERROR gdm_common_error_quark() + +diff --git a/common/gdm-log.c b/common/gdm-log.c +index 8a2d0154..22d8c7d6 100644 +--- a/common/gdm-log.c ++++ b/common/gdm-log.c +@@ -30,7 +30,9 @@ + #include + + #include ++#ifdef WITH_SYSTEMD + #include ++#endif + + #include + #include +@@ -133,7 +135,27 @@ gdm_log_init (void) + + initialized = TRUE; + ++#ifdef WITH_SYSTEMD ++ is_sd_booted = sd_booted () > 0; ++#endif ++ + g_log_set_default_handler (gdm_log_default_handler, NULL); ++ ++ /* Only set up syslog if !systemd, otherwise with systemd ++ * enabled, we keep the default GLib log handler which goes to ++ * stderr, which is routed to the appropriate place in the ++ * systemd service file. ++ */ ++ if (!is_sd_booted) { ++ prg_name = g_get_prgname (); ++ ++ options = LOG_PID; ++#ifdef LOG_PERROR ++ options |= LOG_PERROR; ++#endif ++ ++ openlog (prg_name, options, LOG_DAEMON); ++ } + } + + void +diff --git a/configure.ac b/configure.ac +index 602969bd..07a56ce4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -257,7 +257,15 @@ AC_ARG_WITH(tcp-wrappers, + [Use TCP Wrappers @<:@default=auto@:>@]),, + with_tcp_wrappers=auto) + +- ++AC_ARG_WITH(console-kit, ++ AS_HELP_STRING([--with-console-kit], ++ [Add ConsoleKit support @<:@default=auto@:>@]),, ++ with_console_kit=no) ++ ++AC_ARG_WITH(systemd, ++ AS_HELP_STRING([--with-systemd], ++ [Add systemd support @<:@default=auto@:>@]), ++ [with_systemd=$withval], [with_systemd=auto]) + AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], + [Directory for systemd service files]), +@@ -640,14 +648,8 @@ dnl --------------------------------------------------------------------------- + dnl - Check for utmp stuff + dnl --------------------------------------------------------------------------- + +-AC_CHECK_HEADERS(utmp.h utmpx.h libutil.h sys/param.h) +-AC_CHECK_FUNCS([getutxent updwtmpx updwtmp]) +-AC_CHECK_LIB(util, login, [ +- AC_DEFINE(HAVE_LOGIN, 1, [Define if have login]) +- EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ]) +-AC_CHECK_LIB(util, logout, [ +- AC_DEFINE(HAVE_LOGOUT, 1, [Define if have logout]) +- EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ]) ++AC_CHECK_HEADERS(utmp.h utmpx.h util.h sys/param.h) ++AC_CHECK_FUNCS([getutxent getttyent updwtmpx updwtmp]) + AC_CHECK_LIB(util, logwtmp, [ + AC_DEFINE(HAVE_LOGWTMP, 1, [Define if have logwtmp]) + EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ]) +@@ -896,12 +898,42 @@ AC_SUBST(XINERAMA_LIBS) + CPPFLAGS="$xinerama_save_cppflags" + + dnl --------------------------------------------------------------------------- ++dnl - Check for ConsoleKit support ++dnl --------------------------------------------------------------------------- ++ ++use_console_kit=no ++if test "x$with_console_kit" != "xno" ; then ++ use_console_kit=yes ++ AC_DEFINE(WITH_CONSOLE_KIT, 1, [Define to enable ConsoleKit support]) ++fi ++AM_CONDITIONAL(WITH_CONSOLE_KIT, test x$use_console_kit = xyes) ++AC_SUBST(WITH_CONSOLE_KIT) ++ ++dnl --------------------------------------------------------------------------- + dnl - Check for systemd support + dnl --------------------------------------------------------------------------- + + PKG_CHECK_MODULES(SYSTEMD, +- [libsystemd]) ++ [libsystemd-login >= 186 libsystemd-daemon], ++ [have_systemd=yes], [have_systemd=no]) + ++if test "x$with_systemd" = "xauto" ; then ++ if test x$have_systemd = xno ; then ++ use_systemd=no ++ else ++ use_systemd=yes ++ fi ++else ++ use_systemd="$with_systemd" ++fi ++ ++if test "x$use_systemd" != "xno" ; then ++ if test "x$have_systemd" = "xno"; then ++ AC_MSG_ERROR([Systemd support explicitly required, but systemd not found]) ++ fi ++ ++ AC_DEFINE(WITH_SYSTEMD, 1, [Define to enable systemd support]) ++fi + AC_SUBST(SYSTEMD_CFLAGS) + AC_SUBST(SYSTEMD_LIBS) + +@@ -1094,6 +1126,14 @@ fi + AC_SUBST(GDM_CUSTOM_CONF) + AC_SUBST(GDM_OLD_CONF, '${gdmconfdir}/gdm.conf') + ++AC_ARG_WITH(consolekit-directory, ++ [AC_HELP_STRING([--with-consolekit-directory], ++ [Specify the directory of ck-get-x11-display-device @<:@default=libexecdir@:>@])],, ++ [with_consolekit_directory="\${libexecdir}"]) ++ ++CONSOLEKIT_DIR=$with_consolekit_directory ++AC_SUBST(CONSOLEKIT_DIR) ++ + AC_ARG_WITH(gnome-settings-daemon-directory, + [AC_HELP_STRING([--with-gnome-settings-daemon-directory], + [Specify the directory of gnome-settings-daemon used by the chooser @<:@default=libexecdir@:>@])],, +@@ -1582,6 +1622,7 @@ echo " + dmconfdir: ${dmconfdir} + localstatedir: ${localstatedir} + datadir: ${datadir} ++ consolekit location: ${with_consolekit_directory} + gnome-settings-daemon location: ${with_gnome_settings_daemon_directory} + gnome-session-check-accel location: ${with_check_accelerated_directory} + source code location: ${srcdir} +@@ -1612,6 +1653,8 @@ echo \ + " Xinerama support: ${XINERAMA_SUPPORT} + XDMCP support: ${XDMCP_SUPPORT} + SELinux support: ${use_selinux} ++ ConsoleKit support: ${use_console_kit} ++ systemd support: ${use_systemd} + systemd unit dir: ${with_systemdsystemunitdir} + plymouth support: ${use_plymouth} + wayland support: ${enable_wayland_support} +@@ -1620,3 +1663,4 @@ echo \ + Enable documentation: ${enable_documentation} + Install GDM's Xsession: ${enable_gdm_xsession} + " ++ +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index ab5dda06..e3cf73a6 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -20,6 +20,7 @@ AM_CPPFLAGS = \ + -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ + -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ + -DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \ ++ -DCONSOLEKIT_DIR=\"$(CONSOLEKIT_DIR)\" \ + $(DISABLE_DEPRECATED_CFLAGS) \ + $(DAEMON_CFLAGS) \ + $(XLIB_CFLAGS) \ +@@ -264,6 +265,11 @@ EXTRA_gdm_SOURCES = \ + $(XDMCP_SOURCES) \ + $(NULL) + ++CONSOLE_KIT_SOURCES = \ ++ $(NULL) ++ ++EXTRA_gdm_SOURCES += $(CONSOLE_KIT_SOURCES) ++ + gdm_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(XLIB_LIBS) \ +@@ -275,6 +281,10 @@ gdm_LDADD = \ + $(EXTRA_DAEMON_LIBS) \ + $(NULL) + ++if WITH_CONSOLE_KIT ++gdm_SOURCES += $(CONSOLE_KIT_SOURCES) ++endif ++ + CLEANFILES = \ + gdm-display-glue.c \ + gdm-local-display-factory-glue.c \ +diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c +index 5fd346ff..88183265 100644 +--- a/daemon/gdm-launch-environment.c ++++ b/daemon/gdm-launch-environment.c +@@ -50,7 +50,7 @@ + #include "gdm-settings-direct.h" + #include "gdm-settings-keys.h" + +-#define INITIAL_SETUP_USERNAME "gnome-initial-setup" ++#define INITIAL_SETUP_USERNAME "_gnome-initial-setup" + #define GDM_SESSION_MODE "gdm" + #define INITIAL_SETUP_SESSION_MODE "initial-setup" + #define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" +@@ -197,6 +197,9 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, + char *seat_id; + + seat_id = launch_environment->priv->x11_display_seat_id; ++ if (g_str_has_prefix (seat_id, "/org/freedesktop/ConsoleKit/")) { ++ seat_id += strlen ("/org/freedesktop/ConsoleKit/"); ++ } + + g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id)); + } +@@ -224,6 +227,8 @@ on_session_setup_complete (GdmSession *session, + gdm_session_set_environment_variable (launch_environment->priv->session, key, value); + } + g_hash_table_destroy (hash); ++ ++ gdm_session_select_session_type (launch_environment->priv->session, "LoginWindow"); + } + + static void +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 7a4643d0..b31310c7 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -42,6 +42,8 @@ + + #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate)) + ++#define CK_SEAT1_PATH "/org/freedesktop/ConsoleKit/Seat1" ++ + #define GDM_DBUS_PATH "/org/gnome/DisplayManager" + #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" + #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" +@@ -57,8 +59,10 @@ struct GdmLocalDisplayFactoryPrivate + /* FIXME: this needs to be per seat? */ + guint num_failures; + ++#ifdef WITH_SYSTEMD + guint seat_new_id; + guint seat_removed_id; ++#endif + }; + + enum { +@@ -206,8 +210,10 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact + + g_debug ("GdmLocalDisplayFactory: Creating transient display"); + +-#ifdef ENABLE_USER_DISPLAY_SERVER +- display = gdm_local_display_new (); ++#if defined ENABLE_USER_DISPLAY_SERVER && defined WITH_SYSTEMD ++ if (LOGIND_RUNNING() > 0) { ++ display = gdm_local_display_new (); ++ } + #else + if (display == NULL) { + guint32 num; +@@ -289,7 +295,7 @@ on_display_status_changed (GdmDisplay *display, + /* reset num failures */ + factory->priv->num_failures = 0; + +- gdm_local_display_factory_sync_seats (factory); ++ create_display (factory, seat_id, session_type, is_initial); + } + break; + case GDM_DISPLAY_FAILED: +@@ -368,7 +374,7 @@ create_display (GdmLocalDisplayFactory *factory, + + g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); + +-#ifdef ENABLE_USER_DISPLAY_SERVER ++#if defined ENABLE_USER_DISPLAY_SERVER && defined WITH_SYSTEMD + if (g_strcmp0 (seat_id, "seat0") == 0) { + display = gdm_local_display_new (); + if (session_type != NULL) { +@@ -400,6 +406,8 @@ create_display (GdmLocalDisplayFactory *factory, + return display; + } + ++#ifdef WITH_SYSTEMD ++ + static void + delete_display (GdmLocalDisplayFactory *factory, + const char *seat_id) { +@@ -536,6 +544,7 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) + factory->priv->seat_removed_id = 0; + } + } ++#endif + + static void + on_display_added (GdmDisplayStore *display_store, +@@ -576,6 +585,7 @@ static gboolean + gdm_local_display_factory_start (GdmDisplayFactory *base_factory) + { + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); ++ GdmDisplay *display; + GdmDisplayStore *store; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); +@@ -594,8 +604,17 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory) + factory, + 0); + +- gdm_local_display_factory_start_monitor (factory); +- return gdm_local_display_factory_sync_seats (factory); ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ gdm_local_display_factory_start_monitor (factory); ++ return gdm_local_display_factory_sync_seats (factory); ++ } ++#endif ++ ++ /* On ConsoleKit just create Seat1, and that's it. */ ++ display = create_display (factory, CK_SEAT1_PATH, NULL, TRUE); ++ ++ return display != NULL; + } + + static gboolean +@@ -606,7 +625,9 @@ 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 + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + +@@ -762,7 +783,9 @@ gdm_local_display_factory_finalize (GObject *object) + + g_hash_table_destroy (factory->priv->used_display_numbers); + ++#ifdef WITH_SYSTEMD + gdm_local_display_factory_stop_monitor (factory); ++#endif + + G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object); + } +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index d080b308..f5439855 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -36,7 +36,9 @@ + + #include + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #include "gdm-common.h" + +@@ -61,7 +63,16 @@ + #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" + #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" + +-#define INITIAL_SETUP_USERNAME "gnome-initial-setup" ++#define INITIAL_SETUP_USERNAME "_gnome-initial-setup" ++ ++#define CK_NAME "org.freedesktop.ConsoleKit" ++#define CK_PATH "/org/freedesktop/ConsoleKit" ++#define CK_INTERFACE "org.freedesktop.ConsoleKit" ++ ++#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" ++#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" ++#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" ++#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + + typedef struct + { +@@ -206,9 +217,10 @@ plymouth_quit_without_transition (void) + } + #endif + ++#ifdef WITH_SYSTEMD + static char * +-get_session_id_for_pid (pid_t pid, +- GError **error) ++get_session_id_for_pid_systemd (pid_t pid, ++ GError **error) + { + char *session, *gsession; + int ret; +@@ -233,11 +245,61 @@ get_session_id_for_pid (pid_t pid, + return NULL; + } + } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static char * ++get_session_id_for_pid_consolekit (GDBusConnection *connection, ++ pid_t pid, ++ GError **error) ++{ ++ GVariant *reply; ++ char *retval; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.ConsoleKit", ++ "/org/freedesktop/ConsoleKit/Manager", ++ "org.freedesktop.ConsoleKit.Manager", ++ "GetSessionForUnixProcess", ++ g_variant_new ("(u)", pid), ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, error); ++ if (reply == NULL) { ++ return NULL; ++ } ++ ++ g_variant_get (reply, "(o)", &retval); ++ g_variant_unref (reply); ++ ++ return retval; ++} ++#endif ++ ++static char * ++get_session_id_for_pid (GDBusConnection *connection, ++ pid_t pid, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return get_session_id_for_pid_systemd (pid, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return get_session_id_for_pid_consolekit (connection, pid, error); ++#endif ++ ++ return NULL; ++} + ++#ifdef WITH_SYSTEMD + static gboolean +-get_uid_for_session_id (const char *session_id, +- uid_t *uid, +- GError **error) ++get_uid_for_systemd_session_id (const char *session_id, ++ uid_t *uid, ++ GError **error) + { + int ret; + +@@ -254,6 +316,60 @@ get_uid_for_session_id (const char *session_id, + + return TRUE; + } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++get_uid_for_consolekit_session_id (GDBusConnection *connection, ++ const char *session_id, ++ uid_t *out_uid, ++ GError **error) ++{ ++ GVariant *reply; ++ guint32 uid; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.ConsoleKit", ++ session_id, ++ "org.freedesktop.ConsoleKit.Session", ++ "GetUnixUser", ++ NULL, ++ G_VARIANT_TYPE ("(u)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ error); ++ if (reply == NULL) { ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(u)", &uid); ++ g_variant_unref (reply); ++ ++ *out_uid = (uid_t) uid; ++ ++ return TRUE; ++} ++#endif ++ ++static gboolean ++get_uid_for_session_id (GDBusConnection *connection, ++ const char *session_id, ++ uid_t *uid, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return get_uid_for_systemd_session_id (session_id, uid, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return get_uid_for_consolekit_session_id (connection, session_id, uid, error); ++#endif ++ ++ return FALSE; ++} + + static gboolean + lookup_by_session_id (const char *id, +@@ -267,10 +383,50 @@ lookup_by_session_id (const char *id, + return g_strcmp0 (current, looking_for) == 0; + } + ++#ifdef WITH_CONSOLE_KIT + static gboolean +-is_login_session (GdmManager *self, +- const char *session_id, +- GError **error) ++is_consolekit_login_session (GdmManager *self, ++ GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++ GVariant *reply; ++ char *session_type = NULL; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.ConsoleKit", ++ session_id, ++ "org.freedesktop.ConsoleKit.Session", ++ "GetSessionType", ++ NULL, ++ G_VARIANT_TYPE ("(s)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ error); ++ if (reply == NULL) { ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(s)", &session_type); ++ g_variant_unref (reply); ++ ++ if (g_strcmp0 (session_type, "LoginWindow") != 0) { ++ g_free (session_type); ++ ++ return FALSE; ++ } ++ ++ g_free (session_type); ++ return TRUE; ++} ++#endif ++ ++#ifdef WITH_SYSTEMD ++static gboolean ++is_systemd_login_session (GdmManager *self, ++ const char *session_id, ++ GError **error) + { + char *session_class = NULL; + int ret; +@@ -295,11 +451,32 @@ is_login_session (GdmManager *self, + g_free (session_class); + return TRUE; + } ++#endif + + static gboolean +-activate_session_id (GdmManager *manager, +- const char *seat_id, +- const char *session_id) ++is_login_session (GdmManager *self, ++ GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return is_systemd_login_session (self, session_id, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return is_consolekit_login_session (self, connection, session_id, error); ++#endif ++ ++ return FALSE; ++} ++ ++#ifdef WITH_SYSTEMD ++static gboolean ++activate_session_id_for_systemd (GdmManager *manager, ++ const char *seat_id, ++ const char *session_id) + { + GError *error = NULL; + GVariant *reply; +@@ -326,15 +503,74 @@ activate_session_id (GdmManager *manager, + + return TRUE; + } ++#endif + ++#ifdef WITH_CONSOLE_KIT + static gboolean +-session_unlock (GdmManager *manager, +- const char *ssid) ++activate_session_id_for_ck (GdmManager *manager, ++ const char *seat_id, ++ const char *session_id) + { + GError *error = NULL; + GVariant *reply; + +- g_debug ("Unlocking session %s", ssid); ++ reply = g_dbus_connection_call_sync (manager->priv->connection, ++ CK_NAME, ++ seat_id, ++ "org.freedesktop.ConsoleKit.Seat", ++ "ActivateSession", ++ g_variant_new ("(o)", session_id), ++ NULL, /* expected reply */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ if (reply == NULL) { ++ g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n", ++ g_dbus_error_get_remote_error (error), error->message); ++ g_error_free (error); ++ ++ /* It is very likely that the "error" just reported is ++ * that the session is already active. Unfortunately, ++ * ConsoleKit doesn't use proper error codes and it ++ * translates the error message, so we have no real way ++ * to detect this case... ++ */ ++ return TRUE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++#endif ++ ++static gboolean ++activate_session_id (GdmManager *manager, ++ const char *seat_id, ++ const char *session_id) ++{ ++ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return activate_session_id_for_systemd (manager, seat_id, session_id); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return activate_session_id_for_ck (manager, seat_id, session_id); ++#else ++ return FALSE; ++#endif ++} ++ ++#ifdef WITH_SYSTEMD ++static gboolean ++session_unlock_for_systemd (GdmManager *manager, ++ const char *ssid) ++{ ++ GError *error = NULL; ++ GVariant *reply; + + reply = g_dbus_connection_call_sync (manager->priv->connection, + "org.freedesktop.login1", +@@ -358,6 +594,59 @@ session_unlock (GdmManager *manager, + + return TRUE; + } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++session_unlock_for_ck (GdmManager *manager, ++ const char *ssid) ++{ ++ GError *error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (manager->priv->connection, ++ CK_NAME, ++ ssid, ++ CK_SESSION_INTERFACE, ++ "Unlock", ++ NULL, /* parameters */ ++ NULL, /* expected reply */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ if (reply == NULL) { ++ g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n", ++ g_dbus_error_get_remote_error (error), error->message); ++ g_error_free (error); ++ return FALSE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++#endif ++ ++static gboolean ++session_unlock (GdmManager *manager, ++ const char *ssid) ++{ ++ ++ g_debug ("Unlocking session %s", ssid); ++ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return session_unlock_for_systemd (manager, ssid); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return session_unlock_for_ck (manager, ssid); ++#else ++ return TRUE; ++#endif ++} + + static GdmSession * + find_session_for_user_on_seat (GdmManager *manager, +@@ -389,10 +678,43 @@ find_session_for_user_on_seat (GdmManager *manager, + return NULL; + } + ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++is_consolekit_remote_session (GdmManager *self, ++ GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++ GVariant *reply; ++ gboolean is_remote; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.ConsoleKit", ++ session_id, ++ "org.freedesktop.ConsoleKit.Session", ++ "IsLocal", ++ NULL, ++ G_VARIANT_TYPE ("(b)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ error); ++ if (reply == NULL) { ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(b)", &is_remote); ++ g_variant_unref (reply); ++ ++ return is_remote; ++} ++#endif ++ ++#ifdef WITH_SYSTEMD + static gboolean +-is_remote_session (GdmManager *self, +- const char *session_id, +- GError **error) ++is_systemd_remote_session (GdmManager *self, ++ const char *session_id, ++ GError **error) + { + char *seat; + int ret; +@@ -418,10 +740,31 @@ is_remote_session (GdmManager *self, + + return is_remote; + } ++#endif ++ ++static gboolean ++is_remote_session (GdmManager *self, ++ GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return is_systemd_remote_session (self, session_id, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return is_consolekit_remote_session (self, connection, session_id, error); ++#endif ++ ++ return FALSE; ++} + ++#ifdef WITH_SYSTEMD + static char * +-get_seat_id_for_session_id (const char *session_id, +- GError **error) ++get_seat_id_for_systemd_session_id (const char *session_id, ++ GError **error) + { + int ret; + char *seat, *out_seat; +@@ -446,10 +789,61 @@ get_seat_id_for_session_id (const char *session_id, + + return out_seat; + } ++#endif + ++#ifdef WITH_CONSOLE_KIT + static char * +-get_tty_for_session_id (const char *session_id, +- GError **error) ++get_seat_id_for_consolekit_session_id (GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++ GVariant *reply; ++ char *retval; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.ConsoleKit", ++ session_id, ++ "org.freedesktop.ConsoleKit.Session", ++ "GetSeatId", ++ NULL, ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ error); ++ if (reply == NULL) { ++ return NULL; ++ } ++ ++ g_variant_get (reply, "(o)", &retval); ++ g_variant_unref (reply); ++ ++ return retval; ++} ++#endif ++ ++static char * ++get_seat_id_for_session_id (GDBusConnection *connection, ++ const char *session_id, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return get_seat_id_for_systemd_session_id (session_id, error); ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ return get_seat_id_for_consolekit_session_id (connection, session_id, error); ++#endif ++ ++ return NULL; ++} ++ ++#ifdef WITH_SYSTEMD ++static char * ++get_tty_for_systemd_session_id (const char *session_id, ++ GError **error) + { + int ret; + char *tty, *out_tty; +@@ -473,6 +867,20 @@ get_tty_for_session_id (const char *session_id, + + return out_tty; + } ++#endif ++ ++static char * ++get_tty_for_session_id (const char *session_id, ++ GError **error) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return get_tty_for_systemd_session_id (session_id, error); ++ } ++#endif ++ ++ return NULL; ++} + + static void + get_display_and_details_for_bus_sender (GdmManager *self, +@@ -516,7 +924,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, + goto out; + } + +- session_id = get_session_id_for_pid (pid, &error); ++ session_id = get_session_id_for_pid (connection, pid, &error); + + if (session_id == NULL) { + g_debug ("GdmManager: Error while retrieving session id for sender: %s", +@@ -530,7 +938,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, + } + + if (out_is_login_screen != NULL) { +- *out_is_login_screen = is_login_session (self, session_id, &error); ++ *out_is_login_screen = is_login_session (self, connection, session_id, &error); + + if (error != NULL) { + g_debug ("GdmManager: Error while checking if sender is login screen: %s", +@@ -540,7 +948,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, + } + } + +- if (!get_uid_for_session_id (session_id, &session_uid, &error)) { ++ if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) { + g_debug ("GdmManager: Error while retrieving uid for session: %s", + error->message); + g_error_free (error); +@@ -557,7 +965,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, + } + + if (out_seat_id != NULL) { +- *out_seat_id = get_seat_id_for_session_id (session_id, &error); ++ *out_seat_id = get_seat_id_for_session_id (connection, session_id, &error); + + if (error != NULL) { + g_debug ("GdmManager: Error while retrieving seat id for session: %s", +@@ -567,7 +975,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, + } + + if (out_is_remote != NULL) { +- *out_is_remote = is_remote_session (self, session_id, &error); ++ *out_is_remote = is_remote_session (self, connection, session_id, &error); + + if (error != NULL) { + g_debug ("GdmManager: Error while retrieving remoteness for session: %s", +@@ -956,7 +1364,8 @@ on_reauthentication_client_rejected (GdmSession *session, + * same audit session, ignore it since it doesn't "own" the + * reauthentication session + */ +- client_session_id = get_session_id_for_pid (pid_of_client, ++ client_session_id = get_session_id_for_pid (self->priv->connection, ++ pid_of_client, + NULL); + session_id = g_object_get_data (G_OBJECT (session), "caller-session-id"); + +@@ -1168,16 +1577,20 @@ static gboolean + display_is_on_seat0 (GdmDisplay *display) + { + gboolean is_on_seat0 = TRUE; +- char *seat_id = NULL; + +- g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL); ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ char *seat_id = NULL; + +- if (g_strcmp0 (seat_id, "seat0") != 0) { +- is_on_seat0 = FALSE; +- } ++ g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL); + +- g_free (seat_id); ++ if (g_strcmp0 (seat_id, "seat0") != 0) { ++ is_on_seat0 = FALSE; ++ } + ++ g_free (seat_id); ++ } ++#endif + return is_on_seat0; + } + +@@ -1315,133 +1728,6 @@ maybe_start_pending_initial_login (GdmManager *manager, + g_free (user_session_seat_id); + } + +-static gboolean +-get_login_window_session_id (const char *seat_id, +- char **session_id) +-{ +- gboolean ret; +- int res, i; +- char **sessions; +- char *service_id; +- char *service_class; +- char *state; +- +- 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_class (sessions[i], &service_class); +- if (res < 0) { +- g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); +- ret = FALSE; +- goto out; +- } +- +- if (strcmp (service_class, "greeter") != 0) { +- free (service_class); +- continue; +- } +- +- free (service_class); +- +- ret = sd_session_get_state (sessions[i], &state); +- if (ret < 0) { +- g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); +- ret = FALSE; +- goto out; +- } +- +- if (g_strcmp0 (state, "closing") == 0) { +- free (state); +- continue; +- } +- free (state); +- +- 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-launch-environment") == 0) { +- *session_id = g_strdup (sessions[i]); +- ret = TRUE; +- +- free (service_id); +- goto out; +- } +- +- free (service_id); +- } +- +- *session_id = NULL; +- ret = TRUE; +- +-out: +- if (sessions) { +- for (i = 0; sessions[i]; i ++) { +- free (sessions[i]); +- } +- +- free (sessions); +- } +- +- return ret; +-} +- +-static void +-activate_login_window_session_on_seat (GdmManager *self, +- const char *seat_id) +-{ +- char *session_id; +- +- if (!get_login_window_session_id (seat_id, &session_id)) { +- return; +- } +- +- activate_session_id (self, seat_id, session_id); +-} +- +-static void +-maybe_activate_other_session (GdmManager *self, +- GdmDisplay *old_display) +-{ +- char *seat_id = NULL; +- char *session_id; +- int ret; +- +- g_object_get (G_OBJECT (old_display), +- "seat-id", &seat_id, +- NULL); +- +- ret = sd_seat_get_active (seat_id, &session_id, NULL); +- +- if (ret == 0) { +- GdmDisplay *display; +- +- display = gdm_display_store_find (self->priv->display_store, +- lookup_by_session_id, +- (gpointer) session_id); +- +- if (display == NULL) { +- activate_login_window_session_on_seat (self, seat_id); +- } +- } +- +- g_free (seat_id); +-} +- + static const char * + get_username_for_greeter_display (GdmManager *manager, + GdmDisplay *display) +@@ -1684,7 +1970,6 @@ on_display_status_changed (GdmDisplay *display, + manager->priv->ran_once = TRUE; + } + maybe_start_pending_initial_login (manager, display); +- maybe_activate_other_session (manager, display); + break; + default: + break; +@@ -2014,11 +2299,57 @@ on_user_session_died (GdmSession *session, + } + + static char * ++query_ck_for_display_device (GdmManager *manager, ++ GdmDisplay *display) ++{ ++ char *out; ++ char *command; ++ char *display_name = NULL; ++ int status; ++ gboolean res; ++ GError *error; ++ ++ g_object_get (G_OBJECT (display), ++ "x11-display-name", &display_name, ++ NULL); ++ ++ error = NULL; ++ command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s", ++ display_name); ++ g_free (display_name); ++ ++ g_debug ("GdmManager: Running helper %s", command); ++ out = NULL; ++ res = g_spawn_command_line_sync (command, ++ &out, ++ NULL, ++ &status, ++ &error); ++ if (! res) { ++ g_warning ("GdmManager: Could not run helper %s: %s", command, error->message); ++ g_error_free (error); ++ } else { ++ out = g_strstrip (out); ++ g_debug ("GdmManager: Got tty: '%s'", out); ++ } ++ ++ g_free (command); ++ ++ return out; ++} ++ ++static char * + get_display_device (GdmManager *manager, + GdmDisplay *display) + { +- /* systemd finds the display device out on its own based on the display */ +- return NULL; ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ /* systemd finds the display device out on its own based on the display */ ++ return NULL; ++ } ++#endif ++ ++ return query_ck_for_display_device (manager, display); + } + + static void +@@ -2027,26 +2358,6 @@ on_session_reauthenticated (GdmSession *session, + GdmManager *manager) + { + gboolean fail_if_already_switched = FALSE; +- +- if (gdm_session_get_display_mode (session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { +- const char *seat_id; +- char *session_id; +- +- seat_id = gdm_session_get_display_seat_id (session); +- if (get_login_window_session_id (seat_id, &session_id)) { +- GdmDisplay *display = gdm_display_store_find (manager->priv->display_store, +- lookup_by_session_id, +- (gpointer) session_id); +- +- if (display != NULL) { +- gdm_display_stop_greeter_session (display); +- gdm_display_unmanage (display); +- gdm_display_finish (display); +- } +- } +- g_free (session_id); +- } +- + /* There should already be a session running, so jump to its + * VT. In the event we're already on the right VT, (i.e. user + * used an unlock screen instead of a user switched login screen), +diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c +index 6357d344..6ecd0f70 100644 +--- a/daemon/gdm-server.c ++++ b/daemon/gdm-server.c +@@ -43,7 +43,9 @@ + #include + #endif + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #ifdef ENABLE_SYSTEMD_JOURNAL + #include +@@ -122,11 +124,59 @@ static void gdm_server_finalize (GObject *object); + + G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT) + ++static char * ++_gdm_server_query_ck_for_display_device (GdmServer *server) ++{ ++ char *out; ++ char *command; ++ int status; ++ gboolean res; ++ GError *error; ++ ++ g_return_val_if_fail (GDM_IS_SERVER (server), NULL); ++ ++ error = NULL; ++ command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s", ++ server->priv->display_name); ++ ++ g_debug ("GdmServer: Running helper %s", command); ++ out = NULL; ++ res = g_spawn_command_line_sync (command, ++ &out, ++ NULL, ++ &status, ++ &error); ++ if (! res) { ++ g_warning ("Could not run helper: %s", error->message); ++ g_error_free (error); ++ } else { ++ out = g_strstrip (out); ++ g_debug ("GdmServer: Got tty: '%s'", out); ++ } ++ ++ g_free (command); ++ ++ return out; ++} ++ + char * + gdm_server_get_display_device (GdmServer *server) + { +- /* systemd finds the display device out on its own based on the display */ +- return NULL; ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ /* systemd finds the display device out on its own based on the display */ ++ return NULL; ++ } ++#endif ++ ++ if (server->priv->display_device == NULL) { ++ server->priv->display_device = ++ _gdm_server_query_ck_for_display_device (server); ++ ++ g_object_notify (G_OBJECT (server), "display-device"); ++ } ++ ++ return g_strdup (server->priv->display_device); + } + + static void +@@ -226,7 +276,9 @@ gdm_server_init_command (GdmServer *server) + debug_options = ""; + } + +-#define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s" ++ #define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s" ++ ++#ifdef WITH_SYSTEMD + + /* This is a temporary hack to work around the fact that XOrg + * currently lacks support for multi-seat hotplugging for +@@ -242,6 +294,10 @@ gdm_server_init_command (GdmServer *server) + * wasn't booted using systemd, or b) the wrapper tool is + * missing, or c) we are running for the main seat 'seat0'. */ + ++ if (!LOGIND_RUNNING()) { ++ goto fallback; ++ } ++ + #ifdef ENABLE_SYSTEMD_JOURNAL + /* For systemd, we don't have a log file but instead log to stdout, + so set it to the xserver's built-in default verbosity */ +@@ -264,8 +320,9 @@ gdm_server_init_command (GdmServer *server) + return; + + fallback: +- server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options); ++#endif + ++ server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options); + } + + static gboolean +@@ -315,10 +372,12 @@ gdm_server_resolve_command_line (GdmServer *server, + argv[len++] = g_strdup (server->priv->auth_file); + } + +- if (server->priv->display_seat_id != NULL) { ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING() && server->priv->display_seat_id != NULL) { + argv[len++] = g_strdup ("-seat"); + argv[len++] = g_strdup (server->priv->display_seat_id); + } ++#endif + + /* If we were compiled with Xserver >= 1.17 we need to specify + * '-listen tcp' as the X server dosen't listen on tcp sockets +diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c +index 69dca2e5..c117f709 100644 +--- a/daemon/gdm-session-worker-job.c ++++ b/daemon/gdm-session-worker-job.c +@@ -36,7 +36,9 @@ + #include + #endif + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #ifdef ENABLE_SYSTEMD_JOURNAL + #include +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index d97b02b5..a6354163 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -28,9 +28,11 @@ + #include + #include + #include ++#ifdef WITH_SYSTEMD + #include + #include + #include ++#endif + #include + #include + #include +@@ -49,7 +51,9 @@ + + #include + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #ifdef ENABLE_SYSTEMD_JOURNAL + #include +@@ -131,6 +135,10 @@ struct GdmSessionWorkerPrivate + + int exit_code; + ++#ifdef WITH_CONSOLE_KIT ++ char *session_cookie; ++#endif ++ + pam_handle_t *pam_handle; + + GPid child_pid; +@@ -145,6 +153,7 @@ struct GdmSessionWorkerPrivate + char *hostname; + char *username; + char *log_file; ++ char *session_type; + char *session_id; + uid_t uid; + gid_t gid; +@@ -207,6 +216,204 @@ G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker, + G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER, + worker_interface_init)) + ++#ifdef WITH_CONSOLE_KIT ++static gboolean ++open_ck_session (GdmSessionWorker *worker) ++{ ++ GDBusConnection *system_bus; ++ GVariantBuilder builder; ++ GVariant *parameters; ++ GVariant *in_args; ++ struct passwd *pwent; ++ GVariant *reply; ++ GError *error = NULL; ++ const char *display_name; ++ const char *display_device; ++ const char *display_hostname; ++ const char *session_type; ++ gint32 uid; ++ ++ g_assert (worker->priv->session_cookie == NULL); ++ ++ if (worker->priv->x11_display_name != NULL) { ++ display_name = worker->priv->x11_display_name; ++ } else { ++ display_name = ""; ++ } ++ if (worker->priv->hostname != NULL) { ++ display_hostname = worker->priv->hostname; ++ } else { ++ display_hostname = ""; ++ } ++ if (worker->priv->display_device != NULL) { ++ display_device = worker->priv->display_device; ++ } else { ++ display_device = ""; ++ } ++ ++ if (worker->priv->session_type != NULL) { ++ session_type = worker->priv->session_type; ++ } else { ++ session_type = ""; ++ } ++ ++ g_assert (worker->priv->username != NULL); ++ ++ gdm_get_pwent_for_name (worker->priv->username, &pwent); ++ if (pwent == NULL) { ++ goto out; ++ } ++ ++ uid = (gint32) pwent->pw_uid; ++ ++ error = NULL; ++ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); ++ ++ if (system_bus == NULL) { ++ g_warning ("Couldn't create connection to system bus: %s", ++ error->message); ++ ++ g_error_free (error); ++ goto out; ++ } ++ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sv)")); ++ g_variant_builder_add_parsed (&builder, "('unix-user', <%i>)", uid); ++ g_variant_builder_add_parsed (&builder, "('x11-display-device', <%s>)", display_device); ++ g_variant_builder_add_parsed (&builder, "('x11-display', <%s>)", display_name); ++ g_variant_builder_add_parsed (&builder, "('remote-host-name', <%s>)", display_hostname); ++ g_variant_builder_add_parsed (&builder, "('is-local', <%b>)", worker->priv->display_is_local); ++ g_variant_builder_add_parsed (&builder, "('session-type', <%s>)", session_type); ++ ++ parameters = g_variant_builder_end (&builder); ++ in_args = g_variant_new_tuple (¶meters, 1); ++ ++ reply = g_dbus_connection_call_sync (system_bus, ++ "org.freedesktop.ConsoleKit", ++ "/org/freedesktop/ConsoleKit/Manager", ++ "org.freedesktop.ConsoleKit.Manager", ++ "OpenSessionWithParameters", ++ in_args, ++ G_VARIANT_TYPE ("(s)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ ++ if (! reply) { ++ g_warning ("%s\n", error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ g_variant_get (reply, "(s)", &worker->priv->session_cookie); ++ ++ g_variant_unref (reply); ++ ++out: ++ return worker->priv->session_cookie != NULL; ++} ++ ++static void ++close_ck_session (GdmSessionWorker *worker) ++{ ++ GDBusConnection *system_bus; ++ GVariant *reply; ++ GError *error = NULL; ++ gboolean was_closed; ++ ++ if (worker->priv->session_cookie == NULL) { ++ return; ++ } ++ ++ error = NULL; ++ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); ++ ++ if (system_bus == NULL) { ++ g_warning ("Couldn't create connection to system bus: %s", ++ error->message); ++ ++ g_error_free (error); ++ goto out; ++ } ++ ++ reply = g_dbus_connection_call_sync (system_bus, ++ "org.freedesktop.ConsoleKit", ++ "/org/freedesktop/ConsoleKit/Manager", ++ "org.freedesktop.ConsoleKit.Manager", ++ "CloseSession", ++ g_variant_new ("(s)", worker->priv->session_cookie), ++ G_VARIANT_TYPE ("(b)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ ++ if (! reply) { ++ g_warning ("%s", error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ g_variant_get (reply, "(b)", &was_closed); ++ ++ if (!was_closed) { ++ g_warning ("Unable to close ConsoleKit session"); ++ } ++ ++ g_variant_unref (reply); ++ ++out: ++ g_clear_pointer (&worker->priv->session_cookie, ++ (GDestroyNotify) g_free); ++} ++ ++static char * ++get_ck_session_id (GdmSessionWorker *worker) ++{ ++ GDBusConnection *system_bus; ++ GVariant *reply; ++ GError *error = NULL; ++ char *session_id = NULL; ++ ++ error = NULL; ++ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); ++ ++ if (system_bus == NULL) { ++ g_warning ("Couldn't create connection to system bus: %s", ++ error->message); ++ ++ g_error_free (error); ++ goto out; ++ } ++ ++ reply = g_dbus_connection_call_sync (system_bus, ++ "org.freedesktop.ConsoleKit", ++ "/org/freedesktop/ConsoleKit/Manager", ++ "org.freedesktop.ConsoleKit.Manager", ++ "GetSessionForCookie", ++ g_variant_new ("(s)", worker->priv->session_cookie), ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ ++ if (reply == NULL) { ++ g_warning ("%s", error->message); ++ g_clear_error (&error); ++ goto out; ++ } ++ ++ g_variant_get (reply, "(o)", &session_id); ++ ++ g_variant_unref (reply); ++ ++out: ++ return session_id; ++} ++#endif ++ + /* adapted from glib script_execute */ + static void + script_execute (const gchar *file, +@@ -754,6 +961,7 @@ gdm_session_worker_stop_auditor (GdmSessionWorker *worker) + worker->priv->auditor = NULL; + } + ++#ifdef WITH_SYSTEMD + static void + on_release_display (int signal) + { +@@ -879,6 +1087,7 @@ jump_to_vt (GdmSessionWorker *worker, + + close (active_vt_tty_fd); + } ++#endif + + static void + gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, +@@ -909,9 +1118,11 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, + + gdm_session_worker_stop_auditor (worker); + ++#ifdef WITH_SYSTEMD + if (worker->priv->login_vt != worker->priv->session_vt) { + jump_to_vt (worker, worker->priv->login_vt); + } ++#endif + + worker->priv->login_vt = 0; + worker->priv->session_vt = 0; +@@ -963,32 +1174,6 @@ _get_xauth_for_pam (const char *x11_authority_file) + #endif + + static gboolean +-ensure_login_vt (GdmSessionWorker *worker) +-{ +- int fd; +- struct vt_stat vt_state = { 0 }; +- gboolean got_login_vt = FALSE; +- +- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); +- +- if (fd < 0) { +- g_debug ("GdmSessionWorker: couldn't open VT master: %m"); +- return FALSE; +- } +- +- if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { +- g_debug ("GdmSessionWorker: couldn't get current VT: %m"); +- goto out; +- } +- +- worker->priv->login_vt = vt_state.v_active; +- got_login_vt = TRUE; +-out: +- close (fd); +- return got_login_vt; +-} +- +-static gboolean + gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + const char *service, + const char *username, +@@ -1002,7 +1187,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + { + struct pam_conv pam_conversation; + int error_code; +- char tty_string[256]; + + g_assert (worker->priv->pam_handle == NULL); + +@@ -1063,10 +1247,12 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + } + } + ++#ifdef WITH_SYSTEMD + /* set seat ID */ +- if (seat_id != NULL && seat_id[0] != '\0') { ++ if (seat_id != NULL && seat_id[0] != '\0' && LOGIND_RUNNING()) { + gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id); + } ++#endif + + if (strcmp (service, "gdm-launch-environment") == 0) { + gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter"); +@@ -1075,14 +1261,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, + g_debug ("GdmSessionWorker: state SETUP_COMPLETE"); + worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE; + +- /* Temporarily set PAM_TTY with the currently active VT (login screen) +- PAM_TTY will be reset with the users VT right before the user session is opened */ +- ensure_login_vt (worker); +- g_snprintf (tty_string, 256, "/dev/tty%d", worker->priv->login_vt); +- pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); +- if (!display_is_local) +- worker->priv->password_is_required = TRUE; +- + out: + if (error_code != PAM_SUCCESS) { + gdm_session_worker_uninitialize_pam (worker, error_code); +@@ -1629,6 +1807,26 @@ gdm_session_worker_get_environment (GdmSessionWorker *worker) + return (const char * const *) pam_getenvlist (worker->priv->pam_handle); + } + ++#ifdef WITH_CONSOLE_KIT ++static void ++register_ck_session (GdmSessionWorker *worker) ++{ ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ return; ++ } ++#endif ++ ++ open_ck_session (worker); ++ ++ if (worker->priv->session_cookie != NULL) { ++ gdm_session_worker_set_environment_variable (worker, ++ "XDG_SESSION_COOKIE", ++ worker->priv->session_cookie); ++ } ++} ++#endif ++ + static gboolean + run_script (GdmSessionWorker *worker, + const char *dir) +@@ -1659,6 +1857,9 @@ session_worker_child_watch (GPid pid, + : WIFSIGNALED (status) ? WTERMSIG (status) + : -1); + ++#ifdef WITH_CONSOLE_KIT ++ close_ck_session (worker); ++#endif + + gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); + +@@ -1849,12 +2050,14 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, + + error_code = PAM_SUCCESS; + ++#ifdef WITH_SYSTEMD + /* If we're in new vt mode, jump to the new vt now. There's no need to jump for + * the other two modes: in the logind case, the session will activate itself when + * ready, and in the reuse server case, we're already on the correct VT. */ + if (worker->priv->display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) { + jump_to_vt (worker, worker->priv->session_vt); + } ++#endif + + if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PostLogin")) { + g_set_error (error, +@@ -1919,6 +2122,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, + _exit (2); + } + ++#ifdef WITH_SYSTEMD + /* Take control of the tty + */ + if (needs_controlling_terminal) { +@@ -1926,6 +2130,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, + g_debug ("GdmSessionWorker: could not take control of tty: %m"); + } + } ++#endif + + #ifdef HAVE_LOGINCAP + if (setusercontext (NULL, passwd_entry, passwd_entry->pw_uid, LOGIN_SETALL) < 0) { +@@ -2070,11 +2275,13 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, + return TRUE; + } + ++#ifdef WITH_SYSTEMD + static gboolean + set_up_for_new_vt (GdmSessionWorker *worker) + { + int fd; + char vt_string[256], tty_string[256]; ++ struct vt_stat vt_state = { 0 }; + int session_vt = 0; + + fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); +@@ -2084,6 +2291,11 @@ set_up_for_new_vt (GdmSessionWorker *worker) + return FALSE; + } + ++ if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { ++ g_debug ("GdmSessionWorker: couldn't get current VT: %m"); ++ goto fail; ++ } ++ + if (worker->priv->display_is_initial) { + session_vt = atoi (GDM_INITIAL_VT); + } else { +@@ -2093,6 +2305,7 @@ set_up_for_new_vt (GdmSessionWorker *worker) + } + } + ++ worker->priv->login_vt = vt_state.v_active; + worker->priv->session_vt = session_vt; + + close (fd); +@@ -2155,6 +2368,7 @@ fail: + close (fd); + return FALSE; + } ++#endif + + static gboolean + set_up_for_current_vt (GdmSessionWorker *worker, +@@ -2222,12 +2436,14 @@ set_up_for_current_vt (GdmSessionWorker *worker, + } + #endif + ++#ifdef WITH_SYSTEMD + if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { + g_debug ("GdmSessionWorker: setting XDG_VTNR to current vt"); + set_xdg_vtnr_to_current_vt (worker); + } else { + g_debug ("GdmSessionWorker: not setting XDG_VTNR since not seat0"); + } ++#endif + + return TRUE; + out: +@@ -2251,6 +2467,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, + return FALSE; + } + break; ++#ifdef WITH_SYSTEMD + case GDM_SESSION_DISPLAY_MODE_NEW_VT: + case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED: + if (!set_up_for_new_vt (worker)) { +@@ -2261,6 +2478,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, + return FALSE; + } + break; ++#endif + } + + flags = 0; +@@ -2282,7 +2500,17 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, + g_debug ("GdmSessionWorker: state SESSION_OPENED"); + worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED; + ++#ifdef WITH_SYSTEMD + session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID"); ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ register_ck_session (worker); ++ ++ if (session_id == NULL) { ++ session_id = get_ck_session_id (worker); ++ } ++#endif + + if (session_id != NULL) { + g_free (worker->priv->session_id); +@@ -2388,6 +2616,19 @@ gdm_session_worker_handle_set_session_name (GdmDBusWorker *object, + } + + static gboolean ++gdm_session_worker_handle_set_session_type (GdmDBusWorker *object, ++ GDBusMethodInvocation *invocation, ++ const char *session_type) ++{ ++ GdmSessionWorker *worker = GDM_SESSION_WORKER (object); ++ g_debug ("GdmSessionWorker: session type set to %s", session_type); ++ g_free (worker->priv->session_type); ++ worker->priv->session_type = g_strdup (session_type); ++ gdm_dbus_worker_complete_set_session_type (object, invocation); ++ return TRUE; ++} ++ ++static gboolean + gdm_session_worker_handle_set_session_display_mode (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *str) +@@ -3194,6 +3435,7 @@ worker_interface_init (GdmDBusWorkerIface *interface) + interface->handle_open = gdm_session_worker_handle_open; + interface->handle_set_language_name = gdm_session_worker_handle_set_language_name; + interface->handle_set_session_name = gdm_session_worker_handle_set_session_name; ++ interface->handle_set_session_type = gdm_session_worker_handle_set_session_type; + interface->handle_set_session_display_mode = gdm_session_worker_handle_set_session_display_mode; + interface->handle_set_environment_variable = gdm_session_worker_handle_set_environment_variable; + interface->handle_start_program = gdm_session_worker_handle_start_program; +diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml +index 9f6d8b35..853bc6a4 100644 +--- a/daemon/gdm-session-worker.xml ++++ b/daemon/gdm-session-worker.xml +@@ -13,6 +13,9 @@ + + + ++ ++ ++ + + + +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index ff3a1acb..5e26c5b5 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -3076,6 +3076,10 @@ gdm_session_bypasses_xsession (GdmSession *self) + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + ++ if (!LOGIND_RUNNING()) { ++ return GDM_SESSION_DISPLAY_MODE_REUSE_VT; ++ } ++ + #ifdef ENABLE_WAYLAND_SUPPORT + if (gdm_session_is_wayland_session (self)) { + bypasses_xsession = TRUE; +@@ -3171,6 +3175,27 @@ gdm_session_select_program (GdmSession *self, + } + + void ++gdm_session_select_session_type (GdmSession *self, ++ const char *text) ++{ ++ GHashTableIter iter; ++ gpointer key, value; ++ ++ g_debug ("GdmSession: selecting session type '%s'", text); ++ ++ g_hash_table_iter_init (&iter, self->priv->conversations); ++ while (g_hash_table_iter_next (&iter, &key, &value)) { ++ GdmSessionConversation *conversation; ++ ++ conversation = (GdmSessionConversation *) value; ++ ++ gdm_dbus_worker_call_set_session_type (conversation->worker_proxy, ++ text, ++ NULL, NULL, NULL); ++ } ++} ++ ++void + gdm_session_select_session (GdmSession *self, + const char *text) + { +diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h +index a22c0954..44b16f64 100644 +--- a/daemon/gdm-session.h ++++ b/daemon/gdm-session.h +@@ -180,6 +180,8 @@ void gdm_session_answer_query (GdmSession *session, + const char *text); + void gdm_session_select_program (GdmSession *session, + const char *command_line); ++void gdm_session_select_session_type (GdmSession *session, ++ const char *session_type); + void gdm_session_select_session (GdmSession *session, + const char *session_name); + void gdm_session_select_user (GdmSession *session, +diff --git a/libgdm/gdm-user-switching.c b/libgdm/gdm-user-switching.c +index 3d4303e3..a195d052 100644 +--- a/libgdm/gdm-user-switching.c ++++ b/libgdm/gdm-user-switching.c +@@ -31,12 +31,25 @@ + #include + #include + ++#ifdef WITH_SYSTEMD + #include ++#endif + + #include "common/gdm-common.h" + #include "gdm-user-switching.h" + #include "gdm-client.h" + ++#ifdef WITH_CONSOLE_KIT ++#define CK_NAME "org.freedesktop.ConsoleKit" ++#define CK_PATH "/org/freedesktop/ConsoleKit" ++#define CK_INTERFACE "org.freedesktop.ConsoleKit" ++ ++#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" ++#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 gboolean + create_transient_display (GDBusConnection *connection, + GCancellable *cancellable, +@@ -67,12 +80,304 @@ create_transient_display (GDBusConnection *connection, + return TRUE; + } + ++#ifdef WITH_CONSOLE_KIT ++ ++static gboolean ++get_current_session_id (GDBusConnection *connection, ++ char **session_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ CK_MANAGER_PATH, ++ CK_MANAGER_INTERFACE, ++ "GetCurrentSession", ++ NULL, /* parameters */ ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine session: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(o)", session_id); ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static gboolean ++get_seat_id_for_session (GDBusConnection *connection, ++ const char *session_id, ++ char **seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ session_id, ++ CK_SESSION_INTERFACE, ++ "GetSeatId", ++ NULL, /* parameters */ ++ G_VARIANT_TYPE ("(o)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine seat: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(o)", seat_id); ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static char * ++get_current_seat_id (GDBusConnection *connection) ++{ ++ gboolean res; ++ char *session_id; ++ char *seat_id; ++ ++ session_id = NULL; ++ seat_id = NULL; ++ ++ res = get_current_session_id (connection, &session_id); ++ if (res) { ++ res = get_seat_id_for_session (connection, session_id, &seat_id); ++ } ++ g_free (session_id); ++ ++ return seat_id; ++} ++ ++static gboolean ++activate_session_id_for_ck (GDBusConnection *connection, ++ GCancellable *cancellable, ++ const char *seat_id, ++ const char *session_id, ++ GError **error) ++{ ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "ActivateSession", ++ g_variant_new ("(o)", session_id), ++ NULL, ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, error); ++ if (reply == NULL) { ++ g_prefix_error (error, _("Unable to activate session: ")); ++ return FALSE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static gboolean ++session_is_login_window (GDBusConnection *connection, ++ const char *session_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ const char *value; ++ gboolean ret; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ session_id, ++ CK_SESSION_INTERFACE, ++ "GetSessionType", ++ NULL, ++ G_VARIANT_TYPE ("(s)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine session type: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(&s)", &value); ++ ++ if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) { ++ ret = FALSE; ++ } else { ++ ret = TRUE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return ret; ++} ++ ++static gboolean ++seat_can_activate_sessions (GDBusConnection *connection, ++ const char *seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ gboolean ret; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "CanActivateSessions", ++ NULL, ++ G_VARIANT_TYPE ("(b)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to determine if can activate sessions: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(b)", &ret); ++ g_variant_unref (reply); ++ ++ return ret; ++} ++ ++static const char ** ++seat_get_sessions (GDBusConnection *connection, ++ const char *seat_id) ++{ ++ GError *local_error = NULL; ++ GVariant *reply; ++ const char **value; ++ ++ reply = g_dbus_connection_call_sync (connection, ++ CK_NAME, ++ seat_id, ++ CK_SEAT_INTERFACE, ++ "GetSessions", ++ NULL, ++ G_VARIANT_TYPE ("(ao)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, &local_error); ++ if (reply == NULL) { ++ g_warning ("Unable to list sessions: %s", local_error->message); ++ g_error_free (local_error); ++ return FALSE; ++ } ++ ++ g_variant_get (reply, "(^ao)", &value); ++ g_variant_unref (reply); ++ ++ return value; ++} ++ ++static gboolean ++get_login_window_session_id_for_ck (GDBusConnection *connection, ++ const char *seat_id, ++ char **session_id) ++{ ++ gboolean can_activate_sessions; ++ const char **sessions; ++ int i; ++ ++ *session_id = NULL; ++ sessions = NULL; ++ ++ g_debug ("checking if seat can activate sessions"); ++ ++ can_activate_sessions = seat_can_activate_sessions (connection, seat_id); ++ if (! can_activate_sessions) { ++ g_debug ("seat is unable to activate sessions"); ++ return FALSE; ++ } ++ ++ sessions = seat_get_sessions (connection, seat_id); ++ for (i = 0; sessions [i] != NULL; i++) { ++ const char *ssid; ++ ++ ssid = sessions [i]; ++ ++ if (session_is_login_window (connection, ssid)) { ++ *session_id = g_strdup (ssid); ++ break; ++ } ++ } ++ g_free (sessions); ++ ++ return TRUE; ++} ++ + static gboolean +-activate_session_id (GDBusConnection *connection, +- GCancellable *cancellable, +- const char *seat_id, +- const char *session_id, +- GError **error) ++goto_login_session_for_ck (GDBusConnection *connection, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ gboolean ret; ++ gboolean res; ++ 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"); ++ g_set_error (error, GDM_CLIENT_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_CLIENT_ERROR, 0, _("User unable to switch sessions.")); ++ return FALSE; ++ } ++ ++ if (session_id != NULL) { ++ res = activate_session_id_for_ck (connection, cancellable, seat_id, session_id, error); ++ if (res) { ++ ret = TRUE; ++ } ++ } ++ ++ if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) { ++ res = create_transient_display (connection, cancellable, error); ++ if (res) { ++ ret = TRUE; ++ } ++ } ++ ++ return ret; ++} ++#endif ++ ++#ifdef WITH_SYSTEMD ++ ++static gboolean ++activate_session_id_for_systemd (GDBusConnection *connection, ++ GCancellable *cancellable, ++ const char *seat_id, ++ const char *session_id, ++ GError **error) + { + GVariant *reply; + +@@ -97,8 +402,8 @@ activate_session_id (GDBusConnection *connection, + } + + static gboolean +-get_login_window_session_id (const char *seat_id, +- char **session_id) ++get_login_window_session_id_for_systemd (const char *seat_id, ++ char **session_id) + { + gboolean ret; + int res, i; +@@ -182,9 +487,9 @@ out: + } + + static gboolean +-goto_login_session (GDBusConnection *connection, +- GCancellable *cancellable, +- GError **error) ++goto_login_session_for_systemd (GDBusConnection *connection, ++ GCancellable *cancellable, ++ GError **error) + { + gboolean ret; + int res; +@@ -238,9 +543,9 @@ goto_login_session (GDBusConnection *connection, + return FALSE; + } + +- res = get_login_window_session_id (seat_id, &session_id); ++ res = get_login_window_session_id_for_systemd (seat_id, &session_id); + if (res && session_id != NULL) { +- res = activate_session_id (connection, cancellable, seat_id, session_id, error); ++ res = activate_session_id_for_systemd (connection, cancellable, seat_id, session_id, error); + + if (res) { + ret = TRUE; +@@ -259,10 +564,11 @@ goto_login_session (GDBusConnection *connection, + + return ret; + } ++#endif + + gboolean + gdm_goto_login_session_sync (GCancellable *cancellable, +- GError **error) ++ GError **error) + { + GDBusConnection *connection; + gboolean retval; +@@ -271,8 +577,23 @@ gdm_goto_login_session_sync (GCancellable *cancellable, + if (!connection) + return FALSE; + +- retval = goto_login_session (connection, cancellable, error); ++#ifdef WITH_SYSTEMD ++ if (LOGIND_RUNNING()) { ++ retval = goto_login_session_for_systemd (connection, ++ cancellable, ++ error); ++ ++ g_object_unref (connection); ++ return retval; ++ } ++#endif ++ ++#ifdef WITH_CONSOLE_KIT ++ retval = goto_login_session_for_ck (connection, cancellable, error); + + g_object_unref (connection); + return retval; ++#else ++ return FALSE; ++#endif + } +-- +2.13.0 + -- cgit v1.2.3