2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
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
16 #include "user-manager.h"
17 #include "user-manager-glue.h"
19 struct UserManagerPrivate
21 /* Configuration file */
24 /* TRUE if have scanned users */
31 G_DEFINE_TYPE (UserManager, user_manager, G_TYPE_OBJECT);
34 user_manager_new (GKeyFile *config_file)
38 manager = g_object_new (USER_MANAGER_TYPE, NULL);
39 manager->priv->config = config_file;
45 compare_user (gconstpointer a, gconstpointer b)
47 const UserInfo *user_a = a, *user_b = b;
48 const gchar *name_a, *name_b;
49 name_a = user_a->real_name ? user_a->real_name : user_a->name;
50 name_b = user_b->real_name ? user_b->real_name : user_b->name;
51 return strcmp (name_a, name_b);
55 update_users (UserManager *manager)
57 gchar **hidden_users, **hidden_shells;
61 if (manager->priv->have_users)
64 /* User listing is disabled */
65 if (g_key_file_has_key (manager->priv->config, "UserManager", "load-users", NULL) &&
66 !g_key_file_get_boolean (manager->priv->config, "UserManager", "load-users", NULL))
68 manager->priv->have_users = TRUE;
72 if (g_key_file_has_key (manager->priv->config, "UserManager", "minimum-uid", NULL))
73 minimum_uid = g_key_file_get_integer (manager->priv->config, "UserManager", "minimum-uid", NULL);
77 value = g_key_file_get_string (manager->priv->config, "UserManager", "hidden-users", NULL);
79 value = g_strdup ("nobody nobody4 noaccess");
80 hidden_users = g_strsplit (value, " ", -1);
83 value = g_key_file_get_string (manager->priv->config, "UserManager", "hidden-shells", NULL);
85 value = g_strdup ("/bin/false /usr/sbin/nologin");
86 hidden_shells = g_strsplit (value, " ", -1);
104 /* Ignore system users */
105 if (entry->pw_uid < minimum_uid)
108 /* Ignore users disabled by shell */
111 for (i = 0; hidden_shells[i] && strcmp (entry->pw_shell, hidden_shells[i]) != 0; i++);
112 if (hidden_shells[i])
116 /* Ignore certain users */
117 for (i = 0; hidden_users[i] && strcmp (entry->pw_name, hidden_users[i]) != 0; i++);
121 user = g_malloc0 (sizeof (UserInfo));
122 user->name = g_strdup (entry->pw_name);
124 tokens = g_strsplit (entry->pw_gecos, ",", -1);
125 if (tokens[0] != NULL && tokens[0][0] != '\0')
126 user->real_name = g_strdup (tokens[0]);
128 user->real_name = NULL;
131 user->home_dir = g_strdup (entry->pw_dir);
133 image_path = g_build_filename (user->home_dir, ".face", NULL);
134 if (g_file_test (image_path, G_FILE_TEST_EXISTS))
135 user->image = g_filename_to_uri (image_path, NULL, NULL);
137 user->image = g_strdup ("");
140 manager->priv->users = g_list_insert_sorted (manager->priv->users, user, compare_user);
144 g_warning ("Failed to read password database: %s", strerror (errno));
148 g_strfreev (hidden_users);
149 g_strfreev (hidden_shells);
151 manager->priv->have_users = TRUE;
155 user_manager_get_num_users (UserManager *manager)
157 update_users (manager);
158 return g_list_length (manager->priv->users);
162 user_manager_get_user (UserManager *manager, const gchar *username)
166 update_users (manager);
168 for (link = manager->priv->users; link; link = link->next)
170 UserInfo *info = link->data;
171 if (strcmp (info->name, username) == 0)
178 #define TYPE_USER dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID)
181 user_manager_get_users (UserManager *manager, GPtrArray **users, GError *error)
185 update_users (manager);
187 *users = g_ptr_array_sized_new (g_list_length (manager->priv->users));
188 for (link = manager->priv->users; link; link = link->next)
190 UserInfo *info = link->data;
191 GValue value = { 0 };
193 g_value_init (&value, TYPE_USER);
194 g_value_take_boxed (&value, dbus_g_type_specialized_construct (TYPE_USER));
195 dbus_g_type_struct_set (&value, 0, info->name, 1, info->real_name, 2, info->image, 3, info->logged_in, G_MAXUINT);
196 g_ptr_array_add (*users, g_value_get_boxed (&value));
203 user_manager_get_user_defaults (UserManager *manager, gchar *username, gchar **language, gchar **layout, gchar **session, GError *error)
205 const UserInfo *info;
210 info = user_manager_get_user (manager, username);
214 dmrc_file = g_key_file_new ();
215 g_key_file_set_string (dmrc_file, "Desktop", "Language", "");
216 g_key_file_set_string (dmrc_file, "Desktop", "Layout", "");
217 g_key_file_set_string (dmrc_file, "Desktop", "Session", "");
219 /* Load the users login settings (~/.dmrc) */
220 path = g_build_filename (info->home_dir, ".dmrc", NULL);
221 have_dmrc = g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_NONE, NULL);
224 /* If no .dmrc, then load from the cache */
229 filename = g_strdup_printf ("%s.dmrc", username);
230 path = g_build_filename (CACHE_DIR, "dmrc", filename, NULL);
232 have_dmrc = g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_NONE, NULL);
236 *language = g_key_file_get_string (dmrc_file, "Desktop", "Language", NULL);
237 *layout = g_key_file_get_string (dmrc_file, "Desktop", "Layout", NULL);
238 *session = g_key_file_get_string (dmrc_file, "Desktop", "Session", NULL);
240 g_key_file_free (dmrc_file);
247 user_manager_init (UserManager *manager)
249 manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, USER_MANAGER_TYPE, UserManagerPrivate);
253 user_manager_class_init (UserManagerClass *klass)
255 g_type_class_add_private (klass, sizeof (UserManagerPrivate));
257 dbus_g_object_type_install_info (USER_MANAGER_TYPE, &dbus_glib_user_manager_object_info);