[gdm/multi-stack: 6/45] Propagate service name to more layers



commit f7108150aeab14a890652f8f0d24be3ef6bc9647
Author: Ray Strode <rstrode redhat com>
Date:   Thu Jan 22 08:52:01 2009 -0500

    Propagate service name to more layers
    
    This is more prep work to get multiple concurrent
    PAM stacks going.

 daemon/gdm-factory-slave.c               |   69 +++--
 daemon/gdm-greeter-server.c              |  120 ++++++--
 daemon/gdm-greeter-server.h              |   17 +-
 daemon/gdm-product-slave.c               |  246 ++++++++++++---
 daemon/gdm-session-direct.c              |  498 +++++++++++++++++------------
 daemon/gdm-session-private.h             |   26 ++-
 daemon/gdm-session-relay.c               |  135 +++++++--
 daemon/gdm-session-worker.c              |   27 ++
 daemon/gdm-session.c                     |  175 ++++++-----
 daemon/gdm-session.h                     |   54 +++-
 daemon/gdm-simple-slave.c                |   78 ++++--
 daemon/test-session.c                    |   22 +-
 gui/simple-greeter/gdm-greeter-client.c  |  188 +++++++++---
 gui/simple-greeter/gdm-greeter-client.h  |   16 +-
 gui/simple-greeter/gdm-greeter-session.c |   11 +-
 15 files changed, 1191 insertions(+), 491 deletions(-)
---
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
index ca3ba48..553ae3a 100644
--- a/daemon/gdm-factory-slave.c
+++ b/daemon/gdm-factory-slave.c
@@ -144,45 +144,49 @@ on_greeter_session_died (GdmGreeterSession    *greeter,
 
 static void
 on_session_info (GdmSession      *session,
+                 const char      *service_name,
                  const char      *text,
                  GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: Info: %s", text);
-        gdm_greeter_server_info (slave->priv->greeter_server, text);
+        gdm_greeter_server_info (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_problem (GdmSession      *session,
+                    const char      *service_name,
                     const char      *text,
                     GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: Problem: %s", text);
-        gdm_greeter_server_problem (slave->priv->greeter_server, text);
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_info_query (GdmSession      *session,
+                       const char      *service_name,
                        const char      *text,
                        GdmFactorySlave *slave)
 {
 
         g_debug ("GdmFactorySlave: Info query: %s", text);
-        gdm_greeter_server_info_query (slave->priv->greeter_server, text);
+        gdm_greeter_server_info_query (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_secret_info_query (GdmSession      *session,
+                              const char      *service_name,
                               const char      *text,
                               GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: Secret info query: %s", text);
-        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
+        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_conversation_started (GdmSession      *session,
-                                 GdmFactorySlave *slave,
-                                 const char      *service_name)
+                                 const char      *service_name,
+                                 GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: session conversation started");
 
@@ -192,17 +196,19 @@ on_session_conversation_started (GdmSession      *session,
 
 static void
 on_session_setup_complete (GdmSession      *session,
+                           const char      *service_name,
                            GdmFactorySlave *slave)
 {
-        gdm_session_authenticate (session);
+        gdm_session_authenticate (session, service_name);
 }
 
 static void
 on_session_setup_failed (GdmSession      *session,
+                         const char      *service_name,
                          const char      *message,
                          GdmFactorySlave *slave)
 {
-        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to initialize login system"));
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to initialize login system"));
 
         queue_greeter_reset (slave);
 }
@@ -224,23 +230,26 @@ on_session_reset_failed (GdmSession      *session,
 
 static void
 on_session_authenticated (GdmSession      *session,
+                          const char      *service_name,
                           GdmFactorySlave *slave)
 {
-        gdm_session_authorize (session);
+        gdm_session_authorize (session, service_name);
 }
 
 static void
 on_session_authentication_failed (GdmSession      *session,
+                                  const char      *service_name,
                                   const char      *message,
                                   GdmFactorySlave *slave)
 {
-        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authenticate user"));
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to authenticate user"));
 
         queue_greeter_reset (slave);
 }
 
 static void
 on_session_authorized (GdmSession      *session,
+                       const char      *service_name,
                        GdmFactorySlave *slave)
 {
         int flag;
@@ -248,60 +257,65 @@ on_session_authorized (GdmSession      *session,
         /* FIXME: check for migration? */
         flag = GDM_SESSION_CRED_ESTABLISH;
 
-        gdm_session_accredit (session, flag);
+        gdm_session_accredit (session, service_name, flag);
 }
 
 static void
 on_session_authorization_failed (GdmSession      *session,
+                                 const char      *service_name,
                                  const char      *message,
                                  GdmFactorySlave *slave)
 {
-        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authorize user"));
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to authorize user"));
 
         queue_greeter_reset (slave);
 }
 
 static void
 on_session_accredited (GdmSession      *session,
+                       const char      *service_name,
                        GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave:  session user verified");
 
-        gdm_session_open_session (session);
+        gdm_session_open_session (session, service_name);
 }
 
 static void
 on_session_accreditation_failed (GdmSession      *session,
+                                 const char      *service_name,
                                  const char      *message,
                                  GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: could not successfully authenticate user: %s",
                  message);
 
-        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to establish credentials"));
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to establish credentials"));
 
         queue_greeter_reset (slave);
 }
 
 static void
 on_session_opened (GdmSession      *session,
+                   const char      *service_name,
                    GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: session opened");
 
-        gdm_session_start_session (session);
+        gdm_session_start_session (session, service_name);
 
         gdm_greeter_server_reset (slave->priv->greeter_server);
 }
 
 static void
 on_session_open_failed (GdmSession      *session,
+                        const char      *service_name,
                         const char      *message,
                         GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: could not open session: %s", message);
 
-        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to open session"));
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to open session"));
 
         queue_greeter_reset (slave);
 }
@@ -389,37 +403,48 @@ on_session_relay_connected (GdmSessionRelay *session,
                             GdmFactorySlave *slave)
 {
         g_debug ("GdmFactorySlave: Relay Connected");
+}
+
+static void
+on_greeter_start_conversation (GdmGreeterServer *greeter_server,
+                               const char       *service_name,
+                               GdmFactorySlave  *slave)
+{
+        g_debug ("GdmFactorySlave: start conversation");
 
-        gdm_session_start_conversation (GDM_SESSION (slave->priv->session), "gdm");
+        gdm_session_start_conversation (GDM_SESSION (slave->priv->session), service_name);
 }
 
 static void
 on_greeter_begin_verification (GdmGreeterServer *greeter_server,
+                               const char       *service_name,
                                GdmFactorySlave  *slave)
 {
         g_debug ("GdmFactorySlave: begin verification");
         gdm_session_setup (GDM_SESSION (slave->priv->session),
-                           "gdm");
+                           service_name);
 }
 
 static void
 on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
+                                        const char       *service_name,
                                         const char       *username,
                                         GdmFactorySlave  *slave)
 {
         g_debug ("GdmFactorySlave: begin verification for user");
         gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
-                                    "gdm",
+                                    service_name,
                                     username);
 }
 
 static void
 on_greeter_answer (GdmGreeterServer *greeter_server,
+                   const char       *service_name,
                    const char       *text,
                    GdmFactorySlave  *slave)
 {
         g_debug ("GdmFactorySlave: Greeter answer");
-        gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
+        gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
 }
 
 static void
@@ -516,6 +541,10 @@ run_greeter (GdmFactorySlave *slave)
 
         slave->priv->greeter_server = gdm_greeter_server_new (display_id);
         g_signal_connect (slave->priv->greeter_server,
+                          "start-conversation",
+                          G_CALLBACK (on_greeter_start_conversation),
+                          slave);
+        g_signal_connect (slave->priv->greeter_server,
                           "begin-verification",
                           G_CALLBACK (on_greeter_begin_verification),
                           slave);
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
index ffca7ec..dae34c5 100644
--- a/daemon/gdm-greeter-server.c
+++ b/daemon/gdm-greeter-server.c
@@ -43,6 +43,7 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#include "gdm-marshal.h"
 #include "gdm-greeter-server.h"
 
 #define GDM_GREETER_SERVER_DBUS_PATH      "/org/gnome/DisplayManager/GreeterServer"
@@ -156,6 +157,46 @@ send_dbus_string_and_int_signal (GdmGreeterServer *greeter_server,
 }
 
 static void
+send_dbus_string_string_signal (GdmGreeterServer *greeter_server,
+                                const char       *name,
+                                const char       *text1,
+                                const char       *text2)
+{
+        DBusMessage    *message;
+        DBusMessageIter iter;
+        const char     *str;
+
+        g_return_if_fail (greeter_server != NULL);
+
+        message = dbus_message_new_signal (GDM_GREETER_SERVER_DBUS_PATH,
+                                           GDM_GREETER_SERVER_DBUS_INTERFACE,
+                                           name);
+
+        dbus_message_iter_init_append (message, &iter);
+
+        if (text1 != NULL) {
+                str = text1;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str);
+
+        if (text2 != NULL) {
+                str = text2;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str);
+
+        g_debug ("GreeterServer: Sending %s (%s)", name, str);
+        if (! send_dbus_message (greeter_server->priv->greeter_connection, message)) {
+                g_debug ("GreeterServer: Could not send %s signal", name);
+        }
+
+        dbus_message_unref (message);
+}
+
+static void
 send_dbus_string_signal (GdmGreeterServer *greeter_server,
                          const char       *name,
                          const char       *text)
@@ -208,34 +249,38 @@ send_dbus_void_signal (GdmGreeterServer *greeter_server,
 
 gboolean
 gdm_greeter_server_info_query (GdmGreeterServer *greeter_server,
+                               const char       *service_name,
                                const char       *text)
 {
-        send_dbus_string_signal (greeter_server, "InfoQuery", text);
+        send_dbus_string_string_signal (greeter_server, "InfoQuery", service_name, text);
 
         return TRUE;
 }
 
 gboolean
 gdm_greeter_server_secret_info_query (GdmGreeterServer *greeter_server,
+                                      const char       *service_name,
                                       const char       *text)
 {
-        send_dbus_string_signal (greeter_server, "SecretInfoQuery", text);
+        send_dbus_string_string_signal (greeter_server, "SecretInfoQuery", service_name, text);
         return TRUE;
 }
 
 gboolean
 gdm_greeter_server_info (GdmGreeterServer *greeter_server,
+                         const char       *service_name,
                          const char       *text)
 {
-        send_dbus_string_signal (greeter_server, "Info", text);
+        send_dbus_string_string_signal (greeter_server, "Info", service_name, text);
         return TRUE;
 }
 
 gboolean
 gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
+                            const char       *service_name,
                             const char       *text)
 {
-        send_dbus_string_signal (greeter_server, "Problem", text);
+        send_dbus_string_string_signal (greeter_server, "Problem", service_name, text);
         return TRUE;
 }
 
@@ -291,9 +336,10 @@ gdm_greeter_server_request_timed_login (GdmGreeterServer *greeter_server,
 }
 
 void
-gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server)
+gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server,
+                                    const char       *service_name)
 {
-        send_dbus_void_signal (greeter_server, "UserAuthorized");
+        send_dbus_string_signal (greeter_server, "UserAuthorized", service_name);
 }
 
 /* Note: Use abstract sockets like dbus does by default on Linux. Abstract
@@ -358,6 +404,16 @@ handle_begin_verification (GdmGreeterServer *greeter_server,
                            DBusMessage      *message)
 {
         DBusMessage *reply;
+        DBusError    error;
+        const char  *service_name;
+
+        dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GreeterServer: BeginVerification");
 
@@ -365,7 +421,7 @@ handle_begin_verification (GdmGreeterServer *greeter_server,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION], 0);
+        g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION], 0, service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -379,7 +435,6 @@ handle_begin_auto_login (GdmGreeterServer *greeter_server,
         DBusError    error;
         const char  *text;
 
-
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
                                      DBUS_TYPE_STRING, &text,
@@ -406,13 +461,16 @@ handle_begin_verification_for_user (GdmGreeterServer *greeter_server,
         DBusMessage *reply;
         DBusError    error;
         const char  *text;
+        const char  *service_name;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
         }
+        dbus_error_free (&error);
 
         g_debug ("GreeterServer: BeginVerificationForUser for '%s'", text);
 
@@ -420,7 +478,7 @@ handle_begin_verification_for_user (GdmGreeterServer *greeter_server,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION_FOR_USER], 0, text);
+        g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION_FOR_USER], 0, service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -433,13 +491,16 @@ handle_answer_query (GdmGreeterServer *greeter_server,
         DBusMessage *reply;
         DBusError    error;
         const char  *text;
+        const char  *service_name;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
         }
+        dbus_error_free (&error);
 
         g_debug ("GreeterServer: AnswerQuery");
 
@@ -447,7 +508,7 @@ handle_answer_query (GdmGreeterServer *greeter_server,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        g_signal_emit (greeter_server, signals [QUERY_ANSWER], 0, text);
+        g_signal_emit (greeter_server, signals [QUERY_ANSWER], 0, service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -644,9 +705,11 @@ handle_start_session_when_ready (GdmGreeterServer *greeter_server,
         DBusMessage *reply;
         DBusError    error;
         gboolean     should_start_session;
+        char        *service_name;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_BOOLEAN, &should_start_session,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -660,9 +723,9 @@ handle_start_session_when_ready (GdmGreeterServer *greeter_server,
         dbus_message_unref (reply);
 
         if (should_start_session) {
-                g_signal_emit (greeter_server, signals [START_SESSION_WHEN_READY], 0);
+                g_signal_emit (greeter_server, signals [START_SESSION_WHEN_READY], 0, service_name);
         } else {
-                g_signal_emit (greeter_server, signals [START_SESSION_LATER] ,0);
+                g_signal_emit (greeter_server, signals [START_SESSION_LATER] ,0, service_name);
         }
 
         return DBUS_HANDLER_RESULT_HANDLED;
@@ -735,13 +798,16 @@ do_introspect (DBusConnection *connection,
                                "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "    </method>\n"
                                "    <method name=\"BeginVerification\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "    </method>\n"
                                "    <method name=\"BeginTimedLogin\">\n"
                                "    </method>\n"
                                "    <method name=\"BeginVerificationForUser\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"username\" direction=\"in\" type=\"s\"/>\n"
                                "    </method>\n"
                                "    <method name=\"AnswerQuery\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"text\" direction=\"in\" type=\"s\"/>\n"
                                "    </method>\n"
                                "    <method name=\"SelectSession\">\n"
@@ -764,18 +830,23 @@ do_introspect (DBusConnection *connection,
                                "      <arg name=\"id\" direction=\"out\" type=\"o\"/>\n"
                                "    </method>\n"
                                "    <method name=\"StartSessionWhenReady\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"should_start_session\" type=\"b\"/>\n"
                                "    </method>\n"
                                "    <signal name=\"Info\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
                                "    <signal name=\"Problem\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
                                "    <signal name=\"InfoQuery\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
                                "    <signal name=\"SecretInfoQuery\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
                                "    <signal name=\"SelectedUserChanged\">\n"
@@ -800,6 +871,7 @@ do_introspect (DBusConnection *connection,
                                "    <signal name=\"Reset\">\n"
                                "    </signal>\n"
                                "    <signal name=\"UserAuthorized\">\n"
+                               "      <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
                                "    </signal>\n"
                                "  </interface>\n");
 
@@ -1175,9 +1247,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterServerClass, begin_verification),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [BEGIN_AUTO_LOGIN] =
                 g_signal_new ("begin-auto-login",
                               G_OBJECT_CLASS_TYPE (object_class),
@@ -1196,10 +1268,10 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterServerClass, begin_verification_for_user),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [QUERY_ANSWER] =
                 g_signal_new ("query-answer",
                               G_OBJECT_CLASS_TYPE (object_class),
@@ -1207,10 +1279,10 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterServerClass, query_answer),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [SESSION_SELECTED] =
                 g_signal_new ("session-selected",
                               G_OBJECT_CLASS_TYPE (object_class),
@@ -1304,9 +1376,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterServerClass, start_session_when_ready),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
 
         signals [START_SESSION_LATER] =
                 g_signal_new ("start-session-later",
@@ -1315,9 +1387,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterServerClass, start_session_later),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
 }
 
 static void
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
index 7333db1..6d0dd87 100644
--- a/daemon/gdm-greeter-server.h
+++ b/daemon/gdm-greeter-server.h
@@ -48,10 +48,13 @@ typedef struct
         void (* start_conversation)         (GdmGreeterServer  *greeter_server,
                                              const char        *service_name);
         void (* begin_auto_login)           (GdmGreeterServer  *greeter_server);
-        void (* begin_verification)         (GdmGreeterServer  *greeter_server);
+        void (* begin_verification)         (GdmGreeterServer  *greeter_server,
+                                             const char        *service_name);
         void (* begin_verification_for_user)(GdmGreeterServer  *greeter_server,
+                                             const char        *service_name,
                                              const char        *username);
         void (* query_answer)               (GdmGreeterServer  *greeter_server,
+                                             const char        *service_name,
                                              const char        *text);
         void (* session_selected)           (GdmGreeterServer  *greeter_server,
                                              const char        *name);
@@ -66,7 +69,8 @@ typedef struct
         void (* cancelled)                  (GdmGreeterServer  *greeter_server);
         void (* connected)                  (GdmGreeterServer  *greeter_server);
         void (* disconnected)               (GdmGreeterServer  *greeter_server);
-        void (* start_session_when_ready)   (GdmGreeterServer  *greeter_server);
+        void (* start_session_when_ready)   (GdmGreeterServer  *greeter_server,
+                                             const char        *service_name);
         void (* start_session_later)        (GdmGreeterServer  *greeter_server);
 } GdmGreeterServerClass;
 
@@ -77,14 +81,17 @@ gboolean            gdm_greeter_server_start                 (GdmGreeterServer *
 gboolean            gdm_greeter_server_stop                  (GdmGreeterServer *greeter_server);
 char *              gdm_greeter_server_get_address           (GdmGreeterServer *greeter_server);
 
-
 gboolean            gdm_greeter_server_info_query            (GdmGreeterServer *greeter_server,
+                                                              const char       *service_name,
                                                               const char       *text);
 gboolean            gdm_greeter_server_secret_info_query     (GdmGreeterServer *greeter_server,
+                                                              const char       *service_name,
                                                               const char       *text);
 gboolean            gdm_greeter_server_info                  (GdmGreeterServer *greeter_server,
+                                                              const char       *service_name,
                                                               const char       *text);
 gboolean            gdm_greeter_server_problem               (GdmGreeterServer *greeter_server,
+                                                              const char       *service_name,
                                                               const char       *text);
 gboolean            gdm_greeter_server_reset                 (GdmGreeterServer *greeter_server);
 gboolean            gdm_greeter_server_ready                 (GdmGreeterServer *greeter_server,
@@ -101,8 +108,8 @@ void                gdm_greeter_server_default_session_name_changed (GdmGreeterS
 void                gdm_greeter_server_request_timed_login   (GdmGreeterServer *greeter_server,
                                                               const char       *username,
                                                               int               delay);
-void                gdm_greeter_server_user_authorized       (GdmGreeterServer *greeter_server);
-
+void                gdm_greeter_server_user_authorized       (GdmGreeterServer *greeter_server,
+                                                              const char       *service_name);
 
 G_END_DECLS
 
diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
index ec6300d..93d83a1 100644
--- a/daemon/gdm-product-slave.c
+++ b/daemon/gdm-product-slave.c
@@ -79,6 +79,8 @@ struct GdmProductSlavePrivate
 
         DBusGProxy       *product_display_proxy;
         DBusGConnection  *connection;
+
+        char             *start_session_service_name;
 };
 
 enum {
@@ -93,6 +95,68 @@ static void     gdm_product_slave_finalize      (GObject             *object);
 G_DEFINE_TYPE (GdmProductSlave, gdm_product_slave, GDM_TYPE_SLAVE)
 
 static gboolean
+send_dbus_string_string_method (DBusConnection *connection,
+                                const char     *method,
+                                const char     *payload1,
+                                const char     *payload2)
+{
+        DBusError       error;
+        DBusMessage    *message;
+        DBusMessage    *reply;
+        DBusMessageIter iter;
+        const char     *str;
+
+        g_debug ("GdmProductSlave: Calling %s", method);
+        message = dbus_message_new_method_call (NULL,
+                                                RELAY_SERVER_DBUS_PATH,
+                                                RELAY_SERVER_DBUS_INTERFACE,
+                                                method);
+        if (message == NULL) {
+                g_warning ("Couldn't allocate the D-Bus message");
+                return FALSE;
+        }
+
+        dbus_message_iter_init_append (message, &iter);
+
+        if (payload1 != NULL) {
+                str = payload1;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter,
+                                        DBUS_TYPE_STRING,
+                                        &str);
+        if (payload2 != NULL) {
+                str = payload2;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter,
+                                        DBUS_TYPE_STRING,
+                                        &str);
+        dbus_error_init (&error);
+        reply = dbus_connection_send_with_reply_and_block (connection,
+                                                           message,
+                                                           -1,
+                                                           &error);
+
+        dbus_message_unref (message);
+
+        if (dbus_error_is_set (&error)) {
+                g_warning ("%s %s raised: %s\n",
+                           method,
+                           error.name,
+                           error.message);
+                return FALSE;
+        }
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+        dbus_connection_flush (connection);
+
+        return TRUE;
+}
+static gboolean
 send_dbus_string_method (DBusConnection *connection,
                          const char     *method,
                          const char     *payload)
@@ -356,7 +420,8 @@ setup_session (GdmProductSlave *slave)
         g_free (display_device);
         g_free (auth_file);
 
-        gdm_session_start_session (GDM_SESSION (slave->priv->session));
+        gdm_session_start_session (GDM_SESSION (slave->priv->session),
+                                   slave->priv->start_session_service_name);
 
         return TRUE;
 }
@@ -508,114 +573,133 @@ on_session_reset_failed (GdmSession      *session,
 
 static void
 on_session_authenticated (GdmSession      *session,
+                          const char      *service_name,
                           GdmProductSlave *slave)
 {
-        send_dbus_void_method (slave->priv->session_relay_connection,
-                               "Authenticated");
+        send_dbus_string_method (slave->priv->session_relay_connection,
+                                 "Authenticated", service_name);
 }
 
 static void
 on_session_authentication_failed (GdmSession      *session,
+                                  const char      *service_name,
                                   const char      *message,
                                   GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "AuthenticationFailed",
-                                 message);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "AuthenticationFailed",
+                                        service_name,
+                                        message);
 }
 
 static void
 on_session_authorized (GdmSession      *session,
+                       const char      *service_name,
                        GdmProductSlave *slave)
 {
-        send_dbus_void_method (slave->priv->session_relay_connection,
-                               "Authorized");
+        send_dbus_string_method (slave->priv->session_relay_connection,
+                                 "Authorized", service_name);
 }
 
 static void
 on_session_authorization_failed (GdmSession      *session,
+                                 const char      *service_name,
                                  const char      *message,
                                  GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "AuthorizationFailed",
-                                 message);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "AuthorizationFailed",
+                                        service_name,
+                                        message);
 }
 
 static void
 on_session_accredited (GdmSession      *session,
+                       const char      *service_name,
                        GdmProductSlave *slave)
 {
-        send_dbus_void_method (slave->priv->session_relay_connection,
-                               "Accredited");
+        send_dbus_string_method (slave->priv->session_relay_connection,
+                                 "Accredited", service_name);
 }
 
 static void
 on_session_accreditation_failed (GdmSession      *session,
+                                 const char      *service_name,
                                  const char      *message,
                                  GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "AccreditationFailed",
-                                 message);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "AccreditationFailed",
+                                        service_name,
+                                        message);
 }
 
 static void
 on_session_opened (GdmSession      *session,
+                   const char      *service_name,
                    GdmProductSlave *slave)
 {
-        send_dbus_void_method (slave->priv->session_relay_connection,
-                               "SessionOpened");
+        send_dbus_string_method (slave->priv->session_relay_connection,
+                                 "SessionOpened", service_name);
 }
 
 static void
 on_session_open_failed (GdmSession      *session,
+                        const char      *service_name,
                         const char      *message,
                         GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "SessionOpenFailed",
-                                 message);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "SessionOpenFailed",
+                                        service_name,
+                                        message);
 }
 
 static void
 on_session_info (GdmSession      *session,
+                 const char      *service_name,
                  const char      *text,
                  GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "Info",
-                                 text);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "Info",
+                                        service_name,
+                                        text);
 }
 
 static void
 on_session_problem (GdmSession      *session,
+                    const char      *service_name,
                     const char      *text,
                     GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "Problem",
-                                 text);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "Problem",
+                                        service_name,
+                                        text);
 }
 
 static void
 on_session_info_query (GdmSession      *session,
+                       const char      *service_name,
                        const char      *text,
                        GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "InfoQuery",
-                                 text);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "InfoQuery",
+                                        service_name, text);
 }
 
 static void
 on_session_secret_info_query (GdmSession      *session,
+                              const char      *service_name,
                               const char      *text,
                               GdmProductSlave *slave)
 {
-        send_dbus_string_method (slave->priv->session_relay_connection,
-                                 "SecretInfoQuery",
-                                 text);
+        send_dbus_string_string_method (slave->priv->session_relay_connection,
+                                        "SecretInfoQuery",
+                                        service_name,
+                                        text);
 }
 
 static void
@@ -676,36 +760,92 @@ static void
 on_relay_authenticate (GdmProductSlave *slave,
                        DBusMessage     *message)
 {
-        g_debug ("GdmProductSlave: Relay Authenticate");
+        DBusError   error;
+        char *service_name;
+        dbus_bool_t res;
 
-        gdm_session_authenticate (GDM_SESSION (slave->priv->session));
+        dbus_error_init (&error);
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+                g_debug ("GdmProductSlave: Relay Authenticate");
+                gdm_session_authenticate (GDM_SESSION (slave->priv->session), service_name);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
+        dbus_error_free (&error);
 }
 
 static void
 on_relay_authorize (GdmProductSlave *slave,
                     DBusMessage     *message)
 {
-        g_debug ("GdmProductSlave: Relay Authorize");
+        DBusError   error;
+        char *service_name;
+        dbus_bool_t res;
 
-        gdm_session_authorize (GDM_SESSION (slave->priv->session));
+        dbus_error_init (&error);
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+                g_debug ("GdmProductSlave: Relay Authorize");
+                gdm_session_authorize (GDM_SESSION (slave->priv->session), service_name);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
+        dbus_error_free (&error);
 }
 
 static void
 on_relay_establish_credentials (GdmProductSlave *slave,
                                 DBusMessage     *message)
 {
-        g_debug ("GdmProductSlave: Relay EstablishCredentials");
+        DBusError   error;
+        char *service_name;
+        dbus_bool_t res;
 
-        gdm_session_accredit (GDM_SESSION (slave->priv->session), GDM_SESSION_CRED_ESTABLISH);
+        dbus_error_init (&error);
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+                g_debug ("GdmProductSlave: Relay EstablishCredentials");
+                gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, GDM_SESSION_CRED_ESTABLISH);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
+        dbus_error_free (&error);
 }
 
 static void
 on_relay_refresh_credentials (GdmProductSlave *slave,
                               DBusMessage     *message)
 {
-        g_debug ("GdmProductSlave: Relay RefreshCredentials");
+        DBusError   error;
+        char *service_name;
+        dbus_bool_t res;
 
-        gdm_session_accredit (GDM_SESSION (slave->priv->session), GDM_SESSION_CRED_REFRESH);
+        dbus_error_init (&error);
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+                g_debug ("GdmProductSlave: Relay RefreshCredentials");
+                gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, GDM_SESSION_CRED_REFRESH);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
+        dbus_error_free (&error);
 }
 
 static void
@@ -714,16 +854,18 @@ on_relay_answer_query (GdmProductSlave *slave,
 {
         DBusError   error;
         const char *text;
+        const char *service_name;
         dbus_bool_t res;
 
         dbus_error_init (&error);
         res = dbus_message_get_args (message,
                                      &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID);
         if (res) {
                 g_debug ("GdmProductSlave: Relay AnswerQuery");
-                gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
+                gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
         } else {
                 g_warning ("Unable to get arguments: %s", error.message);
                 dbus_error_free (&error);
@@ -831,7 +973,25 @@ static void
 on_relay_start_session (GdmProductSlave *slave,
                         DBusMessage     *message)
 {
-        gdm_product_slave_create_server (slave);
+        DBusError   error;
+        const char *service_name;
+        dbus_bool_t res;
+
+        dbus_error_init (&error);
+
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+                g_debug ("GdmProductSlave: Relay StartSession");
+                g_free (slave->priv->start_session_service_name);
+                slave->priv->start_session_service_name = g_strdup (service_name);
+                gdm_product_slave_create_server (slave);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
 }
 
 static void
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 8171b4e..9d6a6b9 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -88,10 +88,10 @@ struct _GdmSessionDirectPrivate
         char                *selected_user;
         char                *user_x11_authority_file;
 
-        GdmSessionConversation *conversation;
         GHashTable          *conversations;
 
-        GdmSessionWorkerJob *job;
+        GList               *pending_connections;
+
         GPid                 session_pid;
         guint32              is_running : 1;
 
@@ -198,14 +198,30 @@ send_dbus_void_signal (GdmSessionConversation *conversation,
         dbus_message_unref (message);
 }
 
+static GdmSessionConversation *
+find_conversation_by_name (GdmSessionDirect *session,
+                           const char       *service_name)
+{
+        GdmSessionConversation *conversation;
+
+        conversation = g_hash_table_lookup (session->priv->conversations, service_name);
+
+        if (conversation == NULL) {
+                g_warning ("Tried to look up non-existant conversation");
+        }
+
+        return conversation;
+}
+
 static void
 on_authentication_failed (GdmSession *session,
+                          const char *service_name,
                           const char *message)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
-        conversation = impl->priv->conversation;
+        conversation = find_conversation_by_name (impl, service_name);
         if (conversation != NULL) {
                 gdm_session_record_failed (conversation->worker_pid,
                                            impl->priv->selected_user,
@@ -216,12 +232,13 @@ on_authentication_failed (GdmSession *session,
 }
 
 static void
-on_session_started (GdmSession *session)
+on_session_started (GdmSession *session,
+                    const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
-        conversation = impl->priv->conversation;
+        conversation = find_conversation_by_name (impl, service_name);
         if (conversation != NULL) {
                 gdm_session_record_login (conversation->worker_pid,
                                           impl->priv->selected_user,
@@ -233,12 +250,13 @@ on_session_started (GdmSession *session)
 
 static void
 on_session_start_failed (GdmSession *session,
+                         const char *service_name,
                          const char *message)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
-        conversation = impl->priv->conversation;
+        conversation = find_conversation_by_name (impl, service_name);
         if (conversation != NULL) {
                 gdm_session_record_login (conversation->worker_pid,
                                           impl->priv->selected_user,
@@ -263,7 +281,7 @@ on_session_exited (GdmSession *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
-                                          DBusConnection   *connection,
+                                          GdmSessionConversation *conversation,
                                           DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -271,17 +289,17 @@ gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
         g_debug ("GdmSessionDirect: Emitting 'setup-complete' signal");
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_setup_complete (GDM_SESSION (session));
+        _gdm_session_setup_complete (GDM_SESSION (session), conversation->service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
-                                        DBusConnection   *connection,
+                                        GdmSessionConversation *conversation,
                                         DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -296,12 +314,12 @@ gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'setup-failed' signal");
 
-        _gdm_session_setup_failed (GDM_SESSION (session), text);
+        _gdm_session_setup_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -309,7 +327,7 @@ gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
-                                          DBusConnection   *connection,
+                                          GdmSessionConversation *conversation,
                                           DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -317,7 +335,7 @@ gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
         g_debug ("GdmSessionDirect: Emitting 'reset-complete' signal");
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         _gdm_session_reset_complete (GDM_SESSION (session));
@@ -327,7 +345,7 @@ gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
-                                        DBusConnection   *connection,
+                                        GdmSessionConversation *conversation,
                                         DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -342,7 +360,7 @@ gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'reset-failed' signal");
@@ -354,7 +372,7 @@ gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_authenticated (GdmSessionDirect *session,
-                                         DBusConnection   *connection,
+                                         GdmSessionConversation *conversation,
                                          DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -362,17 +380,17 @@ gdm_session_direct_handle_authenticated (GdmSessionDirect *session,
         g_debug ("GdmSessionDirect: Emitting 'authenticated' signal");
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authenticated (GDM_SESSION (session));
+        _gdm_session_authenticated (GDM_SESSION (session), conversation->service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_authentication_failed (GdmSessionDirect *session,
-                                                 DBusConnection   *connection,
+                                                 GdmSessionConversation *conversation,
                                                  DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -387,19 +405,19 @@ gdm_session_direct_handle_authentication_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'authentication-failed' signal");
 
-        _gdm_session_authentication_failed (GDM_SESSION (session), text);
+        _gdm_session_authentication_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_authorized (GdmSessionDirect *session,
-                                      DBusConnection   *connection,
+                                      GdmSessionConversation *conversation,
                                       DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -407,17 +425,17 @@ gdm_session_direct_handle_authorized (GdmSessionDirect *session,
         g_debug ("GdmSessionDirect: Emitting 'authorized' signal");
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authorized (GDM_SESSION (session));
+        _gdm_session_authorized (GDM_SESSION (session), conversation->service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_authorization_failed (GdmSessionDirect *session,
-                                                DBusConnection   *connection,
+                                                GdmSessionConversation *conversation,
                                                 DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -432,19 +450,19 @@ gdm_session_direct_handle_authorization_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'authorization-failed' signal");
 
-        _gdm_session_authorization_failed (GDM_SESSION (session), text);
+        _gdm_session_authorization_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_accredited (GdmSessionDirect *session,
-                                      DBusConnection   *connection,
+                                      GdmSessionConversation *conversation,
                                       DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -452,17 +470,17 @@ gdm_session_direct_handle_accredited (GdmSessionDirect *session,
         g_debug ("GdmSessionDirect: Emitting 'accredited' signal");
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_accredited (GDM_SESSION (session));
+        _gdm_session_accredited (GDM_SESSION (session), conversation->service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_accreditation_failed (GdmSessionDirect *session,
-                                                DBusConnection   *connection,
+                                                GdmSessionConversation *conversation,
                                                 DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -477,12 +495,12 @@ gdm_session_direct_handle_accreditation_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'accreditation-failed' signal");
 
-        _gdm_session_accreditation_failed (GDM_SESSION (session), text);
+        _gdm_session_accreditation_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -764,7 +782,7 @@ gdm_session_direct_select_user (GdmSession *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
-                                            DBusConnection   *connection,
+                                            GdmSessionConversation *conversation,
                                             DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -779,7 +797,7 @@ gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: changing username from '%s' to '%s'",
@@ -846,14 +864,11 @@ set_pending_query (GdmSessionConversation *conversation,
 
 static DBusHandlerResult
 gdm_session_direct_handle_info_query (GdmSessionDirect *session,
-                                      DBusConnection   *connection,
+                                      GdmSessionConversation *conversation,
                                       DBusMessage      *message)
 {
         DBusError    error;
         const char  *text;
-        GdmSessionConversation *conversation;
-
-        conversation = session->priv->conversation;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
@@ -865,21 +880,18 @@ gdm_session_direct_handle_info_query (GdmSessionDirect *session,
         set_pending_query (conversation, message);
 
         g_debug ("GdmSessionDirect: Emitting 'info-query' signal");
-        _gdm_session_info_query (GDM_SESSION (session), text);
+        _gdm_session_info_query (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session,
-                                             DBusConnection   *connection,
+                                             GdmSessionConversation *conversation,
                                              DBusMessage      *message)
 {
         DBusError    error;
         const char  *text;
-        GdmSessionConversation *conversation;
-
-        conversation = session->priv->conversation;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
@@ -891,14 +903,14 @@ gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session,
         set_pending_query (conversation, message);
 
         g_debug ("GdmSessionDirect: Emitting 'secret-info-query' signal");
-        _gdm_session_secret_info_query (GDM_SESSION (session), text);
+        _gdm_session_secret_info_query (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_info (GdmSessionDirect *session,
-                                DBusConnection   *connection,
+                                GdmSessionConversation *conversation,
                                 DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -913,31 +925,28 @@ gdm_session_direct_handle_info (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'info' signal");
-        _gdm_session_info (GDM_SESSION (session), text);
+        _gdm_session_info (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
-                                                DBusConnection   *connection,
+                                                GdmSessionConversation *conversation,
                                                 DBusMessage      *message)
 {
         DBusMessage *reply;
-        GdmSessionConversation *conversation;
 
         g_debug ("GdmSessionDirect: worker cancelling pending query");
 
-        conversation = session->priv->conversation;
-
         cancel_pending_query (conversation);
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         return DBUS_HANDLER_RESULT_HANDLED;
@@ -945,7 +954,7 @@ gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_problem (GdmSessionDirect *session,
-                                   DBusConnection   *connection,
+                                   GdmSessionConversation *conversation,
                                    DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -960,18 +969,18 @@ gdm_session_direct_handle_problem (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'problem' signal");
-        _gdm_session_problem (GDM_SESSION (session), text);
+        _gdm_session_problem (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_session_opened (GdmSessionDirect *session,
-                                          DBusConnection   *connection,
+                                          GdmSessionConversation *conversation,
                                           DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -986,10 +995,10 @@ gdm_session_direct_handle_session_opened (GdmSessionDirect *session,
 
         g_debug ("GdmSessionDirect: Emitting 'session-opened' signal");
 
-        _gdm_session_session_opened (GDM_SESSION (session));
+        _gdm_session_session_opened (GDM_SESSION (session), conversation->service_name);
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         return DBUS_HANDLER_RESULT_HANDLED;
@@ -997,7 +1006,7 @@ gdm_session_direct_handle_session_opened (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_open_failed (GdmSessionDirect *session,
-                                       DBusConnection   *connection,
+                                       GdmSessionConversation *conversation,
                                        DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1012,18 +1021,18 @@ gdm_session_direct_handle_open_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'session-open-failed' signal");
-        _gdm_session_session_open_failed (GDM_SESSION (session), text);
+        _gdm_session_session_open_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_session_started (GdmSessionDirect *session,
-                                           DBusConnection   *connection,
+                                           GdmSessionConversation *conversation,
                                            DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1042,7 +1051,7 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'session-started' signal with pid '%d'",
@@ -1051,14 +1060,14 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
         session->priv->session_pid = pid;
         session->priv->is_running = TRUE;
 
-        _gdm_session_session_started (GDM_SESSION (session), pid);
+        _gdm_session_session_started (GDM_SESSION (session), conversation->service_name, pid);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_start_failed (GdmSessionDirect *session,
-                                        DBusConnection   *connection,
+                                        GdmSessionConversation *conversation,
                                         DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1073,18 +1082,18 @@ gdm_session_direct_handle_start_failed (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'session-start-failed' signal");
-        _gdm_session_session_start_failed (GDM_SESSION (session), text);
+        _gdm_session_session_start_failed (GDM_SESSION (session), conversation->service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
 gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
-                                          DBusConnection   *connection,
+                                          GdmSessionConversation *conversation,
                                           DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1099,7 +1108,7 @@ gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'session-exited' signal with exit code '%d'",
@@ -1113,7 +1122,7 @@ gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_session_died (GdmSessionDirect *session,
-                                        DBusConnection   *connection,
+                                        GdmSessionConversation *conversation,
                                         DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1128,7 +1137,7 @@ gdm_session_direct_handle_session_died (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         g_debug ("GdmSessionDirect: Emitting 'session-died' signal with signal number '%d'",
@@ -1142,7 +1151,7 @@ gdm_session_direct_handle_session_died (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
-                                                    DBusConnection   *connection,
+                                                    GdmSessionConversation *conversation,
                                                     DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1157,7 +1166,7 @@ gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         if (strcmp (language_name,
@@ -1175,7 +1184,7 @@ gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
-                                                  DBusConnection   *connection,
+                                                  GdmSessionConversation *conversation,
                                                   DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1190,7 +1199,7 @@ gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         if (strcmp (layout_name,
@@ -1208,7 +1217,7 @@ gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
 
 static DBusHandlerResult
 gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
-                                                   DBusConnection   *connection,
+                                                   GdmSessionConversation *conversation,
                                                    DBusMessage      *message)
 {
         DBusMessage *reply;
@@ -1223,7 +1232,7 @@ gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
         }
 
         reply = dbus_message_new_method_return (message);
-        dbus_connection_send (connection, reply, NULL);
+        dbus_connection_send (conversation->worker_connection, reply, NULL);
         dbus_message_unref (reply);
 
         if (! get_session_command_for_name (session_name, NULL)) {
@@ -1251,58 +1260,61 @@ session_worker_message (DBusConnection *connection,
                         DBusMessage    *message,
                         void           *user_data)
 {
-        GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
+        GdmSessionConversation *conversation = user_data;
+        GdmSessionDirect *session;
+
+        session = conversation->session;
 
         if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "InfoQuery")) {
-                return gdm_session_direct_handle_info_query (session, connection, message);
+                return gdm_session_direct_handle_info_query (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SecretInfoQuery")) {
-                return gdm_session_direct_handle_secret_info_query (session, connection, message);
+                return gdm_session_direct_handle_secret_info_query (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Info")) {
-                return gdm_session_direct_handle_info (session, connection, message);
+                return gdm_session_direct_handle_info (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Problem")) {
-                return gdm_session_direct_handle_problem (session, connection, message);
+                return gdm_session_direct_handle_problem (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "CancelPendingQuery")) {
-                return gdm_session_direct_handle_cancel_pending_query (session, connection, message);
+                return gdm_session_direct_handle_cancel_pending_query (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupComplete")) {
-                return gdm_session_direct_handle_setup_complete (session, connection, message);
+                return gdm_session_direct_handle_setup_complete (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupFailed")) {
-                return gdm_session_direct_handle_setup_failed (session, connection, message);
+                return gdm_session_direct_handle_setup_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetComplete")) {
-                return gdm_session_direct_handle_reset_complete (session, connection, message);
+                return gdm_session_direct_handle_reset_complete (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetFailed")) {
-                return gdm_session_direct_handle_reset_failed (session, connection, message);
+                return gdm_session_direct_handle_reset_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authenticated")) {
-                return gdm_session_direct_handle_authenticated (session, connection, message);
+                return gdm_session_direct_handle_authenticated (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthenticationFailed")) {
-                return gdm_session_direct_handle_authentication_failed (session, connection, message);
+                return gdm_session_direct_handle_authentication_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authorized")) {
-                return gdm_session_direct_handle_authorized (session, connection, message);
+                return gdm_session_direct_handle_authorized (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthorizationFailed")) {
-                return gdm_session_direct_handle_authorization_failed (session, connection, message);
+                return gdm_session_direct_handle_authorization_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Accredited")) {
-                return gdm_session_direct_handle_accredited (session, connection, message);
+                return gdm_session_direct_handle_accredited (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AccreditationFailed")) {
-                return gdm_session_direct_handle_accreditation_failed (session, connection, message);
+                return gdm_session_direct_handle_accreditation_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) {
-                return gdm_session_direct_handle_username_changed (session, connection, message);
+                return gdm_session_direct_handle_username_changed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) {
-                return gdm_session_direct_handle_session_opened (session, connection, message);
+                return gdm_session_direct_handle_session_opened (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "OpenFailed")) {
-                return gdm_session_direct_handle_open_failed (session, connection, message);
+                return gdm_session_direct_handle_open_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) {
-                return gdm_session_direct_handle_session_started (session, connection, message);
+                return gdm_session_direct_handle_session_started (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) {
-                return gdm_session_direct_handle_start_failed (session, connection, message);
+                return gdm_session_direct_handle_start_failed (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionExited")) {
-                return gdm_session_direct_handle_session_exited (session, connection, message);
+                return gdm_session_direct_handle_session_exited (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionDied")) {
-                return gdm_session_direct_handle_session_died (session, connection, message);
+                return gdm_session_direct_handle_session_died (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLanguageNameRead")) {
-                return gdm_session_direct_handle_saved_language_name_read (session, connection, message);
+                return gdm_session_direct_handle_saved_language_name_read (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLayoutNameRead")) {
-                return gdm_session_direct_handle_saved_layout_name_read (session, connection, message);
+                return gdm_session_direct_handle_saved_layout_name_read (session, conversation, message);
         } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedSessionNameRead")) {
-                return gdm_session_direct_handle_saved_session_name_read (session, connection, message);
+                return gdm_session_direct_handle_saved_session_name_read (session, conversation, message);
         }
 
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1536,6 +1548,27 @@ session_unregister_handler (DBusConnection  *connection,
         g_debug ("session_unregister_handler");
 }
 
+static GdmSessionConversation *
+find_conversation_by_pid (GdmSessionDirect *session,
+                          GPid              pid)
+{
+        GHashTableIter iter;
+        gpointer key, value;
+
+        g_hash_table_iter_init (&iter, session->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                if (conversation->worker_pid == pid) {
+                        return conversation;
+                }
+        }
+
+        return NULL;
+}
+
 static dbus_bool_t
 allow_user_function (DBusConnection *connection,
                      unsigned long   uid,
@@ -1550,40 +1583,85 @@ allow_user_function (DBusConnection *connection,
         return FALSE;
 }
 
-static GdmSessionConversation *
-find_conversation_by_name (GdmSessionDirect *session,
-                           const char       *service_name)
+static gboolean
+register_worker (GdmSessionDirect *session,
+                 DBusConnection   *connection)
 {
         GdmSessionConversation *conversation;
+        DBusObjectPathVTable vtable = { &session_unregister_handler,
+                                        &session_message_handler,
+                                        NULL, NULL, NULL, NULL };
+        GList *connection_node;
+        gulong pid;
 
-        conversation = g_hash_table_lookup (session->priv->conversations, service_name);
+        g_debug ("GdmSessionDirect: Authenticating new connection");
+
+        connection_node = g_list_find (session->priv->pending_connections, connection);
+
+        if (connection_node == NULL) {
+                g_debug ("GdmSessionDirect: Ignoring connection that we aren't tracking");
+                return FALSE;
+        }
+
+        session->priv->pending_connections =
+                g_list_delete_link (session->priv->pending_connections,
+                                    connection_node);
+
+        if (!dbus_connection_get_unix_process_id (connection, &pid)) {
+                g_warning ("GdmSessionDirect: Unable to read pid on new worker connection");
+                dbus_connection_unref (connection);
+                return FALSE;
+        }
+
+        conversation = find_conversation_by_pid (session, (GPid) pid);
 
         if (conversation == NULL) {
-                g_warning ("Tried to look up non-existant conversation");
+                g_warning ("GdmSessionDirect: New worker connection is from unknown source");
+                dbus_connection_unref (connection);
+                return FALSE;
         }
 
-        return conversation;
+        conversation->worker_connection = connection;
+
+        g_debug ("GdmSessionDirect: worker connection is %p", connection);
+
+        dbus_connection_register_object_path (connection,
+                                              GDM_SESSION_DBUS_PATH,
+                                              &vtable,
+                                              conversation);
+
+        g_debug ("GdmSessionDirect: Emitting conversation-started signal");
+        _gdm_session_conversation_started (GDM_SESSION (session),
+                                           conversation->service_name);
+
+        g_debug ("GdmSessionDirect: Conversation started");
+
+        return TRUE;
 }
 
-static GdmSessionConversation *
-find_conversation_by_pid (GdmSessionDirect *session,
-                          GPid              pid)
+static DBusHandlerResult
+on_message (DBusConnection *connection,
+            DBusMessage    *message,
+            void           *user_data)
 {
-        GHashTableIter iter;
-        gpointer key, value;
+        GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
 
-        g_hash_table_iter_init (&iter, session->priv->conversations);
-        while (g_hash_table_iter_next (&iter, &key, &value)) {
-                GdmSessionConversation *conversation;
+        g_debug ("GdmSessionDirect: got message");
 
-                conversation = (GdmSessionConversation *) value;
+        if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Hello")) {
+                DBusMessage *reply;
 
-                if (conversation->worker_pid == pid) {
-                        return conversation;
+                if (register_worker (session, connection)) {
+                        reply = dbus_message_new_method_return (message);
+                } else {
+                        reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "");
                 }
+
+                dbus_connection_send (connection, reply, NULL);
+                return DBUS_HANDLER_RESULT_HANDLED;
         }
 
-        return NULL;
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static void
@@ -1592,50 +1670,23 @@ handle_connection (DBusServer      *server,
                    void            *user_data)
 {
         GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
-        GdmSessionConversation *conversation;
-        gulong pid;
-
         g_debug ("GdmSessionDirect: Handing new connection");
 
-        if (!dbus_connection_get_unix_process_id (new_connection, &pid)) {
-                g_warning ("Unable to read pid on new worker connection");
-                return;
-        }
-
-        conversation = find_conversation_by_pid (session, (GPid) pid);
-
-        if (conversation == NULL) {
-                g_warning ("New worker connection is from unknown source");
-                return;
-        }
-
-        if (conversation->worker_connection == NULL) {
-                DBusObjectPathVTable vtable = { &session_unregister_handler,
-                                                &session_message_handler,
-                                                NULL, NULL, NULL, NULL
-                };
-
-                conversation->worker_connection = new_connection;
-                dbus_connection_ref (new_connection);
-                dbus_connection_setup_with_g_main (new_connection, NULL);
-
-                g_debug ("GdmSessionDirect: worker connection is %p", new_connection);
-                dbus_connection_set_exit_on_disconnect (new_connection, FALSE);
-
-                dbus_connection_set_unix_user_function (new_connection,
-                                                        allow_user_function,
-                                                        session,
-                                                        NULL);
-
-                dbus_connection_register_object_path (new_connection,
-                                                      GDM_SESSION_DBUS_PATH,
-                                                      &vtable,
-                                                      session);
+        /* add to the list of pending connections.  We won't be able to
+         * associate it with a specific worker conversation until we have
+         * authenticated the connection (from the Hello handler).
+         */
+        session->priv->pending_connections =
+                g_list_prepend (session->priv->pending_connections,
+                                dbus_connection_ref (new_connection));
+        dbus_connection_setup_with_g_main (new_connection, NULL);
+        dbus_connection_set_exit_on_disconnect (new_connection, FALSE);
 
-                g_debug ("GdmSessionDirect: Emitting conversation-started signal");
-                _gdm_session_conversation_started (GDM_SESSION (session),
-                                                   conversation->service_name);
-        }
+        dbus_connection_set_unix_user_function (new_connection,
+                                                allow_user_function,
+                                                session,
+                                                NULL);
+        dbus_connection_add_filter (new_connection, on_message, session, NULL);
 }
 
 static gboolean
@@ -1820,6 +1871,8 @@ stop_conversation (GdmSessionConversation *conversation)
                                               conversation);
 
         if (conversation->worker_connection != NULL) {
+                dbus_connection_remove_filter (conversation->worker_connection, on_message, session);
+
                 dbus_connection_close (conversation->worker_connection);
                 conversation->worker_connection = NULL;
         }
@@ -1845,10 +1898,6 @@ gdm_session_direct_start_conversation (GdmSession *session,
 
         g_hash_table_insert (impl->priv->conversations,
                              g_strdup (service_name), conversation);
-
-        if (impl->priv->conversation != NULL) {
-                impl->priv->conversation = conversation;
-        }
 }
 
 static void
@@ -1999,45 +2048,50 @@ gdm_session_direct_setup_for_user (GdmSession *session,
 }
 
 static void
-gdm_session_direct_authenticate (GdmSession *session)
+gdm_session_direct_authenticate (GdmSession *session,
+                                 const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
         g_return_if_fail (session != NULL);
-        g_return_if_fail (impl->priv->conversation != NULL);
-        g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
 
-        conversation = impl->priv->conversation;
-        send_dbus_void_signal (conversation, "Authenticate");
+        conversation = find_conversation_by_name (impl, service_name);
+        if (conversation != NULL) {
+                send_dbus_void_signal (conversation, "Authenticate");
+        }
 }
 
 static void
-gdm_session_direct_authorize (GdmSession *session)
+gdm_session_direct_authorize (GdmSession *session,
+                              const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
         g_return_if_fail (session != NULL);
-        g_return_if_fail (impl->priv->conversation != NULL);
-        g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
 
-        conversation = impl->priv->conversation;
-        send_dbus_void_signal (conversation, "Authorize");
+        conversation = find_conversation_by_name (impl, service_name);
+        if (conversation != NULL) {
+                send_dbus_void_signal (conversation, "Authorize");
+        }
 }
 
 static void
 gdm_session_direct_accredit (GdmSession *session,
+                             const char *service_name,
                              int         cred_flag)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
 
         g_return_if_fail (session != NULL);
-        g_return_if_fail (impl->priv->conversation != NULL);
-        g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
 
-        conversation = impl->priv->conversation;
+        conversation = find_conversation_by_name (impl, service_name);
+        if (conversation == NULL) {
+                return;
+        }
+
         switch (cred_flag) {
         case GDM_SESSION_CRED_ESTABLISH:
                 send_dbus_void_signal (conversation, "EstablishCredentials");
@@ -2051,13 +2105,12 @@ gdm_session_direct_accredit (GdmSession *session,
 }
 
 static void
-send_environment_variable (const char       *key,
-                           const char       *value,
-                           GdmSessionDirect *session)
+send_environment_variable (const char             *key,
+                           const char             *value,
+                           GdmSessionConversation *conversation)
 {
         DBusMessage    *message;
         DBusMessageIter iter;
-        GdmSessionConversation *conversation;
 
         message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH,
                                            GDM_SESSION_DBUS_INTERFACE,
@@ -2067,7 +2120,6 @@ send_environment_variable (const char       *key,
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
         dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
 
-        conversation = session->priv->conversation;
         if (! send_dbus_message (conversation, message)) {
                 g_debug ("GdmSessionDirect: Could not send %s signal", "SetEnvironmentVariable");
         }
@@ -2076,12 +2128,13 @@ send_environment_variable (const char       *key,
 }
 
 static void
-send_environment (GdmSessionDirect *session)
+send_environment (GdmSessionDirect       *session,
+                  GdmSessionConversation *conversation)
 {
 
         g_hash_table_foreach (session->priv->environment,
                               (GHFunc) send_environment_variable,
-                              session);
+                              conversation);
 }
 
 static const char *
@@ -2203,17 +2256,22 @@ setup_session_environment (GdmSessionDirect *session)
 }
 
 static void
-gdm_session_direct_open_session (GdmSession *session)
+gdm_session_direct_open_session (GdmSession *session,
+                                 const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
+        GdmSessionConversation *conversation;
 
         g_return_if_fail (session != NULL);
 
-        send_dbus_void_signal (impl, "OpenSession");
+        conversation = find_conversation_by_name (impl, service_name);
+
+        send_dbus_string_signal (conversation, "OpenSession", service_name);
 }
 
 static void
-gdm_session_direct_start_session (GdmSession *session)
+gdm_session_direct_start_session (GdmSession *session,
+                                  const char *service_name)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
         GdmSessionConversation *conversation;
@@ -2233,10 +2291,11 @@ gdm_session_direct_start_session (GdmSession *session)
 
         g_free (command);
 
+        conversation = find_conversation_by_name (impl, service_name);
+
         setup_session_environment (impl);
-        send_environment (impl);
+        send_environment (impl, conversation);
 
-        conversation = impl->priv->conversation;
         send_dbus_string_signal (conversation, "StartProgram", program);
         g_free (program);
 }
@@ -2282,6 +2341,11 @@ gdm_session_direct_close (GdmSession *session)
 
         stop_all_conversations (impl);
 
+        g_list_foreach (impl->priv->pending_connections,
+                        (GFunc) dbus_connection_unref, NULL);
+        g_list_free (impl->priv->pending_connections);
+        impl->priv->pending_connections = NULL;
+
         g_free (impl->priv->selected_user);
         impl->priv->selected_user = NULL;
 
@@ -2314,6 +2378,7 @@ gdm_session_direct_close (GdmSession *session)
 
 static void
 gdm_session_direct_answer_query  (GdmSession *session,
+                                  const char *service_name,
                                   const char *text)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
@@ -2321,7 +2386,7 @@ gdm_session_direct_answer_query  (GdmSession *session,
 
         g_return_if_fail (session != NULL);
 
-        conversation = impl->priv->conversation;
+        conversation = find_conversation_by_name (impl, service_name);
 
         answer_pending_query (conversation, text);
 }
@@ -2396,7 +2461,8 @@ gdm_session_direct_select_session (GdmSession *session,
                                    const char *text)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
-        GdmSessionConversation *conversation;
+        GHashTableIter iter;
+        gpointer key, value;
 
         g_free (impl->priv->selected_session);
 
@@ -2406,9 +2472,15 @@ gdm_session_direct_select_session (GdmSession *session,
                 impl->priv->selected_session = g_strdup (text);
         }
 
-        conversation = impl->priv->conversation;
-        send_dbus_string_signal (conversation, "SetSessionName",
-                                 get_session_name (impl));
+        g_hash_table_iter_init (&iter, impl->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                send_dbus_string_signal (conversation, "SetSessionName",
+                                         get_session_name (impl));
+        }
 }
 
 static void
@@ -2416,7 +2488,8 @@ gdm_session_direct_select_language (GdmSession *session,
                                     const char *text)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
-        GdmSessionConversation *conversation;
+        GHashTableIter iter;
+        gpointer key, value;
 
         g_free (impl->priv->selected_language);
 
@@ -2426,9 +2499,15 @@ gdm_session_direct_select_language (GdmSession *session,
                 impl->priv->selected_language = g_strdup (text);
         }
 
-        conversation = impl->priv->conversation;
-        send_dbus_string_signal (conversation, "SetLanguageName",
-                                 get_language_name (impl));
+        g_hash_table_iter_init (&iter, impl->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                send_dbus_string_signal (conversation, "SetLanguageName",
+                                         get_language_name (impl));
+        }
 }
 
 static void
@@ -2436,7 +2515,8 @@ gdm_session_direct_select_layout (GdmSession *session,
                                   const char *text)
 {
         GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
-        GdmSessionConversation *conversation;
+        GHashTableIter iter;
+        gpointer key, value;
 
         g_free (impl->priv->selected_layout);
 
@@ -2446,9 +2526,15 @@ gdm_session_direct_select_layout (GdmSession *session,
                 impl->priv->selected_layout = g_strdup (text);
         }
 
-        conversation = impl->priv->conversation;
-        send_dbus_string_signal (conversation, "SetLayoutName",
-                                 get_layout_name (impl));
+        g_hash_table_iter_init (&iter, impl->priv->conversations);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                GdmSessionConversation *conversation;
+
+                conversation = (GdmSessionConversation *) value;
+
+                send_dbus_string_signal (conversation, "SetLayoutName",
+                                         get_layout_name (impl));
+        }
 }
 
 static void
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
index 74b6069..4dc6e44 100644
--- a/daemon/gdm-session-private.h
+++ b/daemon/gdm-session-private.h
@@ -29,27 +29,39 @@ G_BEGIN_DECLS
 /* state changes */
 void             _gdm_session_conversation_started         (GdmSession   *session,
                                                             const char   *service_name);
-void             _gdm_session_setup_complete               (GdmSession   *session);
+void             _gdm_session_setup_complete               (GdmSession   *session,
+                                                            const char   *service_name);
 void             _gdm_session_setup_failed                 (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *message);
 void             _gdm_session_reset_complete               (GdmSession   *session);
 void             _gdm_session_reset_failed                 (GdmSession   *session,
                                                             const char   *message);
-void             _gdm_session_authenticated                (GdmSession   *session);
+void             _gdm_session_authenticated                (GdmSession   *session,
+                                                            const char   *service_name);
 void             _gdm_session_authentication_failed        (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
-void             _gdm_session_authorized                   (GdmSession   *session);
+void             _gdm_session_authorized                   (GdmSession   *session,
+                                                            const char   *service_name);
 void             _gdm_session_authorization_failed         (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
-void             _gdm_session_accredited                   (GdmSession   *session);
+void             _gdm_session_accredited                   (GdmSession   *session,
+                                                            const char   *service_name);
 void             _gdm_session_accreditation_failed         (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
-void             _gdm_session_session_opened               (GdmSession   *session);
+void             _gdm_session_session_opened               (GdmSession   *session,
+                                                            const char   *service_name);
 void             _gdm_session_session_open_failed          (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *message);
 void             _gdm_session_session_started              (GdmSession   *session,
+                                                            const char   *service_name,
                                                             int           pid);
 void             _gdm_session_session_start_failed         (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *message);
 void             _gdm_session_session_exited               (GdmSession   *session,
                                                             int           exit_code);
@@ -70,12 +82,16 @@ void             _gdm_session_selected_user_changed        (GdmSession   *sessio
 
 /* call and response stuff */
 void             _gdm_session_info_query                   (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
 void             _gdm_session_secret_info_query            (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
 void             _gdm_session_info                         (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
 void             _gdm_session_problem                      (GdmSession   *session,
+                                                            const char   *service_name,
                                                             const char   *text);
 
 G_END_DECLS
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
index a0b4cbf..98ccc51 100644
--- a/daemon/gdm-session-relay.c
+++ b/daemon/gdm-session-relay.c
@@ -212,31 +212,34 @@ gdm_session_relay_setup_for_user (GdmSession *session,
 }
 
 static void
-gdm_session_relay_authenticate (GdmSession *session)
+gdm_session_relay_authenticate (GdmSession *session,
+                                const char *service_name)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
-        send_dbus_void_signal (impl, "Authenticate");
+        send_dbus_string_signal (impl, "Authenticate", service_name);
 }
 
 static void
-gdm_session_relay_authorize (GdmSession *session)
+gdm_session_relay_authorize (GdmSession *session,
+                             const char *service_name)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
-        send_dbus_void_signal (impl, "Authorize");
+        send_dbus_string_signal (impl, "Authorize", service_name);
 }
 
 static void
 gdm_session_relay_accredit (GdmSession *session,
+                            const char *service_name,
                             int         cred_flag)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
 
         switch (cred_flag) {
         case GDM_SESSION_CRED_ESTABLISH:
-                send_dbus_void_signal (impl, "EstablishCredentials");
+                send_dbus_string_signal (impl, "EstablishCredentials", service_name);
                 break;
         case GDM_SESSION_CRED_REFRESH:
-                send_dbus_void_signal (impl, "RefreshCredentials");
+                send_dbus_string_signal (impl, "RefreshCredentials", service_name);
                 break;
         default:
                 g_assert_not_reached ();
@@ -244,18 +247,20 @@ gdm_session_relay_accredit (GdmSession *session,
 }
 
 static void
-gdm_session_relay_open_session (GdmSession *session)
+gdm_session_relay_open_session (GdmSession *session,
+                                const char *service_name)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
-        send_dbus_void_signal (impl, "OpenSession");
+        send_dbus_string_signal (impl, "OpenSession", service_name);
 }
 
 static void
 gdm_session_relay_answer_query (GdmSession *session,
+                                const char *service_name,
                                 const char *text)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
-        send_dbus_string_signal (impl, "AnswerQuery", text);
+        send_dbus_string_string_signal (impl, "AnswerQuery", service_name, text);
 }
 
 static void
@@ -299,11 +304,12 @@ gdm_session_relay_cancel (GdmSession *session)
 }
 
 static void
-gdm_session_relay_start_session (GdmSession *session)
+gdm_session_relay_start_session (GdmSession *session,
+                                 const char *service_name)
 {
         GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
 
-        send_dbus_void_signal (impl, "StartSession");
+        send_dbus_string_signal (impl, "StartSession", service_name);
 }
 
 /* Note: Use abstract sockets like dbus does by default on Linux. Abstract
@@ -341,10 +347,12 @@ handle_info_query (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
-        const char  *text;
+        char  *service_name;
+        char  *text;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -356,7 +364,7 @@ handle_info_query (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_info_query (GDM_SESSION (session_relay), text);
+        _gdm_session_info_query (GDM_SESSION (session_relay), service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -368,12 +376,14 @@ handle_secret_info_query (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
-        const char  *text;
+        char        *service_name;
+        char  *text;
 
         text = NULL;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -385,7 +395,7 @@ handle_secret_info_query (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_secret_info_query (GDM_SESSION (session_relay), text);
+        _gdm_session_secret_info_query (GDM_SESSION (session_relay), service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -397,12 +407,14 @@ handle_info (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
-        const char  *text;
+        char        *service_name;
+        char        *text;
 
         text = NULL;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -414,7 +426,7 @@ handle_info (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_info (GDM_SESSION (session_relay), text);
+        _gdm_session_info (GDM_SESSION (session_relay), service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -426,12 +438,14 @@ handle_problem (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
-        const char  *text;
+        char        *service_name;
+        char        *text;
 
         text = NULL;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_STRING, &text,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -443,7 +457,7 @@ handle_problem (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_problem (GDM_SESSION (session_relay), text);
+        _gdm_session_problem (GDM_SESSION (session_relay), service_name, text);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -455,8 +469,15 @@ handle_setup_complete (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: SetupComplete");
 
@@ -464,7 +485,7 @@ handle_setup_complete (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_setup_complete (GDM_SESSION (session_relay));
+        _gdm_session_setup_complete (GDM_SESSION (session_relay), service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -476,8 +497,15 @@ handle_setup_failed (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: SetupFailed");
 
@@ -485,7 +513,7 @@ handle_setup_failed (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_setup_failed (GDM_SESSION (session_relay), NULL);
+        _gdm_session_setup_failed (GDM_SESSION (session_relay), service_name, NULL);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -498,8 +526,15 @@ handle_authenticated (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: Authenticated");
 
@@ -507,7 +542,7 @@ handle_authenticated (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authenticated (GDM_SESSION (session_relay));
+        _gdm_session_authenticated (GDM_SESSION (session_relay), service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -519,8 +554,15 @@ handle_authentication_failed (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: AuthenticationFailed");
 
@@ -528,7 +570,7 @@ handle_authentication_failed (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authentication_failed (GDM_SESSION (session_relay), NULL);
+        _gdm_session_authentication_failed (GDM_SESSION (session_relay), service_name, NULL);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -540,8 +582,15 @@ handle_authorized (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: Authorized");
 
@@ -549,7 +598,7 @@ handle_authorized (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authorized (GDM_SESSION (session_relay));
+        _gdm_session_authorized (GDM_SESSION (session_relay), service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -561,8 +610,15 @@ handle_authorization_failed (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: AuthorizationFailed");
 
@@ -570,7 +626,7 @@ handle_authorization_failed (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_authorization_failed (GDM_SESSION (session_relay), NULL);
+        _gdm_session_authorization_failed (GDM_SESSION (session_relay), service_name, NULL);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -582,8 +638,15 @@ handle_accredited (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: Accredited");
 
@@ -591,7 +654,7 @@ handle_accredited (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_accredited (GDM_SESSION (session_relay));
+        _gdm_session_accredited (GDM_SESSION (session_relay), service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -603,8 +666,15 @@ handle_accreditation_failed (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
+        if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
+                                     DBUS_TYPE_INVALID)) {
+                g_warning ("ERROR: %s", error.message);
+        }
+        dbus_error_free (&error);
 
         g_debug ("GdmSessionRelay: AccreditationFailed");
 
@@ -612,7 +682,7 @@ handle_accreditation_failed (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_accreditation_failed (GDM_SESSION (session_relay), NULL);
+        _gdm_session_accreditation_failed (GDM_SESSION (session_relay), service_name, NULL);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -623,9 +693,11 @@ handle_session_opened (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
         }
@@ -637,7 +709,7 @@ handle_session_opened (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_session_opened (GDM_SESSION (session_relay));
+        _gdm_session_session_opened (GDM_SESSION (session_relay), service_name);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -649,9 +721,11 @@ handle_session_open_failed (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
 
         dbus_error_init (&error);
         if (! dbus_message_get_args (message, &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
         }
@@ -663,7 +737,7 @@ handle_session_open_failed (GdmSessionRelay *session_relay,
         dbus_connection_send (connection, reply, NULL);
         dbus_message_unref (reply);
 
-        _gdm_session_session_open_failed (GDM_SESSION (session_relay), NULL);
+        _gdm_session_session_open_failed (GDM_SESSION (session_relay), service_name, NULL);
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -675,6 +749,7 @@ handle_session_started (GdmSessionRelay *session_relay,
 {
         DBusMessage *reply;
         DBusError    error;
+        char        *service_name;
         int          pid;
 
         dbus_error_init (&error);
@@ -682,6 +757,7 @@ handle_session_started (GdmSessionRelay *session_relay,
         pid = 0;
         if (! dbus_message_get_args (message,
                                      &error,
+                                     DBUS_TYPE_STRING, &service_name,
                                      DBUS_TYPE_INT32, &pid,
                                      DBUS_TYPE_INVALID)) {
                 g_warning ("ERROR: %s", error.message);
@@ -694,6 +770,7 @@ handle_session_started (GdmSessionRelay *session_relay,
         dbus_message_unref (reply);
 
         _gdm_session_session_started (GDM_SESSION (session_relay),
+                                      service_name,
                                       pid);
 
         return DBUS_HANDLER_RESULT_HANDLED;
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 5e34fb9..2f07e13 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2876,6 +2876,28 @@ worker_dbus_filter_function (DBusConnection *connection,
         return DBUS_HANDLER_RESULT_HANDLED;
 }
 
+static void
+send_hello (GdmSessionWorker *worker)
+{
+        DBusMessage *message, *reply;
+        DBusError error;
+
+        message = dbus_message_new_method_call (NULL,
+                                                GDM_SESSION_DBUS_PATH,
+                                                GDM_SESSION_DBUS_INTERFACE,
+                                                "Hello");
+
+        dbus_error_init (&error);
+        reply = dbus_connection_send_with_reply_and_block (worker->priv->connection,
+                                                           message, -1, &error);
+        dbus_message_unref (message);
+        dbus_error_free (&error);
+
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+}
+
 static GObject *
 gdm_session_worker_constructor (GType                  type,
                                 guint                  n_construct_properties,
@@ -2902,6 +2924,11 @@ gdm_session_worker_constructor (GType                  type,
                 exit (1);
         }
 
+        /* Send an initial Hello message so that the session can associate
+         * the conversation we manage with our pid.
+         */
+        send_hello (worker);
+
         dbus_connection_setup_with_g_main (worker->priv->connection, NULL);
         dbus_connection_set_exit_on_disconnect (worker->priv->connection, TRUE);
 
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 1820e29..a7b4e8b 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -24,6 +24,7 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
+#include "gdm-marshal.h"
 #include "gdm-session.h"
 #include "gdm-session-private.h"
 
@@ -116,37 +117,41 @@ gdm_session_setup_for_user (GdmSession *session,
 }
 
 void
-gdm_session_authenticate (GdmSession *session)
+gdm_session_authenticate (GdmSession *session,
+                          const char *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->authenticate (session);
+        GDM_SESSION_GET_IFACE (session)->authenticate (session, service_name);
 }
 
 void
-gdm_session_authorize (GdmSession *session)
+gdm_session_authorize (GdmSession *session,
+                       const char *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->authorize (session);
+        GDM_SESSION_GET_IFACE (session)->authorize (session, service_name);
 }
 
 void
 gdm_session_accredit (GdmSession *session,
+                      const char *service_name,
                       int         flag)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->accredit (session, flag);
+        GDM_SESSION_GET_IFACE (session)->accredit (session, service_name, flag);
 }
 
 void
 gdm_session_answer_query (GdmSession *session,
+                          const char *service_name,
                           const char *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->answer_query (session, text);
+        GDM_SESSION_GET_IFACE (session)->answer_query (session, service_name, text);
 }
 
 void
@@ -194,19 +199,21 @@ gdm_session_cancel (GdmSession *session)
 }
 
 void
-gdm_session_open_session (GdmSession *session)
+gdm_session_open_session (GdmSession *session,
+                          const char *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->open_session (session);
+        GDM_SESSION_GET_IFACE (session)->open_session (session, service_name);
 }
 
 void
-gdm_session_start_session (GdmSession *session)
+gdm_session_start_session (GdmSession *session,
+                           const char *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        GDM_SESSION_GET_IFACE (session)->start_session (session);
+        GDM_SESSION_GET_IFACE (session)->start_session (session, service_name);
 }
 
 static void
@@ -223,7 +230,7 @@ gdm_session_class_init (gpointer g_iface)
                               NULL,
                               g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [SETUP_COMPLETE] =
                 g_signal_new ("setup-complete",
                               iface_type,
@@ -231,9 +238,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, setup_complete),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1,
+                              G_TYPE_STRING);
         signals [SETUP_FAILED] =
                 g_signal_new ("setup-failed",
                               iface_type,
@@ -241,10 +249,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, setup_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [RESET_COMPLETE] =
                 g_signal_new ("reset-complete",
                               iface_type,
@@ -273,9 +281,9 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, authenticated),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [AUTHENTICATION_FAILED] =
                 g_signal_new ("authentication-failed",
                               iface_type,
@@ -283,10 +291,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, authentication_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [AUTHORIZED] =
                 g_signal_new ("authorized",
                               iface_type,
@@ -294,9 +302,9 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, authorized),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [AUTHORIZATION_FAILED] =
                 g_signal_new ("authorization-failed",
                               iface_type,
@@ -304,10 +312,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, authorization_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [ACCREDITED] =
                 g_signal_new ("accredited",
                               iface_type,
@@ -315,9 +323,9 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, accredited),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1, G_TYPE_STRING);
         signals [ACCREDITATION_FAILED] =
                 g_signal_new ("accreditation-failed",
                               iface_type,
@@ -325,10 +333,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, accreditation_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
 
          signals [INFO_QUERY] =
                 g_signal_new ("info-query",
@@ -337,10 +345,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, info_query),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [SECRET_INFO_QUERY] =
                 g_signal_new ("secret-info-query",
                               iface_type,
@@ -348,10 +356,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, secret_info_query),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [INFO] =
                 g_signal_new ("info",
                               iface_type,
@@ -359,10 +367,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, info),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [PROBLEM] =
                 g_signal_new ("problem",
                               iface_type,
@@ -370,10 +378,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, problem),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [SESSION_OPENED] =
                 g_signal_new ("session-opened",
                               iface_type,
@@ -381,9 +389,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, session_opened),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
+                              g_cclosure_marshal_VOID__STRING,
                               G_TYPE_NONE,
-                              0);
+                              1,
+                              G_TYPE_STRING);
         signals [SESSION_OPEN_FAILED] =
                 g_signal_new ("session-open-failed",
                               iface_type,
@@ -391,10 +400,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, session_open_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [SESSION_STARTED] =
                 g_signal_new ("session-started",
                               iface_type,
@@ -402,10 +411,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, session_started),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__INT,
+                              gdm_marshal_VOID__STRING_INT,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_INT);
+                              2,
+                              G_TYPE_STRING, G_TYPE_INT);
         signals [SESSION_START_FAILED] =
                 g_signal_new ("session-start-failed",
                               iface_type,
@@ -413,10 +422,10 @@ gdm_session_class_init (gpointer g_iface)
                               G_STRUCT_OFFSET (GdmSessionIface, session_start_failed),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
         signals [SESSION_EXITED] =
                 g_signal_new ("session-exited",
                               iface_type,
@@ -496,19 +505,21 @@ gdm_session_class_init (gpointer g_iface)
 }
 
 void
-_gdm_session_setup_complete (GdmSession   *session)
+_gdm_session_setup_complete (GdmSession   *session,
+                             const char   *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        g_signal_emit (session, signals [SETUP_COMPLETE], 0);
+        g_signal_emit (session, signals [SETUP_COMPLETE], 0, service_name);
 }
 
 void
 _gdm_session_setup_failed (GdmSession   *session,
+                           const char   *service_name,
                            const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SETUP_FAILED], 0, text);
+        g_signal_emit (session, signals [SETUP_FAILED], 0, service_name, text);
 }
 
 void
@@ -528,114 +539,128 @@ _gdm_session_reset_failed (GdmSession   *session,
 }
 
 void
-_gdm_session_authenticated (GdmSession   *session)
+_gdm_session_authenticated (GdmSession   *session,
+                            const char   *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        g_signal_emit (session, signals [AUTHENTICATED], 0);
+        g_signal_emit (session, signals [AUTHENTICATED], 0, service_name);
 }
 
 void
 _gdm_session_authentication_failed (GdmSession   *session,
+                                    const char   *service_name,
                                     const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [AUTHENTICATION_FAILED], 0, text);
+        g_signal_emit (session, signals [AUTHENTICATION_FAILED], 0, service_name, text);
 }
 
 void
-_gdm_session_authorized (GdmSession   *session)
+_gdm_session_authorized (GdmSession   *session,
+                         const char   *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        g_signal_emit (session, signals [AUTHORIZED], 0);
+        g_signal_emit (session, signals [AUTHORIZED], 0, service_name);
 }
 
 void
 _gdm_session_authorization_failed (GdmSession   *session,
+                                   const char   *service_name,
                                    const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [AUTHORIZATION_FAILED], 0, text);
+        g_signal_emit (session, signals [AUTHORIZATION_FAILED], 0, service_name, text);
 }
 
 void
-_gdm_session_accredited (GdmSession   *session)
+_gdm_session_accredited (GdmSession   *session,
+                         const char   *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
 
-        g_signal_emit (session, signals [ACCREDITED], 0);
+        g_signal_emit (session, signals [ACCREDITED], 0, service_name);
 }
 
 void
 _gdm_session_accreditation_failed (GdmSession   *session,
+                                   const char   *service_name,
                                    const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [ACCREDITATION_FAILED], 0, text);
+        g_signal_emit (session, signals [ACCREDITATION_FAILED], 0, service_name, text);
 }
 
 void
 _gdm_session_info_query (GdmSession   *session,
+                         const char   *service_name,
                          const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [INFO_QUERY], 0, text);
+        g_signal_emit (session, signals [INFO_QUERY], 0, service_name, text);
 }
 
 void
 _gdm_session_secret_info_query (GdmSession   *session,
+                                const char   *service_name,
                                 const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SECRET_INFO_QUERY], 0, text);
+        g_signal_emit (session, signals [SECRET_INFO_QUERY], 0, service_name, text);
 }
 
 void
 _gdm_session_info (GdmSession   *session,
+                   const char   *service_name,
                    const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [INFO], 0, text);
+        g_signal_emit (session, signals [INFO], 0, service_name, text);
 }
 
 void
 _gdm_session_problem (GdmSession   *session,
+                      const char   *service_name,
                       const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [PROBLEM], 0, text);
+        g_signal_emit (session, signals [PROBLEM], 0, service_name, text);
 }
 
 void
-_gdm_session_session_opened (GdmSession   *session)
+_gdm_session_session_opened (GdmSession   *session,
+                             const char   *service_name)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SESSION_OPENED], 0);
+        g_signal_emit (session, signals [SESSION_OPENED], 0, service_name);
 }
 
 void
 _gdm_session_session_open_failed (GdmSession   *session,
+                                  const char   *service_name,
                                   const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SESSION_OPEN_FAILED], 0, text);
+        g_signal_emit (session, signals [SESSION_OPEN_FAILED], 0, service_name, text);
 }
 
 void
 _gdm_session_session_started (GdmSession   *session,
+                              const char   *service_name,
                               int           pid)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SESSION_STARTED], 0, pid);
+        g_signal_emit (session, signals [SESSION_STARTED], 0, service_name, pid);
 }
 
 void
 _gdm_session_session_start_failed (GdmSession   *session,
+                                   const char   *service_name,
                                    const char   *text)
 {
         g_return_if_fail (GDM_IS_SESSION (session));
-        g_signal_emit (session, signals [SESSION_START_FAILED], 0, text);
+        g_signal_emit (session, signals [SESSION_START_FAILED], 0, service_name, text);
 }
 
 void
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 00c2fa4..20a442b 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -53,12 +53,17 @@ struct _GdmSessionIface
                                               const char   *service_name,
                                               const char   *username);
         void (* reset)                       (GdmSession   *session);
-        void (* authenticate)                (GdmSession   *session);
-        void (* authorize)                   (GdmSession   *session);
+        void (* authenticate)                (GdmSession   *session,
+                                              const char   *service_name);
+        void (* authorize)                   (GdmSession   *session,
+                                              const char   *service_name);
         void (* accredit)                    (GdmSession   *session,
+                                              const char   *service_name,
                                               int           cred_flag);
-        void (* open_session)                (GdmSession   *session);
+        void (* open_session)                (GdmSession   *session,
+                                              const char   *service_name);
         void (* answer_query)                (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *text);
         void (* select_language)             (GdmSession   *session,
                                               const char   *text);
@@ -68,41 +73,58 @@ struct _GdmSessionIface
                                               const char   *text);
         void (* select_user)                 (GdmSession   *session,
                                               const char   *text);
-        void (* start_session)               (GdmSession   *session);
+        void (* start_session)               (GdmSession   *session,
+                                              const char   *service_name);
         void (* close)                       (GdmSession   *session);
         void (* cancel)                      (GdmSession   *session);
 
         /* Signals */
-        void (* setup_complete)              (GdmSession   *session);
+        void (* setup_complete)              (GdmSession   *session,
+                                              const char   *service_name);
         void (* setup_failed)                (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
         void (* reset_complete)              (GdmSession   *session);
         void (* reset_failed)                (GdmSession   *session,
                                               const char   *message);
-        void (* authenticated)               (GdmSession   *session);
+        void (* authenticated)               (GdmSession   *session,
+                                              const char   *service_name);
         void (* authentication_failed)       (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
-        void (* authorized)                  (GdmSession   *session);
+        void (* authorized)                  (GdmSession   *session,
+                                              const char   *service_name);
         void (* authorization_failed)        (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
-        void (* accredited)                  (GdmSession   *session);
+        void (* accredited)                  (GdmSession   *session,
+                                              const char   *service_name);
         void (* accreditation_failed)        (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
 
         void (* info_query)                  (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *query_text);
         void (* secret_info_query)           (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *query_text);
         void (* info)                        (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *info);
         void (* problem)                     (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *problem);
-        void (* session_opened)              (GdmSession   *session);
+        void (* session_opened)              (GdmSession   *session,
+                                              const char   *service_name);
         void (* session_open_failed)         (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
         void (* session_started)             (GdmSession   *session,
+                                              const char   *service_name,
                                               int           pid);
         void (* session_start_failed)        (GdmSession   *session,
+                                              const char   *service_name,
                                               const char   *message);
         void (* session_exited)              (GdmSession   *session,
                                               int           exit_code);
@@ -132,15 +154,21 @@ void     gdm_session_setup_for_user              (GdmSession *session,
                                                   const char *service_name,
                                                   const char *username);
 void     gdm_session_reset                       (GdmSession *session);
-void     gdm_session_authenticate                (GdmSession *session);
-void     gdm_session_authorize                   (GdmSession *session);
+void     gdm_session_authenticate                (GdmSession *session,
+                                                  const char *service_name);
+void     gdm_session_authorize                   (GdmSession *session,
+                                                  const char *service_name);
 void     gdm_session_accredit                    (GdmSession *session,
+                                                  const char *service_name,
                                                   int         cred_flag);
-void     gdm_session_open_session                (GdmSession *session);
-void     gdm_session_start_session               (GdmSession *session);
+void     gdm_session_open_session                (GdmSession *session,
+                                                  const char *service_name);
+void     gdm_session_start_session               (GdmSession *session,
+                                                  const char *service_name);
 void     gdm_session_close                       (GdmSession *session);
 
 void     gdm_session_answer_query                (GdmSession *session,
+                                                  const char *service_name,
                                                   const char *text);
 void     gdm_session_select_session              (GdmSession *session,
                                                   const char *session_name);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index a0b01e2..fed2e8b 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -71,6 +71,8 @@ struct GdmSimpleSlavePrivate
         guint              greeter_reset_id;
         guint              start_session_id;
 
+        char              *start_session_service_name;
+
         int                ping_interval;
 
         GPid               server_pid;
@@ -101,6 +103,7 @@ static void start_greeter      (GdmSimpleSlave *slave);
 
 static void
 on_session_started (GdmSession       *session,
+                    const char       *service_name,
                     int               pid,
                     GdmSimpleSlave   *slave)
 {
@@ -209,19 +212,22 @@ queue_greeter_reset (GdmSimpleSlave *slave)
 
 static void
 on_session_setup_complete (GdmSession     *session,
+                           const char     *service_name,
                            GdmSimpleSlave *slave)
 {
-        gdm_session_authenticate (session);
+        gdm_session_authenticate (session, service_name);
 }
 
 static void
 on_session_setup_failed (GdmSession     *session,
+                         const char     *service_name,
                          const char     *message,
                          GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
                 gdm_greeter_server_problem (slave->priv->greeter_server,
-                                           message != NULL ? message:  _("Unable to initialize login system"));
+                                            service_name,
+                                            message != NULL ? message:  _("Unable to initialize login system"));
         }
 
         destroy_session (slave);
@@ -245,18 +251,21 @@ on_session_reset_failed (GdmSession     *session,
 
 static void
 on_session_authenticated (GdmSession     *session,
+                          const char     *service_name,
                           GdmSimpleSlave *slave)
 {
-        gdm_session_authorize (session);
+        gdm_session_authorize (session, service_name);
 }
 
 static void
 on_session_authentication_failed (GdmSession     *session,
+                                  const char     *service_name,
                                   const char     *message,
                                   GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
                 gdm_greeter_server_problem (slave->priv->greeter_server,
+                                            service_name,
                                             message != NULL ? message : _("Unable to authenticate user"));
         }
         destroy_session (slave);
@@ -264,7 +273,8 @@ on_session_authentication_failed (GdmSession     *session,
 }
 
 static void
-gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
+gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave,
+                                      const char     *service_name)
 {
         if (slave->priv->start_session_when_ready) {
                 char *ssid;
@@ -285,7 +295,7 @@ gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
                 g_free (ssid);
                 g_free (username);
 
-                gdm_session_accredit (GDM_SESSION (slave->priv->session), cred_flag);
+                gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, cred_flag);
         } else {
                 slave->priv->waiting_to_start_session = TRUE;
         }
@@ -293,25 +303,28 @@ gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
 
 static void
 on_session_authorized (GdmSession     *session,
+                       const char     *service_name,
                        GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
-                gdm_greeter_server_user_authorized (slave->priv->greeter_server);
-                gdm_simple_slave_accredit_when_ready (slave);
+                gdm_greeter_server_user_authorized (slave->priv->greeter_server, service_name);
+                gdm_simple_slave_accredit_when_ready (slave, service_name);
         } else {
                 slave->priv->start_session_when_ready = TRUE;
-                gdm_simple_slave_accredit_when_ready (slave);
+                gdm_simple_slave_accredit_when_ready (slave, service_name);
         }
 }
 
 static void
 on_session_authorization_failed (GdmSession     *session,
+                                 const char     *service_name,
                                  const char     *message,
                                  GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
                 gdm_greeter_server_problem (slave->priv->greeter_server,
-                                           message != NULL ? message :  _("Unable to authorize user"));
+                                            service_name,
+                                            message != NULL ? message :  _("Unable to authorize user"));
         }
 
         destroy_session (slave);
@@ -397,31 +410,38 @@ start_session_timeout (GdmSimpleSlave *slave)
 
         g_free (auth_file);
 
-        gdm_session_start_session (GDM_SESSION (slave->priv->session));
+        gdm_session_start_session (GDM_SESSION (slave->priv->session),
+                                   slave->priv->start_session_service_name);
  out:
         slave->priv->start_session_id = 0;
+        g_free (slave->priv->start_session_service_name);
+        slave->priv->start_session_service_name = NULL;
         return FALSE;
 }
 
 static void
-queue_start_session (GdmSimpleSlave *slave)
+queue_start_session (GdmSimpleSlave *slave,
+                     const char     *service_name)
 {
         if (slave->priv->start_session_id > 0) {
                 return;
         }
 
         slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave);
+        slave->priv->start_session_service_name = g_strdup (service_name);
 }
 
 static void
 on_session_accredited (GdmSession     *session,
+                       const char     *service_name,
                        GdmSimpleSlave *slave)
 {
-        gdm_session_open_session (session);
+        gdm_session_open_session (session, service_name);
 }
 
 static void
 on_session_accreditation_failed (GdmSession     *session,
+                                 const char     *service_name,
                                  const char     *message,
                                  GdmSimpleSlave *slave)
 {
@@ -442,6 +462,7 @@ on_session_accreditation_failed (GdmSession     *session,
                                 problem = _("Unable to establish credentials");
                         }
                         gdm_greeter_server_problem (slave->priv->greeter_server,
+                                                    service_name,
                                                     problem);
                 }
         }
@@ -457,62 +478,68 @@ on_session_accreditation_failed (GdmSession     *session,
 
 static void
 on_session_opened (GdmSession     *session,
+                   const char     *service_name,
                    GdmSimpleSlave *slave)
 {
-        queue_start_session (slave);
+        queue_start_session (slave, service_name);
 }
 
 static void
 on_session_open_failed (GdmSession     *session,
+                        const char     *service_name,
                         const char     *message,
                         GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
                 gdm_greeter_server_problem (slave->priv->greeter_server,
+                                            service_name,
                                             _("Unable to open session"));
         }
 
-        destroy_session (slave);
-        queue_greeter_reset (slave);
+        gdm_session_stop_conversation (session, service_name);
 }
 
 static void
 on_session_info (GdmSession     *session,
+                 const char     *service_name,
                  const char     *text,
                  GdmSimpleSlave *slave)
 {
         g_debug ("GdmSimpleSlave: Info: %s", text);
         if (slave->priv->greeter_server != NULL) {
-                gdm_greeter_server_info (slave->priv->greeter_server, text);
+                gdm_greeter_server_info (slave->priv->greeter_server, service_name, text);
         }
 }
 
 static void
 on_session_problem (GdmSession     *session,
+                    const char     *service_name,
                     const char     *text,
                     GdmSimpleSlave *slave)
 {
         g_debug ("GdmSimpleSlave: Problem: %s", text);
-        gdm_greeter_server_problem (slave->priv->greeter_server, text);
+        gdm_greeter_server_problem (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_info_query (GdmSession     *session,
+                       const char     *service_name,
                        const char     *text,
                        GdmSimpleSlave *slave)
 {
 
         g_debug ("GdmSimpleSlave: Info query: %s", text);
-        gdm_greeter_server_info_query (slave->priv->greeter_server, text);
+        gdm_greeter_server_info_query (slave->priv->greeter_server, service_name, text);
 }
 
 static void
 on_session_secret_info_query (GdmSession     *session,
+                              const char     *service_name,
                               const char     *text,
                               GdmSimpleSlave *slave)
 {
         g_debug ("GdmSimpleSlave: Secret info query: %s", text);
-        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
+        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, service_name, text);
 }
 
 static void
@@ -790,11 +817,12 @@ on_greeter_start_conversation (GdmGreeterServer *greeter_server,
 
 static void
 on_greeter_begin_verification (GdmGreeterServer *greeter_server,
+                               const char       *service_name,
                                GdmSimpleSlave   *slave)
 {
         g_debug ("GdmSimpleSlave: begin verification");
         gdm_session_setup (GDM_SESSION (slave->priv->session),
-                           "gdm");
+                           service_name);
 }
 
 static void
@@ -810,21 +838,23 @@ on_greeter_begin_auto_login (GdmGreeterServer *greeter_server,
 
 static void
 on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
+                                        const char       *service_name,
                                         const char       *username,
                                         GdmSimpleSlave   *slave)
 {
         g_debug ("GdmSimpleSlave: begin verification");
         gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
-                                    "gdm",
+                                    service_name,
                                     username);
 }
 
 static void
 on_greeter_answer (GdmGreeterServer *greeter_server,
+                   const char       *service_name,
                    const char       *text,
                    GdmSimpleSlave   *slave)
 {
-        gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
+        gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
 }
 
 static void
@@ -887,18 +917,20 @@ on_greeter_connected (GdmGreeterServer *greeter_server,
 
 static void
 on_start_session_when_ready (GdmGreeterServer *session,
+                             const char       *service_name,
                              GdmSimpleSlave   *slave)
 {
         g_debug ("GdmSimpleSlave: Will start session when ready");
         slave->priv->start_session_when_ready = TRUE;
 
         if (slave->priv->waiting_to_start_session) {
-                gdm_simple_slave_accredit_when_ready (slave);
+                gdm_simple_slave_accredit_when_ready (slave, service_name);
         }
 }
 
 static void
 on_start_session_later (GdmGreeterServer *session,
+                        const char       *service_name,
                         GdmSimpleSlave   *slave)
 {
         g_debug ("GdmSimpleSlave: Will start session when ready and told");
diff --git a/daemon/test-session.c b/daemon/test-session.c
index ed13ff7..7f6c5fe 100644
--- a/daemon/test-session.c
+++ b/daemon/test-session.c
@@ -44,10 +44,11 @@ on_conversation_started (GdmSession *session,
 
 static void
 on_session_setup_complete (GdmSession *session,
+                           const char *service_name,
                            gpointer    data)
 {
         g_debug ("Session setup complete");
-        gdm_session_authenticate (session);
+        gdm_session_authenticate (session, service_name);
 }
 
 static void
@@ -79,10 +80,11 @@ on_session_reset_failed (GdmSession *session,
 
 static void
 on_session_authenticated (GdmSession *session,
+                          const char *service_name,
                           gpointer    data)
 {
         g_debug ("Session authenticated");
-        gdm_session_authorize (session);
+        gdm_session_authorize (session, service_name);
 }
 
 static void
@@ -97,14 +99,16 @@ on_session_authentication_failed (GdmSession *session,
 
 static void
 on_session_authorized (GdmSession *session,
+                       const char *service_name,
                        gpointer    data)
 {
         g_debug ("Session authorized");
-        gdm_session_accredit (session, GDM_SESSION_CRED_ESTABLISH);
+        gdm_session_accredit (session, service_name, GDM_SESSION_CRED_ESTABLISH);
 }
 
 static void
 on_session_authorization_failed (GdmSession *session,
+                                 const char *service_name,
                                  const char *message,
                                  gpointer    data)
 {
@@ -115,6 +119,7 @@ on_session_authorization_failed (GdmSession *session,
 
 static void
 on_session_accredited (GdmSession *session,
+                       const char *service_name,
                        gpointer    data)
 {
         char *username;
@@ -125,12 +130,13 @@ on_session_accredited (GdmSession *session,
                  username ? username : "", username ? " " : "");
         g_free (username);
 
-        gdm_session_start_session (session);
+        gdm_session_start_session (session, service_name);
 
 }
 
 static void
 on_session_accreditation_failed (GdmSession *session,
+                                 const char *service_name,
                                  const char *message,
                                  gpointer    data)
 {
@@ -165,6 +171,7 @@ on_session_died (GdmSession *session,
 
 static void
 on_info_query (GdmSession *session,
+               const char *service_name,
                const char *query_text)
 {
         char answer[1024];
@@ -178,12 +185,13 @@ on_info_query (GdmSession *session,
                 gdm_session_close (session);
                 g_main_loop_quit (loop);
         } else {
-                gdm_session_answer_query (session, answer);
+                gdm_session_answer_query (session, service_name, answer);
         }
 }
 
 static void
 on_info (GdmSession *session,
+         const char *service_name,
          const char *info)
 {
         g_print ("\n** NOTE: %s\n", info);
@@ -191,6 +199,7 @@ on_info (GdmSession *session,
 
 static void
 on_problem (GdmSession *session,
+            const char *service_name,
             const char *problem)
 {
         g_print ("\n** WARNING: %s\n", problem);
@@ -198,6 +207,7 @@ on_problem (GdmSession *session,
 
 static void
 on_secret_info_query (GdmSession *session,
+                      const char *service_name,
                       const char *query_text)
 {
         char           answer[1024];
@@ -222,7 +232,7 @@ on_secret_info_query (GdmSession *session,
 
         g_print ("\n");
 
-        gdm_session_answer_query (session, answer);
+        gdm_session_answer_query (session, service_name, answer);
 }
 
 static void
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
index 8d061a4..0891e8b 100644
--- a/gui/simple-greeter/gdm-greeter-client.c
+++ b/gui/simple-greeter/gdm-greeter-client.c
@@ -134,6 +134,37 @@ emit_string_and_int_signal_for_message (GdmGreeterClient *client,
 }
 
 static void
+emit_string_and_string_signal_for_message (GdmGreeterClient *client,
+                                           const char       *name,
+                                           DBusMessage      *message,
+                                           int               signal)
+{
+        DBusError   error;
+        char *text1;
+        char *text2;
+        dbus_bool_t res;
+
+        dbus_error_init (&error);
+        res = dbus_message_get_args (message,
+                                     &error,
+                                     DBUS_TYPE_STRING, &text1,
+                                     DBUS_TYPE_STRING, &text2,
+                                     DBUS_TYPE_INVALID);
+        if (res) {
+
+                g_debug ("GdmGreeterClient: Received %s (%s, %s)", name, text1, text2);
+
+                g_signal_emit (client,
+                               gdm_greeter_client_signals[signal],
+                               0, text1, text2);
+        } else {
+                g_warning ("Unable to get arguments: %s", error.message);
+                dbus_error_free (&error);
+        }
+        dbus_error_free (&error);
+}
+
+static void
 emit_string_signal_for_message (GdmGreeterClient *client,
                                 const char       *name,
                                 DBusMessage      *message,
@@ -200,37 +231,35 @@ static void
 on_user_authorized (GdmGreeterClient *client,
                     DBusMessage      *message)
 {
-        g_signal_emit (client,
-                       gdm_greeter_client_signals[USER_AUTHORIZED],
-                       0);
+        emit_string_signal_for_message (client, "UserAuthorized", message, USER_AUTHORIZED);
 }
 
 static void
 on_info_query (GdmGreeterClient *client,
                DBusMessage      *message)
 {
-        emit_string_signal_for_message (client, "InfoQuery", message, INFO_QUERY);
+        emit_string_and_string_signal_for_message (client, "InfoQuery", message, INFO_QUERY);
 }
 
 static void
 on_secret_info_query (GdmGreeterClient *client,
                       DBusMessage      *message)
 {
-        emit_string_signal_for_message (client, "SecretInfoQuery", message, SECRET_INFO_QUERY);
+        emit_string_and_string_signal_for_message (client, "SecretInfoQuery", message, SECRET_INFO_QUERY);
 }
 
 static void
 on_info (GdmGreeterClient *client,
          DBusMessage      *message)
 {
-        emit_string_signal_for_message (client, "Info", message, INFO);
+        emit_string_and_string_signal_for_message (client, "Info", message, INFO);
 }
 
 static void
 on_problem (GdmGreeterClient *client,
             DBusMessage      *message)
 {
-        emit_string_signal_for_message (client, "Problem", message, PROBLEM);
+        emit_string_and_string_signal_for_message (client, "Problem", message, PROBLEM);
 }
 
 static void
@@ -307,14 +336,22 @@ send_dbus_string_method (DBusConnection *connection,
 }
 
 static gboolean
-send_dbus_bool_method (DBusConnection *connection,
-                       const char     *method,
-                       gboolean        payload)
+send_dbus_string_and_bool_method (DBusConnection *connection,
+                                  const char     *method,
+                                  const char     *string_payload,
+                                  gboolean        bool_payload)
 {
         DBusError       error;
         DBusMessage    *message;
         DBusMessage    *reply;
         DBusMessageIter iter;
+        const char     *str;
+
+        if (string_payload != NULL) {
+                str = string_payload;
+        } else {
+                str = "";
+        }
 
         g_debug ("GdmGreeterClient: Calling %s", method);
         message = dbus_message_new_method_call (NULL,
@@ -328,8 +365,77 @@ send_dbus_bool_method (DBusConnection *connection,
 
         dbus_message_iter_init_append (message, &iter);
         dbus_message_iter_append_basic (&iter,
+                                        DBUS_TYPE_STRING,
+                                        &str);
+
+        dbus_message_iter_append_basic (&iter,
                                         DBUS_TYPE_BOOLEAN,
-                                        &payload);
+                                        &bool_payload);
+
+        dbus_error_init (&error);
+        reply = dbus_connection_send_with_reply_and_block (connection,
+                                                           message,
+                                                           -1,
+                                                           &error);
+
+        dbus_message_unref (message);
+
+        if (dbus_error_is_set (&error)) {
+                g_warning ("%s %s raised: %s\n",
+                           method,
+                           error.name,
+                           error.message);
+                return FALSE;
+        }
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+        dbus_connection_flush (connection);
+
+        return TRUE;
+}
+
+static gboolean
+send_dbus_string_and_string_method (DBusConnection *connection,
+                                    const char     *method,
+                                    const char     *payload1,
+                                    const char     *payload2)
+{
+        DBusError       error;
+        DBusMessage    *message;
+        DBusMessage    *reply;
+        DBusMessageIter iter;
+        const char     *str;
+
+        g_debug ("GdmGreeterClient: Calling %s", method);
+        message = dbus_message_new_method_call (NULL,
+                                                GREETER_SERVER_DBUS_PATH,
+                                                GREETER_SERVER_DBUS_INTERFACE,
+                                                method);
+        if (message == NULL) {
+                g_warning ("Couldn't allocate the D-Bus message");
+                return FALSE;
+        }
+
+        dbus_message_iter_init_append (message, &iter);
+
+        if (payload1 != NULL) {
+                str = payload1;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter,
+                                        DBUS_TYPE_STRING,
+                                        &str);
+
+        if (payload2 != NULL) {
+                str = payload2;
+        } else {
+                str = "";
+        }
+        dbus_message_iter_append_basic (&iter,
+                                        DBUS_TYPE_STRING,
+                                        &str);
 
         dbus_error_init (&error);
         reply = dbus_connection_send_with_reply_and_block (connection,
@@ -412,37 +518,44 @@ gdm_greeter_client_call_begin_auto_login (GdmGreeterClient *client,
 }
 
 void
-gdm_greeter_client_call_begin_verification (GdmGreeterClient *client)
+gdm_greeter_client_call_begin_verification (GdmGreeterClient *client,
+                                            const char       *service_name)
 {
-        send_dbus_void_method (client->priv->connection,
-                               "BeginVerification");
+        send_dbus_string_method (client->priv->connection,
+                                 "BeginVerification", service_name);
 }
 
 void
 gdm_greeter_client_call_begin_verification_for_user (GdmGreeterClient *client,
+                                                     const char       *service_name,
                                                      const char       *username)
 {
-        send_dbus_string_method (client->priv->connection,
-                                 "BeginVerificationForUser",
-                                 username);
+        send_dbus_string_and_string_method (client->priv->connection,
+                                            "BeginVerificationForUser",
+                                            service_name,
+                                            username);
 }
 
 void
 gdm_greeter_client_call_answer_query (GdmGreeterClient *client,
+                                      const char       *service_name,
                                       const char       *text)
 {
-        send_dbus_string_method (client->priv->connection,
-                                 "AnswerQuery",
-                                 text);
+        send_dbus_string_and_string_method (client->priv->connection,
+                                            "AnswerQuery",
+                                            service_name,
+                                            text);
 }
 
 void
 gdm_greeter_client_call_start_session_when_ready  (GdmGreeterClient *client,
+                                                   const char       *service_name,
                                                    gboolean          should_start_session)
 {
-        send_dbus_bool_method (client->priv->connection,
-                               "StartSessionWhenReady",
-                               should_start_session);
+        send_dbus_string_and_bool_method (client->priv->connection,
+                                          "StartSessionWhenReady",
+                                          service_name,
+                                          should_start_session);
 }
 
 void
@@ -835,10 +948,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterClientClass, info_query),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
 
         gdm_greeter_client_signals[SECRET_INFO_QUERY] =
                 g_signal_new ("secret-info-query",
@@ -847,10 +960,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterClientClass, secret_info_query),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
 
         gdm_greeter_client_signals[INFO] =
                 g_signal_new ("info",
@@ -859,10 +972,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterClientClass, info),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
 
         gdm_greeter_client_signals[PROBLEM] =
                 g_signal_new ("problem",
@@ -871,10 +984,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterClientClass, problem),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__STRING,
+                              gdm_marshal_VOID__STRING_STRING,
                               G_TYPE_NONE,
-                              1,
-                              G_TYPE_STRING);
+                              2,
+                              G_TYPE_STRING, G_TYPE_STRING);
 
         gdm_greeter_client_signals[READY] =
                 g_signal_new ("ready",
@@ -956,8 +1069,9 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
                               G_STRUCT_OFFSET (GdmGreeterClientClass, user_authorized),
                               NULL,
                               NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE, 0);
+                              g_cclosure_marshal_VOID__STRING,
+                              G_TYPE_NONE,
+                              1, G_TYPE_STRING);
 }
 
 static void
diff --git a/gui/simple-greeter/gdm-greeter-client.h b/gui/simple-greeter/gdm-greeter-client.h
index 88b0281..2f857dc 100644
--- a/gui/simple-greeter/gdm-greeter-client.h
+++ b/gui/simple-greeter/gdm-greeter-client.h
@@ -45,17 +45,22 @@ typedef struct
         GObjectClass   parent_class;
 
         void (* info_query)              (GdmGreeterClient  *client,
+                                          const char        *service_name,
                                           const char        *query_text);
 
         void (* secret_info_query)       (GdmGreeterClient  *client,
+                                          const char        *service_name,
                                           const char        *query_text);
 
         void (* info)                    (GdmGreeterClient  *client,
+                                          const char        *service_name,
                                           const char        *info);
 
         void (* problem)                 (GdmGreeterClient  *client,
+                                          const char        *service_name,
                                           const char        *problem);
-        void (* ready)                   (GdmGreeterClient  *client);
+        void (* ready)                   (GdmGreeterClient  *client,
+                                          const char        *service_name);
         void (* reset)                   (GdmGreeterClient  *client);
         void (* selected_user_changed)   (GdmGreeterClient  *client,
                                           const char        *username);
@@ -69,7 +74,8 @@ typedef struct
         void (* timed_login_requested)   (GdmGreeterClient  *client,
                                           const char        *username,
                                           int                delay);
-        void (* user_authorized)         (GdmGreeterClient  *client);
+        void (* user_authorized)         (GdmGreeterClient  *client,
+                                          const char        *service_name);
 } GdmGreeterClientClass;
 
 #define GDM_GREETER_CLIENT_ERROR (gdm_greeter_client_error_quark ())
@@ -95,8 +101,10 @@ void               gdm_greeter_client_call_start_conversation        (GdmGreeter
                                                                       const char       *service_name);
 void               gdm_greeter_client_call_begin_auto_login          (GdmGreeterClient *client,
                                                                       const char       *username);
-void               gdm_greeter_client_call_begin_verification        (GdmGreeterClient *client);
+void               gdm_greeter_client_call_begin_verification        (GdmGreeterClient *client,
+                                                                      const char       *service_name);
 void               gdm_greeter_client_call_begin_verification_for_user (GdmGreeterClient *client,
+                                                                        const char       *service_name,
                                                                         const char       *username);
 void               gdm_greeter_client_call_cancel                    (GdmGreeterClient *client);
 void               gdm_greeter_client_call_disconnect                (GdmGreeterClient *client);
@@ -111,9 +119,11 @@ void               gdm_greeter_client_call_select_layout             (GdmGreeter
 void               gdm_greeter_client_call_select_session            (GdmGreeterClient *client,
                                                                       const char       *text);
 void               gdm_greeter_client_call_answer_query              (GdmGreeterClient *client,
+                                                                      const char       *service_name,
                                                                       const char       *text);
 
 void               gdm_greeter_client_call_start_session_when_ready  (GdmGreeterClient *client,
+                                                                      const char       *service_name,
                                                                       gboolean          should_start_session);
 
 
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
index cd0cbdf..e856dd4 100644
--- a/gui/simple-greeter/gdm-greeter-session.c
+++ b/gui/simple-greeter/gdm-greeter-session.c
@@ -65,6 +65,7 @@ static gpointer session_object = NULL;
 
 static void
 on_info (GdmGreeterClient  *client,
+         const char        *service_name,
          const char        *text,
          GdmGreeterSession *session)
 {
@@ -75,6 +76,7 @@ on_info (GdmGreeterClient  *client,
 
 static void
 on_problem (GdmGreeterClient  *client,
+            const char        *service_name,
             const char        *text,
             GdmGreeterSession *session)
 {
@@ -173,6 +175,7 @@ on_user_authorized (GdmGreeterClient  *client,
 
 static void
 on_info_query (GdmGreeterClient  *client,
+               const char        *service_name,
                const char        *text,
                GdmGreeterSession *session)
 {
@@ -183,6 +186,7 @@ on_info_query (GdmGreeterClient  *client,
 
 static void
 on_secret_info_query (GdmGreeterClient  *client,
+                      const char        *service_name,
                       const char        *text,
                       GdmGreeterSession *session)
 {
@@ -204,7 +208,8 @@ static void
 on_begin_verification (GdmGreeterLoginWindow *login_window,
                        GdmGreeterSession     *session)
 {
-        gdm_greeter_client_call_begin_verification (session->priv->client);
+        gdm_greeter_client_call_begin_verification (session->priv->client,
+                                                    "gdm");
 }
 
 static void
@@ -213,6 +218,7 @@ on_begin_verification_for_user (GdmGreeterLoginWindow *login_window,
                                 GdmGreeterSession     *session)
 {
         gdm_greeter_client_call_begin_verification_for_user (session->priv->client,
+                                                             "gdm",
                                                              username);
 }
 
@@ -222,6 +228,7 @@ on_query_answer (GdmGreeterLoginWindow *login_window,
                  GdmGreeterSession     *session)
 {
         gdm_greeter_client_call_answer_query (session->priv->client,
+                                              "gdm",
                                               text);
 }
 
@@ -285,7 +292,7 @@ static void
 on_start_session (GdmGreeterLoginWindow *login_window,
                   GdmGreeterSession     *session)
 {
-        gdm_greeter_client_call_start_session_when_ready (session->priv->client, TRUE);
+        gdm_greeter_client_call_start_session_when_ready (session->priv->client, "gdm", TRUE);
 }
 
 static int



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