1 /*
2 * Copyright (C) 2010-2011 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
4 *
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9 * license.
10 */
11
12 #include <errno.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include "dmrc.h"
17 #include "configuration.h"
18 #include "privileges.h"
19 #include "user-list.h"
20
21 GKeyFile *
dmrc_load(CommonUser * user)22 dmrc_load (CommonUser *user)
23 {
24 g_autoptr(GKeyFile) dmrc_file = g_key_file_new ();
25
26 /* Load from the user directory, if this fails (e.g. the user directory
27 * is not yet mounted) then load from the cache */
28 g_autofree gchar *path = g_build_filename (common_user_get_home_directory (user), ".dmrc", NULL);
29
30 /* Guard against privilege escalation through symlinks, etc. */
31 gboolean drop_privileges = geteuid () == 0;
32 if (drop_privileges)
33 privileges_drop (common_user_get_uid (user), common_user_get_gid (user));
34 gboolean have_dmrc = g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_KEEP_COMMENTS, NULL);
35 if (drop_privileges)
36 privileges_reclaim ();
37
38 /* If no ~/.dmrc, then load from the cache */
39 if (!have_dmrc)
40 {
41 g_autofree gchar *filename = g_strdup_printf ("%s.dmrc", common_user_get_name (user));
42 g_autofree gchar *cache_dir = config_get_string (config_get_instance (), "LightDM", "cache-directory");
43 g_autofree gchar *cache_path = g_build_filename (cache_dir, "dmrc", filename, NULL);
44
45 g_key_file_load_from_file (dmrc_file, cache_path, G_KEY_FILE_KEEP_COMMENTS, NULL);
46 }
47
48 return g_steal_pointer (&dmrc_file);
49 }
50
51 void
dmrc_save(GKeyFile * dmrc_file,CommonUser * user)52 dmrc_save (GKeyFile *dmrc_file, CommonUser *user)
53 {
54 gsize length;
55 g_autofree gchar *data = g_key_file_to_data (dmrc_file, &length, NULL);
56
57 /* Update the users .dmrc */
58 g_autofree gchar *path = g_build_filename (common_user_get_home_directory (user), ".dmrc", NULL);
59
60 /* Guard against privilege escalation through symlinks, etc. */
61 gboolean drop_privileges = geteuid () == 0;
62 if (drop_privileges)
63 privileges_drop (common_user_get_uid (user), common_user_get_gid (user));
64 g_debug ("Writing %s", path);
65 g_file_set_contents (path, data, length, NULL);
66 if (drop_privileges)
67 privileges_reclaim ();
68
69 /* Update the .dmrc cache */
70 g_autofree gchar *cache_dir = config_get_string (config_get_instance (), "LightDM", "cache-directory");
71 g_autofree gchar *dmrc_cache_dir = g_build_filename (cache_dir, "dmrc", NULL);
72 if (g_mkdir_with_parents (dmrc_cache_dir, 0700) < 0)
73 g_warning ("Failed to make DMRC cache directory %s: %s", dmrc_cache_dir, strerror (errno));
74
75 g_autofree gchar *filename = g_strdup_printf ("%s.dmrc", common_user_get_name (user));
76 g_autofree gchar *cache_path = g_build_filename (dmrc_cache_dir, filename, NULL);
77 g_file_set_contents (cache_path, data, length, NULL);
78 }
79