summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorAdrian Szyndela <adrian.s@samsung.com>2020-04-07 08:00:23 +0200
committerAdrian Szyndela <adrian.s@samsung.com>2020-04-16 12:29:39 +0200
commit931a8fa172e295be9b14ee5c5ed7658f3f0d86dd (patch)
tree2694374a1fea462046be21e0773567ac9d8992c1 /bus
parent4255f571aea9dbd7eba3accd1144c7df53958a7d (diff)
parent23cc709db8fab94f11fa48772bff396b20aea8b0 (diff)
downloaddbus-931a8fa172e295be9b14ee5c5ed7658f3f0d86dd.tar.gz
dbus-931a8fa172e295be9b14ee5c5ed7658f3f0d86dd.tar.bz2
dbus-931a8fa172e295be9b14ee5c5ed7658f3f0d86dd.zip
Merge dbus-1.12.16 into tizen
dbus 1.12.16
Diffstat (limited to 'bus')
-rw-r--r--bus/Makefile.am87
-rw-r--r--bus/activation-helper.c2
-rw-r--r--bus/activation-helper.h2
-rw-r--r--bus/activation.c413
-rw-r--r--bus/activation.h1
-rw-r--r--bus/apparmor.c43
-rw-r--r--bus/audit.c5
-rw-r--r--bus/bus.c193
-rw-r--r--bus/bus.h8
-rw-r--r--bus/config-loader-expat.c25
-rw-r--r--bus/config-parser-common.c7
-rw-r--r--bus/config-parser-trivial.c72
-rw-r--r--bus/config-parser-trivial.h2
-rw-r--r--bus/config-parser.c988
-rw-r--r--bus/config-parser.h21
-rw-r--r--bus/connection.c170
-rw-r--r--bus/connection.h4
-rw-r--r--bus/dbus.service.in2
-rw-r--r--bus/desktop-file.c14
-rw-r--r--bus/desktop-file.h1
-rw-r--r--bus/dir-watch-inotify.c6
-rw-r--r--bus/dir-watch-kqueue.c8
-rw-r--r--bus/dispatch.c323
-rw-r--r--bus/driver.c808
-rw-r--r--bus/driver.h24
-rw-r--r--bus/main.c84
-rw-r--r--bus/messagebus-config.in178
-rwxr-xr-xbus/messagebus.in92
-rw-r--r--bus/policy.c64
-rw-r--r--bus/policy.h12
-rw-r--r--bus/rc.messagebus.in79
-rw-r--r--bus/selinux.c88
-rw-r--r--bus/selinux.h3
-rw-r--r--bus/services.c20
-rw-r--r--bus/signals.c34
-rw-r--r--bus/stats.c46
-rw-r--r--bus/system.conf.in26
-rw-r--r--bus/systemd-user/dbus.service.in2
-rw-r--r--bus/systemd-user/dbus.socket.in2
-rw-r--r--bus/sysusers.d/dbus.conf.in5
-rw-r--r--bus/test-launch-helper.c25
-rw-r--r--bus/test-main.c21
-rw-r--r--bus/test-system.c21
-rw-r--r--bus/test.c8
-rw-r--r--bus/tmpfiles.d/dbus.conf.in9
45 files changed, 2528 insertions, 1520 deletions
diff --git a/bus/Makefile.am b/bus/Makefile.am
index 5f28a25f..a82db939 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -1,9 +1,13 @@
dbusdatadir=$(datadir)/dbus-1
legacydbusdatadir=$(sysconfdir)/dbus-1
dbus_daemon_execdir = $(DBUS_DAEMONDIR)
+# Always lib, even if ${libdir} is lib64 or lib/x86_64-linux-gnu
+systemdtmpfilesdir = $(prefix)/lib/tmpfiles.d
+systemdsysusersdir = $(prefix)/lib/sysusers.d
DBUS_BUS_LIBS = \
- $(XML_LIBS) \
+ $(CODE_COVERAGE_LIBS) \
+ $(EXPAT_LIBS) \
$(SELINUX_LIBS) \
$(APPARMOR_LIBS) \
$(THREAD_LIBS) \
@@ -13,15 +17,17 @@ DBUS_BUS_LIBS = \
$(NULL)
DBUS_LAUNCHER_LIBS = \
- $(XML_LIBS) \
+ $(CODE_COVERAGE_LIBS) \
+ $(EXPAT_LIBS) \
$(THREAD_LIBS) \
$(NETWORK_libs) \
$(NULL)
AM_CPPFLAGS = \
+ $(CODE_COVERAGE_CPPFLAGS) \
-I$(top_srcdir) \
$(DBUS_STATIC_BUILD_CPPFLAGS) \
- $(XML_CFLAGS) \
+ $(EXPAT_CFLAGS) \
$(APPARMOR_CFLAGS) \
-DDBUS_SYSTEM_CONFIG_FILE=\""$(dbusdatadir)/system.conf"\" \
-DDBUS_COMPILATION \
@@ -31,9 +37,13 @@ AM_CPPFLAGS = \
# if assertions are enabled, improve backtraces
AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ -Wl,-z,relro,-z,now
+AM_CFLAGS = \
+ $(CODE_COVERAGE_CFLAGS) \
+ $(NULL)
+
EFENCE=
-CONFIG_IN_FILES= \
+EXTRA_DIST = \
session.conf.in \
system.conf.in \
legacy-config/session.conf.in \
@@ -62,8 +72,6 @@ agentdir=$(LAUNCHD_AGENT_DIR)
agent_DATA=org.freedesktop.dbus-session.plist
endif
-XML_SOURCES=config-loader-expat.c
-
if DBUS_BUS_ENABLE_KQUEUE
DIR_WATCH_SOURCE=dir-watch-kqueue.c
else
@@ -86,6 +94,7 @@ BUS_SOURCES= \
bus.h \
check.c \
check.h \
+ config-loader-expat.c \
config-parser.c \
config-parser.h \
config-parser-common.c \
@@ -118,7 +127,7 @@ BUS_SOURCES= \
test.h \
utils.c \
utils.h \
- $(XML_SOURCES)
+ $(NULL)
dbus_daemon_SOURCES= \
$(BUS_SOURCES) \
@@ -131,7 +140,7 @@ dbus_daemon_LDADD= \
$(DBUS_BUS_LIBS)
LAUNCH_HELPER_SOURCES= \
- $(XML_SOURCES) \
+ config-loader-expat.c \
config-parser-common.c \
config-parser-common.h \
config-parser-trivial.c \
@@ -214,7 +223,7 @@ endif DBUS_UNIX
endif DBUS_ENABLE_EMBEDDED_TESTS
test_bus_system_SOURCES= \
- $(XML_SOURCES) \
+ config-loader-expat.c \
config-parser-common.c \
config-parser-common.h \
config-parser-trivial.c \
@@ -239,10 +248,6 @@ test_bus_LDADD = \
$(DBUS_BUS_LIBS) \
$(NULL)
-## mop up the gcov files
-clean-local:
- /bin/rm *.bb *.bbg *.da *.gcov || true
-
install-data-hook:
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/session.d
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/services
@@ -255,8 +260,6 @@ if HAVE_SYSTEMD
# Install dbus.socket as default implementation of a D-Bus stack.
# Deliberately not using $(LN_S) here: ln -fs is not universally portable,
# but neither is systemd, so it's OK to assume here that ln complies with SUS.
- $(mkinstalldirs) $(DESTDIR)$(systemdsystemunitdir)/dbus.target.wants
- ln -fs ../dbus.socket $(DESTDIR)$(systemdsystemunitdir)/dbus.target.wants/dbus.socket
# Unconditionally enable D-Bus on systemd installations
$(mkinstalldirs) $(DESTDIR)$(systemdsystemunitdir)/sockets.target.wants
ln -fs ../dbus.socket $(DESTDIR)$(systemdsystemunitdir)/sockets.target.wants/dbus.socket
@@ -277,53 +280,26 @@ install-exec-hook:
fi
endif
-#### Init scripts fun
-SCRIPT_IN_FILES=messagebus.in \
- messagebus-config.in \
- rc.messagebus.in
-
-## Red Hat start
-if DBUS_INIT_SCRIPTS_RED_HAT
-
-initddir=$(sysconfdir)/rc.d/init.d
-
-initd_SCRIPTS= \
- messagebus
-
-endif
- ## Red Hat end
-
-## Slackware start
-if DBUS_INIT_SCRIPTS_SLACKWARE
-
-initddir=$(sysconfdir)/rc.d/
-
-initd_SCRIPTS= \
- rc.messagebus
-
-endif
-## Slackware end
-
-## Cygwin start
-if DBUS_INIT_SCRIPTS_CYGWIN
-
-bin_SCRIPTS= \
- messagebus-config
-
-endif
-## Cygwin end
-
-if HAVE_SYSTEMD
-SCRIPT_IN_FILES += \
+EXTRA_DIST += \
dbus.service.in \
dbus.socket.in \
systemd-user/dbus.service.in \
systemd-user/dbus.socket.in \
+ sysusers.d/dbus.conf.in \
+ tmpfiles.d/dbus.conf.in \
$(NULL)
+if HAVE_SYSTEMD
systemdsystemunit_DATA = \
dbus.service \
dbus.socket
+
+nodist_systemdsysusers_DATA = \
+ sysusers.d/dbus.conf
+
+nodist_systemdtmpfiles_DATA = \
+ tmpfiles.d/dbus.conf \
+ $(NULL)
endif
if DBUS_ENABLE_USER_SESSION
@@ -333,6 +309,5 @@ systemduserunit_DATA = \
$(NULL)
endif
-#### Extra dist
-
-EXTRA_DIST=$(CONFIG_IN_FILES) $(SCRIPT_IN_FILES)
+# Add rules for code-coverage testing, as defined by AX_CODE_COVERAGE
+include $(top_srcdir)/aminclude_static.am
diff --git a/bus/activation-helper.c b/bus/activation-helper.c
index 394f3938..5b6a0908 100644
--- a/bus/activation-helper.c
+++ b/bus/activation-helper.c
@@ -80,7 +80,7 @@ desktop_file_for_name (BusConfigParser *parser,
goto out;
}
- service_dirs = bus_config_parser_get_service_dirs (parser);
+ service_dirs = bus_config_parser_get_service_paths (parser);
for (link = _dbus_list_get_first_link (service_dirs);
link != NULL;
link = _dbus_list_get_next_link (service_dirs, link))
diff --git a/bus/activation-helper.h b/bus/activation-helper.h
index 361a4c6a..43e7b150 100644
--- a/bus/activation-helper.h
+++ b/bus/activation-helper.h
@@ -25,6 +25,8 @@
#ifndef BUS_ACTIVATION_HELPER_H
#define BUS_ACTIVATION_HELPER_H
+#include <dbus/dbus.h>
+
dbus_bool_t run_launch_helper (const char *bus_name, DBusError *error);
diff --git a/bus/activation.c b/bus/activation.c
index 99b3554a..9031e60e 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -26,6 +26,7 @@
#include <config.h>
#include "activation.h"
#include "activation-exit-codes.h"
+#include "config-parser.h"
#include "desktop-file.h"
#include "dispatch.h"
#include "services.h"
@@ -54,7 +55,7 @@ struct BusActivation
* i.e. number of pending activation requests, not pending
* activations per se
*/
- DBusHashTable *directories;
+ DBusList *directories;
DBusHashTable *environment;
};
@@ -62,6 +63,7 @@ typedef struct
{
int refcount;
char *dir_c;
+ BusServiceDirFlags flags;
DBusHashTable *entries;
} BusServiceDirectory;
@@ -72,6 +74,7 @@ struct BusActivationEntry
char *exec;
char *user;
char *systemd_service;
+ char *assumed_apparmor_label;
unsigned long mtime;
BusServiceDirectory *s_dir;
char *filename;
@@ -247,6 +250,7 @@ bus_activation_entry_unref (BusActivationEntry *entry)
dbus_free (entry->user);
dbus_free (entry->filename);
dbus_free (entry->systemd_service);
+ dbus_free (entry->assumed_apparmor_label);
dbus_free (entry);
}
@@ -259,11 +263,13 @@ update_desktop_file_entry (BusActivation *activation,
DBusError *error)
{
char *name, *exec, *user, *exec_tmp, *systemd_service;
+ char *assumed_apparmor_label;
BusActivationEntry *entry;
DBusStat stat_buf;
DBusString file_path;
DBusError tmp_error;
dbus_bool_t retval;
+ DBusString str;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -274,6 +280,7 @@ update_desktop_file_entry (BusActivation *activation,
exec_tmp = NULL;
entry = NULL;
systemd_service = NULL;
+ assumed_apparmor_label = NULL;
dbus_error_init (&tmp_error);
@@ -311,9 +318,18 @@ update_desktop_file_entry (BusActivation *activation,
error))
goto out;
- exec = _dbus_strdup (_dbus_replace_install_prefix (exec_tmp));
- dbus_free (exec_tmp);
- exec_tmp = NULL;
+ if (!_dbus_string_init (&str))
+ goto out;
+
+ if (!_dbus_string_append (&str, exec_tmp) ||
+ !_dbus_replace_install_prefix (&str) ||
+ !_dbus_string_steal_data (&str, &exec))
+ {
+ _dbus_string_free (&str);
+ goto out;
+ }
+
+ _dbus_string_free (&str);
/* user is not _required_ unless we are using system activation */
if (!bus_desktop_file_get_string (desktop_file,
@@ -360,6 +376,28 @@ update_desktop_file_entry (BusActivation *activation,
}
}
+ /* assumed AppArmor label is never required */
+ if (!bus_desktop_file_get_string (desktop_file,
+ DBUS_SERVICE_SECTION,
+ DBUS_SERVICE_ASSUMED_APPARMOR_LABEL,
+ &assumed_apparmor_label, &tmp_error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+ /* if we got OOM, then exit */
+ if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
+ {
+ dbus_move_error (&tmp_error, error);
+ goto out;
+ }
+ else
+ {
+ /* if we have error because we didn't find anything then continue */
+ dbus_error_free (&tmp_error);
+ dbus_free (assumed_apparmor_label);
+ assumed_apparmor_label = NULL;
+ }
+ }
+
_DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
entry = _dbus_hash_table_lookup_string (s_dir->entries,
@@ -367,8 +405,69 @@ update_desktop_file_entry (BusActivation *activation,
if (entry == NULL) /* New file */
{
+ DBusString expected_name;
+
+ if (!_dbus_string_init (&expected_name))
+ {
+ BUS_SET_OOM (error);
+ goto out;
+ }
+
+ if (!_dbus_string_append (&expected_name, name) ||
+ !_dbus_string_append (&expected_name, ".service"))
+ {
+ _dbus_string_free (&expected_name);
+ BUS_SET_OOM (error);
+ goto out;
+ }
+
+ if (_dbus_string_equal (&expected_name, filename))
+ {
+ _dbus_verbose ("Name of \"%s\" is as expected\n",
+ _dbus_string_get_const_data (&file_path));
+ }
+ else if (s_dir->flags & BUS_SERVICE_DIR_FLAGS_STRICT_NAMING)
+ {
+ bus_context_log_and_set_error (activation->context,
+ DBUS_SYSTEM_LOG_WARNING, error,
+ DBUS_ERROR_FAILED,
+ "Service file \"%s\" should have "
+ "been named \"%s\": not loading it",
+ _dbus_string_get_const_data (&file_path),
+ _dbus_string_get_const_data (&expected_name));
+ _dbus_string_free (&expected_name);
+ goto out;
+ }
+ else if (bus_context_get_servicehelper (activation->context) != NULL)
+ {
+ bus_context_log (activation->context, DBUS_SYSTEM_LOG_WARNING,
+ "Service file \"%s\" should have been named \"%s\" "
+ "and will not work with system bus activation",
+ _dbus_string_get_const_data (&file_path),
+ _dbus_string_get_const_data (&expected_name));
+ /* We don't actually error out here, because *technically* it could
+ * still work on systemd systems, where we tell systemd to start the
+ * SystemdService instead of launching dbus-daemon-launch-helper
+ * ourselves. But maybe we should:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=99874 */
+ }
+ else
+ {
+ /* We could maybe log mismatched names for session services in
+ * a user-visible way too, but not until
+ * https://lintian.debian.org/tags/dbus-session-service-wrong-name.html
+ * is a bit shorter.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=99873 */
+ _dbus_verbose ("Name of \"%s\" should canonically be \"%s\"\n",
+ _dbus_string_get_const_data (&file_path),
+ _dbus_string_get_const_data (&expected_name));
+ }
+
+ _dbus_string_free (&expected_name);
+
/* FIXME we need a better-defined algorithm for which service file to
* pick than "whichever one is first in the directory listing"
+ * See also https://bugs.freedesktop.org/show_bug.cgi?id=99874
*/
if (_dbus_hash_table_lookup_string (activation->entries, name))
{
@@ -388,6 +487,7 @@ update_desktop_file_entry (BusActivation *activation,
entry->exec = exec;
entry->user = user;
entry->systemd_service = systemd_service;
+ entry->assumed_apparmor_label = assumed_apparmor_label;
entry->refcount = 1;
/* ownership has been transferred to entry, do not free separately */
@@ -395,6 +495,7 @@ update_desktop_file_entry (BusActivation *activation,
exec = NULL;
user = NULL;
systemd_service = NULL;
+ assumed_apparmor_label = NULL;
entry->s_dir = s_dir;
entry->filename = _dbus_strdup (_dbus_string_get_const_data (filename));
@@ -452,6 +553,10 @@ update_desktop_file_entry (BusActivation *activation,
entry->systemd_service = systemd_service;
systemd_service = NULL;
+ dbus_free (entry->assumed_apparmor_label);
+ entry->assumed_apparmor_label = assumed_apparmor_label;
+ assumed_apparmor_label = NULL;
+
if (!_dbus_hash_table_insert_string (activation->entries,
entry->name, bus_activation_entry_ref(entry)))
{
@@ -469,10 +574,12 @@ update_desktop_file_entry (BusActivation *activation,
out:
/* if these have been transferred into entry, the variables will be NULL */
+ dbus_free (exec_tmp);
dbus_free (name);
dbus_free (exec);
dbus_free (user);
dbus_free (systemd_service);
+ dbus_free (assumed_apparmor_label);
_dbus_string_free (&file_path);
if (entry)
@@ -732,9 +839,6 @@ update_directory (BusActivation *activation,
static dbus_bool_t
populate_environment (BusActivation *activation)
{
- DBusString key;
- DBusString value;
- int i;
char **environment;
dbus_bool_t retval = FALSE;
@@ -743,50 +847,7 @@ populate_environment (BusActivation *activation)
if (environment == NULL)
return FALSE;
- if (!_dbus_string_init (&key))
- {
- dbus_free_string_array (environment);
- return FALSE;
- }
-
- if (!_dbus_string_init (&value))
- {
- _dbus_string_free (&key);
- dbus_free_string_array (environment);
- return FALSE;
- }
-
- for (i = 0; environment[i] != NULL; i++)
- {
- if (!_dbus_string_append (&key, environment[i]))
- break;
-
- if (_dbus_string_split_on_byte (&key, '=', &value))
- {
- char *hash_key, *hash_value;
-
- if (!_dbus_string_steal_data (&key, &hash_key))
- break;
-
- if (!_dbus_string_steal_data (&value, &hash_value))
- break;
-
- if (!_dbus_hash_table_insert_string (activation->environment,
- hash_key, hash_value))
- break;
- }
- _dbus_string_set_length (&key, 0);
- _dbus_string_set_length (&value, 0);
- }
-
- if (environment[i] != NULL)
- goto out;
-
- retval = TRUE;
-out:
-
- _dbus_string_free (&key);
- _dbus_string_free (&value);
+ retval = _dbus_hash_table_from_array (activation->environment, environment, '=');
dbus_free_string_array (environment);
return retval;
@@ -819,23 +880,19 @@ bus_activation_reload (BusActivation *activation,
goto failed;
}
- if (activation->directories != NULL)
- _dbus_hash_table_unref (activation->directories);
- activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
- (DBusFreeFunction)bus_service_directory_unref);
-
- if (activation->directories == NULL)
- {
- BUS_SET_OOM (error);
- goto failed;
- }
+ _dbus_list_foreach (&activation->directories,
+ (DBusForeachFunction) bus_service_directory_unref, NULL);
+ _dbus_list_clear (&activation->directories);
link = _dbus_list_get_first_link (directories);
while (link != NULL)
{
+ BusConfigServiceDir *config = link->data;
BusServiceDirectory *s_dir;
- dir = _dbus_strdup ((const char *) link->data);
+ _dbus_assert (config->path != NULL);
+
+ dir = _dbus_strdup (config->path);
if (!dir)
{
BUS_SET_OOM (error);
@@ -852,6 +909,7 @@ bus_activation_reload (BusActivation *activation,
s_dir->refcount = 1;
s_dir->dir_c = dir;
+ s_dir->flags = config->flags;
s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
(DBusFreeFunction)bus_activation_entry_unref);
@@ -863,7 +921,7 @@ bus_activation_reload (BusActivation *activation,
goto failed;
}
- if (!_dbus_hash_table_insert_string (activation->directories, s_dir->dir_c, s_dir))
+ if (!_dbus_list_append (&activation->directories, s_dir))
{
bus_service_directory_unref (s_dir);
BUS_SET_OOM (error);
@@ -970,8 +1028,11 @@ bus_activation_unref (BusActivation *activation)
_dbus_hash_table_unref (activation->entries);
if (activation->pending_activations)
_dbus_hash_table_unref (activation->pending_activations);
- if (activation->directories)
- _dbus_hash_table_unref (activation->directories);
+
+ _dbus_list_foreach (&activation->directories,
+ (DBusForeachFunction) bus_service_directory_unref, NULL);
+ _dbus_list_clear (&activation->directories);
+
if (activation->environment)
_dbus_hash_table_unref (activation->environment);
@@ -1213,6 +1274,7 @@ bus_activation_send_pending_auto_activation_messages (BusActivation *activation
entry->activation_message);
}
+ dbus_error_free (&error);
link = next;
continue;
case BUS_RESULT_LATER:
@@ -1473,7 +1535,8 @@ pending_activation_finished_cb (DBusBabysitter *babysitter,
{
BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
- if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
+ if (p != pending_activation && p->exec != NULL &&
+ strcmp (p->exec, pending_activation->exec) == 0)
pending_activation_failed (p, &error);
}
@@ -1522,7 +1585,12 @@ static dbus_bool_t
pending_activation_timed_out (void *data)
{
BusPendingActivation *pending_activation = data;
+ BusContext *context;
DBusError error;
+ int timeout;
+
+ context = pending_activation->activation->context;
+ timeout = bus_context_get_activation_timeout (context);
/* Kill the spawned process, since it sucks
* (not sure this is what we want to do, but
@@ -1533,10 +1601,11 @@ pending_activation_timed_out (void *data)
dbus_error_init (&error);
- bus_context_log_and_set_error (pending_activation->activation->context,
- DBUS_SYSTEM_LOG_INFO, &error, DBUS_ERROR_TIMED_OUT,
- "Failed to activate service '%s': timed out",
- pending_activation->service_name);
+ bus_context_log_and_set_error (context, DBUS_SYSTEM_LOG_WARNING, &error,
+ DBUS_ERROR_TIMED_OUT,
+ "Failed to activate service '%s': timed out "
+ "(service_start_timeout=%dms)",
+ pending_activation->service_name, timeout);
pending_activation_failed (pending_activation, &error);
@@ -1587,15 +1656,14 @@ add_cancel_pending_to_transaction (BusTransaction *transaction,
static dbus_bool_t
update_service_cache (BusActivation *activation, DBusError *error)
{
- DBusHashIter iter;
+ DBusList *iter;
- _dbus_hash_iter_init (activation->directories, &iter);
- while (_dbus_hash_iter_next (&iter))
+ for (iter = _dbus_list_get_first_link (&activation->directories);
+ iter != NULL;
+ iter = _dbus_list_get_next_link (&activation->directories, iter))
{
DBusError tmp_error;
- BusServiceDirectory *s_dir;
-
- s_dir = _dbus_hash_iter_get_value (&iter);
+ BusServiceDirectory *s_dir = iter->data;
dbus_error_init (&tmp_error);
if (!update_directory (activation, s_dir, &tmp_error))
@@ -1654,51 +1722,7 @@ activation_find_entry (BusActivation *activation,
static char **
bus_activation_get_environment (BusActivation *activation)
{
- char **environment;
- int i, length;
- DBusString entry;
- DBusHashIter iter;
-
- length = _dbus_hash_table_get_n_entries (activation->environment);
-
- environment = dbus_new0 (char *, length + 1);
-
- if (environment == NULL)
- return NULL;
-
- i = 0;
- _dbus_hash_iter_init (activation->environment, &iter);
-
- if (!_dbus_string_init (&entry))
- {
- dbus_free_string_array (environment);
- return NULL;
- }
-
- while (_dbus_hash_iter_next (&iter))
- {
- const char *key, *value;
-
- key = (const char *) _dbus_hash_iter_get_string_key (&iter);
- value = (const char *) _dbus_hash_iter_get_value (&iter);
-
- if (!_dbus_string_append_printf (&entry, "%s=%s", key, value))
- break;
-
- if (!_dbus_string_steal_data (&entry, environment + i))
- break;
- i++;
- }
-
- _dbus_string_free (&entry);
-
- if (i != length)
- {
- dbus_free_string_array (environment);
- environment = NULL;
- }
-
- return environment;
+ return _dbus_hash_table_to_array (activation->environment, '=');
}
dbus_bool_t
@@ -1788,21 +1812,36 @@ bus_activation_activate_service (BusActivation *activation,
BusResult retval = BUS_RESULT_FALSE;
dbus_bool_t was_pending_activation;
DBusString command;
+ int limit;
+ DBusSpawnFlags flags = DBUS_SPAWN_NONE;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (activation->n_pending_activations >=
- bus_context_get_max_pending_activations (activation->context))
+ limit = bus_context_get_max_pending_activations (activation->context);
+
+ if (activation->n_pending_activations >= limit)
{
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
- "The maximum number of pending activations has been reached, activation of %s failed",
- service_name);
+ "The maximum number of pending activations has been "
+ "reached, activation of %s failed "
+ "(max_pending_service_starts=%d)",
+ service_name, limit);
return BUS_RESULT_FALSE;
}
- entry = activation_find_entry (activation, service_name, error);
- if (!entry)
- return BUS_RESULT_FALSE;
+ if (bus_context_get_systemd_activation (activation->context) &&
+ strcmp (service_name, "org.freedesktop.systemd1") == 0)
+ {
+ /* if we're doing systemd activation, we assume systemd will connect
+ * eventually, and it does not need a .service file */
+ entry = NULL;
+ }
+ else
+ {
+ entry = activation_find_entry (activation, service_name, error);
+ if (!entry)
+ return BUS_RESULT_FALSE;
+ }
if (auto_activation && entry != NULL)
{
@@ -1936,17 +1975,20 @@ bus_activation_activate_service (BusActivation *activation,
return BUS_RESULT_FALSE;
}
- pending_activation->exec = _dbus_strdup (entry->exec);
- if (!pending_activation->exec)
+ if (entry != NULL)
{
- _dbus_verbose ("Failed to copy service exec for pending activation\n");
- BUS_SET_OOM (error);
- bus_pending_activation_unref (pending_activation);
- bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ pending_activation->exec = _dbus_strdup (entry->exec);
+ if (!pending_activation->exec)
+ {
+ _dbus_verbose ("Failed to copy service exec for pending activation\n");
+ BUS_SET_OOM (error);
+ bus_pending_activation_unref (pending_activation);
+ bus_pending_activation_entry_free (pending_activation_entry);
+ return FALSE;
+ }
}
- if (entry->systemd_service)
+ if (entry != NULL && entry->systemd_service != NULL)
{
pending_activation->systemd_service = _dbus_strdup (entry->systemd_service);
if (!pending_activation->systemd_service)
@@ -2036,6 +2078,7 @@ bus_activation_activate_service (BusActivation *activation,
DBusString service_string;
BusService *service;
BusRegistry *registry;
+ DBusConnection *systemd = NULL;
/* OK, we have a systemd service configured for this entry,
hence let's enqueue an activation request message. This
@@ -2084,11 +2127,14 @@ bus_activation_activate_service (BusActivation *activation,
_dbus_string_init_const (&service_string, "org.freedesktop.systemd1");
service = bus_registry_lookup (registry, &service_string);
+ if (service)
+ systemd = bus_service_get_primary_owners_connection (service);
+
/* Following the general principle of "log early and often",
* we capture that we *want* to send the activation message, even if
* systemd is not actually there to receive it yet */
if (!bus_transaction_capture (activation_transaction,
- NULL, message))
+ NULL, systemd, message))
{
dbus_message_unref (message);
BUS_SET_OOM (error);
@@ -2098,22 +2144,25 @@ bus_activation_activate_service (BusActivation *activation,
if (service != NULL)
{
bus_context_log (activation->context,
- DBUS_SYSTEM_LOG_INFO, "Activating via systemd: service name='%s' unit='%s'",
+ DBUS_SYSTEM_LOG_INFO, "Activating via systemd: service name='%s' unit='%s' requested by '%s' (%s)",
service_name,
- entry->systemd_service);
+ entry->systemd_service,
+ bus_connection_get_name (connection),
+ bus_connection_get_loginfo (connection));
/* Wonderful, systemd is connected, let's just send the msg */
retval = bus_dispatch_matches (activation_transaction, NULL,
- bus_service_get_primary_owners_connection (service),
- message, NULL, error);
+ systemd, message, NULL, error);
if (BUS_RESULT_LATER == retval)
_dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
}
else
{
bus_context_log (activation->context,
- DBUS_SYSTEM_LOG_INFO, "Activating systemd to hand-off: service name='%s' unit='%s'",
+ DBUS_SYSTEM_LOG_INFO, "Activating systemd to hand-off: service name='%s' unit='%s' requested by '%s' (%s)",
service_name,
- entry->systemd_service);
+ entry->systemd_service,
+ bus_connection_get_name (connection),
+ bus_connection_get_loginfo (connection));
/* systemd is not around, let's "activate" it. */
retval = bus_activation_activate_service (activation, NULL, activation_transaction, TRUE,
message, "org.freedesktop.systemd1", error, deferred_message);
@@ -2141,6 +2190,11 @@ bus_activation_activate_service (BusActivation *activation,
proceed with traditional activation. */
}
+ /* If entry was NULL, it would be because we were doing systemd activation
+ * and activating systemd itself; but we already handled that case with
+ * an early-return */
+ _dbus_assert (entry != NULL);
+
/* use command as system and session different */
if (!_dbus_string_init (&command))
{
@@ -2220,19 +2274,27 @@ bus_activation_activate_service (BusActivation *activation,
_dbus_verbose ("Spawning %s ...\n", argv[0]);
if (servicehelper != NULL)
bus_context_log (activation->context,
- DBUS_SYSTEM_LOG_INFO, "Activating service name='%s' (using servicehelper)",
- service_name);
+ DBUS_SYSTEM_LOG_INFO, "Activating service name='%s' requested by '%s' (%s) (using servicehelper)",
+ service_name,
+ bus_connection_get_name (connection),
+ bus_connection_get_loginfo (connection));
else
bus_context_log (activation->context,
- DBUS_SYSTEM_LOG_INFO, "Activating service name='%s'",
- service_name);
+ DBUS_SYSTEM_LOG_INFO, "Activating service name='%s' requested by '%s' (%s)",
+ service_name,
+ bus_connection_get_name (connection),
+ bus_connection_get_loginfo (connection));
dbus_error_init (&tmp_error);
+ if (bus_context_get_using_syslog (activation->context))
+ flags |= DBUS_SPAWN_REDIRECT_OUTPUT;
+
if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter,
service_name,
argv,
envp,
+ flags,
child_setup,
activation,
&tmp_error))
@@ -2341,7 +2403,7 @@ dbus_activation_systemd_failure (BusActivation *activation,
DBUS_TYPE_STRING, &code,
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID))
- dbus_set_error(&error, code, str);
+ dbus_set_error (&error, code, "%s", str);
if (unit)
@@ -2370,13 +2432,19 @@ dbus_activation_systemd_failure (BusActivation *activation,
return TRUE;
}
+const char *
+bus_activation_entry_get_assumed_apparmor_label (BusActivationEntry *entry)
+{
+ return entry->assumed_apparmor_label;
+}
+
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include <stdio.h>
-#define SERVICE_NAME_1 "MyService1"
-#define SERVICE_NAME_2 "MyService2"
-#define SERVICE_NAME_3 "MyService3"
+#define SERVICE_NAME_1 "com.example.MyService1"
+#define SERVICE_NAME_2 "org.example.MyService2"
+#define SERVICE_NAME_3 "net.example.MyService3"
#define SERVICE_FILE_1 "service-1.service"
#define SERVICE_FILE_2 "service-2.service"
@@ -2503,21 +2571,8 @@ out:
static dbus_bool_t
init_service_reload_test (DBusString *dir)
{
- DBusStat stat_buf;
-
- if (!_dbus_stat (dir, &stat_buf, NULL))
- {
- if (!_dbus_create_directory (dir, NULL))
- return FALSE;
- }
- else
- {
- if (!test_remove_directory (dir))
- return FALSE;
-
- if (!_dbus_create_directory (dir, NULL))
- return FALSE;
- }
+ if (!_dbus_create_directory (dir, NULL))
+ return FALSE;
/* Create one initial file */
if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1"))
@@ -2596,9 +2651,13 @@ do_test (const char *description, dbus_bool_t oom_test, CheckData *data)
}
static dbus_bool_t
-do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
+do_service_reload_test (const DBusString *test_data_dir,
+ DBusString *dir,
+ dbus_bool_t oom_test)
{
BusActivation *activation;
+ BusConfigServiceDir config;
+ BusContext *context;
DBusString address;
DBusList *directories;
CheckData d;
@@ -2606,10 +2665,18 @@ do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
directories = NULL;
_dbus_string_init_const (&address, "");
- if (!_dbus_list_append (&directories, _dbus_string_get_data (dir)))
+ config.path = _dbus_string_get_data (dir);
+ config.flags = BUS_SERVICE_DIR_FLAGS_NONE;
+
+ if (!_dbus_list_append (&directories, &config))
return FALSE;
- activation = bus_activation_new (NULL, &address, &directories, NULL);
+ context = bus_context_new_test (test_data_dir,
+ "valid-config-files/debug-allow-all.conf");
+ if (context == NULL)
+ return FALSE;
+
+ activation = bus_activation_new (context, &address, &directories, NULL);
if (!activation)
return FALSE;
@@ -2670,6 +2737,7 @@ do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
bus_activation_unref (activation);
_dbus_list_clear (&directories);
+ bus_context_unref (context);
return TRUE;
}
@@ -2700,16 +2768,19 @@ bus_activation_service_reload_test (const DBusString *test_data_dir)
if (!init_service_reload_test (&directory))
_dbus_assert_not_reached ("could not initiate service reload test");
- if (!do_service_reload_test (&directory, FALSE))
+ if (!do_service_reload_test (test_data_dir, &directory, FALSE))
{
/* Do nothing? */
}
+ if (!cleanup_service_reload_test (&directory))
+ goto out;
+
/* Do OOM tests */
if (!init_service_reload_test (&directory))
_dbus_assert_not_reached ("could not initiate service reload test");
- if (!do_service_reload_test (&directory, TRUE))
+ if (!do_service_reload_test (test_data_dir, &directory, TRUE))
{
/* Do nothing? */
}
diff --git a/bus/activation.h b/bus/activation.h
index c24f85d3..bd91954f 100644
--- a/bus/activation.h
+++ b/bus/activation.h
@@ -65,5 +65,6 @@ dbus_bool_t bus_activation_send_pending_auto_activation_messages (BusActivati
BusService *service,
BusTransaction *transaction);
+const char *bus_activation_entry_get_assumed_apparmor_label (BusActivationEntry *entry);
#endif /* BUS_ACTIVATION_H */
diff --git a/bus/apparmor.c b/bus/apparmor.c
index 46725dbf..471fb551 100644
--- a/bus/apparmor.c
+++ b/bus/apparmor.c
@@ -46,6 +46,7 @@
#include <libaudit.h>
#endif /* HAVE_LIBAUDIT */
+#include "activation.h"
#include "audit.h"
#include "connection.h"
#include "utils.h"
@@ -606,7 +607,9 @@ bus_apparmor_allows_acquire_service (DBusConnection *connection,
BusAppArmorConfinement *con = NULL;
DBusString qstr, auxdata;
dbus_bool_t free_auxdata = FALSE;
- dbus_bool_t allow = FALSE, audit = TRUE;
+ /* the AppArmor API uses pointers to int for pointers to boolean, and
+ * int is not strictly guaranteed to be the same as dbus_bool_t */
+ int allow = FALSE, audit = TRUE;
unsigned long pid;
int res, serrno = 0;
@@ -743,13 +746,15 @@ bus_apparmor_allows_send (DBusConnection *sender,
#ifdef HAVE_APPARMOR
BusAppArmorConfinement *src_con = NULL, *dst_con = NULL;
DBusString qstr, auxdata;
- dbus_bool_t src_allow = FALSE, dst_allow = FALSE;
- dbus_bool_t src_audit = TRUE, dst_audit = TRUE;
+ int src_allow = FALSE, dst_allow = FALSE;
+ int src_audit = TRUE, dst_audit = TRUE;
dbus_bool_t free_auxdata = FALSE;
unsigned long pid;
int len, res, src_errno = 0, dst_errno = 0;
uint32_t src_perm = AA_DBUS_SEND, dst_perm = AA_DBUS_RECEIVE;
const char *msgtypestr = dbus_message_type_to_string(msgtype);
+ const char *dst_label = NULL;
+ const char *dst_mode = NULL;
if (!apparmor_enabled)
return TRUE;
@@ -766,12 +771,22 @@ bus_apparmor_allows_send (DBusConnection *sender,
{
dst_con = bus_connection_dup_apparmor_confinement (proposed_recipient);
}
+ else if (activation_entry != NULL)
+ {
+ dst_label = bus_activation_entry_get_assumed_apparmor_label (activation_entry);
+ }
else
{
dst_con = bus_con;
bus_apparmor_confinement_ref (dst_con);
}
+ if (dst_con != NULL)
+ {
+ dst_label = dst_con->label;
+ dst_mode = dst_con->mode;
+ }
+
/* map reply messages to initial send and receive permission. That is
* permission to receive a message from X grants permission to reply to X.
* And permission to send a message to Y grants permission to receive a reply
@@ -799,7 +814,7 @@ bus_apparmor_allows_send (DBusConnection *sender,
goto oom;
if (!build_message_query (&qstr, src_con->label, bustype, destination,
- dst_con->label, path, interface, member))
+ dst_label, path, interface, member))
{
_dbus_string_free (&qstr);
goto oom;
@@ -818,7 +833,11 @@ bus_apparmor_allows_send (DBusConnection *sender,
}
}
- if (is_unconfined (dst_con->label, dst_con->mode))
+ /* When deciding whether we can activate a service, we only check that
+ * we are allowed to send a message to it, not that it is allowed to
+ * receive that message from us.
+ */
+ if (activation_entry != NULL || is_unconfined (dst_label, dst_mode))
{
dst_allow = TRUE;
dst_audit = FALSE;
@@ -828,7 +847,7 @@ bus_apparmor_allows_send (DBusConnection *sender,
if (!_dbus_string_init (&qstr))
goto oom;
- if (!build_message_query (&qstr, dst_con->label, bustype, source,
+ if (!build_message_query (&qstr, dst_label, bustype, source,
src_con->label, path, interface, member))
{
_dbus_string_free (&qstr);
@@ -851,7 +870,7 @@ bus_apparmor_allows_send (DBusConnection *sender,
/* Don't fail operations on profiles in complain mode */
if (modestr_is_complain (src_con->mode))
src_allow = TRUE;
- if (modestr_is_complain (dst_con->mode))
+ if (modestr_is_complain (dst_mode))
dst_allow = TRUE;
if (!src_allow || !dst_allow)
@@ -922,8 +941,8 @@ bus_apparmor_allows_send (DBusConnection *sender,
!_dbus_append_pair_uint (&auxdata, "peer_pid", pid))
goto oom;
- if (dst_con->label &&
- !_dbus_append_pair_str (&auxdata, "peer_label", dst_con->label))
+ if (dst_label &&
+ !_dbus_append_pair_str (&auxdata, "peer_label", dst_label))
goto oom;
if (src_errno && !_dbus_append_pair_str (&auxdata, "info", strerror (src_errno)))
@@ -950,8 +969,8 @@ bus_apparmor_allows_send (DBusConnection *sender,
!_dbus_append_pair_uint (&auxdata, "pid", pid))
goto oom;
- if (dst_con->label &&
- !_dbus_append_pair_str (&auxdata, "label", dst_con->label))
+ if (dst_label &&
+ !_dbus_append_pair_str (&auxdata, "label", dst_label))
goto oom;
if (sender && dbus_connection_get_unix_process_id (sender, &pid) &&
@@ -1011,7 +1030,7 @@ bus_apparmor_allows_eavesdropping (DBusConnection *connection,
#ifdef HAVE_APPARMOR
BusAppArmorConfinement *con = NULL;
DBusString qstr, auxdata;
- dbus_bool_t allow = FALSE, audit = TRUE;
+ int allow = FALSE, audit = TRUE;
dbus_bool_t free_auxdata = FALSE;
unsigned long pid;
int res, serrno = 0;
diff --git a/bus/audit.c b/bus/audit.c
index 7705e425..91f2c5cf 100644
--- a/bus/audit.c
+++ b/bus/audit.c
@@ -166,8 +166,9 @@ _dbus_change_to_daemon_user (const char *user,
_dbus_strerror (errno));
break;
case -5:
- _dbus_warn ("Failed to drop supplementary groups: %s\n",
- _dbus_strerror (errno));
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to drop supplementary groups: %s",
+ _dbus_strerror (errno));
break;
case -6:
dbus_set_error (error, _dbus_error_from_errno (errno),
diff --git a/bus/bus.c b/bus/bus.c
index 1063d7b2..eb932f66 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -25,6 +25,7 @@
#include "bus.h"
#include <stdio.h>
+#include <stdlib.h>
#include "activation.h"
#include "connection.h"
@@ -38,6 +39,7 @@
#include "audit.h"
#include "dir-watch.h"
#include "check.h"
+#include <dbus/dbus-auth.h>
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-credentials.h>
@@ -92,19 +94,15 @@ server_get_context (DBusServer *server)
BusContext *context;
BusServerData *bd;
- if (!dbus_server_allocate_data_slot (&server_data_slot))
- return NULL;
+ /* this data slot was allocated by the BusContext */
+ _dbus_assert (server_data_slot >= 0);
bd = BUS_SERVER_DATA (server);
- if (bd == NULL)
- {
- dbus_server_free_data_slot (&server_data_slot);
- return NULL;
- }
- context = bd->context;
+ /* every DBusServer in the dbus-daemon has gone through setup_server() */
+ _dbus_assert (bd != NULL);
- dbus_server_free_data_slot (&server_data_slot);
+ context = bd->context;
return context;
}
@@ -176,10 +174,9 @@ new_connection_callback (DBusServer *server,
{
BusContext *context = data;
+ /* If this fails it logs a warning, so we don't need to do that */
if (!bus_connections_setup_connection (context->connections, new_connection))
{
- _dbus_verbose ("No memory to setup new connection\n");
-
/* if we don't do this, it will get unref'd without
* being disconnected... kind of strange really
* that we have to do this, people won't get it right
@@ -287,6 +284,7 @@ process_config_first_time_only (BusContext *context,
DBusList **auth_mechanisms_list;
int len;
dbus_bool_t retval;
+ DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -294,7 +292,27 @@ process_config_first_time_only (BusContext *context,
auth_mechanisms = NULL;
pidfile = NULL;
- _dbus_init_system_log (TRUE);
+ if (flags & BUS_CONTEXT_FLAG_SYSLOG_ALWAYS)
+ {
+ context->syslog = TRUE;
+ log_flags |= DBUS_LOG_FLAGS_SYSTEM_LOG;
+
+ if (flags & BUS_CONTEXT_FLAG_SYSLOG_ONLY)
+ log_flags &= ~DBUS_LOG_FLAGS_STDERR;
+ }
+ else if (flags & BUS_CONTEXT_FLAG_SYSLOG_NEVER)
+ {
+ context->syslog = FALSE;
+ }
+ else
+ {
+ context->syslog = bus_config_parser_get_syslog (parser);
+
+ if (context->syslog)
+ log_flags |= DBUS_LOG_FLAGS_SYSTEM_LOG;
+ }
+
+ _dbus_init_system_log ("dbus-daemon", log_flags);
if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION)
context->systemd_activation = TRUE;
@@ -414,6 +432,26 @@ process_config_first_time_only (BusContext *context,
link = _dbus_list_get_first_link (auth_mechanisms_list);
while (link != NULL)
{
+ DBusString name;
+ _dbus_string_init_const (&name, link->data);
+ if (!_dbus_auth_is_supported_mechanism (&name))
+ {
+ DBusString list;
+ if (!_dbus_string_init (&list))
+ goto oom;
+
+ if (!_dbus_auth_dump_supported_mechanisms (&list))
+ {
+ _dbus_string_free (&list);
+ goto oom;
+ }
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Unsupported auth mechanism \"%s\" in bus config file detected. Supported mechanisms are \"%s\".",
+ (char*)link->data,
+ _dbus_string_get_const_data (&list));
+ _dbus_string_free (&list);
+ goto failed;
+ }
auth_mechanisms[i] = _dbus_strdup (link->data);
if (auth_mechanisms[i] == NULL)
goto oom;
@@ -476,7 +514,6 @@ process_config_first_time_only (BusContext *context,
}
context->fork = bus_config_parser_get_fork (parser);
- context->syslog = bus_config_parser_get_syslog (parser);
context->keep_umask = bus_config_parser_get_keep_umask (parser);
context->allow_anonymous = bus_config_parser_get_allow_anonymous (parser);
@@ -635,32 +672,6 @@ process_config_every_time (BusContext *context,
return retval;
}
-static dbus_bool_t
-list_concat_new (DBusList **a,
- DBusList **b,
- DBusList **result)
-{
- DBusList *link;
-
- *result = NULL;
-
- for (link = _dbus_list_get_first_link (a); link; link = _dbus_list_get_next_link (a, link))
- {
- if (!_dbus_list_append (result, link->data))
- goto oom;
- }
- for (link = _dbus_list_get_first_link (b); link; link = _dbus_list_get_next_link (b, link))
- {
- if (!_dbus_list_append (result, link->data))
- goto oom;
- }
-
- return TRUE;
-oom:
- _dbus_list_clear (result);
- return FALSE;
-}
-
static void
raise_file_descriptor_limit (BusContext *context)
{
@@ -684,11 +695,11 @@ raise_file_descriptor_limit (BusContext *context)
/* We used to compute a suitable rlimit based on the configured number
* of connections, but that breaks down as soon as we allow fd-passing,
* because each connection is allowed to pass 64 fds to us, and if
- * they all did, we'd hit kernel limits. We now hard-code 64k as a
- * good limit, like systemd does: that's enough to avoid DoS from
- * anything short of multiple uids conspiring against us.
+ * they all did, we'd hit kernel limits. We now hard-code a good
+ * limit that is enough to avoid DoS from anything short of multiple
+ * uids conspiring against us, much like systemd does.
*/
- if (!_dbus_rlimit_raise_fd_limit_if_privileged (65536, &error))
+ if (!_dbus_rlimit_raise_fd_limit (&error))
{
bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
"%s: %s", error.name, error.message);
@@ -706,8 +717,6 @@ process_config_postinit (BusContext *context,
DBusHashTable *service_context_table;
DBusList *watched_dirs = NULL;
- raise_file_descriptor_limit (context);
-
service_context_table = bus_config_parser_steal_service_context_table (parser);
if (!bus_registry_set_service_context_table (context->registry,
service_context_table))
@@ -721,9 +730,7 @@ process_config_postinit (BusContext *context,
/* We need to monitor both the configuration directories and directories
* containing .service files.
*/
- if (!list_concat_new (bus_config_parser_get_conf_dirs (parser),
- bus_config_parser_get_service_dirs (parser),
- &watched_dirs))
+ if (!bus_config_parser_get_watched_dirs (parser, &watched_dirs))
{
BUS_SET_OOM (error);
return FALSE;
@@ -933,9 +940,38 @@ bus_context_new (const DBusString *config_file,
!_dbus_pipe_is_stdout_or_stderr (print_pid_pipe))
_dbus_pipe_close (print_pid_pipe, NULL);
+ /* Raise the file descriptor limits before dropping the privileges
+ * required to do so.
+ */
+ raise_file_descriptor_limit (context);
+
+ /* Here we change our credentials if required,
+ * as soon as we've set up our sockets and pidfile.
+ * This must be done before initializing LSMs, so that the netlink
+ * monitoring thread started by avc_init() will not lose CAP_AUDIT_WRITE
+ * when the main thread calls setuid().
+ * https://bugs.freedesktop.org/show_bug.cgi?id=92832
+ */
+ if (context->user != NULL)
+ {
+ if (!_dbus_change_to_daemon_user (context->user, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+ }
+
+ /* Auditing should be initialized before LSMs, so that the LSMs are able
+ * to log audit-events that happen during their initialization.
+ */
+ bus_audit_init (context);
+
if (!bus_selinux_full_init ())
{
- bus_context_log (context, DBUS_SYSTEM_LOG_FATAL, "SELinux enabled but D-Bus initialization failed; check system log\n");
+ bus_context_log (context, DBUS_SYSTEM_LOG_ERROR,
+ "SELinux enabled but D-Bus initialization failed; "
+ "check system log");
+ exit (1);
}
if (!bus_apparmor_full_init (error))
@@ -952,6 +988,11 @@ bus_context_new (const DBusString *config_file,
"AppArmor D-Bus mediation is enabled\n");
}
+ /* When SELinux is used, this must happen after bus_selinux_full_init()
+ * so that it has access to the access vector cache, which is required
+ * to process <associate/> elements.
+ * http://lists.freedesktop.org/archives/dbus/2008-October/010491.html
+ */
if (!process_config_postinit (context, parser, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
@@ -964,20 +1005,6 @@ bus_context_new (const DBusString *config_file,
parser = NULL;
}
- /* Here we change our credentials if required,
- * as soon as we've set up our sockets and pidfile
- */
- if (context->user != NULL)
- {
- if (!_dbus_change_to_daemon_user (context->user, error))
- {
- _DBUS_ASSERT_ERROR_IS_SET (error);
- goto failed;
- }
- }
-
- bus_audit_init (context);
-
context->check = bus_check_new(context, error);
if (context->check == NULL)
goto failed;
@@ -1356,25 +1383,17 @@ bus_context_get_initial_fd_limit (BusContext *context)
return context->initial_fd_limit;
}
+dbus_bool_t
+bus_context_get_using_syslog (BusContext *context)
+{
+ return context->syslog;
+}
+
void
bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...)
{
va_list args;
- if (!context->syslog)
- {
- /* we're not syslogging; just output to stderr */
- va_start (args, msg);
- vfprintf (stderr, msg, args);
- fprintf (stderr, "\n");
- va_end (args);
-
- if (severity == DBUS_SYSTEM_LOG_FATAL)
- _dbus_exit (1);
-
- return;
- }
-
va_start (args, msg);
if (context->log_prefix)
@@ -1388,12 +1407,12 @@ bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char
if (!_dbus_string_append_printf_valist (&full_msg, msg, args))
goto oom_out;
- _dbus_system_log (severity, "%s", _dbus_string_get_const_data (&full_msg));
+ _dbus_log (severity, "%s", _dbus_string_get_const_data (&full_msg));
oom_out:
_dbus_string_free (&full_msg);
}
else
- _dbus_system_logv (severity, msg, args);
+ _dbus_logv (severity, msg, args);
out:
va_end (args);
@@ -1411,19 +1430,7 @@ bus_context_log_literal (BusContext *context,
DBusSystemLogSeverity severity,
const char *msg)
{
- if (!context->syslog)
- {
- fputs (msg, stderr);
- fputc ('\n', stderr);
-
- if (severity == DBUS_SYSTEM_LOG_FATAL)
- _dbus_exit (1);
- }
- else
- {
- _dbus_system_log (severity, "%s%s", nonnull (context->log_prefix, ""),
- msg);
- }
+ _dbus_log (severity, "%s%s", nonnull (context->log_prefix, ""), msg);
}
void
@@ -1728,7 +1735,7 @@ bus_context_check_security_policy (BusContext *context,
}
else
{
- _dbus_assert_not_reached ("a message was somehow sent to an inactive recipient from a source other than the message bus\n");
+ _dbus_assert_not_reached ("a message was somehow sent to an inactive recipient from a source other than the message bus");
recipient_policy = NULL;
}
}
diff --git a/bus/bus.h b/bus/bus.h
index 6382b188..6562d376 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -92,7 +92,10 @@ typedef enum
BUS_CONTEXT_FLAG_FORK_ALWAYS = (1 << 1),
BUS_CONTEXT_FLAG_FORK_NEVER = (1 << 2),
BUS_CONTEXT_FLAG_WRITE_PID_FILE = (1 << 3),
- BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION = (1 << 4)
+ BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION = (1 << 4),
+ BUS_CONTEXT_FLAG_SYSLOG_ALWAYS = (1 << 5),
+ BUS_CONTEXT_FLAG_SYSLOG_NEVER = (1 << 6),
+ BUS_CONTEXT_FLAG_SYSLOG_ONLY = (1 << 7)
} BusContextFlags;
BusContext* bus_context_new (const DBusString *config_file,
@@ -139,6 +142,7 @@ int bus_context_get_max_match_rules_per_connection (BusContext
int bus_context_get_max_replies_per_connection (BusContext *context);
int bus_context_get_reply_timeout (BusContext *context);
DBusRLimit * bus_context_get_initial_fd_limit (BusContext *context);
+dbus_bool_t bus_context_get_using_syslog (BusContext *context);
void bus_context_log (BusContext *context,
DBusSystemLogSeverity severity,
const char *msg,
@@ -152,7 +156,6 @@ void bus_context_log_and_set_error (BusContext
const char *name,
const char *msg,
...) _DBUS_GNUC_PRINTF (5, 6);
-void bus_context_check_all_watches (BusContext *context);
BusResult bus_context_check_security_policy (BusContext *context,
BusTransaction *transaction,
DBusConnection *sender,
@@ -162,6 +165,7 @@ BusResult bus_context_check_security_policy (BusContext
BusActivationEntry *activation_entry,
DBusError *error,
BusDeferredMessage **deferred_message);
+void bus_context_check_all_watches (BusContext *context);
dbus_bool_t bus_context_check_recipient_message_limits (BusContext *context,
DBusConnection *recipient,
diff --git a/bus/config-loader-expat.c b/bus/config-loader-expat.c
index b571fda3..6cbd37eb 100644
--- a/bus/config-loader-expat.c
+++ b/bus/config-loader-expat.c
@@ -203,6 +203,20 @@ bus_config_load (const DBusString *file,
goto failed;
}
+ /* We do not need protection against hash collisions (CVE-2012-0876)
+ * because we are only parsing trusted XML; and if we let Expat block
+ * waiting for the CSPRNG to be initialized, as it does by default to
+ * defeat CVE-2012-0876, it can cause timeouts during early boot on
+ * entropy-starved embedded devices.
+ *
+ * TODO: When Expat gets a more explicit API for this than
+ * XML_SetHashSalt, check for that too, and use it preferentially.
+ * https://github.com/libexpat/libexpat/issues/91 */
+#if defined(HAVE_XML_SETHASHSALT)
+ /* Any nonzero number will do. https://xkcd.com/221/ */
+ XML_SetHashSalt (expat, 4);
+#endif
+
if (!_dbus_string_get_dirname (file, &dirname))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -242,7 +256,7 @@ bus_config_load (const DBusString *file,
data_str = _dbus_string_get_const_data (&data);
- if (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE))
+ if (XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE) == XML_STATUS_ERROR)
{
if (context.error != NULL &&
!dbus_error_is_set (context.error))
@@ -254,10 +268,13 @@ bus_config_load (const DBusString *file,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
else
dbus_set_error (error, DBUS_ERROR_FAILED,
- "Error in file %s, line %d, column %d: %s\n",
+ "Error in file %s, line %lu, column %lu: %s\n",
filename,
- XML_GetCurrentLineNumber (expat),
- XML_GetCurrentColumnNumber (expat),
+ /* The XML_Size type varies according to
+ * build options, so cast to something we can
+ * cope with. */
+ (unsigned long) XML_GetCurrentLineNumber (expat),
+ (unsigned long) XML_GetCurrentColumnNumber (expat),
XML_ErrorString (e));
}
diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c
index ea25f5e6..e2f253d8 100644
--- a/bus/config-parser-common.c
+++ b/bus/config-parser-common.c
@@ -193,10 +193,9 @@ bus_config_parser_element_type_to_name (ElementType type)
return "allow_anonymous";
case ELEMENT_APPARMOR:
return "apparmor";
+ default:
+ _dbus_assert_not_reached ("bad element type");
+ return NULL;
}
-
- _dbus_assert_not_reached ("bad element type");
-
- return NULL;
}
diff --git a/bus/config-parser-trivial.c b/bus/config-parser-trivial.c
index 03ad8382..dd65c6d4 100644
--- a/bus/config-parser-trivial.c
+++ b/bus/config-parser-trivial.c
@@ -162,6 +162,7 @@ bus_config_parser_start_element (BusConfigParser *parser,
switch (parser->type)
{
+ case ELEMENT_SERVICEDIR:
case ELEMENT_SERVICEHELPER:
case ELEMENT_USER:
case ELEMENT_CONFIGTYPE:
@@ -185,6 +186,26 @@ bus_config_parser_start_element (BusConfigParser *parser,
break;
}
+ case ELEMENT_NONE:
+ case ELEMENT_BUSCONFIG:
+ case ELEMENT_INCLUDE:
+ case ELEMENT_LISTEN:
+ case ELEMENT_AUTH:
+ case ELEMENT_POLICY:
+ case ELEMENT_LIMIT:
+ case ELEMENT_ALLOW:
+ case ELEMENT_DENY:
+ case ELEMENT_FORK:
+ case ELEMENT_PIDFILE:
+ case ELEMENT_INCLUDEDIR:
+ case ELEMENT_SELINUX:
+ case ELEMENT_ASSOCIATE:
+ case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
+ case ELEMENT_KEEP_UMASK:
+ case ELEMENT_SYSLOG:
+ case ELEMENT_ALLOW_ANONYMOUS:
+ case ELEMENT_APPARMOR:
+ /* fall through */
default:
{
/* we really don't care about the others... */
@@ -286,6 +307,28 @@ bus_config_parser_content (BusConfigParser *parser,
}
}
break;
+
+ case ELEMENT_NONE:
+ case ELEMENT_BUSCONFIG:
+ case ELEMENT_INCLUDE:
+ case ELEMENT_LISTEN:
+ case ELEMENT_AUTH:
+ case ELEMENT_POLICY:
+ case ELEMENT_LIMIT:
+ case ELEMENT_ALLOW:
+ case ELEMENT_DENY:
+ case ELEMENT_FORK:
+ case ELEMENT_PIDFILE:
+ case ELEMENT_INCLUDEDIR:
+ case ELEMENT_SELINUX:
+ case ELEMENT_ASSOCIATE:
+ case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
+ case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
+ case ELEMENT_KEEP_UMASK:
+ case ELEMENT_SYSLOG:
+ case ELEMENT_ALLOW_ANONYMOUS:
+ case ELEMENT_APPARMOR:
+ /* fall through */
default:
{
/* we don't care about the others... really */
@@ -324,8 +367,11 @@ bus_config_parser_get_type (BusConfigParser *parser)
return _dbus_string_get_const_data (&parser->bus_type);
}
+/*
+ * @returns A list of strings, owned by the BusConfigParser
+ */
DBusList**
-bus_config_parser_get_service_dirs (BusConfigParser *parser)
+bus_config_parser_get_service_paths (BusConfigParser *parser)
{
return &parser->service_dirs;
}
@@ -370,14 +416,14 @@ check_return_values (const DBusString *full_path)
user = bus_config_parser_get_user (parser);
if (user == NULL)
{
- _dbus_warn ("User was NULL!\n");
+ _dbus_warn ("User was NULL!");
goto finish;
}
#if 0
/* the username can be configured in configure.in so this test doesn't work */
if (strcmp (user, "dbus") != 0)
{
- _dbus_warn ("User was invalid; '%s'!\n", user);
+ _dbus_warn ("User was invalid; '%s'!", user);
goto finish;
}
printf (" <user>dbus</user> OKAY!\n");
@@ -387,21 +433,21 @@ check_return_values (const DBusString *full_path)
type = bus_config_parser_get_type (parser);
if (type == NULL)
{
- _dbus_warn ("Type was NULL!\n");
+ _dbus_warn ("Type was NULL!");
goto finish;
}
if (strcmp (type, "system") != 0)
{
- _dbus_warn ("Type was invalid; '%s'!\n", user);
+ _dbus_warn ("Type was invalid; '%s'!", user);
goto finish;
}
printf (" <type>system</type> OKAY!\n");
/* check dirs return value is okay */
- dirs = bus_config_parser_get_service_dirs (parser);
+ dirs = bus_config_parser_get_service_paths (parser);
if (dirs == NULL)
{
- _dbus_warn ("Service dirs are NULL!\n");
+ _dbus_warn ("Service dirs are NULL!");
goto finish;
}
printf (" <standard_system_service_dirs/> OKAY!\n");
@@ -440,7 +486,7 @@ do_load (const DBusString *full_path,
}
else if (validity == VALID)
{
- _dbus_warn ("Failed to load valid file but still had memory: %s\n",
+ _dbus_warn ("Failed to load valid file but still had memory: %s",
error.message);
dbus_error_free (&error);
@@ -460,7 +506,7 @@ do_load (const DBusString *full_path,
if (validity == INVALID)
{
- _dbus_warn ("Accepted invalid file\n");
+ _dbus_warn ("Accepted invalid file");
return FALSE;
}
@@ -497,7 +543,7 @@ process_test_valid_subdir (const DBusString *test_base_dir,
dir = NULL;
if (!_dbus_string_init (&test_directory))
- _dbus_assert_not_reached ("didn't allocate test_directory\n");
+ _dbus_assert_not_reached ("didn't allocate test_directory");
_dbus_string_init_const (&filename, subdir);
@@ -510,13 +556,13 @@ process_test_valid_subdir (const DBusString *test_base_dir,
_dbus_string_free (&filename);
if (!_dbus_string_init (&filename))
- _dbus_assert_not_reached ("didn't allocate filename string\n");
+ _dbus_assert_not_reached ("didn't allocate filename string");
dbus_error_init (&error);
dir = _dbus_directory_open (&test_directory, &error);
if (dir == NULL)
{
- _dbus_warn ("Could not open %s: %s\n",
+ _dbus_warn ("Could not open %s: %s",
_dbus_string_get_const_data (&test_directory),
error.message);
dbus_error_free (&error);
@@ -576,7 +622,7 @@ process_test_valid_subdir (const DBusString *test_base_dir,
if (dbus_error_is_set (&error))
{
- _dbus_warn ("Could not get next file in %s: %s\n",
+ _dbus_warn ("Could not get next file in %s: %s",
_dbus_string_get_const_data (&test_directory),
error.message);
dbus_error_free (&error);
diff --git a/bus/config-parser-trivial.h b/bus/config-parser-trivial.h
index 31ddef6b..abe41fdf 100644
--- a/bus/config-parser-trivial.h
+++ b/bus/config-parser-trivial.h
@@ -59,7 +59,7 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser,
/* Functions for extracting the parse results */
const char* bus_config_parser_get_user (BusConfigParser *parser);
const char* bus_config_parser_get_type (BusConfigParser *parser);
-DBusList** bus_config_parser_get_service_dirs (BusConfigParser *parser);
+DBusList** bus_config_parser_get_service_paths (BusConfigParser *parser);
/* Loader functions (backended off one of the XML parsers). Returns a
* finished ConfigParser.
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 00005cc7..42218547 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -100,7 +100,7 @@ struct BusConfigParser
DBusList *mechanisms; /**< Auth mechanisms */
- DBusList *service_dirs; /**< Directories to look for session services in */
+ DBusList *service_dirs; /**< BusConfigServiceDirs to look for session services in */
DBusList *conf_dirs; /**< Directories to look for policy configuration in */
@@ -232,7 +232,33 @@ merge_service_context_hash (DBusHashTable *dest,
return FALSE;
}
-static dbus_bool_t
+/*
+ * Create a new BusConfigServiceDir. Takes ownership of path if #TRUE is returned.
+ *
+ * @returns #FALSE on OOM
+ */
+static BusConfigServiceDir *
+bus_config_service_dir_new_take (char *path,
+ BusServiceDirFlags flags)
+{
+ BusConfigServiceDir *self = dbus_new0 (BusConfigServiceDir, 1);
+
+ if (self == NULL)
+ return NULL;
+
+ self->path = path; /* take ownership */
+ self->flags = flags;
+ return self;
+}
+
+static void
+bus_config_service_dir_free (BusConfigServiceDir *self)
+{
+ dbus_free (self->path);
+ dbus_free (self);
+}
+
+static BusConfigServiceDir *
service_dirs_find_dir (DBusList **service_dirs,
const char *dir)
{
@@ -242,42 +268,81 @@ service_dirs_find_dir (DBusList **service_dirs,
for (link = *service_dirs; link; link = _dbus_list_get_next_link(service_dirs, link))
{
- const char *link_dir;
-
- link_dir = (const char *)link->data;
- if (strcmp (dir, link_dir) == 0)
- return TRUE;
- }
+ BusConfigServiceDir *link_dir = link->data;
- return FALSE;
-}
-
-static dbus_bool_t
-service_dirs_append_unique_or_free (DBusList **service_dirs,
- char *dir)
-{
- if (!service_dirs_find_dir (service_dirs, dir))
- return _dbus_list_append (service_dirs, dir);
+ if (strcmp (dir, link_dir->path) == 0)
+ return link_dir;
+ }
- dbus_free (dir);
- return TRUE;
+ return NULL;
}
-static void
+static void
service_dirs_append_link_unique_or_free (DBusList **service_dirs,
DBusList *dir_link)
{
- if (!service_dirs_find_dir (service_dirs, dir_link->data))
+ BusConfigServiceDir *dir = dir_link->data;
+ BusConfigServiceDir *already = service_dirs_find_dir (service_dirs,
+ dir->path);
+
+ if (already == NULL)
{
_dbus_list_append_link (service_dirs, dir_link);
}
else
{
- dbus_free (dir_link->data);
+ /* BusServiceDirFlags are chosen such that the compatible thing to do
+ * is to "and" the flags. For example, if a directory is explicitly
+ * added as a <servicedir> (which is watched with inotify) and is also
+ * the transient service directory (which should not be watched),
+ * the compatible thing to do is to watch it. */
+ already->flags &= dir->flags;
+ bus_config_service_dir_free (dir_link->data);
_dbus_list_free_link (dir_link);
}
}
+/*
+ * Consume links from dirs (a list of paths), converting them into links in
+ * service_dirs (a list of unique BusServiceDir).
+ *
+ * On success, return TRUE. dirs will be empty, and every original entry in
+ * dirs will have a corresponding service_dirs entry.
+ *
+ * On OOM, return FALSE. Each original entry of dirs has either been
+ * appended to service_dirs or left in dirs.
+ */
+static dbus_bool_t
+service_dirs_absorb_string_list (DBusList **service_dirs,
+ DBusList **dirs,
+ BusServiceDirFlags flags)
+{
+ DBusList *link;
+
+ _dbus_assert (service_dirs != NULL);
+ _dbus_assert (dirs != NULL);
+
+ while ((link = _dbus_list_pop_first_link (dirs)))
+ {
+ char *path = link->data;
+ BusConfigServiceDir *dir = bus_config_service_dir_new_take (path, flags);
+
+ if (dir == NULL)
+ {
+ /* OOM - roll back (this does not need to allocate memory) */
+ _dbus_list_prepend_link (service_dirs, link);
+ return FALSE;
+ }
+
+ /* Ownership of path has been taken by dir */
+ link->data = dir;
+ service_dirs_append_link_unique_or_free (service_dirs, link);
+ }
+
+ _dbus_assert (*dirs == NULL);
+ return TRUE;
+}
+
static dbus_bool_t
merge_included (BusConfigParser *parser,
BusConfigParser *included,
@@ -515,7 +580,7 @@ bus_config_parser_unref (BusConfigParser *parser)
_dbus_list_clear (&parser->listen_on);
_dbus_list_foreach (&parser->service_dirs,
- (DBusForeachFunction) dbus_free,
+ (DBusForeachFunction) bus_config_service_dir_free,
NULL);
_dbus_list_clear (&parser->service_dirs);
@@ -583,7 +648,7 @@ locate_attributes (BusConfigParser *parser,
const char *name;
const char **retloc;
int n_attrs;
-#define MAX_ATTRS 24
+#define MAX_ATTRS 25
LocateAttr attrs[MAX_ATTRS];
dbus_bool_t retval;
int i;
@@ -832,9 +897,8 @@ start_busconfig_child (BusConfigParser *parser,
}
else if (element_type == ELEMENT_STANDARD_SESSION_SERVICEDIRS)
{
- DBusList *link;
- DBusList *dirs;
- dirs = NULL;
+ DBusError local_error = DBUS_ERROR_INIT;
+ DBusList *dirs = NULL;
if (!check_no_attributes (parser, "standard_session_servicedirs", attribute_names, attribute_values, error))
return FALSE;
@@ -845,20 +909,54 @@ start_busconfig_child (BusConfigParser *parser,
return FALSE;
}
+ if (_dbus_set_up_transient_session_servicedirs (&dirs, &local_error))
+ {
+ if (!service_dirs_absorb_string_list (&parser->service_dirs, &dirs,
+ BUS_SERVICE_DIR_FLAGS_NO_WATCH |
+ BUS_SERVICE_DIR_FLAGS_STRICT_NAMING))
+ {
+ BUS_SET_OOM (error);
+ _dbus_list_foreach (&dirs, (DBusForeachFunction) dbus_free,
+ NULL);
+ _dbus_list_clear (&dirs);
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Failing to set these up isn't fatal */
+ _dbus_warn ("Unable to set up transient service directory: %s",
+ local_error.message);
+ dbus_error_free (&local_error);
+ }
+
+ _dbus_assert (dirs == NULL);
+
if (!_dbus_get_standard_session_servicedirs (&dirs))
{
BUS_SET_OOM (error);
return FALSE;
}
- while ((link = _dbus_list_pop_first_link (&dirs)))
- service_dirs_append_link_unique_or_free (&parser->service_dirs, link);
+ /* We have traditionally watched the standard session service
+ * directories with inotify, and allowed service files whose names do not
+ * match the bus name */
+ if (!service_dirs_absorb_string_list (&parser->service_dirs, &dirs,
+ BUS_SERVICE_DIR_FLAGS_NONE))
+ {
+ BUS_SET_OOM (error);
+ _dbus_list_foreach (&dirs, (DBusForeachFunction) dbus_free,
+ NULL);
+ _dbus_list_clear (&dirs);
+ return FALSE;
+ }
+
+ _dbus_assert (dirs == NULL);
return TRUE;
}
else if (element_type == ELEMENT_STANDARD_SYSTEM_SERVICEDIRS)
{
- DBusList *link;
DBusList *dirs;
dirs = NULL;
@@ -877,8 +975,19 @@ start_busconfig_child (BusConfigParser *parser,
return FALSE;
}
- while ((link = _dbus_list_pop_first_link (&dirs)))
- service_dirs_append_link_unique_or_free (&parser->service_dirs, link);
+ /* We have traditionally watched the standard system service
+ * directories with inotify, and allowed service files whose names do not
+ * match the bus name (the servicehelper won't successfully activate
+ * them, but we do still parse them) */
+ if (!service_dirs_absorb_string_list (&parser->service_dirs, &dirs,
+ BUS_SERVICE_DIR_FLAGS_NONE))
+ {
+ BUS_SET_OOM (error);
+ _dbus_list_foreach (&dirs, (DBusForeachFunction) dbus_free,
+ NULL);
+ _dbus_list_clear (&dirs);
+ return FALSE;
+ }
return TRUE;
}
@@ -1049,7 +1158,7 @@ start_busconfig_child (BusConfigParser *parser,
&e->d.policy.gid_uid_or_at_console))
e->d.policy.type = POLICY_USER;
else
- _dbus_warn ("Unknown username \"%s\" in message bus configuration file\n",
+ _dbus_warn ("Unknown username \"%s\" in message bus configuration file",
user);
}
else if (group != NULL)
@@ -1061,7 +1170,7 @@ start_busconfig_child (BusConfigParser *parser,
&e->d.policy.gid_uid_or_at_console))
e->d.policy.type = POLICY_GROUP;
else
- _dbus_warn ("Unknown group \"%s\" in message bus configuration file\n",
+ _dbus_warn ("Unknown group \"%s\" in message bus configuration file",
group);
}
else if (at_console != NULL)
@@ -1167,6 +1276,43 @@ start_busconfig_child (BusConfigParser *parser,
}
}
+/*
+ * Parse an attribute named name, whose content is content, or NULL if
+ * missing. It is meant to be a (long) integer between min and max inclusive.
+ * If it is missing, use def as the default value (which does not
+ * necessarily need to be between min and max).
+ */
+static dbus_bool_t
+parse_int_attribute (const char *name,
+ const char *content,
+ long min,
+ long max,
+ long def,
+ long *value,
+ DBusError *error)
+{
+ DBusString parse_string;
+
+ *value = def;
+
+ if (content == NULL)
+ return TRUE;
+
+ _dbus_string_init_const (&parse_string, content);
+
+ if (!_dbus_string_parse_int (&parse_string, 0, value, NULL) ||
+ *value < min || *value > max)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad value \"%s\" for %s attribute, must be an "
+ "integer in range %ld to %ld inclusive",
+ content, name, min, max);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static dbus_bool_t
append_rule_from_element (BusConfigParser *parser,
const char *element_name,
@@ -1176,6 +1322,8 @@ append_rule_from_element (BusConfigParser *parser,
DBusError *error)
{
const char *log;
+
+ /* Group: send_ attributes */
const char *send_interface;
const char *send_member;
const char *send_error;
@@ -1183,15 +1331,32 @@ append_rule_from_element (BusConfigParser *parser,
const char *send_destination_prefix;
const char *send_path;
const char *send_type;
+ const char *send_requested_reply;
+ const char *send_broadcast;
+ /* TRUE if any send_ attribute is present */
+ dbus_bool_t any_send_attribute;
+
+ /* Group: receive_ attributes */
const char *receive_interface;
const char *receive_member;
const char *receive_error;
const char *receive_sender;
const char *receive_path;
const char *receive_type;
- const char *eavesdrop;
- const char *send_requested_reply;
const char *receive_requested_reply;
+ /* TRUE if any receive_ attribute is present */
+ dbus_bool_t any_receive_attribute;
+
+ /* Group: message-matching modifiers that can go on send_ or receive_ */
+ const char *eavesdrop;
+ const char *max_fds_attr;
+ long max_fds = DBUS_MAXIMUM_MESSAGE_UNIX_FDS;
+ const char *min_fds_attr;
+ long min_fds = 0;
+ /* TRUE if any message-matching modifier is present */
+ dbus_bool_t any_message_attribute;
+
+ /* Non-message-related attributes */
const char *own;
const char *own_prefix;
const char *user;
@@ -1199,7 +1364,7 @@ append_rule_from_element (BusConfigParser *parser,
const char *privilege;
BusPolicyRule *rule;
-
+
if (!locate_attributes (parser, element_name,
attribute_names,
attribute_values,
@@ -1211,6 +1376,7 @@ append_rule_from_element (BusConfigParser *parser,
"send_destination_prefix", &send_destination_prefix,
"send_path", &send_path,
"send_type", &send_type,
+ "send_broadcast", &send_broadcast,
"receive_interface", &receive_interface,
"receive_member", &receive_member,
"receive_error", &receive_error,
@@ -1218,6 +1384,8 @@ append_rule_from_element (BusConfigParser *parser,
"receive_path", &receive_path,
"receive_type", &receive_type,
"eavesdrop", &eavesdrop,
+ "max_fds", &max_fds_attr,
+ "min_fds", &min_fds_attr,
"send_requested_reply", &send_requested_reply,
"receive_requested_reply", &receive_requested_reply,
"own", &own,
@@ -1229,12 +1397,36 @@ append_rule_from_element (BusConfigParser *parser,
NULL))
return FALSE;
- if (!(send_interface || send_member || send_error ||
- send_destination || send_destination_prefix ||
- send_type || send_path ||
- receive_interface || receive_member || receive_error || receive_sender ||
- receive_type || receive_path || eavesdrop ||
- send_requested_reply || receive_requested_reply ||
+ any_send_attribute = (send_destination != NULL ||
+ send_destination_prefix != NULL ||
+ send_broadcast != NULL ||
+ send_path != NULL ||
+ send_type != NULL ||
+ send_interface != NULL ||
+ send_member != NULL ||
+ send_error != NULL ||
+ send_requested_reply != NULL);
+ any_receive_attribute = (receive_sender != NULL ||
+ receive_path != NULL ||
+ receive_type != NULL ||
+ receive_interface != NULL ||
+ receive_member != NULL ||
+ receive_error != NULL ||
+ receive_requested_reply != NULL ||
+ /* <allow eavesdrop="true"/> means the same as
+ * <allow receive_sender="*" eavesdrop="true"/>,
+ * but <allow send_anything="anything"/> can also
+ * take the eavesdrop attribute and still counts
+ * as a send rule. */
+ (!any_send_attribute && eavesdrop != NULL));
+ any_message_attribute = (any_send_attribute ||
+ any_receive_attribute ||
+ eavesdrop != NULL ||
+ max_fds_attr != NULL ||
+ min_fds_attr != NULL);
+
+ if (!(any_send_attribute ||
+ any_receive_attribute ||
privilege ||
own || own_prefix || user || group))
{
@@ -1284,124 +1476,57 @@ append_rule_from_element (BusConfigParser *parser,
* interface + member
* error
*
- * base send_ can combine with send_destination, send_destination_prefix, send_path, send_type, send_requested_reply
+ * base send_ can combine with send_destination, send_destination_prefix, send_path, send_type, send_requested_reply, send_broadcast, eavesdrop
* send_destination must not occur with send_destination_prefix
* base receive_ with receive_sender, receive_path, receive_type, receive_requested_reply, eavesdrop
*
* user, group, own, own_prefix must occur alone
- *
- * Pretty sure the below stuff is broken, FIXME think about it more.
*/
- if ((send_interface && (send_error ||
- receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_member && (send_error ||
- receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_error && (receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_destination && (send_destination_prefix ||
- receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_destination_prefix && (receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_type && (receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_path && (receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (send_requested_reply && (receive_interface ||
- receive_member ||
- receive_error ||
- receive_sender ||
- receive_requested_reply ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (receive_interface && (receive_error ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (receive_member && (receive_error ||
- own || own_prefix ||
- user ||
- group)) ||
-
- (receive_error && (own || own_prefix ||
- user ||
- group)) ||
-
- (eavesdrop && (own || own_prefix ||
- user ||
- group)) ||
-
- (receive_requested_reply && (own || own_prefix ||
- user ||
- group)) ||
-
- (own && (own_prefix || user || group)) ||
-
- (own_prefix && (own || user || group)) ||
-
- (user && group))
+ if (any_message_attribute +
+ ((own != NULL) +
+ (own_prefix != NULL) +
+ (user != NULL) +
+ (group != NULL)) > 1)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
- "Invalid combination of attributes on element <%s>",
+ "Invalid combination of attributes on element <%s>: "
+ "own, own_prefix, user, group and the message-related "
+ "attributes cannot be combined",
element_name);
return FALSE;
}
-
+
+ if (any_send_attribute && any_receive_attribute)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Invalid combination of attributes on element <%s>: "
+ "send and receive attributes cannot be combined",
+ element_name);
+ return FALSE;
+ }
+
+ if ((send_member != NULL || send_interface != NULL) && send_error != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Invalid combination of attributes on element <%s>: "
+ "send_error cannot be combined with send_member or "
+ "send_interface",
+ element_name);
+ return FALSE;
+ }
+
+ if ((receive_member != NULL || receive_interface != NULL) &&
+ receive_error != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Invalid combination of attributes on element <%s>: "
+ "receive_error cannot be combined with receive_member "
+ "or receive_interface",
+ element_name);
+ return FALSE;
+ }
+
rule = NULL;
/* In BusPolicyRule, NULL represents wildcard.
@@ -1409,8 +1534,7 @@ append_rule_from_element (BusConfigParser *parser,
*/
#define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0')
- if (send_interface || send_member || send_error || send_destination || send_destination_prefix ||
- send_path || send_type || send_requested_reply)
+ if (any_send_attribute)
{
int message_type;
@@ -1450,6 +1574,29 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
}
+ if (send_broadcast &&
+ !(strcmp (send_broadcast, "true") == 0 ||
+ strcmp (send_broadcast, "false") == 0))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad value \"%s\" for %s attribute, must be true or false",
+ send_broadcast, "send_broadcast");
+ return FALSE;
+ }
+
+ if (send_destination != NULL &&
+ send_broadcast != NULL &&
+ strcmp (send_broadcast, "true") == 0)
+ {
+ /* Broadcast messages have no destination, so this cannot
+ * possibly match */
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Rule with send_broadcast=\"true\" and "
+ "send_destination=\"%s\" cannot match anything",
+ send_destination);
+ return FALSE;
+ }
+
if (send_requested_reply &&
!(strcmp (send_requested_reply, "true") == 0 ||
strcmp (send_requested_reply, "false") == 0))
@@ -1459,7 +1606,19 @@ append_rule_from_element (BusConfigParser *parser,
"send_requested_reply", send_requested_reply);
return FALSE;
}
-
+
+ /* Matching only messages with DBUS_MAXIMUM_MESSAGE_UNIX_FDS or fewer
+ * fds is the same as matching all messages, so we always set a maximum,
+ * but perhaps an unrealistically high one. */
+ if (!parse_int_attribute ("max_fds", max_fds_attr,
+ 0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS,
+ DBUS_MAXIMUM_MESSAGE_UNIX_FDS, &max_fds,
+ error) ||
+ !parse_int_attribute ("min_fds", min_fds_attr,
+ 0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS, 0, &min_fds,
+ error))
+ return FALSE;
+
rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, access);
if (rule == NULL)
goto nomem;
@@ -1473,6 +1632,18 @@ append_rule_from_element (BusConfigParser *parser,
if (send_requested_reply)
rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0);
+ if (send_broadcast)
+ {
+ if (strcmp (send_broadcast, "true") == 0)
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_TRUE;
+ else
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_FALSE;
+ }
+ else
+ {
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_ANY;
+ }
+
rule->d.send.message_type = message_type;
rule->d.send.path = _dbus_strdup (send_path);
rule->d.send.interface = _dbus_strdup (send_interface);
@@ -1488,6 +1659,9 @@ append_rule_from_element (BusConfigParser *parser,
rule->d.send.destination = _dbus_strdup (send_destination_prefix);
rule->d.send.destination_prefix = 1;
}
+ rule->d.send.max_fds = max_fds;
+ rule->d.send.min_fds = min_fds;
+
if (send_path && rule->d.send.path == NULL)
goto nomem;
if (send_interface && rule->d.send.interface == NULL)
@@ -1499,8 +1673,7 @@ append_rule_from_element (BusConfigParser *parser,
if ((send_destination || send_destination_prefix) && rule->d.send.destination == NULL)
goto nomem;
}
- else if (receive_interface || receive_member || receive_error || receive_sender ||
- receive_path || receive_type || eavesdrop || receive_requested_reply)
+ else if (any_receive_attribute)
{
int message_type;
@@ -1550,7 +1723,16 @@ append_rule_from_element (BusConfigParser *parser,
"receive_requested_reply", receive_requested_reply);
return FALSE;
}
-
+
+ if (!parse_int_attribute ("max_fds", max_fds_attr,
+ 0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS,
+ DBUS_MAXIMUM_MESSAGE_UNIX_FDS, &max_fds,
+ error) ||
+ !parse_int_attribute ("min_fds", min_fds_attr,
+ 0, DBUS_MAXIMUM_MESSAGE_UNIX_FDS, 0, &min_fds,
+ error))
+ return FALSE;
+
rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, access);
if (rule == NULL)
goto nomem;
@@ -1567,6 +1749,8 @@ append_rule_from_element (BusConfigParser *parser,
rule->d.receive.member = _dbus_strdup (receive_member);
rule->d.receive.error = _dbus_strdup (receive_error);
rule->d.receive.origin = _dbus_strdup (receive_sender);
+ rule->d.receive.max_fds = max_fds;
+ rule->d.receive.min_fds = min_fds;
if (receive_path && rule->d.receive.path == NULL)
goto nomem;
@@ -1630,7 +1814,7 @@ append_rule_from_element (BusConfigParser *parser,
}
else
{
- _dbus_warn ("Unknown username \"%s\" on element <%s>\n",
+ _dbus_warn ("Unknown username \"%s\" on element <%s>",
user, element_name);
}
}
@@ -1662,7 +1846,7 @@ append_rule_from_element (BusConfigParser *parser,
}
else
{
- _dbus_warn ("Unknown group \"%s\" on element <%s>\n",
+ _dbus_warn ("Unknown group \"%s\" on element <%s>",
group, element_name);
}
}
@@ -1685,6 +1869,7 @@ append_rule_from_element (BusConfigParser *parser,
switch (pe->d.policy.type)
{
case POLICY_IGNORED:
+ default:
/* drop the rule on the floor */
break;
@@ -2121,6 +2306,7 @@ bus_config_parser_end_element (BusConfigParser *parser,
switch (e->type)
{
case ELEMENT_NONE:
+ default:
_dbus_assert_not_reached ("element in stack has no type");
break;
@@ -2189,7 +2375,8 @@ make_full_path (const DBusString *basedir,
{
if (_dbus_path_is_absolute (filename))
{
- return _dbus_string_copy (filename, 0, full_path, 0);
+ if (!_dbus_string_copy (filename, 0, full_path, 0))
+ return FALSE;
}
else
{
@@ -2198,9 +2385,12 @@ make_full_path (const DBusString *basedir,
if (!_dbus_concat_dir_and_file (full_path, filename))
return FALSE;
-
- return TRUE;
}
+
+ if (!_dbus_replace_install_prefix (full_path))
+ return FALSE;
+
+ return TRUE;
}
static dbus_bool_t
@@ -2373,15 +2563,17 @@ include_dir (BusConfigParser *parser,
{
if (dbus_error_is_set (error))
{
- /* We log to syslog unconditionally here, because this is
+ /* We use both syslog and stderr here, because this is
* the configuration parser, so we don't yet know whether
- * this bus is going to want to write to syslog! (There's
- * also some layer inversion going on, if we want to use
- * the bus context.) */
- _dbus_system_log (DBUS_SYSTEM_LOG_INFO,
- "Encountered error '%s' while parsing '%s'\n",
- error->message,
- _dbus_string_get_const_data (&full_path));
+ * this bus is going to want to write to syslog! Err on
+ * the side of making sure the message gets to the sysadmin
+ * somehow. */
+ _dbus_init_system_log ("dbus-daemon",
+ DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG);
+ _dbus_log (DBUS_SYSTEM_LOG_INFO,
+ "Encountered error '%s' while parsing '%s'",
+ error->message,
+ _dbus_string_get_const_data (&full_path));
dbus_error_free (error);
}
}
@@ -2457,6 +2649,7 @@ bus_config_parser_content (BusConfigParser *parser,
switch (top_element_type (parser))
{
case ELEMENT_NONE:
+ default:
_dbus_assert_not_reached ("element at top of stack has no type");
return FALSE;
@@ -2662,8 +2855,10 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_SERVICEDIR:
{
char *s;
+ BusConfigServiceDir *dir;
DBusString full_path;
-
+ DBusList *link;
+
e->had_content = TRUE;
if (!_dbus_string_init (&full_path))
@@ -2681,14 +2876,29 @@ bus_config_parser_content (BusConfigParser *parser,
goto nomem;
}
- /* _only_ extra session directories can be specified */
- if (!service_dirs_append_unique_or_free (&parser->service_dirs, s))
+ /* <servicedir/> has traditionally implied that we watch the
+ * directory with inotify, and allow service files whose names do not
+ * match the bus name */
+ dir = bus_config_service_dir_new_take (s, BUS_SERVICE_DIR_FLAGS_NONE);
+
+ if (dir == NULL)
{
_dbus_string_free (&full_path);
dbus_free (s);
goto nomem;
}
+ link = _dbus_list_alloc_link (dir);
+
+ if (link == NULL)
+ {
+ _dbus_string_free (&full_path);
+ bus_config_service_dir_free (dir);
+ goto nomem;
+ }
+
+ /* cannot fail */
+ service_dirs_append_link_unique_or_free (&parser->service_dirs, link);
_dbus_string_free (&full_path);
}
break;
@@ -2858,6 +3068,51 @@ bus_config_parser_steal_service_context_table (BusConfigParser *parser)
return table;
}
+/*
+ * Return a list of the directories that should be watched with inotify,
+ * as strings. The list might be empty and is in arbitrary order.
+ *
+ * The list must be empty on entry. On success, the links are owned by the
+ * caller and must be freed, but the data in each link remains owned by
+ * the BusConfigParser and must not be freed: in GObject-Introspection
+ * notation, it is (transfer container).
+ */
+dbus_bool_t
+bus_config_parser_get_watched_dirs (BusConfigParser *parser,
+ DBusList **watched_dirs)
+{
+ DBusList *link;
+
+ _dbus_assert (*watched_dirs == NULL);
+
+ for (link = _dbus_list_get_first_link (&parser->conf_dirs);
+ link != NULL;
+ link = _dbus_list_get_next_link (&parser->conf_dirs, link))
+ {
+ if (!_dbus_list_append (watched_dirs, link->data))
+ goto oom;
+ }
+
+ for (link = _dbus_list_get_first_link (&parser->service_dirs);
+ link != NULL;
+ link = _dbus_list_get_next_link (&parser->service_dirs, link))
+ {
+ BusConfigServiceDir *dir = link->data;
+
+ if (dir->flags & BUS_SERVICE_DIR_FLAGS_NO_WATCH)
+ continue;
+
+ if (!_dbus_list_append (watched_dirs, dir->path))
+ goto oom;
+ }
+
+ return TRUE;
+
+oom:
+ _dbus_list_clear (watched_dirs);
+ return FALSE;
+}
+
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include <stdio.h>
@@ -2872,7 +3127,7 @@ static dbus_bool_t
do_check_own_rules (BusPolicy *policy)
{
const struct {
- char *name;
+ const char *name;
dbus_bool_t allowed;
} checks[] = {
{"org.freedesktop", FALSE},
@@ -2902,12 +3157,12 @@ do_check_own_rules (BusPolicy *policy)
ret ? "allowed" : "not allowed");
if (checks[i].allowed && !ret)
{
- _dbus_warn ("Cannot own %s\n", checks[i].name);
+ _dbus_warn ("Cannot own %s", checks[i].name);
return FALSE;
}
if (!checks[i].allowed && ret)
{
- _dbus_warn ("Can own %s\n", checks[i].name);
+ _dbus_warn ("Can own %s", checks[i].name);
return FALSE;
}
_dbus_string_free (&service_name);
@@ -2945,7 +3200,7 @@ do_load (const DBusString *full_path,
}
else if (validity == VALID)
{
- _dbus_warn ("Failed to load valid file but still had memory: %s\n",
+ _dbus_warn ("Failed to load valid file but still had memory: %s",
error.message);
dbus_error_free (&error);
@@ -2970,7 +3225,7 @@ do_load (const DBusString *full_path,
if (validity == INVALID)
{
- _dbus_warn ("Accepted invalid file\n");
+ _dbus_warn ("Accepted invalid file");
return FALSE;
}
@@ -3008,7 +3263,7 @@ process_test_valid_subdir (const DBusString *test_base_dir,
dir = NULL;
if (!_dbus_string_init (&test_directory))
- _dbus_assert_not_reached ("didn't allocate test_directory\n");
+ _dbus_assert_not_reached ("didn't allocate test_directory");
_dbus_string_init_const (&filename, subdir);
@@ -3021,13 +3276,13 @@ process_test_valid_subdir (const DBusString *test_base_dir,
_dbus_string_free (&filename);
if (!_dbus_string_init (&filename))
- _dbus_assert_not_reached ("didn't allocate filename string\n");
+ _dbus_assert_not_reached ("didn't allocate filename string");
dbus_error_init (&error);
dir = _dbus_directory_open (&test_directory, &error);
if (dir == NULL)
{
- _dbus_warn ("Could not open %s: %s\n",
+ _dbus_warn ("Could not open %s: %s",
_dbus_string_get_const_data (&test_directory),
error.message);
dbus_error_free (&error);
@@ -3089,7 +3344,7 @@ process_test_valid_subdir (const DBusString *test_base_dir,
if (dbus_error_is_set (&error))
{
- _dbus_warn ("Could not get next file in %s: %s\n",
+ _dbus_warn ("Could not get next file in %s: %s",
_dbus_string_get_const_data (&test_directory),
error.message);
dbus_error_free (&error);
@@ -3158,8 +3413,29 @@ elements_equal (const Element *a,
return FALSE;
break;
+ case ELEMENT_NONE:
+ case ELEMENT_BUSCONFIG:
+ case ELEMENT_USER:
+ case ELEMENT_LISTEN:
+ case ELEMENT_AUTH:
+ case ELEMENT_ALLOW:
+ case ELEMENT_DENY:
+ case ELEMENT_FORK:
+ case ELEMENT_PIDFILE:
+ case ELEMENT_SERVICEDIR:
+ case ELEMENT_SERVICEHELPER:
+ case ELEMENT_INCLUDEDIR:
+ case ELEMENT_CONFIGTYPE:
+ case ELEMENT_SELINUX:
+ case ELEMENT_ASSOCIATE:
+ case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
+ case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
+ case ELEMENT_KEEP_UMASK:
+ case ELEMENT_SYSLOG:
+ case ELEMENT_ALLOW_ANONYMOUS:
+ case ELEMENT_APPARMOR:
default:
- /* do nothing */
+ /* do nothing: nothing in the Element struct for these types */
break;
}
@@ -3210,6 +3486,34 @@ lists_of_c_strings_equal (DBusList *a,
}
static dbus_bool_t
+lists_of_service_dirs_equal (DBusList *a,
+ DBusList *b)
+{
+ DBusList *ia;
+ DBusList *ib;
+
+ ia = a;
+ ib = b;
+
+ while (ia != NULL && ib != NULL)
+ {
+ BusConfigServiceDir *da = ia->data;
+ BusConfigServiceDir *db = ib->data;
+
+ if (strcmp (da->path, db->path))
+ return FALSE;
+
+ if (da->flags != db->flags)
+ return FALSE;
+
+ ia = _dbus_list_get_next_link (&a, ia);
+ ib = _dbus_list_get_next_link (&b, ib);
+ }
+
+ return ia == NULL && ib == NULL;
+}
+
+static dbus_bool_t
limits_equal (const BusLimits *a,
const BusLimits *b)
{
@@ -3252,7 +3556,7 @@ config_parsers_equal (const BusConfigParser *a,
if (!lists_of_c_strings_equal (a->mechanisms, b->mechanisms))
return FALSE;
- if (!lists_of_c_strings_equal (a->service_dirs, b->service_dirs))
+ if (!lists_of_service_dirs_equal (a->service_dirs, b->service_dirs))
return FALSE;
/* FIXME: compare policy */
@@ -3300,7 +3604,7 @@ all_are_equiv (const DBusString *target_directory)
dir = _dbus_directory_open (target_directory, &error);
if (dir == NULL)
{
- _dbus_warn ("Could not open %s: %s\n",
+ _dbus_warn ("Could not open %s: %s",
_dbus_string_get_const_data (target_directory),
error.message);
dbus_error_free (&error);
@@ -3337,7 +3641,7 @@ all_are_equiv (const DBusString *target_directory)
if (parser == NULL)
{
- _dbus_warn ("Could not load file %s: %s\n",
+ _dbus_warn ("Could not load file %s: %s",
_dbus_string_get_const_data (&full_path),
error.message);
_dbus_string_free (&full_path);
@@ -3406,7 +3710,7 @@ process_test_equiv_subdir (const DBusString *test_base_dir,
dir = _dbus_directory_open (&test_directory, &error);
if (dir == NULL)
{
- _dbus_warn ("Could not open %s: %s\n",
+ _dbus_warn ("Could not open %s: %s",
_dbus_string_get_const_data (&test_directory),
error.message);
dbus_error_free (&error);
@@ -3451,52 +3755,79 @@ process_test_equiv_subdir (const DBusString *test_base_dir,
static const char *test_session_service_dir_matches[] =
{
-#ifdef DBUS_UNIX
- "/testhome/foo/.testlocal/testshare/dbus-1/services",
- "/testusr/testlocal/testshare/dbus-1/services",
- "/testusr/testshare/dbus-1/services",
- DBUS_DATADIR"/dbus-1/services",
-#endif
/* will be filled in test_default_session_servicedirs() */
#ifdef DBUS_WIN
- NULL,
- NULL,
+ NULL, /* install root-based */
+ NULL, /* CommonProgramFiles-based */
+#else
+ NULL, /* XDG_RUNTIME_DIR-based */
+ NULL, /* XDG_DATA_HOME-based */
+ NULL, /* XDG_DATA_DIRS-based */
+ NULL, /* XDG_DATA_DIRS-based */
+ DBUS_DATADIR "/dbus-1/services",
#endif
NULL
};
static dbus_bool_t
-test_default_session_servicedirs (void)
+test_default_session_servicedirs (const DBusString *test_base_dir)
{
- DBusList *dirs;
+ BusConfigParser *parser = NULL;
+ DBusError error = DBUS_ERROR_INIT;
+ DBusList **dirs;
+ DBusList *watched_dirs = NULL;
DBusList *link;
+ DBusString tmp;
+ DBusString full_path;
DBusString progs;
DBusString install_root_based;
+ DBusString runtime_dir_based;
+ DBusString data_home_based;
+ DBusString data_dirs_based;
+ DBusString data_dirs_based2;
int i;
dbus_bool_t ret = FALSE;
#ifdef DBUS_WIN
- const char *tmp;
const char *common_progs;
+#else
+ const char *dbus_test_builddir;
+ const char *xdg_data_home;
+ const char *xdg_runtime_dir;
#endif
- /* On Unix we don't actually use these, but it's easier to handle the
- * deallocation if we always allocate them, whether needed or not */
- if (!_dbus_string_init (&progs) ||
- !_dbus_string_init (&install_root_based))
+ /* On each platform we don't actually use all of these, but it's easier to
+ * handle the deallocation if we always allocate them, whether needed or
+ * not */
+ if (!_dbus_string_init (&full_path) ||
+ !_dbus_string_init (&progs) ||
+ !_dbus_string_init (&install_root_based) ||
+ !_dbus_string_init (&runtime_dir_based) ||
+ !_dbus_string_init (&data_home_based) ||
+ !_dbus_string_init (&data_dirs_based) ||
+ !_dbus_string_init (&data_dirs_based2))
_dbus_assert_not_reached ("OOM allocating strings");
+ if (!_dbus_string_copy (test_base_dir, 0,
+ &full_path, 0))
+ _dbus_assert_not_reached ("couldn't copy test_base_dir to full_path");
+
+ _dbus_string_init_const (&tmp, "valid-config-files");
+
+ if (!_dbus_concat_dir_and_file (&full_path, &tmp))
+ _dbus_assert_not_reached ("couldn't allocate full path");
+
+ _dbus_string_init_const (&tmp, "standard-session-dirs.conf");
+
+ if (!_dbus_concat_dir_and_file (&full_path, &tmp))
+ _dbus_assert_not_reached ("couldn't allocate full path");
+
#ifdef DBUS_WIN
if (!_dbus_string_append (&install_root_based, DBUS_DATADIR) ||
- !_dbus_string_append (&install_root_based, "/dbus-1/services"))
+ !_dbus_string_append (&install_root_based, "/dbus-1/services") ||
+ !_dbus_replace_install_prefix (&install_root_based))
goto out;
- tmp = _dbus_replace_install_prefix (
- _dbus_string_get_const_data (&install_root_based));
-
- if (tmp == NULL ||
- !_dbus_string_set_length (&install_root_based, 0) ||
- !_dbus_string_append (&install_root_based, tmp))
- goto out;
+ _dbus_assert (_dbus_path_is_absolute (&install_root_based));
test_session_service_dir_matches[0] = _dbus_string_get_const_data (
&install_root_based);
@@ -3513,72 +3844,143 @@ test_default_session_servicedirs (void)
test_session_service_dir_matches[1] = _dbus_string_get_const_data(&progs);
}
+#else
+ dbus_test_builddir = _dbus_getenv ("DBUS_TEST_BUILDDIR");
+ xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
+ xdg_runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
+
+ if (dbus_test_builddir == NULL || xdg_data_home == NULL ||
+ xdg_runtime_dir == NULL)
+ {
+ printf ("Not testing default session service directories because a "
+ "build-time testing environment variable is not set: "
+ "see AM_TESTS_ENVIRONMENT in tests/Makefile.am\n");
+ ret = TRUE;
+ goto out;
+ }
+
+ if (!_dbus_string_append (&data_dirs_based, dbus_test_builddir) ||
+ !_dbus_string_append (&data_dirs_based, "/XDG_DATA_DIRS/dbus-1/services") ||
+ !_dbus_string_append (&data_dirs_based2, dbus_test_builddir) ||
+ !_dbus_string_append (&data_dirs_based2, "/XDG_DATA_DIRS2/dbus-1/services") ||
+ !_dbus_string_append (&runtime_dir_based, xdg_runtime_dir) ||
+ !_dbus_string_append (&data_home_based, xdg_data_home) ||
+ !_dbus_string_append (&data_home_based, "/dbus-1/services"))
+ _dbus_assert_not_reached ("out of memory");
+
+ if (!_dbus_ensure_directory (&runtime_dir_based, NULL))
+ _dbus_assert_not_reached ("Unable to create fake XDG_RUNTIME_DIR");
+
+ if (!_dbus_string_append (&runtime_dir_based, "/dbus-1/services"))
+ _dbus_assert_not_reached ("out of memory");
+
+ /* Sanity check: the Makefile sets this up. We assume that if this is
+ * right, the XDG_DATA_DIRS will be too. */
+ if (!_dbus_string_starts_with_c_str (&data_home_based, dbus_test_builddir))
+ _dbus_assert_not_reached ("$XDG_DATA_HOME should start with $DBUS_TEST_BUILDDIR");
+
+ if (!_dbus_string_starts_with_c_str (&runtime_dir_based, dbus_test_builddir))
+ _dbus_assert_not_reached ("$XDG_RUNTIME_DIR should start with $DBUS_TEST_BUILDDIR");
+
+ test_session_service_dir_matches[0] = _dbus_string_get_const_data (
+ &runtime_dir_based);
+ test_session_service_dir_matches[1] = _dbus_string_get_const_data (
+ &data_home_based);
+ test_session_service_dir_matches[2] = _dbus_string_get_const_data (
+ &data_dirs_based);
+ test_session_service_dir_matches[3] = _dbus_string_get_const_data (
+ &data_dirs_based2);
#endif
- dirs = NULL;
- printf ("Testing retrieving the default session service directories\n");
- if (!_dbus_get_standard_session_servicedirs (&dirs))
- _dbus_assert_not_reached ("couldn't get stardard dirs");
+ parser = bus_config_load (&full_path, TRUE, NULL, &error);
- /* make sure our defaults end with share/dbus-1/service */
- while ((link = _dbus_list_pop_first_link (&dirs)))
+ if (parser == NULL)
+ _dbus_assert_not_reached (error.message);
+
+ dirs = bus_config_parser_get_service_dirs (parser);
+
+ for (link = _dbus_list_get_first_link (dirs), i = 0;
+ link != NULL;
+ link = _dbus_list_get_next_link (dirs, link), i++)
{
- DBusString path;
-
- printf (" default service dir: %s\n", (char *)link->data);
- _dbus_string_init_const (&path, (char *)link->data);
- if (!_dbus_string_ends_with_c_str (&path, "dbus-1/services"))
+ BusConfigServiceDir *dir = link->data;
+ BusServiceDirFlags expected = BUS_SERVICE_DIR_FLAGS_NONE;
+
+ printf (" test service dir: '%s'\n", dir->path);
+ printf (" current standard service dir: '%s'\n", test_session_service_dir_matches[i]);
+ if (test_session_service_dir_matches[i] == NULL)
{
- printf ("error with default session service directories\n");
- dbus_free (link->data);
- _dbus_list_free_link (link);
+ printf ("more directories parsed than in match set\n");
goto out;
}
- dbus_free (link->data);
- _dbus_list_free_link (link);
+ if (strcmp (test_session_service_dir_matches[i], dir->path) != 0)
+ {
+ printf ("'%s' directory does not match '%s' in the match set\n",
+ dir->path, test_session_service_dir_matches[i]);
+ goto out;
+ }
+
+#ifndef DBUS_WIN
+ /* On Unix we expect the first directory in the search path to be
+ * in the XDG_RUNTIME_DIR, and we expect it to have special flags */
+ if (i == 0)
+ expected = (BUS_SERVICE_DIR_FLAGS_NO_WATCH |
+ BUS_SERVICE_DIR_FLAGS_STRICT_NAMING);
+#endif
+
+ if (dir->flags != expected)
+ {
+ printf ("'%s' directory has flags 0x%x, should be 0x%x\n",
+ dir->path, dir->flags, expected);
+ goto out;
+ }
+ }
+
+ if (test_session_service_dir_matches[i] != NULL)
+ {
+ printf ("extra data %s in the match set was not matched\n",
+ test_session_service_dir_matches[i]);
+ goto out;
}
-#ifdef DBUS_UNIX
- if (!dbus_setenv ("XDG_DATA_HOME", "/testhome/foo/.testlocal/testshare"))
- _dbus_assert_not_reached ("couldn't setenv XDG_DATA_HOME");
+ if (!bus_config_parser_get_watched_dirs (parser, &watched_dirs))
+ _dbus_assert_not_reached ("out of memory");
- if (!dbus_setenv ("XDG_DATA_DIRS", ":/testusr/testlocal/testshare: :/testusr/testshare:"))
- _dbus_assert_not_reached ("couldn't setenv XDG_DATA_DIRS");
+#ifdef DBUS_WIN
+ /* We expect all directories to be watched (not that it matters on Windows,
+ * because we don't know how) */
+ i = 0;
+#else
+ /* We expect all directories except the first to be watched, because
+ * the first one is transient */
+ i = 1;
#endif
- if (!_dbus_get_standard_session_servicedirs (&dirs))
- _dbus_assert_not_reached ("couldn't get stardard dirs");
- /* make sure we read and parse the env variable correctly */
- i = 0;
- while ((link = _dbus_list_pop_first_link (&dirs)))
+ for (link = _dbus_list_get_first_link (&watched_dirs);
+ link != NULL;
+ link = _dbus_list_get_next_link (&watched_dirs, link), i++)
{
- printf (" test service dir: %s\n", (char *)link->data);
+ printf (" watched service dir: '%s'\n", (const char *) link->data);
+ printf (" current standard service dir: '%s'\n",
+ test_session_service_dir_matches[i]);
+
if (test_session_service_dir_matches[i] == NULL)
{
printf ("more directories parsed than in match set\n");
- dbus_free (link->data);
- _dbus_list_free_link (link);
goto out;
}
-
- if (strcmp (test_session_service_dir_matches[i],
- (char *)link->data) != 0)
+
+ if (strcmp (test_session_service_dir_matches[i],
+ (const char *) link->data) != 0)
{
- printf ("%s directory does not match %s in the match set\n",
- (char *)link->data,
+ printf ("'%s' directory does not match '%s' in the match set\n",
+ (const char *) link->data,
test_session_service_dir_matches[i]);
- dbus_free (link->data);
- _dbus_list_free_link (link);
goto out;
}
-
- ++i;
-
- dbus_free (link->data);
- _dbus_list_free_link (link);
}
-
+
if (test_session_service_dir_matches[i] != NULL)
{
printf ("extra data %s in the match set was not matched\n",
@@ -3589,25 +3991,27 @@ test_default_session_servicedirs (void)
ret = TRUE;
out:
+ if (parser != NULL)
+ bus_config_parser_unref (parser);
+
+ _dbus_list_clear (&watched_dirs);
+ _dbus_string_free (&full_path);
_dbus_string_free (&install_root_based);
_dbus_string_free (&progs);
+ _dbus_string_free (&runtime_dir_based);
+ _dbus_string_free (&data_home_based);
+ _dbus_string_free (&data_dirs_based);
+ _dbus_string_free (&data_dirs_based2);
return ret;
}
+#ifndef DBUS_WIN
static const char *test_system_service_dir_matches[] =
{
-#ifdef DBUS_UNIX
"/usr/local/share/dbus-1/system-services",
"/usr/share/dbus-1/system-services",
-#endif
DBUS_DATADIR"/dbus-1/system-services",
-#ifdef DBUS_UNIX
"/lib/dbus-1/system-services",
-#endif
-
-#ifdef DBUS_WIN
- NULL,
-#endif
NULL
};
@@ -3616,69 +4020,10 @@ test_default_system_servicedirs (void)
{
DBusList *dirs;
DBusList *link;
- DBusString progs;
-#ifndef DBUS_UNIX
- const char *common_progs;
-#endif
int i;
- /* On Unix we don't actually use this variable, but it's easier to handle the
- * deallocation if we always allocate it, whether needed or not */
- if (!_dbus_string_init (&progs))
- _dbus_assert_not_reached ("OOM allocating progs");
-
-#ifndef DBUS_UNIX
- common_progs = _dbus_getenv ("CommonProgramFiles");
-
- if (common_progs)
- {
- if (!_dbus_string_append (&progs, common_progs))
- {
- _dbus_string_free (&progs);
- return FALSE;
- }
-
- if (!_dbus_string_append (&progs, "/dbus-1/system-services"))
- {
- _dbus_string_free (&progs);
- return FALSE;
- }
- test_system_service_dir_matches[1] = _dbus_string_get_const_data(&progs);
- }
-#endif
dirs = NULL;
- printf ("Testing retrieving the default system service directories\n");
- if (!_dbus_get_standard_system_servicedirs (&dirs))
- _dbus_assert_not_reached ("couldn't get stardard dirs");
-
- /* make sure our defaults end with share/dbus-1/system-service */
- while ((link = _dbus_list_pop_first_link (&dirs)))
- {
- DBusString path;
-
- printf (" default service dir: %s\n", (char *)link->data);
- _dbus_string_init_const (&path, (char *)link->data);
- if (!_dbus_string_ends_with_c_str (&path, "dbus-1/system-services"))
- {
- printf ("error with default system service directories\n");
- dbus_free (link->data);
- _dbus_list_free_link (link);
- _dbus_string_free (&progs);
- return FALSE;
- }
-
- dbus_free (link->data);
- _dbus_list_free_link (link);
- }
-
-#ifdef DBUS_UNIX
- if (!dbus_setenv ("XDG_DATA_HOME", "/testhome/foo/.testlocal/testshare"))
- _dbus_assert_not_reached ("couldn't setenv XDG_DATA_HOME");
-
- if (!dbus_setenv ("XDG_DATA_DIRS", ":/testusr/testlocal/testshare: :/testusr/testshare:"))
- _dbus_assert_not_reached ("couldn't setenv XDG_DATA_DIRS");
-#endif
if (!_dbus_get_standard_system_servicedirs (&dirs))
_dbus_assert_not_reached ("couldn't get stardard dirs");
@@ -3692,7 +4037,6 @@ test_default_system_servicedirs (void)
printf ("more directories parsed than in match set\n");
dbus_free (link->data);
_dbus_list_free_link (link);
- _dbus_string_free (&progs);
return FALSE;
}
@@ -3704,7 +4048,6 @@ test_default_system_servicedirs (void)
test_system_service_dir_matches[i]);
dbus_free (link->data);
_dbus_list_free_link (link);
- _dbus_string_free (&progs);
return FALSE;
}
@@ -3719,13 +4062,12 @@ test_default_system_servicedirs (void)
printf ("extra data %s in the match set was not matched\n",
test_system_service_dir_matches[i]);
- _dbus_string_free (&progs);
return FALSE;
}
- _dbus_string_free (&progs);
return TRUE;
}
+#endif
dbus_bool_t
bus_config_parser_test (const DBusString *test_data_dir)
@@ -3737,7 +4079,7 @@ bus_config_parser_test (const DBusString *test_data_dir)
return TRUE;
}
- if (!test_default_session_servicedirs())
+ if (!test_default_session_servicedirs (test_data_dir))
return FALSE;
#ifdef DBUS_WIN
diff --git a/bus/config-parser.h b/bus/config-parser.h
index ba5bf749..a24e74b2 100644
--- a/bus/config-parser.h
+++ b/bus/config-parser.h
@@ -73,6 +73,8 @@ DBusList** bus_config_parser_get_conf_dirs (BusConfigParser *parser);
BusPolicy* bus_config_parser_steal_policy (BusConfigParser *parser);
void bus_config_parser_get_limits (BusConfigParser *parser,
BusLimits *limits);
+dbus_bool_t bus_config_parser_get_watched_dirs (BusConfigParser *parser,
+ DBusList **watched_dirs);
DBusHashTable* bus_config_parser_steal_service_context_table (BusConfigParser *parser);
@@ -84,4 +86,23 @@ BusConfigParser* bus_config_load (const DBusString *file,
const BusConfigParser *parent,
DBusError *error);
+/*
+ * These are chosen such that if we configure a directory twice with different
+ * flags, we have to do an "and" operation on the flags - the compatible
+ * thing to do is to have no flags.
+ */
+typedef enum
+{
+ BUS_SERVICE_DIR_FLAGS_NO_WATCH = (1 << 0),
+ BUS_SERVICE_DIR_FLAGS_STRICT_NAMING = (1 << 1),
+ /* Keep this one at the end to reduce diffs when adding new entries */
+ BUS_SERVICE_DIR_FLAGS_NONE = 0
+} BusServiceDirFlags;
+
+typedef struct
+{
+ BusServiceDirFlags flags;
+ char *path;
+} BusConfigServiceDir;
+
#endif /* BUS_CONFIG_PARSER_H */
diff --git a/bus/connection.c b/bus/connection.c
index 7253c98e..e1802e7d 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -454,9 +454,6 @@ free_connection_data (void *data)
if (d->policy)
bus_client_policy_unref (d->policy);
- if (d->selinux_id)
- bus_selinux_id_unref (d->selinux_id);
-
if (d->apparmor_confinement)
bus_apparmor_confinement_unref (d->apparmor_confinement);
@@ -601,7 +598,7 @@ cache_peer_loginfo_string (BusConnectionData *d,
DBusString loginfo_buf;
unsigned long uid;
unsigned long pid;
- char *windows_sid;
+ char *windows_sid = NULL, *security_label = NULL;
dbus_bool_t prev_added;
if (!_dbus_string_init (&loginfo_buf))
@@ -630,16 +627,48 @@ cache_peer_loginfo_string (BusConnectionData *d,
_dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL);
if (!_dbus_string_append_byte (&loginfo_buf, '"'))
goto oom;
+ else
+ prev_added = TRUE;
}
if (dbus_connection_get_windows_user (connection, &windows_sid))
{
dbus_bool_t did_append;
+
+ if (prev_added)
+ {
+ if (!_dbus_string_append_byte (&loginfo_buf, ' '))
+ goto oom;
+ }
+
did_append = _dbus_string_append_printf (&loginfo_buf,
- "sid=\"%s\" ", windows_sid);
+ "sid=\"%s\"", windows_sid);
dbus_free (windows_sid);
+ windows_sid = NULL;
+ if (!did_append)
+ goto oom;
+ else
+ prev_added = TRUE;
+ }
+
+ if (_dbus_connection_get_linux_security_label (connection, &security_label))
+ {
+ dbus_bool_t did_append;
+
+ if (prev_added)
+ {
+ if (!_dbus_string_append_byte (&loginfo_buf, ' '))
+ goto oom;
+ }
+
+ did_append = _dbus_string_append_printf (&loginfo_buf,
+ "label=\"%s\"", security_label);
+ dbus_free (security_label);
+ security_label = NULL;
if (!did_append)
goto oom;
+ else
+ prev_added = TRUE;
}
if (!_dbus_string_steal_data (&loginfo_buf, &(d->cached_loginfo_string)))
@@ -650,6 +679,11 @@ cache_peer_loginfo_string (BusConnectionData *d,
return TRUE;
oom:
_dbus_string_free (&loginfo_buf);
+ if (security_label != NULL)
+ dbus_free (security_label);
+ if (windows_sid != NULL)
+ dbus_free (windows_sid);
+
return FALSE;
}
@@ -687,6 +721,18 @@ static dbus_bool_t
pending_unix_fds_timeout_cb (void *data)
{
DBusConnection *connection = data;
+ BusConnectionData *d = BUS_CONNECTION_DATA (connection);
+ int limit;
+
+ _dbus_assert (d != NULL);
+ limit = bus_context_get_pending_fd_timeout (d->connections->context);
+ bus_context_log (d->connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "Connection \"%s\" (%s) has had Unix fds pending for too long, "
+ "closing it (pending_fd_timeout=%d ms)",
+ d->name != NULL ? d->name : "(null)",
+ bus_connection_get_loginfo (connection),
+ limit);
+
dbus_connection_close (connection);
return TRUE;
}
@@ -696,15 +742,13 @@ bus_connections_setup_connection (BusConnections *connections,
DBusConnection *connection)
{
- BusConnectionData *d;
- dbus_bool_t retval;
+ BusConnectionData *d = NULL;
DBusError error;
-
d = dbus_new0 (BusConnectionData, 1);
if (d == NULL)
- return FALSE;
+ goto oom;
d->connections = connections;
d->connection = connection;
@@ -718,39 +762,35 @@ bus_connections_setup_connection (BusConnections *connections,
connection_data_slot,
d, free_connection_data))
{
+ /* We have to free d explicitly, because this is the only code
+ * path where it's non-NULL but dbus_connection_set_data() hasn't
+ * taken responsibility for freeing it. */
dbus_free (d);
- return FALSE;
+ d = NULL;
+ goto oom;
}
dbus_connection_set_route_peer_messages (connection, TRUE);
-
- retval = FALSE;
dbus_error_init (&error);
d->selinux_id = bus_selinux_init_connection_id (connection,
&error);
if (dbus_error_is_set (&error))
{
- /* This is a bit bogus because we pretend all errors
- * are OOM; this is done because we know that in bus.c
- * an OOM error disconnects the connection, which is
- * the same thing we want on any other error.
- */
+ bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "Unable to set up new connection: %s", error.message);
dbus_error_free (&error);
- goto out;
+ goto error;
}
d->apparmor_confinement = bus_apparmor_init_connection_confinement (connection,
&error);
if (dbus_error_is_set (&error))
{
- /* This is a bit bogus because we pretend all errors
- * are OOM; this is done because we know that in bus.c
- * an OOM error disconnects the connection, which is
- * the same thing we want on any other error.
- */
+ bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "Unable to set up new connection: %s", error.message);
dbus_error_free (&error);
- goto out;
+ goto error;
}
if (!dbus_connection_set_watch_functions (connection,
@@ -759,14 +799,14 @@ bus_connections_setup_connection (BusConnections *connections,
toggle_connection_watch,
connection,
NULL))
- goto out;
+ goto oom;
if (!dbus_connection_set_timeout_functions (connection,
add_connection_timeout,
remove_connection_timeout,
NULL,
connection, NULL))
- goto out;
+ goto oom;
/* For now we don't need to set a Windows user function because
* there are no policies in the config file controlling what
@@ -784,18 +824,18 @@ bus_connections_setup_connection (BusConnections *connections,
d->link_in_connection_list = _dbus_list_alloc_link (connection);
if (d->link_in_connection_list == NULL)
- goto out;
+ goto oom;
/* Setup the connection with the dispatcher */
if (!bus_dispatch_add_connection (connection))
- goto out;
+ goto oom;
if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
{
if (!_dbus_loop_queue_dispatch (bus_context_get_loop (connections->context), connection))
{
bus_dispatch_remove_connection (connection);
- goto out;
+ goto oom;
}
}
@@ -804,12 +844,12 @@ bus_connections_setup_connection (BusConnections *connections,
pending_unix_fds_timeout_cb,
connection, NULL);
if (d->pending_unix_fds_timeout == NULL)
- goto out;
+ goto oom;
_dbus_timeout_disable (d->pending_unix_fds_timeout);
if (!_dbus_loop_add_timeout (bus_context_get_loop (connections->context),
d->pending_unix_fds_timeout))
- goto out;
+ goto oom;
_dbus_connection_set_pending_fds_function (connection,
(DBusPendingFdsChangeFunction) check_pending_fds_cb,
@@ -832,13 +872,15 @@ bus_connections_setup_connection (BusConnections *connections,
* stop accept()ing any more, to avert a DoS. See fd.o #80919 */
bus_context_check_all_watches (d->connections->context);
- retval = TRUE;
+ return TRUE;
- out:
- if (!retval)
+oom:
+ bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "No memory to set up new connection");
+ /* fall through */
+error:
+ if (d != NULL)
{
- if (d->selinux_id)
- bus_selinux_id_unref (d->selinux_id);
d->selinux_id = NULL;
if (d->apparmor_confinement)
@@ -889,7 +931,7 @@ bus_connections_setup_connection (BusConnections *connections,
/* "d" has now been freed */
}
- return retval;
+ return FALSE;
}
void
@@ -1697,13 +1739,23 @@ bus_connection_get_name (DBusConnection *connection)
dbus_bool_t
bus_connections_check_limits (BusConnections *connections,
DBusConnection *requesting_completion,
+ const char **limit_name_out,
+ int *limit_out,
DBusError *error)
{
unsigned long uid;
+ int limit;
+
+ limit = bus_context_get_max_completed_connections (connections->context);
- if (connections->n_completed >=
- bus_context_get_max_completed_connections (connections->context))
+ if (connections->n_completed >= limit)
{
+ if (limit_name_out != NULL)
+ *limit_name_out = "max_completed_connections";
+
+ if (limit_out != NULL)
+ *limit_out = limit;
+
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The maximum number of active connections has been reached");
return FALSE;
@@ -1711,9 +1763,16 @@ bus_connections_check_limits (BusConnections *connections,
if (dbus_connection_get_unix_user (requesting_completion, &uid))
{
- if (get_connections_for_uid (connections, uid) >=
- bus_context_get_max_connections_per_user (connections->context))
+ limit = bus_context_get_max_connections_per_user (connections->context);
+
+ if (get_connections_for_uid (connections, uid) >= limit)
{
+ if (limit_name_out != NULL)
+ *limit_name_out = "max_connections_per_user";
+
+ if (limit_out != NULL)
+ *limit_out = limit;
+
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The maximum number of active connections for UID %lu has been reached",
uid);
@@ -1933,6 +1992,7 @@ bus_connections_expect_reply (BusConnections *connections,
DBusList *link;
CancelPendingReplyData *cprd;
int count;
+ int limit;
_dbus_assert (will_get_reply != NULL);
_dbus_assert (will_send_reply != NULL);
@@ -1963,10 +2023,19 @@ bus_connections_expect_reply (BusConnections *connections,
if (pending->will_get_reply == will_get_reply)
++count;
}
-
- if (count >=
- bus_context_get_max_replies_per_connection (connections->context))
+
+ limit = bus_context_get_max_replies_per_connection (connections->context);
+
+ if (count >= limit)
{
+ bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
+ "The maximum number of pending replies for "
+ "\"%s\" (%s) has been reached "
+ "(max_replies_per_connection=%d)",
+ bus_connection_get_name (will_get_reply),
+ bus_connection_get_loginfo (will_get_reply),
+ limit);
+
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The maximum number of pending replies per connection has been reached");
return FALSE;
@@ -2246,6 +2315,7 @@ bus_transaction_get_context (BusTransaction *transaction)
dbus_bool_t
bus_transaction_capture (BusTransaction *transaction,
DBusConnection *sender,
+ DBusConnection *addressed_recipient,
DBusMessage *message)
{
BusConnections *connections;
@@ -2265,8 +2335,8 @@ bus_transaction_capture (BusTransaction *transaction,
* There's little point, since there is up to 1 per process. */
_dbus_assert (mm != NULL);
- if (!bus_matchmaker_get_recipients (mm, connections, sender, NULL, message,
- &recipients))
+ if (!bus_matchmaker_get_recipients (mm, connections, sender,
+ addressed_recipient, message, &recipients))
goto out;
for (link = _dbus_list_get_first_link (&recipients);
@@ -2288,6 +2358,7 @@ out:
dbus_bool_t
bus_transaction_capture_error_reply (BusTransaction *transaction,
+ DBusConnection *addressed_recipient,
const DBusError *error,
DBusMessage *in_reply_to)
{
@@ -2314,7 +2385,7 @@ bus_transaction_capture_error_reply (BusTransaction *transaction,
if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
goto out;
- ret = bus_transaction_capture (transaction, NULL, reply);
+ ret = bus_transaction_capture (transaction, NULL, addressed_recipient, reply);
out:
dbus_message_unref (reply);
@@ -2357,7 +2428,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
/* Capture it for monitors, even if the real recipient's receive policy
* does not allow it to receive this message from us (which would be odd).
*/
- if (!bus_transaction_capture (transaction, NULL, message))
+ if (!bus_transaction_capture (transaction, NULL, connection, message))
return FALSE;
/* If security policy doesn't allow the message, we would silently
@@ -2374,7 +2445,8 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
case BUS_RESULT_TRUE:
break;
case BUS_RESULT_FALSE:
- if (!bus_transaction_capture_error_reply (transaction, &error, message))
+ if (!bus_transaction_capture_error_reply (transaction, connection,
+ &error, message))
{
bus_context_log (transaction->context, DBUS_SYSTEM_LOG_WARNING,
"message from dbus-daemon rejected but not enough "
diff --git a/bus/connection.h b/bus/connection.h
index 6c6fca8d..ba7ce2f3 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -58,6 +58,8 @@ BusSELinuxID* bus_connection_get_selinux_id (DBusConnection
BusAppArmorConfinement* bus_connection_dup_apparmor_confinement (DBusConnection *connection);
dbus_bool_t bus_connections_check_limits (BusConnections *connections,
DBusConnection *requesting_completion,
+ const char **limit_name_out,
+ int *limit_out,
DBusError *error);
void bus_connections_expire_incomplete (BusConnections *connections);
@@ -158,8 +160,10 @@ dbus_bool_t bus_transaction_send (BusTransaction *
dbus_bool_t deferred_dispatch);
dbus_bool_t bus_transaction_capture (BusTransaction *transaction,
DBusConnection *connection,
+ DBusConnection *addressed_recipient,
DBusMessage *message);
dbus_bool_t bus_transaction_capture_error_reply (BusTransaction *transaction,
+ DBusConnection *addressed_recipient,
const DBusError *error,
DBusMessage *in_reply_to);
dbus_bool_t bus_transaction_send_from_driver (BusTransaction *transaction,
diff --git a/bus/dbus.service.in b/bus/dbus.service.in
index 9686f362..21ea6769 100644
--- a/bus/dbus.service.in
+++ b/bus/dbus.service.in
@@ -6,7 +6,7 @@ Requires=dbus.socket
[Service]
Type=notify
-ExecStart=@EXPANDED_BINDIR@/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
+ExecStart=@EXPANDED_BINDIR@/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
ExecReload=@EXPANDED_BINDIR@/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
OOMScoreAdjust=-900
User=dbus
diff --git a/bus/desktop-file.c b/bus/desktop-file.c
index bfeb72e2..fd4f0d31 100644
--- a/bus/desktop-file.c
+++ b/bus/desktop-file.c
@@ -88,7 +88,7 @@ static unsigned char valid[256] = {
};
static void report_error (BusDesktopFileParser *parser,
- char *message,
+ const char *message,
const char *error_name,
DBusError *error);
@@ -378,12 +378,16 @@ parse_comment_or_blank (BusDesktopFileParser *parser)
static dbus_bool_t
is_valid_section_name (const char *name)
{
- /* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'. */
+ /* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'.
+ *
+ * We don't use isprint() here because it's locale-dependent. ASCII
+ * characters <= 0x1f and 0x7f are control characters, and bytes with
+ * values >= 0x80 aren't ASCII. 0x20 is a space, which we must allow,
+ * not least because DBUS_SERVICE_SECTION contains one. */
while (*name)
{
- if (!((*name >= 'A' && *name <= 'Z') || (*name >= 'a' || *name <= 'z') ||
- *name == '\n' || *name == '\t'))
+ if (*name <= 0x1f || *name >= 0x7f || *name == '[' || *name == ']')
return FALSE;
name++;
@@ -579,7 +583,7 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error)
static void
report_error (BusDesktopFileParser *parser,
- char *message,
+ const char *message,
const char *error_name,
DBusError *error)
{
diff --git a/bus/desktop-file.h b/bus/desktop-file.h
index e405625c..14477387 100644
--- a/bus/desktop-file.h
+++ b/bus/desktop-file.h
@@ -35,6 +35,7 @@
#define DBUS_SERVICE_EXEC "Exec"
#define DBUS_SERVICE_USER "User"
#define DBUS_SERVICE_SYSTEMD_SERVICE "SystemdService"
+#define DBUS_SERVICE_ASSUMED_APPARMOR_LABEL "AssumedAppArmorLabel"
typedef struct BusDesktopFile BusDesktopFile;
diff --git a/bus/dir-watch-inotify.c b/bus/dir-watch-inotify.c
index a287f0ba..447dc2db 100644
--- a/bus/dir-watch-inotify.c
+++ b/bus/dir-watch-inotify.c
@@ -157,7 +157,7 @@ _set_watched_dirs_internal (DBusList **directories)
/* Not all service directories need to exist. */
if (errno != ENOENT)
{
- _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
+ _dbus_warn ("Cannot setup inotify for '%s'; error '%s'", new_dirs[i], _dbus_strerror (errno));
goto out;
}
else
@@ -236,7 +236,7 @@ _init_inotify (BusContext *context)
#endif
if (inotify_fd <= 0)
{
- _dbus_warn ("Cannot initialize inotify\n");
+ _dbus_warn ("Cannot initialize inotify");
goto out;
}
@@ -252,7 +252,7 @@ _init_inotify (BusContext *context)
if (watch == NULL)
{
- _dbus_warn ("Unable to create inotify watch\n");
+ _dbus_warn ("Unable to create inotify watch");
goto out;
}
diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c
index c1e83245..9b1784e8 100644
--- a/bus/dir-watch-kqueue.c
+++ b/bus/dir-watch-kqueue.c
@@ -137,7 +137,7 @@ _init_kqueue (BusContext *context)
kq = kqueue ();
if (kq < 0)
{
- _dbus_warn ("Cannot create kqueue; error '%s'\n", _dbus_strerror (errno));
+ _dbus_warn ("Cannot create kqueue; error '%s'", _dbus_strerror (errno));
goto out;
}
@@ -149,7 +149,7 @@ _init_kqueue (BusContext *context)
if (watch == NULL)
{
- _dbus_warn ("Unable to create kqueue watch\n");
+ _dbus_warn ("Unable to create kqueue watch");
goto out1;
}
@@ -276,7 +276,7 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories)
{
if (errno != ENOENT)
{
- _dbus_warn ("Cannot open directory '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
+ _dbus_warn ("Cannot open directory '%s'; error '%s'", new_dirs[i], _dbus_strerror (errno));
goto out;
}
else
@@ -297,7 +297,7 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories)
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_RENAME, 0, 0);
if (kevent (kq, &ev, 1, NULL, 0, NULL) == -1)
{
- _dbus_warn ("Cannot setup a kevent for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
+ _dbus_warn ("Cannot setup a kevent for '%s'; error '%s'", new_dirs[i], _dbus_strerror (errno));
close (fd);
goto out;
}
diff --git a/bus/dispatch.c b/bus/dispatch.c
index f4dea605..3cdae9f9 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -75,8 +75,8 @@ send_one_message (DBusConnection *connection,
if (result == BUS_RESULT_FALSE)
{
- if (!bus_transaction_capture_error_reply (transaction, &stack_error,
- message))
+ if (!bus_transaction_capture_error_reply (transaction, sender,
+ &stack_error, message))
{
bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
"broadcast rejected, but not enough "
@@ -96,8 +96,8 @@ send_one_message (DBusConnection *connection,
bus_connection_get_name (connection),
bus_connection_get_loginfo (connection));
- if (!bus_transaction_capture_error_reply (transaction, &stack_error,
- message))
+ if (!bus_transaction_capture_error_reply (transaction, sender,
+ &stack_error, message))
{
bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
"broadcast with Unix fd not delivered, but not "
@@ -483,17 +483,17 @@ bus_dispatch (DBusConnection *connection,
*/
service_name = dbus_message_get_destination (message);
- if (!bus_transaction_capture (transaction, connection, message))
- {
- BUS_SET_OOM (&error);
- goto out;
- }
-
if (service_name &&
strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
{
BusDeferredMessage *deferred_message;
+ if (!bus_transaction_capture (transaction, connection, NULL, message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
+
switch (bus_context_check_security_policy (context, transaction,
connection, NULL, NULL, message,
NULL, &error,
@@ -530,6 +530,12 @@ bus_dispatch (DBusConnection *connection,
}
else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
{
+ if (!bus_transaction_capture (transaction, connection, NULL, message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
+
_dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
dbus_connection_close (connection);
goto out;
@@ -552,6 +558,13 @@ bus_dispatch (DBusConnection *connection,
BusActivation *activation;
BusDeferredMessage *deferred_message;
+ if (!bus_transaction_capture (transaction, connection, NULL,
+ message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
+
activation = bus_connection_get_activation (connection);
/* This will do as much of a security policy check as it can.
@@ -581,6 +594,13 @@ bus_dispatch (DBusConnection *connection,
}
else if (service == NULL)
{
+ if (!bus_transaction_capture (transaction, connection,
+ NULL, message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
+
dbus_set_error (&error,
DBUS_ERROR_NAME_HAS_NO_OWNER,
"Name \"%s\" does not exist",
@@ -591,6 +611,21 @@ bus_dispatch (DBusConnection *connection,
{
addressed_recipient = bus_service_get_primary_owners_connection (service);
_dbus_assert (addressed_recipient != NULL);
+
+ if (!bus_transaction_capture (transaction, connection,
+ addressed_recipient, message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
+ }
+ }
+ else /* service_name == NULL */
+ {
+ if (!bus_transaction_capture (transaction, connection, NULL, message))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
}
}
@@ -769,7 +804,7 @@ warn_unexpected_real (DBusConnection *connection,
int line)
{
if (message)
- _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
+ _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s",
function, line,
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) : "(unset)",
@@ -780,7 +815,7 @@ warn_unexpected_real (DBusConnection *connection,
connection,
expected);
else
- _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
+ _dbus_warn ("%s:%d received no message on %p, expecting %s",
function, line, connection, expected);
}
@@ -840,7 +875,7 @@ check_service_owner_changed_foreach (DBusConnection *connection,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a message on %p, expecting %s\n",
+ _dbus_warn ("Did not receive a message on %p, expecting %s",
connection, "NameOwnerChanged");
goto out;
}
@@ -876,7 +911,7 @@ check_service_owner_changed_foreach (DBusConnection *connection,
}
else
{
- _dbus_warn ("Did not get the expected arguments\n");
+ _dbus_warn ("Did not get the expected arguments");
goto out;
}
}
@@ -885,13 +920,13 @@ check_service_owner_changed_foreach (DBusConnection *connection,
|| (d->expected_kind == OWNER_CHANGED && (!old_owner[0] || !new_owner[0]))
|| (d->expected_kind == SERVICE_DELETED && (!old_owner[0] || new_owner[0])))
{
- _dbus_warn ("inconsistent NameOwnerChanged arguments\n");
+ _dbus_warn ("inconsistent NameOwnerChanged arguments");
goto out;
}
if (strcmp (service_name, d->expected_service_name) != 0)
{
- _dbus_warn ("expected info on service %s, got info on %s\n",
+ _dbus_warn ("expected info on service %s, got info on %s",
d->expected_service_name,
service_name);
goto out;
@@ -900,7 +935,7 @@ check_service_owner_changed_foreach (DBusConnection *connection,
if (*service_name == ':' && new_owner[0]
&& strcmp (service_name, new_owner) != 0)
{
- _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
+ _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])",
service_name, old_owner, new_owner);
goto out;
}
@@ -1112,7 +1147,7 @@ check_hello_message (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Hello", serial, connection);
goto out;
}
@@ -1121,7 +1156,7 @@ check_hello_message (BusContext *context,
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -1171,7 +1206,7 @@ check_hello_message (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected single string argument to hello\n");
+ _dbus_warn ("Did not get the expected single string argument to hello");
goto out;
}
}
@@ -1203,7 +1238,7 @@ check_hello_message (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Expecting %s, got nothing\n",
+ _dbus_warn ("Expecting %s, got nothing",
"NameAcquired");
goto out;
}
@@ -1211,7 +1246,7 @@ check_hello_message (BusContext *context,
if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
"NameAcquired"))
{
- _dbus_warn ("Expecting %s, got smthg else\n",
+ _dbus_warn ("Expecting %s, got smthg else",
"NameAcquired");
goto out;
}
@@ -1231,7 +1266,7 @@ check_hello_message (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
+ _dbus_warn ("Did not get the expected single string argument to ServiceAcquired");
goto out;
}
}
@@ -1240,7 +1275,7 @@ check_hello_message (BusContext *context,
if (strcmp (acquired, name) != 0)
{
- _dbus_warn ("Acquired name is %s but expected %s\n",
+ _dbus_warn ("Acquired name is %s but expected %s",
acquired, name);
goto out;
}
@@ -1323,7 +1358,7 @@ check_double_hello_message (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Hello", serial, connection);
goto out;
}
@@ -1332,7 +1367,7 @@ check_double_hello_message (BusContext *context,
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -1425,7 +1460,7 @@ check_get_connection_unix_user (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"GetConnectionUnixUser", serial, connection);
goto out;
}
@@ -1481,7 +1516,7 @@ check_get_connection_unix_user (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
+ _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser");
goto out;
}
}
@@ -1570,7 +1605,7 @@ check_get_connection_unix_process_id (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"GetConnectionUnixProcessID", serial, connection);
goto out;
}
@@ -1644,7 +1679,7 @@ check_get_connection_unix_process_id (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
+ _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID");
goto out;
}
}
@@ -1660,7 +1695,7 @@ check_get_connection_unix_process_id (BusContext *context,
if (pid != (dbus_uint32_t) _dbus_getpid ())
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
+ _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid");
goto out;
}
}
@@ -1755,7 +1790,7 @@ check_add_match (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"AddMatch", serial, connection);
goto out;
}
@@ -1764,7 +1799,7 @@ check_add_match (BusContext *context,
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -1880,7 +1915,7 @@ check_get_all_match_rules (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"AddMatch", serial, connection);
goto out;
}
@@ -1889,7 +1924,7 @@ check_get_all_match_rules (BusContext *context,
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -2047,7 +2082,7 @@ check_nonexistent_service_no_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"StartServiceByName", serial, connection);
goto out;
}
@@ -2058,7 +2093,7 @@ check_nonexistent_service_no_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -2082,7 +2117,7 @@ check_nonexistent_service_no_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully activate %s\n",
+ _dbus_warn ("Did not expect to successfully activate %s",
NONEXISTENT_SERVICE_NAME);
goto out;
}
@@ -2140,7 +2175,7 @@ check_nonexistent_service_auto_start (BusContext *context,
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -2151,7 +2186,7 @@ check_nonexistent_service_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -2175,7 +2210,7 @@ check_nonexistent_service_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully activate %s\n",
+ _dbus_warn ("Did not expect to successfully activate %s",
NONEXISTENT_SERVICE_NAME);
goto out;
}
@@ -2235,7 +2270,7 @@ check_base_service_activated (BusContext *context,
}
else
{
- _dbus_warn ("Message %s doesn't have a service name: %s\n",
+ _dbus_warn ("Message %s doesn't have a service name: %s",
"NameOwnerChanged (creation)",
error.message);
goto out;
@@ -2244,21 +2279,21 @@ check_base_service_activated (BusContext *context,
if (*base_service != ':')
{
- _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
+ _dbus_warn ("Expected base service activation, got \"%s\" instead",
base_service);
goto out;
}
if (strcmp (base_service, base_service_from_bus) != 0)
{
- _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
+ _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"",
base_service, base_service_from_bus);
goto out;
}
if (old_owner[0])
{
- _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
+ _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"",
old_owner);
goto out;
}
@@ -2340,7 +2375,7 @@ check_service_activated (BusContext *context,
}
else
{
- _dbus_warn ("Message %s doesn't have a service name: %s\n",
+ _dbus_warn ("Message %s doesn't have a service name: %s",
"NameOwnerChanged (creation)",
error.message);
goto out;
@@ -2349,21 +2384,21 @@ check_service_activated (BusContext *context,
if (strcmp (service_name, activated_name) != 0)
{
- _dbus_warn ("Expected to see service %s created, saw %s instead\n",
+ _dbus_warn ("Expected to see service %s created, saw %s instead",
activated_name, service_name);
goto out;
}
if (strcmp (base_service_name, base_service_from_bus) != 0)
{
- _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
+ _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead",
base_service_from_bus, base_service_name);
goto out;
}
if (old_owner[0])
{
- _dbus_warn ("expected a %s, got a %s\n",
+ _dbus_warn ("expected a %s, got a %s",
"NameOwnerChanged (creation)",
"NameOwnerChanged (change)");
goto out;
@@ -2389,7 +2424,7 @@ check_service_activated (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Expected a reply to %s, got nothing\n",
+ _dbus_warn ("Expected a reply to %s, got nothing",
"StartServiceByName");
goto out;
}
@@ -2415,7 +2450,7 @@ check_service_activated (BusContext *context,
{
if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
- _dbus_warn ("Did not have activation result first argument to %s: %s\n",
+ _dbus_warn ("Did not have activation result first argument to %s: %s",
"StartServiceByName", error.message);
goto out;
}
@@ -2430,7 +2465,7 @@ check_service_activated (BusContext *context,
; /* Good also */
else
{
- _dbus_warn ("Activation result was %u, no good.\n",
+ _dbus_warn ("Activation result was %u, no good.",
activation_result);
goto out;
}
@@ -2441,7 +2476,7 @@ check_service_activated (BusContext *context,
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after verifying existent activation results\n");
+ _dbus_warn ("Messages were left over after verifying existent activation results");
goto out;
}
@@ -2493,7 +2528,7 @@ check_service_auto_activated (BusContext *context,
}
else
{
- _dbus_warn ("Message %s doesn't have a service name: %s\n",
+ _dbus_warn ("Message %s doesn't have a service name: %s",
"NameOwnerChanged",
error.message);
dbus_error_free (&error);
@@ -2503,7 +2538,7 @@ check_service_auto_activated (BusContext *context,
if (strcmp (service_name, activated_name) != 0)
{
- _dbus_warn ("Expected to see service %s created, saw %s instead\n",
+ _dbus_warn ("Expected to see service %s created, saw %s instead",
activated_name, service_name);
goto out;
}
@@ -2725,7 +2760,7 @@ check_send_exit_to_service (BusContext *context,
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after %s\n",
+ _dbus_warn ("Messages were left over after %s",
_DBUS_FUNCTION_NAME);
goto out;
}
@@ -2757,7 +2792,7 @@ check_got_error (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not get an expected error\n");
+ _dbus_warn ("Did not get an expected error");
goto out;
}
@@ -2785,7 +2820,7 @@ check_got_error (BusContext *context,
if (!error_found)
{
- _dbus_warn ("Expected error %s or other, got %s instead\n",
+ _dbus_warn ("Expected error %s or other, got %s instead",
first_error_name,
dbus_message_get_error_name (message));
goto out;
@@ -2840,7 +2875,7 @@ check_got_service_info (DBusMessage *message)
}
else
{
- _dbus_warn ("unexpected arguments for NameOwnerChanged message\n");
+ _dbus_warn ("unexpected arguments for NameOwnerChanged message");
message_kind = GOT_SOMETHING_ELSE;
}
}
@@ -2929,7 +2964,7 @@ check_existent_service_no_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after %s %d on %p\n",
+ _dbus_warn ("Did not receive any messages after %s %d on %p",
"StartServiceByName", serial, connection);
goto out;
}
@@ -2941,7 +2976,7 @@ check_existent_service_no_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -2963,7 +2998,7 @@ check_existent_service_no_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect error %s\n",
+ _dbus_warn ("Did not expect error %s",
dbus_message_get_error_name (message));
goto out;
}
@@ -2985,7 +3020,7 @@ check_existent_service_no_auto_start (BusContext *context,
message = dbus_connection_borrow_message (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after base service creation notification\n");
+ _dbus_warn ("Did not receive any messages after base service creation notification");
goto out;
}
@@ -2997,6 +3032,7 @@ check_existent_service_no_auto_start (BusContext *context,
switch (message_kind)
{
case GOT_SOMETHING_ELSE:
+ default:
_dbus_warn ("Unexpected message after ActivateService "
"(should be an error or a service announcement");
goto out;
@@ -3056,7 +3092,7 @@ check_existent_service_no_auto_start (BusContext *context,
if (message == NULL)
{
_dbus_warn ("Failed to pop message we just put back! "
- "should have been a NameOwnerChanged (creation)\n");
+ "should have been a NameOwnerChanged (creation)");
goto out;
}
@@ -3069,7 +3105,7 @@ check_existent_service_no_auto_start (BusContext *context,
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after successful activation\n");
+ _dbus_warn ("Messages were left over after successful activation");
goto out;
}
@@ -3151,7 +3187,7 @@ check_segfault_service_no_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"StartServiceByName", serial, connection);
goto out;
}
@@ -3162,7 +3198,7 @@ check_segfault_service_no_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -3203,7 +3239,7 @@ check_segfault_service_no_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully activate segfault service\n");
+ _dbus_warn ("Did not expect to successfully activate segfault service");
goto out;
}
@@ -3260,7 +3296,7 @@ check_segfault_service_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -3271,7 +3307,7 @@ check_segfault_service_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -3304,7 +3340,7 @@ check_segfault_service_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully activate segfault service\n");
+ _dbus_warn ("Did not expect to successfully activate segfault service");
goto out;
}
@@ -3367,13 +3403,13 @@ check_existent_hello_from_self (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n");
+ _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message");
return FALSE;
}
if (dbus_message_get_reply_serial (message) != serial)
{
- _dbus_warn ("Wrong reply serial\n");
+ _dbus_warn ("Wrong reply serial");
dbus_message_unref (message);
return FALSE;
}
@@ -3420,20 +3456,20 @@ check_existent_ping (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n");
+ _dbus_warn ("Failed to pop message! Should have been reply from Ping message");
return FALSE;
}
if (dbus_message_get_reply_serial (message) != serial)
{
- _dbus_warn ("Wrong reply serial\n");
+ _dbus_warn ("Wrong reply serial");
dbus_message_unref (message);
return FALSE;
}
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
{
- _dbus_warn ("Unexpected message return during Ping\n");
+ _dbus_warn ("Unexpected message return during Ping");
dbus_message_unref (message);
return FALSE;
}
@@ -3451,10 +3487,21 @@ static dbus_bool_t
check_existent_get_machine_id (BusContext *context,
DBusConnection *connection)
{
+ DBusError error = DBUS_ERROR_INIT;
DBusMessage *message;
dbus_uint32_t serial;
+ DBusGUID uuid;
const char *machine_id;
+ if (!_dbus_read_local_machine_uuid (&uuid, FALSE, &error))
+ {
+ /* Unable to test further: either we ran out of memory, or neither
+ * dbus nor systemd was ever correctly installed on this machine */
+ _dbus_verbose ("Machine UUID not available: %s", error.message);
+ dbus_error_free (&error);
+ return TRUE;
+ }
+
message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
"/org/freedesktop/TestSuite",
"org.freedesktop.DBus.Peer",
@@ -3482,20 +3529,20 @@ check_existent_get_machine_id (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n");
+ _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message");
return FALSE;
}
if (dbus_message_get_reply_serial (message) != serial)
{
- _dbus_warn ("Wrong reply serial\n");
+ _dbus_warn ("Wrong reply serial");
dbus_message_unref (message);
return FALSE;
}
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
{
- _dbus_warn ("Unexpected message return during GetMachineId\n");
+ _dbus_warn ("Unexpected message return during GetMachineId");
dbus_message_unref (message);
return FALSE;
}
@@ -3503,14 +3550,14 @@ check_existent_get_machine_id (BusContext *context,
machine_id = NULL;
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID))
{
- _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n");
+ _dbus_warn ("Did not get a machine ID in reply to GetMachineId");
dbus_message_unref (message);
return FALSE;
}
if (machine_id == NULL || strlen (machine_id) != 32)
{
- _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null");
+ _dbus_warn ("Machine id looks bogus: '%s'", machine_id ? machine_id : "null");
dbus_message_unref (message);
return FALSE;
}
@@ -3586,7 +3633,7 @@ check_existent_service_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
+ _dbus_warn ("Did not receive any messages after auto start %d on %p",
serial, connection);
goto out;
}
@@ -3616,7 +3663,7 @@ check_existent_service_auto_start (BusContext *context,
if (message == NULL)
{
_dbus_warn ("No message after auto activation "
- "(should be a service announcement)\n");
+ "(should be a service announcement)");
dbus_connection_return_message (connection, message);
message = NULL;
goto out;
@@ -3634,7 +3681,7 @@ check_existent_service_auto_start (BusContext *context,
if (message == NULL)
{
_dbus_warn ("Failed to pop message we just put back! "
- "should have been a NameOwnerChanged (creation)\n");
+ "should have been a NameOwnerChanged (creation)");
goto out;
}
@@ -3672,7 +3719,8 @@ check_existent_service_auto_start (BusContext *context,
case GOT_ERROR:
case GOT_SOMETHING_ELSE:
- _dbus_warn ("Unexpected message after auto activation\n");
+ default:
+ _dbus_warn ("Unexpected message after auto activation");
goto out;
}
}
@@ -3689,13 +3737,13 @@ check_existent_service_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
+ _dbus_warn ("Failed to pop message! Should have been reply from echo message");
goto out;
}
if (dbus_message_get_reply_serial (message) != serial)
{
- _dbus_warn ("Wrong reply serial\n");
+ _dbus_warn ("Wrong reply serial");
goto out;
}
@@ -3773,7 +3821,7 @@ check_launch_service_file_missing (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -3784,7 +3832,7 @@ check_launch_service_file_missing (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -3810,7 +3858,7 @@ check_launch_service_file_missing (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully auto-start missing service\n");
+ _dbus_warn ("Did not expect to successfully auto-start missing service");
goto out;
}
@@ -3823,6 +3871,8 @@ check_launch_service_file_missing (BusContext *context,
return retval;
}
+#ifndef DBUS_WIN
+
#define SERVICE_USER_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoUser"
/* returns TRUE if the correct thing happens,
@@ -3860,7 +3910,7 @@ check_launch_service_user_missing (BusContext *context,
if (!dbus_connection_get_is_connected (connection))
{
- _dbus_warn ("connection was disconnected\n");
+ _dbus_warn ("connection was disconnected");
return TRUE;
}
@@ -3869,7 +3919,7 @@ check_launch_service_user_missing (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -3880,7 +3930,7 @@ check_launch_service_user_missing (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -3906,7 +3956,7 @@ check_launch_service_user_missing (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully auto-start missing service\n");
+ _dbus_warn ("Did not expect to successfully auto-start missing service");
goto out;
}
@@ -3956,7 +4006,7 @@ check_launch_service_exec_missing (BusContext *context,
if (!dbus_connection_get_is_connected (connection))
{
- _dbus_warn ("connection was disconnected\n");
+ _dbus_warn ("connection was disconnected");
return TRUE;
}
@@ -3965,7 +4015,7 @@ check_launch_service_exec_missing (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -3976,7 +4026,7 @@ check_launch_service_exec_missing (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -4010,7 +4060,7 @@ check_launch_service_exec_missing (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully auto-start missing service\n");
+ _dbus_warn ("Did not expect to successfully auto-start missing service");
goto out;
}
@@ -4060,7 +4110,7 @@ check_launch_service_service_missing (BusContext *context,
if (!dbus_connection_get_is_connected (connection))
{
- _dbus_warn ("connection was disconnected\n");
+ _dbus_warn ("connection was disconnected");
return TRUE;
}
@@ -4069,7 +4119,7 @@ check_launch_service_service_missing (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -4080,7 +4130,7 @@ check_launch_service_service_missing (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -4114,7 +4164,7 @@ check_launch_service_service_missing (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully auto-start missing service\n");
+ _dbus_warn ("Did not expect to successfully auto-start missing service");
goto out;
}
@@ -4126,6 +4176,7 @@ check_launch_service_service_missing (BusContext *context,
return retval;
}
+#endif
#define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail"
@@ -4172,7 +4223,7 @@ check_shell_fail_service_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
"Echo message (auto activation)", serial, connection);
goto out;
}
@@ -4183,7 +4234,7 @@ check_shell_fail_service_auto_start (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -4209,7 +4260,7 @@ check_shell_fail_service_auto_start (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect to successfully auto-start shell fail service\n");
+ _dbus_warn ("Did not expect to successfully auto-start shell fail service");
goto out;
}
@@ -4276,7 +4327,7 @@ check_shell_service_success_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
+ _dbus_warn ("Did not receive any messages after auto start %d on %p",
serial, connection);
goto out;
}
@@ -4306,7 +4357,7 @@ check_shell_service_success_auto_start (BusContext *context,
if (message == NULL)
{
_dbus_warn ("No message after auto activation "
- "(should be a service announcement)\n");
+ "(should be a service announcement)");
dbus_connection_return_message (connection, message);
message = NULL;
goto out;
@@ -4324,7 +4375,7 @@ check_shell_service_success_auto_start (BusContext *context,
if (message == NULL)
{
_dbus_warn ("Failed to pop message we just put back! "
- "should have been a NameOwnerChanged (creation)\n");
+ "should have been a NameOwnerChanged (creation)");
goto out;
}
@@ -4362,7 +4413,8 @@ check_shell_service_success_auto_start (BusContext *context,
case GOT_ERROR:
case GOT_SOMETHING_ELSE:
- _dbus_warn ("Unexpected message after auto activation\n");
+ default:
+ _dbus_warn ("Unexpected message after auto activation");
goto out;
}
}
@@ -4379,13 +4431,13 @@ check_shell_service_success_auto_start (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
+ _dbus_warn ("Failed to pop message! Should have been reply from echo message");
goto out;
}
if (dbus_message_get_reply_serial (message) != serial)
{
- _dbus_warn ("Wrong reply serial\n");
+ _dbus_warn ("Wrong reply serial");
goto out;
}
@@ -4399,7 +4451,7 @@ check_shell_service_success_auto_start (BusContext *context,
DBUS_TYPE_STRING, &argv[6],
DBUS_TYPE_INVALID))
{
- _dbus_warn ("Error getting arguments from return\n");
+ _dbus_warn ("Error getting arguments from return");
goto out;
}
@@ -4408,42 +4460,42 @@ check_shell_service_success_auto_start (BusContext *context,
*/
if (strcmp("-test", argv[1]) != 0)
{
- _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)",
"-test", argv[1]);
goto out;
}
if (strcmp("that", argv[2]) != 0)
{
- _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)",
"that", argv[2]);
goto out;
}
if (strcmp("we get", argv[3]) != 0)
{
- _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)",
"we get", argv[3]);
goto out;
}
if (strcmp("back", argv[4]) != 0)
{
- _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)",
"back", argv[4]);
goto out;
}
if (strcmp("--what", argv[5]) != 0)
{
- _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)",
"--what", argv[5]);
goto out;
}
if (strcmp("we put in", argv[6]) != 0)
{
- _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n",
+ _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)",
"we put in", argv[6]);
goto out;
}
@@ -4484,7 +4536,7 @@ check_oom_check1_func (void *data)
if (!check_no_leftovers (d->context))
{
- _dbus_warn ("Messages were left over, should be covered by test suite\n");
+ _dbus_warn ("Messages were left over, should be covered by test suite");
return FALSE;
}
@@ -4561,7 +4613,7 @@ check_get_services (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ _dbus_warn ("Did not receive a reply to %s %d on %p",
method, serial, connection);
goto out;
}
@@ -4613,7 +4665,7 @@ check_get_services (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method);
+ _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s", method);
goto out;
}
} else {
@@ -4662,7 +4714,7 @@ check_list_services (BusContext *context,
if (!_dbus_string_array_contains ((const char **)services, existent))
{
- _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent);
+ _dbus_warn ("Did not get the expected %s from ListActivatableNames", existent);
dbus_free_string_array (services);
return FALSE;
}
@@ -4720,7 +4772,7 @@ check_list_services (BusContext *context,
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after %s %d on %p\n",
+ _dbus_warn ("Did not receive any messages after %s %d on %p",
"StartServiceByName", serial, connection);
goto out;
}
@@ -4732,7 +4784,7 @@ check_list_services (BusContext *context,
{
if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
{
- _dbus_warn ("Message has wrong sender %s\n",
+ _dbus_warn ("Message has wrong sender %s",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
@@ -4754,7 +4806,7 @@ check_list_services (BusContext *context,
}
else
{
- _dbus_warn ("Did not expect error %s\n",
+ _dbus_warn ("Did not expect error %s",
dbus_message_get_error_name (message));
goto out;
}
@@ -4776,7 +4828,7 @@ check_list_services (BusContext *context,
message = dbus_connection_borrow_message (connection);
if (message == NULL)
{
- _dbus_warn ("Did not receive any messages after base service creation notification\n");
+ _dbus_warn ("Did not receive any messages after base service creation notification");
goto out;
}
@@ -4790,8 +4842,9 @@ check_list_services (BusContext *context,
case GOT_SOMETHING_ELSE:
case GOT_ERROR:
case GOT_SERVICE_DELETED:
+ default:
_dbus_warn ("Unexpected message after ActivateService "
- "(should be an error or a service announcement)\n");
+ "(should be an error or a service announcement)");
goto out;
case GOT_SERVICE_CREATED:
@@ -4799,7 +4852,7 @@ check_list_services (BusContext *context,
if (message == NULL)
{
_dbus_warn ("Failed to pop message we just put back! "
- "should have been a NameOwnerChanged (creation)\n");
+ "should have been a NameOwnerChanged (creation)");
goto out;
}
@@ -4812,7 +4865,7 @@ check_list_services (BusContext *context,
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after successful activation\n");
+ _dbus_warn ("Messages were left over after successful activation");
goto out;
}
@@ -4827,7 +4880,7 @@ check_list_services (BusContext *context,
if (!_dbus_string_array_contains ((const char **)services, existent))
{
- _dbus_warn ("Did not get the expected %s from ListNames\n", existent);
+ _dbus_warn ("Did not get the expected %s from ListNames", existent);
goto out;
}
@@ -4866,7 +4919,7 @@ check_oom_check2_func (void *data)
if (!check_no_leftovers (d->context))
{
- _dbus_warn ("Messages were left over, should be covered by test suite\n");
+ _dbus_warn ("Messages were left over, should be covered by test suite");
return FALSE;
}
@@ -4888,7 +4941,7 @@ check2_try_iterations (BusContext *context,
if (!_dbus_test_oom_handling (description, check_oom_check2_func,
&d))
{
- _dbus_warn ("%s failed during oom\n", description);
+ _dbus_warn ("%s failed during oom", description);
_dbus_assert_not_reached ("test failed");
}
}
@@ -5019,7 +5072,7 @@ bus_dispatch_test_conf (const DBusString *test_data_dir,
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after setting up initial connections\n");
+ _dbus_warn ("Messages were left over after setting up initial connections");
_dbus_assert_not_reached ("initial connection setup failed");
}
@@ -5077,6 +5130,7 @@ bus_dispatch_test_conf (const DBusString *test_data_dir,
return TRUE;
}
+#ifndef DBUS_WIN
static dbus_bool_t
bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
const char *filename)
@@ -5133,6 +5187,7 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
return TRUE;
}
+#endif
typedef struct {
DBusTimeout *timeout;
@@ -5316,7 +5371,7 @@ bus_dispatch_sha1_test (const DBusString *test_data_dir)
if (!check_no_leftovers (context))
{
- _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
+ _dbus_warn ("Messages were left over after setting up initial SHA-1 connection");
_dbus_assert_not_reached ("initial connection setup failed");
}
diff --git a/bus/driver.c b/bus/driver.c
index d5c662cb..c468fe58 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -43,13 +43,6 @@
#include <dbus/dbus-marshal-validate.h>
#include <string.h>
-typedef enum
-{
- BUS_DRIVER_FOUND_SELF,
- BUS_DRIVER_FOUND_PEER,
- BUS_DRIVER_FOUND_ERROR,
-} BusDriverFound;
-
static inline const char *
nonnull (const char *maybe_null,
const char *if_null)
@@ -75,7 +68,7 @@ bus_driver_get_owner_of_name (DBusConnection *connection,
return bus_service_get_primary_owners_connection (serv);
}
-static BusDriverFound
+BusDriverFound
bus_driver_get_conn_helper (DBusConnection *connection,
DBusMessage *message,
const char *what_we_want,
@@ -257,7 +250,7 @@ bus_driver_send_service_owner_changed (const char *service_name,
_dbus_assert (dbus_message_has_signature (message, "sss"));
- if (!bus_transaction_capture (transaction, NULL, message))
+ if (!bus_transaction_capture (transaction, NULL, NULL, message))
goto oom;
switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
@@ -441,6 +434,9 @@ bus_driver_handle_hello (DBusConnection *connection,
BusResult retval;
BusRegistry *registry;
BusConnections *connections;
+ DBusError tmp_error;
+ int limit;
+ const char *limit_name;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -458,11 +454,19 @@ bus_driver_handle_hello (DBusConnection *connection,
* incomplete connections. It's even OK if the connection wants to
* retry the hello message, we support that.
*/
+ dbus_error_init (&tmp_error);
connections = bus_connection_get_connections (connection);
if (!bus_connections_check_limits (connections, connection,
- error))
+ &limit_name, &limit,
+ &tmp_error))
{
- _DBUS_ASSERT_ERROR_IS_SET (error);
+ BusContext *context;
+
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+ context = bus_connection_get_context (connection);
+ bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s (%s=%d)",
+ tmp_error.message, limit_name, limit);
+ dbus_move_error (&tmp_error, error);
return BUS_RESULT_FALSE;
}
@@ -983,11 +987,11 @@ bus_driver_handle_activate_service (DBusConnection *connection,
return retval;
}
-static dbus_bool_t
-send_ack_reply (DBusConnection *connection,
- BusTransaction *transaction,
- DBusMessage *message,
- DBusError *error)
+dbus_bool_t
+bus_driver_send_ack_reply (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
{
DBusMessage *reply;
@@ -1047,7 +1051,7 @@ bus_driver_send_or_activate (BusTransaction *transaction,
activation = bus_context_get_activation (context);
- if (!bus_transaction_capture (transaction, NULL, message))
+ if (!bus_transaction_capture (transaction, NULL, NULL, message))
{
BUS_SET_OOM (error);
_dbus_verbose ("No memory for bus_transaction_capture()");
@@ -1100,21 +1104,6 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!bus_driver_check_message_is_for_us (message, error))
- return FALSE;
-
-#ifdef DBUS_UNIX
- {
- /* UpdateActivationEnvironment is basically a recipe for privilege
- * escalation so let's be extra-careful: do not allow the sysadmin
- * to shoot themselves in the foot.
- */
- if (!bus_driver_check_caller_is_privileged (connection, transaction,
- message, error))
- return FALSE;
- }
-#endif
-
context = bus_connection_get_context (connection);
if (bus_context_get_servicehelper (context) != NULL)
@@ -1298,8 +1287,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
}
}
- if (!send_ack_reply (connection, transaction,
- message, error))
+ if (!bus_driver_send_ack_reply (connection, transaction, message, error))
goto out;
retval = BUS_RESULT_TRUE;
@@ -1322,6 +1310,7 @@ bus_driver_handle_add_match (DBusConnection *connection,
const char *text, *bustype;
DBusString str;
BusMatchmaker *matchmaker;
+ int limit;
BusContext *context;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -1329,15 +1318,25 @@ bus_driver_handle_add_match (DBusConnection *connection,
text = NULL;
rule = NULL;
- if (bus_connection_get_n_match_rules (connection) >=
- bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
+ context = bus_transaction_get_context (transaction);
+ limit = bus_context_get_max_match_rules_per_connection (context);
+
+ if (bus_connection_get_n_match_rules (connection) >= limit)
{
- dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ DBusError tmp_error;
+
+ dbus_error_init (&tmp_error);
+ dbus_set_error (&tmp_error, DBUS_ERROR_LIMITS_EXCEEDED,
"Connection \"%s\" is not allowed to add more match rules "
- "(increase limits in configuration file if required)",
+ "(increase limits in configuration file if required; "
+ "max_match_rules_per_connection=%d)",
bus_connection_is_active (connection) ?
bus_connection_get_name (connection) :
- "(inactive)");
+ "(inactive)",
+ limit);
+ bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s",
+ tmp_error.message);
+ dbus_move_error (&tmp_error, error);
goto failed;
}
@@ -1355,11 +1354,17 @@ bus_driver_handle_add_match (DBusConnection *connection,
if (rule == NULL)
goto failed;
- context = bus_transaction_get_context (transaction);
- bustype = context ? bus_context_get_type (context) : NULL;
- if (bus_match_rule_get_client_is_eavesdropping (rule) &&
- !bus_apparmor_allows_eavesdropping (connection, bustype, error))
- goto failed;
+ bustype = bus_context_get_type (context);
+
+ if (bus_match_rule_get_client_is_eavesdropping (rule))
+ {
+ if (!bus_driver_check_caller_is_privileged (connection,
+ transaction,
+ message,
+ error) ||
+ !bus_apparmor_allows_eavesdropping (connection, bustype, error))
+ goto failed;
+ }
matchmaker = bus_connection_get_matchmaker (connection);
@@ -1369,8 +1374,7 @@ bus_driver_handle_add_match (DBusConnection *connection,
goto failed;
}
- if (!send_ack_reply (connection, transaction,
- message, error))
+ if (!bus_driver_send_ack_reply (connection, transaction, message, error))
{
bus_matchmaker_remove_rule (matchmaker, rule);
goto failed;
@@ -1420,8 +1424,7 @@ bus_driver_handle_remove_match (DBusConnection *connection,
/* Send the ack before we remove the rule, since the ack is undone
* on transaction cancel, but rule removal isn't.
*/
- if (!send_ack_reply (connection, transaction,
- message, error))
+ if (!bus_driver_send_ack_reply (connection, transaction, message, error))
goto failed;
matchmaker = bus_connection_get_matchmaker (connection);
@@ -1528,6 +1531,8 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
DBusMessage *message,
DBusError *error)
{
+ static const char dbus_service_name[] = DBUS_SERVICE_DBUS;
+
const char *text;
DBusList *base_names;
DBusList *link;
@@ -1536,7 +1541,6 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
BusService *service;
DBusMessage *reply;
DBusMessageIter iter, array_iter;
- char *dbus_service_name = DBUS_SERVICE_DBUS;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -1557,7 +1561,7 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
_dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
{
/* ORG_FREEDESKTOP_DBUS owns itself */
- if (! _dbus_list_append (&base_names, dbus_service_name))
+ if (! _dbus_list_append (&base_names, (char *) dbus_service_name))
goto oom;
}
else if (service == NULL)
@@ -1658,6 +1662,8 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
uid = DBUS_UID_UNSET;
break;
case BUS_DRIVER_FOUND_ERROR:
+ /* fall through */
+ default:
goto failed;
}
@@ -1725,6 +1731,8 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
pid = DBUS_PID_UNSET;
break;
case BUS_DRIVER_FOUND_ERROR:
+ /* fall through */
+ default:
goto failed;
}
@@ -1772,7 +1780,7 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
DBusConnection *conn;
DBusMessage *reply;
void *data = NULL;
- dbus_uint32_t data_size;
+ dbus_int32_t data_size;
const char *service;
BusDriverFound found;
@@ -1852,8 +1860,9 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
if (reply == NULL)
goto oom;
- /* FIXME: Obtain the SELinux security context for the bus daemon itself */
- if (found == BUS_DRIVER_FOUND_PEER)
+ if (found == BUS_DRIVER_FOUND_SELF)
+ context = bus_selinux_get_self ();
+ else if (found == BUS_DRIVER_FOUND_PEER)
context = bus_connection_get_selinux_id (conn);
else
context = NULL;
@@ -1922,6 +1931,8 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
ulong_uid = DBUS_UID_UNSET;
break;
case BUS_DRIVER_FOUND_ERROR:
+ /* fall through */
+ default:
goto failed;
}
@@ -2193,18 +2204,11 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!bus_driver_check_message_is_for_us (message, error))
- goto out;
-
context = bus_transaction_get_context (transaction);
bustype = context ? bus_context_get_type (context) : NULL;
if (!bus_apparmor_allows_eavesdropping (connection, bustype, error))
goto out;
- if (!bus_driver_check_caller_is_privileged (connection, transaction,
- message, error))
- goto out;
-
if (!dbus_message_get_args (message, error,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &match_rules, &n_match_rules,
DBUS_TYPE_UINT32, &flags,
@@ -2263,7 +2267,7 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
/* Send the ack before we remove the rule, since the ack is undone
* on transaction cancel, but becoming a monitor isn't.
*/
- if (!send_ack_reply (connection, transaction, message, error))
+ if (!bus_driver_send_ack_reply (connection, transaction, message, error))
goto out;
if (!bus_connection_be_monitor (connection, transaction, &rules, error))
@@ -2288,6 +2292,109 @@ out:
return ret;
}
+static dbus_bool_t
+bus_driver_handle_get_machine_id (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ DBusMessage *reply = NULL;
+ DBusString uuid;
+ const char *str;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!_dbus_string_init (&uuid))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
+ goto fail;
+
+ reply = dbus_message_new_method_return (message);
+
+ if (reply == NULL)
+ goto oom;
+
+ str = _dbus_string_get_const_data (&uuid);
+
+ if (!dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID))
+ goto oom;
+
+ _dbus_assert (dbus_message_has_signature (reply, "s"));
+
+ if (!bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ _dbus_string_free (&uuid);
+ dbus_message_unref (reply);
+ return TRUE;
+
+oom:
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ BUS_SET_OOM (error);
+
+fail:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ _dbus_string_free (&uuid);
+ return FALSE;
+}
+
+static dbus_bool_t
+bus_driver_handle_ping (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ return bus_driver_send_ack_reply (connection, transaction, message, error);
+}
+
+static dbus_bool_t bus_driver_handle_get (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error);
+
+static dbus_bool_t bus_driver_handle_get_all (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error);
+
+static dbus_bool_t bus_driver_handle_set (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error);
+
+static dbus_bool_t features_getter (BusContext *context,
+ DBusMessageIter *variant_iter);
+static dbus_bool_t interfaces_getter (BusContext *context,
+ DBusMessageIter *variant_iter);
+
+typedef enum
+{
+ /* Various older methods were available at every object path. We have to
+ * preserve that behaviour for backwards compatibility, but we can at least
+ * stop doing that for newly added methods.
+ * The special Peer interface should also work at any object path.
+ * <https://bugs.freedesktop.org/show_bug.cgi?id=101256> */
+ METHOD_FLAG_ANY_PATH = (1 << 0),
+
+ /* If set, callers must be privileged. On Unix, the uid of the connection
+ * must either be the uid of this process, or 0 (root). On Windows,
+ * the SID of the connection must be the SID of this process. */
+ METHOD_FLAG_PRIVILEGED = (1 << 1),
+
+ METHOD_FLAG_NONE = 0
+} MethodFlags;
+
typedef struct
{
const char *name;
@@ -2297,8 +2404,17 @@ typedef struct
BusTransaction *transaction,
DBusMessage *message,
DBusError *error);
+ MethodFlags flags;
} MessageHandler;
+typedef struct
+{
+ const char *name;
+ const char *type;
+ dbus_bool_t (* getter) (BusContext *context,
+ DBusMessageIter *variant_iter);
+} PropertyHandler;
+
/* For speed it might be useful to sort this in order of
* frequency of use (but doesn't matter with only a few items
* anyhow)
@@ -2307,114 +2423,178 @@ static const MessageHandler dbus_message_handlers[] = {
{ "Hello",
"",
DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_hello },
+ bus_driver_handle_hello,
+ METHOD_FLAG_ANY_PATH },
{ "RequestName",
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
- bus_driver_handle_acquire_service },
+ bus_driver_handle_acquire_service,
+ METHOD_FLAG_ANY_PATH },
{ "ReleaseName",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
- bus_driver_handle_release_service },
+ bus_driver_handle_release_service,
+ METHOD_FLAG_ANY_PATH },
{ "StartServiceByName",
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
- bus_driver_handle_activate_service },
+ bus_driver_handle_activate_service,
+ METHOD_FLAG_ANY_PATH },
{ "UpdateActivationEnvironment",
DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
"",
- bus_driver_handle_update_activation_environment },
+ bus_driver_handle_update_activation_environment,
+ METHOD_FLAG_PRIVILEGED },
{ "NameHasOwner",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_BOOLEAN_AS_STRING,
- bus_driver_handle_service_exists },
+ bus_driver_handle_service_exists,
+ METHOD_FLAG_ANY_PATH },
{ "ListNames",
"",
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_list_services },
+ bus_driver_handle_list_services,
+ METHOD_FLAG_ANY_PATH },
{ "ListActivatableNames",
"",
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_list_activatable_services },
+ bus_driver_handle_list_activatable_services,
+ METHOD_FLAG_ANY_PATH },
{ "AddMatch",
DBUS_TYPE_STRING_AS_STRING,
"",
- bus_driver_handle_add_match },
+ bus_driver_handle_add_match,
+ METHOD_FLAG_ANY_PATH },
{ "RemoveMatch",
DBUS_TYPE_STRING_AS_STRING,
"",
- bus_driver_handle_remove_match },
+ bus_driver_handle_remove_match,
+ METHOD_FLAG_ANY_PATH },
{ "GetNameOwner",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_get_service_owner },
+ bus_driver_handle_get_service_owner,
+ METHOD_FLAG_ANY_PATH },
{ "ListQueuedOwners",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_list_queued_owners },
+ bus_driver_handle_list_queued_owners,
+ METHOD_FLAG_ANY_PATH },
{ "GetConnectionUnixUser",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
- bus_driver_handle_get_connection_unix_user },
+ bus_driver_handle_get_connection_unix_user,
+ METHOD_FLAG_ANY_PATH },
{ "GetConnectionUnixProcessID",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,
- bus_driver_handle_get_connection_unix_process_id },
+ bus_driver_handle_get_connection_unix_process_id,
+ METHOD_FLAG_ANY_PATH },
{ "GetAdtAuditSessionData",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
- bus_driver_handle_get_adt_audit_session_data },
+ bus_driver_handle_get_adt_audit_session_data,
+ METHOD_FLAG_ANY_PATH },
{ "GetConnectionSELinuxSecurityContext",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
- bus_driver_handle_get_connection_selinux_security_context },
+ bus_driver_handle_get_connection_selinux_security_context,
+ METHOD_FLAG_ANY_PATH },
{ "ReloadConfig",
"",
"",
- bus_driver_handle_reload_config },
+ bus_driver_handle_reload_config,
+ METHOD_FLAG_ANY_PATH },
{ "GetId",
"",
DBUS_TYPE_STRING_AS_STRING,
- bus_driver_handle_get_id },
+ bus_driver_handle_get_id,
+ METHOD_FLAG_ANY_PATH },
{ "GetConnectionCredentials", "s", "a{sv}",
- bus_driver_handle_get_connection_credentials },
+ bus_driver_handle_get_connection_credentials,
+ METHOD_FLAG_ANY_PATH },
{ NULL, NULL, NULL, NULL }
};
+static const PropertyHandler dbus_property_handlers[] = {
+ { "Features", "as", features_getter },
+ { "Interfaces", "as", interfaces_getter },
+ { NULL, NULL, NULL }
+};
+
static BusResult bus_driver_handle_introspect (DBusConnection *,
BusTransaction *, DBusMessage *, DBusError *);
+static const MessageHandler properties_message_handlers[] = {
+ { "Get", "ss", "v", bus_driver_handle_get, METHOD_FLAG_NONE },
+ { "GetAll", "s", "a{sv}", bus_driver_handle_get_all, METHOD_FLAG_NONE },
+ { "Set", "ssv", "", bus_driver_handle_set, METHOD_FLAG_NONE },
+ { NULL, NULL, NULL, NULL }
+};
+
static const MessageHandler introspectable_message_handlers[] = {
- { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
+ { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect,
+ METHOD_FLAG_ANY_PATH },
{ NULL, NULL, NULL, NULL }
};
static const MessageHandler monitoring_message_handlers[] = {
- { "BecomeMonitor", "asu", "", bus_driver_handle_become_monitor },
+ { "BecomeMonitor", "asu", "", bus_driver_handle_become_monitor,
+ METHOD_FLAG_PRIVILEGED },
{ NULL, NULL, NULL, NULL }
};
#ifdef DBUS_ENABLE_VERBOSE_MODE
static const MessageHandler verbose_message_handlers[] = {
- { "EnableVerbose", "", "", bus_driver_handle_enable_verbose},
- { "DisableVerbose", "", "", bus_driver_handle_disable_verbose},
+ { "EnableVerbose", "", "", bus_driver_handle_enable_verbose,
+ METHOD_FLAG_NONE },
+ { "DisableVerbose", "", "", bus_driver_handle_disable_verbose,
+ METHOD_FLAG_NONE },
{ NULL, NULL, NULL, NULL }
};
#endif
#ifdef DBUS_ENABLE_STATS
static const MessageHandler stats_message_handlers[] = {
- { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
- { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
- { "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules },
+ { "GetStats", "", "a{sv}", bus_stats_handle_get_stats,
+ METHOD_FLAG_NONE },
+ { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats,
+ METHOD_FLAG_NONE },
+ { "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules,
+ METHOD_FLAG_NONE },
{ NULL, NULL, NULL, NULL }
};
#endif
+static const MessageHandler peer_message_handlers[] = {
+ { "GetMachineId", "", "s", bus_driver_handle_get_machine_id,
+ METHOD_FLAG_ANY_PATH },
+ { "Ping", "", "", bus_driver_handle_ping, METHOD_FLAG_ANY_PATH },
+ { NULL, NULL, NULL, NULL }
+};
+
+typedef enum
+{
+ /* Various older interfaces were available at every object path. We have to
+ * preserve that behaviour for backwards compatibility, but we can at least
+ * stop doing that for newly added interfaces:
+ * <https://bugs.freedesktop.org/show_bug.cgi?id=101256>
+ * Introspectable and Peer are also useful at all object paths. */
+ INTERFACE_FLAG_ANY_PATH = (1 << 0),
+
+ /* Set this flag for interfaces that should not show up in the
+ * Interfaces property. */
+ INTERFACE_FLAG_UNINTERESTING = (1 << 1),
+
+ INTERFACE_FLAG_NONE = 0
+} InterfaceFlags;
+
typedef struct {
const char *name;
const MessageHandler *message_handlers;
const char *extra_introspection;
+ InterfaceFlags flags;
+ const PropertyHandler *property_handlers;
} InterfaceHandler;
/* These should ideally be sorted by frequency of use, although it
@@ -2431,15 +2611,42 @@ static InterfaceHandler interface_handlers[] = {
" </signal>\n"
" <signal name=\"NameAcquired\">\n"
" <arg type=\"s\"/>\n"
- " </signal>\n" },
- { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
- { DBUS_INTERFACE_MONITORING, monitoring_message_handlers, NULL },
+ " </signal>\n",
+ /* Not in the Interfaces property because if you can get the properties
+ * of the o.fd.DBus interface, then you certainly have the o.fd.DBus
+ * interface, so there is little point in listing it explicitly.
+ * Partially available at all paths for backwards compatibility. */
+ INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING,
+ dbus_property_handlers },
+ { DBUS_INTERFACE_PROPERTIES, properties_message_handlers,
+ " <signal name=\"PropertiesChanged\">\n"
+ " <arg type=\"s\" name=\"interface_name\"/>\n"
+ " <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
+ " <arg type=\"as\" name=\"invalidated_properties\"/>\n"
+ " </signal>\n",
+ /* Not in the Interfaces property because if you can get the properties
+ * of the o.fd.DBus interface, then you certainly have Properties. */
+ INTERFACE_FLAG_UNINTERESTING },
+ { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL,
+ /* Not in the Interfaces property because introspection isn't really a
+ * feature in the same way as e.g. Monitoring.
+ * Available at all paths so tools like d-feet can start from "/". */
+ INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
+ { DBUS_INTERFACE_MONITORING, monitoring_message_handlers, NULL,
+ INTERFACE_FLAG_NONE },
#ifdef DBUS_ENABLE_VERBOSE_MODE
- { DBUS_INTERFACE_VERBOSE, verbose_message_handlers, NULL },
+ { DBUS_INTERFACE_VERBOSE, verbose_message_handlers, NULL,
+ INTERFACE_FLAG_NONE },
#endif
#ifdef DBUS_ENABLE_STATS
- { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
+ { BUS_INTERFACE_STATS, stats_message_handlers, NULL,
+ INTERFACE_FLAG_NONE },
#endif
+ { DBUS_INTERFACE_PEER, peer_message_handlers, NULL,
+ /* Not in the Interfaces property because it's a pseudo-interface
+ * on all object paths of all connections, rather than a feature of the
+ * bus driver object. */
+ INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
{ NULL, NULL, NULL }
};
@@ -2479,10 +2686,13 @@ write_args_for_direction (DBusString *xml,
}
dbus_bool_t
-bus_driver_generate_introspect_string (DBusString *xml)
+bus_driver_generate_introspect_string (DBusString *xml,
+ dbus_bool_t is_canonical_path,
+ DBusMessage *message)
{
const InterfaceHandler *ih;
const MessageHandler *mh;
+ const PropertyHandler *ph;
if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
return FALSE;
@@ -2491,6 +2701,9 @@ bus_driver_generate_introspect_string (DBusString *xml)
for (ih = interface_handlers; ih->name != NULL; ih++)
{
+ if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
+ continue;
+
if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n",
ih->name))
return FALSE;
@@ -2511,6 +2724,20 @@ bus_driver_generate_introspect_string (DBusString *xml)
return FALSE;
}
+ for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
+ {
+ /* We only have constant properties so far, so hard-code that bit */
+ if (!_dbus_string_append_printf (xml,
+ " <property name=\"%s\" type=\"%s\" access=\"read\">\n",
+ ph->name, ph->type))
+ return FALSE;
+
+ if (!_dbus_string_append (xml,
+ " <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
+ " </property>\n"))
+ return FALSE;
+ }
+
if (ih->extra_introspection != NULL &&
!_dbus_string_append (xml, ih->extra_introspection))
return FALSE;
@@ -2519,6 +2746,28 @@ bus_driver_generate_introspect_string (DBusString *xml)
return FALSE;
}
+ if (message != NULL)
+ {
+ /* Make the bus driver object path discoverable */
+ if (dbus_message_has_path (message, "/"))
+ {
+ if (!_dbus_string_append (xml,
+ " <node name=\"org/freedesktop/DBus\"/>\n"))
+ return FALSE;
+ }
+ else if (dbus_message_has_path (message, "/org"))
+ {
+ if (!_dbus_string_append (xml,
+ " <node name=\"freedesktop/DBus\"/>\n"))
+ return FALSE;
+ }
+ else if (dbus_message_has_path (message, "/org/freedesktop"))
+ {
+ if (!_dbus_string_append (xml, " <node name=\"DBus\"/>\n"))
+ return FALSE;
+ }
+ }
+
if (!_dbus_string_append (xml, "</node>\n"))
return FALSE;
@@ -2534,6 +2783,7 @@ bus_driver_handle_introspect (DBusConnection *connection,
DBusString xml;
DBusMessage *reply;
const char *v_STRING;
+ dbus_bool_t is_canonical_path;
_dbus_verbose ("Introspect() on bus driver\n");
@@ -2554,7 +2804,9 @@ bus_driver_handle_introspect (DBusConnection *connection,
return BUS_RESULT_FALSE;
}
- if (!bus_driver_generate_introspect_string (&xml))
+ is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
+
+ if (!bus_driver_generate_introspect_string (&xml, is_canonical_path, message))
goto oom;
v_STRING = _dbus_string_get_const_data (&xml);
@@ -2587,38 +2839,6 @@ bus_driver_handle_introspect (DBusConnection *connection,
return BUS_RESULT_FALSE;
}
-/*
- * Set @error and return FALSE if the message is not directed to the
- * dbus-daemon by its canonical object path. This is hardening against
- * system services with poorly-written security policy files, which
- * might allow sending dangerously broad equivalence classes of messages
- * such as "anything with this assumed-to-be-safe object path".
- *
- * dbus-daemon is unusual in that it normally ignores the object path
- * of incoming messages; we need to keep that behaviour for the "read"
- * read-only method calls like GetConnectionUnixUser for backwards
- * compatibility, but it seems safer to be more restrictive for things
- * intended to be root-only or privileged-developers-only.
- *
- * It is possible that there are other system services with the same
- * quirk as dbus-daemon.
- */
-dbus_bool_t
-bus_driver_check_message_is_for_us (DBusMessage *message,
- DBusError *error)
-{
- if (!dbus_message_has_path (message, DBUS_PATH_DBUS))
- {
- dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
- "Method '%s' is only available at the canonical object path '%s'",
- dbus_message_get_member (message), DBUS_PATH_DBUS);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
BusResult
bus_driver_handle_message (DBusConnection *connection,
BusTransaction *transaction,
@@ -2629,6 +2849,7 @@ bus_driver_handle_message (DBusConnection *connection,
const InterfaceHandler *ih;
const MessageHandler *mh;
dbus_bool_t found_interface = FALSE;
+ dbus_bool_t is_canonical_path;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -2637,6 +2858,15 @@ bus_driver_handle_message (DBusConnection *connection,
BusContext *context;
DBusConnection *systemd;
+ /* This is a directed signal, not a method call, so the log message
+ * is a little weird (it talks about "calling" ActivationFailure),
+ * but it's close enough */
+ if (!bus_driver_check_caller_is_privileged (connection,
+ transaction,
+ message,
+ error))
+ return BUS_RESULT_FALSE;
+
context = bus_connection_get_context (connection);
systemd = bus_driver_get_owner_of_name (connection,
"org.freedesktop.systemd1");
@@ -2655,6 +2885,14 @@ bus_driver_handle_message (DBusConnection *connection,
return BUS_RESULT_TRUE;
}
+ if (!bus_context_get_systemd_activation (context))
+ {
+ bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
+ "Ignoring unexpected ActivationFailure message "
+ "while not using systemd activation");
+ return BUS_RESULT_FALSE;
+ }
+
return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
}
@@ -2677,8 +2915,13 @@ bus_driver_handle_message (DBusConnection *connection,
_dbus_assert (dbus_message_get_sender (message) != NULL ||
strcmp (name, "Hello") == 0);
+ is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
+
for (ih = interface_handlers; ih->name != NULL; ih++)
{
+ if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
+ continue;
+
if (interface != NULL && strcmp (interface, ih->name) != 0)
continue;
@@ -2691,6 +2934,24 @@ bus_driver_handle_message (DBusConnection *connection,
_dbus_verbose ("Found driver handler for %s\n", name);
+ if ((mh->flags & METHOD_FLAG_PRIVILEGED) &&
+ !bus_driver_check_caller_is_privileged (connection, transaction,
+ message, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return BUS_RESULT_FALSE;
+ }
+
+ if (!(is_canonical_path || (mh->flags & METHOD_FLAG_ANY_PATH)))
+ {
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+ "Method '%s' is only available at the canonical object path '%s'",
+ dbus_message_get_member (message), DBUS_PATH_DBUS);
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return BUS_RESULT_FALSE;
+ }
+
if (!dbus_message_has_signature (message, mh->in_args))
{
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -2741,3 +3002,298 @@ bus_driver_remove_connection (DBusConnection *connection)
* with the bus driver.
*/
}
+
+static dbus_bool_t
+features_getter (BusContext *context,
+ DBusMessageIter *variant_iter)
+{
+ DBusMessageIter arr_iter;
+
+ if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &arr_iter))
+ return FALSE;
+
+ if (bus_apparmor_enabled ())
+ {
+ const char *s = "AppArmor";
+
+ if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
+ goto abandon;
+ }
+
+ if (bus_selinux_enabled ())
+ {
+ const char *s = "SELinux";
+
+ if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
+ goto abandon;
+ }
+
+ if (bus_context_get_systemd_activation (context))
+ {
+ const char *s = "SystemdActivation";
+
+ if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
+ goto abandon;
+ }
+
+ return dbus_message_iter_close_container (variant_iter, &arr_iter);
+
+abandon:
+ dbus_message_iter_abandon_container (variant_iter, &arr_iter);
+ return FALSE;
+}
+
+static dbus_bool_t
+interfaces_getter (BusContext *context,
+ DBusMessageIter *variant_iter)
+{
+ DBusMessageIter arr_iter;
+ const InterfaceHandler *ih;
+
+ if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &arr_iter))
+ return FALSE;
+
+ for (ih = interface_handlers; ih->name != NULL; ih++)
+ {
+ if (ih->flags & INTERFACE_FLAG_UNINTERESTING)
+ continue;
+
+ if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING,
+ &ih->name))
+ goto abandon;
+ }
+
+ return dbus_message_iter_close_container (variant_iter, &arr_iter);
+
+abandon:
+ dbus_message_iter_abandon_container (variant_iter, &arr_iter);
+ return FALSE;
+}
+
+static const InterfaceHandler *
+bus_driver_find_interface (const char *name,
+ dbus_bool_t canonical_path,
+ DBusError *error)
+{
+ const InterfaceHandler *ih;
+
+ for (ih = interface_handlers; ih->name != NULL; ih++)
+ {
+ if (!(canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
+ continue;
+
+ if (strcmp (name, ih->name) == 0)
+ return ih;
+ }
+
+ dbus_set_error (error, DBUS_ERROR_UNKNOWN_INTERFACE,
+ "Interface \"%s\" not found", name);
+ return NULL;
+}
+
+static const PropertyHandler *
+interface_handler_find_property (const InterfaceHandler *ih,
+ const char *name,
+ DBusError *error)
+{
+ const PropertyHandler *ph;
+
+ for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
+ {
+ if (strcmp (name, ph->name) == 0)
+ return ph;
+ }
+
+ dbus_set_error (error, DBUS_ERROR_UNKNOWN_PROPERTY,
+ "Property \"%s.%s\" not found", ih->name, name);
+ return NULL;
+}
+
+static dbus_bool_t
+bus_driver_handle_get (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ const InterfaceHandler *ih;
+ const PropertyHandler *handler;
+ const char *iface;
+ const char *prop;
+ BusContext *context;
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+ DBusMessageIter var_iter;
+
+ /* The message signature has already been checked for us,
+ * so this should always succeed. */
+ if (!dbus_message_get_args (message, error,
+ DBUS_TYPE_STRING, &iface,
+ DBUS_TYPE_STRING, &prop,
+ DBUS_TYPE_INVALID))
+ return FALSE;
+
+ /* We only implement Properties on /org/freedesktop/DBus so far. */
+ ih = bus_driver_find_interface (iface, TRUE, error);
+
+ if (ih == NULL)
+ return FALSE;
+
+ handler = interface_handler_find_property (ih, prop, error);
+
+ if (handler == NULL)
+ return FALSE;
+
+ context = bus_transaction_get_context (transaction);
+
+ reply = dbus_message_new_method_return (message);
+
+ if (reply == NULL)
+ goto oom;
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT,
+ handler->type, &var_iter))
+ goto oom;
+
+ if (!handler->getter (context, &var_iter))
+ {
+ dbus_message_iter_abandon_container (&iter, &var_iter);
+ goto oom;
+ }
+
+ if (!dbus_message_iter_close_container (&iter, &var_iter))
+ goto oom;
+
+ if (!bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+ return TRUE;
+
+oom:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ BUS_SET_OOM (error);
+ return FALSE;
+}
+
+static dbus_bool_t
+bus_driver_handle_get_all (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ const InterfaceHandler *ih;
+ const char *iface;
+ const PropertyHandler *ph;
+ DBusMessageIter reply_iter;
+ DBusMessageIter array_iter;
+ BusContext *context;
+ DBusMessage *reply = NULL;
+
+ /* The message signature has already been checked for us,
+ * so this should always succeed. */
+ if (!dbus_message_get_args (message, error,
+ DBUS_TYPE_STRING, &iface,
+ DBUS_TYPE_INVALID))
+ return FALSE;
+
+ /* We only implement Properties on /org/freedesktop/DBus so far. */
+ ih = bus_driver_find_interface (iface, TRUE, error);
+
+ if (ih == NULL)
+ return FALSE;
+
+ context = bus_transaction_get_context (transaction);
+
+ reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
+
+ if (reply == NULL)
+ goto oom;
+
+ for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
+ {
+ DBusMessageIter entry_iter;
+ DBusMessageIter var_iter;
+
+ if (!_dbus_asv_open_entry (&array_iter, &entry_iter, ph->name,
+ ph->type, &var_iter))
+ goto oom_abandon_message;
+
+ if (!ph->getter (context, &var_iter))
+ {
+ _dbus_asv_abandon_entry (&array_iter, &entry_iter, &var_iter);
+ goto oom_abandon_message;
+ }
+
+ if (!_dbus_asv_close_entry (&array_iter, &entry_iter, &var_iter))
+ goto oom_abandon_message;
+ }
+
+ if (!_dbus_asv_close (&reply_iter, &array_iter))
+ goto oom;
+
+ if (!bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+ return TRUE;
+
+oom_abandon_message:
+ _dbus_asv_abandon (&reply_iter, &array_iter);
+ /* fall through */
+oom:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ BUS_SET_OOM (error);
+ return FALSE;
+}
+
+static dbus_bool_t
+bus_driver_handle_set (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ const InterfaceHandler *ih;
+ const char *iface;
+ const char *prop;
+ const PropertyHandler *handler;
+ DBusMessageIter iter;
+
+ /* We already checked this in bus_driver_handle_message() */
+ _dbus_assert (dbus_message_has_signature (message, "ssv"));
+
+ if (!dbus_message_iter_init (message, &iter))
+ _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
+
+ dbus_message_iter_get_basic (&iter, &iface);
+
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
+
+ dbus_message_iter_get_basic (&iter, &prop);
+
+ /* We only implement Properties on /org/freedesktop/DBus so far. */
+ ih = bus_driver_find_interface (iface, TRUE, error);
+
+ if (ih == NULL)
+ return FALSE;
+
+ handler = interface_handler_find_property (ih, prop, error);
+
+ if (handler == NULL)
+ return FALSE;
+
+ /* We don't implement any properties that can be set yet. */
+ dbus_set_error (error, DBUS_ERROR_PROPERTY_READ_ONLY,
+ "Property '%s.%s' cannot be set", iface, prop);
+ return FALSE;
+}
diff --git a/bus/driver.h b/bus/driver.h
index 3ff4ff15..183c28b9 100644
--- a/bus/driver.h
+++ b/bus/driver.h
@@ -27,6 +27,13 @@
#include <dbus/dbus.h>
#include "connection.h"
+typedef enum
+{
+ BUS_DRIVER_FOUND_SELF,
+ BUS_DRIVER_FOUND_PEER,
+ BUS_DRIVER_FOUND_ERROR,
+} BusDriverFound;
+
void bus_driver_remove_connection (DBusConnection *connection);
BusResult bus_driver_handle_message (DBusConnection *connection,
BusTransaction *transaction,
@@ -45,8 +52,19 @@ dbus_bool_t bus_driver_send_service_owner_changed (const char *service_name
const char *new_owner,
BusTransaction *transaction,
DBusError *error);
-dbus_bool_t bus_driver_generate_introspect_string (DBusString *xml);
-dbus_bool_t bus_driver_check_message_is_for_us (DBusMessage *message,
- DBusError *error);
+dbus_bool_t bus_driver_generate_introspect_string (DBusString *xml,
+ dbus_bool_t canonical_path,
+ DBusMessage *message);
+
+BusDriverFound bus_driver_get_conn_helper (DBusConnection *connection,
+ DBusMessage *message,
+ const char *what_we_want,
+ const char **name_p,
+ DBusConnection **peer_conn_p,
+ DBusError *error);
+dbus_bool_t bus_driver_send_ack_reply (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error);
#endif /* BUS_DRIVER_H */
diff --git a/bus/main.c b/bus/main.c
index 28ea39a1..d5d6510a 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -45,6 +45,9 @@
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
+#ifdef DBUS_UNIX
+#include <dbus/dbus-sysdeps-unix.h>
+#endif
static BusContext *context;
@@ -67,6 +70,10 @@ typedef enum
static void
signal_handler (int sig)
{
+ /* Signal handlers that might set errno must save and restore the errno
+ * that the interrupted function might have been relying on. */
+ int saved_errno = errno;
+
switch (sig)
{
case SIGHUP:
@@ -128,10 +135,19 @@ signal_handler (int sig)
}
}
break;
+
+ default:
+ /* can't happen unless this signal handler gets used for a wrong
+ * signal, but keep -Wswitch-default happy */
+ break;
}
+
+ errno = saved_errno;
}
#endif /* DBUS_UNIX */
+static void usage (void) _DBUS_GNUC_NORETURN;
+
static void
usage (void)
{
@@ -146,6 +162,9 @@ usage (void)
" [--introspect]"
" [--address=ADDRESS]"
" [--nopidfile]"
+ " [--nosyslog]"
+ " [--syslog]"
+ " [--syslog-only]"
" [--nofork]"
#ifdef DBUS_UNIX
" [--fork]"
@@ -155,6 +174,8 @@ usage (void)
exit (1);
}
+static void version (void) _DBUS_GNUC_NORETURN;
+
static void
version (void)
{
@@ -166,6 +187,8 @@ version (void)
exit (0);
}
+static void introspect (void) _DBUS_GNUC_NORETURN;
+
static void
introspect (void)
{
@@ -175,7 +198,7 @@ introspect (void)
if (!_dbus_string_init (&xml))
goto oom;
- if (!bus_driver_generate_introspect_string (&xml))
+ if (!bus_driver_generate_introspect_string (&xml, TRUE, NULL))
{
_dbus_string_free (&xml);
goto oom;
@@ -187,7 +210,7 @@ introspect (void)
exit (0);
oom:
- _dbus_warn ("Can not introspect - Out of memory\n");
+ _dbus_warn ("Can not introspect - Out of memory");
exit (1);
}
@@ -256,7 +279,7 @@ handle_reload_watch (DBusWatch *watch,
if ((reload_pipe[RELOAD_READ_END].fd > 0) &&
_dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
{
- _dbus_warn ("Couldn't read from reload pipe.\n");
+ _dbus_warn ("Couldn't read from reload pipe.");
close_reload_pipe (&watch);
return TRUE;
}
@@ -282,7 +305,7 @@ handle_reload_watch (DBusWatch *watch,
_DBUS_ASSERT_ERROR_IS_SET (&error);
_dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
- _dbus_warn ("Unable to reload configuration: %s\n",
+ _dbus_warn ("Unable to reload configuration: %s",
error.message);
dbus_error_free (&error);
}
@@ -323,7 +346,7 @@ setup_reload_pipe (DBusLoop *loop)
if (!_dbus_socketpair (&reload_pipe[0], &reload_pipe[1],
TRUE, &error))
{
- _dbus_warn ("Unable to create reload pipe: %s\n",
+ _dbus_warn ("Unable to create reload pipe: %s",
error.message);
dbus_error_free (&error);
exit (1);
@@ -335,7 +358,7 @@ setup_reload_pipe (DBusLoop *loop)
if (watch == NULL)
{
- _dbus_warn ("Unable to create reload watch: %s\n",
+ _dbus_warn ("Unable to create reload watch: %s",
error.message);
dbus_error_free (&error);
exit (1);
@@ -343,7 +366,7 @@ setup_reload_pipe (DBusLoop *loop)
if (!_dbus_loop_add_watch (loop, watch))
{
- _dbus_warn ("Unable to add reload watch to main loop: %s\n",
+ _dbus_warn ("Unable to add reload watch to main loop: %s",
error.message);
dbus_error_free (&error);
exit (1);
@@ -382,6 +405,27 @@ main (int argc, char **argv)
dbus_bool_t print_address;
dbus_bool_t print_pid;
BusContextFlags flags;
+#ifdef DBUS_UNIX
+ const char *error_str;
+
+ /* Redirect stdin from /dev/null since we will never need it, and
+ * redirect stdout and stderr to /dev/null if not already open.
+ *
+ * We should do this as the very first thing, to ensure that when we
+ * create other file descriptors (for example for epoll, inotify or
+ * a socket), they never get assigned as fd 0, 1 or 2. If they were,
+ * which could happen if our caller had (incorrectly) closed those
+ * standard fds, they'd get closed when we daemonize - for example,
+ * closing our listening socket would stop us listening, and closing
+ * a Linux epoll socket would cause the main loop to fail. */
+ if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
+ {
+ fprintf (stderr,
+ "dbus-daemon: fatal error setting up standard fds: %s: %s\n",
+ error_str, _dbus_strerror (errno));
+ return 1;
+ }
+#endif
if (!_dbus_string_init (&config_file))
return 1;
@@ -420,6 +464,21 @@ main (int argc, char **argv)
{
introspect ();
}
+ else if (strcmp (arg, "--nosyslog") == 0)
+ {
+ flags &= ~BUS_CONTEXT_FLAG_SYSLOG_ALWAYS;
+ flags |= BUS_CONTEXT_FLAG_SYSLOG_NEVER;
+ }
+ else if (strcmp (arg, "--syslog") == 0)
+ {
+ flags &= ~BUS_CONTEXT_FLAG_SYSLOG_NEVER;
+ flags |= BUS_CONTEXT_FLAG_SYSLOG_ALWAYS;
+ }
+ else if (strcmp (arg, "--syslog-only") == 0)
+ {
+ flags &= ~BUS_CONTEXT_FLAG_SYSLOG_NEVER;
+ flags |= (BUS_CONTEXT_FLAG_SYSLOG_ALWAYS|BUS_CONTEXT_FLAG_SYSLOG_ONLY);
+ }
else if (strcmp (arg, "--nofork") == 0)
{
flags &= ~BUS_CONTEXT_FLAG_FORK_ALWAYS;
@@ -444,14 +503,14 @@ main (int argc, char **argv)
{
check_two_config_files (&config_file, "system");
- if (!_dbus_append_system_config_file (&config_file))
+ if (!_dbus_get_system_config_file (&config_file))
exit (1);
}
else if (strcmp (arg, "--session") == 0)
{
check_two_config_files (&config_file, "session");
- if (!_dbus_append_session_config_file (&config_file))
+ if (!_dbus_get_session_config_file (&config_file))
exit (1);
}
else if (strstr (arg, "--config-file=") == arg)
@@ -620,13 +679,13 @@ main (int argc, char **argv)
if (!bus_selinux_pre_init ())
{
- _dbus_warn ("SELinux pre-initialization failed\n");
+ _dbus_warn ("SELinux pre-initialization failed");
exit (1);
}
if (!bus_apparmor_pre_init ())
{
- _dbus_warn ("AppArmor pre-initialization failed: out of memory\n");
+ _dbus_warn ("AppArmor pre-initialization failed: out of memory");
exit (1);
}
@@ -636,9 +695,10 @@ main (int argc, char **argv)
_dbus_string_get_length(&address) > 0 ? &address : NULL,
&error);
_dbus_string_free (&config_file);
+ _dbus_string_free (&address);
if (context == NULL)
{
- _dbus_warn ("Failed to start message bus: %s\n",
+ _dbus_warn ("Failed to start message bus: %s",
error.message);
dbus_error_free (&error);
exit (1);
diff --git a/bus/messagebus-config.in b/bus/messagebus-config.in
deleted file mode 100644
index 39459dcb..00000000
--- a/bus/messagebus-config.in
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/bin/sh
-#
-# messagebus-config, Copyright 2009 Yaakov Selkowitz
-#
-# This file is part of the Cygwin port of dbus.
-
-# ======================================================================
-# Initialization
-# ======================================================================
-PROGNAME=$(basename $0)
-_tdir=$(dirname $0)
-PROGDIR=$(cd $_tdir && pwd)
-
-CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
-
-# Subdirectory where the new package is being installed
-PREFIX=@prefix@
-
-# Directory where the config files are stored
-SYSCONFDIR=@sysconfdir@/dbus-1
-DEVDIR=/dev
-LOGDIR=/var/log
-RUNDIR=$(dirname @DBUS_SYSTEM_PID_FILE@)
-SOCKDIR=$(dirname @DBUS_SYSTEM_SOCKET@)
-
-source ${CSIH_SCRIPT}
-
-# ======================================================================
-# Routine: install_service
-# Install messagebus as a service
-# ======================================================================
-install_service() {
-
- if csih_is_nt
- then
-
- # Check if messagebus is installed and remove on user request.
- if cygrunsrv -Q messagebus > /dev/null 2>&1
- then
- csih_warning "The messagebus service is already installed."
- echo
- if csih_request "Do you want to reinstall it with different args?"
- then
- cygrunsrv -E messagebus
- cygrunsrv -R messagebus
- fi
- fi
-
- # Install messagebus service if it is not already installed
- if ! cygrunsrv -Q messagebus > /dev/null 2>&1
- then
- echo
- csih_warning "The following function requires administrator privileges!"
- if csih_request "Do you want to install messagebus as service?"
- then
- if cygrunsrv -I messagebus -d "CYGWIN D-Bus system service" -p @EXPANDED_BINDIR@/dbus-daemon -a "--nofork --system"
- then
- echo
- csih_inform "The messagebus service has been installed under the LocalSystem"
- csih_inform "account (also known as SYSTEM). To start the service now, call"
- csih_inform "\`net start messagebus' or \`cygrunsrv -S messagebus'. Otherwise, it"
- csih_inform "will start automatically after the next reboot."
- echo
- csih_inform "Check ${SYSCONFDIR}/system.conf first, if it suits your needs."
- fi
- fi # user allowed us to install messagebus
- fi # messagebus already installed
- fi # csih_is_nt
-} # --- End of install_service --- #
-
-
-# ======================================================================
-# Main Entry Point
-# ======================================================================
-
-
-# Check how the script has been started. If
-# (1) it has been started by giving the full path and
-# that path is /etc/postinstall, OR
-# (2) Otherwise, if the environment variable
-# CONFIG_AUTO_ANSWER_NO is set
-# then set auto_answer to "no". This allows automatic
-# creation of the config files in /etc w/o overwriting
-# them if they already exist. In both cases, color
-# escape sequences are suppressed, so as to prevent
-# cluttering setup's logfiles.
-if [ "$PROGDIR" = "/etc/postinstall" ]
-then
- csih_auto_answer="no"
- csih_disable_color
-fi
-if [ -n "${CONFIG_AUTO_ANSWER_NO}" ]
-then
- csih_auto_answer="no"
- csih_disable_color
-fi
-
-
-# ======================================================================
-# Parse options
-# ======================================================================
-while :
-do
- case $# in
- 0)
- break
- ;;
- esac
-
- option=$1
- shift
-
- case "$option" in
- -d | --debug )
- set -x
- csih_trace_on
- ;;
-
- -y | --yes )
- csih_auto_answer=yes
- ;;
-
- -n | --no )
- csih_auto_answer=no
- ;;
-
- *)
- echo "usage: ${PROGNAME} [OPTION]..."
- echo
- echo "This script creates a basic messagebus configuration."
- echo
- echo "Options:"
- echo " --debug -d Enable shell's debug output."
- echo " --yes -y Answer all questions with \"yes\" automatically."
- echo " --no -n Answer all questions with \"no\" automatically."
- echo
- exit 1
- ;;
-
- esac
-done
-
-# ======================================================================
-# Action!
-# ======================================================================
-
-# Check for ${SYSCONFDIR} directory
-csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
-chmod 775 "${SYSCONFDIR}"
-setfacl -m u:system:rwx "${SYSCONFDIR}"
-
-# Check for ${DEVDIR} directory
-csih_make_dir "${DEVDIR}" "Syslogging using messagebus will not work."
-chmod 775 "${DEVDIR}"
-setfacl -m u:system:rwx "${DEVDIR}"
-
-# Check for ${LOGDIR} directory
-csih_make_dir "${LOGDIR}" "Syslogging using messagebus will not work."
-chmod 775 "${LOGDIR}"
-setfacl -m u:system:rwx "${LOGDIR}"
-
-# Check for ${RUNDIR} directory
-csih_make_dir "${RUNDIR}" "PID files of running processes will not be created."
-chmod 775 "${RUNDIR}"
-setfacl -m u:system:rwx "${RUNDIR}"
-
-# Check for ${SOCKDIR} directory
-csih_make_dir "${SOCKDIR}" "SOCKET files of running processes will not be created."
-chmod 775 "${SOCKDIR}"
-setfacl -m u:system:rwx "${SOCKDIR}"
-
-# maybe: csih_auto_answer=no will skip,
-# interactive user will get a chance to override
-install_service
-
-
-echo
-echo "Configuration finished. Have fun!"
diff --git a/bus/messagebus.in b/bus/messagebus.in
deleted file mode 100755
index 3e2ee07a..00000000
--- a/bus/messagebus.in
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/sh
-#
-# messagebus: The D-BUS systemwide message bus
-#
-# chkconfig: 345 22 85
-# description: This is a daemon which broadcasts notifications of system events \
-# and other messages. See http://www.freedesktop.org/software/dbus/
-#
-# processname: dbus-daemon
-# pidfile: @DBUS_SYSTEM_PID_FILE@
-#
-### BEGIN INIT INFO
-# Provides: messagebus
-# Required-Start: $syslog $local_fs
-# Required-Stop: $syslog $local_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: The D-Bus systemwide message bus
-# Description: This is a daemon which broadcasts notifications of system
-# events and other messages. See http://www.freedesktop.org/software/dbus
-### END INIT INFO
-
-# Sanity checks.
-[ -x @EXPANDED_BINDIR@/dbus-daemon ] || exit 0
-
-# Source function library.
-. @EXPANDED_SYSCONFDIR@/rc.d/init.d/functions
-
-# so we can rearrange this easily
-processname=dbus-daemon
-servicename=messagebus
-
-RETVAL=0
-
-start() {
- echo -n $"Starting system message bus: "
- if [ -x @EXPANDED_BINDIR@/dbus-uuidgen ] ; then
- @EXPANDED_BINDIR@/dbus-uuidgen --ensure
- fi
-
- daemon --check $servicename $processname --system
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch @EXPANDED_LOCALSTATEDIR@/lock/subsys/$servicename
-}
-
-stop() {
- echo -n $"Stopping system message bus: "
-
- ## we don't want to kill all the per-user $processname, we want
- ## to use the pid file *only*; because we use the fake nonexistent
- ## program name "$servicename" that should be safe-ish
- killproc $servicename -TERM
- RETVAL=$?
- echo
- if [ $RETVAL -eq 0 ]; then
- rm -f @EXPANDED_LOCALSTATEDIR@/lock/subsys/$servicename
- rm -f @DBUS_SYSTEM_PID_FILE@
- fi
-}
-
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status $servicename
- RETVAL=$?
- ;;
- restart)
- stop
- start
- ;;
- condrestart)
- if [ -f @EXPANDED_LOCALSTATEDIR@/lock/subsys/$servicename ]; then
- stop
- start
- fi
- ;;
- reload)
- echo "Message bus can't reload its configuration, you have to restart it"
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
- ;;
-esac
-exit $RETVAL
diff --git a/bus/policy.c b/bus/policy.c
index 24c0f06d..6e642951 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -30,6 +30,7 @@
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-internals.h>
+#include <dbus/dbus-message-internal.h>
BusPolicyRule*
bus_policy_rule_new (BusPolicyRuleType type,
@@ -71,6 +72,8 @@ bus_policy_rule_new (BusPolicyRuleType type,
break;
case BUS_POLICY_RULE_OWN:
break;
+ default:
+ _dbus_assert_not_reached ("invalid rule");
}
return rule;
@@ -118,6 +121,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
break;
case BUS_POLICY_RULE_GROUP:
break;
+ default:
+ _dbus_assert_not_reached ("invalid rule");
}
dbus_free (rule->privilege);
@@ -264,6 +269,9 @@ add_list_to_client (DBusList **list,
if (!bus_client_policy_append_rule (client, rule))
return FALSE;
break;
+
+ default:
+ _dbus_assert_not_reached ("invalid rule");
}
}
@@ -836,8 +844,11 @@ bus_client_policy_optimize (BusClientPolicy *policy)
remove_preceding =
rule->d.own.service_name == NULL;
break;
+
+ /* The other rule types don't appear in this list */
case BUS_POLICY_RULE_USER:
case BUS_POLICY_RULE_GROUP:
+ default:
_dbus_assert_not_reached ("invalid rule");
break;
}
@@ -1090,7 +1101,27 @@ bus_client_policy_check_can_send (DBusConnection *sender,
continue;
}
}
-
+
+ if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
+ {
+ if (dbus_message_get_destination (message) == NULL &&
+ dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ /* it's a broadcast */
+ if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
+ {
+ _dbus_verbose (" (policy) skipping rule because message is a broadcast\n");
+ continue;
+ }
+ }
+ /* else it isn't a broadcast: there is some destination */
+ else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
+ {
+ _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n");
+ continue;
+ }
+ }
+
if (rule->d.send.destination != NULL)
{
if (!rule->d.send.destination_prefix)
@@ -1176,6 +1207,20 @@ bus_client_policy_check_can_send (DBusConnection *sender,
}
}
+ if (rule->d.send.min_fds > 0 ||
+ rule->d.send.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
+ {
+ unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
+
+ if (n_fds < rule->d.send.min_fds || n_fds > rule->d.send.max_fds)
+ {
+ _dbus_verbose (" (policy) skipping rule because message has %u fds "
+ "and that is outside range [%u,%u]",
+ n_fds, rule->d.send.min_fds, rule->d.send.max_fds);
+ continue;
+ }
+ }
+
/* Use this rule */
switch (rule->access)
{
@@ -1421,7 +1466,22 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
}
}
}
-
+
+ if (rule->d.receive.min_fds > 0 ||
+ rule->d.receive.max_fds < DBUS_MAXIMUM_MESSAGE_UNIX_FDS)
+ {
+ unsigned int n_fds = _dbus_message_get_n_unix_fds (message);
+
+ if (n_fds < rule->d.receive.min_fds || n_fds > rule->d.receive.max_fds)
+ {
+ _dbus_verbose (" (policy) skipping rule because message has %u fds "
+ "and that is outside range [%u,%u]",
+ n_fds, rule->d.receive.min_fds,
+ rule->d.receive.max_fds);
+ continue;
+ }
+ }
+
/* Use this rule */
switch (rule->access)
{
diff --git a/bus/policy.h b/bus/policy.h
index 951ece1f..be704e3b 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -47,6 +47,13 @@ typedef enum
BUS_POLICY_RULE_ACCESS_CHECK
} BusPolicyRuleAccess;
+typedef enum
+{
+ BUS_POLICY_TRISTATE_ANY = 0,
+ BUS_POLICY_TRISTATE_FALSE,
+ BUS_POLICY_TRISTATE_TRUE
+} BusPolicyTristate;
+
/** determines whether the rule affects a connection, or some global item */
#define BUS_POLICY_RULE_IS_PER_CLIENT(rule) (!((rule)->type == BUS_POLICY_RULE_USER || \
(rule)->type == BUS_POLICY_RULE_GROUP))
@@ -72,10 +79,13 @@ struct BusPolicyRule
char *member;
char *error;
char *destination;
+ unsigned int max_fds;
+ unsigned int min_fds;
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
unsigned int log : 1;
unsigned int destination_prefix : 1;
+ unsigned int broadcast : 2; /**< really a BusPolicyTristate */
} send;
struct
@@ -88,6 +98,8 @@ struct BusPolicyRule
char *member;
char *error;
char *origin;
+ unsigned int max_fds;
+ unsigned int min_fds;
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
} receive;
diff --git a/bus/rc.messagebus.in b/bus/rc.messagebus.in
deleted file mode 100644
index c52ca777..00000000
--- a/bus/rc.messagebus.in
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-#
-# messagebus: The D-BUS systemwide message bus
-#
-# chkconfig: 345 97 03
-# description: This is a daemon which broadcasts notifications of system events \
-# and other messages. See http://www.freedesktop.org/software/dbus/
-#
-# processname: dbus-daemon
-# pidfile: @DBUS_SYSTEM_PID_FILE@
-#
-
-# Sanity checks.
-#[ -x @EXPANDED_BINDIR@/dbus-daemon ] || exit 0
-
-# Source function library.
-#. @EXPANDED_SYSCONFDIR@/rc.d/init.d/functions
-
-# so we can rearrange this easily
-#processname=dbus-daemon
-#servicename=messagebus
-
-#RETVAL=0
-
-start() {
- echo "Starting system message bus"
- if [ -x @EXPANDED_BINDIR@/dbus-uuidgen ] ; then
- @EXPANDED_BINDIR@/dbus-uuidgen --ensure
- fi
-
- if [ -x @EXPANDED_BINDIR@/dbus-daemon ];then
- @EXPANDED_BINDIR@/dbus-daemon --system
- fi
- #daemon --check $servicename $processname --system
- #RETVAL=$?
- #echo
- #[ $RETVAL -eq 0 ] && touch @EXPANDED_LOCALSTATEDIR@/lock/subsys/$servicename
-}
-
-stop() {
- echo "Stopping system message bus"
-
- ## we don't want to kill all the per-user $processname, we want
- ## to use the pid file *only*; because we use the fake nonexistent
- ## program name "$servicename" that should be safe-ish
- killall dbus-daemon
- #RETVAL=$?
- #echo
- #if [ $RETVAL -eq 0 ]; then
- # rm -f @EXPANDED_LOCALSTATEDIR@/lock/subsys/$servicename
- # rm -f @DBUS_SYSTEM_PID_FILE@
- #fi
-}
-
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status $servicename
- RETVAL=$?
- ;;
- restart)
- stop
- start
- ;;
- reload)
- echo "Message bus can't reload its configuration, you have to restart it"
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|reload}"
- ;;
-esac
-exit $RETVAL
diff --git a/bus/selinux.c b/bus/selinux.c
index be66d4f0..d09afb4b 100644
--- a/bus/selinux.c
+++ b/bus/selinux.c
@@ -71,7 +71,7 @@ static security_id_t bus_sid = SECSID_WILD;
static pthread_t avc_notify_thread;
/* Prototypes for AVC callback functions. */
-static void log_callback (const char *fmt, ...);
+static void log_callback (const char *fmt, ...) _DBUS_GNUC_PRINTF (1, 2);
static void log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft);
static void *avc_create_thread (void (*run) (void));
static void avc_stop_thread (void *thread);
@@ -146,7 +146,9 @@ log_callback (const char *fmt, ...)
vsyslog (LOG_USER | LOG_INFO, fmt, ap);
+#ifdef HAVE_LIBAUDIT
out:
+#endif
va_end(ap);
}
@@ -203,7 +205,7 @@ avc_create_thread (void (*run) (void))
rc = pthread_create (&avc_notify_thread, NULL, (void *(*) (void *)) run, NULL);
if (rc != 0)
{
- _dbus_warn ("Failed to start AVC thread: %s\n", _dbus_strerror (rc));
+ _dbus_warn ("Failed to start AVC thread: %s", _dbus_strerror (rc));
exit (1);
}
return &avc_notify_thread;
@@ -225,7 +227,7 @@ avc_alloc_lock (void)
avc_mutex = dbus_new (pthread_mutex_t, 1);
if (avc_mutex == NULL)
{
- _dbus_warn ("Could not create mutex: %s\n", _dbus_strerror (errno));
+ _dbus_warn ("Could not create mutex: %s", _dbus_strerror (errno));
exit (1);
}
pthread_mutex_init (avc_mutex, NULL);
@@ -270,6 +272,19 @@ bus_selinux_enabled (void)
#endif /* HAVE_SELINUX */
}
+BusSELinuxID*
+bus_selinux_get_self (void)
+{
+#ifdef HAVE_SELINUX
+ if(bus_selinux_enabled ())
+ return BUS_SID_FROM_SELINUX (bus_sid);
+ else
+ return NULL;
+#else
+ return NULL;
+#endif /* HAVE_SELINUX */
+}
+
/**
* Do early initialization; determine whether SELinux is enabled.
*/
@@ -284,7 +299,7 @@ bus_selinux_pre_init (void)
r = is_selinux_enabled ();
if (r < 0)
{
- _dbus_warn ("Could not tell if SELinux is enabled: %s\n",
+ _dbus_warn ("Could not tell if SELinux is enabled: %s",
_dbus_strerror (errno));
return FALSE;
}
@@ -337,7 +352,7 @@ bus_selinux_full_init (void)
if (selinux_set_mapping (dbus_map) < 0)
{
- _dbus_warn ("Failed to set up security class mapping (selinux_set_mapping():%s).\n",
+ _dbus_warn ("Failed to set up security class mapping (selinux_set_mapping():%s).",
strerror (errno));
return FALSE;
}
@@ -345,7 +360,7 @@ bus_selinux_full_init (void)
avc_entry_ref_init (&aeref);
if (avc_init ("avc", &mem_cb, &log_cb, &thread_cb, &lock_cb) < 0)
{
- _dbus_warn ("Failed to start Access Vector Cache (AVC).\n");
+ _dbus_warn ("Failed to start Access Vector Cache (AVC).");
return FALSE;
}
else
@@ -356,7 +371,7 @@ bus_selinux_full_init (void)
if (avc_add_callback (policy_reload_callback, AVC_CALLBACK_RESET,
NULL, NULL, 0, 0) < 0)
{
- _dbus_warn ("Failed to add policy reload callback: %s\n",
+ _dbus_warn ("Failed to add policy reload callback: %s",
_dbus_strerror (errno));
avc_destroy ();
return FALSE;
@@ -387,37 +402,6 @@ bus_selinux_full_init (void)
}
/**
- * Decrement SID reference count.
- *
- * @param sid the SID to decrement
- */
-void
-bus_selinux_id_unref (BusSELinuxID *sid)
-{
-#ifdef HAVE_SELINUX
- if (!selinux_enabled)
- return;
-
- _dbus_assert (sid != NULL);
-
- sidput (SELINUX_SID_FROM_BUS (sid));
-#endif /* HAVE_SELINUX */
-}
-
-void
-bus_selinux_id_ref (BusSELinuxID *sid)
-{
-#ifdef HAVE_SELINUX
- if (!selinux_enabled)
- return;
-
- _dbus_assert (sid != NULL);
-
- sidget (SELINUX_SID_FROM_BUS (sid));
-#endif /* HAVE_SELINUX */
-}
-
-/**
* Determine if the SELinux security policy allows the given sender
* security context to go to the given recipient security context.
* This function determines if the requested permissions are to be
@@ -448,7 +432,7 @@ bus_selinux_check (BusSELinuxID *sender_sid,
if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid),
override_sid ?
SELINUX_SID_FROM_BUS (override_sid) :
- SELINUX_SID_FROM_BUS (bus_sid),
+ bus_sid,
target_class, requested, &aeref, auxdata) < 0)
{
switch (errno)
@@ -773,7 +757,7 @@ bus_selinux_init_connection_id (DBusConnection *connection,
"Error getting SID from context \"%s\": %s\n",
con, _dbus_strerror (errno));
- _dbus_warn ("Error getting SID from context \"%s\": %s\n",
+ _dbus_warn ("Error getting SID from context \"%s\": %s",
con, _dbus_strerror (errno));
freecon (con);
@@ -787,21 +771,6 @@ bus_selinux_init_connection_id (DBusConnection *connection,
#endif /* HAVE_SELINUX */
}
-
-/**
- * Function for freeing hash table data. These SIDs
- * should no longer be referenced.
- */
-static void
-bus_selinux_id_table_free_value (BusSELinuxID *sid)
-{
-#ifdef HAVE_SELINUX
- /* NULL sometimes due to how DBusHashTable works */
- if (sid)
- bus_selinux_id_unref (sid);
-#endif /* HAVE_SELINUX */
-}
-
/**
* Creates a new table mapping service names to security ID.
* A security ID is a "compiled" security context, a security
@@ -813,8 +782,7 @@ DBusHashTable*
bus_selinux_id_table_new (void)
{
return _dbus_hash_table_new (DBUS_HASH_STRING,
- (DBusFreeFunction) dbus_free,
- (DBusFreeFunction) bus_selinux_id_table_free_value);
+ (DBusFreeFunction) dbus_free, NULL);
}
/**
@@ -854,7 +822,7 @@ bus_selinux_id_table_insert (DBusHashTable *service_table,
return FALSE;
}
- _dbus_warn ("Error getting SID from context \"%s\": %s\n",
+ _dbus_warn ("Error getting SID from context \"%s\": %s",
(char *) service_context,
_dbus_strerror (errno));
goto out;
@@ -876,9 +844,6 @@ bus_selinux_id_table_insert (DBusHashTable *service_table,
retval = TRUE;
out:
- if (sid != SECSID_WILD)
- sidput (sid);
-
if (key)
dbus_free (key);
@@ -1013,7 +978,6 @@ bus_selinux_shutdown (void)
if (bus_sid != SECSID_WILD)
{
- sidput (bus_sid);
bus_sid = SECSID_WILD;
bus_avc_print_stats ();
diff --git a/bus/selinux.h b/bus/selinux.h
index 5252b189..a0383cdd 100644
--- a/bus/selinux.h
+++ b/bus/selinux.h
@@ -33,8 +33,7 @@ void bus_selinux_shutdown (void);
dbus_bool_t bus_selinux_enabled (void);
-void bus_selinux_id_ref (BusSELinuxID *sid);
-void bus_selinux_id_unref (BusSELinuxID *sid);
+BusSELinuxID *bus_selinux_get_self (void);
DBusHashTable* bus_selinux_id_table_new (void);
BusSELinuxID* bus_selinux_id_table_lookup (DBusHashTable *service_table,
diff --git a/bus/services.c b/bus/services.c
index 9e466d87..af0307c4 100644
--- a/bus/services.c
+++ b/bus/services.c
@@ -393,6 +393,7 @@ bus_registry_acquire_service (BusRegistry *registry,
BusActivation *activation;
BusSELinuxID *sid;
BusOwner *primary_owner;
+ int limit;
retval = BUS_RESULT_FALSE;
@@ -493,16 +494,25 @@ bus_registry_acquire_service (BusRegistry *registry,
goto out;
}
- if (bus_connection_get_n_services_owned (connection) >=
- bus_context_get_max_services_per_connection (registry->context))
+ limit = bus_context_get_max_services_per_connection (registry->context);
+
+ if (bus_connection_get_n_services_owned (connection) >= limit)
{
- dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ DBusError tmp_error;
+
+ dbus_error_init (&tmp_error);
+ dbus_set_error (&tmp_error, DBUS_ERROR_LIMITS_EXCEEDED,
"Connection \"%s\" (%s) is not allowed to own more services "
- "(increase limits in configuration file if required)",
+ "(increase limits in configuration file if required)"
+ "max_names_per_connection=%d)",
bus_connection_is_active (connection) ?
bus_connection_get_name (connection) :
"(inactive)",
- bus_connection_get_loginfo (connection));
+ bus_connection_get_loginfo (connection),
+ limit);
+ bus_context_log (registry->context, DBUS_SYSTEM_LOG_WARNING,
+ "%s", tmp_error.message);
+ dbus_move_error (&tmp_error, error);
goto out;
}
diff --git a/bus/signals.c b/bus/signals.c
index e8def9f7..6b7a464c 100644
--- a/bus/signals.c
+++ b/bus/signals.c
@@ -871,7 +871,7 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule,
else
{
dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
- "Key '%s' in match rule contains junk after argument number (%u). Only 'arg%upath' (for example) or 'arg0namespace' are valid", key, arg, arg);
+ "Key '%s' in match rule contains junk after argument number (%lu). Only 'arg%lupath' (for example) or 'arg0namespace' are valid", key, arg, arg);
goto failed;
}
}
@@ -889,7 +889,7 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule,
rule->args[arg] != NULL)
{
dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
- "Argument %d matched more than once in match rule\n", key);
+ "Argument %s matched more than once in match rule\n", key);
goto failed;
}
@@ -1887,9 +1887,18 @@ match_rule_matches (BusMatchRule *rule,
return FALSE;
if (addressed_recipient == NULL)
- {
- if (strcmp (rule->destination,
- DBUS_SERVICE_DBUS) != 0)
+ {
+ /* If the message is going to be delivered to the dbus-daemon
+ * itself, its destination will be "org.freedesktop.DBus",
+ * which we again match against the rule (see bus_dispatch()
+ * in bus/dispatch.c, which checks for o.fd.DBus first).
+ *
+ * If we are monitoring and we don't know who is going to receive
+ * the message (for instance because they haven't been activated yet),
+ * assume they will own the requested destination name and no other,
+ * and match the rule's destination against that.
+ */
+ if (strcmp (rule->destination, destination) != 0)
return FALSE;
}
else
@@ -2192,7 +2201,7 @@ check_parse (dbus_bool_t should_succeed,
if (should_succeed && rule == NULL)
{
- _dbus_warn ("Failed to parse: %s: %s: \"%s\"\n",
+ _dbus_warn ("Failed to parse: %s: %s: \"%s\"",
error.name, error.message,
_dbus_string_get_const_data (&str));
exit (1);
@@ -2200,7 +2209,7 @@ check_parse (dbus_bool_t should_succeed,
if (!should_succeed && rule != NULL)
{
- _dbus_warn ("Failed to fail to parse: \"%s\"\n",
+ _dbus_warn ("Failed to fail to parse: \"%s\"",
_dbus_string_get_const_data (&str));
exit (1);
}
@@ -2540,7 +2549,7 @@ test_equality (void)
if (!match_rule_equal (first, second))
{
- _dbus_warn ("rule %s and %s should have been equal\n",
+ _dbus_warn ("rule %s and %s should have been equal",
equality_tests[i].first,
equality_tests[i].second);
exit (1);
@@ -2553,7 +2562,9 @@ test_equality (void)
_dbus_assert (second_str != NULL);
_dbus_assert (strcmp (first_str, second_str) == 0);
first_reparsed = check_parse (TRUE, first_str);
+ _dbus_assert (first_reparsed != NULL);
second_reparsed = check_parse (TRUE, second_str);
+ _dbus_assert (second_reparsed != NULL);
_dbus_assert (match_rule_equal (first, first_reparsed));
_dbus_assert (match_rule_equal (second, second_reparsed));
bus_match_rule_unref (first_reparsed);
@@ -2572,10 +2583,11 @@ test_equality (void)
if (i != j)
{
second = check_parse (TRUE, equality_tests[j].second);
+ _dbus_assert (second != NULL);
if (match_rule_equal (first, second))
{
- _dbus_warn ("rule %s and %s should not have been equal\n",
+ _dbus_warn ("rule %s and %s should not have been equal",
equality_tests[i].first,
equality_tests[j].second);
exit (1);
@@ -2685,7 +2697,7 @@ check_matches (dbus_bool_t expected_to_match,
if (matched != expected_to_match)
{
- _dbus_warn ("Expected rule %s to %s message %d, failed\n",
+ _dbus_warn ("Expected rule %s to %s message %d, failed",
rule_text, expected_to_match ?
"match" : "not match", number);
exit (1);
@@ -2814,7 +2826,7 @@ test_path_match (int type,
if (matched != should_match)
{
_dbus_warn ("Expected rule %s to %s message "
- "with first arg %s of type '%c', failed\n",
+ "with first arg %s of type '%c', failed",
rule_text,
should_match ? "match" : "not match",
path,
diff --git a/bus/stats.c b/bus/stats.c
index 5312b96a..27422352 100644
--- a/bus/stats.c
+++ b/bus/stats.c
@@ -51,9 +51,6 @@ bus_stats_handle_get_stats (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!bus_driver_check_message_is_for_us (message, error))
- return FALSE;
-
context = bus_transaction_get_context (transaction);
connections = bus_context_get_connections (context);
@@ -123,40 +120,37 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
DBusMessage *message,
DBusError *error)
{
- const char *bus_name = NULL;
- DBusString bus_name_str;
+ BusDriverFound found;
DBusMessage *reply = NULL;
DBusMessageIter iter, arr_iter;
static dbus_uint32_t stats_serial = 0;
dbus_uint32_t in_messages, in_bytes, in_fds, in_peak_bytes, in_peak_fds;
dbus_uint32_t out_messages, out_bytes, out_fds, out_peak_bytes, out_peak_fds;
- BusRegistry *registry;
- BusService *service;
DBusConnection *stats_connection;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!bus_driver_check_message_is_for_us (message, error))
- return FALSE;
+ found = bus_driver_get_conn_helper (caller_connection, message,
+ "statistics", NULL, &stats_connection,
+ error);
- registry = bus_connection_get_registry (caller_connection);
-
- if (! dbus_message_get_args (message, error,
- DBUS_TYPE_STRING, &bus_name,
- DBUS_TYPE_INVALID))
- return BUS_RESULT_FALSE;
-
- _dbus_string_init_const (&bus_name_str, bus_name);
- service = bus_registry_lookup (registry, &bus_name_str);
-
- if (service == NULL)
+ switch (found)
{
- dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
- "Bus name '%s' has no owner", bus_name);
- return BUS_RESULT_FALSE;
+ case BUS_DRIVER_FOUND_SELF:
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "GetConnectionStats is not meaningful for the "
+ "message bus \"%s\" itself", DBUS_SERVICE_DBUS);
+ goto failed;
+
+ case BUS_DRIVER_FOUND_PEER:
+ break;
+
+ case BUS_DRIVER_FOUND_ERROR:
+ /* fall through */
+ default:
+ goto failed;
}
- stats_connection = bus_service_get_primary_owners_connection (service);
_dbus_assert (stats_connection != NULL);
reply = _dbus_asv_new_method_return (message, &iter, &arr_iter);
@@ -218,10 +212,12 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
return BUS_RESULT_TRUE;
oom:
+ BUS_SET_OOM (error);
+ /* fall through */
+failed:
if (reply != NULL)
dbus_message_unref (reply);
- BUS_SET_OOM (error);
return BUS_RESULT_FALSE;
}
diff --git a/bus/system.conf.in b/bus/system.conf.in
index 58975dc5..f139b557 100644
--- a/bus/system.conf.in
+++ b/bus/system.conf.in
@@ -67,7 +67,8 @@
send_interface="org.freedesktop.DBus" />
<allow send_destination="org.freedesktop.DBus"
send_interface="org.freedesktop.DBus.Introspectable"/>
-
+ <allow send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus.Properties"/>
<!-- But disallow some specific bus services -->
<deny send_destination="org.freedesktop.DBus"
send_interface="org.freedesktop.DBus"
@@ -101,6 +102,29 @@
<!-- Include legacy configuration location -->
<include ignore_missing="yes">@SYSCONFDIR_FROM_PKGDATADIR@/dbus-1/system.conf</include>
+ <!-- The defaults for these limits are hard-coded in dbus-daemon.
+ Some clarifications:
+ Times are in milliseconds (ms); 1000ms = 1 second
+ 133169152 bytes = 127 MiB
+ 33554432 bytes = 32 MiB
+ 150000ms = 2.5 minutes -->
+ <!-- <limit name="max_incoming_bytes">133169152</limit> -->
+ <!-- <limit name="max_incoming_unix_fds">64</limit> -->
+ <!-- <limit name="max_outgoing_bytes">133169152</limit> -->
+ <!-- <limit name="max_outgoing_unix_fds">64</limit> -->
+ <!-- <limit name="max_message_size">33554432</limit> -->
+ <!-- <limit name="max_message_unix_fds">16</limit> -->
+ <!-- <limit name="service_start_timeout">25000</limit> -->
+ <!-- <limit name="auth_timeout">5000</limit> -->
+ <!-- <limit name="pending_fd_timeout">150000</limit> -->
+ <!-- <limit name="max_completed_connections">2048</limit> -->
+ <!-- <limit name="max_incomplete_connections">64</limit> -->
+ <!-- <limit name="max_connections_per_user">256</limit> -->
+ <!-- <limit name="max_pending_service_starts">512</limit> -->
+ <!-- <limit name="max_names_per_connection">512</limit> -->
+ <!-- <limit name="max_match_rules_per_connection">512</limit> -->
+ <!-- <limit name="max_replies_per_connection">128</limit> -->
+
<!-- Config files are placed here that among other things, punch
holes in the above policy for specific services. -->
<includedir>system.d</includedir>
diff --git a/bus/systemd-user/dbus.service.in b/bus/systemd-user/dbus.service.in
index 6af9c19b..103fdec9 100644
--- a/bus/systemd-user/dbus.service.in
+++ b/bus/systemd-user/dbus.service.in
@@ -5,7 +5,7 @@ DefaultDependencies=no
Requires=dbus.socket
[Service]
-ExecStart=@EXPANDED_BINDIR@/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
+ExecStart=@EXPANDED_BINDIR@/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
ExecReload=@EXPANDED_BINDIR@/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
Capabilities=all-eip
diff --git a/bus/systemd-user/dbus.socket.in b/bus/systemd-user/dbus.socket.in
index 0028e0a7..45d938b7 100644
--- a/bus/systemd-user/dbus.socket.in
+++ b/bus/systemd-user/dbus.socket.in
@@ -4,6 +4,8 @@ DefaultDependencies=no
[Socket]
ListenStream=%t/bus
+# FIXME: check the commented line below
+#ExecStartPost=-@SYSTEMCTL@ --user set-environment DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus
[Install]
Also=dbus.service
diff --git a/bus/sysusers.d/dbus.conf.in b/bus/sysusers.d/dbus.conf.in
new file mode 100644
index 00000000..fb35702d
--- /dev/null
+++ b/bus/sysusers.d/dbus.conf.in
@@ -0,0 +1,5 @@
+# sysusers.d snippet for creating the D-Bus system user automatically
+# at boot on systemd-based systems that ship with an unpopulated
+# /etc. See sysusers.d(5) for details.
+
+u @DBUS_USER@ - "System Message Bus"
diff --git a/bus/test-launch-helper.c b/bus/test-launch-helper.c
index e9ba412a..5872ab20 100644
--- a/bus/test-launch-helper.c
+++ b/bus/test-launch-helper.c
@@ -30,7 +30,12 @@
#include <dbus/dbus-internals.h>
#include <dbus/dbus-misc.h>
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
+#if !defined(DBUS_ENABLE_EMBEDDED_TESTS) || !defined(DBUS_UNIX)
+#error This file is only relevant for the embedded tests on Unix
+#endif
+
+static void die (const char *failure) _DBUS_GNUC_NORETURN;
+
static void
die (const char *failure)
{
@@ -46,7 +51,7 @@ check_memleaks (const char *name)
printf ("%s: checking for memleaks\n", name);
if (_dbus_get_malloc_blocks_outstanding () != 0)
{
- _dbus_warn ("%d dbus_malloc blocks were not freed\n",
+ _dbus_warn ("%d dbus_malloc blocks were not freed",
_dbus_get_malloc_blocks_outstanding ());
die ("memleaks");
}
@@ -57,8 +62,6 @@ test_post_hook (const char *name)
{
check_memleaks (name);
}
-#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
-
#ifdef ACTIVATION_LAUNCHER_DO_OOM
@@ -80,7 +83,7 @@ bus_activation_helper_oom_test (void *data)
/* we failed, but a OOM is good */
if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
- _dbus_warn ("FAILED SELF TEST: Error: %s\n", error.message);
+ _dbus_warn ("FAILED SELF TEST: Error: %s", error.message);
retval = FALSE;
}
dbus_error_free (&error);
@@ -98,11 +101,10 @@ bus_activation_helper_oom_test (void *data)
int
main (int argc, char **argv)
{
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
const char *dir;
DBusString config_file;
- if (argc > 1)
+ if (argc > 1 && strcmp (argv[1], "--tap") != 0)
dir = argv[1];
else
dir = _dbus_getenv ("DBUS_TEST_DATA");
@@ -130,7 +132,7 @@ main (int argc, char **argv)
if (!_dbus_test_oom_handling ("dbus-daemon-launch-helper",
bus_activation_helper_oom_test,
- "org.freedesktop.DBus.TestSuiteEchoService"))
+ (char *) "org.freedesktop.DBus.TestSuiteEchoService"))
die ("OOM failed");
test_post_hook (argv[0]);
@@ -138,11 +140,4 @@ main (int argc, char **argv)
printf ("%s: Success\n", argv[0]);
return 0;
-#else /* DBUS_ENABLE_EMBEDDED_TESTS */
-
- printf ("Not compiled with test support\n");
-
- return 0;
-#endif
}
-
diff --git a/bus/test-main.c b/bus/test-main.c
index 788574fe..4d3df87a 100644
--- a/bus/test-main.c
+++ b/bus/test-main.c
@@ -31,11 +31,16 @@
#include <dbus/dbus-message-internal.h>
#include "selinux.h"
+#ifndef DBUS_ENABLE_EMBEDDED_TESTS
+#error This file is only relevant for the embedded tests
+#endif
+
#ifdef DBUS_UNIX
# include <dbus/dbus-sysdeps-unix.h>
#endif
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
+static void die (const char *failure) _DBUS_GNUC_NORETURN;
+
static void
die (const char *failure)
{
@@ -51,12 +56,11 @@ check_memleaks (const char *name)
printf ("%s: checking for memleaks\n", name);
if (_dbus_get_malloc_blocks_outstanding () != 0)
{
- _dbus_warn ("%d dbus_malloc blocks were not freed\n",
+ _dbus_warn ("%d dbus_malloc blocks were not freed",
_dbus_get_malloc_blocks_outstanding ());
die ("memleaks");
}
}
-#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
static DBusInitialFDs *initial_fds = NULL;
@@ -72,7 +76,7 @@ test_pre_hook (void)
initial_fds = _dbus_check_fdleaks_enter ();
}
-static char *progname = "";
+static const char *progname = "";
static void
test_post_hook (void)
@@ -88,14 +92,13 @@ test_post_hook (void)
int
main (int argc, char **argv)
{
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
const char *dir;
const char *only;
DBusString test_data_dir;
progname = argv[0];
- if (argc > 1)
+ if (argc > 1 && strcmp (argv[1], "--tap") != 0)
dir = argv[1];
else
dir = _dbus_getenv ("DBUS_TEST_DATA");
@@ -190,10 +193,4 @@ main (int argc, char **argv)
return 0;
-#else /* DBUS_ENABLE_EMBEDDED_TESTS */
-
- printf ("Not compiled with test support\n");
-
- return 0;
-#endif
}
diff --git a/bus/test-system.c b/bus/test-system.c
index 5f02d0ab..de1f003b 100644
--- a/bus/test-system.c
+++ b/bus/test-system.c
@@ -29,7 +29,12 @@
#include <dbus/dbus-sysdeps.h>
#include <dbus/dbus-internals.h>
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
+#if !defined(DBUS_ENABLE_EMBEDDED_TESTS) || !defined(DBUS_UNIX)
+#error This file is only relevant for the embedded tests on Unix
+#endif
+
+static void die (const char *failure) _DBUS_GNUC_NORETURN;
+
static void
die (const char *failure)
{
@@ -45,19 +50,18 @@ check_memleaks (const char *name)
printf ("%s: checking for memleaks\n", name);
if (_dbus_get_malloc_blocks_outstanding () != 0)
{
- _dbus_warn ("%d dbus_malloc blocks were not freed\n",
+ _dbus_warn ("%d dbus_malloc blocks were not freed",
_dbus_get_malloc_blocks_outstanding ());
die ("memleaks");
}
}
-#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
static void
test_pre_hook (void)
{
}
-static char *progname = "";
+static const char *progname = "";
static void
test_post_hook (void)
{
@@ -67,13 +71,12 @@ test_post_hook (void)
int
main (int argc, char **argv)
{
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
const char *dir;
DBusString test_data_dir;
progname = argv[0];
- if (argc > 1)
+ if (argc > 1 && strcmp (argv[1], "--tap") != 0)
dir = argv[1];
else
dir = _dbus_getenv ("DBUS_TEST_DATA");
@@ -98,10 +101,4 @@ main (int argc, char **argv)
printf ("%s: Success\n", argv[0]);
return 0;
-#else /* DBUS_ENABLE_EMBEDDED_TESTS */
-
- printf ("Not compiled with test support\n");
-
- return 0;
-#endif
}
diff --git a/bus/test.c b/bus/test.c
index 31ef4c8f..76960a30 100644
--- a/bus/test.c
+++ b/bus/test.c
@@ -270,14 +270,14 @@ bus_context_new_test (const DBusString *test_data_dir,
if (!_dbus_string_init (&config_file))
{
- _dbus_warn ("No memory\n");
+ _dbus_warn ("No memory");
return NULL;
}
if (!_dbus_string_copy (test_data_dir, 0,
&config_file, 0))
{
- _dbus_warn ("No memory\n");
+ _dbus_warn ("No memory");
_dbus_string_free (&config_file);
return NULL;
}
@@ -286,7 +286,7 @@ bus_context_new_test (const DBusString *test_data_dir,
if (!_dbus_concat_dir_and_file (&config_file, &relative))
{
- _dbus_warn ("No memory\n");
+ _dbus_warn ("No memory");
_dbus_string_free (&config_file);
return NULL;
}
@@ -297,7 +297,7 @@ bus_context_new_test (const DBusString *test_data_dir,
{
_DBUS_ASSERT_ERROR_IS_SET (&error);
- _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
+ _dbus_warn ("Failed to create debug bus context from configuration file %s: %s",
filename, error.message);
dbus_error_free (&error);
diff --git a/bus/tmpfiles.d/dbus.conf.in b/bus/tmpfiles.d/dbus.conf.in
new file mode 100644
index 00000000..0ec7de04
--- /dev/null
+++ b/bus/tmpfiles.d/dbus.conf.in
@@ -0,0 +1,9 @@
+# Fields: type; path; mode; uid; gid; age; argument (symlink target)
+
+# Make ${localstatedir}/lib/dbus (required for systemd < 237)
+# Adjust mode and ownership if it already exists.
+d @EXPANDED_LOCALSTATEDIR@/lib/dbus 0755 - - -
+
+# Make ${localstatedir}/lib/dbus/machine-id a symlink to /etc/machine-id
+# if it does not already exist
+L @EXPANDED_LOCALSTATEDIR@/lib/dbus/machine-id - - - - /etc/machine-id