summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2009-10-28 21:32:00 -0400
committerRay Strode <rstrode@redhat.com>2011-06-13 20:33:47 -0400
commit0d92891917576227b40eca56c4b173b879aa8792 (patch)
treeaac34c6b9130eef2486cb4405114356a5ef162e8
parenta4f5409c77a1a30c7a7f5466e86c12197aee0743 (diff)
downloadgdm-0d92891917576227b40eca56c4b173b879aa8792.tar.gz
daemon: Distinguish "pam module failed" from "authentication failed"
If pam_start() fails, that suggests the configured service stack is failing independent of the user account. This commit exposes that failure as "service unavailable" instead of "authentication failed".
-rw-r--r--daemon/gdm-greeter-server.c13
-rw-r--r--daemon/gdm-greeter-server.h5
-rw-r--r--daemon/gdm-session-direct.c26
-rw-r--r--daemon/gdm-session-private.h2
-rw-r--r--daemon/gdm-session-relay.c33
-rw-r--r--daemon/gdm-session-worker.c29
-rw-r--r--daemon/gdm-session.c21
-rw-r--r--daemon/gdm-session.h2
-rw-r--r--daemon/gdm-simple-slave.c36
-rw-r--r--gui/simple-greeter/gdm-greeter-client.c20
-rw-r--r--gui/simple-greeter/gdm-greeter-client.h2
11 files changed, 154 insertions, 35 deletions
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
index c7501dbb..e1475a4c 100644
--- a/daemon/gdm-greeter-server.c
+++ b/daemon/gdm-greeter-server.c
@@ -285,9 +285,18 @@ gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
}
gboolean
-gdm_greeter_server_authentication_failed (GdmGreeterServer *greeter_server)
+gdm_greeter_server_authentication_failed (GdmGreeterServer *greeter_server,
+ const char *service_name)
{
- send_dbus_void_signal (greeter_server, "AuthenticationFailed");
+ send_dbus_string_signal (greeter_server, "AuthenticationFailed", service_name);
+ return TRUE;
+}
+
+gboolean
+gdm_greeter_server_service_unavailable (GdmGreeterServer *greeter_server,
+ const char *service_name)
+{
+ send_dbus_string_signal (greeter_server, "ServiceUnavailable", service_name);
return TRUE;
}
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
index faa68961..c4c66a12 100644
--- a/daemon/gdm-greeter-server.h
+++ b/daemon/gdm-greeter-server.h
@@ -91,7 +91,10 @@ gboolean gdm_greeter_server_info (GdmGreeterServer *
gboolean gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
const char *service_name,
const char *text);
-gboolean gdm_greeter_server_authentication_failed (GdmGreeterServer *greeter_server);
+gboolean gdm_greeter_server_authentication_failed (GdmGreeterServer *greeter_server,
+ const char *service_name);
+gboolean gdm_greeter_server_service_unavailable (GdmGreeterServer *greeter_server,
+ const char *service_name);
gboolean gdm_greeter_server_reset (GdmGreeterServer *greeter_server);
gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
const char *service_name);
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 8c2b0b2d..fa8ae49d 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -281,9 +281,27 @@ on_session_exited (GdmSession *session,
}
static DBusHandlerResult
-gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
- GdmSessionConversation *conversation,
- DBusMessage *message)
+gdm_session_direct_handle_service_unavailable (GdmSessionDirect *session,
+ GdmSessionConversation *conversation,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+
+ g_debug ("GdmSessionDirect: Emitting 'service-unavailable' signal");
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ _gdm_session_service_unavailable (GDM_SESSION (session), conversation->service_name);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
+ GdmSessionConversation *conversation,
+ DBusMessage *message)
{
DBusMessage *reply;
@@ -1237,6 +1255,8 @@ session_worker_message (DBusConnection *connection,
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, conversation, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ServiceUnavailable")) {
+ return gdm_session_direct_handle_service_unavailable (session, conversation, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupComplete")) {
return gdm_session_direct_handle_setup_complete (session, conversation, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupFailed")) {
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
index e15b7dda..fb1f972e 100644
--- a/daemon/gdm-session-private.h
+++ b/daemon/gdm-session-private.h
@@ -31,6 +31,8 @@ void _gdm_session_conversation_started (GdmSession *sessio
const char *service_name);
void _gdm_session_conversation_stopped (GdmSession *session,
const char *service_name);
+void _gdm_session_service_unavailable (GdmSession *session,
+ const char *service_name);
void _gdm_session_setup_complete (GdmSession *session,
const char *service_name);
void _gdm_session_setup_failed (GdmSession *session,
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
index 50f1140e..f76fa6fc 100644
--- a/daemon/gdm-session-relay.c
+++ b/daemon/gdm-session-relay.c
@@ -455,6 +455,34 @@ handle_problem (GdmSessionRelay *session_relay,
}
static DBusHandlerResult
+handle_service_unavailable (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: ServiceUnavailable");
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ _gdm_session_service_unavailable (GDM_SESSION (session_relay), service_name);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
handle_setup_complete (GdmSessionRelay *session_relay,
DBusConnection *connection,
DBusMessage *message)
@@ -833,6 +861,8 @@ session_handle_child_message (DBusConnection *connection,
return handle_info (session_relay, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "Problem")) {
return handle_problem (session_relay, connection, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "ServiceUnavailable")) {
+ return handle_service_unavailable (session_relay, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SetupComplete")) {
return handle_setup_complete (session_relay, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SetupFailed")) {
@@ -890,6 +920,9 @@ do_introspect (DBusConnection *connection,
" <method name=\"ConversationStarted\">\n"
" <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
" </method>\n"
+ " <method name=\"ServiceUnavailable\">\n"
+ " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
" <method name=\"SetupComplete\">\n"
" </method>\n"
" <method name=\"SetupFailed\">\n"
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 2a891c1d..a7e2bd96 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2004,9 +2004,16 @@ do_setup (GdmSessionWorker *worker)
worker->priv->display_device,
&error);
if (! res) {
- send_dbus_string_method (worker->priv->connection,
- "SetupFailed",
- error->message);
+ if (g_error_matches (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_SERVICE_UNAVAILABLE)) {
+ send_dbus_void_method (worker->priv->connection,
+ "ServiceUnavailable");
+ } else {
+ send_dbus_string_method (worker->priv->connection,
+ "SetupFailed",
+ error->message);
+ }
g_error_free (error);
return;
}
@@ -2027,10 +2034,18 @@ do_authenticate (GdmSessionWorker *worker)
worker->priv->password_is_required,
&error);
if (! res) {
- g_debug ("GdmSessionWorker: Unable to verify user");
- send_dbus_string_method (worker->priv->connection,
- "AuthenticationFailed",
- error->message);
+ if (g_error_matches (error,
+ GDM_SESSION_WORKER_ERROR,
+ GDM_SESSION_WORKER_ERROR_SERVICE_UNAVAILABLE)) {
+ g_debug ("GdmSessionWorker: Unable to use authentication service");
+ send_dbus_void_method (worker->priv->connection,
+ "ServiceUnavailable");
+ } else {
+ g_debug ("GdmSessionWorker: Unable to verify user");
+ send_dbus_string_method (worker->priv->connection,
+ "AuthenticationFailed",
+ error->message);
+ }
g_error_free (error);
return;
}
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 4c7f6bc2..bf7c878e 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -31,6 +31,7 @@
enum {
CONVERSATION_STARTED = 0,
CONVERSATION_STOPPED,
+ SERVICE_UNAVAILABLE,
SETUP_COMPLETE,
SETUP_FAILED,
RESET_COMPLETE,
@@ -241,6 +242,17 @@ gdm_session_class_init (gpointer g_iface)
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1, G_TYPE_STRING);
+ signals [SERVICE_UNAVAILABLE] =
+ g_signal_new ("service-unavailable",
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmSessionIface, service_unavailable),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
signals [SETUP_COMPLETE] =
g_signal_new ("setup-complete",
iface_type,
@@ -504,6 +516,15 @@ gdm_session_class_init (gpointer g_iface)
}
void
+_gdm_session_service_unavailable (GdmSession *session,
+ const char *service_name)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+
+ g_signal_emit (session, signals [SERVICE_UNAVAILABLE], 0, service_name);
+}
+
+void
_gdm_session_setup_complete (GdmSession *session,
const char *service_name)
{
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 9e72f898..ab160318 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -49,6 +49,8 @@ struct _GdmSessionIface
const char *service_name);
void (* stop_conversation) (GdmSession *session,
const char *service_name);
+ void (* service_unavailable) (GdmSession *session,
+ const char *service_name);
void (* setup) (GdmSession *session,
const char *service_name);
void (* setup_for_user) (GdmSession *session,
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 6eb1448e..7b9d7d8b 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -266,22 +266,6 @@ greeter_reset_timeout (GdmSimpleSlave *slave)
return FALSE;
}
-static gboolean
-auth_failed_reset_timeout (GdmSimpleSlave *slave)
-{
- g_debug ("GdmSimpleSlave: auth failed resetting slave");
-
- if (slave->priv->greeter_server != NULL) {
- gdm_greeter_server_authentication_failed (slave->priv->greeter_server);
- reset_session (slave);
- } else {
- start_greeter (slave);
- create_new_session (slave);
- }
- slave->priv->greeter_reset_id = 0;
- return FALSE;
-}
-
static void
queue_greeter_reset (GdmSimpleSlave *slave)
{
@@ -293,14 +277,16 @@ queue_greeter_reset (GdmSimpleSlave *slave)
}
static void
-queue_auth_failed_reset (GdmSimpleSlave *slave)
+on_session_service_unavailable (GdmSession *session,
+ const char *service_name,
+ GdmSimpleSlave *slave)
{
- /* use the greeter reset idle id so we don't do both at once */
- if (slave->priv->greeter_reset_id > 0) {
- return;
+ if (slave->priv->greeter_server != NULL) {
+ gdm_greeter_server_service_unavailable (slave->priv->greeter_server,
+ service_name);
}
- slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)auth_failed_reset_timeout, slave);
+ gdm_session_stop_conversation (session, service_name);
}
static void
@@ -363,7 +349,6 @@ on_session_authentication_failed (GdmSession *session,
g_debug ("GdmSimpleSlave: Authentication failed - may retry");
gdm_session_stop_conversation (session, service_name);
- queue_auth_failed_reset (slave);
}
static void
@@ -788,6 +773,10 @@ create_new_session (GdmSimpleSlave *slave)
G_CALLBACK (on_session_conversation_stopped),
slave);
g_signal_connect (slave->priv->session,
+ "service-unavailable",
+ G_CALLBACK (on_session_service_unavailable),
+ slave);
+ g_signal_connect (slave->priv->session,
"setup-complete",
G_CALLBACK (on_session_setup_complete),
slave);
@@ -901,6 +890,9 @@ destroy_session (GdmSimpleSlave *slave)
G_CALLBACK (on_session_conversation_stopped),
slave);
g_signal_handlers_disconnect_by_func (slave->priv->session,
+ G_CALLBACK (on_session_service_unavailable),
+ slave);
+ g_signal_handlers_disconnect_by_func (slave->priv->session,
G_CALLBACK (on_session_setup_complete),
slave);
g_signal_handlers_disconnect_by_func (slave->priv->session,
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
index e9916266..65d21d91 100644
--- a/gui/simple-greeter/gdm-greeter-client.c
+++ b/gui/simple-greeter/gdm-greeter-client.c
@@ -63,6 +63,7 @@ enum {
PROBLEM,
INFO_QUERY,
SECRET_INFO_QUERY,
+ SERVICE_UNAVAILABLE,
READY,
RESET,
AUTHENTICATION_FAILED,
@@ -256,6 +257,13 @@ on_problem (GdmGreeterClient *client,
}
static void
+on_service_unavailable (GdmGreeterClient *client,
+ DBusMessage *message)
+{
+ emit_string_signal_for_message (client, "ServiceUnavailable", message, SERVICE_UNAVAILABLE);
+}
+
+static void
on_ready (GdmGreeterClient *client,
DBusMessage *message)
{
@@ -730,6 +738,8 @@ client_dbus_handle_message (DBusConnection *connection,
on_info (client, message);
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "Problem")) {
on_problem (client, message);
+ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "ServiceUnavailable")) {
+ on_service_unavailable (client, message);
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "Ready")) {
on_ready (client, message);
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "Reset")) {
@@ -961,6 +971,16 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
2,
G_TYPE_STRING, G_TYPE_STRING);
+ gdm_greeter_client_signals[SERVICE_UNAVAILABLE] =
+ g_signal_new ("service-unavailable",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GdmGreeterClientClass, service_unavailable),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
gdm_greeter_client_signals[READY] =
g_signal_new ("ready",
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/gui/simple-greeter/gdm-greeter-client.h b/gui/simple-greeter/gdm-greeter-client.h
index 658da484..124f53d0 100644
--- a/gui/simple-greeter/gdm-greeter-client.h
+++ b/gui/simple-greeter/gdm-greeter-client.h
@@ -59,6 +59,8 @@ typedef struct
void (* problem) (GdmGreeterClient *client,
const char *service_name,
const char *problem);
+ void (* service_unavailable) (GdmGreeterClient *client,
+ const char *service_name);
void (* ready) (GdmGreeterClient *client,
const char *service_name);
void (* reset) (GdmGreeterClient *client);