From 32964af4bf85ba8668606c8895795ec2af762b2c Mon Sep 17 00:00:00 2001
From: Niveditha Rau <niveditha.rau@oracle.com>
Date: Tue, 29 Dec 2015 11:59:18 -0800
Subject: [PATCH 02/19] disable systemd

---
 common/gdm-common.c                | 330 ++++++++++++++++++++++-
 common/gdm-common.h                |   3 +
 common/gdm-log.c                   |  21 ++
 configure.ac                       |  80 +++---
 daemon/Makefile.am                 |  10 +
 daemon/gdm-launch-environment.c    |   5 +
 daemon/gdm-local-display-factory.c |  60 ++++-
 daemon/gdm-manager.c               | 531 ++++++++++++++++++++++++++++++++++---
 daemon/gdm-server.c                |  75 +++++-
 daemon/gdm-session-record.c        | 102 ++++++-
 daemon/gdm-session-worker-job.c    |   3 +
 daemon/gdm-session-worker.c        | 277 ++++++++++++++++++-
 daemon/gdm-session-worker.xml      |   3 +
 daemon/gdm-session.c               |  26 ++
 daemon/gdm-session.h               |   2 +
 libgdm/gdm-user-switching.c        | 351 +++++++++++++++++++++++-
 16 files changed, 1749 insertions(+), 130 deletions(-)

diff --git a/common/gdm-common.c b/common/gdm-common.c
index a96b30f..e06f0d9 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -39,12 +39,25 @@
 #include "mkdtemp.h"
 #endif
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-login.h>
+#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,300 @@ 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
-activate_session_id (GDBusConnection *connection,
-                     const char      *seat_id,
-                     const char      *session_id)
+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_for_systemd (GDBusConnection *connection,
+                                 const char      *seat_id,
+                                 const char      *session_id)
 {
         GError *local_error = NULL;
         GVariant *reply;
@@ -373,8 +676,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,7 +745,7 @@ out:
 }
 
 static gboolean
-goto_login_session (GDBusConnection  *connection,
+goto_login_session_for_systemd (GDBusConnection  *connection,
                     GError          **error)
 {
         gboolean        ret;
@@ -497,7 +800,7 @@ 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);
 
@@ -518,6 +821,7 @@ goto_login_session (GDBusConnection  *connection,
 
         return ret;
 }
+#endif
 
 gboolean
 gdm_goto_login_session (GError **error)
@@ -533,7 +837,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 d0812ed..19dbbbb 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -33,6 +33,9 @@
 
 #define GDM_CUSTOM_SESSION  "custom"
 
+/* 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 8a2d015..03b7bcc 100644
--- a/common/gdm-log.c
+++ b/common/gdm-log.c
@@ -30,7 +30,9 @@
 #include <unistd.h>
 
 #include <syslog.h>
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-daemon.h>
+#endif
 
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -132,8 +134,27 @@ gdm_log_init (void)
                 return;
 
         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 bedac99..0ada667 100644
--- a/configure.ac
+++ b/configure.ac
@@ -244,6 +244,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],
@@ -614,14 +623,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" ])
@@ -870,51 +873,16 @@ AC_SUBST(XINERAMA_LIBS)
 CPPFLAGS="$xinerama_save_cppflags"
 
 dnl ---------------------------------------------------------------------------
-dnl - Check for systemd support
+dnl - Check for ConsoleKit support
 dnl ---------------------------------------------------------------------------
 
-PKG_CHECK_MODULES(SYSTEMD,
-                  [libsystemd])
-
-AC_SUBST(SYSTEMD_CFLAGS)
-AC_SUBST(SYSTEMD_LIBS)
-
-PKG_CHECK_MODULES(JOURNALD,
-                  [libsystemd],
-                  [have_journald=yes], [have_journald=no])
-
-if test "x$enable_systemd_journal" = "xauto" ; then
-        if test x$have_journald = xno ; then
-                use_journald=no
-        else
-                use_journald=yes
-        fi
-
-else
-        use_journald="$enable_systemd_journal"
-fi
-
-if test "x$use_journald" != "xno" ; then
-        if test "x$have_journald" = "xno"; then
-                AC_MSG_ERROR([journald support explicitly required, but journald not found])
-        fi
-
-        AC_DEFINE(ENABLE_SYSTEMD_JOURNAL, 1, [Define to enable systemd journal support])
-fi
-AC_SUBST(JOURNALD_CFLAGS)
-AC_SUBST(JOURNALD_LIBS)
-
-if test "x$enable_wayland_support" != "xno" ; then
-        AC_DEFINE(ENABLE_WAYLAND_SUPPORT, 1, [Define to enable wayland support])
-fi
-
-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])
-
-if test "x$with_systemdsystemunitdir" != xno; then
-        AC_SUBST(SYSTEMD_SYSTEM_UNIT_DIR, [$with_systemdsystemunitdir])
+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 plymouth support
@@ -1068,6 +1036,15 @@ 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@:>@])],,
@@ -1549,6 +1526,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}
@@ -1578,6 +1556,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:          ${use_wayland}
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index ab5dda0..dece5db 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 1beceea..b176c63 100644
--- a/daemon/gdm-launch-environment.c
+++ b/daemon/gdm-launch-environment.c
@@ -176,6 +176,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));
         }
@@ -204,6 +207,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 de6ecdd..5d58a89 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 SYSTEMD_SEAT0_PATH                  "seat0"
 
 #define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
@@ -59,8 +61,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 {
@@ -190,8 +194,22 @@ store_display (GdmLocalDisplayFactory *factory,
 static const char *
 get_seat_of_transient_display (GdmLocalDisplayFactory *factory)
 {
+
+        const char *seat_id = NULL;
+
         /* FIXME: don't hardcode seat */
-        return SYSTEMD_SEAT0_PATH;
+
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING() > 0) {
+                seat_id = SYSTEMD_SEAT0_PATH;
+        }
+#endif
+
+        if (seat_id == NULL) {
+                seat_id = CK_SEAT1_PATH;
+        }
+
+        return seat_id;
 }
 
 /*
@@ -216,7 +234,19 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
 
         g_debug ("GdmLocalDisplayFactory: Creating transient display");
 
-        display = gdm_local_display_new ();
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING() > 0) {
+                display = gdm_local_display_new ();
+        }
+#endif
+
+        if (display == NULL) {
+                guint32 num;
+
+                num = take_next_display_number (factory);
+
+                display = gdm_legacy_display_new (num);
+        }
 
         seat_id = get_seat_of_transient_display (factory);
         g_object_set (display,
@@ -290,7 +320,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:
@@ -371,13 +401,14 @@ create_display (GdmLocalDisplayFactory *factory,
 
         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
 
-
+#ifdef WITH_SYSTEMD
         if (g_strcmp0 (seat_id, "seat0") == 0) {
                 display = gdm_local_display_new ();
                 if (session_type != NULL) {
                         g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
                 }
         }
+#endif
 
         if (display == NULL) {
                 guint32 num;
@@ -402,6 +433,7 @@ create_display (GdmLocalDisplayFactory *factory,
         return display;
 }
 
+#ifdef WITH_SYSTEMD
 static void
 delete_display (GdmLocalDisplayFactory *factory,
                 const char             *seat_id) {
@@ -538,6 +570,7 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
                 factory->priv->seat_removed_id = 0;
         }
 }
+#endif
 
 static void
 on_display_added (GdmDisplayStore        *display_store,
@@ -578,6 +611,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);
@@ -596,8 +630,18 @@ 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
@@ -608,7 +652,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));
 
@@ -764,7 +810,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 7602e75..3d1d2eb 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -34,7 +34,9 @@
 #include <glib/gstdio.h>
 #include <glib-object.h>
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-login.h>
+#endif
 
 #include "gdm-common.h"
 
@@ -59,6 +61,15 @@
 
 #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
 {
         GdmManager *manager;
@@ -202,9 +213,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;
@@ -229,11 +241,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;
 
@@ -250,6 +312,61 @@ 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,
@@ -263,10 +380,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;
@@ -291,11 +448,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;
@@ -322,15 +500,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",
@@ -354,6 +591,60 @@ 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,
@@ -385,10 +676,43 @@ find_session_for_user_on_seat (GdmManager *manager,
         return NULL;
 }
 
+#ifdef WITH_CONSOLE_KIT
 static gboolean
-is_remote_session (GdmManager  *self,
-                   const char  *session_id,
-                   GError     **error)
+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_systemd_remote_session (GdmManager  *self,
+                           const char  *session_id,
+                           GError     **error)
 {
         char *seat;
         int ret;
@@ -414,10 +738,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;
@@ -442,10 +787,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;
@@ -469,6 +865,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,
@@ -512,7 +922,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",
@@ -526,7 +936,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",
@@ -536,7 +946,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);
@@ -553,7 +963,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",
@@ -563,7 +973,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",
@@ -927,7 +1337,7 @@ 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");
 
@@ -1139,16 +1549,19 @@ 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);
-
-        if (g_strcmp0 (seat_id, "seat0") != 0) {
-            is_on_seat0 = FALSE;
-        }
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                char *seat_id = NULL;
 
-        g_free (seat_id);
+                g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
 
+                if (g_strcmp0 (seat_id, "seat0") != 0) {
+                        is_on_seat0 = FALSE;
+                }
+                g_free (seat_id);
+        }
+#endif
         return is_on_seat0;
 }
 
@@ -1749,11 +2162,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
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index eb7db0e..08f2354 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -43,7 +43,9 @@
 #include <linux/vt.h>
 #endif
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-daemon.h>
+#endif
 
 #ifdef ENABLE_SYSTEMD_JOURNAL
 #include <systemd/sd-journal.h>
@@ -122,23 +124,66 @@ 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
 gdm_server_ready (GdmServer *server)
 {
         g_debug ("GdmServer: Got USR1 from X server - emitting READY");
-
-        gdm_run_script (GDMCONFDIR "/Init", GDM_USERNAME,
-                        server->priv->display_name,
-                        NULL, /* hostname */
-                        server->priv->auth_file);
-
         g_signal_emit (server, signals[READY], 0);
 }
 
@@ -159,7 +204,7 @@ got_sigusr1 (gpointer user_data)
                 GdmServer *server = l->data;
 
                 if (server->priv->pid == pid)
-                        gdm_server_ready (server);
+                       gdm_server_ready (server);
         }
 
         return G_SOURCE_REMOVE;
@@ -228,6 +273,8 @@ gdm_server_init_command (GdmServer *server)
 
 #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
          * display devices. This bit should be removed as soon as XOrg
@@ -242,6 +289,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,6 +315,8 @@ gdm_server_init_command (GdmServer *server)
         return;
 
 fallback:
+#endif
+
         server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
 
 }
@@ -315,10 +368,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 (server->priv->disable_tcp && ! query_in_arglist) {
                 argv[len++] = g_strdup ("-nolisten");
diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c
index 32933ef..590a1e8 100644
--- a/daemon/gdm-session-record.c
+++ b/daemon/gdm-session-record.c
@@ -33,6 +33,16 @@
 #include <utmp.h>
 #endif
 
+#if defined(HAVE_UTIL_H)
+#include <util.h>
+#endif
+
+#if defined(HAVE_GETTTYENT)
+#include <fcntl.h> /* open(2) */
+#include <ttyent.h>
+static int fd = -1;
+#endif
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
@@ -43,6 +53,10 @@
 #define GDM_BAD_SESSION_RECORDS_FILE "/var/log/btmp"
 #endif
 
+static void write_utmp_login_manually (struct utmp *ut);
+static void write_utmp_logout_manually (char *);
+
+
 #if !defined(GDM_NEW_SESSION_RECORDS_FILE)
 #    if defined(WTMPX_FILE)
 #        define GDM_NEW_SESSION_RECORDS_FILE WTMPX_FILE
@@ -183,6 +197,85 @@ record_set_line (UTMP       *u,
         g_debug ("using ut_line %.*s", (int) sizeof (u->ut_line), u->ut_line);
 }
 
+static void
+write_utmp_login_manually (struct utmp *ut)
+{
+#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H)
+        UTMP ubuf;
+        int topslot = -1;
+
+        g_debug ("Adding new utmp record");
+
+        /*
+         * First, loop through /etc/ttys, if needed, to initialize the
+         * top of the tty slots, since gdm has no tty.
+         */
+        if (topslot < 0) {
+                topslot = 0;
+                while (getttyent () != (struct ttyent *) NULL)
+                        topslot++;
+        }
+        if ((topslot < 0) || ((fd < 0) &&
+            (fd = open (_PATH_UTMP, O_RDWR|O_CREAT, 0644)) < 0))
+                return;
+
+        /*
+         * Now find a slot that's not in use...
+         */
+        (void) lseek (fd, (off_t) (topslot * sizeof (struct utmp)), SEEK_SET);
+
+        while (1) {
+                if (read (fd, &ubuf, sizeof (struct utmp)) ==
+                    sizeof (struct utmp)) {
+                        if (!ubuf.ut_name[0]) {
+                                (void) lseek (fd, -(off_t) sizeof (struct utmp),
+                                    SEEK_CUR);
+                                break;
+                        }
+                        topslot++;
+                } else {
+                        (void) lseek (fd, (off_t) (topslot *
+                            sizeof (struct utmp)), SEEK_SET);
+                        break;
+                }
+        }
+
+        (void) write (fd, ut, sizeof (struct utmp));
+#endif
+}
+
+static void
+write_utmp_logout_manually (char *line)
+{
+#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H)
+        int rval = 1;
+        struct timeval tv;
+        UTMP ut;
+
+        g_debug ("Removing utmp record");
+
+
+        if (fd >= 0) {
+            (void) lseek (fd, 0, SEEK_SET);
+            while (read (fd, &ut, sizeof (struct utmp)) == sizeof (struct utmp)) {
+                    if (!ut.ut_name[0] ||
+                        strncmp (ut.ut_line, line, UT_LINESIZE))
+                            continue;
+                    bzero (ut.ut_name, UT_NAMESIZE);
+                    bzero (ut.ut_host, UT_HOSTSIZE);
+                    gettimeofday (&tv, NULL);
+                    ut.ut_time = tv.tv_sec;
+                    (void) lseek (fd, -(off_t) sizeof (struct utmp), SEEK_CUR);
+                    (void) write (fd, &ut, sizeof (struct utmp));
+                    rval = 0;
+            }
+        }
+
+        if (rval != 0)
+            g_debug ("Failed to remove utmp record");
+#endif
+}
+
 void
 gdm_session_record_login (GPid                  session_pid,
                           const char           *user_name,
@@ -227,8 +320,9 @@ gdm_session_record_login (GPid                  session_pid,
 #if defined(HAVE_GETUTXENT)
         g_debug ("Adding or updating utmp record for login");
         pututxline (&session_record);
-#elif defined(HAVE_LOGIN)
-	login (&session_record);
+#else
+        if (strcmp (session_record.ut_name, "(unknown)") != 0)
+            write_utmp_login_manually (&session_record);
 #endif
 }
 
@@ -270,8 +364,8 @@ gdm_session_record_logout (GPid                  session_pid,
 #if defined(HAVE_GETUTXENT)
         g_debug ("Adding or updating utmp record for logout");
         pututxline (&session_record);
-#elif defined(HAVE_LOGOUT)
-        logout (session_record.ut_line);
+#else
+        write_utmp_logout_manually (session_record.ut_line);
 #endif
 }
 
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
index 69dca2e..52a6e9f 100644
--- a/daemon/gdm-session-worker-job.c
+++ b/daemon/gdm-session-worker-job.c
@@ -36,7 +36,10 @@
 #include <sys/prctl.h>
 #endif
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-daemon.h>
+#endif
+
 
 #ifdef ENABLE_SYSTEMD_JOURNAL
 #include <systemd/sd-journal.h>
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 5ae5b3f..3b10940 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -28,9 +28,11 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#ifdef WITH_SYSTEMD
 #include <sys/ioctl.h>
 #include <sys/vt.h>
 #include <sys/kd.h>
+#endif
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
@@ -49,7 +51,9 @@
 
 #include <X11/Xauth.h>
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-daemon.h>
+#endif
 
 #ifdef ENABLE_SYSTEMD_JOURNAL
 #include <systemd/sd-journal.h>
@@ -130,6 +134,9 @@ struct GdmSessionWorkerPrivate
         int               state;
 
         int               exit_code;
+#ifdef WITH_CONSOLE_KIT
+        char             *session_cookie;
+#endif
 
         pam_handle_t     *pam_handle;
 
@@ -145,6 +152,7 @@ struct GdmSessionWorkerPrivate
         char             *hostname;
         char             *username;
         char             *log_file;
+        char             *session_type;
         char             *session_id;
         uid_t             uid;
         gid_t             gid;
@@ -207,6 +215,207 @@ 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 (&parameters, 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 +963,7 @@ gdm_session_worker_stop_auditor (GdmSessionWorker *worker)
         worker->priv->auditor = NULL;
 }
 
+#ifdef WITH_SYSTEMD
 static void
 on_release_display (int signal)
 {
@@ -879,6 +1089,7 @@ jump_to_vt (GdmSessionWorker  *worker,
 
         close (active_vt_tty_fd);
 }
+#endif
 
 static void
 gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
@@ -909,9 +1120,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;
@@ -1036,10 +1249,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");
@@ -1235,6 +1450,7 @@ gdm_session_worker_environment_variable_is_set (GdmSessionWorker *worker,
         return pam_getenv (worker->priv->pam_handle, key) != NULL;
 }
 
+
 static gboolean
 _change_user (GdmSessionWorker  *worker,
               uid_t              uid,
@@ -1595,6 +1811,27 @@ 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)
@@ -1625,6 +1862,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);
 
@@ -1813,12 +2053,15 @@ 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
 
         session_pid = fork ();
 
@@ -1865,6 +2108,7 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
                         _exit (2);
                 }
 
+#ifdef WITH_SYSTEMD
                 /* Take control of the tty
                  */
                 if (needs_controlling_terminal) {
@@ -1872,6 +2116,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) {
@@ -2016,6 +2261,7 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
         return TRUE;
 }
 
+#ifdef WITH_SYSTEMD
 static gboolean
 set_up_for_new_vt (GdmSessionWorker *worker)
 {
@@ -2073,6 +2319,7 @@ fail:
         close (fd);
         return FALSE;
 }
+#endif
 
 static gboolean
 set_up_for_current_vt (GdmSessionWorker  *worker,
@@ -2161,6 +2408,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)) {
@@ -2171,6 +2419,7 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
                         return FALSE;
                 }
                 break;
+#endif
         }
 
         flags = 0;
@@ -2200,7 +2449,9 @@ 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
 
         /* FIXME: should we do something here?
          * Note that error return status from PreSession script should
@@ -2210,6 +2461,14 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
          */
         run_script (worker, GDMCONFDIR "/PreSession");
 
+#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);
                 worker->priv->session_id = session_id;
@@ -2314,6 +2573,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)
@@ -3121,6 +3393,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 9f6d8b3..853bc6a 100644
--- a/daemon/gdm-session-worker.xml
+++ b/daemon/gdm-session-worker.xml
@@ -13,6 +13,9 @@
     <method name="SetSessionName">
       <arg name="session_name" direction="in" type="s" />
     </method>
+    <method name="SetSessionType">
+      <arg name="session_type" direction="in" type="s"/>
+    </method>
     <method name="SetSessionDisplayMode">
       <arg name="mode" direction="in" type="s"/>
     </method>
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 5707b15..49edb0c 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -3071,6 +3071,11 @@ gdm_session_get_display_mode (GdmSession *self)
                  self->priv->is_program_session? "yes" : "no",
                  self->priv->display_seat_id);
 
+        if (!LOGIND_RUNNING()) {
+                return GDM_SESSION_DISPLAY_MODE_REUSE_VT;
+        }
+
+
 #ifdef ENABLE_WAYLAND_SUPPORT
         /* Wayland sessions are for now assumed to run in a
          * mutter-launch-like environment, so we allocate
@@ -3112,6 +3117,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 7cfaca1..6d13f11 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -176,6 +176,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 3d4303e..b08d7a5 100644
--- a/libgdm/gdm-user-switching.c
+++ b/libgdm/gdm-user-switching.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -
  *
  * Copyright (C) 2012 Red Hat, Inc.
  * Copyright (C) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
@@ -31,12 +31,26 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-login.h>
+#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 +81,305 @@ 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
+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 (GDBusConnection  *connection,
-                     GCancellable     *cancellable,
-                     const char       *seat_id,
-                     const char       *session_id,
-                     GError          **error)
+activate_session_id_for_systemd (GDBusConnection  *connection,
+                                 GCancellable     *cancellable,
+                                 const char       *seat_id,
+                                 const char       *session_id,
+                                 GError          **error)
 {
         GVariant *reply;
 
@@ -97,8 +404,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 +489,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 +545,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,6 +566,7 @@ goto_login_session (GDBusConnection  *connection,
 
         return ret;
 }
+#endif
 
 gboolean
 gdm_goto_login_session_sync (GCancellable  *cancellable,
@@ -271,8 +579,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.7.4

