From 1ccda26d327a16e6345b00748295b857cbbde166 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sun, 7 May 2017 12:43:48 +0200
Subject: [PATCH 1/2] dbus needs to be updated to get all user-defined
environment when the session starts.
dbus-update-activation-environment excepts certain environment
variables, that systemd won't. We're going to want to eventually
send the environment to systemd, too, so we should make sure the
same set of variables get sent to both.
See: https://bugzilla.gnome.org/show_bug.cgi?id=736660
---
mate-session/gsm-util.c | 123 ++++++++++++++++++++++++++++++++++++------------
mate-session/gsm-util.h | 2 +
mate-session/main.c | 3 ++
3 files changed, 99 insertions(+), 29 deletions(-)
diff --git a/mate-session/gsm-util.c b/mate-session/gsm-util.c
index 6320b24..b026f12 100644
--- a/mate-session/gsm-util.c
+++ b/mate-session/gsm-util.c
@@ -435,54 +435,119 @@ gsm_util_update_activation_environment (const char *variable,
const char *value,
GError **error)
{
- DBusGConnection *dbus_connection;
- DBusGProxy *bus_proxy;
- GHashTable *environment;
+ GDBusConnection *connection;
gboolean environment_updated;
+ GVariantBuilder builder;
+ GVariant *reply;
+ GError *bus_error = NULL;
environment_updated = FALSE;
- bus_proxy = NULL;
- environment = NULL;
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
- dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
+ if (connection == NULL) {
+ return FALSE;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+ g_variant_builder_add (&builder, "{ss}", variable, value);
+
+ 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, &bus_error);
+
+ if (bus_error != NULL) {
+ g_propagate_error (error, bus_error);
+ } else {
+ environment_updated = TRUE;
+ g_variant_unref (reply);
+ }
- if (dbus_connection == NULL) {
+ g_clear_object (&connection);
+
+ return environment_updated;
+}
+
+gboolean
+gsm_util_export_activation_environment (GError **error)
+{
+ GDBusConnection *connection;
+ gboolean environment_updated = FALSE;
+ char **entry_names;
+ int i = 0;
+ GVariantBuilder builder;
+ GRegex *name_regex, *value_regex;
+ GVariant *reply;
+ GError *bus_error = NULL;
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+ if (connection == NULL) {
return FALSE;
}
- bus_proxy = dbus_g_proxy_new_for_name_owner (dbus_connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- error);
+ name_regex = g_regex_new ("^[a-zA-Z_][a-zA-Z0-9_]*$", G_REGEX_OPTIMIZE, 0, error);
- if (bus_proxy == NULL) {
- goto out;
+ if (name_regex == NULL) {
+ return FALSE;
}
- environment = g_hash_table_new (g_str_hash, g_str_equal);
+ value_regex = g_regex_new ("^([[:blank:]]|[^[:cntrl:]])*$", G_REGEX_OPTIMIZE, 0, error);
- g_hash_table_insert (environment, (void *) variable, (void *) value);
+ if (value_regex == NULL) {
+ return FALSE;
+ }
- if (!dbus_g_proxy_call (bus_proxy,
- "UpdateActivationEnvironment", error,
- DBUS_TYPE_G_STRING_STRING_HASHTABLE,
- environment, G_TYPE_INVALID,
- G_TYPE_INVALID))
- goto out;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+ for (entry_names = g_listenv (); entry_names[i] != NULL; i++) {
+ const char *entry_name = entry_names[i];
+ const char *entry_value = g_getenv (entry_name);
- environment_updated = TRUE;
+ if (!g_utf8_validate (entry_name, -1, NULL))
+ continue;
- out:
+ if (!g_regex_match (name_regex, entry_name, 0, NULL))
+ continue;
- if (bus_proxy != NULL) {
- g_object_unref (bus_proxy);
- }
+ if (!g_utf8_validate (entry_value, -1, NULL))
+ continue;
- if (environment != NULL) {
- g_hash_table_destroy (environment);
+ if (!g_regex_match (value_regex, entry_value, 0, NULL))
+ continue;
+
+ g_variant_builder_add (&builder, "{ss}", entry_name, entry_value);
+ }
+ g_regex_unref (name_regex);
+ g_regex_unref (value_regex);
+
+ g_strfreev (entry_names);
+
+ 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, &bus_error);
+
+ if (bus_error != NULL) {
+ g_propagate_error (error, bus_error);
+ } else {
+ environment_updated = TRUE;
+ g_variant_unref (reply);
}
+ g_clear_object (&connection);
+
return environment_updated;
}
diff --git a/mate-session/gsm-util.h b/mate-session/gsm-util.h
index efc980c..112ce6f 100644
--- a/mate-session/gsm-util.h
+++ b/mate-session/gsm-util.h
@@ -48,6 +48,8 @@ void gsm_util_init_error (gboolean fatal,
char * gsm_util_generate_startup_id (void);
+gboolean gsm_util_export_activation_environment (GError **error);
+
void gsm_util_setenv (const char *variable,
const char *value);
diff --git a/mate-session/main.c b/mate-session/main.c
index db55ebd..da931af 100644
--- a/mate-session/main.c
+++ b/mate-session/main.c
@@ -620,6 +620,8 @@ int main(int argc, char** argv)
exit(1);
}
+ gsm_util_export_activation_environment (NULL);
+
mdm_log_init();
/* Allows to enable/disable debug from GSettings only if it is not set from argument */
@@ -727,3 +729,4 @@ int main(int argc, char** argv)
return 0;
}
+
From f992dd90dab0814085dcc2e09f787ec8dd4b7da6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sun, 7 May 2017 12:48:32 +0200
Subject: [PATCH 2/2] systemd user-session needs to be updated to get all
user-defined enviroment when the session starts.
If we get passed an environment variable, send it along to the
systemd --user session so things running in that context can pick
it up.
See: https://bugzilla.gnome.org/show_bug.cgi?id=736660
---
mate-session/gsm-util.c | 131 +++++++++++++++++++++++++++++++++++++++++++++---
mate-session/gsm-util.h | 4 ++
mate-session/main.c | 4 ++
3 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/mate-session/gsm-util.c b/mate-session/gsm-util.c
index b026f12..92e813b 100644
--- a/mate-session/gsm-util.c
+++ b/mate-session/gsm-util.c
@@ -551,21 +551,140 @@ gsm_util_export_activation_environment (GError **error)
return environment_updated;
}
+#ifdef HAVE_SYSTEMD
+gboolean
+gsm_util_export_user_environment (GError **error)
+{
+ GDBusConnection *connection;
+ gboolean environment_updated = FALSE;
+ char **entries;
+ int i = 0;
+ GVariantBuilder builder;
+ GRegex *regex;
+ GVariant *reply;
+ GError *bus_error = NULL;
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+ if (connection == NULL) {
+ return FALSE;
+ }
+
+ regex = g_regex_new ("^[a-zA-Z_][a-zA-Z0-9_]*=([[:blank:]]|[^[:cntrl:]])*$", G_REGEX_OPTIMIZE, 0, error);
+
+ if (regex == NULL) {
+ return FALSE;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+ for (entries = g_get_environ (); entries[i] != NULL; i++) {
+ const char *entry = entries[i];
+
+ if (!g_utf8_validate (entry, -1, NULL))
+ continue;
+
+ if (!g_regex_match (regex, entry, 0, NULL))
+ continue;
+
+ g_variant_builder_add (&builder, "s", entry);
+ }
+ g_regex_unref (regex);
+
+ g_strfreev (entries);
+
+ reply = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SetEnvironment",
+ g_variant_new ("(@as)",
+ g_variant_builder_end (&builder)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &bus_error);
+
+ if (bus_error != NULL) {
+ g_propagate_error (error, bus_error);
+ } else {
+ environment_updated = TRUE;
+ g_variant_unref (reply);
+ }
+
+ g_clear_object (&connection);
+
+ return environment_updated;
+}
+
+static gboolean
+gsm_util_update_user_environment (const char *variable,
+ const char *value,
+ GError **error)
+{
+ GDBusConnection *connection;
+ gboolean environment_updated;
+ char *entry;
+ GVariantBuilder builder;
+ GVariant *reply;
+ GError *bus_error = NULL;
+
+ environment_updated = FALSE;
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+ if (connection == NULL) {
+ return FALSE;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+ entry = g_strdup_printf ("%s=%s", variable, value);
+ g_variant_builder_add (&builder, "s", entry);
+ g_free (entry);
+
+ reply = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SetEnvironment",
+ g_variant_new ("(@as)",
+ g_variant_builder_end (&builder)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &bus_error);
+
+ if (bus_error != NULL) {
+ g_propagate_error (error, bus_error);
+ } else {
+ environment_updated = TRUE;
+ g_variant_unref (reply);
+ }
+
+ g_clear_object (&connection);
+
+ return environment_updated;
+}
+#endif
+
void
gsm_util_setenv (const char *variable,
const char *value)
{
- GError *bus_error;
+ GError *error = NULL;
g_setenv (variable, value, TRUE);
- bus_error = NULL;
-
/* If this fails it isn't fatal, it means some things like session
* management and keyring won't work in activated clients.
*/
- if (!gsm_util_update_activation_environment (variable, value, &bus_error)) {
- g_warning ("Could not make bus activated clients aware of %s=%s environment variable: %s", variable, value, bus_error->message);
- g_error_free (bus_error);
+ if (!gsm_util_update_activation_environment (variable, value, &error)) {
+ g_warning ("Could not make bus activated clients aware of %s=%s environment variable: %s", variable, value, error->message);
+ g_clear_error (&error);
+ }
+
+#ifdef HAVE_SYSTEMD
+ /* If this fails, the system user session won't get the updated environment
+ */
+ if (!gsm_util_update_user_environment (variable, value, &error)) {
+ g_debug ("Could not make systemd aware of %s=%s environment variable: %s", variable, value, error->message);
+ g_clear_error (&error);
}
+#endif
}
diff --git a/mate-session/gsm-util.h b/mate-session/gsm-util.h
index 112ce6f..2c406af 100644
--- a/mate-session/gsm-util.h
+++ b/mate-session/gsm-util.h
@@ -50,6 +50,10 @@ char * gsm_util_generate_startup_id (void);
gboolean gsm_util_export_activation_environment (GError **error);
+#ifdef HAVE_SYSTEMD
+gboolean gsm_util_export_user_environment (GError **error);
+#endif
+
void gsm_util_setenv (const char *variable,
const char *value);
diff --git a/mate-session/main.c b/mate-session/main.c
index da931af..161772d 100644
--- a/mate-session/main.c
+++ b/mate-session/main.c
@@ -622,6 +622,10 @@ int main(int argc, char** argv)
gsm_util_export_activation_environment (NULL);
+#ifdef HAVE_SYSTEMD
+ gsm_util_export_user_environment (NULL);
+#endif
+
mdm_log_init();
/* Allows to enable/disable debug from GSettings only if it is not set from argument */