541 lines
19 KiB
Diff
541 lines
19 KiB
Diff
From 0b466395de112bb247ec586e9ef9770c31e74657 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 4 Feb 2016 13:36:06 -0500
|
|
Subject: [PATCH 1/4] daemon: support dbus user buses with X sessions
|
|
|
|
If the dbus user bus was started when the user first
|
|
logged in, before the session was started, then that
|
|
dbus daemon won't have DISPLAY and XAUTHORITY in its
|
|
activation environment.
|
|
|
|
This means programs activated from that dbus daemon
|
|
also won't have DISPLAY and XAUTHORITY in their
|
|
activation environments.
|
|
|
|
This commit changes GDM to explicitly put the two
|
|
variables in the activation environment via D-Bus,
|
|
rather than sending them into the bus environment
|
|
process when launching the bus (since in the case
|
|
of the user bus, we don't launch it).
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=761568
|
|
---
|
|
daemon/gdm-x-session.c | 42 +++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 39 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
|
|
index 624f67c..c01cc5e 100644
|
|
--- a/daemon/gdm-x-session.c
|
|
+++ b/daemon/gdm-x-session.c
|
|
@@ -351,144 +351,180 @@ on_bus_finished (GSubprocess *subprocess,
|
|
goto out;
|
|
}
|
|
|
|
if (g_subprocess_get_if_exited (subprocess)) {
|
|
int exit_status;
|
|
|
|
exit_status = g_subprocess_get_exit_status (subprocess);
|
|
|
|
g_debug ("message bus exited with status %d", exit_status);
|
|
} else {
|
|
int signal_number;
|
|
|
|
signal_number = g_subprocess_get_term_sig (subprocess);
|
|
g_debug ("message bus was killed with status %d", signal_number);
|
|
}
|
|
|
|
g_clear_object (&state->bus_subprocess);
|
|
out:
|
|
g_main_loop_quit (state->main_loop);
|
|
}
|
|
|
|
static gboolean
|
|
spawn_bus (State *state,
|
|
GCancellable *cancellable)
|
|
{
|
|
GPtrArray *arguments = NULL;
|
|
GSubprocessLauncher *launcher = NULL;
|
|
GSubprocess *subprocess = NULL;
|
|
GInputStream *input_stream = NULL;
|
|
GDataInputStream *data_stream = NULL;
|
|
+ GDBusConnection *connection = NULL;
|
|
+ GVariantBuilder *builder = NULL;
|
|
+ GVariant *reply = NULL;
|
|
GError *error = NULL;
|
|
const char *bus_env = NULL;
|
|
char *bus_address_fd_string;
|
|
char *bus_address = NULL;
|
|
gsize bus_address_size;
|
|
|
|
gboolean is_running = FALSE;
|
|
int ret;
|
|
int pipe_fds[2];
|
|
|
|
g_debug ("Running session message bus");
|
|
|
|
bus_env = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
|
|
if (bus_env != NULL) {
|
|
g_debug ("session message bus already running, not starting another one");
|
|
state->bus_address = g_strdup (bus_env);
|
|
return TRUE;
|
|
}
|
|
|
|
ret = g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error);
|
|
|
|
if (!ret) {
|
|
g_debug ("could not open pipe: %s", error->message);
|
|
goto out;
|
|
}
|
|
|
|
arguments = g_ptr_array_new ();
|
|
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
|
|
|
|
- g_subprocess_launcher_setenv (launcher, "DISPLAY", state->display_name, TRUE);
|
|
- g_subprocess_launcher_setenv (launcher, "XAUTHORITY", state->auth_file, TRUE);
|
|
-
|
|
g_subprocess_launcher_take_fd (launcher, pipe_fds[1], BUS_ADDRESS_FILENO);
|
|
|
|
bus_address_fd_string = g_strdup_printf ("%d", BUS_ADDRESS_FILENO);
|
|
|
|
g_ptr_array_add (arguments, "dbus-daemon");
|
|
|
|
g_ptr_array_add (arguments, "--print-address");
|
|
g_ptr_array_add (arguments, bus_address_fd_string);
|
|
g_ptr_array_add (arguments, "--session");
|
|
g_ptr_array_add (arguments, NULL);
|
|
|
|
subprocess = g_subprocess_launcher_spawnv (launcher,
|
|
(const char * const *) arguments->pdata,
|
|
&error);
|
|
g_free (bus_address_fd_string);
|
|
g_clear_object (&launcher);
|
|
g_ptr_array_free (arguments, TRUE);
|
|
|
|
if (subprocess == NULL) {
|
|
g_debug ("could not start dbus-daemon: %s", error->message);
|
|
goto out;
|
|
}
|
|
|
|
input_stream = g_unix_input_stream_new (pipe_fds[0], TRUE);
|
|
data_stream = g_data_input_stream_new (input_stream);
|
|
g_clear_object (&input_stream);
|
|
|
|
bus_address = g_data_input_stream_read_line (data_stream,
|
|
&bus_address_size,
|
|
cancellable,
|
|
&error);
|
|
|
|
if (error != NULL) {
|
|
g_debug ("could not read address from session message bus: %s", error->message);
|
|
goto out;
|
|
}
|
|
|
|
if (bus_address == NULL) {
|
|
g_debug ("session message bus did not write address");
|
|
goto out;
|
|
}
|
|
|
|
state->bus_address = bus_address;
|
|
|
|
state->bus_subprocess = g_object_ref (subprocess);
|
|
|
|
g_subprocess_wait_async (state->bus_subprocess,
|
|
cancellable,
|
|
(GAsyncReadyCallback)
|
|
on_bus_finished,
|
|
state);
|
|
|
|
+ connection = g_dbus_connection_new_for_address_sync (state->bus_address,
|
|
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
|
|
+ G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
|
|
+ NULL,
|
|
+ cancellable,
|
|
+ &error);
|
|
+
|
|
+ if (connection == NULL) {
|
|
+ g_debug ("could not open connection to session bus: %s",
|
|
+ error->message);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
|
|
+ g_variant_builder_add (&builder, "{ss}", "DISPLAY", state->display_name);
|
|
+ g_variant_builder_add (&builder, "{ss}", "XAUTHORITY", state->auth_file);
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.DBus",
|
|
+ "/org/freedesktop/DBus",
|
|
+ "org.freedesktop.DBus",
|
|
+ "UpdateActivationEnvironment",
|
|
+ g_variant_new ("(@a{ss})",
|
|
+ g_variant_builder_end (&builder)),
|
|
+ NULL,
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1, NULL, &error);
|
|
+
|
|
+ if (reply == NULL) {
|
|
+ g_debug ("could not update activation environment: %s", error->message);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+ g_clear_object (&connection);
|
|
+
|
|
is_running = TRUE;
|
|
out:
|
|
g_clear_object (&data_stream);
|
|
g_clear_object (&subprocess);
|
|
g_clear_object (&launcher);
|
|
g_clear_error (&error);
|
|
|
|
return is_running;
|
|
}
|
|
|
|
|
|
static void
|
|
on_session_finished (GSubprocess *subprocess,
|
|
GAsyncResult *result,
|
|
State *state)
|
|
{
|
|
gboolean cancelled;
|
|
|
|
cancelled = !g_subprocess_wait_finish (subprocess, result, NULL);
|
|
|
|
if (cancelled) {
|
|
goto out;
|
|
}
|
|
|
|
if (g_subprocess_get_if_exited (subprocess)) {
|
|
int exit_status;
|
|
|
|
exit_status = g_subprocess_get_exit_status (subprocess);
|
|
|
|
g_debug ("session exited with status %d", exit_status);
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From ee14ddb28e0df3f6726b10d1b7fffb898b058738 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 5 Feb 2016 10:42:20 -0500
|
|
Subject: [PATCH 2/4] gdm-x-session: fix tiny leak in error path
|
|
|
|
I wasn't cleaning up the dbus connection in out: so
|
|
it leaked in an error path.
|
|
|
|
Spotted by Michael Catanzaro
|
|
---
|
|
daemon/gdm-x-session.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
|
|
index c01cc5e..41e4118 100644
|
|
--- a/daemon/gdm-x-session.c
|
|
+++ b/daemon/gdm-x-session.c
|
|
@@ -469,64 +469,64 @@ spawn_bus (State *state,
|
|
cancellable,
|
|
&error);
|
|
|
|
if (connection == NULL) {
|
|
g_debug ("could not open connection to session bus: %s",
|
|
error->message);
|
|
goto out;
|
|
}
|
|
|
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
|
|
g_variant_builder_add (&builder, "{ss}", "DISPLAY", state->display_name);
|
|
g_variant_builder_add (&builder, "{ss}", "XAUTHORITY", state->auth_file);
|
|
|
|
reply = g_dbus_connection_call_sync (connection,
|
|
"org.freedesktop.DBus",
|
|
"/org/freedesktop/DBus",
|
|
"org.freedesktop.DBus",
|
|
"UpdateActivationEnvironment",
|
|
g_variant_new ("(@a{ss})",
|
|
g_variant_builder_end (&builder)),
|
|
NULL,
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, &error);
|
|
|
|
if (reply == NULL) {
|
|
g_debug ("could not update activation environment: %s", error->message);
|
|
goto out;
|
|
}
|
|
|
|
g_variant_unref (reply);
|
|
- g_clear_object (&connection);
|
|
|
|
is_running = TRUE;
|
|
out:
|
|
+ g_clear_object (&connection);
|
|
g_clear_object (&data_stream);
|
|
g_clear_object (&subprocess);
|
|
g_clear_object (&launcher);
|
|
g_clear_error (&error);
|
|
|
|
return is_running;
|
|
}
|
|
|
|
|
|
static void
|
|
on_session_finished (GSubprocess *subprocess,
|
|
GAsyncResult *result,
|
|
State *state)
|
|
{
|
|
gboolean cancelled;
|
|
|
|
cancelled = !g_subprocess_wait_finish (subprocess, result, NULL);
|
|
|
|
if (cancelled) {
|
|
goto out;
|
|
}
|
|
|
|
if (g_subprocess_get_if_exited (subprocess)) {
|
|
int exit_status;
|
|
|
|
exit_status = g_subprocess_get_exit_status (subprocess);
|
|
|
|
g_debug ("session exited with status %d", exit_status);
|
|
|
|
state->session_exit_status = exit_status;
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From a8982d70e65d13f5c0a65a144d659c65382b04f3 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 9 Feb 2016 11:34:30 -0500
|
|
Subject: [PATCH 3/4] gdm-x-session: fix pointer confusion in
|
|
UpdateActivationEnv call
|
|
|
|
commit 99eeae91c1f11997521ad3bc016a7b2d23ec7942 introduced a
|
|
call to UpdateActivationEnvironment but mucked up the GVariantBuilder
|
|
declaration. This commit fixes that.
|
|
---
|
|
daemon/gdm-x-session.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
|
|
index 41e4118..6957c83 100644
|
|
--- a/daemon/gdm-x-session.c
|
|
+++ b/daemon/gdm-x-session.c
|
|
@@ -352,61 +352,61 @@ on_bus_finished (GSubprocess *subprocess,
|
|
}
|
|
|
|
if (g_subprocess_get_if_exited (subprocess)) {
|
|
int exit_status;
|
|
|
|
exit_status = g_subprocess_get_exit_status (subprocess);
|
|
|
|
g_debug ("message bus exited with status %d", exit_status);
|
|
} else {
|
|
int signal_number;
|
|
|
|
signal_number = g_subprocess_get_term_sig (subprocess);
|
|
g_debug ("message bus was killed with status %d", signal_number);
|
|
}
|
|
|
|
g_clear_object (&state->bus_subprocess);
|
|
out:
|
|
g_main_loop_quit (state->main_loop);
|
|
}
|
|
|
|
static gboolean
|
|
spawn_bus (State *state,
|
|
GCancellable *cancellable)
|
|
{
|
|
GPtrArray *arguments = NULL;
|
|
GSubprocessLauncher *launcher = NULL;
|
|
GSubprocess *subprocess = NULL;
|
|
GInputStream *input_stream = NULL;
|
|
GDataInputStream *data_stream = NULL;
|
|
GDBusConnection *connection = NULL;
|
|
- GVariantBuilder *builder = NULL;
|
|
+ GVariantBuilder builder;
|
|
GVariant *reply = NULL;
|
|
GError *error = NULL;
|
|
const char *bus_env = NULL;
|
|
char *bus_address_fd_string;
|
|
char *bus_address = NULL;
|
|
gsize bus_address_size;
|
|
|
|
gboolean is_running = FALSE;
|
|
int ret;
|
|
int pipe_fds[2];
|
|
|
|
g_debug ("Running session message bus");
|
|
|
|
bus_env = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
|
|
if (bus_env != NULL) {
|
|
g_debug ("session message bus already running, not starting another one");
|
|
state->bus_address = g_strdup (bus_env);
|
|
return TRUE;
|
|
}
|
|
|
|
ret = g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error);
|
|
|
|
if (!ret) {
|
|
g_debug ("could not open pipe: %s", error->message);
|
|
goto out;
|
|
}
|
|
|
|
arguments = g_ptr_array_new ();
|
|
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
|
|
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From 1c7fdfad3b47b9e7c27862c5926120235151bd57 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 9 Feb 2016 11:49:02 -0500
|
|
Subject: [PATCH 4/4] gdm-session: update session type when the session
|
|
defaults change
|
|
|
|
If a user has never logged in before and they login using autologin,
|
|
then we don't select the correct session type if they end up
|
|
with a wayland session. This is because we fail to initialize
|
|
the session type based on the default session type.
|
|
|
|
This commit changes the code to update the session type anytime the
|
|
session defaults are reset.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=761785
|
|
---
|
|
daemon/gdm-session.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index c230dae..b839fea 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -581,60 +581,62 @@ get_fallback_session_name (GdmSession *self)
|
|
strlen (".desktop"));
|
|
|
|
break;
|
|
}
|
|
session = g_sequence_iter_next (session);
|
|
} while (!g_sequence_iter_is_end (session));
|
|
|
|
g_free (self->priv->fallback_session_name);
|
|
self->priv->fallback_session_name = name;
|
|
|
|
g_sequence_free (sessions);
|
|
|
|
out:
|
|
return self->priv->fallback_session_name;
|
|
}
|
|
|
|
static const char *
|
|
get_default_session_name (GdmSession *self)
|
|
{
|
|
if (self->priv->saved_session != NULL) {
|
|
return self->priv->saved_session;
|
|
}
|
|
|
|
return get_fallback_session_name (self);
|
|
}
|
|
|
|
static void
|
|
gdm_session_defaults_changed (GdmSession *self)
|
|
{
|
|
|
|
+ update_session_type (self);
|
|
+
|
|
if (self->priv->greeter_interface != NULL) {
|
|
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
|
get_default_language_name (self));
|
|
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
|
get_default_session_name (self));
|
|
}
|
|
}
|
|
|
|
void
|
|
gdm_session_select_user (GdmSession *self,
|
|
const char *text)
|
|
{
|
|
|
|
g_debug ("GdmSession: Setting user: '%s'", text);
|
|
|
|
g_free (self->priv->selected_user);
|
|
self->priv->selected_user = g_strdup (text);
|
|
|
|
g_free (self->priv->saved_session);
|
|
self->priv->saved_session = NULL;
|
|
|
|
g_free (self->priv->saved_language);
|
|
self->priv->saved_language = NULL;
|
|
}
|
|
|
|
static void
|
|
cancel_pending_query (GdmSessionConversation *conversation)
|
|
{
|
|
if (conversation->pending_invocation == NULL) {
|
|
return;
|
|
@@ -893,62 +895,60 @@ worker_on_saved_language_name_read (GdmDBusWorker *worker,
|
|
{
|
|
GdmSession *self = conversation->session;
|
|
|
|
if (strlen (language_name) > 0 &&
|
|
strcmp (language_name, get_default_language_name (self)) != 0) {
|
|
g_free (self->priv->saved_language);
|
|
self->priv->saved_language = g_strdup (language_name);
|
|
|
|
if (self->priv->greeter_interface != NULL) {
|
|
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
|
language_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
worker_on_saved_session_name_read (GdmDBusWorker *worker,
|
|
const char *session_name,
|
|
GdmSessionConversation *conversation)
|
|
{
|
|
GdmSession *self = conversation->session;
|
|
|
|
if (! get_session_command_for_name (self, session_name, NULL)) {
|
|
/* ignore sessions that don't exist */
|
|
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
|
|
g_free (self->priv->saved_session);
|
|
self->priv->saved_session = NULL;
|
|
return;
|
|
}
|
|
|
|
- update_session_type (self);
|
|
-
|
|
if (strcmp (session_name,
|
|
get_default_session_name (self)) != 0) {
|
|
g_free (self->priv->saved_session);
|
|
self->priv->saved_session = g_strdup (session_name);
|
|
|
|
if (self->priv->greeter_interface != NULL) {
|
|
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
|
session_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
static GdmSessionConversation *
|
|
find_conversation_by_pid (GdmSession *self,
|
|
GPid pid)
|
|
{
|
|
GHashTableIter iter;
|
|
gpointer key, value;
|
|
|
|
g_hash_table_iter_init (&iter, self->priv->conversations);
|
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
GdmSessionConversation *conversation;
|
|
|
|
conversation = (GdmSessionConversation *) value;
|
|
|
|
if (conversation->worker_pid == pid) {
|
|
return conversation;
|
|
}
|
|
}
|
|
|
|
--
|
|
2.7.0
|
|
|