]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - tests/src/test-runner.c
Merge with trunk
[sojka/lightdm.git] / tests / src / test-runner.c
index 1d20bef9bb0c6e2e40cf74139b673fa1a9012f66..644a18d2008b61067ba2a15fffa5a2806b789e32 100644 (file)
@@ -55,6 +55,7 @@ typedef struct
     gchar *language;
     gchar *xsession;
     gchar **layouts;
+    gboolean hidden;
 } AccountsUser;
 static GList *accounts_users = NULL;
 static void handle_user_call (GDBusConnection       *connection,
@@ -119,6 +120,9 @@ static GList *status_clients = NULL;
 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)
@@ -235,7 +239,7 @@ quit (int status)
     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))
@@ -494,6 +498,38 @@ handle_command (const gchar *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-") ||
@@ -526,7 +562,7 @@ handle_command (const gchar *command)
 }
 
 static void
-run_commands ()
+run_commands (void)
 {
     /* Stop daemon if requested */
     while (TRUE)
@@ -998,7 +1034,7 @@ ck_name_acquired_cb (GDBusConnection *connection,
 }
 
 static void
-start_console_kit_daemon ()
+start_console_kit_daemon (void)
 {
     service_count++;
     g_bus_own_name (G_BUS_TYPE_SYSTEM,
@@ -1236,12 +1272,101 @@ start_login1_daemon ()
                     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);
@@ -1259,21 +1384,16 @@ load_passwd_file ()
 
         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;
@@ -1282,6 +1402,18 @@ load_passwd_file ()
             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);
@@ -1302,16 +1434,7 @@ load_passwd_file ()
             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);
         }
@@ -1343,7 +1466,8 @@ handle_accounts_call (GDBusConnection       *connection,
         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));
@@ -1357,16 +1481,8 @@ handle_accounts_call (GDBusConnection       *connection,
         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);
@@ -1453,6 +1569,12 @@ accounts_name_acquired_cb (GDBusConnection *connection,
         "      <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 =
@@ -1509,7 +1631,7 @@ accounts_name_acquired_cb (GDBusConnection *connection,
 }
 
 static void
-start_accounts_service_daemon ()
+start_accounts_service_daemon (void)
 {
     service_count++;
     g_bus_own_name (G_BUS_TYPE_SYSTEM,
@@ -1523,7 +1645,7 @@ start_accounts_service_daemon ()
 }
 
 static void
-run_lightdm ()
+run_lightdm (void)
 {
     GString *command_line;
     gchar **lightdm_argv;
@@ -1576,6 +1698,7 @@ int
 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;
@@ -1639,22 +1762,30 @@ main (int argc, char **argv)
     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)
     {
@@ -1665,13 +1796,13 @@ main (int argc, char **argv)
         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)
@@ -1689,7 +1820,12 @@ main (int argc, char **argv)
     /* 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);
@@ -1702,11 +1838,11 @@ main (int argc, char **argv)
         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 */
@@ -1801,7 +1937,6 @@ main (int argc, char **argv)
     };
     passwd_data = g_string_new ("");
     group_data = g_string_new ("");
-    int i;
     for (i = 0; users[i].user_name; i++)
     {
         GKeyFile *dmrc_file;