diff options
author | Ray Strode <rstrode@redhat.com> | 2009-03-09 15:41:12 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2009-04-17 10:24:48 -0400 |
commit | 66e8c2a4e38fc9bdd60b83c9bed480ed3bc90358 (patch) | |
tree | 5c59db4f4e1bf7c4ff5455635eb6a811959fbdf2 | |
parent | 75d9abdf87e20d4382882f47f1434381f0a944bf (diff) | |
download | gdm-66e8c2a4e38fc9bdd60b83c9bed480ed3bc90358.tar.gz |
Don't tear down greeter until pam_open_session finishes
Some PAM modules ask questions at that late stage of the game,
and so we need a greeter to forward the questions on to the
user.
-rw-r--r-- | daemon/gdm-factory-slave.c | 37 | ||||
-rw-r--r-- | daemon/gdm-product-slave.c | 30 | ||||
-rw-r--r-- | daemon/gdm-session-direct.c | 70 | ||||
-rw-r--r-- | daemon/gdm-session-private.h | 5 | ||||
-rw-r--r-- | daemon/gdm-session-relay.c | 68 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 16 | ||||
-rw-r--r-- | daemon/gdm-session.c | 50 | ||||
-rw-r--r-- | daemon/gdm-session.h | 9 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 33 |
9 files changed, 310 insertions, 8 deletions
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c index 826612e5..ef6d2363 100644 --- a/daemon/gdm-factory-slave.c +++ b/daemon/gdm-factory-slave.c @@ -278,9 +278,7 @@ on_session_accredited (GdmSession *session, { g_debug ("GdmFactorySlave: session user verified"); - gdm_session_start_session (session, service_name); - - gdm_greeter_server_reset (slave->priv->greeter_server); + gdm_session_open_session (session, service_name); } static void @@ -298,6 +296,31 @@ on_session_accreditation_failed (GdmSession *session, } static void +on_session_opened (GdmSession *session, + const char *service_name, + GdmFactorySlave *slave) +{ + g_debug ("GdmFactorySlave: session opened"); + + 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, service_name, _("Unable to open session")); + + queue_greeter_reset (slave); +} + +static void on_session_session_started (GdmSession *session, GdmFactorySlave *slave) { @@ -767,6 +790,14 @@ gdm_factory_slave_start (GdmSlave *slave) G_CALLBACK (on_session_accreditation_failed), slave); g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session, + "session-opened", + G_CALLBACK (on_session_opened), + slave); + g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session, + "session-open-failed", + G_CALLBACK (on_session_open_failed), + slave); + g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session, "info", G_CALLBACK (on_session_info), slave); diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c index dd2e1bcf..93d83a1c 100644 --- a/daemon/gdm-product-slave.c +++ b/daemon/gdm-product-slave.c @@ -635,6 +635,27 @@ on_session_accreditation_failed (GdmSession *session, } static void +on_session_opened (GdmSession *session, + const char *service_name, + GdmProductSlave *slave) +{ + 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_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, @@ -1051,7 +1072,14 @@ create_new_session (GdmProductSlave *slave) "accreditation-failed", G_CALLBACK (on_session_accreditation_failed), slave); - + g_signal_connect (slave->priv->session, + "session-opened", + G_CALLBACK (on_session_opened), + slave); + g_signal_connect (slave->priv->session, + "session-open-failed", + G_CALLBACK (on_session_open_failed), + slave); g_signal_connect (slave->priv->session, "info", G_CALLBACK (on_session_info), diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c index e5296a45..805adbf3 100644 --- a/daemon/gdm-session-direct.c +++ b/daemon/gdm-session-direct.c @@ -945,6 +945,58 @@ gdm_session_direct_handle_problem (GdmSessionDirect *session, } static DBusHandlerResult +gdm_session_direct_handle_session_opened (GdmSessionDirect *session, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + + g_debug ("GdmSessionDirect: Handling SessionOpened"); + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + g_debug ("GdmSessionDirect: Emitting 'session-opened' signal"); + + _gdm_session_session_opened (GDM_SESSION (session), conversation->service_name); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_direct_handle_open_failed (GdmSessionDirect *session, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (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), conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult gdm_session_direct_handle_session_started (GdmSessionDirect *session, GdmSessionConversation *conversation, DBusMessage *message) @@ -1223,6 +1275,10 @@ session_worker_message (DBusConnection *connection, 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, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) { + 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, conversation, message); } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) { return gdm_session_direct_handle_session_started (session, conversation, message); } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) { @@ -2215,6 +2271,19 @@ setup_session_environment (GdmSessionDirect *session) } static void +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); + + conversation = find_conversation_by_name (impl, service_name); + send_dbus_void_signal (conversation, "OpenSession"); +} + +static void gdm_session_direct_start_session (GdmSession *session, const char *service_name) { @@ -2687,6 +2756,7 @@ gdm_session_iface_init (GdmSessionIface *iface) iface->authenticate = gdm_session_direct_authenticate; iface->authorize = gdm_session_direct_authorize; iface->accredit = gdm_session_direct_accredit; + iface->open_session = gdm_session_direct_open_session; iface->close = gdm_session_direct_close; iface->cancel = gdm_session_direct_cancel; diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h index 860c09c1..36781dd0 100644 --- a/daemon/gdm-session-private.h +++ b/daemon/gdm-session-private.h @@ -54,6 +54,11 @@ void _gdm_session_accredited (GdmSession *sessio void _gdm_session_accreditation_failed (GdmSession *session, const char *service_name, const char *text); +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); diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c index 6e15f75f..3bf8ed70 100644 --- a/daemon/gdm-session-relay.c +++ b/daemon/gdm-session-relay.c @@ -247,6 +247,14 @@ gdm_session_relay_accredit (GdmSession *session, } static void +gdm_session_relay_open_session (GdmSession *session, + const char *service_name) +{ + GdmSessionRelay *impl = GDM_SESSION_RELAY (session); + send_dbus_string_signal (impl, "OpenSession", service_name); +} + +static void gdm_session_relay_answer_query (GdmSession *session, const char *service_name, const char *text) @@ -678,6 +686,61 @@ handle_accreditation_failed (GdmSessionRelay *session_relay, return DBUS_HANDLER_RESULT_HANDLED; } +static DBusHandlerResult +handle_session_opened (GdmSessionRelay *session_relay, + DBusConnection *connection, + DBusMessage *message) +{ + 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: Session Opened"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (connection, reply, NULL); + dbus_message_unref (reply); + + _gdm_session_session_opened (GDM_SESSION (session_relay), service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +handle_session_open_failed (GdmSessionRelay *session_relay, + DBusConnection *connection, + DBusMessage *message) +{ + 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: Session Open Failed"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (connection, reply, NULL); + dbus_message_unref (reply); + + _gdm_session_session_open_failed (GDM_SESSION (session_relay), service_name, NULL); + + return DBUS_HANDLER_RESULT_HANDLED; +} static DBusHandlerResult handle_session_started (GdmSessionRelay *session_relay, @@ -794,6 +857,10 @@ session_handle_child_message (DBusConnection *connection, return handle_accredited (session_relay, connection, message); } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "AccreditationFailed")) { return handle_accreditation_failed (session_relay, connection, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SessionOpened")) { + return handle_session_opened (session_relay, connection, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SessionOpenFailed")) { + return handle_session_open_failed (session_relay, connection, message); } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SessionStarted")) { return handle_session_started (session_relay, connection, message); } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SessionStopped")) { @@ -1193,6 +1260,7 @@ gdm_session_iface_init (GdmSessionIface *iface) iface->authenticate = gdm_session_relay_authenticate; iface->authorize = gdm_session_relay_authorize; iface->accredit = gdm_session_relay_accredit; + iface->open_session = gdm_session_relay_open_session; iface->close = gdm_session_relay_close; iface->cancel = gdm_session_relay_cancel; diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 3b4288c6..b470d888 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -2197,13 +2197,13 @@ do_open_session (GdmSessionWorker *worker) res = gdm_session_worker_open_user_session (worker, &error); if (! res) { send_dbus_string_method (worker->priv->connection, - "StartFailed", + "OpenFailed", error->message); g_error_free (error); return; } - queue_state_change (worker); + send_dbus_void_method (worker->priv->connection, "SessionOpened"); } static void @@ -2319,7 +2319,7 @@ on_start_program (GdmSessionWorker *worker, const char *text; dbus_bool_t res; - /* FIXME: return error if not in ACCREDITED state */ + /* FIXME: return error if not in SESSION_OPENED state */ dbus_error_init (&error); res = dbus_message_get_args (message, @@ -2458,6 +2458,14 @@ on_establish_credentials (GdmSessionWorker *worker, } static void +on_open_session (GdmSessionWorker *worker, + DBusMessage *message) +{ + /* FIXME: return error if not in ACCREDITED state */ + queue_state_change (worker); +} + +static void on_reauthenticate (GdmSessionWorker *worker, DBusMessage *message) { @@ -2517,6 +2525,8 @@ worker_dbus_handle_message (DBusConnection *connection, on_authorize (worker, message); } else if (dbus_message_is_signal (message, GDM_SESSION_DBUS_INTERFACE, "EstablishCredentials")) { on_establish_credentials (worker, message); + } else if (dbus_message_is_signal (message, GDM_SESSION_DBUS_INTERFACE, "OpenSession")) { + on_open_session (worker, message); } else if (dbus_message_is_signal (message, GDM_SESSION_DBUS_INTERFACE, "StartProgram")) { on_start_program (worker, message); } else if (dbus_message_is_signal (message, GDM_SESSION_DBUS_INTERFACE, "Reauthenticate")) { diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index 9ee34af7..88580717 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -46,6 +46,8 @@ enum { PROBLEM, INFO_QUERY, SECRET_INFO_QUERY, + SESSION_OPENED, + SESSION_OPEN_FAILED, SESSION_STARTED, SESSION_START_FAILED, SESSION_EXITED, @@ -207,6 +209,15 @@ gdm_session_cancel (GdmSession *session) } void +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, service_name); +} + +void gdm_session_start_session (GdmSession *session, const char *service_name) { @@ -391,6 +402,28 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + signals [SESSION_OPENED] = + g_signal_new ("session-opened", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmSessionIface, session_opened), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + signals [SESSION_OPEN_FAILED] = + g_signal_new ("session-open-failed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmSessionIface, session_open_failed), + NULL, + NULL, + gdm_marshal_VOID__STRING_STRING, + G_TYPE_NONE, + 2, + G_TYPE_STRING, G_TYPE_STRING); signals [SESSION_STARTED] = g_signal_new ("session-started", iface_type, @@ -616,6 +649,23 @@ _gdm_session_problem (GdmSession *session, } void +_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, 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, service_name, text); +} + +void _gdm_session_session_started (GdmSession *session, const char *service_name, int pid) diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h index c45a7700..22c2ccba 100644 --- a/daemon/gdm-session.h +++ b/daemon/gdm-session.h @@ -62,6 +62,8 @@ struct _GdmSessionIface void (* accredit) (GdmSession *session, const char *service_name, int cred_flag); + void (* open_session) (GdmSession *session, + const char *service_name); void (* answer_query) (GdmSession *session, const char *service_name, const char *text); @@ -115,6 +117,11 @@ struct _GdmSessionIface void (* problem) (GdmSession *session, const char *service_name, const char *problem); + 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); @@ -160,6 +167,8 @@ void gdm_session_authorize (GdmSession *session, void gdm_session_accredit (GdmSession *session, const char *service_name, int cred_flag); +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); diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index d08613fb..17f5f7a3 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -423,7 +423,7 @@ on_session_accredited (GdmSession *session, const char *service_name, GdmSimpleSlave *slave) { - queue_start_session (slave, service_name); + gdm_session_open_session (session, service_name); } static void @@ -457,6 +457,29 @@ on_session_accreditation_failed (GdmSession *session, } static void +on_session_opened (GdmSession *session, + const char *service_name, + GdmSimpleSlave *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")); + } + + gdm_session_stop_conversation (session, service_name); +} + +static void on_session_info (GdmSession *session, const char *service_name, const char *text, @@ -688,6 +711,14 @@ create_new_session (GdmSimpleSlave *slave) G_CALLBACK (on_session_accreditation_failed), slave); g_signal_connect (slave->priv->session, + "session-opened", + G_CALLBACK (on_session_opened), + slave); + g_signal_connect (slave->priv->session, + "session-open-failed", + G_CALLBACK (on_session_open_failed), + slave); + g_signal_connect (slave->priv->session, "info", G_CALLBACK (on_session_info), slave); |