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