summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2015-06-18 14:03:23 +0200
committerAlexander Larsson <alexl@redhat.com>2015-06-22 17:29:19 +0200
commita5c74b3695244733fc06f1724a91e8f44f6b219e (patch)
tree10a1b4734bca634a14bdc7c146b930267e3ad60e
parent6e26045943d27656b4444e157d0d10c025aa69db (diff)
downloadgdm-a5c74b3695244733fc06f1724a91e8f44f6b219e.tar.gz
load env.d/*.env files and set in session environment
This loads key-value files from /usr/share/gdm/env.d/*.env and /etc/gdm/env.d/*.env (in alphabetical filename order) and sets in the session environment. https://bugzilla.gnome.org/show_bug.cgi?id=751158
-rw-r--r--daemon/gdm-session-worker.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 6ed6d6cc..5ae5b3f2 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -1355,6 +1355,130 @@ _lookup_passwd_info (const char *username,
return ret;
}
+static char *
+get_var_cb (const char *key,
+ gpointer user_data)
+{
+ return gdm_session_worker_get_environment_variable (user_data, key);
+}
+
+static void
+load_env_file (GdmSessionWorker *worker,
+ GFile *file)
+{
+ gchar *contents;
+ gchar **lines;
+ gchar *line, *p;
+ gchar *var, *var_end;
+ gchar *expanded;
+ char *filename;
+ int i;
+
+ filename = g_file_get_path (file);
+ g_debug ("Loading env vars from %s\n", filename);
+ g_free (filename);
+
+ if (g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL)) {
+ lines = g_strsplit (contents, "\n", -1);
+ g_free (contents);
+ for (i = 0; lines[i] != NULL; i++) {
+ line = lines[i];
+ p = line;
+ while (g_ascii_isspace (*p))
+ p++;
+ if (*p == '#' || *p == '\0')
+ continue;
+ var = p;
+ while (gdm_shell_var_is_valid_char (*p, p == var))
+ p++;
+ var_end = p;
+ while (g_ascii_isspace (*p))
+ p++;
+ if (var == var_end || *p != '=') {
+ g_warning ("Invalid env.d line '%s'\n", line);
+ continue;
+ }
+ *var_end = 0;
+ p++; /* Skip = */
+ while (g_ascii_isspace (*p))
+ p++;
+
+ expanded = gdm_shell_expand (p, get_var_cb, worker);
+ expanded = g_strchomp (expanded);
+ gdm_session_worker_set_environment_variable (worker, var, expanded);
+ g_free (expanded);
+ }
+ g_strfreev (lines);
+ }
+}
+
+static gint
+compare_str (gconstpointer a,
+ gconstpointer b)
+{
+ return strcmp (*(const char **)a, *(const char **)b);
+}
+
+static void
+gdm_session_worker_load_env_dir (GdmSessionWorker *worker,
+ GFile *dir)
+{
+ GFileInfo *info = NULL;
+ GFileEnumerator *enumerator = NULL;
+ GPtrArray *names = NULL;
+ GFile *file;
+ const gchar *name;
+ int i;
+
+ enumerator = g_file_enumerate_children (dir,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE","
+ G_FILE_ATTRIBUTE_STANDARD_NAME","
+ G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN","
+ G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, NULL);
+ if (!enumerator) {
+ goto out;
+ }
+
+ names = g_ptr_array_new_with_free_func (g_free);
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) {
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR &&
+ !g_file_info_get_is_hidden (info) &&
+ g_str_has_suffix (g_file_info_get_name (info), ".env"))
+ g_ptr_array_add (names, g_strdup (g_file_info_get_name (info)));
+
+ g_clear_object (&info);
+ }
+
+ g_ptr_array_sort (names, compare_str);
+
+ for (i = 0; i < names->len; i++) {
+ name = g_ptr_array_index (names, i);
+ file = g_file_get_child (dir, name);
+ load_env_file (worker, file);
+ g_object_unref (file);
+ }
+
+ out:
+ g_clear_pointer (&names, g_ptr_array_unref);
+ g_clear_object (&enumerator);
+}
+
+static void
+gdm_session_worker_load_env_d (GdmSessionWorker *worker)
+{
+ GFile *dir;
+
+ dir = g_file_new_for_path (DATADIR "/gdm/env.d");
+ gdm_session_worker_load_env_dir (worker, dir);
+ g_object_unref (dir);
+
+ dir = g_file_new_for_path (GDMCONFDIR "/env.d");
+ gdm_session_worker_load_env_dir (worker, dir);
+ g_object_unref (dir);
+}
+
static gboolean
gdm_session_worker_accredit_user (GdmSessionWorker *worker,
GError **error)
@@ -1762,6 +1886,10 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
}
#endif
+ if (!worker->priv->is_program_session) {
+ gdm_session_worker_load_env_d (worker);
+ }
+
environment = gdm_session_worker_get_environment (worker);
g_assert (geteuid () == getuid ());