gchar *language;
gchar *xsession;
gchar **layouts;
+ gboolean hidden;
} AccountsUser;
static GList *accounts_users = NULL;
static void handle_user_call (GDBusConnection *connection,
static void run_lightdm (void);
static void quit (int status);
static void check_status (const gchar *status);
+static AccountsUser *get_accounts_user_by_uid (guint uid);
+static AccountsUser *get_accounts_user_by_name (const gchar *username);
+static void accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal);
static gboolean
kill_timeout_cb (gpointer data)
if (status_socket_name)
unlink (status_socket_name);
- if (temp_dir)
+ if (temp_dir && getenv ("DEBUG") == NULL)
{
gchar *command = g_strdup_printf ("rm -rf %s", temp_dir);
if (system (command))
g_hash_table_insert (children, GINT_TO_POINTER (process->pid), process);
}
}
+ else if (strcmp (name, "ADD-USER") == 0)
+ {
+ gchar *status_text, *username;
+ AccountsUser *user;
+
+ username = g_hash_table_lookup (params, "USERNAME");
+ user = get_accounts_user_by_name (username);
+ if (user)
+ accounts_user_set_hidden (user, FALSE, TRUE);
+ else
+ g_warning ("Unknown user %s", username);
+
+ status_text = g_strdup_printf ("RUNNER ADD-USER USERNAME=%s", username);
+ check_status (status_text);
+ g_free (status_text);
+ }
+ else if (strcmp (name, "DELETE-USER") == 0)
+ {
+ gchar *status_text, *username;
+ AccountsUser *user;
+
+ username = g_hash_table_lookup (params, "USERNAME");
+ user = get_accounts_user_by_name (username);
+ if (user)
+ accounts_user_set_hidden (user, TRUE, TRUE);
+ else
+ g_warning ("Unknown user %s", username);
+
+ status_text = g_strdup_printf ("RUNNER DELETE-USER USERNAME=%s", username);
+ check_status (status_text);
+ g_free (status_text);
+ }
/* Forward to external processes */
else if (g_str_has_prefix (name, "SESSION-") ||
g_str_has_prefix (name, "GREETER-") ||
}
static void
-run_commands ()
+run_commands (void)
{
/* Stop daemon if requested */
while (TRUE)
}
static void
-start_console_kit_daemon ()
+start_console_kit_daemon (void)
{
service_count++;
g_bus_own_name (G_BUS_TYPE_SYSTEM,
NULL);
}
+static AccountsUser *
+get_accounts_user_by_uid (guint uid)
+{
+ GList *link;
+
+ for (link = accounts_users; link; link = link->next)
+ {
+ AccountsUser *u = link->data;
+ if (u->uid == uid)
+ return u;
+ }
+
+ return NULL;
+}
+
+static AccountsUser *
+get_accounts_user_by_name (const gchar *username)
+{
+ GList *link;
+
+ for (link = accounts_users; link; link = link->next)
+ {
+ AccountsUser *u = link->data;
+ if (strcmp (u->user_name, username) == 0)
+ return u;
+ }
+
+ return NULL;
+}
+
+static void
+accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal)
+{
+ GError *error = NULL;
+
+ user->hidden = hidden;
+
+ if (user->hidden && user->id != 0)
+ {
+ g_dbus_connection_unregister_object (accounts_connection, user->id);
+ g_dbus_connection_emit_signal (accounts_connection,
+ NULL,
+ "/org/freedesktop/Accounts",
+ "org.freedesktop.Accounts",
+ "UserDeleted",
+ g_variant_new ("(o)", user->path),
+ &error);
+ if (error)
+ g_warning ("Failed to emit UserDeleted: %s", error->message);
+ g_clear_error (&error);
+
+ user->id = 0;
+ }
+ if (!user->hidden && user->id == 0)
+ {
+ user->id = g_dbus_connection_register_object (accounts_connection,
+ user->path,
+ user_info->interfaces[0],
+ &user_vtable,
+ user,
+ NULL,
+ &error);
+ if (error)
+ g_warning ("Failed to register user: %s", error->message);
+ g_clear_error (&error);
+
+ g_dbus_connection_emit_signal (accounts_connection,
+ NULL,
+ "/org/freedesktop/Accounts",
+ "org.freedesktop.Accounts",
+ "UserAdded",
+ g_variant_new ("(o)", user->path),
+ &error);
+ if (error)
+ g_warning ("Failed to emit UserAdded: %s", error->message);
+ g_clear_error (&error);
+ }
+}
+
static void
-load_passwd_file ()
+load_passwd_file (void)
{
gchar *path, *data, **lines;
+ gchar **user_filter = NULL;
int i;
+ if (g_key_file_has_key (config, "test-runner-config", "accounts-service-user-filter", NULL))
+ {
+ gchar *filter;
+
+ filter = g_key_file_get_string (config, "test-runner-config", "accounts-service-user-filter", NULL);
+ user_filter = g_strsplit (filter, " ", -1);
+ g_free (filter);
+ }
+
path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "passwd", NULL);
g_file_get_contents (path, &data, NULL, NULL);
g_free (path);
fields = g_strsplit (lines[i], ":", -1);
if (fields == NULL || g_strv_length (fields) < 7)
+ {
+ g_strfreev (fields);
continue;
+ }
user_name = fields[0];
uid = atoi (fields[2]);
real_name = fields[4];
- for (link = accounts_users; link; link = link->next)
- {
- AccountsUser *u = link->data;
- if (u->uid == uid)
- {
- user = u;
- break;
- }
- }
+ user = get_accounts_user_by_uid (uid);
if (!user)
{
gchar *path;
user = g_malloc0 (sizeof (AccountsUser));
accounts_users = g_list_append (accounts_users, user);
+ /* Only allow users in whitelist */
+ user->hidden = FALSE;
+ if (user_filter)
+ {
+ int j;
+
+ user->hidden = TRUE;
+ for (j = 0; user_filter[j] != NULL; j++)
+ if (strcmp (user_name, user_filter[j]) == 0)
+ user->hidden = FALSE;
+ }
+
dmrc_file = g_key_file_new ();
path = g_build_filename (temp_dir, "home", user_name, ".dmrc", NULL);
g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_NONE, NULL);
user->xsession = g_key_file_get_string (dmrc_file, "Desktop", "Session", NULL);
user->layouts = g_key_file_get_string_list (dmrc_file, "X-Accounts", "Layouts", NULL, NULL);
user->path = g_strdup_printf ("/org/freedesktop/Accounts/User%d", uid);
- user->id = g_dbus_connection_register_object (accounts_connection,
- user->path,
- user_info->interfaces[0],
- &user_vtable,
- user,
- NULL,
- &error);
- if (error)
- g_warning ("Failed to register user: %s", error->message);
- g_clear_error (&error);
+ accounts_user_set_hidden (user, user->hidden, FALSE);
g_key_file_free (dmrc_file);
}
for (link = accounts_users; link; link = link->next)
{
AccountsUser *user = link->data;
- g_variant_builder_add_value (&builder, g_variant_new_object_path (user->path));
+ if (!user->hidden)
+ g_variant_builder_add_value (&builder, g_variant_new_object_path (user->path));
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ao)", &builder));
g_variant_get (parameters, "(&s)", &user_name);
load_passwd_file ();
- for (link = accounts_users; link; link = link->next)
- {
- AccountsUser *u = link->data;
- if (strcmp (u->user_name, user_name) == 0)
- {
- user = u;
- break;
- }
- }
- if (user)
+ user = get_accounts_user_by_name (user_name);
+ if (user && !user->hidden)
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", user->path));
else
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such user: %s", user_name);
" <arg name='name' direction='in' type='s'/>"
" <arg name='user' direction='out' type='o'/>"
" </method>"
+ " <signal name='UserAdded'>"
+ " <arg name='user' type='o'/>"
+ " </signal>"
+ " <signal name='UserDeleted'>"
+ " <arg name='user' type='o'/>"
+ " </signal>"
" </interface>"
"</node>";
static const GDBusInterfaceVTable accounts_vtable =
}
static void
-start_accounts_service_daemon ()
+start_accounts_service_daemon (void)
{
service_count++;
g_bus_own_name (G_BUS_TYPE_SYSTEM,
}
static void
-run_lightdm ()
+run_lightdm (void)
{
GString *command_line;
gchar **lightdm_argv;
main (int argc, char **argv)
{
GMainLoop *loop;
+ int i;
gchar *greeter = NULL, *script_name, *config_file, *path, *path1, *path2, *ld_preload, *ld_library_path, *home_dir;
GString *passwd_data, *group_data;
GSource *status_source;
g_setenv ("GI_TYPELIB_PATH", path1, TRUE);
g_free (path1);
- /* Run from a temporary directory */
- temp_dir = g_build_filename (g_get_tmp_dir (), "lightdm-test-XXXXXX", NULL);
- if (!mkdtemp (temp_dir))
- {
- g_warning ("Error creating temporary directory: %s", strerror (errno));
- quit (EXIT_FAILURE);
- }
- g_chmod (temp_dir, 0755);
+ /* Run in a temporary directory inside the build directory */
+ /* Note we have to pick a name that is short since Unix sockets in this directory have a 108 character limit on their paths */
+ i = 0;
+ while (TRUE) {
+ gchar *name;
+
+ name = g_strdup_printf (".r%d", i);
+ g_free (temp_dir);
+ temp_dir = g_build_filename ("/tmp", name, NULL);
+ g_free (name);
+ if (!g_file_test (temp_dir, G_FILE_TEST_EXISTS))
+ break;
+ i++;
+ }
+ g_mkdir_with_parents (temp_dir, 0755);
g_setenv ("LIGHTDM_TEST_ROOT", temp_dir, TRUE);
/* Open socket for status */
- status_socket_name = g_build_filename (temp_dir, ".status-socket", NULL);
+ /* Note we have to pick a socket name that is short since there is a 108 character limit on the name */
+ status_socket_name = g_build_filename (temp_dir, ".s", NULL);
unlink (status_socket_name);
status_socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
if (error)
- g_warning ("Error creating status socket: %s", error->message);
+ g_warning ("Error creating status socket %s: %s", status_socket_name, error->message);
g_clear_error (&error);
if (status_socket)
{
result = g_socket_bind (status_socket, address, FALSE, &error);
g_object_unref (address);
if (error)
- g_warning ("Error binding status socket: %s", error->message);
+ g_warning ("Error binding status socket %s: %s", status_socket_name, error->message);
g_clear_error (&error);
if (result)
{
result = g_socket_listen (status_socket, &error);
if (error)
- g_warning ("Error listening on status socket: %s", error->message);
+ g_warning ("Error listening on status socket %s: %s", status_socket_name, error->message);
g_clear_error (&error);
}
if (!result)
/* Set up a skeleton file system */
g_mkdir_with_parents (g_strdup_printf ("%s/etc", temp_dir), 0755);
g_mkdir_with_parents (g_strdup_printf ("%s/usr/share", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/xsessions", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/remote-sessions", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/xgreeters", temp_dir), 0755);
g_mkdir_with_parents (g_strdup_printf ("%s/tmp", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/var/run", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/var/log", temp_dir), 0755);
/* Copy over the configuration */
g_mkdir_with_parents (g_strdup_printf ("%s/etc/lightdm", temp_dir), 0755);
perror ("Failed to copy configuration");
/* Copy over the greeter files */
- if (system (g_strdup_printf ("cp -r %s/xsessions %s/usr/share", DATADIR, temp_dir)))
+ if (system (g_strdup_printf ("cp %s/xsessions/* %s/usr/share/xsessions", DATADIR, temp_dir)))
perror ("Failed to copy xsessions");
- if (system (g_strdup_printf ("cp -r %s/remote-sessions %s/usr/share", DATADIR, temp_dir)))
+ if (system (g_strdup_printf ("cp %s/remote-sessions/* %s/usr/share/remote-sessions", DATADIR, temp_dir)))
perror ("Failed to copy remote sessions");
- if (system (g_strdup_printf ("cp -r %s/xgreeters %s/usr/share", DATADIR, temp_dir)))
+ if (system (g_strdup_printf ("cp %s/xgreeters/* %s/usr/share/xgreeters", DATADIR, temp_dir)))
perror ("Failed to copy xgreeters");
/* Set up the default greeter */
};
passwd_data = g_string_new ("");
group_data = g_string_new ("");
- int i;
for (i = 0; users[i].user_name; i++)
{
GKeyFile *dmrc_file;