1 /* Integration tests for the dbus-daemon's uid-based hardening
3 * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
4 * Copyright © 2010-2011 Nokia Corporation
5 * Copyright © 2015 Collabora Ltd.
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation files
9 * (the "Software"), to deal in the Software without restriction,
10 * including without limitation the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include "test-utils-glib.h"
46 const char *config_file;
48 gboolean expect_success;
53 gconstpointer context)
55 const Config *config = context;
58 f->ctx = test_main_context_get ();
60 dbus_error_init (&f->e);
62 address = test_get_dbus_daemon (config ? config->config_file : NULL,
63 TEST_USER_MESSAGEBUS, NULL,
72 f->conn = test_connect_to_bus_as_user (f->ctx, address,
73 config ? config->user : TEST_USER_ME);
83 gconstpointer context)
85 const Config *config = context;
88 DBusMessageIter args_iter;
89 DBusMessageIter arr_iter;
94 m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
95 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "UpdateActivationEnvironment");
100 dbus_message_iter_init_append (m, &args_iter);
102 /* Append an empty a{ss} (string => string dictionary). */
103 if (!dbus_message_iter_open_container (&args_iter, DBUS_TYPE_ARRAY,
104 "{ss}", &arr_iter) ||
105 !dbus_message_iter_close_container (&args_iter, &arr_iter))
108 if (!dbus_connection_send_with_reply (f->conn, m, &pc,
109 DBUS_TIMEOUT_USE_DEFAULT) ||
113 dbus_message_unref (m);
116 if (dbus_pending_call_get_completed (pc))
117 test_pending_call_store_reply (pc, &m);
118 else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
123 test_main_context_iterate (f->ctx, TRUE);
125 if (config->expect_success)
128 g_assert_cmpint (dbus_message_get_type (m), ==,
129 DBUS_MESSAGE_TYPE_METHOD_RETURN);
133 /* it fails, yielding an error message with one string argument */
134 g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
135 g_assert_cmpstr (dbus_message_get_error_name (m), ==,
136 DBUS_ERROR_ACCESS_DENIED);
137 g_assert_cmpstr (dbus_message_get_signature (m), ==, "s");
140 dbus_message_unref (m);
144 test_monitor (Fixture *f,
145 gconstpointer context)
147 const Config *config = context;
150 DBusMessageIter args_iter;
151 DBusMessageIter arr_iter;
152 dbus_uint32_t no_flags = 0;
157 m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
158 DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
163 dbus_message_iter_init_append (m, &args_iter);
165 /* Append an empty as (string array). */
166 if (!dbus_message_iter_open_container (&args_iter, DBUS_TYPE_ARRAY,
168 !dbus_message_iter_close_container (&args_iter, &arr_iter) ||
169 !dbus_message_iter_append_basic (&args_iter,
170 DBUS_TYPE_UINT32, &no_flags))
173 if (!dbus_connection_send_with_reply (f->conn, m, &pc,
174 DBUS_TIMEOUT_USE_DEFAULT) ||
178 dbus_message_unref (m);
181 if (dbus_pending_call_get_completed (pc))
182 test_pending_call_store_reply (pc, &m);
183 else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
188 test_main_context_iterate (f->ctx, TRUE);
190 if (config->expect_success)
193 g_assert_cmpint (dbus_message_get_type (m), ==,
194 DBUS_MESSAGE_TYPE_METHOD_RETURN);
198 /* it fails, yielding an error message with one string argument */
199 g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
200 g_assert_cmpstr (dbus_message_get_error_name (m), ==,
201 DBUS_ERROR_ACCESS_DENIED);
202 g_assert_cmpstr (dbus_message_get_signature (m), ==, "s");
205 dbus_message_unref (m);
209 teardown (Fixture *f,
210 gconstpointer context G_GNUC_UNUSED)
212 dbus_error_free (&f->e);
213 g_clear_error (&f->ge);
217 dbus_connection_close (f->conn);
218 dbus_connection_unref (f->conn);
222 if (f->daemon_pid != 0)
224 test_kill_pid (f->daemon_pid);
225 g_spawn_close_pid (f->daemon_pid);
229 test_main_context_unref (f->ctx);
232 static Config root_ok_config = {
233 "valid-config-files/multi-user.conf",
238 static Config messagebus_ok_config = {
239 "valid-config-files/multi-user.conf",
240 TEST_USER_MESSAGEBUS,
244 static Config other_fail_config = {
245 "valid-config-files/multi-user.conf",
254 test_init (&argc, &argv);
256 /* UpdateActivationEnvironment used to be allowed by dbus-daemon for root
257 * and messagebus but not for other users (although system.conf forbids it
258 * for everyone, and it's useless). It is now hard-coded to fail on a
259 * system bus for everyone, so don't assert that root and messagebus
260 * may call it; continue to assert that it is denied for unprivileged
262 g_test_add ("/uid-permissions/uae/other", Fixture, &other_fail_config,
263 setup, test_uae, teardown);
265 /* BecomeMonitor has the behaviour that UAE used to have. */
266 g_test_add ("/uid-permissions/monitor/root", Fixture, &root_ok_config,
267 setup, test_monitor, teardown);
268 g_test_add ("/uid-permissions/monitor/messagebus", Fixture, &messagebus_ok_config,
269 setup, test_monitor, teardown);
270 g_test_add ("/uid-permissions/monitor/other", Fixture, &other_fail_config,
271 setup, test_monitor, teardown);
273 return g_test_run ();