summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HACKING3
-rw-r--r--bus/activation.c2
-rw-r--r--bus/bus.c186
-rw-r--r--bus/bus.h6
-rw-r--r--bus/config-parser-common.c18
-rw-r--r--bus/config-parser-common.h5
-rw-r--r--bus/config-parser.c85
-rw-r--r--bus/config-parser.h3
-rw-r--r--bus/connection.c104
-rw-r--r--bus/connection.h1
-rw-r--r--bus/dbus-daemon.1.in37
-rw-r--r--bus/driver.c2
-rw-r--r--bus/main.c23
-rw-r--r--bus/policy.c12
-rw-r--r--bus/policy.h8
-rw-r--r--bus/session.conf.in4
-rw-r--r--bus/system.conf.in35
-rw-r--r--configure.in77
-rw-r--r--dbus/dbus-connection.c4
-rw-r--r--dbus/dbus-credentials.h3
-rw-r--r--dbus/dbus-marshal-basic.c42
-rw-r--r--dbus/dbus-marshal-recursive.c2
-rw-r--r--dbus/dbus-marshal-validate-util.c3
-rw-r--r--dbus/dbus-marshal-validate.c83
-rw-r--r--dbus/dbus-message.c2
-rw-r--r--dbus/dbus-spawn.c4
-rw-r--r--dbus/dbus-sysdeps-unix.c48
-rw-r--r--dbus/dbus-sysdeps-util-unix.c149
-rw-r--r--dbus/dbus-sysdeps-util-win.c4
-rw-r--r--dbus/dbus-sysdeps.c4
-rw-r--r--dbus/dbus-sysdeps.h12
-rw-r--r--doc/busconfig.dtd2
-rw-r--r--test/name-test/Makefile.am4
-rwxr-xr-xtest/name-test/run-test-systemserver.sh50
-rwxr-xr-xtest/name-test/test-wait-for-echo.py41
-rw-r--r--test/name-test/tmp-session-like-system.conf91
-rw-r--r--tools/dbus-launch-x11.c6
-rw-r--r--tools/dbus-launch.c2
-rw-r--r--tools/dbus-print-message.c3
-rw-r--r--tools/dbus-send.c51
-rwxr-xr-xtools/run-with-tmp-session-bus.sh5
41 files changed, 1048 insertions, 178 deletions
diff --git a/HACKING b/HACKING
index 58715487..f765866c 100644
--- a/HACKING
+++ b/HACKING
@@ -237,6 +237,5 @@ rules are:
The reviewer group that can approve patches: Havoc Pennington, Michael
Meeks, Alex Larsson, Zack Rusin, Joe Shaw, Mikael Hallendal, Richard
Hult, Owen Fraser-Green, Olivier Andrieu, Colin Walters, Thiago
-Macieira, John Palmieri.
-
+Macieira, John Palmieri, Scott James Remnant.
diff --git a/bus/activation.c b/bus/activation.c
index 18630958..a273c4ad 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -679,7 +679,7 @@ populate_environment (BusActivation *activation)
DBusString value;
int i;
char **environment;
- dbus_bool_t retval;
+ dbus_bool_t retval = FALSE;
environment = _dbus_get_environment ();
diff --git a/bus/bus.c b/bus/bus.c
index a28a2672..1412ea28 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -54,6 +54,9 @@ struct BusContext
BusMatchmaker *matchmaker;
BusLimits limits;
unsigned int fork : 1;
+ unsigned int syslog : 1;
+ unsigned int keep_umask : 1;
+ unsigned int allow_anonymous : 1;
};
static dbus_int32_t server_data_slot = -1;
@@ -188,6 +191,9 @@ new_connection_callback (DBusServer *server,
dbus_connection_set_max_message_size (new_connection,
context->limits.max_message_size);
+ dbus_connection_set_allow_anonymous (new_connection,
+ context->allow_anonymous);
+
/* on OOM, we won't have ref'd the connection so it will die. */
}
@@ -384,6 +390,9 @@ 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);
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
retval = TRUE;
@@ -708,7 +717,8 @@ bus_context_new (const DBusString *config_file,
if (!_dbus_become_daemon (context->pidfile ? &u : NULL,
print_pid_pipe,
- error))
+ error,
+ context->keep_umask))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
goto failed;
@@ -736,6 +746,11 @@ bus_context_new (const DBusString *config_file,
if (print_pid_pipe && _dbus_pipe_is_valid (print_pid_pipe) &&
!_dbus_pipe_is_stdout_or_stderr (print_pid_pipe))
_dbus_pipe_close (print_pid_pipe, NULL);
+
+ if (!bus_selinux_full_init ())
+ {
+ _dbus_warn ("SELinux initialization failed\n");
+ }
if (!process_config_postinit (context, parser, error))
{
@@ -766,11 +781,6 @@ bus_context_new (const DBusString *config_file,
#endif
}
- if (!bus_selinux_full_init ())
- {
- _dbus_warn ("SELinux initialization failed\n");
- }
-
dbus_server_free_data_slot (&server_data_slot);
return context;
@@ -826,7 +836,10 @@ bus_context_reload_config (BusContext *context,
}
ret = TRUE;
+ bus_context_log_info (context, "Reloaded configuration");
failed:
+ if (!ret)
+ bus_context_log_info (context, "Unable to reload configuration: %s", error->message);
if (parser != NULL)
bus_config_parser_unref (parser);
return ret;
@@ -1107,6 +1120,32 @@ bus_context_get_reply_timeout (BusContext *context)
return context->limits.reply_timeout;
}
+void
+bus_context_log_info (BusContext *context, const char *msg, ...)
+{
+ va_list args;
+
+ va_start (args, msg);
+
+ if (context->syslog)
+ _dbus_log_info (msg, args);
+
+ va_end (args);
+}
+
+void
+bus_context_log_security (BusContext *context, const char *msg, ...)
+{
+ va_list args;
+
+ va_start (args, msg);
+
+ if (context->syslog)
+ _dbus_log_security (msg, args);
+
+ va_end (args);
+}
+
/*
* addressed_recipient is the recipient specified in the message.
*
@@ -1129,20 +1168,44 @@ bus_context_check_security_policy (BusContext *context,
DBusMessage *message,
DBusError *error)
{
+ const char *dest;
BusClientPolicy *sender_policy;
BusClientPolicy *recipient_policy;
+ dbus_int32_t toggles;
+ dbus_bool_t log;
int type;
dbus_bool_t requested_reply;
+ const char *sender_name;
+ const char *sender_loginfo;
+ const char *proposed_recipient_loginfo;
type = dbus_message_get_type (message);
+ dest = dbus_message_get_destination (message);
/* dispatch.c was supposed to ensure these invariants */
- _dbus_assert (dbus_message_get_destination (message) != NULL ||
+ _dbus_assert (dest != NULL ||
type == DBUS_MESSAGE_TYPE_SIGNAL ||
(sender == NULL && !bus_connection_is_active (proposed_recipient)));
_dbus_assert (type == DBUS_MESSAGE_TYPE_SIGNAL ||
addressed_recipient != NULL ||
- strcmp (dbus_message_get_destination (message), DBUS_SERVICE_DBUS) == 0);
+ strcmp (dest, DBUS_SERVICE_DBUS) == 0);
+
+ /* Used in logging below */
+ if (sender != NULL)
+ {
+ sender_name = bus_connection_get_name (sender);
+ sender_loginfo = bus_connection_get_loginfo (sender);
+ }
+ else
+ {
+ sender_name = NULL;
+ sender_loginfo = "(bus)";
+ }
+
+ if (proposed_recipient != NULL)
+ proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient);
+ else
+ proposed_recipient_loginfo = "bus";
switch (type)
{
@@ -1166,10 +1229,6 @@ bus_context_check_security_policy (BusContext *context,
if (sender != NULL)
{
- const char *dest;
-
- dest = dbus_message_get_destination (message);
-
/* First verify the SELinux access controls. If allowed then
* go on with the standard checks.
*/
@@ -1185,8 +1244,9 @@ bus_context_check_security_policy (BusContext *context,
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"An SELinux policy prevents this sender "
"from sending this message to this recipient "
- "(rejected message had interface \"%s\" "
+ "(rejected message had sender \"%s\" interface \"%s\" "
"member \"%s\" error name \"%s\" destination \"%s\")",
+ sender_name ? sender_name : "(unset)",
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) : "(unset)",
dbus_message_get_member (message) ?
@@ -1299,57 +1359,112 @@ bus_context_check_security_policy (BusContext *context,
(proposed_recipient != NULL && sender == NULL && recipient_policy == NULL) ||
(proposed_recipient == NULL && recipient_policy == NULL));
+ log = FALSE;
if (sender_policy &&
!bus_client_policy_check_can_send (sender_policy,
context->registry,
requested_reply,
proposed_recipient,
- message))
+ message, &toggles, &log))
{
- const char *dest;
-
- dest = dbus_message_get_destination (message);
- dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
- "A security policy in place prevents this sender "
- "from sending this message to this recipient, "
- "see message bus configuration file (rejected message "
- "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")",
+ const char *msg = "Rejected send message, %d matched rules; "
+ "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))";
+
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
+ toggles,
+ dbus_message_type_to_string (dbus_message_get_type (message)),
+ sender_name ? sender_name : "(unset)",
+ sender_loginfo,
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) : "(unset)",
dbus_message_get_member (message) ?
dbus_message_get_member (message) : "(unset)",
dbus_message_get_error_name (message) ?
dbus_message_get_error_name (message) : "(unset)",
- dest ? dest : DBUS_SERVICE_DBUS);
+ requested_reply,
+ dest ? dest : DBUS_SERVICE_DBUS,
+ proposed_recipient_loginfo);
+ /* Needs to be duplicated to avoid calling malloc and having to handle OOM */
+ if (addressed_recipient == proposed_recipient)
+ bus_context_log_security (context, msg,
+ toggles,
+ dbus_message_type_to_string (dbus_message_get_type (message)),
+ sender_name ? sender_name : "(unset)",
+ sender_loginfo,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
+ requested_reply,
+ dest ? dest : DBUS_SERVICE_DBUS,
+ proposed_recipient_loginfo);
_dbus_verbose ("security policy disallowing message due to sender policy\n");
return FALSE;
}
+ if (log)
+ bus_context_log_security (context,
+ "Would reject message, %d matched rules; "
+ "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))",
+ toggles,
+ dbus_message_type_to_string (dbus_message_get_type (message)),
+ sender_name ? sender_name : "(unset)",
+ sender_loginfo,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
+ requested_reply,
+ dest ? dest : DBUS_SERVICE_DBUS,
+ proposed_recipient_loginfo);
+
if (recipient_policy &&
!bus_client_policy_check_can_receive (recipient_policy,
context->registry,
requested_reply,
sender,
addressed_recipient, proposed_recipient,
- message))
+ message, &toggles))
{
- const char *dest;
-
- dest = dbus_message_get_destination (message);
- dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
- "A security policy in place prevents this recipient "
- "from receiving this message from this sender, "
- "see message bus configuration file (rejected message "
- "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\" reply serial %u requested_reply=%d)",
+ const char *msg = "Rejected receive message, %d matched rules; "
+ "type=\"%s\" sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" reply serial=%u requested_reply=%d destination=\"%s\" (%s))";
+
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
+ toggles,
+ dbus_message_type_to_string (dbus_message_get_type (message)),
+ sender_name ? sender_name : "(unset)",
+ sender_loginfo,
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) : "(unset)",
dbus_message_get_member (message) ?
dbus_message_get_member (message) : "(unset)",
dbus_message_get_error_name (message) ?
dbus_message_get_error_name (message) : "(unset)",
- dest ? dest : DBUS_SERVICE_DBUS,
dbus_message_get_reply_serial (message),
- requested_reply);
+ requested_reply,
+ dest ? dest : DBUS_SERVICE_DBUS,
+ proposed_recipient_loginfo);
+ /* Needs to be duplicated to avoid calling malloc and having to handle OOM */
+ if (addressed_recipient == proposed_recipient)
+ bus_context_log_security (context, msg,
+ toggles,
+ dbus_message_type_to_string (dbus_message_get_type (message)),
+ sender_name ? sender_name : "(unset)",
+ sender_loginfo,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
+ dbus_message_get_reply_serial (message),
+ requested_reply,
+ dest ? dest : DBUS_SERVICE_DBUS,
+ proposed_recipient_loginfo);
_dbus_verbose ("security policy disallowing message due to recipient policy\n");
return FALSE;
}
@@ -1359,9 +1474,6 @@ bus_context_check_security_policy (BusContext *context,
dbus_connection_get_outgoing_size (proposed_recipient) >
context->limits.max_outgoing_bytes)
{
- const char *dest;
-
- dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The destination service \"%s\" has a full message queue",
dest ? dest : (proposed_recipient ?
diff --git a/bus/bus.h b/bus/bus.h
index ad231040..74bdb821 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -107,6 +107,12 @@ int bus_context_get_max_services_per_connection (BusContext
int bus_context_get_max_match_rules_per_connection (BusContext *context);
int bus_context_get_max_replies_per_connection (BusContext *context);
int bus_context_get_reply_timeout (BusContext *context);
+void bus_context_log_info (BusContext *context,
+ const char *msg,
+ ...);
+void bus_context_log_security (BusContext *context,
+ const char *msg,
+ ...);
dbus_bool_t bus_context_check_security_policy (BusContext *context,
BusTransaction *transaction,
DBusConnection *sender,
diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c
index 6e4bb701..4965c192 100644
--- a/bus/config-parser-common.c
+++ b/bus/config-parser-common.c
@@ -114,6 +114,18 @@ bus_config_parser_element_name_to_type (const char *name)
{
return ELEMENT_ASSOCIATE;
}
+ else if (strcmp (name, "keep_umask") == 0)
+ {
+ return ELEMENT_KEEP_UMASK;
+ }
+ else if (strcmp (name, "syslog") == 0)
+ {
+ return ELEMENT_SYSLOG;
+ }
+ else if (strcmp (name, "allow_anonymous") == 0)
+ {
+ return ELEMENT_ALLOW_ANONYMOUS;
+ }
return ELEMENT_NONE;
}
@@ -162,6 +174,12 @@ bus_config_parser_element_type_to_name (ElementType type)
return "selinux";
case ELEMENT_ASSOCIATE:
return "associate";
+ case ELEMENT_KEEP_UMASK:
+ return "keep_umask";
+ case ELEMENT_SYSLOG:
+ return "syslog";
+ case ELEMENT_ALLOW_ANONYMOUS:
+ return "allow_anonymous";
}
_dbus_assert_not_reached ("bad element type");
diff --git a/bus/config-parser-common.h b/bus/config-parser-common.h
index 3718c958..2c296433 100644
--- a/bus/config-parser-common.h
+++ b/bus/config-parser-common.h
@@ -47,7 +47,10 @@ typedef enum
ELEMENT_SELINUX,
ELEMENT_ASSOCIATE,
ELEMENT_STANDARD_SESSION_SERVICEDIRS,
- ELEMENT_STANDARD_SYSTEM_SERVICEDIRS
+ ELEMENT_STANDARD_SYSTEM_SERVICEDIRS,
+ ELEMENT_KEEP_UMASK,
+ ELEMENT_SYSLOG,
+ ELEMENT_ALLOW_ANONYMOUS
} ElementType;
ElementType bus_config_parser_element_name_to_type (const char *element_name);
diff --git a/bus/config-parser.c b/bus/config-parser.c
index f9e0b7d7..34d8684a 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -111,7 +111,13 @@ struct BusConfigParser
unsigned int fork : 1; /**< TRUE to fork into daemon mode */
+ unsigned int keep_umask : 1; /**< TRUE to keep original umask when forking */
+
+ unsigned int syslog : 1; /**< TRUE to enable syslog */
+
unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */
+
+ unsigned int allow_anonymous : 1; /**< TRUE to allow anonymous connections */
};
static Element*
@@ -306,6 +312,9 @@ merge_included (BusConfigParser *parser,
if (included->fork)
parser->fork = TRUE;
+ if (included->keep_umask)
+ parser->keep_umask = TRUE;
+
if (included->pidfile != NULL)
{
dbus_free (parser->pidfile);
@@ -698,6 +707,36 @@ start_busconfig_child (BusConfigParser *parser,
return TRUE;
}
+ else if (element_type == ELEMENT_KEEP_UMASK)
+ {
+ if (!check_no_attributes (parser, "keep_umask", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_KEEP_UMASK) == NULL)
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ parser->keep_umask = TRUE;
+
+ return TRUE;
+ }
+ else if (element_type == ELEMENT_SYSLOG)
+ {
+ if (!check_no_attributes (parser, "syslog", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_SYSLOG) == NULL)
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ parser->syslog = TRUE;
+
+ return TRUE;
+ }
else if (element_type == ELEMENT_PIDFILE)
{
if (!check_no_attributes (parser, "pidfile", attribute_names, attribute_values, error))
@@ -815,6 +854,20 @@ start_busconfig_child (BusConfigParser *parser,
return TRUE;
}
+ else if (element_type == ELEMENT_ALLOW_ANONYMOUS)
+ {
+ if (!check_no_attributes (parser, "allow_anonymous", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_ALLOW_ANONYMOUS) == NULL)
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ parser->allow_anonymous = TRUE;
+ return TRUE;
+ }
else if (element_type == ELEMENT_SERVICEDIR)
{
if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error))
@@ -1073,6 +1126,7 @@ append_rule_from_element (BusConfigParser *parser,
dbus_bool_t allow,
DBusError *error)
{
+ const char *log;
const char *send_interface;
const char *send_member;
const char *send_error;
@@ -1116,6 +1170,7 @@ append_rule_from_element (BusConfigParser *parser,
"own", &own,
"user", &user,
"group", &group,
+ "log", &log,
NULL))
return FALSE;
@@ -1320,6 +1375,9 @@ append_rule_from_element (BusConfigParser *parser,
if (eavesdrop)
rule->d.send.eavesdrop = (strcmp (eavesdrop, "true") == 0);
+ if (log)
+ rule->d.send.log = (strcmp (log, "true") == 0);
+
if (send_requested_reply)
rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0);
@@ -1947,10 +2005,13 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_ALLOW:
case ELEMENT_DENY:
case ELEMENT_FORK:
+ case ELEMENT_KEEP_UMASK:
+ case ELEMENT_SYSLOG:
case ELEMENT_SELINUX:
case ELEMENT_ASSOCIATE:
case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
+ case ELEMENT_ALLOW_ANONYMOUS:
break;
}
@@ -2232,8 +2293,11 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_ALLOW:
case ELEMENT_DENY:
case ELEMENT_FORK:
+ case ELEMENT_KEEP_UMASK:
+ case ELEMENT_SYSLOG:
case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
+ case ELEMENT_ALLOW_ANONYMOUS:
case ELEMENT_SELINUX:
case ELEMENT_ASSOCIATE:
if (all_whitespace (content))
@@ -2554,6 +2618,24 @@ bus_config_parser_get_fork (BusConfigParser *parser)
return parser->fork;
}
+dbus_bool_t
+bus_config_parser_get_keep_umask (BusConfigParser *parser)
+{
+ return parser->keep_umask;
+}
+
+dbus_bool_t
+bus_config_parser_get_syslog (BusConfigParser *parser)
+{
+ return parser->syslog;
+}
+
+dbus_bool_t
+bus_config_parser_get_allow_anonymous (BusConfigParser *parser)
+{
+ return parser->allow_anonymous;
+}
+
const char *
bus_config_parser_get_pidfile (BusConfigParser *parser)
{
@@ -2947,6 +3029,9 @@ config_parsers_equal (const BusConfigParser *a,
if (! bools_equal (a->fork, b->fork))
return FALSE;
+ if (! bools_equal (a->keep_umask, b->keep_umask))
+ return FALSE;
+
if (! bools_equal (a->is_toplevel, b->is_toplevel))
return FALSE;
diff --git a/bus/config-parser.h b/bus/config-parser.h
index ec0dfed1..bb3a30f4 100644
--- a/bus/config-parser.h
+++ b/bus/config-parser.h
@@ -65,6 +65,9 @@ const char* bus_config_parser_get_type (BusConfigParser *parser);
DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser);
dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser);
+dbus_bool_t bus_config_parser_get_allow_anonymous (BusConfigParser *parser);
+dbus_bool_t bus_config_parser_get_syslog (BusConfigParser *parser);
+dbus_bool_t bus_config_parser_get_keep_umask (BusConfigParser *parser);
const char* bus_config_parser_get_pidfile (BusConfigParser *parser);
const char* bus_config_parser_get_servicehelper (BusConfigParser *parser);
DBusList** bus_config_parser_get_service_dirs (BusConfigParser *parser);
diff --git a/bus/connection.c b/bus/connection.c
index ed1b1391..9159c898 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -32,6 +32,9 @@
#include <dbus/dbus-hash.h>
#include <dbus/dbus-timeout.h>
+/* Trim executed commands to this length; we want to keep logs readable */
+#define MAX_LOG_COMMAND_LEN 50
+
static void bus_connection_remove_transactions (DBusConnection *connection);
typedef struct
@@ -76,6 +79,7 @@ typedef struct
DBusPreallocatedSend *oom_preallocated;
BusClientPolicy *policy;
+ char *cached_loginfo_string;
BusSELinuxID *selinux_id;
long connection_tv_sec; /**< Time when we connected (seconds component) */
@@ -406,6 +410,8 @@ free_connection_data (void *data)
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
+ dbus_free (d->cached_loginfo_string);
+
dbus_free (d->name);
dbus_free (d);
@@ -537,13 +543,72 @@ bus_connections_unref (BusConnections *connections)
}
}
+/* Used for logging */
+static dbus_bool_t
+cache_peer_loginfo_string (BusConnectionData *d,
+ DBusConnection *connection)
+{
+ DBusString loginfo_buf;
+ unsigned long uid;
+ unsigned long pid;
+ char *windows_sid;
+ dbus_bool_t prev_added;
+
+ if (!_dbus_string_init (&loginfo_buf))
+ return FALSE;
+
+ prev_added = FALSE;
+ if (dbus_connection_get_unix_user (connection, &uid))
+ {
+ if (!_dbus_string_append_printf (&loginfo_buf, "uid=%ld", uid))
+ goto oom;
+ else
+ prev_added = TRUE;
+ }
+
+ if (dbus_connection_get_unix_process_id (connection, &pid))
+ {
+ if (prev_added)
+ {
+ if (!_dbus_string_append_byte (&loginfo_buf, ' '))
+ goto oom;
+ }
+ if (!_dbus_string_append_printf (&loginfo_buf, "pid=%ld comm=\"", pid))
+ goto oom;
+ /* Ignore errors here; we may not have permissions to read the
+ * proc file. */
+ _dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL);
+ if (!_dbus_string_append_byte (&loginfo_buf, '"'))
+ goto oom;
+ }
+
+ if (dbus_connection_get_windows_user (connection, &windows_sid))
+ {
+ if (!_dbus_string_append_printf (&loginfo_buf, "sid=\"%s\" ", windows_sid))
+ goto oom;
+ dbus_free (windows_sid);
+ }
+
+ if (!_dbus_string_steal_data (&loginfo_buf, &(d->cached_loginfo_string)))
+ goto oom;
+
+ _dbus_string_free (&loginfo_buf);
+
+ return TRUE;
+oom:
+ _dbus_string_free (&loginfo_buf);
+ return FALSE;
+}
+
dbus_bool_t
bus_connections_setup_connection (BusConnections *connections,
DBusConnection *connection)
{
+
BusConnectionData *d;
dbus_bool_t retval;
DBusError error;
+
d = dbus_new0 (BusConnectionData, 1);
@@ -583,7 +648,7 @@ bus_connections_setup_connection (BusConnections *connections,
dbus_error_free (&error);
goto out;
}
-
+
if (!dbus_connection_set_watch_functions (connection,
add_connection_watch,
remove_connection_watch,
@@ -842,6 +907,18 @@ bus_connection_is_in_unix_group (DBusConnection *connection,
return FALSE;
}
+const char *
+bus_connection_get_loginfo (DBusConnection *connection)
+{
+ BusConnectionData *d;
+
+ d = BUS_CONNECTION_DATA (connection);
+
+ if (!bus_connection_is_active (connection))
+ return "inactive";
+ return d->cached_loginfo_string;
+}
+
BusClientPolicy*
bus_connection_get_policy (DBusConnection *connection)
{
@@ -1302,16 +1379,15 @@ bus_connection_complete (DBusConnection *connection,
{
if (!adjust_connections_for_uid (d->connections,
uid, 1))
- {
- BUS_SET_OOM (error);
- dbus_free (d->name);
- d->name = NULL;
- bus_client_policy_unref (d->policy);
- d->policy = NULL;
- return FALSE;
- }
+ goto fail;
}
-
+
+ /* Create and cache a string which holds information about the
+ * peer process; used for logging purposes.
+ */
+ if (!cache_peer_loginfo_string (d, connection))
+ goto fail;
+
/* Now the connection is active, move it between lists */
_dbus_list_unlink (&d->connections->incomplete,
d->link_in_connection_list);
@@ -1329,6 +1405,14 @@ bus_connection_complete (DBusConnection *connection,
_dbus_assert (bus_connection_is_active (connection));
return TRUE;
+fail:
+ BUS_SET_OOM (error);
+ dbus_free (d->name);
+ d->name = NULL;
+ if (d->policy)
+ bus_client_policy_unref (d->policy);
+ d->policy = NULL;
+ return FALSE;
}
const char *
diff --git a/bus/connection.h b/bus/connection.h
index 5099bcf9..4f352169 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -50,6 +50,7 @@ BusConnections* bus_connection_get_connections (DBusConnection
BusRegistry* bus_connection_get_registry (DBusConnection *connection);
BusActivation* bus_connection_get_activation (DBusConnection *connection);
BusMatchmaker* bus_connection_get_matchmaker (DBusConnection *connection);
+const char * bus_connection_get_loginfo (DBusConnection *connection);
BusSELinuxID* bus_connection_get_selinux_id (DBusConnection *connection);
dbus_bool_t bus_connections_check_limits (BusConnections *connections,
DBusConnection *requesting_completion,
diff --git a/bus/dbus-daemon.1.in b/bus/dbus-daemon.1.in
index 5599afe6..4b55ac29 100644
--- a/bus/dbus-daemon.1.in
+++ b/bus/dbus-daemon.1.in
@@ -1,6 +1,6 @@
.\"
.\" dbus-daemon manual page.
-.\" Copyright (C) 2003 Red Hat, Inc.
+.\" Copyright (C) 2003,2008 Red Hat, Inc.
.\"
.TH dbus-daemon 1
.SH NAME
@@ -214,6 +214,13 @@ into the background, etc.). This is generally used
rather than the \-\-fork command line option.
.TP
+.I "<keep_umask>"
+
+.PP
+If present, the bus daemon keeps its original umask when forking.
+This may be useful to avoid affecting the behavior of child processes.
+
+.TP
.I "<listen>"
.PP
@@ -410,15 +417,27 @@ they are analogous to a firewall in that they allow expected traffic
and prevent unexpected traffic.
.PP
-The <policy> element has one of three attributes:
+Currently, the system bus has a default-deny policy for sending method calls
+and owning bus names. Everything else, in particular reply messages, receive
+checks, and signals has a default allow policy.
+
+.PP
+In general, it is best to keep system services as small, targeted programs which
+run in their own process and provide a single bus name. Then, all that is needed
+is an <allow> rule for the "own" permission to let the process claim the bus
+name, and a "send_destination" rule to allow traffic from some or all uids to
+your service.
+
+.PP
+The <policy> element has one of four attributes:
.nf
context="(default|mandatory)"
+ at_console="(true|false)"
user="username or userid"
group="group name or gid"
.fi
.PP
-
Policies are applied to a connection as follows:
.nf
- all context="default" policies are applied
@@ -426,6 +445,8 @@ Policies are applied to a connection as follows:
in undefined order
- all user="connection's auth user" policies are applied
in undefined order
+ - all at_console="true" policies are applied
+ - all at_console="false" policies are applied
- all context="mandatory" policies are applied
.fi
@@ -474,9 +495,7 @@ The possible attributes of these elements are:
.PP
Examples:
.nf
- <deny send_interface="org.freedesktop.System" send_member="Reboot"/>
- <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/>
- <deny own="org.freedesktop.System"/>
+ <deny send_destination="org.freedesktop.Service" send_interface="org.freedesktop.System" send_member="Reboot"/>
<deny send_destination="org.freedesktop.System"/>
<deny receive_sender="org.freedesktop.System"/>
<deny user="john"/>
@@ -566,7 +585,11 @@ received" are evaluated separately.
.PP
Be careful with send_interface/receive_interface, because the
-interface field in messages is optional.
+interface field in messages is optional. In particular, do NOT
+specify <deny send_interface="org.foo.Bar"/>! This will cause
+no-interface messages to be blocked for all services, which is
+almost certainly not what you intended. Always use rules of
+the form: <deny send_interface="org.foo.Bar" send_destination="org.foo.Service"/>
.TP
.I "<selinux>"
diff --git a/bus/driver.c b/bus/driver.c
index 05ecd56c..c97bff5d 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -1411,7 +1411,7 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
BusService *serv;
DBusConnection *conn;
DBusMessage *reply;
- char *data = NULL;
+ void *data = NULL;
dbus_uint32_t data_size;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
diff --git a/bus/main.c b/bus/main.c
index 161de19c..51538fe7 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -44,7 +44,6 @@ static void close_reload_pipe (void);
static void
signal_handler (int sig)
{
- DBusString str;
switch (sig)
{
@@ -52,16 +51,20 @@ signal_handler (int sig)
case SIGIO:
/* explicit fall-through */
#endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */
+#ifdef SIGHUP
case SIGHUP:
- _dbus_string_init_const (&str, "foo");
- if ((reload_pipe[RELOAD_WRITE_END] > 0) &&
- !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
- {
- _dbus_warn ("Unable to write to reload pipe.\n");
- close_reload_pipe ();
- }
+ {
+ DBusString str;
+ _dbus_string_init_const (&str, "foo");
+ if ((reload_pipe[RELOAD_WRITE_END] > 0) &&
+ !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
+ {
+ _dbus_warn ("Unable to write to reload pipe.\n");
+ close_reload_pipe ();
+ }
+ }
break;
-
+#endif
case SIGTERM:
_dbus_loop_quit (bus_context_get_loop (context));
break;
@@ -458,7 +461,9 @@ main (int argc, char **argv)
setup_reload_pipe (bus_context_get_loop (context));
+#ifdef SIGHUP
_dbus_set_signal_handler (SIGHUP, signal_handler);
+#endif
_dbus_set_signal_handler (SIGTERM, signal_handler);
#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX
_dbus_set_signal_handler (SIGIO, signal_handler);
diff --git a/bus/policy.c b/bus/policy.c
index caa544e7..ef31800f 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -866,7 +866,9 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
BusRegistry *registry,
dbus_bool_t requested_reply,
DBusConnection *receiver,
- DBusMessage *message)
+ DBusMessage *message,
+ dbus_int32_t *toggles,
+ dbus_bool_t *log)
{
DBusList *link;
dbus_bool_t allowed;
@@ -876,6 +878,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
*/
_dbus_verbose (" (policy) checking send rules\n");
+ *toggles = 0;
allowed = FALSE;
link = _dbus_list_get_first_link (&policy->rules);
@@ -1026,6 +1029,8 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
/* Use this rule */
allowed = rule->allow;
+ *log = rule->d.send.log;
+ (*toggles)++;
_dbus_verbose (" (policy) used rule, allow now = %d\n",
allowed);
@@ -1044,7 +1049,8 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
DBusConnection *sender,
DBusConnection *addressed_recipient,
DBusConnection *proposed_recipient,
- DBusMessage *message)
+ DBusMessage *message,
+ dbus_int32_t *toggles)
{
DBusList *link;
dbus_bool_t allowed;
@@ -1059,6 +1065,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
*/
_dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
+ *toggles = 0;
allowed = FALSE;
link = _dbus_list_get_first_link (&policy->rules);
@@ -1223,6 +1230,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
/* Use this rule */
allowed = rule->allow;
+ (*toggles)++;
_dbus_verbose (" (policy) used rule, allow now = %d\n",
allowed);
diff --git a/bus/policy.h b/bus/policy.h
index adb9a059..a75e0dd9 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -65,6 +65,7 @@ struct BusPolicyRule
char *destination;
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
+ unsigned int log : 1;
} send;
struct
@@ -141,14 +142,17 @@ dbus_bool_t bus_client_policy_check_can_send (BusClientPolicy *policy,
BusRegistry *registry,
dbus_bool_t requested_reply,
DBusConnection *receiver,
- DBusMessage *message);
+ DBusMessage *message,
+ dbus_int32_t *toggles,
+ dbus_bool_t *log);
dbus_bool_t bus_client_policy_check_can_receive (BusClientPolicy *policy,
BusRegistry *registry,
dbus_bool_t requested_reply,
DBusConnection *sender,
DBusConnection *addressed_recipient,
DBusConnection *proposed_recipient,
- DBusMessage *message);
+ DBusMessage *message,
+ dbus_int32_t *toggles);
dbus_bool_t bus_client_policy_check_can_own (BusClientPolicy *policy,
DBusConnection *connection,
const DBusString *service_name);
diff --git a/bus/session.conf.in b/bus/session.conf.in
index b2dee5b3..794eb8da 100644
--- a/bus/session.conf.in
+++ b/bus/session.conf.in
@@ -8,6 +8,10 @@
<!-- Our well-known bus type, don't change this -->
<type>session</type>
+ <!-- If we fork, keep the user's original umask to avoid affecting
+ the behavior of child processes. -->
+ <keep_umask/>
+
<listen>unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@</listen>
<standard_session_servicedirs />
diff --git a/bus/system.conf.in b/bus/system.conf.in
index 6a71926e..92f4cc42 100644
--- a/bus/system.conf.in
+++ b/bus/system.conf.in
@@ -29,6 +29,9 @@
<!-- Write a pid file -->
<pidfile>@DBUS_SYSTEM_PID_FILE@</pidfile>
+ <!-- Enable logging to syslog -->
+ <syslog/>
+
<!-- Only allow socket-credentials-based authentication -->
<auth>EXTERNAL</auth>
@@ -39,21 +42,29 @@
<listen>@DBUS_SYSTEM_BUS_DEFAULT_ADDRESS@</listen>
<policy context="default">
- <!-- Deny everything then punch holes -->
- <deny send_interface="*"/>
- <deny receive_interface="*"/>
- <deny own="*"/>
- <!-- But allow all users to connect -->
+ <!-- All users can connect to system bus -->
<allow user="*"/>
+
+ <!-- Holes must be punched in service configuration files for
+ name ownership and sending method calls -->
+ <deny own="*"/>
+ <deny send_type="method_call"/>
+
+ <!-- Signals and reply messages (method returns, errors) are allowed
+ by default -->
+ <allow send_type="signal"/>
+ <allow send_requested_reply="true" send_type="method_return"/>
+ <allow send_requested_reply="true" send_type="error"/>
+
+ <!-- All messages may be received by default -->
+ <allow receive_type="method_call"/>
+ <allow receive_type="method_return"/>
+ <allow receive_type="error"/>
+ <allow receive_type="signal"/>
+
<!-- Allow anyone to talk to the message bus -->
- <!-- FIXME I think currently these allow rules are always implicit
- even if they aren't in here -->
<allow send_destination="org.freedesktop.DBus"/>
- <allow receive_sender="org.freedesktop.DBus"/>
- <!-- valid replies are always allowed -->
- <allow send_requested_reply="true"/>
- <allow receive_requested_reply="true"/>
- <!-- disallow changing the activation environment of system services -->
+ <!-- But disallow some specific bus services -->
<deny send_destination="org.freedesktop.DBus"
send_interface="org.freedesktop.DBus"
send_member="UpdateActivationEnvironment"/>
diff --git a/configure.in b/configure.in
index 8c05b11c..9d825c7d 100644
--- a/configure.in
+++ b/configure.in
@@ -8,7 +8,7 @@ m4_define([dbus_version],
[dbus_major_version.dbus_minor_version.dbus_micro_version])
AC_INIT(dbus, [dbus_version])
-AC_CANONICAL_TARGET
+AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.9 tar-ustar])
AM_CONFIG_HEADER(config.h)
@@ -175,6 +175,12 @@ ld_supports_flag() {
fi
}
+if test x$USE_MAINTAINER_MODE = xyes; then
+ if cc_supports_flag "-Werror"; then
+ CFLAGS="$CFLAGS -Werror"
+ fi
+fi
+
if test "x$GCC" = "xyes"; then
changequote(,)dnl
case " $CFLAGS " in
@@ -221,11 +227,6 @@ if test "x$GCC" = "xyes"; then
esac
case " $CFLAGS " in
- *[\ \ ]-Wsign-compare[\ \ ]*) ;;
- *) CFLAGS="$CFLAGS -Wsign-compare" ;;
- esac
-
- case " $CFLAGS " in
*[\ \ ]-Wdeclaration-after-statement[\ \ ]*) ;;
*) if cc_supports_flag -Wdeclaration-after-statement; then
CFLAGS="$CFLAGS -Wdeclaration-after-statement"
@@ -264,6 +265,41 @@ if test "x$GCC" = "xyes"; then
fi
;;
esac
+
+ ### Disabled warnings, and compiler flag overrides
+
+ # Let's just ignore unused for now
+ case " $CFLAGS " in
+ *[\ \ ]-Wno-unused[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wno-unused" ;;
+ esac
+
+ # This group is for warnings we currently don't pass.
+ # We would like to, however. Please fix.
+
+ # http://bugs.freedesktop.org/show_bug.cgi?id=17433
+ case " $CFLAGS " in
+ *[\ \ ]-Wno-sign-compare[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wno-sign-compare" ;;
+ esac
+ case " $CFLAGS " in
+ *[\ \ ]-Wno-pointer-sign[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wno-pointer-sign" ;;
+ esac
+
+ # http://bugs.freedesktop.org/show_bug.cgi?id=19195
+ case " $CFLAGS " in
+ *[\ \ ]-Wno-format[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wno-format" ;;
+ esac
+
+ # This one is special - it's not a warning override.
+ # http://bugs.freedesktop.org/show_bug.cgi?id=10599
+ case " $CFLAGS " in
+ *[\ \ ]-fno-strict-aliasing[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -fno-strict-aliasing" ;;
+ esac
+ ### End disabled warnings
if test "x$enable_ansi" = "xyes"; then
case " $CFLAGS " in
@@ -284,7 +320,7 @@ if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -pedantic" ;;
- esac
+ esac
fi
if test x$enable_gcov = xyes; then
case " $CFLAGS " in
@@ -321,7 +357,7 @@ AC_MSG_RESULT($ac_gcsections)
# Add -D_POSIX_PTHREAD_SEMANTICS if on Solaris
#
-case $target_os in
+case $host_os in
solaris*)
CFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS" ;;
esac
@@ -775,6 +811,7 @@ AC_CHECK_FUNCS(getpeerucred getpeereid)
#### Abstract sockets
+if ! test x$enable_abstract_sockets = xno; then
AC_LANG_PUSH(C)
AC_CACHE_CHECK([abstract socket namespace],
ac_cv_have_abstract_sockets,
@@ -818,6 +855,7 @@ AC_CACHE_CHECK([abstract socket namespace],
[ac_cv_have_abstract_sockets=no]
)])
AC_LANG_POP(C)
+fi
if test x$enable_abstract_sockets = xyes; then
if test x$ac_cv_have_abstract_sockets = xno; then
@@ -851,30 +889,27 @@ AC_CHECK_LIB(expat, XML_ParserCreate_MM,
dbus_use_libxml=false
dbus_use_expat=false
if test x$with_xml = xexpat; then
- dbus_use_expat=true
if ! $have_expat ; then
AC_MSG_ERROR([Explicitly requested expat but expat not found])
fi
+ dbus_use_expat=true
elif test x$with_xml = xlibxml; then
- dbus_use_libxml=true
PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= 2.6.0, have_libxml=true, have_libxml=false)
-
if ! $have_libxml ; then
AC_MSG_ERROR([Explicitly requested libxml but libxml not found])
fi
+ dbus_use_libxml=true
else
### expat is the default because libxml can't currently survive
### our brutal OOM-handling unit test setup.
### http://bugzilla.gnome.org/show_bug.cgi?id=109368
- if $have_expat ; then
- with_xml=expat
- dbus_use_expat=true
- elif $have_libxml ; then
- with_xml=libxml
- dbus_use_libxml=true
- else
- AC_MSG_ERROR([No XML library found, check config.log for failed attempts])
+ if test x$have_expat = xfalse; then
+ AC_MSG_ERROR([Could not find expat.h, check config.log for failed attempts])
fi
+ ### By default, only use Expat since it's tested and known to work. If you're a
+ ### general-purpose OS vendor, please don't enable libxml. For embedded use
+ ### if your OS is built around libxml, that's another case.
+ dbus_use_expat=true
fi
AM_CONDITIONAL(DBUS_USE_EXPAT, $dbus_use_expat)
@@ -957,7 +992,7 @@ AM_CONDITIONAL(DBUS_BUS_ENABLE_INOTIFY, test x$have_inotify = xyes)
if test x$enable_dnotify = xno ; then
have_dnotify=no;
else
- if test x$have_inotify = xno -a x$target_os = xlinux-gnu -o x$target_os = xlinux; then
+ if test x$have_inotify = xno -a x$host_os = xlinux-gnu -o x$host_os = xlinux; then
have_dnotify=yes;
else
have_dnotify=no;
@@ -995,7 +1030,7 @@ dnl console owner file
if test x$enable_console_owner_file = xno ; then
have_console_owner_file=no;
else
- case $target_os in
+ case $host_os in
solaris*)
have_console_owner_file=yes;
AC_DEFINE(HAVE_CONSOLE_OWNER_FILE,1,[Have console owner file])
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index a960a991..ae07adf0 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -448,7 +448,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection,
DBusList *link)
{
DBusPendingCall *pending;
- dbus_int32_t reply_serial;
+ dbus_uint32_t reply_serial;
DBusMessage *message;
_dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
@@ -459,7 +459,7 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection,
/* If this is a reply we're waiting on, remove timeout for it */
reply_serial = dbus_message_get_reply_serial (message);
- if (reply_serial != -1)
+ if (reply_serial != 0)
{
pending = _dbus_hash_table_lookup_int (connection->pending_replies,
reply_serial);
diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h
index d4c8d160..8eed2bd2 100644
--- a/dbus/dbus-credentials.h
+++ b/dbus/dbus-credentials.h
@@ -47,6 +47,9 @@ dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials
dbus_uid_t uid);
dbus_bool_t _dbus_credentials_add_windows_sid (DBusCredentials *credentials,
const char *windows_sid);
+dbus_bool_t _dbus_credentials_add_adt_audit_data (DBusCredentials *credentials,
+ void *audit_data,
+ dbus_int32_t size);
dbus_bool_t _dbus_credentials_include (DBusCredentials *credentials,
DBusCredentialType type);
dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials);
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c
index 0a33ff15..38fbe2d6 100644
--- a/dbus/dbus-marshal-basic.c
+++ b/dbus/dbus-marshal-basic.c
@@ -508,59 +508,74 @@ _dbus_marshal_read_basic (const DBusString *str,
int *new_pos)
{
const char *str_data;
- DBusBasicValue *vp;
_dbus_assert (dbus_type_is_basic (type));
str_data = _dbus_string_get_const_data (str);
- vp = value;
+ /* Below we volatile types to avoid aliasing issues;
+ * see http://bugs.freedesktop.org/show_bug.cgi?id=20137
+ */
+
switch (type)
{
case DBUS_TYPE_BYTE:
- vp->byt = _dbus_string_get_byte (str, pos);
+ {
+ volatile unsigned char *vp = value;
+ *vp = (unsigned char) _dbus_string_get_byte (str, pos);
(pos)++;
+ }
break;
case DBUS_TYPE_INT16:
case DBUS_TYPE_UINT16:
+ {
+ volatile dbus_uint16_t *vp = value;
pos = _DBUS_ALIGN_VALUE (pos, 2);
- vp->u16 = *(dbus_uint16_t *)(str_data + pos);
+ *vp = *(dbus_uint16_t *)(str_data + pos);
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
- vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16);
+ *vp = DBUS_UINT16_SWAP_LE_BE (*vp);
pos += 2;
+ }
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
case DBUS_TYPE_BOOLEAN:
+ {
+ volatile dbus_uint32_t *vp = value;
pos = _DBUS_ALIGN_VALUE (pos, 4);
- vp->u32 = *(dbus_uint32_t *)(str_data + pos);
+ *vp = *(dbus_uint32_t *)(str_data + pos);
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
- vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32);
+ *vp = DBUS_UINT32_SWAP_LE_BE (*vp);
pos += 4;
+ }
break;
case DBUS_TYPE_INT64:
case DBUS_TYPE_UINT64:
case DBUS_TYPE_DOUBLE:
+ {
+ volatile dbus_uint64_t *vp = value;
pos = _DBUS_ALIGN_VALUE (pos, 8);
#ifdef DBUS_HAVE_INT64
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
- vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
+ *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
else
- vp->u64 = *(dbus_uint64_t*)(str_data + pos);
+ *vp = *(dbus_uint64_t*)(str_data + pos);
#else
- vp->u64 = *(DBus8ByteStruct*) (str_data + pos);
+ *vp = *(DBus8ByteStruct*) (str_data + pos);
swap_8_octets (vp, byte_order);
#endif
pos += 8;
+ }
break;
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
{
int len;
+ volatile char **vp = value;
len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos);
- vp->str = (char*) str_data + pos;
+ *vp = (char*) str_data + pos;
pos += len + 1; /* length plus nul */
}
@@ -568,11 +583,12 @@ _dbus_marshal_read_basic (const DBusString *str,
case DBUS_TYPE_SIGNATURE:
{
int len;
+ volatile char **vp = value;
len = _dbus_string_get_byte (str, pos);
pos += 1;
- vp->str = (char*) str_data + pos;
+ *vp = (char*) str_data + pos;
pos += len + 1; /* length plus nul */
}
@@ -1333,7 +1349,7 @@ _dbus_verbose_bytes (const unsigned char *data,
if (aligned != data)
{
- _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
+ _dbus_verbose ("%4ld\t%p: ", - (long)(data - aligned), aligned);
while (aligned != data)
{
_dbus_verbose (" ");
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c
index 6c2902e2..76ee344f 100644
--- a/dbus/dbus-marshal-recursive.c
+++ b/dbus/dbus-marshal-recursive.c
@@ -1654,7 +1654,7 @@ writer_recurse_init_and_check (DBusTypeWriter *writer,
_dbus_type_to_string (expected),
_dbus_string_get_const_data (writer->type_str), writer->type_pos);
else
- _dbus_warn_check_failed ("Writing an element of type %s, but no value is expected here\n",
+ _dbus_warn_check_failed ("Writing an element of type %s, but no value is expected here\n"
"The overall signature expected here was '%s' and we are on byte %d of that signature.\n",
_dbus_type_to_string (sub->container_type),
_dbus_string_get_const_data (writer->type_str), writer->type_pos);
diff --git a/dbus/dbus-marshal-validate-util.c b/dbus/dbus-marshal-validate-util.c
index f2901d74..ac901c38 100644
--- a/dbus/dbus-marshal-validate-util.c
+++ b/dbus/dbus-marshal-validate-util.c
@@ -227,7 +227,8 @@ _dbus_marshal_validate_test (void)
"not a valid signature",
"123",
".",
- "("
+ "(",
+ "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */
};
/* Signature with reason */
diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
index e63a463b..ee955485 100644
--- a/dbus/dbus-marshal-validate.c
+++ b/dbus/dbus-marshal-validate.c
@@ -246,13 +246,15 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
}
}
- if (last == DBUS_DICT_ENTRY_BEGIN_CHAR &&
- !dbus_type_is_basic (*p))
+ if (last == DBUS_DICT_ENTRY_BEGIN_CHAR)
{
- result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
- goto out;
+ if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p)))
+ {
+ result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
+ goto out;
+ }
}
-
+
last = *p;
++p;
}
@@ -369,12 +371,30 @@ validate_body_helper (DBusTypeReader *reader,
/* p may now be == end */
_dbus_assert (p <= end);
-
+
if (current_type == DBUS_TYPE_ARRAY)
{
int array_elem_type = _dbus_type_reader_get_element_type (reader);
+
+ if (!_dbus_type_is_valid (array_elem_type))
+ {
+ return DBUS_INVALID_UNKNOWN_TYPECODE;
+ }
+
alignment = _dbus_type_get_alignment (array_elem_type);
- p = _DBUS_ALIGN_ADDRESS (p, alignment);
+
+ a = _DBUS_ALIGN_ADDRESS (p, alignment);
+
+ /* a may now be == end */
+ if (a > end)
+ return DBUS_INVALID_NOT_ENOUGH_DATA;
+
+ while (p != a)
+ {
+ if (*p != '\0')
+ return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
+ ++p;
+ }
}
if (claimed_len > (unsigned long) (end - p))
@@ -405,6 +425,7 @@ validate_body_helper (DBusTypeReader *reader,
DBusTypeReader sub;
DBusValidity validity;
const unsigned char *array_end;
+ int array_elem_type;
if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
@@ -417,16 +438,46 @@ validate_body_helper (DBusTypeReader *reader,
array_end = p + claimed_len;
- while (p < array_end)
+ array_elem_type = _dbus_type_reader_get_element_type (reader);
+
+ /* avoid recursive call to validate_body_helper if this is an array
+ * of fixed-size elements
+ */
+ if (dbus_type_is_fixed (array_elem_type))
+ {
+ /* bools need to be handled differently, because they can
+ * have an invalid value
+ */
+ if (array_elem_type == DBUS_TYPE_BOOLEAN)
+ {
+ dbus_uint32_t v;
+ alignment = _dbus_type_get_alignment (array_elem_type);
+
+ while (p < array_end)
+ {
+ v = _dbus_unpack_uint32 (byte_order, p);
+
+ if (!(v == 0 || v == 1))
+ return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
+
+ p += alignment;
+ }
+ }
+
+ else
+ {
+ p = array_end;
+ }
+ }
+
+ else
{
- /* FIXME we are calling a function per array element! very bad
- * need if (dbus_type_is_fixed(elem_type)) here to just skip
- * big blocks of ints/bytes/etc.
- */
-
- validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
- if (validity != DBUS_VALID)
- return validity;
+ while (p < array_end)
+ {
+ validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
+ if (validity != DBUS_VALID)
+ return validity;
+ }
}
if (p != array_end)
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index cd447985..e2c4771e 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -1726,7 +1726,7 @@ _dbus_message_iter_init_common (DBusMessage *message,
*
* The easiest way to iterate is like this:
* @code
- * dbus_message_iter_init (&iter);
+ * dbus_message_iter_init (message, &iter);
* while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
* dbus_message_iter_next (&iter);
* @endcode
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index 35ccba6c..f4e3b587 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -36,6 +36,8 @@
#include <errno.h>
#endif
+extern char **environ;
+
/**
* @addtogroup DBusInternalsUtils
* @{
@@ -914,8 +916,6 @@ do_exec (int child_err_report_fd,
if (envp == NULL)
{
- extern char **environ;
-
_dbus_assert (environ != NULL);
envp = environ;
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 1e45649f..29d234a4 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -79,8 +79,8 @@
#define O_BINARY 0
#endif
-#ifndef _AI_ADDRCONFIG
-#define _AI_ADDRCONFIG 0
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
#endif
#ifndef HAVE_SOCKLEN_T
@@ -758,6 +758,7 @@ _dbus_connect_tcp_socket (const char *host,
const char *family,
DBusError *error)
{
+ int saved_errno = 0;
int fd = -1, res;
struct addrinfo hints;
struct addrinfo *ai, *tmp;
@@ -783,7 +784,7 @@ _dbus_connect_tcp_socket (const char *host,
else
{
dbus_set_error (error,
- _dbus_error_from_errno (errno),
+ DBUS_ERROR_BAD_ADDRESS,
"Unknown address family %s", family);
return -1;
}
@@ -814,6 +815,7 @@ _dbus_connect_tcp_socket (const char *host,
if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
{
+ saved_errno = errno;
_dbus_close(fd, NULL);
fd = -1;
tmp = tmp->ai_next;
@@ -827,9 +829,9 @@ _dbus_connect_tcp_socket (const char *host,
if (fd == -1)
{
dbus_set_error (error,
- _dbus_error_from_errno (errno),
+ _dbus_error_from_errno (saved_errno),
"Failed to connect to socket \"%s:%s\" %s",
- host, port, _dbus_strerror(errno));
+ host, port, _dbus_strerror(saved_errno));
return -1;
}
@@ -867,6 +869,7 @@ _dbus_listen_tcp_socket (const char *host,
int **fds_p,
DBusError *error)
{
+ int saved_errno;
int nlisten_fd = 0, *listen_fd = NULL, res, i;
struct addrinfo hints;
struct addrinfo *ai, *tmp;
@@ -885,7 +888,7 @@ _dbus_listen_tcp_socket (const char *host,
else
{
dbus_set_error (error,
- _dbus_error_from_errno (errno),
+ DBUS_ERROR_BAD_ADDRESS,
"Unknown address family %s", family);
return -1;
}
@@ -917,8 +920,9 @@ _dbus_listen_tcp_socket (const char *host,
if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
{
+ saved_errno = errno;
_dbus_close(fd, NULL);
- if (errno == EADDRINUSE)
+ if (saved_errno == EADDRINUSE)
{
/* Depending on kernel policy, it may or may not
be neccessary to bind to both IPv4 & 6 addresses
@@ -926,28 +930,30 @@ _dbus_listen_tcp_socket (const char *host,
tmp = tmp->ai_next;
continue;
}
- dbus_set_error (error, _dbus_error_from_errno (errno),
+ dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"Failed to bind socket \"%s:%s\": %s",
- host ? host : "*", port, _dbus_strerror (errno));
+ host ? host : "*", port, _dbus_strerror (saved_errno));
goto failed;
}
if (listen (fd, 30 /* backlog */) < 0)
{
+ saved_errno = errno;
_dbus_close (fd, NULL);
- dbus_set_error (error, _dbus_error_from_errno (errno),
+ dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"Failed to listen on socket \"%s:%s\": %s",
- host ? host : "*", port, _dbus_strerror (errno));
+ host ? host : "*", port, _dbus_strerror (saved_errno));
goto failed;
}
newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
if (!newlisten_fd)
{
+ saved_errno = errno;
_dbus_close (fd, NULL);
- dbus_set_error (error, _dbus_error_from_errno (errno),
+ dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"Failed to allocate file handle array: %s",
- _dbus_strerror (errno));
+ _dbus_strerror (saved_errno));
goto failed;
}
listen_fd = newlisten_fd;
@@ -1493,7 +1499,11 @@ fill_user_info (DBusUserInfo *info,
/* retrieve maximum needed size for buf */
buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
- if (buflen <= 0)
+ /* sysconf actually returns a long, but everything else expects size_t,
+ * so just recast here.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=17061
+ */
+ if ((long) buflen <= 0)
buflen = 1024;
result = -1;
@@ -2224,6 +2234,15 @@ _dbus_string_save_to_file (const DBusString *str,
total += bytes_written;
}
+ if (fsync(fd))
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Could not synchronize file %s: %s",
+ tmp_filename_c, _dbus_strerror (errno));
+
+ goto out;
+ }
+
if (!_dbus_close (fd, NULL))
{
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -2767,7 +2786,6 @@ _dbus_full_duplex_pipe (int *fd1,
#endif
}
-
/**
* Measure the length of the given format string and arguments,
* not including the terminating nul.
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c
index 55eb9346..df9f7116 100644
--- a/dbus/dbus-sysdeps-util-unix.c
+++ b/dbus/dbus-sysdeps-util-unix.c
@@ -43,6 +43,8 @@
#include <sys/socket.h>
#include <dirent.h>
#include <sys/un.h>
+#include <syslog.h>
+#include <syslog.h>
#ifdef HAVE_LIBAUDIT
#include <sys/prctl.h>
#include <sys/capability.h>
@@ -69,12 +71,14 @@
* @param pidfile #NULL, or pidfile to create
* @param print_pid_pipe pipe to print daemon's pid to, or -1 for none
* @param error return location for errors
+ * @param keep_umask #TRUE to keep the original umask
* @returns #FALSE on failure
*/
dbus_bool_t
_dbus_become_daemon (const DBusString *pidfile,
DBusPipe *print_pid_pipe,
- DBusError *error)
+ DBusError *error,
+ dbus_bool_t keep_umask)
{
const char *s;
pid_t child_pid;
@@ -121,9 +125,12 @@ _dbus_become_daemon (const DBusString *pidfile,
_dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
}
- /* Get a predictable umask */
- _dbus_verbose ("setting umask\n");
- umask (022);
+ if (!keep_umask)
+ {
+ /* Get a predictable umask */
+ _dbus_verbose ("setting umask\n");
+ umask (022);
+ }
_dbus_verbose ("calling setsid()\n");
if (setsid () == -1)
@@ -451,6 +458,38 @@ _dbus_change_to_daemon_user (const char *user,
return FALSE;
}
+void
+_dbus_init_system_log (void)
+{
+ openlog ("dbus", LOG_PID, LOG_DAEMON);
+}
+
+/**
+ * Log an informative message. Intended for use primarily by
+ * the system bus.
+ *
+ * @param msg a printf-style format string
+ * @param args arguments for the format string
+ */
+void
+_dbus_log_info (const char *msg, va_list args)
+{
+ vsyslog (LOG_DAEMON|LOG_NOTICE, msg, args);
+}
+
+/**
+ * Log a security-related message. Intended for use primarily by
+ * the system bus.
+ *
+ * @param msg a printf-style format string
+ * @param args arguments for the format string
+ */
+void
+_dbus_log_security (const char *msg, va_list args)
+{
+ vsyslog (LOG_AUTH|LOG_NOTICE, msg, args);
+}
+
/** Installs a UNIX signal handler
*
* @param sig the signal to handle
@@ -836,7 +875,11 @@ fill_group_info (DBusGroupInfo *info,
/* retrieve maximum needed size for buf */
buflen = sysconf (_SC_GETGR_R_SIZE_MAX);
- if (buflen <= 0)
+ /* sysconf actually returns a long, but everything else expects size_t,
+ * so just recast here.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=17061
+ */
+ if ((long) buflen <= 0)
buflen = 1024;
result = -1;
@@ -1096,3 +1139,99 @@ _dbus_string_get_dirname (const DBusString *filename,
}
/** @} */ /* DBusString stuff */
+static void
+string_squash_nonprintable (DBusString *str)
+{
+ char *buf;
+ int i, len;
+
+ buf = _dbus_string_get_data (str);
+ len = _dbus_string_get_length (str);
+
+ for (i = 0; i < len; i++)
+ if (buf[i] == '\0')
+ buf[i] = ' ';
+ else if (buf[i] < 0x20 || buf[i] > 127)
+ buf[i] = '?';
+}
+
+/**
+ * Get a printable string describing the command used to execute
+ * the process with pid. This string should only be used for
+ * informative purposes such as logging; it may not be trusted.
+ *
+ * The command is guaranteed to be printable ASCII and no longer
+ * than max_len.
+ *
+ * @param pid Process id
+ * @param str Append command to this string
+ * @param max_len Maximum length of returned command
+ * @param error return location for errors
+ * @returns #FALSE on error
+ */
+dbus_bool_t
+_dbus_command_for_pid (unsigned long pid,
+ DBusString *str,
+ int max_len,
+ DBusError *error)
+{
+ /* This is all Linux-specific for now */
+ DBusString path;
+ DBusString cmdline;
+ int fd;
+
+ if (!_dbus_string_init (&path))
+ {
+ _DBUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!_dbus_string_init (&cmdline))
+ {
+ _DBUS_SET_OOM (error);
+ _dbus_string_free (&path);
+ return FALSE;
+ }
+
+ if (!_dbus_string_append_printf (&path, "/proc/%ld/cmdline", pid))
+ goto oom;
+
+ fd = open (_dbus_string_get_const_data (&path), O_RDONLY);
+ if (fd < 0)
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to open \"%s\": %s",
+ _dbus_string_get_const_data (&path),
+ _dbus_strerror (errno));
+ goto fail;
+ }
+
+ if (!_dbus_read (fd, &cmdline, max_len))
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to read from \"%s\": %s",
+ _dbus_string_get_const_data (&path),
+ _dbus_strerror (errno));
+ goto fail;
+ }
+
+ if (!_dbus_close (fd, error))
+ goto fail;
+
+ string_squash_nonprintable (&cmdline);
+
+ if (!_dbus_string_copy (&cmdline, 0, str, _dbus_string_get_length (str)))
+ goto oom;
+
+ _dbus_string_free (&cmdline);
+ _dbus_string_free (&path);
+ return TRUE;
+oom:
+ _DBUS_SET_OOM (error);
+fail:
+ _dbus_string_free (&cmdline);
+ _dbus_string_free (&path);
+ return FALSE;
+} \ No newline at end of file
diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c
index 8608ad0e..6358531b 100644
--- a/dbus/dbus-sysdeps-util-win.c
+++ b/dbus/dbus-sysdeps-util-win.c
@@ -70,12 +70,14 @@ errno_t strcpy_s(char *dest, size_t size, char *src)
* @param pidfile #NULL, or pidfile to create
* @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none
* @param error return location for errors
+ * @param keep_umask #TRUE to keep the original umask
* @returns #FALSE on failure
*/
dbus_bool_t
_dbus_become_daemon (const DBusString *pidfile,
DBusPipe *print_pid_pipe,
- DBusError *error)
+ DBusError *error,
+ dbus_bool_t keep_umask)
{
return TRUE;
}
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index d740f875..00a1a3de 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -51,6 +51,8 @@ _DBUS_DEFINE_GLOBAL_LOCK (win_fds);
_DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
_DBUS_DEFINE_GLOBAL_LOCK (system_users);
+extern char **environ;
+
/**
* @defgroup DBusSysdeps Internal system-dependent API
* @ingroup DBusInternals
@@ -191,7 +193,6 @@ _dbus_clearenv (void)
if (clearenv () != 0)
rc = FALSE;
#else
- extern char **environ;
if (environ != NULL)
environ[0] = NULL;
@@ -210,7 +211,6 @@ char **
_dbus_get_environment (void)
{
int i, length;
- extern char **environ;
char **environment;
_dbus_assert (environ != NULL);
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index 80236f05..b766f3f9 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -400,7 +400,8 @@ void _dbus_print_backtrace (void);
dbus_bool_t _dbus_become_daemon (const DBusString *pidfile,
DBusPipe *print_pid_pipe,
- DBusError *error);
+ DBusError *error,
+ dbus_bool_t keep_umask);
dbus_bool_t _dbus_verify_daemon_user (const char *user);
dbus_bool_t _dbus_change_to_daemon_user (const char *user,
@@ -411,6 +412,11 @@ dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
dbus_pid_t pid_to_write,
DBusError *error);
+dbus_bool_t _dbus_command_for_pid (unsigned long pid,
+ DBusString *str,
+ int max_len,
+ DBusError *error);
+
/** A UNIX signal handler */
typedef void (* DBusSignalHandler) (int sig);
@@ -420,6 +426,10 @@ void _dbus_set_signal_handler (int sig,
dbus_bool_t _dbus_user_at_console (const char *username,
DBusError *error);
+void _dbus_init_system_log (void);
+void _dbus_log_info (const char *msg, va_list args);
+void _dbus_log_security (const char *msg, va_list args);
+
/* Define DBUS_VA_COPY() to do the right thing for copying va_list variables.
* config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy.
*/
diff --git a/doc/busconfig.dtd b/doc/busconfig.dtd
index 84593fe0..0cc519b4 100644
--- a/doc/busconfig.dtd
+++ b/doc/busconfig.dtd
@@ -1,6 +1,7 @@
<!ELEMENT busconfig (user |
type |
fork |
+ keep_umask |
listen |
pidfile |
includedir |
@@ -21,6 +22,7 @@
<!ELEMENT type (#PCDATA)>
<!ELEMENT pidfile (#PCDATA)>
<!ELEMENT fork EMPTY>
+<!ELEMENT keep_umask EMPTY>
<!ELEMENT include (#PCDATA)>
<!ATTLIST include
diff --git a/test/name-test/Makefile.am b/test/name-test/Makefile.am
index 17e05bec..10a2536d 100644
--- a/test/name-test/Makefile.am
+++ b/test/name-test/Makefile.am
@@ -5,12 +5,12 @@ INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_TEST_C
## TESTS
if DBUS_BUILD_TESTS
TESTS_ENVIRONMENT=DBUS_TOP_BUILDDIR=@abs_top_builddir@ DBUS_TOP_SRCDIR=@abs_top_srcdir@
-TESTS=run-test.sh
+TESTS=run-test.sh run-test-systemserver.sh
else
TESTS=
endif
-EXTRA_DIST=run-test.sh
+EXTRA_DIST=run-test.sh run-test-systemserver.sh test-wait-for-echo.py
if DBUS_BUILD_TESTS
diff --git a/test/name-test/run-test-systemserver.sh b/test/name-test/run-test-systemserver.sh
new file mode 100755
index 00000000..34dd6487
--- /dev/null
+++ b/test/name-test/run-test-systemserver.sh
@@ -0,0 +1,50 @@
+#! /bin/sh
+die()
+{
+ if ! test -z "$DBUS_SESSION_BUS_PID" ; then
+ echo "killing message bus "$DBUS_SESSION_BUS_PID >&2
+ kill -9 $DBUS_SESSION_BUS_PID
+ fi
+ echo $SCRIPTNAME: $* >&2
+
+ exit 1
+}
+
+SCRIPTNAME=$0
+MODE=$1
+
+## so the tests can complain if you fail to use the script to launch them
+DBUS_TEST_NAME_RUN_TEST_SCRIPT=1
+export DBUS_TEST_NAME_RUN_TEST_SCRIPT
+
+SOURCE_CONFIG_FILE=$DBUS_TOP_SRCDIR/test/name-test/tmp-session-like-system.conf
+export SOURCE_CONFIG_FILE
+# Rerun ourselves with tmp session bus if we're not already
+if test -z "$DBUS_TEST_NAME_IN_SYS_RUN_TEST"; then
+ DBUS_TEST_NAME_IN_SYS_RUN_TEST=1
+ export DBUS_TEST_NAME_IN_SYS_RUN_TEST
+ exec $DBUS_TOP_SRCDIR/tools/run-with-tmp-session-bus.sh $SCRIPTNAME $MODE
+fi
+
+if test -n "$DBUS_TEST_MONITOR"; then
+ dbus-monitor --session &
+fi
+
+echo "running test-expected-echo-fail"
+${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/tools/dbus-send --print-reply --dest=org.freedesktop.DBus.TestSuiteEchoService /org/freedesktop/TestSuite org.freedesktop.TestSuite.Echo string:hi >echo-error-output.tmp 2>&1
+if ! grep -q 'DBus.Error' echo-error-output.tmp; then
+ echo "Didn't get expected failure; output was:"
+ echo "====="
+ cat echo-error-output.tmp
+ echo "====="
+ exit 1
+fi
+
+echo "running test echo signal"
+if ! python ./test-wait-for-echo.py; then
+ echo "Failed test-wait-for-echo"
+ exit 1
+fi
+
+
+exit 0
diff --git a/test/name-test/test-wait-for-echo.py b/test/name-test/test-wait-for-echo.py
new file mode 100755
index 00000000..bd09e459
--- /dev/null
+++ b/test/name-test/test-wait-for-echo.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+import os,sys
+
+try:
+ import gobject
+ import dbus
+ import dbus.mainloop.glib
+except:
+ print "Failed import, aborting test"
+ sys.exit(0)
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+loop = gobject.MainLoop()
+
+exitcode = 0
+
+def handle_noreceipt():
+ print "Failed to get signal"
+ global exitcode
+ exitcode = 1
+ loop.quit()
+
+gobject.timeout_add(7000, handle_noreceipt)
+
+bus = dbus.SessionBus()
+
+def sighandler(*args, **kwargs):
+ print "got signal"
+ loop.quit()
+
+bus.add_signal_receiver(sighandler, dbus_interface='org.freedesktop.TestSuite', signal_name='Foo')
+
+o = bus.get_object('org.freedesktop.DBus.TestSuiteEchoService', '/org/freedesktop/TestSuite')
+i = dbus.Interface(o, 'org.freedesktop.TestSuite')
+def nullhandler(*args, **kwargs):
+ pass
+i.EmitFoo(reply_handler=nullhandler, error_handler=nullhandler)
+
+loop.run()
+sys.exit(exitcode)
diff --git a/test/name-test/tmp-session-like-system.conf b/test/name-test/tmp-session-like-system.conf
new file mode 100644
index 00000000..29ab115f
--- /dev/null
+++ b/test/name-test/tmp-session-like-system.conf
@@ -0,0 +1,91 @@
+<!-- This configuration file controls the per-user-login-session message bus.
+ Add a session-local.conf and edit that rather than changing this
+ file directly. -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <!-- Our well-known bus type, don't change this -->
+ <type>session</type>
+
+ <!-- If we fork, keep the user's original umask to avoid affecting
+ the behavior of child processes. -->
+ <keep_umask/>
+
+ <syslog/>
+
+ <listen>unix:tmpdir=/tmp</listen>
+
+ <standard_session_servicedirs />
+
+ <!-- intended to match system bus -->
+ <policy context="default">
+ <!-- All users can connect to system bus -->
+ <allow user="*"/>
+
+ <!-- Holes must be punched in service configuration files for
+ name ownership and sending method calls -->
+ <deny own="*"/>
+ <deny send_type="method_call"/>
+
+ <!-- Signals and reply messages (method returns, errors) are allowed
+ by default -->
+ <allow send_type="signal"/>
+ <allow send_requested_reply="true" send_type="method_return"/>
+ <allow send_requested_reply="true" send_type="error"/>
+
+ <!-- All messages may be received by default -->
+ <allow receive_type="method_call"/>
+ <allow receive_type="method_return"/>
+ <allow receive_type="error"/>
+ <allow receive_type="signal"/>
+
+ <!-- Allow anyone to talk to the message bus -->
+ <allow send_destination="org.freedesktop.DBus"/>
+ <!-- But disallow some specific bus services -->
+ <deny send_destination="org.freedesktop.DBus"
+ send_interface="org.freedesktop.DBus"
+ send_member="UpdateActivationEnvironment"/>
+
+ <!-- Specific to the test suite -->
+ <allow own="org.freedesktop.DBus.TestSuiteEchoService"/>
+ <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+ <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService"
+ send_interface="org.freedesktop.TestSuite"
+ send_member="EmitFoo"/>
+ </policy>
+
+ <policy context="default">
+ <allow own="org.freedesktop.DBus.TestSuiteEchoService"/>
+ <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+ <allow send_destination="org.freedesktop.DBus.TestSuiteEchoService"
+ send_interface="org.freedesktop.TestSuite"
+ send_member="EmitFoo"/>
+ </policy>
+
+ <!-- For the session bus, override the default relatively-low limits
+ with essentially infinite limits, since the bus is just running
+ as the user anyway, using up bus resources is not something we need
+ to worry about. In some cases, we do set the limits lower than
+ "all available memory" if exceeding the limit is almost certainly a bug,
+ having the bus enforce a limit is nicer than a huge memory leak. But the
+ intent is that these limits should never be hit. -->
+
+ <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max -->
+ <limit name="max_incoming_bytes">1000000000</limit>
+ <limit name="max_outgoing_bytes">1000000000</limit>
+ <limit name="max_message_size">1000000000</limit>
+ <limit name="service_start_timeout">120000</limit>
+ <limit name="auth_timeout">240000</limit>
+ <limit name="max_completed_connections">100000</limit>
+ <limit name="max_incomplete_connections">10000</limit>
+ <limit name="max_connections_per_user">100000</limit>
+ <limit name="max_pending_service_starts">10000</limit>
+ <limit name="max_names_per_connection">50000</limit>
+ <limit name="max_match_rules_per_connection">50000</limit>
+ <limit name="max_replies_per_connection">50000</limit>
+ <limit name="reply_timeout">300000</limit>
+
+</busconfig>
diff --git a/tools/dbus-launch-x11.c b/tools/dbus-launch-x11.c
index 442e9ba2..b1824181 100644
--- a/tools/dbus-launch-x11.c
+++ b/tools/dbus-launch-x11.c
@@ -361,9 +361,9 @@ set_address_in_x11(char *address, pid_t pid)
}
/* Create our window */
- wid = XCreateSimpleWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10,
- 0, WhitePixel (xdisplay, 0),
- BlackPixel (xdisplay, 0));
+ wid = XCreateWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10,
+ 0, CopyFromParent, InputOnly, CopyFromParent,
+ 0, NULL);
verbose ("Created window %d\n", wid);
/* Save the property in the window */
diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c
index 216f7435..139d0aaf 100644
--- a/tools/dbus-launch.c
+++ b/tools/dbus-launch.c
@@ -402,7 +402,9 @@ signal_handler (int sig)
{
switch (sig)
{
+#ifdef SIGHUP
case SIGHUP:
+#endif
case SIGTERM:
got_sighup = TRUE;
break;
diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c
index d5fced34..ea15769f 100644
--- a/tools/dbus-print-message.c
+++ b/tools/dbus-print-message.c
@@ -263,7 +263,8 @@ print_message (DBusMessage *message, dbus_bool_t literal)
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
case DBUS_MESSAGE_TYPE_SIGNAL:
- printf (" path=%s; interface=%s; member=%s\n",
+ printf (" serial=%u path=%s; interface=%s; member=%s\n",
+ dbus_message_get_serial (message),
dbus_message_get_path (message),
dbus_message_get_interface (message),
dbus_message_get_member (message));
diff --git a/tools/dbus-send.c b/tools/dbus-send.c
index 407c0497..81a9c372 100644
--- a/tools/dbus-send.c
+++ b/tools/dbus-send.c
@@ -33,7 +33,7 @@ static const char *appname;
static void
usage (int ecode)
{
- fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
+ fprintf (stderr, "Usage: %s [--help] [--system | --session | --address=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
exit (ecode);
}
@@ -222,6 +222,8 @@ main (int argc, char *argv[])
const char *path = NULL;
int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
const char *type_str = NULL;
+ const char *address = NULL;
+ int session_or_system = FALSE;
appname = argv[0];
@@ -237,9 +239,29 @@ main (int argc, char *argv[])
char *arg = argv[i];
if (strcmp (arg, "--system") == 0)
- type = DBUS_BUS_SYSTEM;
+ {
+ type = DBUS_BUS_SYSTEM;
+ session_or_system = TRUE;
+ }
else if (strcmp (arg, "--session") == 0)
- type = DBUS_BUS_SESSION;
+ {
+ type = DBUS_BUS_SESSION;
+ session_or_system = TRUE;
+ }
+ else if (strstr (arg, "--address") == arg)
+ {
+ address = strchr (arg, '=');
+
+ if (address == NULL)
+ {
+ fprintf (stderr, "\"--address=\" requires an ADDRESS\n");
+ usage (1);
+ }
+ else
+ {
+ address = address + 1;
+ }
+ }
else if (strncmp (arg, "--print-reply", 13) == 0)
{
print_reply = TRUE;
@@ -271,6 +293,13 @@ main (int argc, char *argv[])
if (name == NULL)
usage (1);
+ if (session_or_system &&
+ (address != NULL))
+ {
+ fprintf (stderr, "\"--address\" may not be used with \"--system\" or \"--session\"\n");
+ usage (1);
+ }
+
if (type_str != NULL)
{
message_type = dbus_message_type_from_string (type_str);
@@ -284,11 +313,21 @@ main (int argc, char *argv[])
}
dbus_error_init (&error);
- connection = dbus_bus_get (type, &error);
+
+ if (address != NULL)
+ {
+ connection = dbus_connection_open (address, &error);
+ }
+ else
+ {
+ connection = dbus_bus_get (type, &error);
+ }
+
if (connection == NULL)
{
- fprintf (stderr, "Failed to open connection to %s message bus: %s\n",
- (type == DBUS_BUS_SYSTEM) ? "system" : "session",
+ fprintf (stderr, "Failed to open connection to \"%s\" message bus: %s\n",
+ (address != NULL) ? address :
+ ((type == DBUS_BUS_SYSTEM) ? "system" : "session"),
error.message);
dbus_error_free (&error);
exit (1);
diff --git a/tools/run-with-tmp-session-bus.sh b/tools/run-with-tmp-session-bus.sh
index f95ee62e..982184a2 100755
--- a/tools/run-with-tmp-session-bus.sh
+++ b/tools/run-with-tmp-session-bus.sh
@@ -26,8 +26,11 @@ SERVICE_DIR="$DBUS_TOP_BUILDDIR/test/data/valid-service-files"
ESCAPED_SERVICE_DIR=`echo $SERVICE_DIR | sed -e 's/\//\\\\\\//g'`
echo "escaped service dir is: $ESCAPED_SERVICE_DIR" >&2
+if test -z "$SOURCE_CONFIG_FILE"; then
+ SOURCE_CONFIG_FILE="$DBUS_TOP_BUILDDIR/bus/session.conf";
+fi
## create a configuration file based on the standard session.conf
-cat $DBUS_TOP_BUILDDIR/bus/session.conf | \
+cat $SOURCE_CONFIG_FILE | \
sed -e 's/<standard_session_servicedirs.*$/<servicedir>'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' | \
sed -e 's/<include.*$//g' \
> $CONFIG_FILE