[gdm/wip/multi-seat-2-30] Add ConsoleKit MultiSeat support. See bug #536355.



commit 137b3c55d2ab45d0ea99eaa34871b591f7767a2c
Author: Brian Cameron <brian cameron oracle com>
Date:   Thu Dec 15 17:25:52 2011 -0600

    Add ConsoleKit MultiSeat support.  See bug #536355.

 common/gdm-marshal.list            |    1 +
 common/gdm-settings-keys.h         |    2 -
 configure.ac                       |  134 +-----
 daemon/Makefile.am                 |    2 +
 daemon/ck-connector.c              |  187 ++++++++
 daemon/ck-connector.h              |    5 +
 daemon/gdm-display.c               |  225 +++++++++-
 daemon/gdm-display.h               |   20 +
 daemon/gdm-display.xml             |   23 +-
 daemon/gdm-dynamic-display.c       |  246 +++++++++++
 daemon/gdm-dynamic-display.h       |   60 +++
 daemon/gdm-factory-slave.c         |   20 +-
 daemon/gdm-greeter-session.c       |    4 +
 daemon/gdm-greeter-session.h       |    2 +
 daemon/gdm-local-display-factory.c |  858 ++++++++++++++++++++++++++++++++++--
 daemon/gdm-product-slave.c         |   11 +-
 daemon/gdm-server.c                |  221 +++++++---
 daemon/gdm-server.h                |    3 +-
 daemon/gdm-session-direct.c        |  263 +++++++++++
 daemon/gdm-session-worker.c        |   42 ++-
 daemon/gdm-simple-slave.c          |   58 ++-
 daemon/gdm-slave-proxy.c           |    1 +
 daemon/gdm-slave.c                 |  185 ++++++++
 daemon/gdm-slave.h                 |    7 +-
 daemon/gdm-welcome-session.c       |   65 +++-
 daemon/gdm-xdmcp-chooser-display.c |    2 +-
 daemon/main.c                      |   12 +
 daemon/simple-slave-main.c         |   13 +
 data/Init.in                       |    2 +-
 data/Makefile.am                   |   11 -
 data/PostSession.in                |    1 +
 data/PreSession.in                 |    2 +-
 data/gdm.schemas.in.in             |    6 -
 docs/C/gdm.xml                     |   12 -
 34 files changed, 2425 insertions(+), 281 deletions(-)
---
diff --git a/common/gdm-marshal.list b/common/gdm-marshal.list
index d5455e1..d6578fd 100644
--- a/common/gdm-marshal.list
+++ b/common/gdm-marshal.list
@@ -5,3 +5,4 @@ VOID:STRING,STRING
 VOID:UINT,UINT
 VOID:STRING,INT
 VOID:DOUBLE
+VOID:STRING,STRING,STRING,POINTER,STRING,POINTER
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index 65a1628..293ecb8 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -39,8 +39,6 @@ G_BEGIN_DECLS
 #define GDM_KEY_EXCLUDE "greeter/Exclude"
 #define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
 
-#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
-
 #define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
 #define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
 #define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
diff --git a/configure.ac b/configure.ac
index c25fdd7..3bb3866 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1095,105 +1095,6 @@ AC_CHECK_LIB(devinfo, di_devperm_login, [
                             PAM_LIBS="$PAM_LIBS -ldevinfo" ])
 
 dnl ---------------------------------------------------------------------------
-dnl - Check for X Server location
-dnl ---------------------------------------------------------------------------
-
-# First check with "! -h" for /usr/X11R6 and /usr/X11 since they often
-# symlink to each other, and configure should use the more stable
-# location (the real directory) if possible.
-#
-# On Solaris, the /usr/bin/Xserver script is used to decide whether to
-# use Xsun or Xorg, so this is used on Solaris.
-#
-# When testing for /usr/X11R6, first check with "! -h" for /usr/X11R6
-# and /usr/X11 since they often symlink to each other, and configure
-# should use the more stable location (the real directory) if possible.
-#
-if test -x /usr/X11/bin/Xserver; then
-   X_PATH="/usr/X11/bin"
-   X_SERVER_PATH="/usr/X11/bin"
-   X_SERVER="/usr/X11/bin/Xserver"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test ! -h /usr/X11R6 -a -x /usr/X11R6/bin/X; then
-   X_PATH="/usr/X11R6/bin"
-   X_SERVER_PATH="/usr/X11R6/bin"
-   X_SERVER="/usr/X11R6/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test ! -h /usr/X11 -a -x /usr/X11/bin/X; then
-   X_PATH="/usr/X11/bin"
-   X_SERVER_PATH="/usr/X11/bin"
-   X_SERVER="/usr/X11/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test -x /usr/X11R6/bin/X; then
-   X_PATH="/usr/X11R6/bin"
-   X_SERVER_PATH="/usr/X11R6/bin"
-   X_SERVER="/usr/X11R6/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test -x /usr/bin/Xorg; then
-   X_PATH="/usr/bin"
-   X_SERVER_PATH="/usr/bin"
-   X_SERVER="/usr/bin/Xorg"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test -x /usr/X11/bin/X; then
-   X_PATH="/usr/X11/bin"
-   X_SERVER_PATH="/usr/X11/bin"
-   X_SERVER="/usr/X11/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test -x /usr/openwin/bin/Xsun; then
-   # Do not add /usr/openwin/bin here because on Solaris you need
-   # /usr/openwin/bin in your PATH even if you are using the Xorg
-   # Xserver.  We add this to the path below.
-   X_PATH="/usr/openwin/bin"
-   X_SERVER_PATH="/usr/openwin/bin"
-   X_SERVER="/usr/openwin/bin/Xsun"
-   X_CONFIG_OPTIONS="-audit 0 -nobanner"
-elif test -x /opt/X11R6/bin/X; then
-   X_PATH="/opt/X11R6/bin"
-   X_SERVER_PATH="/opt/X11R6/bin"
-   X_SERVER="/opt/X11R6/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-elif test -x /usr/bin/X; then
-   X_PATH="/usr/bin"
-   X_SERVER_PATH="/usr/bin"
-   X_SERVER="/usr/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-else
-   # what to do, what to do, this is wrong, but this just sets the
-   # defaults, perhaps this user is cross compiling or some such
-   X_PATH="/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin"
-   X_SERVER_PATH="/usr/X11R6/bin"
-   X_SERVER="/usr/X11R6/bin/X"
-   X_CONFIG_OPTIONS="-audit 0"
-fi
-
-dnl ---------------------------------------------------------------------------
-dnl - Check for Xnest / Xephyr support
-dnl ---------------------------------------------------------------------------
-
-# Use Xephyr if it is available.  It works better than Xnest since Xephyr
-# supports the Xserver extensions, even if on a remote machine.
-#
-X_XNEST_UNSCALED_FONTPATH="true"
-if test -x $X_SERVER_PATH/Xephyr; then
-    X_XNEST_CMD="$X_SERVER_PATH/Xephyr"
-    X_XNEST_CONFIG_OPTIONS="-audit 0"
-else
-    if test -x /usr/openwin/bin/Xnest; then
-        # If on Solaris, Xnest is only shipped with the Xsun Xserver, so
-        # use this version.
-        #
-        X_XNEST_CMD="/usr/openwin/bin/Xnest"
-        X_XNEST_CONFIG_OPTIONS="-audit 0 -name Xnest -pn"
-        X_XNEST_UNSCALED_FONTPATH="false"
-    else
-        if test -x $X_SERVER_PATH/Xnest; then
-            X_XNEST_CMD="$X_SERVER_PATH/Xnest"
-            X_XNEST_CONFIG_OPTIONS="-audit 0 -name Xnest"
-        fi
-    fi
-fi
-
-dnl ---------------------------------------------------------------------------
 dnl - Expand vars
 dnl ---------------------------------------------------------------------------
 
@@ -1357,6 +1258,21 @@ else
    XSESSION_SHELL=/bin/sh
 fi
 
+dnl ---------------------------------------------------------------------------
+dnl - PATH in scripts
+dnl ---------------------------------------------------------------------------
+AC_ARG_WITH(script-path,
+            AS_HELP_STRING([--with-script-path=<dir>],
+                           [script path]))
+
+if ! test -z "$with_script_path"; then
+   SCRIPT_PATH=$with_script_path
+else
+   SCRIPT_PATH=/usr/bin
+fi
+
+AC_SUBST(SCRIPT_PATH)
+
 # Set configuration choices.
 #
 AC_SUBST(XSESSION_SHELL)
@@ -1364,21 +1280,6 @@ AC_DEFINE_UNQUOTED(XSESSION_SHELL,"$XSESSION_SHELL",[xsession shell])
 AC_SUBST(SOUND_PROGRAM)
 AC_DEFINE_UNQUOTED(SOUND_PROGRAM,"$SOUND_PROGRAM",[])
 
-AC_SUBST(X_PATH)
-AC_SUBST(X_SERVER)
-AC_SUBST(X_SERVER_PATH)
-AC_SUBST(X_CONFIG_OPTIONS)
-AC_DEFINE_UNQUOTED(X_SERVER,"$X_SERVER",[])
-AC_DEFINE_UNQUOTED(X_SERVER_PATH,"$X_SERVER_PATH",[])
-AC_DEFINE_UNQUOTED(X_CONFIG_OPTIONS,"$X_CONFIG_OPTIONS", [Options used when launching xserver])
-
-AC_SUBST(X_XNEST_CMD)
-AC_SUBST(X_XNEST_CONFIG_OPTIONS)
-AC_SUBST(X_XNEST_UNSCALED_FONTPATH)
-AC_DEFINE_UNQUOTED(X_XNEST_CMD,"$X_XNEST_CMD",[])
-AC_DEFINE_UNQUOTED(X_XNEST_CONFIG_OPTIONS,"$X_XNEST_CONFIG_OPTIONS",[])
-AC_DEFINE_UNQUOTED(X_XNEST_UNSCALED_FONTPATH,"$X_XNEST_UNSCALED_FONTPATH",[])
-
 ## Stuff for debian/changelog.in
 #if test -e "debian/changelog"; then
 #  DEBIAN_DATESTAMP=`head -1 debian/changelog| sed -e 's/.*cvs.//' -e 's/).*//'`
@@ -1403,6 +1304,9 @@ gui/user-switch-applet/Makefile
 utils/Makefile
 data/gdm.conf
 data/Makefile
+data/Init
+data/PostSession
+data/PreSession
 data/faces/Makefile
 data/greeter-autostart/Makefile
 data/greeter-autostart/at-spi-registryd-wrapper.desktop.in
@@ -1446,7 +1350,7 @@ echo "
 
         dbus-1 system.d dir:      ${DBUS_SYS_DIR}
         PAM prefix:               ${PAM_PREFIX}
-        X server:                 ${X_SERVER}
+        script path:              ${SCRIPT_PATH}
 "
 
 dnl TCP Wrappers support?
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 731a041..acd2b10 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -299,6 +299,8 @@ gdm_binary_SOURCES = 			\
 	gdm-static-display.h		\
 	gdm-transient-display.c		\
 	gdm-transient-display.h		\
+	gdm-dynamic-display.c		\
+	gdm-dynamic-display.h		\
 	gdm-static-factory-display.c	\
 	gdm-static-factory-display.h	\
 	gdm-product-display.c		\
diff --git a/daemon/ck-connector.c b/daemon/ck-connector.c
index 0117eb9..8609ccb 100644
--- a/daemon/ck-connector.c
+++ b/daemon/ck-connector.c
@@ -65,6 +65,7 @@ struct _CkConnector
 {
         int             refcount;
         char           *cookie;
+        char           *session_id;
         dbus_bool_t     session_created;
         DBusConnection *connection;
 };
@@ -76,8 +77,11 @@ static struct {
         { "display-device",     DBUS_TYPE_STRING },
         { "x11-display-device", DBUS_TYPE_STRING },
         { "x11-display",        DBUS_TYPE_STRING },
+        { "seat-id",            DBUS_TYPE_STRING },
+        { "session",            DBUS_TYPE_STRING },
         { "remote-host-name",   DBUS_TYPE_STRING },
         { "session-type",       DBUS_TYPE_STRING },
+        { "display-type",       DBUS_TYPE_STRING },
         { "is-local",           DBUS_TYPE_BOOLEAN },
         { "unix-user",          DBUS_TYPE_INT32 },
 };
@@ -181,6 +185,10 @@ _ck_connector_free (CkConnector *connector)
                 free (connector->cookie);
         }
 
+        if (connector->session_id != NULL) {
+                free (connector->session_id);
+        }
+
         free (connector);
 }
 
@@ -241,6 +249,7 @@ ck_connector_new (void)
         connector->refcount = 1;
         connector->connection = NULL;
         connector->cookie = NULL;
+        connector->session_id = NULL;
         connector->session_created = FALSE;
 oom:
         return connector;
@@ -266,6 +275,7 @@ ck_connector_open_session (CkConnector *connector,
         DBusMessage *reply;
         dbus_bool_t  ret;
         char        *cookie;
+        char        *session_id;
 
         _ck_return_val_if_fail (connector != NULL, FALSE);
         _ck_return_val_if_fail ((error) == NULL || !dbus_error_is_set ((error)), FALSE);
@@ -334,10 +344,68 @@ ck_connector_open_session (CkConnector *connector,
                 goto out;
         }
 
+        dbus_message_unref (message);
+        dbus_message_unref (reply);
+
+        message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+                                                "/org/freedesktop/ConsoleKit/Manager",
+                                                "org.freedesktop.ConsoleKit.Manager",
+                                                "GetSessionForCookie");
+        if (message == NULL) {
+                goto out;
+        }
+
+        dbus_message_append_args (message, DBUS_TYPE_STRING, &connector->cookie,
+                                  DBUS_TYPE_INVALID);
+
+        dbus_error_init (&local_error);
+
+        reply = dbus_connection_send_with_reply_and_block (connector->connection,
+                                                           message,
+                                                           -1,
+                                                           &local_error);
+        if (reply == NULL) {
+                if (dbus_error_is_set (&local_error)) {
+                        dbus_set_error (error,
+                                        CK_CONNECTOR_ERROR,
+                                        "Unable to open session: %s",
+                                        local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        dbus_error_init (&local_error);
+        if (! dbus_message_get_args (reply,
+                                     &local_error,
+                                     DBUS_TYPE_OBJECT_PATH, &session_id,
+                                     DBUS_TYPE_INVALID)) {
+                if (dbus_error_is_set (&local_error)) {
+                        dbus_set_error (error,
+                                        CK_CONNECTOR_ERROR,
+                                        "Unable to open session: %s",
+                                        local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        connector->session_id = strdup (session_id);
+        if (connector->session_id == NULL) {
+                goto out;
+        }
+
         connector->session_created = TRUE;
         ret = TRUE;
 
 out:
+        if (!ret) {
+                free (connector->cookie);
+                connector->cookie = NULL;
+                free (connector->session_id);
+                connector->session_id = NULL;
+        }
+
         if (reply != NULL) {
                 dbus_message_unref (reply);
         }
@@ -362,6 +430,7 @@ ck_connector_open_session_with_parameters_valist (CkConnector *connector,
         DBusMessageIter iter_array;
         dbus_bool_t     ret;
         char           *cookie;
+        char           *session_id;
         const char     *name;
 
         _ck_return_val_if_fail (connector != NULL, FALSE);
@@ -470,6 +539,57 @@ ck_connector_open_session_with_parameters_valist (CkConnector *connector,
                 goto out;
         }
 
+        dbus_message_unref (message);
+        dbus_message_unref (reply);
+
+        message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+                                                "/org/freedesktop/ConsoleKit/Manager",
+                                                "org.freedesktop.ConsoleKit.Manager",
+                                                "GetSessionForCookie");
+        if (message == NULL) {
+                goto out;
+        }
+
+        dbus_message_append_args (message, DBUS_TYPE_STRING, &connector->cookie,
+                                  DBUS_TYPE_INVALID);
+
+        dbus_error_init (&local_error);
+
+        reply = dbus_connection_send_with_reply_and_block (connector->connection,
+                                                           message,
+                                                           -1,
+                                                           &local_error);
+        if (reply == NULL) {
+                if (dbus_error_is_set (&local_error)) {
+                        dbus_set_error (error,
+                                        CK_CONNECTOR_ERROR,
+                                        "Unable to open session: %s",
+                                        local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        dbus_error_init (&local_error);
+        if (! dbus_message_get_args (reply,
+                                     &local_error,
+                                     DBUS_TYPE_OBJECT_PATH, &session_id,
+                                     DBUS_TYPE_INVALID)) {
+                if (dbus_error_is_set (&local_error)) {
+                        dbus_set_error (error,
+                                        CK_CONNECTOR_ERROR,
+                                        "Unable to open session: %s",
+                                        local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        connector->session_id = strdup (session_id);
+        if (connector->session_id == NULL) {
+                goto out;
+        }
+
         connector->session_created = TRUE;
         ret = TRUE;
 
@@ -590,6 +710,73 @@ ck_connector_get_cookie (CkConnector *connector)
 }
 
 /**
+ * Gets the id for the current open session.
+ * Returns #NULL if no session is open.
+ *
+ * @returns a constant string with the session id.
+ */
+const char *
+ck_connector_get_session_id (CkConnector *connector)
+{
+        _ck_return_val_if_fail (connector != NULL, NULL);
+
+        if (! connector->session_created) {
+                return NULL;
+        } else {
+                return connector->session_id;
+        }
+}
+
+dbus_bool_t
+ck_connector_set_remove_on_close (CkConnector *connector,
+                                  gboolean     remove_on_close,
+                                  DBusError   *error)
+{
+        DBusMessage *message;
+        dbus_bool_t  ret;
+        const char  *ssid = ck_connector_get_session_id (connector);
+
+        _ck_return_val_if_fail (connector != NULL, FALSE);
+        _ck_return_val_if_fail ((error) == NULL || !dbus_error_is_set ((error)), FALSE);
+        _ck_return_val_if_fail (ssid != NULL, FALSE);
+
+        message = NULL;
+        ret = FALSE;
+
+        if (!connector->session_created || connector->cookie == NULL) {
+                dbus_set_error (error,
+                                CK_CONNECTOR_ERROR,
+                                "Unable to close session: %s",
+                                "no session open");
+                goto out;
+        }
+
+        message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+                                                ssid,
+                                                "org.freedesktop.ConsoleKit.Session",
+                                                "SetRemoveOnClose");
+        if (message == NULL) {
+                goto out;
+        }
+
+        if (! dbus_message_append_args (message,
+                                        DBUS_TYPE_BOOLEAN, &remove_on_close,
+                                        DBUS_TYPE_INVALID)) {
+                goto out;
+        }
+
+        ret = dbus_connection_send (connector->connection,
+                                      message,
+                                      NULL);
+out:
+        if (message != NULL) {
+                dbus_message_unref (message);
+        }
+
+        return ret;
+}
+
+/**
  * Issues the CloseSession method call on the ConsoleKit manager
  * interface.
  *
diff --git a/daemon/ck-connector.h b/daemon/ck-connector.h
index ab59f55..e0a35d8 100644
--- a/daemon/ck-connector.h
+++ b/daemon/ck-connector.h
@@ -32,6 +32,7 @@
 
 #include <sys/types.h>
 #include <dbus/dbus.h>
+#include <glib.h>
 
 DBUS_BEGIN_DECLS
 
@@ -56,6 +57,10 @@ dbus_bool_t   ck_connector_open_session                 (CkConnector *ckc,
                                                          DBusError   *error);
 
 const char   *ck_connector_get_cookie                   (CkConnector *ckc);
+const char   *ck_connector_get_session_id               (CkConnector *ckc);
+dbus_bool_t   ck_connector_set_remove_on_close          (CkConnector *ckc,
+                                                         gboolean     remove_on_close,
+                                                         DBusError   *error);
 dbus_bool_t   ck_connector_close_session                (CkConnector *ckc,
                                                          DBusError   *error);
 
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index abedc0b..047d23e 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -41,6 +41,7 @@
 #include "gdm-settings-keys.h"
 
 #include "gdm-slave-proxy.h"
+#include "gdm-dynamic-display.h"
 
 static guint32 display_serial = 1;
 
@@ -51,11 +52,14 @@ static guint32 display_serial = 1;
 struct GdmDisplayPrivate
 {
         char                 *id;
+        char                 *session_id;
         char                 *seat_id;
 
         char                 *remote_hostname;
+        char                 *x11_command;
         int                   x11_display_number;
         char                 *x11_display_name;
+        char                 *x11_display_type;
         int                   status;
         time_t                creation_time;
         GTimer               *slave_timer;
@@ -66,6 +70,8 @@ struct GdmDisplayPrivate
         GdmDisplayAccessFile *access_file;
 
         gboolean              is_local;
+        gboolean              use_auth;
+        gboolean              block_console_session_requests;
         guint                 finish_idle_id;
 
         GdmSlaveProxy        *slave_proxy;
@@ -78,13 +84,18 @@ enum {
         PROP_ID,
         PROP_STATUS,
         PROP_SEAT_ID,
+        PROP_SESSION_ID,
+        PROP_X11_COMMAND,
         PROP_REMOTE_HOSTNAME,
         PROP_X11_DISPLAY_NUMBER,
         PROP_X11_DISPLAY_NAME,
+        PROP_X11_DISPLAY_TYPE,
         PROP_X11_COOKIE,
         PROP_X11_AUTHORITY_FILE,
         PROP_IS_LOCAL,
+        PROP_USE_AUTH,
         PROP_SLAVE_COMMAND,
+        PROP_BLOCK_CONSOLE_SESSION_REQUESTS,
 };
 
 static void     gdm_display_class_init  (GdmDisplayClass *klass);
@@ -489,6 +500,20 @@ gdm_display_get_seat_id (GdmDisplay *display,
        return TRUE;
 }
 
+gboolean
+gdm_display_get_session_id (GdmDisplay *display,
+                            char      **session_id,
+                            GError    **error)
+{
+       g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+       if (session_id != NULL) {
+               *session_id = g_strdup (display->priv->session_id);
+       }
+
+       return TRUE;
+}
+
 static gboolean
 finish_idle (GdmDisplay *display)
 {
@@ -513,6 +538,14 @@ slave_exited (GdmSlaveProxy       *proxy,
 {
         g_debug ("GdmDisplay: Slave exited: %d", code);
 
+        if (GDM_IS_DYNAMIC_DISPLAY (display)) {
+                if (code != 0) {
+                        gdm_dynamic_display_respawn (GDM_DYNAMIC_DISPLAY (display), TRUE);
+                } else {
+                        gdm_dynamic_display_respawn (GDM_DYNAMIC_DISPLAY (display), FALSE);
+                }
+        }
+
         queue_finish (display);
 }
 
@@ -550,10 +583,12 @@ gdm_display_real_prepare (GdmDisplay *display)
 
         g_assert (display->priv->slave_proxy == NULL);
 
-        if (!gdm_display_create_authority (display)) {
-                g_warning ("Unable to set up access control for display %d",
-                           display->priv->x11_display_number);
-                return FALSE;
+        if (display->priv->use_auth) {
+                if (!gdm_display_create_authority (display)) {
+                        g_warning ("Unable to set up access control for display %d",
+                                   display->priv->x11_display_number);
+                        return FALSE;
+                }
         }
 
         _gdm_display_set_status (display, GDM_DISPLAY_PREPARED);
@@ -742,6 +777,20 @@ gdm_display_get_id (GdmDisplay         *display,
 }
 
 gboolean
+gdm_display_get_x11_command (GdmDisplay *display,
+                             char      **command,
+                             GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (command != NULL) {
+                *command = g_strdup (display->priv->x11_command);
+        }
+
+        return TRUE;
+}
+
+gboolean
 gdm_display_get_x11_display_name (GdmDisplay   *display,
                                   char        **x11_display,
                                   GError      **error)
@@ -756,6 +805,20 @@ gdm_display_get_x11_display_name (GdmDisplay   *display,
 }
 
 gboolean
+gdm_display_get_x11_display_type (GdmDisplay   *display,
+                                  char        **type,
+                                  GError      **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (type != NULL) {
+                *type = g_strdup (display->priv->x11_display_type);
+        }
+
+        return TRUE;
+}
+
+gboolean
 gdm_display_is_local (GdmDisplay *display,
                       gboolean   *local,
                       GError    **error)
@@ -769,6 +832,20 @@ gdm_display_is_local (GdmDisplay *display,
         return TRUE;
 }
 
+gboolean
+gdm_display_use_auth (GdmDisplay *display,
+                      gboolean   *use_auth,
+                      GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (use_auth != NULL) {
+                *use_auth = display->priv->use_auth;
+        }
+
+        return TRUE;
+}
+
 static void
 _gdm_display_set_id (GdmDisplay     *display,
                      const char     *id)
@@ -778,6 +855,14 @@ _gdm_display_set_id (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_x11_command (GdmDisplay     *display,
+                              const char     *x11_command)
+{
+        g_free (display->priv->x11_command);
+        display->priv->x11_command = g_strdup (x11_command);
+}
+
+static void
 _gdm_display_set_seat_id (GdmDisplay     *display,
                           const char     *seat_id)
 {
@@ -786,6 +871,24 @@ _gdm_display_set_seat_id (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_session_id (GdmDisplay     *display,
+                             const char     *session_id)
+{
+        g_free (display->priv->session_id);
+        display->priv->session_id = g_strdup (session_id);
+}
+
+gboolean
+gdm_display_set_session_id (GdmDisplay *display,
+                            const char *session_id,
+                            GError    **error)
+{
+        _gdm_display_set_session_id (display, session_id);
+        g_object_notify (G_OBJECT (display), "session-id");
+        return TRUE;
+}
+
+static void
 _gdm_display_set_remote_hostname (GdmDisplay     *display,
                                   const char     *hostname)
 {
@@ -809,6 +912,14 @@ _gdm_display_set_x11_display_name (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_x11_display_type (GdmDisplay     *display,
+                                   const char     *display_type)
+{
+        g_free (display->priv->x11_display_type);
+        display->priv->x11_display_type = g_strdup (display_type);
+}
+
+static void
 _gdm_display_set_x11_cookie (GdmDisplay     *display,
                              const char     *x11_cookie)
 {
@@ -824,6 +935,13 @@ _gdm_display_set_is_local (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_use_auth (GdmDisplay     *display,
+                           gboolean        use_auth)
+{
+        display->priv->use_auth = use_auth;
+}
+
+static void
 _gdm_display_set_slave_command (GdmDisplay     *display,
                                 const char     *command)
 {
@@ -832,6 +950,13 @@ _gdm_display_set_slave_command (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_block_console_session_requests (GdmDisplay     *display,
+                                                 gboolean        block_console_session_requests)
+{
+        display->priv->block_console_session_requests = block_console_session_requests;
+}
+
+static void
 gdm_display_set_property (GObject        *object,
                           guint           prop_id,
                           const GValue   *value,
@@ -845,12 +970,18 @@ gdm_display_set_property (GObject        *object,
         case PROP_ID:
                 _gdm_display_set_id (self, g_value_get_string (value));
                 break;
+        case PROP_X11_COMMAND:
+                _gdm_display_set_x11_command (self, g_value_get_string (value));
+                break;
         case PROP_STATUS:
                 _gdm_display_set_status (self, g_value_get_int (value));
                 break;
         case PROP_SEAT_ID:
                 _gdm_display_set_seat_id (self, g_value_get_string (value));
                 break;
+        case PROP_SESSION_ID:
+                _gdm_display_set_session_id (self, g_value_get_string (value));
+                break;
         case PROP_REMOTE_HOSTNAME:
                 _gdm_display_set_remote_hostname (self, g_value_get_string (value));
                 break;
@@ -860,15 +991,24 @@ gdm_display_set_property (GObject        *object,
         case PROP_X11_DISPLAY_NAME:
                 _gdm_display_set_x11_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_X11_DISPLAY_TYPE:
+                _gdm_display_set_x11_display_type (self, g_value_get_string (value));
+                break;
         case PROP_X11_COOKIE:
                 _gdm_display_set_x11_cookie (self, g_value_get_string (value));
                 break;
         case PROP_IS_LOCAL:
                 _gdm_display_set_is_local (self, g_value_get_boolean (value));
                 break;
+        case PROP_USE_AUTH:
+                _gdm_display_set_use_auth (self, g_value_get_boolean (value));
+                break;
         case PROP_SLAVE_COMMAND:
                 _gdm_display_set_slave_command (self, g_value_get_string (value));
                 break;
+        case PROP_BLOCK_CONSOLE_SESSION_REQUESTS:
+                _gdm_display_set_block_console_session_requests (self, g_value_get_boolean (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -889,12 +1029,18 @@ gdm_display_get_property (GObject        *object,
         case PROP_ID:
                 g_value_set_string (value, self->priv->id);
                 break;
+        case PROP_X11_COMMAND:
+                g_value_set_string (value, self->priv->x11_command);
+                break;
         case PROP_STATUS:
                 g_value_set_int (value, self->priv->status);
                 break;
         case PROP_SEAT_ID:
                 g_value_set_string (value, self->priv->seat_id);
                 break;
+        case PROP_SESSION_ID:
+                g_value_set_string (value, self->priv->session_id);
+                break;
         case PROP_REMOTE_HOSTNAME:
                 g_value_set_string (value, self->priv->remote_hostname);
                 break;
@@ -904,6 +1050,9 @@ gdm_display_get_property (GObject        *object,
         case PROP_X11_DISPLAY_NAME:
                 g_value_set_string (value, self->priv->x11_display_name);
                 break;
+        case PROP_X11_DISPLAY_TYPE:
+                g_value_set_string (value, self->priv->x11_display_type);
+                break;
         case PROP_X11_COOKIE:
                 g_value_set_string (value, self->priv->x11_cookie);
                 break;
@@ -914,9 +1063,15 @@ gdm_display_get_property (GObject        *object,
         case PROP_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->is_local);
                 break;
+        case PROP_USE_AUTH:
+                g_value_set_boolean (value, self->priv->use_auth);
+                break;
         case PROP_SLAVE_COMMAND:
                 g_value_set_string (value, self->priv->slave_command);
                 break;
+        case PROP_BLOCK_CONSOLE_SESSION_REQUESTS:
+                g_value_set_boolean (value, self->priv->block_console_session_requests);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -1033,6 +1188,13 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_COMMAND,
+                                         g_param_spec_string ("x11-command",
+                                                              "x11 command",
+                                                              "x11 command",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
                                          PROP_REMOTE_HOSTNAME,
                                          g_param_spec_string ("remote-hostname",
                                                               "remote-hostname",
@@ -1056,6 +1218,13 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_TYPE,
+                                         g_param_spec_string ("x11-display-type",
+                                                              "x11-display-type",
+                                                              "x11-display-type",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
                                          PROP_SEAT_ID,
                                          g_param_spec_string ("seat-id",
                                                               "seat id",
@@ -1063,6 +1232,13 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
+                                         PROP_SESSION_ID,
+                                         g_param_spec_string ("session-id",
+                                                              "session id",
+                                                              "session id",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
                                          PROP_X11_COOKIE,
                                          g_param_spec_string ("x11-cookie",
                                                               "cookie",
@@ -1076,7 +1252,6 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               "authority file",
                                                               NULL,
                                                               G_PARAM_READABLE));
-
         g_object_class_install_property (object_class,
                                          PROP_IS_LOCAL,
                                          g_param_spec_boolean ("is-local",
@@ -1084,7 +1259,13 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                                NULL,
                                                                TRUE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
+        g_object_class_install_property (object_class,
+                                         PROP_USE_AUTH,
+                                         g_param_spec_boolean ("use-auth",
+                                                               NULL,
+                                                               NULL,
+                                                               TRUE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
                                          PROP_SLAVE_COMMAND,
                                          g_param_spec_string ("slave-command",
@@ -1093,6 +1274,13 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               DEFAULT_SLAVE_COMMAND,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
+                                         PROP_BLOCK_CONSOLE_SESSION_REQUESTS,
+                                         g_param_spec_boolean ("block-console-session-requests",
+                                                              "Block Console Session Requests",
+                                                              "Block session requests from ConsoleKit",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE));
+        g_object_class_install_property (object_class,
                                          PROP_STATUS,
                                          g_param_spec_int ("status",
                                                            "status",
@@ -1131,9 +1319,12 @@ gdm_display_finalize (GObject *object)
 
         g_debug ("GdmDisplay: Finalizing display: %s", display->priv->id);
         g_free (display->priv->id);
+        g_free (display->priv->x11_command);
         g_free (display->priv->seat_id);
+        g_free (display->priv->session_id);
         g_free (display->priv->remote_hostname);
         g_free (display->priv->x11_display_name);
+        g_free (display->priv->x11_display_type);
         g_free (display->priv->x11_cookie);
         g_free (display->priv->slave_command);
 
@@ -1151,3 +1342,25 @@ gdm_display_finalize (GObject *object)
 
         G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
 }
+
+gboolean
+gdm_display_block_console_session_requests (GdmDisplay *display,
+                                            GError    **error)
+{
+        if (!display->priv->block_console_session_requests) {
+                _gdm_display_set_block_console_session_requests (display, TRUE);
+                g_object_notify (G_OBJECT (display), "block-console-session-requests");
+        }
+        return TRUE;
+}
+
+gboolean
+gdm_display_unblock_console_session_requests (GdmDisplay *display,
+                                              GError    **error)
+{
+        if (display->priv->block_console_session_requests) {
+                _gdm_display_set_block_console_session_requests (display, FALSE);
+                g_object_notify (G_OBJECT (display), "block-console-session-requests");
+        }
+        return TRUE;
+}
diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h
index 607ea1d..b50549b 100644
--- a/daemon/gdm-display.h
+++ b/daemon/gdm-display.h
@@ -102,6 +102,9 @@ gboolean            gdm_display_unmanage                       (GdmDisplay *disp
 gboolean            gdm_display_get_id                         (GdmDisplay *display,
                                                                 char      **id,
                                                                 GError    **error);
+gboolean            gdm_display_get_x11_command                (GdmDisplay *display,
+                                                                char      **command,
+                                                                GError    **error);
 gboolean            gdm_display_get_remote_hostname            (GdmDisplay *display,
                                                                 char      **hostname,
                                                                 GError    **error);
@@ -111,12 +114,21 @@ gboolean            gdm_display_get_x11_display_number         (GdmDisplay *disp
 gboolean            gdm_display_get_x11_display_name           (GdmDisplay *display,
                                                                 char      **x11_display,
                                                                 GError    **error);
+gboolean            gdm_display_get_x11_display_type           (GdmDisplay *display,
+                                                                char      **type,
+                                                                GError    **error);
 gboolean            gdm_display_get_seat_id                    (GdmDisplay *display,
                                                                 char      **seat_id,
                                                                 GError    **error);
+gboolean            gdm_display_get_session_id                 (GdmDisplay *display,
+                                                                char      **session_id,
+                                                                GError    **error);
 gboolean            gdm_display_is_local                       (GdmDisplay *display,
                                                                 gboolean   *local,
                                                                 GError    **error);
+gboolean            gdm_display_use_auth                       (GdmDisplay *display,
+                                                                gboolean   *use_auth,
+                                                                GError    **error);
 gboolean            gdm_display_get_timed_login_details        (GdmDisplay *display,
                                                                 gboolean   *enabled,
                                                                 char      **username,
@@ -130,6 +142,9 @@ gboolean            gdm_display_get_x11_cookie                 (GdmDisplay *disp
 gboolean            gdm_display_get_x11_authority_file         (GdmDisplay *display,
                                                                 char      **filename,
                                                                 GError    **error);
+gboolean            gdm_display_set_session_id                 (GdmDisplay *display,
+                                                                const char *text,
+                                                                GError    **error);
 gboolean            gdm_display_add_user_authorization         (GdmDisplay *display,
                                                                 const char *username,
                                                                 char      **filename,
@@ -140,6 +155,11 @@ gboolean            gdm_display_remove_user_authorization      (GdmDisplay *disp
 gboolean            gdm_display_set_slave_bus_name             (GdmDisplay *display,
                                                                 const char *name,
                                                                 GError    **error);
+gboolean            gdm_display_block_console_session_requests (GdmDisplay *display,
+                                                                GError    **error);
+
+gboolean            gdm_display_unblock_console_session_requests (GdmDisplay *display,
+                                                                  GError    **error);
 
 
 G_END_DECLS
diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml
index a92e37f..c4d0b35 100644
--- a/daemon/gdm-display.xml
+++ b/daemon/gdm-display.xml
@@ -4,11 +4,17 @@
     <method name="GetId">
       <arg name="id" direction="out" type="o"/>
     </method>
+    <method name="GetX11Command">
+      <arg name="command" direction="out" type="s"/>
+    </method>
     <method name="GetX11DisplayName">
       <arg name="name" direction="out" type="s"/>
     </method>
+    <method name="GetX11DisplayType">
+      <arg name="type" direction="out" type="s"/>
+    </method>
     <method name="GetX11DisplayNumber">
-      <arg name="name" direction="out" type="i"/>
+      <arg name="number" direction="out" type="i"/>
     </method>
     <method name="GetX11Cookie">
       <arg name="x11_cookie" direction="out" type="ay"/>
@@ -17,7 +23,14 @@
       <arg name="filename" direction="out" type="s"/>
     </method>
     <method name="GetSeatId">
-      <arg name="filename" direction="out" type="s"/>
+      <arg name="seat_id" direction="out" type="s"/>
+    </method>
+    <method name="GetSessionId">
+      <arg name="session_id" direction="out" type="s"/>
+    </method>
+    <method name="BlockConsoleSessionRequests">
+    </method>
+    <method name="UnblockConsoleSessionRequests">
     </method>
     <method name="GetRemoteHostname">
       <arg name="hostname" direction="out" type="s"/>
@@ -25,6 +38,9 @@
     <method name="IsLocal">
       <arg name="local" direction="out" type="b"/>
     </method>
+    <method name="UseAuth">
+      <arg name="use_auth" direction="out" type="b"/>
+    </method>
     <method name="AddUserAuthorization">
       <arg name="username" direction="in" type="s"/>
       <arg name="filename" direction="out" type="s"/>
@@ -32,6 +48,9 @@
     <method name="RemoveUserAuthorization">
       <arg name="username" direction="in" type="s"/>
     </method>
+    <method name="SetSessionId">
+      <arg name="session_id" direction="in" type="s"/>
+    </method>
     <method name="SetSlaveBusName">
       <arg name="name" direction="in" type="s"/>
     </method>
diff --git a/daemon/gdm-dynamic-display.c b/daemon/gdm-dynamic-display.c
new file mode 100644
index 0000000..6483150
--- /dev/null
+++ b/daemon/gdm-dynamic-display.c
@@ -0,0 +1,246 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Authors: halton huo sun com
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include "gdm-common.h"
+#include "gdm-display.h"
+#include "gdm-dynamic-display.h"
+
+#define GDM_DYNAMIC_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayPrivate))
+
+struct _GdmDynamicDisplayPrivate
+{
+        gboolean removed;
+        gboolean do_respawn;
+};
+
+enum {
+        PROP_0,
+};
+
+static void     gdm_dynamic_display_class_init   (GdmDynamicDisplayClass *klass);
+static void     gdm_dynamic_display_init         (GdmDynamicDisplay      *display);
+static void     gdm_dynamic_display_finalize     (GObject                  *object);
+
+G_DEFINE_TYPE (GdmDynamicDisplay, gdm_dynamic_display, GDM_TYPE_DISPLAY)
+
+void
+gdm_dynamic_display_respawn (GdmDynamicDisplay *display, gboolean respawn)
+{
+        display->priv->do_respawn = respawn;
+        if (display->priv->do_respawn == TRUE)
+                g_debug ("GdmDynamicDisplay: Set respawn to TRUE.");
+        else
+                g_debug ("GdmDynamicDisplay: Set respawn to FALSE.");
+}
+
+void
+gdm_dynamic_display_removed (GdmDynamicDisplay *display)
+{
+        display->priv->removed = TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_create_authority (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->create_authority (display);
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_add_user_authorization (GdmDisplay *display,
+                                            const char *username,
+                                            char      **filename,
+                                            GError    **error)
+{
+        return GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->add_user_authorization (display, username, filename, error);
+}
+
+static gboolean
+gdm_dynamic_display_remove_user_authorization (GdmDisplay *display,
+                                               const char *username,
+                                               GError    **error)
+{
+        return GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->remove_user_authorization (display, username, error);
+}
+
+static gboolean
+gdm_dynamic_display_manage (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        g_debug ("GdmDynamicDisplay: Manage dynamic display");
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->manage (display);
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_finish (GdmDisplay *display)
+{
+        int status;
+
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        g_debug ("GdmDynamicDisplay: Finish dynamic display");
+
+        /* Don't call parent's finish since we don't ever
+        want to be put in the FINISHED state */
+
+        /* restart dynamic displays */
+        gdm_display_unmanage (display);
+
+        status = gdm_display_get_status (display);
+        if (GDM_DYNAMIC_DISPLAY (display)->priv->do_respawn == TRUE &&
+            GDM_DYNAMIC_DISPLAY(display)->priv->removed == FALSE) {
+                if (status != GDM_DISPLAY_FAILED) {
+                        g_debug ("Respawning...");
+                        gdm_display_manage (display);
+                } else {
+                        g_debug ("Display failed, not respawning...");
+                }
+        } else {
+                g_debug ("Not respawning...");
+        }
+        GDM_DYNAMIC_DISPLAY (display)->priv->do_respawn = FALSE;
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_unmanage (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        g_debug ("GdmDynamicDisplay: Unmanage dynamic display");
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->unmanage (display);
+
+        return TRUE;
+}
+
+static void
+gdm_dynamic_display_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dynamic_display_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dynamic_display_class_init (GdmDynamicDisplayClass *klass)
+{
+        GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+        GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass);
+
+        object_class->get_property = gdm_dynamic_display_get_property;
+        object_class->set_property = gdm_dynamic_display_set_property;
+        object_class->finalize = gdm_dynamic_display_finalize;
+
+        display_class->create_authority = gdm_dynamic_display_create_authority;
+        display_class->add_user_authorization = gdm_dynamic_display_add_user_authorization;
+        display_class->remove_user_authorization = gdm_dynamic_display_remove_user_authorization;
+        display_class->manage = gdm_dynamic_display_manage;
+        display_class->finish = gdm_dynamic_display_finish;
+        display_class->unmanage = gdm_dynamic_display_unmanage;
+
+        g_type_class_add_private (klass, sizeof (GdmDynamicDisplayPrivate));
+}
+
+static void
+gdm_dynamic_display_init (GdmDynamicDisplay *display)
+{
+        display->priv = GDM_DYNAMIC_DISPLAY_GET_PRIVATE (display);
+        display->priv->removed = FALSE;
+        display->priv->do_respawn = FALSE;
+}
+
+static void
+gdm_dynamic_display_finalize (GObject *object)
+{
+        GdmDynamicDisplay *display;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GDM_IS_DYNAMIC_DISPLAY (object));
+
+        g_debug ("GdmDynamicDisplay: Finalize dynamic display");
+
+        display = GDM_DYNAMIC_DISPLAY (object);
+
+        g_return_if_fail (display->priv != NULL);
+
+        G_OBJECT_CLASS (gdm_dynamic_display_parent_class)->finalize (object);
+}
+
+GdmDisplay *
+gdm_dynamic_display_new (int display_number)
+{
+        GObject *object;
+        char    *x11_display;
+
+        x11_display = g_strdup_printf (":%d", display_number);
+        object = g_object_new (GDM_TYPE_DYNAMIC_DISPLAY,
+                               "x11-display-number", display_number,
+                               "x11-display-name", x11_display,
+                               NULL);
+        g_free (x11_display);
+
+        return GDM_DISPLAY (object);
+}
diff --git a/daemon/gdm-dynamic-display.h b/daemon/gdm-dynamic-display.h
new file mode 100644
index 0000000..0c53ea9
--- /dev/null
+++ b/daemon/gdm-dynamic-display.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Authors: halton huo sun com
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __GDM_DYNAMIC_DISPLAY_H
+#define __GDM_DYNAMIC_DISPLAY_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include "gdm-display.h"
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DYNAMIC_DISPLAY         (gdm_dynamic_display_get_type ())
+#define GDM_DYNAMIC_DISPLAY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplay))
+#define GDM_DYNAMIC_DISPLAY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayClass))
+#define GDM_IS_DYNAMIC_DISPLAY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DYNAMIC_DISPLAY))
+#define GDM_IS_DYNAMIC_DISPLAY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DYNAMIC_DISPLAY))
+#define GDM_DYNAMIC_DISPLAY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayClass))
+
+typedef struct _GdmDynamicDisplayPrivate GdmDynamicDisplayPrivate;
+
+typedef struct
+{
+        GdmDisplay                parent;
+        GdmDynamicDisplayPrivate *priv;
+} GdmDynamicDisplay;
+
+typedef struct
+{
+        GdmDisplayClass   parent_class;
+
+} GdmDynamicDisplayClass;
+
+GType               gdm_dynamic_display_get_type                (void);
+GdmDisplay *        gdm_dynamic_display_new                     (int display_number);
+void                gdm_dynamic_display_respawn                 (GdmDynamicDisplay *display, gboolean respawn);
+void                gdm_dynamic_display_removed                 (GdmDynamicDisplay *display);
+
+G_END_DECLS
+
+#endif /* __GDM_DYNAMIC_DISPLAY_H */
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
index e0be0ea..da67a87 100644
--- a/daemon/gdm-factory-slave.c
+++ b/daemon/gdm-factory-slave.c
@@ -482,6 +482,8 @@ run_greeter (GdmFactorySlave *slave)
         gboolean       display_is_local;
         char          *display_id;
         char          *display_name;
+        char          *seat_id;
+        char          *session_id;
         char          *display_device;
         char          *display_hostname;
         char          *auth_file;
@@ -492,6 +494,8 @@ run_greeter (GdmFactorySlave *slave)
         display_is_local = FALSE;
         display_id = NULL;
         display_name = NULL;
+        seat_id = NULL;
+        session_id = NULL;
         auth_file = NULL;
         display_device = NULL;
         display_hostname = NULL;
@@ -500,6 +504,8 @@ run_greeter (GdmFactorySlave *slave)
                       "display-is-local", &display_is_local,
                       "display-id", &display_id,
                       "display-name", &display_name,
+                      "display-seat-id", &seat_id,
+                      "display-session-id", &session_id,
                       "display-hostname", &display_hostname,
                       "display-x11-authority-file", &auth_file,
                       NULL);
@@ -556,6 +562,8 @@ run_greeter (GdmFactorySlave *slave)
 
         g_debug ("GdmFactorySlave: Creating greeter on %s %s", display_name, display_device);
         slave->priv->greeter = gdm_greeter_session_new (display_name,
+                                                        seat_id,
+                                                        session_id,
                                                         display_device,
                                                         display_hostname,
                                                         display_is_local);
@@ -585,6 +593,7 @@ run_greeter (GdmFactorySlave *slave)
 
         g_free (display_id);
         g_free (display_name);
+        g_free (seat_id);
         g_free (display_device);
         g_free (display_hostname);
         g_free (auth_file);
@@ -650,14 +659,12 @@ on_server_died (GdmServer       *server,
 static gboolean
 gdm_factory_slave_run (GdmFactorySlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -665,7 +672,7 @@ gdm_factory_slave_run (GdmFactorySlave *slave)
         if (display_is_local) {
                 gboolean res;
 
-                slave->priv->server = gdm_server_new (display_name, auth_file);
+                slave->priv->server = gdm_server_new (display_id);
                 g_signal_connect (slave->priv->server,
                                   "exited",
                                   G_CALLBACK (on_server_exited),
@@ -697,8 +704,7 @@ gdm_factory_slave_run (GdmFactorySlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-greeter-session.c b/daemon/gdm-greeter-session.c
index 994acbc..3dac4f9 100644
--- a/daemon/gdm-greeter-session.c
+++ b/daemon/gdm-greeter-session.c
@@ -140,6 +140,8 @@ gdm_greeter_session_finalize (GObject *object)
 
 GdmGreeterSession *
 gdm_greeter_session_new (const char *display_name,
+                         const char *seat_id,
+                         const char *session_id,
                          const char *display_device,
                          const char *display_hostname,
                          gboolean    display_is_local)
@@ -153,6 +155,8 @@ gdm_greeter_session_new (const char *display_name,
                                "server-env-var-name", "GDM_GREETER_DBUS_ADDRESS",
                                "register-ck-session", TRUE,
                                "x11-display-name", display_name,
+                               "x11-display-seat-id", seat_id,
+                               "x11-display-session-id", session_id,
                                "x11-display-device", display_device,
                                "x11-display-hostname", display_hostname,
                                "x11-display-is-local", display_is_local,
diff --git a/daemon/gdm-greeter-session.h b/daemon/gdm-greeter-session.h
index 0a171c9..c3c3506 100644
--- a/daemon/gdm-greeter-session.h
+++ b/daemon/gdm-greeter-session.h
@@ -50,6 +50,8 @@ typedef struct
 
 GType                 gdm_greeter_session_get_type           (void);
 GdmGreeterSession *   gdm_greeter_session_new                (const char        *display_name,
+                                                              const char        *seat_id,
+                                                              const char        *session_id,
                                                               const char        *display_device,
                                                               const char        *display_hostname,
                                                               gboolean           display_is_local);
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 73ab499..ffe5ab4 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -27,18 +27,30 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
+#include <dbus/dbus-glib-lowlevel.h>
+
 #include "gdm-display-factory.h"
 #include "gdm-local-display-factory.h"
 #include "gdm-local-display-factory-glue.h"
 
+#include "gdm-marshal.h"
 #include "gdm-display-store.h"
 #include "gdm-static-display.h"
+#include "gdm-dynamic-display.h"
 #include "gdm-transient-display.h"
 #include "gdm-static-factory-display.h"
 #include "gdm-product-display.h"
 
 #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
 
+#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"
+
 #define CK_SEAT1_PATH                       "/org/freedesktop/ConsoleKit/Seat1"
 
 #define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
@@ -47,11 +59,17 @@
 
 #define MAX_DISPLAY_FAILURES 5
 
+#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
+
+#define GDM_DBUS_TYPE_G_STRING_STRING_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
+
 struct GdmLocalDisplayFactoryPrivate
 {
         DBusGConnection *connection;
         DBusGProxy      *proxy;
+        DBusGProxy      *proxy_ck;
         GHashTable      *displays;
+        GHashTable      *managed_seat_proxies;
 
         /* FIXME: this needs to be per seat? */
         guint            num_failures;
@@ -65,7 +83,14 @@ static void     gdm_local_display_factory_class_init    (GdmLocalDisplayFactoryC
 static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory      *factory);
 static void     gdm_local_display_factory_finalize      (GObject                     *object);
 
-static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory);
+static gboolean create_static_displays                  (GdmLocalDisplayFactory      *factory);
+static void     on_display_status_changed               (GdmDisplay                  *display,
+                                                         GParamSpec                  *arg1,
+                                                         GdmLocalDisplayFactory      *factory);
+static void     on_block_console_session_requests_changed (GdmDisplay                  *display,
+                                                         GParamSpec                  *arg1,
+                                                         GdmLocalDisplayFactory      *factory);
+static gboolean connect_to_ck                           (GdmLocalDisplayFactory *factory);
 
 static gpointer local_display_factory_object = NULL;
 
@@ -179,6 +204,100 @@ store_display (GdmLocalDisplayFactory *factory,
         g_hash_table_insert (factory->priv->displays, GUINT_TO_POINTER (num), NULL);
 }
 
+static void
+store_remove_display (GdmLocalDisplayFactory *factory,
+                      guint32                 num,
+                      GdmDisplay             *display)
+{
+        GdmDisplayStore *store;
+
+        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+        gdm_display_store_remove (store, display);
+
+        g_debug ("GdmLocalDisplayFactory: Remove display %d from store", num);
+
+        /* remove from our reserved spot */
+        g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
+}
+
+static gboolean
+lookup_by_session (const char     *id,
+                   GdmDisplay     *display,
+                   gpointer        user_data)
+{
+        char *key1 = user_data;
+        char *key2;
+
+        if (!GDM_IS_DISPLAY (display)) {
+                return FALSE;
+        }
+
+        gdm_display_get_session_id (display, &key2, NULL);
+
+        if (strcmp (key1, key2) == 0) {
+                g_free (key2);
+                return TRUE;
+        }
+        g_free (key2);
+
+        return FALSE;
+}
+
+static gboolean
+lookup_by_x11_display (const char     *id,
+                       GdmDisplay     *display,
+                       gpointer        user_data)
+{
+        char *key1 = user_data;
+        char *key2;
+
+        if (! GDM_IS_DISPLAY (display)) {
+                return FALSE;
+        }
+
+        gdm_display_get_x11_display_name (display, &key2, NULL);
+
+        if (strcmp (key1, key2) == 0) {
+                g_free (key2);
+                return TRUE;
+        }
+        g_free (key2);
+
+        return FALSE;
+}
+
+static gboolean
+lookup_by_x11_display_num (const char     *id,
+                           GdmDisplay     *display,
+                           gpointer        user_data)
+{
+        guint32 key1 = GPOINTER_TO_UINT (user_data);
+        int key2;
+
+        if (! GDM_IS_DISPLAY (display)) {
+                return FALSE;
+        }
+
+        gdm_display_get_x11_display_number (display, &key2, NULL);
+
+        if (key1 == key2) {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+static GdmDisplay *
+factory_find_display (GdmLocalDisplayFactory *factory,
+                      GdmDisplayStoreFunc     predicate,
+                      gpointer                user_data)
+{
+       GdmDisplayStore *store;
+
+       store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+       return gdm_display_store_find (store, predicate, user_data);
+}
+
 /*
   Example:
   dbus-send --system --dest=org.gnome.DisplayManager \
@@ -275,14 +394,113 @@ gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factor
         return ret;
 }
 
+static gboolean
+display_has_pending_sessions (GdmLocalDisplayFactory *factory,
+                              GdmDisplay             *display)
+{
+        return g_object_get_data (G_OBJECT (display),
+                                  "gdm-local-display-factory-console-session-requests") != NULL;
+}
+
 static void
-on_static_display_status_changed (GdmDisplay             *display,
-                                  GParamSpec             *arg1,
-                                  GdmLocalDisplayFactory *factory)
+manage_next_pending_session_on_display (GdmLocalDisplayFactory *factory,
+                                        GdmDisplay             *display)
+{
+        GList    *pending_sessions;
+        GList    *next_session;
+        char     *ssid;
+
+        g_debug ("GdmLocalDisplayFactory: Manage next pending session on display");
+
+        pending_sessions = g_object_get_data (G_OBJECT (display),
+                                              "gdm-local-display-factory-console-session-requests");
+        next_session = g_list_last (pending_sessions);
+
+        if (next_session == NULL) {
+                return;
+        }
+
+        ssid = next_session->data;
+        pending_sessions = g_list_delete_link (pending_sessions, next_session);
+        g_object_set_data (G_OBJECT (display),
+                           "gdm-local-display-factory-console-session-requests",
+                           pending_sessions);
+
+        g_object_set (display, "session-id", ssid, NULL);
+        g_free (ssid);
+
+        gdm_display_manage (display);
+}
+
+static void
+discard_pending_session_on_display (GdmLocalDisplayFactory *factory,
+                                    GdmDisplay             *display,
+                                    const char             *ssid)
+{
+        GList    *pending_sessions;
+        GList    *node;
+
+        pending_sessions = g_object_get_data (G_OBJECT (display),
+                                              "gdm-local-display-factory-console-session-requests");
+        node = g_list_last (pending_sessions);
+
+        while (node != NULL) {
+                GList  *prev_node;
+                char   *node_ssid;
+
+                prev_node = node->prev;
+                node_ssid = node->data;
+
+                if (strcmp (node_ssid, ssid) == 0) {
+                        pending_sessions = g_list_delete_link (pending_sessions, node);
+                        break;
+                }
+
+                node = prev_node;
+        }
+
+        g_object_set_data (G_OBJECT (display),
+                           "gdm-local-display-factory-console-session-requests",
+                           pending_sessions);
+}
+
+static void
+on_block_console_session_requests_changed (GdmDisplay                  *display,
+                                           GParamSpec                  *arg1,
+                                           GdmLocalDisplayFactory      *factory)
+{
+        gboolean  display_is_blocked;
+        int       status;
+
+        g_object_get (G_OBJECT (display),
+                      "status", &status,
+                      "block-console-session-requests",
+                      &display_is_blocked, NULL);
+
+        if (display_is_blocked) {
+                int number;
+
+                gdm_display_get_x11_display_number (display, &number, NULL);
+                g_debug ("GdmLocalDisplayFactory: display :%d is blocked", number);
+                return;
+        }
+
+        if (status == GDM_DISPLAY_UNMANAGED) {
+                manage_next_pending_session_on_display (factory, display);
+        }
+}
+
+static void
+on_display_status_changed (GdmDisplay             *display,
+                           GParamSpec             *arg1,
+                           GdmLocalDisplayFactory *factory)
 {
         int              status;
         GdmDisplayStore *store;
         int              num;
+        gboolean         display_is_blocked;
+
+        g_debug ("GdmLocalDisplayFactory: Display Status Changed");
 
         num = -1;
         gdm_display_get_x11_display_number (display, &num, NULL);
@@ -292,16 +510,17 @@ on_static_display_status_changed (GdmDisplay             *display,
 
         status = gdm_display_get_status (display);
 
+        g_object_get (G_OBJECT (display),
+                      "block-console-session-requests",
+                      &display_is_blocked, NULL);
+
         g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status);
         switch (status) {
         case GDM_DISPLAY_FINISHED:
-                /* remove the display number from factory->priv->displays
-                   so that it may be reused */
-                g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
-                gdm_display_store_remove (store, display);
-                /* reset num failures */
+                /* Do not remove the display number from factory->priv->displays
+                   here because it should be remove under signal "SessionRemoved"
+                 */
                 factory->priv->num_failures = 0;
-                create_display (factory);
                 break;
         case GDM_DISPLAY_FAILED:
                 /* leave the display number in factory->priv->displays
@@ -313,11 +532,13 @@ on_static_display_status_changed (GdmDisplay             *display,
                         g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
                         /* FIXME: should monitor hardware changes to
                            try again when seats change */
-                } else {
-                        create_display (factory);
                 }
                 break;
         case GDM_DISPLAY_UNMANAGED:
+                if (display_has_pending_sessions (factory, display) && !display_is_blocked) {   
+                        store_display (factory, num, display);
+                        manage_next_pending_session_on_display (factory, display);
+                }
                 break;
         case GDM_DISPLAY_PREPARED:
                 break;
@@ -329,42 +550,536 @@ on_static_display_status_changed (GdmDisplay             *display,
         }
 }
 
-static GdmDisplay *
-create_display (GdmLocalDisplayFactory *factory)
+static void
+seat_open_session_request (DBusGProxy             *seat_proxy,
+                           const char             *ssid,
+                           const char             *session_type,
+                           const char             *display_template_name,
+                           GHashTable             *display_variables,
+                           const char             *display_type,
+                           GHashTable             *parameters,
+                           GdmLocalDisplayFactory *factory)
 {
         GdmDisplay *display;
-        guint32     num;
+        gint        argc;
+        gchar     **argv;
+        GError     *error;
+        char       *comm = NULL;
+        const char *sid = NULL;
+        gint32      display_number;
+        gboolean    is_chooser = FALSE;
+        gboolean    use_auth = FALSE;
+        int         i;
+        char       *xserver_command;
+        gboolean    display_is_blocked;
+        GList      *pending_sessions;
+
+        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+
+        g_debug ("GdmLocalDisplayFactory: Open Session Request");
+
+        display_is_blocked = FALSE;
+
+        display = factory_find_display (factory, lookup_by_session, (gpointer)ssid);
+
+        if (display != NULL) {
+                g_object_get (G_OBJECT (display),
+                              "block-console-session-requests",
+                              &display_is_blocked, NULL);
+        }
 
-        num = take_next_display_number (factory);
+        if (strcmp (display_type, "X11") != 0) {
+                g_warning ("Unknown display type '%s' requested", display_type);
+                return;
+        }
+
+        xserver_command = g_hash_table_lookup (parameters, "Exec");
+
+        error = NULL;
+        if (xserver_command == NULL || ! g_shell_parse_argv (xserver_command, &argc, &argv, &error)) {
+                g_warning ("Could not parse command %s: %s", xserver_command, error ? error->message : "ConsoleKit configuration file missing Exec key");
+                if (error)
+                        g_error_free (error);
+                return;
+        }
+
+        g_debug("GdmLocalDisplayFactory: X11 server cmd pre-mangle: %s",
+                xserver_command);
+        for (i = 0; i < argc; i++) {
+                /* replase $display in case of not specified */
+                if (g_str_equal (argv[i], "$display")) {
+                        display_number = take_next_display_number (factory);
+                        argv[i][0] = '\0';
+                        continue;
+                }
+
+                /* get display_number in case of specified */
+                if (g_str_has_prefix (argv[i], ":")) {
+                        display_number = atoi (argv[i]+1);
+                        argv[i][0] = '\0';
+                        continue;
+                }
+
+                if (! g_strcmp0 (argv[i], "-indirect")) {
+                        is_chooser = TRUE;
+                        continue;
+                }
+
+                /*
+                 * -auth is added by gdm_server_resolve_command_line()
+                 * in gdm-server.c
+                 */
+                if (! g_strcmp0 (argv[i], "-auth") &&
+                    ! g_strcmp0 (argv[i+1], "$auth")) {
+                        use_auth = TRUE;
+                        argv[i][0] = '\0';
+                        argv[++i][0] = '\0';
+                        continue;
+                }
+
+                if (!g_strcmp0 (argv[i], "$vt")) {
+                        argv[i][0] = '\0';
+                        continue;
+                }
+        }
+        comm = g_strjoinv (" ", argv);
+        g_debug ("GdmLocalDisplayFactory: X11 server cmd post-mangle: %s",
+                 comm);
+        g_strfreev (argv);
 
-#if 0
-        display = gdm_static_factory_display_new (num);
-#else
-        display = gdm_static_display_new (num);
-#endif
         if (display == NULL) {
-                g_warning ("Unable to create display: %d", num);
-                return NULL;
+                if (is_chooser) {
+                        /* TODO: Start a xdmcp chooser as request */
+
+                        /* display = gdm_xdmcp_chooser_display_new (display_number); */
+                } else {
+                        display = gdm_dynamic_display_new (display_number);
+                }
+
+                if (display == NULL) {
+                        g_warning ("Unable to create display: %d", display_number);
+                        g_free (comm);
+                        return;
+                }
+
+                g_object_set (display, "session-id", ssid, NULL);
+
+                sid = dbus_g_proxy_get_path (seat_proxy);
+                if (IS_STR_SET (sid))
+                        g_object_set (display, "seat-id", sid, NULL);
+                if (IS_STR_SET (comm))
+                        g_object_set (display, "x11-command", comm, NULL);
+                g_free (comm);
+                if (IS_STR_SET (display_template_name))
+                        g_object_set (display, "x11-display-type", display_template_name, NULL);
+                g_object_set (display, "use-auth", use_auth, NULL);
+
+                g_signal_connect (display,
+                                  "notify::status",
+                                  G_CALLBACK (on_display_status_changed),
+                                  factory);
+
+                g_signal_connect (display,
+                                  "notify::block-console-session-requests",
+                                  G_CALLBACK (on_block_console_session_requests_changed),
+                                  factory);
+
+                store_display (factory, display_number, display);
+
+                g_object_unref (display);
+
+                if (! gdm_display_manage (display)) {
+                    gdm_display_unmanage (display);
+                }
+
+                return;
         }
 
-        /* FIXME: don't hardcode seat1? */
-        g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
+        /* FIXME: Make sure the display returned is compatible
+         */
 
-        g_signal_connect (display,
-                          "notify::status",
-                          G_CALLBACK (on_static_display_status_changed),
-                          factory);
+        if (!display_is_blocked) {
+                /* FIXME: What do we do here?
+                 */
+                g_debug ("Got console request to add display for session that "
+                         "already has a display, and display is already in "
+                         "use");
+                return;
+        }
 
-        store_display (factory, num, display);
+        pending_sessions = g_object_get_data (G_OBJECT (display),
+                                              "gdm-local-display-factory-console-session-requests");
+        pending_sessions = g_list_prepend (pending_sessions, g_strdup (ssid));
 
-        /* let store own the ref */
-        g_object_unref (display);
+        g_object_set_data (G_OBJECT (display),
+                           "gdm-local-display-factory-console-session-requests",
+                           pending_sessions);
+}
 
-        if (! gdm_display_manage (display)) {
-                gdm_display_unmanage (display);
+static void
+seat_close_session_request (DBusGProxy             *seat_proxy,
+                            const char             *ssid,
+                            GdmLocalDisplayFactory *factory)
+{
+        GdmDisplay      *display;
+        int              display_number;
+        char            *display_ssid;
+
+        g_debug ("GdmLocalDisplayFactory: Close session request");
+
+        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+
+        display = factory_find_display (factory, lookup_by_session, (gpointer)ssid);
+
+        if (display == NULL) {
+                g_debug ("GdmLocalDisplayFactory: display for session '%s' doesn't exists", ssid);
+                return;
+        }
+
+        g_object_get (G_OBJECT (display), "session-id", &display_ssid, NULL);
+
+        if (display_ssid == NULL || strcmp (ssid, display_ssid) != 0) {
+                g_free (display_ssid);
+                discard_pending_session_on_display (factory, display, ssid);
+                return;
+        }
+        g_free (display_ssid);
+
+        if (! gdm_display_unmanage (display)) {
+                display = NULL;
+                return;
+        }
+
+        gdm_display_get_x11_display_number (display, &display_number, NULL);
+        store_remove_display (factory, display_number, display);
+}
+
+static void
+seat_session_no_respawn (DBusGProxy             *seat_proxy,
+                         const char             *ssid,
+                         GdmLocalDisplayFactory *factory)
+{
+        GdmDisplay      *display;
+        int              display_number;
+        char            *display_ssid;
+
+        g_debug ("GdmLocalDisplayFactory: No Respawn");
+
+        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+
+        display = factory_find_display (factory, lookup_by_session, (gpointer)ssid);
+
+        if (display == NULL) {
+                g_debug ("GdmLocalDisplayFactory: display for session '%s' doesn't exists", ssid);
+                return;
+        }
+
+        if (GDM_IS_DYNAMIC_DISPLAY (display)) {
+                gdm_dynamic_display_removed (GDM_DYNAMIC_DISPLAY (display));
+        }
+}
+
+static gboolean
+get_session_x11_display (GdmLocalDisplayFactory *factory,
+                         const char             *ssid,
+                         char                   **x11_display)
+{
+        DBusGProxy      *proxy;
+        gboolean        res;
+
+        if (!x11_display)
+                return FALSE;
+
+        proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
+                                           CK_NAME,
+                                           ssid,
+                                           CK_SESSION_INTERFACE);
+        if (proxy == NULL) {
+                return FALSE;
+        }
+
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11Display",
+                                 NULL,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, x11_display,
+                                 G_TYPE_INVALID);
+        if (!res) {
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+static void
+seat_session_added (DBusGProxy             *seat_proxy,
+                    const char             *ssid,
+                    GdmLocalDisplayFactory *factory)
+{
+         GdmDisplay      *display;
+         char            *x11_display;
+         gboolean         res;
+
+         g_debug ("GdmLocalDisplayFactory: Adding Seat Session");
+
+         res = get_session_x11_display (factory, ssid, &x11_display);
+         if (!res) {
+                 g_warning ("Failed to get X11 display number for %s", ssid);
+                 return;
+         }
+
+         display = factory_find_display (factory, lookup_by_x11_display, 
+x11_display);
+         if (display) {
+                 gdm_display_set_session_id (display, ssid, NULL);
+                 g_debug ("Update session id for display %s to %s",
+                                 x11_display, ssid);
+         }
+         g_free (x11_display);
+}
+
+
+static void
+seat_session_removed (DBusGProxy             *seat_proxy,
+                      const char             *ssid,
+                      GdmLocalDisplayFactory *factory)
+{
+         GdmDisplay      *display = NULL;
+         gboolean         res;
+         int              status;
+         int              num;
+
+         g_debug ("GdmLocalDisplayFactory: Removed Seat Session");
+
+         display = factory_find_display (factory, lookup_by_session, 
+(gpointer)ssid);
+         if (display) {
+                 num = -1;
+                 gdm_display_get_x11_display_number (display, &num, NULL);
+                 g_assert (num != -1);
+                 store_remove_display (factory, num, display);
+         }
+}
+
+static void
+seat_remove_request (DBusGProxy             *seat_proxy,
+                     GdmLocalDisplayFactory *factory)
+{
+        GHashTableIter iter;
+        gpointer key, value;
+        const char *sid_to_remove;
+        GQueue      ssids_to_remove;
+
+        g_debug ("GdmLocalDisplayFactory: Seat Remove Request");
+
+        sid_to_remove = dbus_g_proxy_get_path (seat_proxy);
+
+        g_queue_init (&ssids_to_remove);
+        g_hash_table_iter_init (&iter, factory->priv->displays);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmDisplay *display;
+                char       *sid;
+                guint32     x11_display_num;
+
+                x11_display_num = GPOINTER_TO_UINT (key);
+                display = factory_find_display (factory,
+                                                lookup_by_x11_display_num,
+                                                GUINT_TO_POINTER (x11_display_num));
+
+                gdm_display_get_seat_id (display, &sid, NULL);
+
+                if (strcmp (sid, sid_to_remove) == 0) {
+                        char       *ssid;
+
+                        gdm_display_get_session_id (display, &ssid, NULL);
+
+                        g_queue_push_tail (&ssids_to_remove, ssid);
+                }
+
+                g_free (sid);
+        }
+
+        while (!g_queue_is_empty (&ssids_to_remove)) {
+                char       *ssid;
+
+                ssid = g_queue_pop_head (&ssids_to_remove);
+
+                seat_close_session_request (seat_proxy, ssid, factory);
+
+                g_free (ssid);
+        }
+
+        g_hash_table_remove (factory->priv->managed_seat_proxies, sid_to_remove);
+
+        dbus_g_proxy_call_no_reply (seat_proxy,
+                                    "Unmanage",
+                                    G_TYPE_INVALID,
+                                    G_TYPE_INVALID);
+
+        if (factory->priv->proxy_ck == NULL) {
+                connect_to_ck (factory);
         }
 
-        return display;
+        dbus_g_proxy_call_no_reply (factory->priv->proxy_ck,
+                                    "RemoveSeat",
+                                    DBUS_TYPE_G_OBJECT_PATH, sid_to_remove,
+                                    G_TYPE_INVALID,
+                                    G_TYPE_INVALID);
+}
+
+static void
+manage_static_sessions_per_seat (GdmLocalDisplayFactory *factory,
+                                 const char             *sid)
+{
+        DBusGProxy *proxy;
+
+        g_debug ("GdmLocalDisplayFactory: Manage Static Sessions Per Seat");
+
+        proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
+                                           CK_NAME,
+                                           sid,
+                                           CK_SEAT_INTERFACE);
+
+        if (proxy == NULL) {
+                g_warning ("Failed to connect to the ConsoleKit seat object");
+                return;
+        }
+
+        dbus_g_object_register_marshaller (gdm_marshal_VOID__STRING_STRING_STRING_POINTER_STRING_POINTER,
+                                           G_TYPE_NONE,
+                                           DBUS_TYPE_G_OBJECT_PATH,
+                                           G_TYPE_STRING,
+                                           G_TYPE_STRING,
+                                           GDM_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+                                           G_TYPE_STRING,
+                                           GDM_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+                                           G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "OpenSessionRequest",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_STRING,
+                                 G_TYPE_STRING,
+                                 GDM_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+                                 G_TYPE_STRING,
+                                 GDM_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "CloseSessionRequest",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "NoRespawn",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "SessionAdded",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "SessionRemoved",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "RemoveRequest",
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "OpenSessionRequest",
+                                     G_CALLBACK (seat_open_session_request),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "CloseSessionRequest",
+                                     G_CALLBACK (seat_close_session_request),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "NoRespawn",
+                                     G_CALLBACK (seat_session_no_respawn),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "SessionAdded",
+                                     G_CALLBACK (seat_session_added),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "SessionRemoved",
+                                     G_CALLBACK (seat_session_removed),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "RemoveRequest",
+                                     G_CALLBACK (seat_remove_request),
+                                     factory,
+                                     NULL);
+
+        dbus_g_proxy_call_no_reply (proxy,
+                                    "Manage",
+                                    G_TYPE_INVALID,
+                                    G_TYPE_INVALID);
+
+        g_hash_table_insert (factory->priv->managed_seat_proxies,
+                             g_strdup (dbus_g_proxy_get_path (proxy)),
+                             proxy);
+}
+
+static void
+seat_added (DBusGProxy             *mgr_proxy,
+            const char             *sid,
+            const char             *type,
+            GdmLocalDisplayFactory *factory)
+{
+        g_debug ("GdmLocalDisplayFactory: Seat Added");
+
+        if (strcmp (type, "Default") == 0) {
+                manage_static_sessions_per_seat (factory, sid);
+        }
+}
+
+static gboolean
+create_static_displays (GdmLocalDisplayFactory *factory)
+{
+        GError     *error;
+        gboolean    res;
+        GPtrArray  *seats;
+        int         i;
+
+        g_debug ("GdmLocalDisplayFactory: Create Static Display");
+
+        seats = NULL;
+
+        if (factory->priv->proxy_ck == NULL) {
+                connect_to_ck (factory);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (factory->priv->proxy_ck,
+                                 "GetUnmanagedSeats",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+                                 &seats,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                g_warning ("Failed to get list of unmanaged seats: %s", error->message);
+                g_error_free (error);
+                }
+                return FALSE;
+        }
+
+        for (i = 0; i < seats->len; i++) {
+                char *sid;
+
+                sid = g_ptr_array_index (seats, i);
+
+                manage_static_sessions_per_seat (factory, sid);
+
+                g_free (sid);
+        }
+
+        return TRUE;
+
 }
 
 static gboolean
@@ -379,7 +1094,7 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
         ret = TRUE;
 
         /* FIXME: use seat configuration */
-        display = create_display (factory);
+        display = create_static_displays (factory);
         if (display == NULL) {
                 ret = FALSE;
         }
@@ -443,6 +1158,67 @@ register_factory (GdmLocalDisplayFactory *factory)
         return TRUE;
 }
 
+static void
+bus_proxy_destroyed_cb (DBusGProxy  *bus_proxy,
+                        GdmLocalDisplayFactoryPrivate *priv)
+{
+        g_debug ("Local Display Factory - Disconnected from D-Bus");
+
+        if (priv == NULL) {
+                /* probably shutting down or something */
+                return;
+        }
+
+        priv->proxy_ck = NULL;
+}
+
+static gboolean
+connect_to_ck (GdmLocalDisplayFactory *factory)
+{
+        GdmLocalDisplayFactoryPrivate *priv;
+
+        g_debug ("GdmLocalDisplayFactory: Connect To ConsoleKit");
+
+        priv = factory->priv;
+
+        priv->proxy_ck = dbus_g_proxy_new_for_name (priv->connection,
+                                                    CK_NAME,
+                                                    CK_MANAGER_PATH,
+                                                    CK_MANAGER_INTERFACE);
+
+        if (priv->proxy_ck == NULL) {
+                g_warning ("Couldn't create proxy for ConsoleKit Manager");
+                return FALSE;
+        }
+
+        dbus_g_object_register_marshaller (gdm_marshal_VOID__STRING_STRING,
+                                           G_TYPE_NONE,
+                                           G_TYPE_STRING, G_TYPE_STRING,
+                                           G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (priv->proxy_ck,
+                                 "SeatAdded",
+                                 G_TYPE_STRING,
+                                 G_TYPE_STRING,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (priv->proxy_ck,
+                                     "SeatAdded",
+                                     G_CALLBACK (seat_added),
+                                     factory,
+                                     NULL);
+        g_signal_connect (priv->proxy_ck,
+                          "destroy",
+                          G_CALLBACK (bus_proxy_destroyed_cb),
+                          priv);
+}
+
+static void
+disconnect_from_ck (GdmLocalDisplayFactory *factory)
+{
+        if (factory->priv->proxy_ck == NULL) {
+                g_object_unref (factory->priv->proxy_ck);
+        }
+}
+
 static GObject *
 gdm_local_display_factory_constructor (GType                  type,
                                        guint                  n_construct_properties,
@@ -460,6 +1236,8 @@ gdm_local_display_factory_constructor (GType                  type,
                 g_warning ("Unable to register local display factory with system bus");
         }
 
+        connect_to_ck (factory);
+
         return G_OBJECT (factory);
 }
 
@@ -488,6 +1266,11 @@ gdm_local_display_factory_init (GdmLocalDisplayFactory *factory)
         factory->priv = GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE (factory);
 
         factory->priv->displays = g_hash_table_new (NULL, NULL);
+        factory->priv->proxy_ck = NULL;
+
+        factory->priv->managed_seat_proxies = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                                    (GDestroyNotify) g_free,
+                                                                    (GDestroyNotify) g_object_unref);
 }
 
 static void
@@ -503,6 +1286,9 @@ gdm_local_display_factory_finalize (GObject *object)
         g_return_if_fail (factory->priv != NULL);
 
         g_hash_table_destroy (factory->priv->displays);
+        g_hash_table_destroy (factory->priv->managed_seat_proxies);
+
+        disconnect_from_ck (factory);
 
         G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
 }
diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
index d4611a9..e344828 100644
--- a/daemon/gdm-product-slave.c
+++ b/daemon/gdm-product-slave.c
@@ -415,14 +415,12 @@ on_server_died (GdmServer       *server,
 static gboolean
 gdm_product_slave_create_server (GdmProductSlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -430,7 +428,7 @@ gdm_product_slave_create_server (GdmProductSlave *slave)
         if (display_is_local) {
                 gboolean res;
 
-                slave->priv->server = gdm_server_new (display_name, auth_file);
+                slave->priv->server = gdm_server_new (display_id);
                 g_signal_connect (slave->priv->server,
                                   "exited",
                                   G_CALLBACK (on_server_exited),
@@ -462,8 +460,7 @@ gdm_product_slave_create_server (GdmProductSlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index feaf673..80e426e 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -43,6 +43,8 @@
 #include <glib/gstdio.h>
 #include <glib-object.h>
 
+#include <dbus/dbus-glib.h>
+
 #include <X11/Xlib.h> /* for Display */
 
 #include "gdm-common.h"
@@ -54,6 +56,9 @@ extern char **environ;
 
 #define GDM_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SERVER, GdmServerPrivate))
 
+#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
+#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
+
 /* These are the servstat values, also used as server
  * process exit codes */
 #define SERVER_TIMEOUT 2        /* Server didn't start */
@@ -69,12 +74,12 @@ struct GdmServerPrivate
         char    *command;
         GPid     pid;
 
-        gboolean disable_tcp;
         int      priority;
         char    *user_name;
         char    *session_args;
 
         char    *log_dir;
+        char    *display_id;
         char    *display_name;
         char    *display_device;
         char    *auth_file;
@@ -101,7 +106,7 @@ enum {
         PROP_USER_NAME,
         PROP_SESSION_ARGS,
         PROP_LOG_DIR,
-        PROP_DISABLE_TCP,
+        PROP_DISPLAY_ID,
 };
 
 enum {
@@ -267,6 +272,11 @@ gdm_server_resolve_command_line (GdmServer  *server,
         gboolean gotvtarg = FALSE;
         gboolean query_in_arglist = FALSE;
 
+        if (!server->priv->command) {
+                g_warning ("X11 server command line is missing");
+                return FALSE;
+        }
+
         g_shell_parse_argv (server->priv->command, &argc, &argv, NULL);
 
         for (len = 0; argv != NULL && argv[len] != NULL; len++) {
@@ -307,11 +317,6 @@ gdm_server_resolve_command_line (GdmServer  *server,
                 query_in_arglist = TRUE;
         }
 
-        if (server->priv->disable_tcp && ! query_in_arglist) {
-                argv[len++] = g_strdup ("-nolisten");
-                argv[len++] = g_strdup ("tcp");
-        }
-
         if (vtarg != NULL && ! gotvtarg) {
                 argv[len++] = g_strdup (vtarg);
         }
@@ -612,16 +617,20 @@ gdm_server_spawn (GdmServer  *server,
         GPtrArray       *env;
         gboolean         ret;
         char            *freeme;
+        char            *tmp;
 
         ret = FALSE;
 
         /* Figure out the server command */
         argv = NULL;
         argc = 0;
-        gdm_server_resolve_command_line (server,
-                                         vtarg,
-                                         &argc,
-                                         &argv);
+        if (! gdm_server_resolve_command_line (server,
+                                               vtarg,
+                                               &argc,
+                                               &argv)) {
+                g_warning ("unable to process X11 server command line");
+                return FALSE;
+        }
 
         if (server->priv->session_args) {
                 server_add_xserver_args (server, &argc, &argv);
@@ -634,6 +643,29 @@ gdm_server_spawn (GdmServer  *server,
                 _exit (SERVER_ABORT);
         }
 
+        /* Sometimes quit X slowly, adding this  to avoid restart session
+           failure */
+        if ((tmp = strstr (server->priv->display_name, ":")) != NULL) {
+                char *socket_file;
+                int   display_num;
+                int   count;
+                char *p;
+
+                tmp++;
+                display_num = g_ascii_strtod (tmp, &p);
+
+                socket_file = g_strdup_printf ("/tmp/.X11-unix/X%d",
+                                               display_num);
+                count = 0;
+                while (count < 5) {
+                        if (!g_file_test (socket_file, G_FILE_TEST_EXISTS))
+                                break;
+                        sleep (1);
+                        count ++;
+                }
+                g_free (socket_file);
+        }
+
         env = get_server_environment (server);
 
         freeme = g_strjoinv (" ", argv);
@@ -743,13 +775,12 @@ gdm_server_stop (GdmServer *server)
         return TRUE;
 }
 
-
 static void
-_gdm_server_set_display_name (GdmServer  *server,
-                              const char *name)
+_gdm_server_set_display_id (GdmServer  *server,
+                            const char *id)
 {
-        g_free (server->priv->display_name);
-        server->priv->display_name = g_strdup (name);
+        g_free (server->priv->display_id);
+        server->priv->display_id = g_strdup (id);
 }
 
 static void
@@ -769,13 +800,6 @@ _gdm_server_set_user_name (GdmServer  *server,
 }
 
 static void
-_gdm_server_set_disable_tcp (GdmServer  *server,
-                             gboolean    disabled)
-{
-        server->priv->disable_tcp = disabled;
-}
-
-static void
 gdm_server_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
@@ -786,8 +810,8 @@ gdm_server_set_property (GObject      *object,
         self = GDM_SERVER (object);
 
         switch (prop_id) {
-        case PROP_DISPLAY_NAME:
-                _gdm_server_set_display_name (self, g_value_get_string (value));
+        case PROP_DISPLAY_ID:
+                _gdm_server_set_display_id (self, g_value_get_string (value));
                 break;
         case PROP_AUTH_FILE:
                 _gdm_server_set_auth_file (self, g_value_get_string (value));
@@ -795,9 +819,6 @@ gdm_server_set_property (GObject      *object,
         case PROP_USER_NAME:
                 _gdm_server_set_user_name (self, g_value_get_string (value));
                 break;
-        case PROP_DISABLE_TCP:
-                _gdm_server_set_disable_tcp (self, g_value_get_boolean (value));
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -815,8 +836,8 @@ gdm_server_get_property (GObject    *object,
         self = GDM_SERVER (object);
 
         switch (prop_id) {
-        case PROP_DISPLAY_NAME:
-                g_value_set_string (value, self->priv->display_name);
+        case PROP_DISPLAY_ID:
+                g_value_set_string (value, self->priv->display_id);
                 break;
         case PROP_DISPLAY_DEVICE:
                 g_value_take_string (value,
@@ -828,9 +849,6 @@ gdm_server_get_property (GObject    *object,
         case PROP_USER_NAME:
                 g_value_set_string (value, self->priv->user_name);
                 break;
-        case PROP_DISABLE_TCP:
-                g_value_set_boolean (value, self->priv->disable_tcp);
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -896,10 +914,10 @@ gdm_server_class_init (GdmServerClass *klass)
                               G_TYPE_INT);
 
         g_object_class_install_property (object_class,
-                                         PROP_DISPLAY_NAME,
-                                         g_param_spec_string ("display-name",
-                                                              "name",
-                                                              "name",
+                                         PROP_DISPLAY_ID,
+                                         g_param_spec_string ("display-id",
+                                                              "display id",
+                                                              "display id",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
@@ -924,13 +942,6 @@ gdm_server_class_init (GdmServerClass *klass)
                                                               "user name",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-        g_object_class_install_property (object_class,
-                                         PROP_DISABLE_TCP,
-                                         g_param_spec_boolean ("disable-tcp",
-                                                               NULL,
-                                                               NULL,
-                                                               TRUE,
-                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 }
 
@@ -941,7 +952,7 @@ gdm_server_init (GdmServer *server)
         server->priv = GDM_SERVER_GET_PRIVATE (server);
 
         server->priv->pid = -1;
-        server->priv->command = g_strdup (X_SERVER " -br -verbose");
+        server->priv->command = NULL;
         server->priv->log_dir = g_strdup (LOGDIR);
 
         add_ready_handler (server);
@@ -978,15 +989,123 @@ gdm_server_finalize (GObject *object)
 }
 
 GdmServer *
-gdm_server_new (const char *display_name,
-                const char *auth_file)
+gdm_server_new (const char *display_id)
 {
-        GObject *object;
+        GObject         *object;
+        GdmServer       *server;
+        DBusGConnection *connection;
+        DBusGProxy      *proxy;
+        GError          *error;
+        gboolean         res;
+        char            *id;
+
+        g_debug ("GdmServer: New Server");
 
         object = g_object_new (GDM_TYPE_SERVER,
-                               "display-name", display_name,
-                               "auth-file", auth_file,
+                               "display-id", display_id,
                                NULL);
 
-        return GDM_SERVER (object);
+        server = GDM_SERVER (object);
+
+        server->priv->pid = -1;
+
+        g_assert (server->priv->display_id != NULL);
+
+        error = NULL;
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        if (connection == NULL) {
+                if (error != NULL) {
+                        g_critical ("error getting system bus: %s", error->message);
+                        g_error_free (error);
+                }
+
+                exit (1);
+        }               
+
+        g_debug ("GdmServer: Creating proxy for %s", server->priv->display_id);
+        error = NULL;
+        proxy = dbus_g_proxy_new_for_name_owner (connection,
+                                                 GDM_DBUS_NAME,
+                                                 server->priv->display_id,
+                                                 GDM_DBUS_DISPLAY_INTERFACE,
+                                                 &error);
+        if (proxy == NULL) {
+                if (error != NULL) {
+                        g_warning ("Failed to create display proxy %s: %s", server->priv->display_id, error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Unable to create display proxy");
+                }
+
+                exit (1);
+        }                        
+                                 
+        /* cache some values up front */
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11DisplayName",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->display_name,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+
+                exit (1);
+        }
+
+        /* If display_name is not set, quit */
+        if (! server->priv->display_name || (strlen (server->priv->display_name) == 0)) {
+                g_warning ("Wrong value of method GetX11DisplayName for %s",server->priv->display_id);
+                exit (1);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11Command",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->command,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11AuthorityFile",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->auth_file,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);   
+        }
+
+        /* If auth_file is not set, set it NULL */
+        if (server->priv->auth_file && (strlen (server->priv->auth_file) == 0)) {
+                g_free (server->priv->auth_file);
+                server->priv->auth_file = NULL;
+        }
+
+        return server;
 }
diff --git a/daemon/gdm-server.h b/daemon/gdm-server.h
index 535a69a..84feb1f 100644
--- a/daemon/gdm-server.h
+++ b/daemon/gdm-server.h
@@ -53,8 +53,7 @@ typedef struct
 } GdmServerClass;
 
 GType               gdm_server_get_type  (void);
-GdmServer *         gdm_server_new       (const char *display_id,
-                                          const char *auth_file);
+GdmServer *         gdm_server_new       (const char *display_id);
 gboolean            gdm_server_start     (GdmServer   *server);
 gboolean            gdm_server_stop      (GdmServer   *server);
 char *              gdm_server_get_display_device (GdmServer *server);
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 73c34e2..3b28d84 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -58,6 +58,8 @@
 #include "gdm-session-record.h"
 #include "gdm-session-worker-job.h"
 
+#define GDM_DBUS_NAME                 "org.gnome.DisplayManager"
+#define GDM_DBUS_DISPLAY_INTERFACE    "org.gnome.DisplayManager.Display"
 #define GDM_SESSION_DBUS_PATH         "/org/gnome/DisplayManager/Session"
 #define GDM_SESSION_DBUS_INTERFACE    "org.gnome.DisplayManager.Session"
 #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
@@ -92,6 +94,9 @@ struct _GdmSessionDirectPrivate
         char                *display_hostname;
         char                *display_device;
         char                *display_x11_authority_file;
+        char                *display_console_session;
+        char                *display_type;
+        char                *display_seat_id;
         gboolean             display_is_local;
 
         char                *fallback_session_name;
@@ -99,6 +104,7 @@ struct _GdmSessionDirectPrivate
         DBusServer          *server;
         char                *server_address;
         GHashTable          *environment;
+        DBusGProxy          *display_proxy;
         DBusGConnection     *connection;
 };
 
@@ -110,7 +116,10 @@ enum {
         PROP_DISPLAY_IS_LOCAL,
         PROP_DISPLAY_DEVICE,
         PROP_DISPLAY_X11_AUTHORITY_FILE,
+        PROP_DISPLAY_CONSOLE_SESSION,
         PROP_USER_X11_AUTHORITY_FILE,
+        PROP_DISPLAY_TYPE,
+        PROP_DISPLAY_SEAT_ID,
 };
 
 static void     gdm_session_iface_init          (GdmSessionIface      *iface);
@@ -802,6 +811,34 @@ gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
+static DBusHandlerResult
+gdm_session_direct_handle_display_console_session_updated (GdmSessionDirect *session,
+                                                           DBusConnection   *connection,
+                                                           DBusMessage      *message)
+{
+        DBusMessage *reply;
+        DBusError    error;
+        const char  *text;
+
+        dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &text,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+
+        reply = dbus_message_new_method_return (message);
+        dbus_connection_send (connection, reply, NULL);
+        dbus_message_unref (reply);
+
+        g_debug ("GdmSessionDirect: changing ck session id to '%s'",
+                 text);
+
+
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+}
+
 static void
 cancel_pending_query (GdmSessionDirect *session)
 {
@@ -1284,6 +1321,8 @@ session_worker_message (DBusConnection *connection,
                 return gdm_session_direct_handle_accreditation_failed (session, connection, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) {
                 return gdm_session_direct_handle_username_changed (session, connection, message);
+        } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "DisplayConsoleSessionUpdated")) {
+                return gdm_session_direct_handle_display_console_session_updated (session, connection, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) {
                 return gdm_session_direct_handle_session_opened (session, connection, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "OpenFailed")) {
@@ -1392,6 +1431,8 @@ do_introspect (DBusConnection *connection,
                                "    <signal name=\"Setup\">\n"
                                "      <arg name=\"service_name\" type=\"s\"/>\n"
                                "      <arg name=\"x11_display_name\" type=\"s\"/>\n"
+                               "      <arg name=\"x11_display_type\" type=\"s\"/>\n"
+                               "      <arg name=\"x11_display_seat_id\" type=\"s\"/>\n"
                                "      <arg name=\"display_device\" type=\"s\"/>\n"
                                "      <arg name=\"hostname\" type=\"s\"/>\n"
                                "      <arg name=\"x11_authority_file\" type=\"s\"/>\n"
@@ -1399,6 +1440,8 @@ do_introspect (DBusConnection *connection,
                                "    <signal name=\"SetupForUser\">\n"
                                "      <arg name=\"service_name\" type=\"s\"/>\n"
                                "      <arg name=\"x11_display_name\" type=\"s\"/>\n"
+                               "      <arg name=\"x11_display_type\" type=\"s\"/>\n"
+                               "      <arg name=\"x11_seat_id\" type=\"s\"/>\n"
                                "      <arg name=\"display_device\" type=\"s\"/>\n"
                                "      <arg name=\"hostname\" type=\"s\"/>\n"
                                "      <arg name=\"x11_authority_file\" type=\"s\"/>\n"
@@ -1763,6 +1806,8 @@ send_setup (GdmSessionDirect *session,
         DBusMessage    *message;
         DBusMessageIter iter;
         const char     *display_name;
+        const char     *display_type;
+        const char     *display_seat_id;
         const char     *display_device;
         const char     *display_hostname;
         const char     *display_x11_authority_file;
@@ -1774,6 +1819,16 @@ send_setup (GdmSessionDirect *session,
         } else {
                 display_name = "";
         }
+        if (session->priv->display_type != NULL) {
+                display_type = session->priv->display_type;
+        } else {
+                display_type = "";
+        }
+        if (session->priv->display_seat_id!= NULL) {
+                display_seat_id = session->priv->display_seat_id;
+        } else {
+                display_seat_id = "";
+        }
         if (session->priv->display_hostname != NULL) {
                 display_hostname = session->priv->display_hostname;
         } else {
@@ -1799,6 +1854,8 @@ send_setup (GdmSessionDirect *session,
         dbus_message_iter_init_append (message, &iter);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_type);
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
@@ -1817,6 +1874,8 @@ send_setup_for_user (GdmSessionDirect *session,
         DBusMessage    *message;
         DBusMessageIter iter;
         const char     *display_name;
+        const char     *display_type;
+        const char     *display_seat_id;
         const char     *display_device;
         const char     *display_hostname;
         const char     *display_x11_authority_file;
@@ -1829,6 +1888,16 @@ send_setup_for_user (GdmSessionDirect *session,
         } else {
                 display_name = "";
         }
+        if (session->priv->display_type != NULL) {
+                display_type = session->priv->display_type;
+        } else {
+                display_type = "";
+        }
+        if (session->priv->display_seat_id != NULL) {
+                display_seat_id = session->priv->display_seat_id;
+        } else {
+                display_seat_id = "";
+        }
         if (session->priv->display_hostname != NULL) {
                 display_hostname = session->priv->display_hostname;
         } else {
@@ -1859,6 +1928,8 @@ send_setup_for_user (GdmSessionDirect *session,
         dbus_message_iter_init_append (message, &iter);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_type);
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
@@ -2369,6 +2440,30 @@ _gdm_session_direct_set_display_x11_authority_file (GdmSessionDirect *session,
 }
 
 static void
+_gdm_session_direct_set_display_type (GdmSessionDirect *session,
+                                      const char       *type)
+{
+        g_free (session->priv->display_type);
+        session->priv->display_type = g_strdup (type);
+}
+
+static void
+_gdm_session_direct_set_display_seat_id (GdmSessionDirect *session,
+                                         const char       *sid)
+{
+        g_free (session->priv->display_seat_id);
+        session->priv->display_seat_id = g_strdup (sid);
+}
+
+static void
+_gdm_session_direct_set_display_console_session (GdmSessionDirect *session,
+                                            const char       *console_session)
+{
+        g_free (session->priv->display_console_session);
+        session->priv->display_console_session = g_strdup (console_session);
+}
+
+static void
 _gdm_session_direct_set_display_is_local (GdmSessionDirect *session,
                                           gboolean          is)
 {
@@ -2404,9 +2499,18 @@ gdm_session_direct_set_property (GObject      *object,
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 _gdm_session_direct_set_display_x11_authority_file (self, g_value_get_string (value));
                 break;
+        case PROP_DISPLAY_CONSOLE_SESSION:
+                _gdm_session_direct_set_display_console_session (self, g_value_get_string (value));
+                break;
         case PROP_DISPLAY_IS_LOCAL:
                 _gdm_session_direct_set_display_is_local (self, g_value_get_boolean (value));
                 break;
+        case PROP_DISPLAY_TYPE:
+                _gdm_session_direct_set_display_type (self, g_value_get_string (value));
+                break;
+        case PROP_DISPLAY_SEAT_ID:
+                _gdm_session_direct_set_display_seat_id (self, g_value_get_string (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -2442,9 +2546,18 @@ gdm_session_direct_get_property (GObject    *object,
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 g_value_set_string (value, self->priv->display_x11_authority_file);
                 break;
+        case PROP_DISPLAY_CONSOLE_SESSION:
+                g_value_set_string (value, self->priv->display_console_session);
+                break;
         case PROP_DISPLAY_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->display_is_local);
                 break;
+        case PROP_DISPLAY_TYPE:
+                g_value_set_string (value, self->priv->display_type);
+                break;
+        case PROP_DISPLAY_SEAT_ID:
+                g_value_set_string (value, self->priv->display_seat_id);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -2480,6 +2593,12 @@ gdm_session_direct_dispose (GObject *object)
         g_free (session->priv->server_address);
         session->priv->server_address = NULL;
 
+        g_free (session->priv->display_type);
+        session->priv->display_type = NULL;
+
+        g_free (session->priv->display_seat_id);
+        session->priv->display_seat_id = NULL;
+
         if (session->priv->server != NULL) {
                 dbus_server_disconnect (session->priv->server);
                 dbus_server_unref (session->priv->server);
@@ -2491,6 +2610,11 @@ gdm_session_direct_dispose (GObject *object)
                 session->priv->environment = NULL;
         }
 
+        if (session->priv->display_proxy != NULL) {
+                g_object_unref (session->priv->display_proxy);
+        }
+
+
         G_OBJECT_CLASS (gdm_session_direct_parent_class)->dispose (object);
 }
 
@@ -2643,6 +2767,14 @@ gdm_session_direct_class_init (GdmSessionDirectClass *session_class)
                                                               "display x11 authority file",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+        g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_CONSOLE_SESSION,
+                                         g_param_spec_string ("display-console-session",
+                                                              "Display ConsoleKit session",
+                                                              "The ConsoleKit Session Id for the display",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         /* not construct only */
         g_object_class_install_property (object_class,
                                          PROP_USER_X11_AUTHORITY_FILE,
@@ -2658,11 +2790,140 @@ gdm_session_direct_class_init (GdmSessionDirectClass *session_class)
                                                               "display device",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_TYPE,
+                                         g_param_spec_string ("display-type",
+                                                              "display type",
+                                                              "display type",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_SEAT_ID,
+                                         g_param_spec_string ("seat-id",
+                                                              "seat id",
+                                                              "seat id",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 
         dbus_g_object_type_install_info (GDM_TYPE_SESSION_DIRECT, &dbus_glib_gdm_session_direct_object_info);
 }
 
+static void
+display_proxy_destroyed_cb (DBusGProxy       *display_proxy,
+                            GdmSessionDirect *session)
+{
+        g_debug ("GdmSessionDirect: Disconnected from display");
+
+        session->priv->display_proxy = NULL;
+}
+
+static gboolean
+init_display_data (GdmSessionDirect *session)
+{
+        gboolean    res;
+        char       *id;
+        GError     *error;
+
+        g_assert (session->priv->display_proxy == NULL);
+
+        error = NULL; 
+        session->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        if (session->priv->connection == NULL) {
+                if (error != NULL) {
+                        g_critical ("error getting system bus: %s", error->message);
+                        g_error_free (error);
+                }
+                exit (1);
+        }
+
+        error = NULL;
+        session->priv->display_proxy = dbus_g_proxy_new_for_name_owner (
+                                                 session->priv->connection,
+                                                 GDM_DBUS_NAME,
+                                                 session->priv->display_id,
+                                                 GDM_DBUS_DISPLAY_INTERFACE,
+                                                 &error);
+
+        g_signal_connect (session->priv->display_proxy,
+                          "destroy",
+                          G_CALLBACK (display_proxy_destroyed_cb),
+                          session);
+
+        if (session->priv->display_proxy == NULL) {
+                if (error != NULL) {
+                        g_warning ("Failed to create display proxy %s: %s", session->priv->display_id, error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Unable to create display proxy");
+                }
+                return FALSE;
+        }
+
+        /* Make sure display ID works */
+        error = NULL;
+        res = dbus_g_proxy_call (session->priv->display_proxy,
+                                 "GetId",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 DBUS_TYPE_G_OBJECT_PATH, &id,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get display id %s: %s", session->priv->display_id, error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get display id %s", session->priv->display_id);
+                }
+
+                return FALSE;
+        }
+
+        if (strcmp (id, session->priv->display_id) != 0) {
+                g_critical ("Display ID doesn't match");
+                exit (1);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (session->priv->display_proxy,
+                                 "GetX11DisplayType",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &session->priv->display_type,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get value");
+                }
+        
+                return FALSE;    
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (session->priv->display_proxy,
+                                 "GetSeatId",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &session->priv->display_seat_id,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get value");
+                }
+
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+
 GdmSessionDirect *
 gdm_session_direct_new (const char *display_id,
                         const char *display_name,
@@ -2682,6 +2943,8 @@ gdm_session_direct_new (const char *display_id,
                                 "display-is-local", display_is_local,
                                 NULL);
 
+        init_display_data (session);
+
         return session;
 }
 
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index f8ba4ba..13a470b 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -118,6 +118,8 @@ struct GdmSessionWorkerPrivate
         /* from Setup */
         char             *service;
         char             *x11_display_name;
+        char             *x11_display_type;
+        char             *seat_id;
         char             *x11_authority_file;
         char             *display_device;
         char             *hostname;
@@ -178,6 +180,8 @@ open_ck_session (GdmSessionWorker  *worker)
         int            res;
         DBusError      error;
         const char     *display_name;
+        const char     *display_type;
+        const char     *seat_id;
         const char     *display_device;
         const char     *display_hostname;
         gboolean        is_local;
@@ -189,6 +193,16 @@ open_ck_session (GdmSessionWorker  *worker)
         } else {
                 display_name = "";
         }
+        if (worker->priv->x11_display_type != NULL) {
+                display_type = worker->priv->x11_display_type;
+        } else {
+                display_type = "";
+        }
+        if (worker->priv->seat_id != NULL) {
+                seat_id = worker->priv->seat_id;
+        } else {
+                seat_id = "";
+        }
         if (worker->priv->hostname != NULL) {
                 display_hostname = worker->priv->hostname;
         } else {
@@ -225,6 +239,8 @@ open_ck_session (GdmSessionWorker  *worker)
         dbus_error_init (&error);
         res = ck_connector_open_session_with_parameters (worker->priv->ckc,
                                                          &error,
+                                                         "display-type", &display_type,
+                                                         "seat-id", &seat_id,
                                                          "unix-user", &pwent->pw_uid,
                                                          "x11-display", &display_name,
                                                          "x11-display-device", &display_device,
@@ -1815,6 +1831,7 @@ static void
 register_ck_session (GdmSessionWorker *worker)
 {
         const char *session_cookie;
+        const char *session_id;
         gboolean    res;
 
         session_cookie = NULL;
@@ -1827,6 +1844,12 @@ register_ck_session (GdmSessionWorker *worker)
                                                              "XDG_SESSION_COOKIE",
                                                              session_cookie);
         }
+
+        session_id = ck_connector_get_session_id (worker->priv->ckc);
+
+        send_dbus_string_method (worker->priv->connection,
+                                 "DisplayConsoleSessionUpdated",
+                                 session_id);
 }
 
 static void
@@ -1846,19 +1869,24 @@ session_worker_child_watch (GPid              pid,
         if (WIFEXITED (status)) {
                 int code = WEXITSTATUS (status);
 
+                ck_connector_set_remove_on_close (worker->priv->ckc,
+                                                  TRUE,
+                                                  NULL);
                 send_dbus_int_method (worker->priv->connection,
                                       "SessionExited",
                                       code);
         } else if (WIFSIGNALED (status)) {
                 int num = WTERMSIG (status);
 
+                ck_connector_set_remove_on_close (worker->priv->ckc,
+                                                  TRUE,
+                                                  NULL);
                 send_dbus_int_method (worker->priv->connection,
                                       "SessionDied",
                                       num);
         }
 
         if (worker->priv->ckc != NULL) {
-                ck_connector_close_session (worker->priv->ckc, NULL);
                 ck_connector_unref (worker->priv->ckc);
                 worker->priv->ckc = NULL;
         }
@@ -2646,6 +2674,8 @@ on_setup (GdmSessionWorker *worker,
         DBusError   error;
         const char *service;
         const char *x11_display_name;
+        const char *x11_display_type;
+        const char *seat_id;
         const char *x11_authority_file;
         const char *console;
         const char *hostname;
@@ -2661,6 +2691,8 @@ on_setup (GdmSessionWorker *worker,
                                      &error,
                                      DBUS_TYPE_STRING, &service,
                                      DBUS_TYPE_STRING, &x11_display_name,
+                                     DBUS_TYPE_STRING, &x11_display_type,
+                                     DBUS_TYPE_STRING, &seat_id,
                                      DBUS_TYPE_STRING, &console,
                                      DBUS_TYPE_STRING, &hostname,
                                      DBUS_TYPE_STRING, &x11_authority_file,
@@ -2668,6 +2700,8 @@ on_setup (GdmSessionWorker *worker,
         if (res) {
                 worker->priv->service = g_strdup (service);
                 worker->priv->x11_display_name = g_strdup (x11_display_name);
+                worker->priv->x11_display_type = g_strdup (x11_display_type);
+                worker->priv->seat_id = g_strdup (seat_id);
                 worker->priv->x11_authority_file = g_strdup (x11_authority_file);
                 worker->priv->display_device = g_strdup (console);
                 worker->priv->hostname = g_strdup (hostname);
@@ -2688,6 +2722,8 @@ on_setup_for_user (GdmSessionWorker *worker,
         DBusError   error;
         const char *service;
         const char *x11_display_name;
+        const char *x11_display_type;
+        const char *seat_id;
         const char *x11_authority_file;
         const char *console;
         const char *hostname;
@@ -2704,6 +2740,8 @@ on_setup_for_user (GdmSessionWorker *worker,
                                      &error,
                                      DBUS_TYPE_STRING, &service,
                                      DBUS_TYPE_STRING, &x11_display_name,
+                                     DBUS_TYPE_STRING, &x11_display_type,
+                                     DBUS_TYPE_STRING, &seat_id,
                                      DBUS_TYPE_STRING, &console,
                                      DBUS_TYPE_STRING, &hostname,
                                      DBUS_TYPE_STRING, &x11_authority_file,
@@ -2712,6 +2750,8 @@ on_setup_for_user (GdmSessionWorker *worker,
         if (res) {
                 worker->priv->service = g_strdup (service);
                 worker->priv->x11_display_name = g_strdup (x11_display_name);
+                worker->priv->x11_display_type = g_strdup (x11_display_type);
+                worker->priv->seat_id = g_strdup (seat_id);
                 worker->priv->x11_authority_file = g_strdup (x11_authority_file);
                 worker->priv->display_device = g_strdup (console);
                 worker->priv->hostname = g_strdup (hostname);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 0b96abb..e80122f 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -385,6 +385,10 @@ start_session_timeout (GdmSimpleSlave *slave)
                 goto out;
         }
 
+        /* Defer requests to use this display from ConsoleKit
+         * for the time being
+         */
+        gdm_slave_block_console_session_requests_on_display (GDM_SLAVE (slave));
         stop_greeter (slave);
 
         auth_file = NULL;
@@ -399,6 +403,7 @@ start_session_timeout (GdmSimpleSlave *slave)
         g_free (auth_file);
 
         gdm_session_start_session (GDM_SESSION (slave->priv->session));
+        gdm_slave_unblock_console_session_requests_on_display (GDM_SLAVE (slave));
  out:
         slave->priv->start_session_id = 0;
         return FALSE;
@@ -600,6 +605,16 @@ on_default_session_name_changed (GdmSession     *session,
 }
 
 static void
+on_console_session_changed (GdmSession     *session,
+                            const char     *text,
+                            GdmSimpleSlave *slave)
+{
+        g_debug ("GdmSimpleSlave: Default session name changed: %s", text);
+
+        gdm_slave_set_console_session_id (GDM_SLAVE (slave), text);
+}
+
+static void
 create_new_session (GdmSimpleSlave *slave)
 {
         gboolean       display_is_local;
@@ -634,6 +649,7 @@ create_new_session (GdmSimpleSlave *slave)
         g_free (display_name);
         g_free (display_device);
         g_free (display_hostname);
+        g_free (display_x11_authority_file);
 
         g_signal_connect (slave->priv->session,
                           "conversation-started",
@@ -740,6 +756,11 @@ create_new_session (GdmSimpleSlave *slave)
                           "default-session-name-changed",
                           G_CALLBACK (on_default_session_name_changed),
                           slave);
+
+        g_signal_connect (slave->priv->session,
+                          "notify::display-console-session",
+                          G_CALLBACK (on_console_session_changed),
+                          slave);
 }
 
 static void
@@ -763,7 +784,7 @@ on_greeter_session_exited (GdmGreeterSession    *greeter,
                            GdmSimpleSlave       *slave)
 {
         g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
-        gdm_slave_stopped (GDM_SLAVE (slave));
+        gdm_slave_failed (GDM_SLAVE (slave));
 }
 
 static void
@@ -907,6 +928,8 @@ start_greeter (GdmSimpleSlave *slave)
         gboolean       display_is_local;
         char          *display_id;
         char          *display_name;
+        char          *seat_id;
+        char          *session_id;
         char          *display_device;
         char          *display_hostname;
         char          *auth_file;
@@ -918,6 +941,8 @@ start_greeter (GdmSimpleSlave *slave)
         display_is_local = FALSE;
         display_id = NULL;
         display_name = NULL;
+        seat_id = NULL;
+        session_id = NULL;
         auth_file = NULL;
         display_device = NULL;
         display_hostname = NULL;
@@ -926,6 +951,8 @@ start_greeter (GdmSimpleSlave *slave)
                       "display-id", &display_id,
                       "display-is-local", &display_is_local,
                       "display-name", &display_name,
+                      "display-seat-id", &seat_id,
+                      "display-session-id", &session_id,
                       "display-hostname", &display_hostname,
                       "display-x11-authority-file", &auth_file,
                       NULL);
@@ -1005,6 +1032,8 @@ start_greeter (GdmSimpleSlave *slave)
 
         g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname);
         slave->priv->greeter = gdm_greeter_session_new (display_name,
+                                                        seat_id,
+                                                        session_id,
                                                         display_device,
                                                         display_hostname,
                                                         display_is_local);
@@ -1035,6 +1064,7 @@ start_greeter (GdmSimpleSlave *slave)
 
         g_free (display_id);
         g_free (display_name);
+        g_free (seat_id);
         g_free (display_device);
         g_free (display_hostname);
         g_free (auth_file);
@@ -1092,7 +1122,11 @@ on_server_exited (GdmServer      *server,
 {
         g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code);
 
-        gdm_slave_stopped (GDM_SLAVE (slave));
+        if (exit_code != 0) {
+                gdm_slave_failed (GDM_SLAVE (slave));
+        } else {
+                gdm_slave_stopped (GDM_SLAVE (slave));
+        }
 }
 
 static void
@@ -1110,31 +1144,20 @@ on_server_died (GdmServer      *server,
 static gboolean
 gdm_simple_slave_run (GdmSimpleSlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
          * exist */
         if (display_is_local) {
                 gboolean res;
-                gboolean disable_tcp;
 
-                slave->priv->server = gdm_server_new (display_name, auth_file);
-
-                disable_tcp = TRUE;
-                if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
-                                                     &disable_tcp)) {
-                        g_object_set (slave->priv->server,
-                                      "disable-tcp", disable_tcp,
-                                      NULL);
-                }
+                slave->priv->server = gdm_server_new (display_id);
 
                 g_signal_connect (slave->priv->server,
                                   "exited",
@@ -1167,8 +1190,7 @@ gdm_simple_slave_run (GdmSimpleSlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-slave-proxy.c b/daemon/gdm-slave-proxy.c
index 48efbd1..a0c7239 100644
--- a/daemon/gdm-slave-proxy.c
+++ b/daemon/gdm-slave-proxy.c
@@ -245,6 +245,7 @@ kill_slave (GdmSlaveProxy *slave)
                 g_warning ("Unable to kill slave process");
         } else {
                 exit_status = gdm_wait_on_pid (slave->priv->pid);
+                g_debug ("GdmSlaveProxy: Slave exit status %d", exit_status);
                 g_spawn_close_pid (slave->priv->pid);
                 slave->priv->pid = 0;
         }
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index 2915da0..cb2a6a9 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -82,11 +82,13 @@ struct GdmSlavePrivate
         /* cached display values */
         char            *display_id;
         char            *display_name;
+        char            *display_type;
         int              display_number;
         char            *display_hostname;
         gboolean         display_is_local;
         gboolean         display_is_parented;
         char            *display_seat_id;
+        char            *display_session_id;
         char            *display_x11_authority_file;
         char            *parent_display_name;
         char            *parent_display_x11_authority_file;
@@ -102,15 +104,18 @@ enum {
         PROP_0,
         PROP_DISPLAY_ID,
         PROP_DISPLAY_NAME,
+        PROP_DISPLAY_TYPE,
         PROP_DISPLAY_NUMBER,
         PROP_DISPLAY_HOSTNAME,
         PROP_DISPLAY_IS_LOCAL,
         PROP_DISPLAY_SEAT_ID,
+        PROP_DISPLAY_SESSION_ID,
         PROP_DISPLAY_X11_AUTHORITY_FILE
 };
 
 enum {
         STOPPED,
+        FAILED,
         LAST_SIGNAL
 };
 
@@ -669,6 +674,24 @@ gdm_slave_real_start (GdmSlave *slave)
 
         error = NULL;
         res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "GetX11DisplayType",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &slave->priv->display_type,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get value");
+                }
+
+                return FALSE;
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
                                  "GetX11DisplayNumber",
                                  &error,
                                  G_TYPE_INVALID,
@@ -758,6 +781,24 @@ gdm_slave_real_start (GdmSlave *slave)
                 return FALSE;
         }
 
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "GetSessionId",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &slave->priv->display_session_id,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get value");
+                }
+
+                return FALSE;
+        }
+
         return TRUE;
 }
 
@@ -813,6 +854,42 @@ gdm_slave_stopped (GdmSlave *slave)
         g_signal_emit (slave, signals [STOPPED], 0);
 }
 
+void
+gdm_slave_failed (GdmSlave *slave)
+{
+        g_return_if_fail (GDM_IS_SLAVE (slave));
+
+        g_signal_emit (slave, signals [FAILED], 0);
+}
+
+void
+gdm_slave_set_console_session_id (GdmSlave   *slave,
+                                  const char *session_id)
+{
+        gboolean res;
+        GError  *error;
+
+        g_debug ("GdmSlave: Informing display of new session id");
+
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "SetConsoleSessionId",
+                                 &error,
+                                 G_TYPE_STRING, session_id,
+                                 G_TYPE_INVALID, G_TYPE_INVALID);
+
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to set console session id: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to set console session id");
+                }
+        } else {
+                g_debug ("GdmSlave: Set console session id");
+        }
+}
+
 gboolean
 gdm_slave_add_user_authorization (GdmSlave   *slave,
                                   const char *username,
@@ -1396,6 +1473,59 @@ gdm_slave_switch_to_user_session (GdmSlave   *slave,
         return ret;
 }
 
+void
+gdm_slave_block_console_session_requests_on_display (GdmSlave *slave)
+{
+        gboolean res;
+        GError  *error;
+
+        g_debug ("GdmSlave: Asking display to ignore ConsoleKit");
+
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "BlockConsoleSessionRequests",
+                                 &error,
+                                 G_TYPE_INVALID, G_TYPE_INVALID);
+
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get display to ignore ConsoleKit: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get display to ignore ConsoleKit");
+                }
+        } else {
+                g_debug ("GdmSlave: Display is now ignoring ConsoleKit");
+        }
+}
+
+void
+gdm_slave_unblock_console_session_requests_on_display (GdmSlave *slave)
+{
+        gboolean res;
+        GError  *error;
+
+        g_debug ("GdmSlave: Informing display to stop ignoring ConsoleKit");
+
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "UnblockConsoleSessionRequests",
+                                 &error,
+                                 G_TYPE_INVALID, G_TYPE_INVALID);
+
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get display to stop ignoring ConsoleKit: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get display to stop ignoring ConsoleKit");
+                }
+        } else {
+                g_debug ("GdmSlave: Display is no longer ignoring ConsoleKit");
+        }
+}
+
+
 static void
 _gdm_slave_set_display_id (GdmSlave   *slave,
                            const char *id)
@@ -1412,6 +1542,15 @@ _gdm_slave_set_display_name (GdmSlave   *slave,
         slave->priv->display_name = g_strdup (name);
 }
 
+
+static void
+_gdm_slave_set_display_type (GdmSlave   *slave,
+                             const char *type)
+{
+        g_free (slave->priv->display_type);
+        slave->priv->display_type = g_strdup (type);
+}
+
 static void
 _gdm_slave_set_display_number (GdmSlave   *slave,
                                int         number)
@@ -1444,6 +1583,14 @@ _gdm_slave_set_display_seat_id (GdmSlave   *slave,
 }
 
 static void
+_gdm_slave_set_display_session_id (GdmSlave   *slave,
+                                   const char *id)
+{
+        g_free (slave->priv->display_session_id);
+        slave->priv->display_session_id = g_strdup (id);
+}
+
+static void
 _gdm_slave_set_display_is_local (GdmSlave   *slave,
                                  gboolean    is)
 {
@@ -1467,6 +1614,9 @@ gdm_slave_set_property (GObject      *object,
         case PROP_DISPLAY_NAME:
                 _gdm_slave_set_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_DISPLAY_TYPE:
+                _gdm_slave_set_display_type (self, g_value_get_string (value));
+                break;
         case PROP_DISPLAY_NUMBER:
                 _gdm_slave_set_display_number (self, g_value_get_int (value));
                 break;
@@ -1476,6 +1626,9 @@ gdm_slave_set_property (GObject      *object,
         case PROP_DISPLAY_SEAT_ID:
                 _gdm_slave_set_display_seat_id (self, g_value_get_string (value));
                 break;
+        case PROP_DISPLAY_SESSION_ID:
+                _gdm_slave_set_display_session_id (self, g_value_get_string (value));
+                break;
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 _gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value));
                 break;
@@ -1505,6 +1658,9 @@ gdm_slave_get_property (GObject    *object,
         case PROP_DISPLAY_NAME:
                 g_value_set_string (value, self->priv->display_name);
                 break;
+        case PROP_DISPLAY_TYPE:
+                g_value_set_string (value, self->priv->display_type);
+                break;
         case PROP_DISPLAY_NUMBER:
                 g_value_set_int (value, self->priv->display_number);
                 break;
@@ -1514,6 +1670,9 @@ gdm_slave_get_property (GObject    *object,
         case PROP_DISPLAY_SEAT_ID:
                 g_value_set_string (value, self->priv->display_seat_id);
                 break;
+        case PROP_DISPLAY_SESSION_ID:
+                g_value_set_string (value, self->priv->display_session_id);
+                break;
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 g_value_set_string (value, self->priv->display_x11_authority_file);
                 break;
@@ -1608,6 +1767,13 @@ gdm_slave_class_init (GdmSlaveClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_TYPE,
+                                         g_param_spec_string ("display-type",
+                                                              "display type",
+                                                              "display type",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
                                          PROP_DISPLAY_NUMBER,
                                          g_param_spec_int ("display-number",
                                                            "display number",
@@ -1631,6 +1797,13 @@ gdm_slave_class_init (GdmSlaveClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_SESSION_ID,
+                                         g_param_spec_string ("display-session-id",
+                                                              "",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
                                          PROP_DISPLAY_X11_AUTHORITY_FILE,
                                          g_param_spec_string ("display-x11-authority-file",
                                                               "",
@@ -1656,6 +1829,17 @@ gdm_slave_class_init (GdmSlaveClass *klass)
                               G_TYPE_NONE,
                               0);
 
+        signals [FAILED] =
+                g_signal_new ("failed",
+                              G_TYPE_FROM_CLASS (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GdmSlaveClass, failed),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
         dbus_g_object_type_install_info (GDM_TYPE_SLAVE, &dbus_glib_gdm_slave_object_info);
 }
 
@@ -1685,6 +1869,7 @@ gdm_slave_finalize (GObject *object)
         g_free (slave->priv->id);
         g_free (slave->priv->display_id);
         g_free (slave->priv->display_name);
+        g_free (slave->priv->display_type);
         g_free (slave->priv->display_hostname);
         g_free (slave->priv->display_seat_id);
         g_free (slave->priv->display_x11_authority_file);
diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h
index af28b00..610b7d6 100644
--- a/daemon/gdm-slave.h
+++ b/daemon/gdm-slave.h
@@ -51,6 +51,7 @@ typedef struct
 
         /* signals */
         void (*stopped) (GdmSlave *slave);
+        void (*failed)  (GdmSlave *slave);
 } GdmSlaveClass;
 
 GType               gdm_slave_get_type               (void);
@@ -72,13 +73,17 @@ gboolean            gdm_slave_add_user_authorization (GdmSlave   *slave,
 gboolean            gdm_slave_switch_to_user_session (GdmSlave   *slave,
                                                       const char *username);
 
+void                gdm_slave_block_console_session_requests_on_display   (GdmSlave *slave);
+void                gdm_slave_unblock_console_session_requests_on_display (GdmSlave *slave);
+
 gboolean            gdm_slave_connect_to_x11_display (GdmSlave   *slave);
 void                gdm_slave_set_busy_cursor        (GdmSlave   *slave);
 gboolean            gdm_slave_run_script             (GdmSlave   *slave,
                                                       const char *dir,
                                                       const char *username);
 void                gdm_slave_stopped                (GdmSlave   *slave);
-
+void                gdm_slave_set_console_session_id (GdmSlave   *slave,
+                                                      const char *session_id);
 G_END_DECLS
 
 #endif /* __GDM_SLAVE_H */
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
index 39c53d8..426e3d0 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -66,6 +66,8 @@ struct GdmWelcomeSessionPrivate
         char           *runtime_dir;
 
         char           *x11_display_name;
+        char           *x11_display_seat_id;
+        char           *x11_display_session_id;
         char           *x11_display_device;
         char           *x11_display_hostname;
         char           *x11_authority_file;
@@ -86,6 +88,8 @@ struct GdmWelcomeSessionPrivate
 enum {
         PROP_0,
         PROP_X11_DISPLAY_NAME,
+        PROP_X11_DISPLAY_SEAT_ID,
+        PROP_X11_DISPLAY_SESSION_ID,
         PROP_X11_DISPLAY_DEVICE,
         PROP_X11_DISPLAY_HOSTNAME,
         PROP_X11_AUTHORITY_FILE,
@@ -135,6 +139,8 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
         const char    *session_type;
         const char    *hostname;
         const char    *x11_display_device;
+        const char    *seat_id;
+        const char    *session_id;
         int            res;
         gboolean       ret;
         DBusError      error;
@@ -170,6 +176,18 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
                 x11_display_device = "";
         }
 
+        if (welcome_session->priv->x11_display_seat_id != NULL) {
+                seat_id = welcome_session->priv->x11_display_seat_id;
+        } else {
+                seat_id = "";
+        }
+
+        if (welcome_session->priv->x11_display_session_id != NULL) {
+                session_id = welcome_session->priv->x11_display_session_id;
+        } else {
+                session_id = "";
+        }
+
         g_debug ("GdmWelcomeSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d",
                  pwent->pw_uid,
                  welcome_session->priv->x11_display_name,
@@ -183,6 +201,8 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
                                                          "unix-user", &pwent->pw_uid,
                                                          "session-type", &session_type,
                                                          "x11-display", &welcome_session->priv->x11_display_name,
+                                                         "seat-id", &seat_id,
+                                                         "session", &session_id,
                                                          "x11-display-device", &x11_display_device,
                                                          "remote-host-name", &hostname,
                                                          "is-local", &welcome_session->priv->x11_display_is_local,
@@ -1007,6 +1027,22 @@ _gdm_welcome_session_set_x11_display_name (GdmWelcomeSession *welcome_session,
 }
 
 static void
+_gdm_welcome_session_set_x11_display_seat_id (GdmWelcomeSession *welcome_session,
+                                              const char        *sid)
+{
+        g_free (welcome_session->priv->x11_display_seat_id);
+        welcome_session->priv->x11_display_seat_id = g_strdup (sid);
+}
+
+static void
+_gdm_welcome_session_set_x11_display_session_id (GdmWelcomeSession *welcome_session,
+                                                 const char        *ssid)
+{
+        g_free (welcome_session->priv->x11_display_session_id);
+        welcome_session->priv->x11_display_session_id = g_strdup (ssid);
+}
+
+static void
 _gdm_welcome_session_set_x11_display_hostname (GdmWelcomeSession *welcome_session,
                                                const char        *name)
 {
@@ -1029,7 +1065,6 @@ _gdm_welcome_session_set_x11_display_is_local (GdmWelcomeSession *welcome_sessio
         welcome_session->priv->x11_display_is_local = is_local;
 }
 
-
 static void
 _gdm_welcome_session_set_x11_authority_file (GdmWelcomeSession *welcome_session,
                                              const char        *file)
@@ -1115,6 +1150,12 @@ gdm_welcome_session_set_property (GObject      *object,
         case PROP_X11_DISPLAY_NAME:
                 _gdm_welcome_session_set_x11_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_X11_DISPLAY_SEAT_ID:
+                _gdm_welcome_session_set_x11_display_seat_id (self, g_value_get_string (value));
+                break;
+        case PROP_X11_DISPLAY_SESSION_ID:
+                _gdm_welcome_session_set_x11_display_session_id (self, g_value_get_string (value));
+                break;
         case PROP_X11_DISPLAY_HOSTNAME:
                 _gdm_welcome_session_set_x11_display_hostname (self, g_value_get_string (value));
                 break;
@@ -1174,6 +1215,12 @@ gdm_welcome_session_get_property (GObject    *object,
         case PROP_X11_DISPLAY_NAME:
                 g_value_set_string (value, self->priv->x11_display_name);
                 break;
+        case PROP_X11_DISPLAY_SEAT_ID:
+                g_value_set_string (value, self->priv->x11_display_seat_id);
+                break;
+        case PROP_X11_DISPLAY_SESSION_ID:
+                g_value_set_string (value, self->priv->x11_display_session_id);
+                break;
         case PROP_X11_DISPLAY_HOSTNAME:
                 g_value_set_string (value, self->priv->x11_display_hostname);
                 break;
@@ -1253,6 +1300,20 @@ gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_SEAT_ID,
+                                         g_param_spec_string ("x11-display-seat-id",
+                                                              "seat id",
+                                                              "seat id",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_SESSION_ID,
+                                         g_param_spec_string ("x11-display-session-id",
+                                                              "session id",
+                                                              "session id",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
                                          PROP_X11_DISPLAY_HOSTNAME,
                                          g_param_spec_string ("x11-display-hostname",
                                                               "hostname",
@@ -1421,6 +1482,8 @@ gdm_welcome_session_finalize (GObject *object)
         g_free (welcome_session->priv->group_name);
         g_free (welcome_session->priv->runtime_dir);
         g_free (welcome_session->priv->x11_display_name);
+        g_free (welcome_session->priv->x11_display_session_id);
+        g_free (welcome_session->priv->x11_display_seat_id);
         g_free (welcome_session->priv->x11_display_device);
         g_free (welcome_session->priv->x11_display_hostname);
         g_free (welcome_session->priv->x11_authority_file);
diff --git a/daemon/gdm-xdmcp-chooser-display.c b/daemon/gdm-xdmcp-chooser-display.c
index 85bd3b7..f7b5a0b 100644
--- a/daemon/gdm-xdmcp-chooser-display.c
+++ b/daemon/gdm-xdmcp-chooser-display.c
@@ -224,7 +224,7 @@ gdm_xdmcp_chooser_display_new (const char              *hostname,
                                "remote-hostname", hostname,
                                "x11-display-number", number,
                                "x11-display-name", x11_display,
-                               "is-local", FALSE,
+                               "is-local", TRUE,
                                "remote-address", address,
                                "session-number", session_number,
                                NULL);
diff --git a/daemon/main.c b/daemon/main.c
index ddc4ca3..d702958 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -215,7 +215,19 @@ bus_proxy_destroyed_cb (DBusGProxy  *bus_proxy,
         g_object_unref (*managerp);
         *managerp = NULL;
 
+#if __sun
+        /*
+         * This function is only called when the D-Bus Service exits.  Calling
+         * this timeout function causes all GDM sessions to exit anyway.  The
+         * timeout function just cauess GDM to act like it is starting again.
+         * Since SMF already takes care of restarting GDM on Solaris, and since
+         * using the timeout confuses SMF, just exit and let SMF take care of
+         * this.
+         */
+        exit (-1);
+#else
         g_timeout_add_seconds (3, (GSourceFunc)bus_reconnect, managerp);
+#endif
 }
 
 static void
diff --git a/daemon/simple-slave-main.c b/daemon/simple-slave-main.c
index eed1742..657cfca 100644
--- a/daemon/simple-slave-main.c
+++ b/daemon/simple-slave-main.c
@@ -154,6 +154,15 @@ on_slave_stopped (GdmSlave   *slave,
         g_main_loop_quit (main_loop);
 }
 
+static void
+on_slave_failed (GdmSlave   *slave,
+                 GMainLoop  *main_loop)
+{
+        g_debug ("slave failed");
+        gdm_return_code = 1;
+        g_main_loop_quit (main_loop);
+}
+
 static gboolean
 is_debug_set (void)
 {
@@ -256,6 +265,10 @@ main (int    argc,
                           "stopped",
                           G_CALLBACK (on_slave_stopped),
                           main_loop);
+        g_signal_connect (slave,
+                          "failed",
+                          G_CALLBACK (on_slave_failed),
+                          main_loop);
         gdm_slave_start (slave);
 
         g_main_loop_run (main_loop);
diff --git a/data/Init.in b/data/Init.in
index dca63a2..f2d4c0a 100644
--- a/data/Init.in
+++ b/data/Init.in
@@ -3,7 +3,7 @@
 # Plus a lot of fun stuff added
 #  -George
 
-PATH="@X_PATH@:$PATH"
+PATH="@SCRIPT_PATH@"
 OLD_IFS=$IFS
 
 gdmwhich () {
diff --git a/data/Makefile.am b/data/Makefile.am
index 2bee3ee..b3be69c 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -21,17 +21,6 @@ Xsession: $(srcdir)/Xsession.in
 		-e 's,[ ]libexecdir[@],$(libexecdir),g' \
 		<$(srcdir)/Xsession.in >Xsession
 
-Init: $(srcdir)/Init.in
-	sed	-e 's,[ ]X_PATH[@],$(X_PATH),g' \
-		<$(srcdir)/Init.in >Init
-
-PreSession: $(srcdir)/PreSession.in
-	sed	-e 's,[ ]X_PATH[@],$(X_PATH),g' \
-		<$(srcdir)/PreSession.in >PreSession
-PostSession: $(srcdir)/PostSession.in
-	sed	-e 's,[ ]X_PATH[@],$(X_PATH),g' \
-		<$(srcdir)/PostSession.in >PostSession
-
 gdm.conf-custom: $(srcdir)/gdm.conf-custom.in
 	sed	-e 's,[ ]GDM_DEFAULTS_CONF[@],$(GDM_DEFAULTS_CONF),g' \
 		<$(srcdir)/gdm.conf-custom.in >gdm.conf-custom
diff --git a/data/PostSession.in b/data/PostSession.in
index c52d3c2..54276fd 100755
--- a/data/PostSession.in
+++ b/data/PostSession.in
@@ -1,3 +1,4 @@
 #!/bin/sh
+PATH="@SCRIPT_PATH@"
 
 exit 0
diff --git a/data/PreSession.in b/data/PreSession.in
index cfabee7..09ad05b 100755
--- a/data/PreSession.in
+++ b/data/PreSession.in
@@ -6,4 +6,4 @@
 #
 # Note that output goes into the .xsession-errors file for easy debugging
 #
-PATH="@X_PATH@:$PATH"
+PATH="@SCRIPT_PATH@"
diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in
index 514117d..8c551ce 100644
--- a/data/gdm.schemas.in.in
+++ b/data/gdm.schemas.in.in
@@ -55,12 +55,6 @@
     </schema>
 
     <schema>
-      <key>security/DisallowTCP</key>
-      <signature>b</signature>
-      <default>true</default>
-    </schema>
-
-    <schema>
       <key>greeter/Include</key>
       <signature>s</signature>
       <default></default>
diff --git a/docs/C/gdm.xml b/docs/C/gdm.xml
index c510301..9420051 100644
--- a/docs/C/gdm.xml
+++ b/docs/C/gdm.xml
@@ -1361,18 +1361,6 @@ TimedLogin=you
         <variablelist>
           <title>[security]</title>
           
-          <varlistentry>
-            <term>DisallowTCP</term>
-            <listitem>
-              <synopsis>DisallowTCP=true</synopsis>
-              <para>
-                If true, then always append <filename>-nolisten tcp</filename>
-                to the command line when starting attached Xservers, thus
-                disallowing TCP connection.  This is a more secure
-                configuration if you are not using remote connections.
-              </para>
-            </listitem>
-          </varlistentry>
         </variablelist>
       </sect3>
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]