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