From b92cc4ed3c71413a10f64a86e548d47133d203eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 6 May 2017 23:04:08 +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
---
cinnamon-session/csm-util.c | 123 +++++++++++++++++++++++++++++++++-----------
cinnamon-session/csm-util.h | 2 +
cinnamon-session/main.c | 2 +
3 files changed, 98 insertions(+), 29 deletions(-)
diff --git a/cinnamon-session/csm-util.c b/cinnamon-session/csm-util.c
index 4fdd6d7..94d16fd 100644
--- a/cinnamon-session/csm-util.c
+++ b/cinnamon-session/csm-util.c
@@ -505,54 +505,119 @@ csm_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
+csm_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/cinnamon-session/csm-util.h b/cinnamon-session/csm-util.h
index 6076867..b2392b9 100644
--- a/cinnamon-session/csm-util.h
+++ b/cinnamon-session/csm-util.h
@@ -52,6 +52,8 @@ void csm_util_init_error (gboolean fatal,
char * csm_util_generate_startup_id (void);
+gboolean csm_util_export_activation_environment (GError **error);
+
void csm_util_setenv (const char *variable,
const char *value);
diff --git a/cinnamon-session/main.c b/cinnamon-session/main.c
index f909819..221235b 100644
--- a/cinnamon-session/main.c
+++ b/cinnamon-session/main.c
@@ -341,6 +341,8 @@ main (int argc, char **argv)
exit (1);
}
+ csm_util_export_activation_environment (NULL);
+
mdm_log_init ();
mdm_log_set_debug (debug);
From 1f76506af33cb72348ee980b651e3dd8746174bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sat, 6 May 2017 23:20:28 +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
---
cinnamon-session/csm-util.c | 127 +++++++++++++++++++++++++++++++++++++++++---
cinnamon-session/csm-util.h | 2 +
cinnamon-session/main.c | 1 +
3 files changed, 124 insertions(+), 6 deletions(-)
diff --git a/cinnamon-session/csm-util.c b/cinnamon-session/csm-util.c
index 94d16fd..fa4e2bd 100644
--- a/cinnamon-session/csm-util.c
+++ b/cinnamon-session/csm-util.c
@@ -621,22 +621,137 @@ csm_util_export_activation_environment (GError **error)
return environment_updated;
}
+gboolean
+csm_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
+csm_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;
+}
+
void
csm_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 (!csm_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 (!csm_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);
+ }
+
+ /* If this fails, the system user session won't get the updated environment
+ */
+ if (!csm_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);
}
}
diff --git a/cinnamon-session/csm-util.h b/cinnamon-session/csm-util.h
index b2392b9..cfd5ddd 100644
--- a/cinnamon-session/csm-util.h
+++ b/cinnamon-session/csm-util.h
@@ -54,6 +54,8 @@ char * csm_util_generate_startup_id (void);
gboolean csm_util_export_activation_environment (GError **error);
+gboolean csm_util_export_user_environment (GError **error);
+
void csm_util_setenv (const char *variable,
const char *value);
diff --git a/cinnamon-session/main.c b/cinnamon-session/main.c
index 221235b..79578a6 100644
--- a/cinnamon-session/main.c
+++ b/cinnamon-session/main.c
@@ -342,6 +342,7 @@ main (int argc, char **argv)
}
csm_util_export_activation_environment (NULL);
+ csm_util_export_user_environment (NULL);
mdm_log_init ();
mdm_log_set_debug (debug);