From 83c0105b2972ff68b50a24101755b5e72a11872b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 20 Oct 2015 16:48:17 -0400
Subject: [PATCH 1/3] gdm-session: emit verification-complete even for logins
Right now we only emit verification-complete when the a user
successfully reauthenticates. We should also do it when they
successfully initially authenticate.
This commit fixes that.
https://bugzilla.gnome.org/show_bug.cgi?id=754814
---
daemon/gdm-session.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 6faa7cd..0fedb7b 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -280,73 +280,72 @@ on_authorize_cb (GdmDBusWorker *proxy,
if (worked) {
gdm_session_accredit (self, service_name);
} else {
report_and_stop_conversation (self, service_name, error);
}
}
static void
on_establish_credentials_cb (GdmDBusWorker *proxy,
GAsyncResult *res,
gpointer user_data)
{
GdmSessionConversation *conversation = user_data;
GdmSession *self;
char *service_name;
GError *error = NULL;
gboolean worked;
worked = gdm_dbus_worker_call_establish_credentials_finish (proxy, res, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
self = conversation->session;
service_name = conversation->service_name;
if (worked) {
- switch (self->priv->verification_mode) {
- case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
- if (self->priv->user_verifier_interface != NULL) {
- gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
- service_name);
- g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
- }
- break;
+ if (self->priv->user_verifier_interface != NULL) {
+ gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
+ service_name);
+ g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
+ }
+ switch (self->priv->verification_mode) {
case GDM_SESSION_VERIFICATION_MODE_LOGIN:
case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
gdm_session_open_session (self, service_name);
break;
+ case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
default:
break;
}
} else {
report_and_stop_conversation (self, service_name, error);
}
}
static const char **
get_system_session_dirs (void)
{
static const char *search_dirs[] = {
"/etc/X11/sessions/",
DMCONFDIR "/Sessions/",
DATADIR "/gdm/BuiltInSessions/",
DATADIR "/xsessions/",
#ifdef ENABLE_WAYLAND_SUPPORT
DATADIR "/wayland-sessions/",
#endif
NULL
};
return search_dirs;
}
static gboolean
is_prog_in_path (const char *prog)
{
char *f;
gboolean ret;
--
2.7.0
From 34a302282a323820f83e76978cd0a07b2ee0304b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 22 Jan 2016 15:59:00 -0500
Subject: [PATCH 2/3] session: keep session object alive while establishing
credentials
The only reference to session objects gets cleaned up when
verification-complete is emitted, which happens in the middle
of the establish_credentials handler.
This commit makes sure the session object stays alive until the
handler completes to prevent a crash.
https://bugzilla.gnome.org/show_bug.cgi?id=754814
---
daemon/gdm-session.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 0fedb7b..dbd4ba6 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -276,82 +276,85 @@ on_authorize_cb (GdmDBusWorker *proxy,
return;
self = conversation->session;
service_name = conversation->service_name;
if (worked) {
gdm_session_accredit (self, service_name);
} else {
report_and_stop_conversation (self, service_name, error);
}
}
static void
on_establish_credentials_cb (GdmDBusWorker *proxy,
GAsyncResult *res,
gpointer user_data)
{
GdmSessionConversation *conversation = user_data;
GdmSession *self;
char *service_name;
GError *error = NULL;
gboolean worked;
worked = gdm_dbus_worker_call_establish_credentials_finish (proxy, res, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
- self = conversation->session;
- service_name = conversation->service_name;
+ self = g_object_ref (conversation->session);
+ service_name = g_strdup (conversation->service_name);
if (worked) {
if (self->priv->user_verifier_interface != NULL) {
gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
service_name);
g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
}
switch (self->priv->verification_mode) {
case GDM_SESSION_VERIFICATION_MODE_LOGIN:
case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
gdm_session_open_session (self, service_name);
break;
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
default:
break;
}
} else {
report_and_stop_conversation (self, service_name, error);
}
+
+ g_free (service_name);
+ g_object_unref (self);
}
static const char **
get_system_session_dirs (void)
{
static const char *search_dirs[] = {
"/etc/X11/sessions/",
DMCONFDIR "/Sessions/",
DATADIR "/gdm/BuiltInSessions/",
DATADIR "/xsessions/",
#ifdef ENABLE_WAYLAND_SUPPORT
DATADIR "/wayland-sessions/",
#endif
NULL
};
return search_dirs;
}
static gboolean
is_prog_in_path (const char *prog)
{
char *f;
gboolean ret;
f = g_find_program_in_path (prog);
ret = (f != NULL);
g_free (f);
return ret;
}
--
2.7.0
From 48e264a2e3fbb5854125fc03a9ea3822abb68b94 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 22 Jan 2016 16:01:20 -0500
Subject: [PATCH 3/3] session: free conversation hash when disposing session
We're currently leaking the hash table when disposing the
session, this commit fixes that.
https://bugzilla.gnome.org/show_bug.cgi?id=754814
---
daemon/gdm-session.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index dbd4ba6..09e6a48 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -3296,60 +3296,63 @@ gdm_session_get_property (GObject *object,
break;
case PROP_DISPLAY_IS_INITIAL:
g_value_set_boolean (value, self->priv->display_is_initial);
break;
case PROP_VERIFICATION_MODE:
g_value_set_enum (value, self->priv->verification_mode);
break;
case PROP_ALLOWED_USER:
g_value_set_uint (value, self->priv->allowed_user);
break;
case PROP_CONVERSATION_ENVIRONMENT:
g_value_set_pointer (value, self->priv->environment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdm_session_dispose (GObject *object)
{
GdmSession *self;
self = GDM_SESSION (object);
g_debug ("GdmSession: Disposing session");
gdm_session_close (self);
+ g_clear_pointer (&self->priv->conversations,
+ g_hash_table_unref);
+
g_clear_object (&self->priv->user_verifier_interface);
g_clear_object (&self->priv->greeter_interface);
g_clear_object (&self->priv->chooser_interface);
g_free (self->priv->display_name);
self->priv->display_name = NULL;
g_free (self->priv->display_hostname);
self->priv->display_hostname = NULL;
g_free (self->priv->display_device);
self->priv->display_device = NULL;
g_free (self->priv->display_seat_id);
self->priv->display_seat_id = NULL;
g_free (self->priv->display_x11_authority_file);
self->priv->display_x11_authority_file = NULL;
g_strfreev (self->priv->conversation_environment);
self->priv->conversation_environment = NULL;
if (self->priv->worker_server != NULL) {
g_dbus_server_stop (self->priv->worker_server);
g_clear_object (&self->priv->worker_server);
}
if (self->priv->outside_server != NULL) {
g_dbus_server_stop (self->priv->outside_server);
g_clear_object (&self->priv->outside_server);
--
2.7.0