summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2009-03-09 15:41:12 -0400
committerRay Strode <rstrode@redhat.com>2010-02-08 16:19:02 -0500
commita736563893b6c99c900198afaeea1684bc8c1259 (patch)
tree48d02cc6b1f74f471f448c7791eb013f3c1a7e31 /daemon
parentf5c918550dbabe04ece27e9f80234af93ef54514 (diff)
downloadgdm-a736563893b6c99c900198afaeea1684bc8c1259.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.
Diffstat (limited to 'daemon')
-rw-r--r--daemon/gdm-factory-slave.c35
-rw-r--r--daemon/gdm-product-slave.c27
-rw-r--r--daemon/gdm-session-direct.c67
-rw-r--r--daemon/gdm-session-private.h3
-rw-r--r--daemon/gdm-session-relay.c63
-rw-r--r--daemon/gdm-session-worker.c20
-rw-r--r--daemon/gdm-session.c46
-rw-r--r--daemon/gdm-session.h5
-rw-r--r--daemon/gdm-simple-slave.c31
9 files changed, 289 insertions, 8 deletions
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
index 8ba64aa9..606c9955 100644
--- a/daemon/gdm-factory-slave.c
+++ b/daemon/gdm-factory-slave.c
@@ -265,9 +265,7 @@ on_session_accredited (GdmSession *session,
{
g_debug ("GdmFactorySlave: session user verified");
- gdm_session_start_session (session);
-
- gdm_greeter_server_reset (slave->priv->greeter_server);
+ gdm_session_open_session (session);
}
static void
@@ -284,6 +282,29 @@ on_session_accreditation_failed (GdmSession *session,
}
static void
+on_session_opened (GdmSession *session,
+ GdmFactorySlave *slave)
+{
+ g_debug ("GdmFactorySlave: session opened");
+
+ gdm_session_start_session (session);
+
+ gdm_greeter_server_reset (slave->priv->greeter_server);
+}
+
+static void
+on_session_open_failed (GdmSession *session,
+ 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"));
+
+ queue_greeter_reset (slave);
+}
+
+static void
on_session_session_started (GdmSession *session,
GdmFactorySlave *slave)
{
@@ -738,6 +759,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 0423b355..cf31f61c 100644
--- a/daemon/gdm-product-slave.c
+++ b/daemon/gdm-product-slave.c
@@ -559,6 +559,24 @@ on_session_accreditation_failed (GdmSession *session,
}
static void
+on_session_opened (GdmSession *session,
+ GdmProductSlave *slave)
+{
+ send_dbus_void_method (slave->priv->session_relay_connection,
+ "SessionOpened");
+}
+
+static void
+on_session_open_failed (GdmSession *session,
+ const char *message,
+ GdmProductSlave *slave)
+{
+ send_dbus_string_method (slave->priv->session_relay_connection,
+ "SessionOpenFailed",
+ message);
+}
+
+static void
on_session_info (GdmSession *session,
const char *text,
GdmProductSlave *slave)
@@ -875,7 +893,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 890f435e..77d5801f 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -936,6 +936,58 @@ gdm_session_direct_handle_problem (GdmSessionDirect *session,
}
static DBusHandlerResult
+gdm_session_direct_handle_session_opened (GdmSessionDirect *session,
+ DBusConnection *connection,
+ 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));
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+gdm_session_direct_handle_open_failed (GdmSessionDirect *session,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+ const char *text;
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &text,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("ERROR: %s", error.message);
+ }
+
+ reply = dbus_message_new_method_return (message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ g_debug ("GdmSessionDirect: Emitting 'session-open-failed' signal");
+ _gdm_session_session_open_failed (GDM_SESSION (session), text);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
gdm_session_direct_handle_session_started (GdmSessionDirect *session,
DBusConnection *connection,
DBusMessage *message)
@@ -1199,6 +1251,10 @@ session_worker_message (DBusConnection *connection,
return gdm_session_direct_handle_accreditation_failed (session, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) {
return gdm_session_direct_handle_username_changed (session, connection, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) {
+ return gdm_session_direct_handle_session_opened (session, connection, message);
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "OpenFailed")) {
+ return gdm_session_direct_handle_open_failed (session, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) {
return gdm_session_direct_handle_session_started (session, connection, message);
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) {
@@ -2001,6 +2057,16 @@ setup_session_environment (GdmSessionDirect *session)
}
static void
+gdm_session_direct_open_session (GdmSession *session)
+{
+ GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
+
+ g_return_if_fail (session != NULL);
+
+ send_dbus_void_signal (impl, "OpenSession");
+}
+
+static void
gdm_session_direct_start_session (GdmSession *session)
{
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
@@ -2472,6 +2538,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 b196e492..7ccf0d73 100644
--- a/daemon/gdm-session-private.h
+++ b/daemon/gdm-session-private.h
@@ -43,6 +43,9 @@ void _gdm_session_authorization_failed (GdmSession *sessio
void _gdm_session_accredited (GdmSession *session);
void _gdm_session_accreditation_failed (GdmSession *session,
const char *text);
+void _gdm_session_session_opened (GdmSession *session);
+void _gdm_session_session_open_failed (GdmSession *session,
+ const char *message);
void _gdm_session_session_started (GdmSession *session,
int pid);
void _gdm_session_session_start_failed (GdmSession *session,
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
index 92254e6a..da0ecb32 100644
--- a/daemon/gdm-session-relay.c
+++ b/daemon/gdm-session-relay.c
@@ -243,6 +243,13 @@ gdm_session_relay_accredit (GdmSession *session,
}
static void
+gdm_session_relay_open_session (GdmSession *session)
+{
+ GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
+ send_dbus_void_signal (impl, "OpenSession");
+}
+
+static void
gdm_session_relay_answer_query (GdmSession *session,
const char *text)
{
@@ -608,6 +615,57 @@ 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;
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ 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));
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+handle_session_open_failed (GdmSessionRelay *session_relay,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ 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), NULL);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
static DBusHandlerResult
handle_session_started (GdmSessionRelay *session_relay,
@@ -715,6 +773,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")) {
@@ -1112,6 +1174,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 deb1cabd..5e34fb9e 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2453,13 +2453,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
@@ -2575,7 +2575,7 @@ on_start_program (GdmSessionWorker *worker,
const char *text;
dbus_bool_t res;
- if (worker->priv->state != GDM_SESSION_WORKER_STATE_ACCREDITED) {
+ if (worker->priv->state != GDM_SESSION_WORKER_STATE_SESSION_OPENED) {
g_debug ("GdmSessionWorker: ignoring spurious start program while in state %s", get_state_name (worker->priv->state));
return;
}
@@ -2734,6 +2734,18 @@ on_establish_credentials (GdmSessionWorker *worker,
}
static void
+on_open_session (GdmSessionWorker *worker,
+ DBusMessage *message)
+{
+ if (worker->priv->state != GDM_SESSION_WORKER_STATE_ACCREDITED) {
+ g_debug ("GdmSessionWorker: ignoring spurious open session for user while in state %s", get_state_name (worker->priv->state));
+ return;
+ }
+
+ queue_state_change (worker);
+}
+
+static void
on_reauthenticate (GdmSessionWorker *worker,
DBusMessage *message)
{
@@ -2805,6 +2817,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 5ca0e88d..1e2af926 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -44,6 +44,8 @@ enum {
PROBLEM,
INFO_QUERY,
SECRET_INFO_QUERY,
+ SESSION_OPENED,
+ SESSION_OPEN_FAILED,
SESSION_STARTED,
SESSION_START_FAILED,
SESSION_EXITED,
@@ -191,6 +193,14 @@ gdm_session_cancel (GdmSession *session)
}
void
+gdm_session_open_session (GdmSession *session)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+
+ GDM_SESSION_GET_IFACE (session)->open_session (session);
+}
+
+void
gdm_session_start_session (GdmSession *session)
{
g_return_if_fail (GDM_IS_SESSION (session));
@@ -363,6 +373,27 @@ gdm_session_class_init (gpointer g_iface)
G_TYPE_NONE,
1,
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__VOID,
+ G_TYPE_NONE,
+ 0);
+ 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,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
signals [SESSION_STARTED] =
g_signal_new ("session-started",
iface_type,
@@ -576,6 +607,21 @@ _gdm_session_problem (GdmSession *session,
}
void
+_gdm_session_session_opened (GdmSession *session)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+ g_signal_emit (session, signals [SESSION_OPENED], 0);
+}
+
+void
+_gdm_session_session_open_failed (GdmSession *session,
+ const char *text)
+{
+ g_return_if_fail (GDM_IS_SESSION (session));
+ g_signal_emit (session, signals [SESSION_OPEN_FAILED], 0, text);
+}
+
+void
_gdm_session_session_started (GdmSession *session,
int pid)
{
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index afe7b831..fb199d39 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -56,6 +56,7 @@ struct _GdmSessionIface
void (* authorize) (GdmSession *session);
void (* accredit) (GdmSession *session,
int cred_flag);
+ void (* open_session) (GdmSession *session);
void (* answer_query) (GdmSession *session,
const char *text);
void (* select_language) (GdmSession *session,
@@ -95,6 +96,9 @@ struct _GdmSessionIface
const char *info);
void (* problem) (GdmSession *session,
const char *problem);
+ void (* session_opened) (GdmSession *session);
+ void (* session_open_failed) (GdmSession *session,
+ const char *message);
void (* session_started) (GdmSession *session,
int pid);
void (* session_start_failed) (GdmSession *session,
@@ -129,6 +133,7 @@ void gdm_session_authenticate (GdmSession *session);
void gdm_session_authorize (GdmSession *session);
void gdm_session_accredit (GdmSession *session,
int cred_flag);
+void gdm_session_open_session (GdmSession *session);
void gdm_session_start_session (GdmSession *session);
void gdm_session_close (GdmSession *session);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index fdc2c0d1..59e3530d 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -418,7 +418,7 @@ static void
on_session_accredited (GdmSession *session,
GdmSimpleSlave *slave)
{
- queue_start_session (slave);
+ gdm_session_open_session (session);
}
static void
@@ -457,6 +457,27 @@ on_session_accreditation_failed (GdmSession *session,
}
static void
+on_session_opened (GdmSession *session,
+ GdmSimpleSlave *slave)
+{
+ queue_start_session (slave);
+}
+
+static void
+on_session_open_failed (GdmSession *session,
+ const char *message,
+ GdmSimpleSlave *slave)
+{
+ if (slave->priv->greeter_server != NULL) {
+ gdm_greeter_server_problem (slave->priv->greeter_server,
+ _("Unable to open session"));
+ }
+
+ destroy_session (slave);
+ queue_greeter_reset (slave);
+}
+
+static void
on_session_info (GdmSession *session,
const char *text,
GdmSimpleSlave *slave)
@@ -659,6 +680,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);