diff --git a/bus/audit.c b/bus/audit.c
index 91f2c5cf65eff82814595a6c5dbb786d9f996ff5..9bfe456a1a319123ac2575b28a0b590a51d1f470 100644
--- a/bus/audit.c
+++ b/bus/audit.c
@@ -54,6 +54,9 @@ bus_audit_init (BusContext *context)
 #ifdef HAVE_LIBAUDIT
   int i;
 
+  if (audit_fd >= 0)
+    return;
+
   capng_get_caps_process ();
 
   /* Work around a bug in libcap-ng < 0.7.7: it leaks a fd, which isn't
@@ -105,7 +108,11 @@ void
 bus_audit_shutdown (void)
 {
 #ifdef HAVE_LIBAUDIT
-  audit_close (audit_fd);
+  if (audit_fd >= 0)
+    {
+      audit_close (audit_fd);
+      audit_fd = -1;
+    }
 #endif /* HAVE_LIBAUDIT */
 }
 
diff --git a/test/bus/dispatch-sha1.c b/test/bus/dispatch-sha1.c
index 364300120f6c661fb744896890ebda8ffe5e64b2..a32508bc010488fbe077f6e71d6ad58d128c0101 100644
--- a/test/bus/dispatch-sha1.c
+++ b/test/bus/dispatch-sha1.c
@@ -27,6 +27,7 @@
 
 #include <dbus/dbus-test-tap.h>
 
+#include "bus/audit.h"
 #include "bus/selinux.h"
 #include "test/test-utils.h"
 
@@ -44,6 +45,8 @@ test_post_hook (void)
 {
   if (_dbus_getenv ("DBUS_TEST_SELINUX"))
     bus_selinux_shutdown ();
+
+  bus_audit_shutdown ();
 }
 
 static DBusTestCase test = { "dispatch-sha1", bus_dispatch_sha1_test };
diff --git a/test/bus/dispatch.c b/test/bus/dispatch.c
index 52bf363d1a76faffc0df3f0962d9f0054e954cc2..ad6718fee11418b5f2b5dbc78d0f8f7e63755678 100644
--- a/test/bus/dispatch.c
+++ b/test/bus/dispatch.c
@@ -27,6 +27,7 @@
 
 #include <dbus/dbus-test-tap.h>
 
+#include "bus/audit.h"
 #include "bus/selinux.h"
 #include "test/test-utils.h"
 
@@ -44,6 +45,8 @@ test_post_hook (void)
 {
   if (_dbus_getenv ("DBUS_TEST_SELINUX"))
     bus_selinux_shutdown ();
+
+  bus_audit_shutdown ();
 }
 
 static DBusTestCase test = { "dispatch", bus_dispatch_test };
diff --git a/test/bus/main.c b/test/bus/main.c
index 770654302bfbd7822633036dc1f67cb99766247f..445e926938d2f7592525fb4ca155af16c576d17d 100644
--- a/test/bus/main.c
+++ b/test/bus/main.c
@@ -28,6 +28,7 @@
 
 #include <dbus/dbus-test-tap.h>
 
+#include "bus/audit.h"
 #include "bus/selinux.h"
 #include "test/test-utils.h"
 
@@ -45,6 +46,8 @@ test_post_hook (void)
 {
   if (_dbus_getenv ("DBUS_TEST_SELINUX"))
     bus_selinux_shutdown ();
+
+  bus_audit_shutdown ();
 }
 
 static DBusTestCase tests[] =
diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c
index 6644795592d23aeae6ef284f13fd6c5d0a0f1ebe..e8bdace3c7623eba11f6a2005af85db5b60c17cb 100644
--- a/test/dbus-daemon.c
+++ b/test/dbus-daemon.c
@@ -2653,7 +2653,7 @@ static Config as_another_user_config = {
     NULL, 1, "valid-config-files/as-another-user.conf",
     /* We start the dbus-daemon as root and drop privileges, like the
      * real system bus does */
-    TEST_USER_ROOT, SPECIFY_ADDRESS
+    TEST_USER_ROOT_DROP_TO_MESSAGEBUS, SPECIFY_ADDRESS
 };
 
 #ifdef ENABLE_TRADITIONAL_ACTIVATION
diff --git a/test/test-utils-glib.c b/test/test-utils-glib.c
index 083c9bfcd6ef5d989c068a475db6e19bf49b1e49..cac62e3593e6cbe02a34a20109c99187451a1865 100644
--- a/test/test-utils-glib.c
+++ b/test/test-utils-glib.c
@@ -126,6 +126,7 @@ spawn_dbus_daemon (const gchar *binary,
           case TEST_USER_ROOT:
             break;
 
+          case TEST_USER_ROOT_DROP_TO_MESSAGEBUS:
           case TEST_USER_MESSAGEBUS:
             pwd = getpwnam (DBUS_USER);
 
@@ -139,6 +140,13 @@ spawn_dbus_daemon (const gchar *binary,
                 return NULL;
               }
 
+            if (user == TEST_USER_ROOT_DROP_TO_MESSAGEBUS)
+              {
+                /* Let the dbus-daemon start as root and drop privileges
+                 * itself */
+                pwd = NULL;
+              }
+
             break;
 
           case TEST_USER_OTHER:
@@ -201,6 +209,24 @@ spawn_dbus_daemon (const gchar *binary,
       &address_fd,
       NULL, /* child's stderr = our stderr */
       &error);
+
+  /* The other uid might not have access to our build directory if we
+   * are building in /root or something */
+  if (user != TEST_USER_ME &&
+      g_getenv ("DBUS_TEST_UNINSTALLED") != NULL &&
+      error != NULL &&
+      error->domain == G_SPAWN_ERROR &&
+      (error->code == G_SPAWN_ERROR_CHDIR ||
+       error->code == G_SPAWN_ERROR_ACCES ||
+       error->code == G_SPAWN_ERROR_PERM))
+    {
+      g_prefix_error (&error, "Unable to launch %s as other user: ",
+          binary);
+      g_test_skip (error->message);
+      g_clear_error (&error);
+      return NULL;
+    }
+
   g_assert_no_error (error);
 
   g_ptr_array_free (argv, TRUE);
@@ -399,6 +425,11 @@ become_other_user (TestUser user,
         username = DBUS_TEST_USER;
         break;
 
+      /* TEST_USER_ROOT_DROP_TO_MESSAGEBUS is only meaningful for
+       * test_get_dbus_daemon(), not as a client */
+      case TEST_USER_ROOT_DROP_TO_MESSAGEBUS:
+        g_return_val_if_reached (FALSE);
+
       case TEST_USER_ME:
       default:
         g_return_val_if_reached (FALSE);
@@ -445,6 +476,11 @@ become_other_user (TestUser user,
             "credentials-passing semantics on this platform");
         return FALSE;
 
+      /* TEST_USER_ROOT_DROP_TO_MESSAGEBUS is only meaningful for
+       * test_get_dbus_daemon(), not as a client */
+      case TEST_USER_ROOT_DROP_TO_MESSAGEBUS:
+        g_return_val_if_reached (FALSE);
+
       case TEST_USER_ME:
       default:
         g_return_val_if_reached (FALSE);
diff --git a/test/test-utils-glib.h b/test/test-utils-glib.h
index ce8171bd19cde508d1f53aae1a7304851f8319f3..c4a2c5436f919e26e824ce4794f0fe77bdcaa937 100644
--- a/test/test-utils-glib.h
+++ b/test/test-utils-glib.h
@@ -45,8 +45,8 @@
  * be run as an arbitrary non-root user, as above.
  *
  * Certain tests can usefully be run again, as root. When this is done,
- * tests using TEST_USER_ROOT, TEST_USER_MESSAGEBUS and/or TEST_USER_OTHER
- * can exercise situations that only arise when there's more than one uid.
+ * tests using a TestUser other than TEST_USER_ME can exercise situations
+ * that only arise when there's more than one uid.
  */
 typedef enum {
     /* Whatever user happens to be running the regression test;
@@ -58,6 +58,11 @@ typedef enum {
      * from configure.ac, usually 'messagebus' but perhaps 'dbus' or
      * '_dbus'. */
     TEST_USER_MESSAGEBUS,
+    /* Run as uid 0, expecting to drop privileges to the user who would
+     * normally run the system bus (so we must skip the test if that user
+     * doesn't exist). Only valid for test_get_dbus_daemon(), not for
+     * test_connect_to_bus_as_user(). */
+    TEST_USER_ROOT_DROP_TO_MESSAGEBUS,
     /* An unprivileged user who is neither root nor DBUS_USER.
      * This is DBUS_TEST_USER from configure.ac, usually 'nobody'. */
     TEST_USER_OTHER