X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bus%2Fbus.c;h=4d9fe1899e78b36b6bdc9e92a26efc4484cde839;hb=05902801b49789f37426754fc6b77f3665afe3b0;hp=2e9a5050e74652f3c499b74fde84a1f426c7df65;hpb=df89cfeb3808acc213c9620db6988611a34207c5;p=platform%2Fupstream%2Fdbus.git diff --git a/bus/bus.c b/bus/bus.c index 2e9a505..4d9fe18 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -2,9 +2,10 @@ /* bus.c message bus context object * * Copyright (C) 2003, 2004 Red Hat, Inc. + * Copyright (C) 2013 Samsung Electronics * * Licensed under the Academic Free License version 2.1 - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -14,7 +15,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -23,6 +24,9 @@ #include #include "bus.h" + +#include + #include "activation.h" #include "connection.h" #include "services.h" @@ -37,6 +41,15 @@ #include #include +#ifdef ENABLE_KDBUS_TRANSPORT +#include "kdbus-d.h" +#include +#endif + +#ifdef DBUS_CYGWIN +#include +#endif + struct BusContext { int refcount; @@ -60,6 +73,10 @@ struct BusContext unsigned int syslog : 1; unsigned int keep_umask : 1; unsigned int allow_anonymous : 1; + unsigned int systemd_activation : 1; +#ifdef ENABLE_KDBUS_TRANSPORT + DBusConnection *myKdbusConnection; //todo maybe can be rafctored and removed +#endif }; static dbus_int32_t server_data_slot = -1; @@ -76,7 +93,7 @@ server_get_context (DBusServer *server) { BusContext *context; BusServerData *bd; - + if (!dbus_server_allocate_data_slot (&server_data_slot)) return NULL; @@ -95,30 +112,15 @@ server_get_context (DBusServer *server) } static dbus_bool_t -server_watch_callback (DBusWatch *watch, - unsigned int condition, - void *data) -{ - /* FIXME this can be done in dbus-mainloop.c - * if the code in activation.c for the babysitter - * watch handler is fixed. - */ - - return dbus_watch_handle (watch, condition); -} - -static dbus_bool_t add_server_watch (DBusWatch *watch, void *data) { DBusServer *server = data; BusContext *context; - + context = server_get_context (server); - - return _dbus_loop_add_watch (context->loop, - watch, server_watch_callback, server, - NULL); + + return _dbus_loop_add_watch (context->loop, watch); } static void @@ -127,20 +129,22 @@ remove_server_watch (DBusWatch *watch, { DBusServer *server = data; BusContext *context; - + context = server_get_context (server); - - _dbus_loop_remove_watch (context->loop, - watch, server_watch_callback, server); -} + _dbus_loop_remove_watch (context->loop, watch); +} static void -server_timeout_callback (DBusTimeout *timeout, - void *data) +toggle_server_watch (DBusWatch *watch, + void *data) { - /* can return FALSE on OOM but we just let it fire again later */ - dbus_timeout_handle (timeout); + DBusServer *server = data; + BusContext *context; + + context = server_get_context (server); + + _dbus_loop_toggle_watch (context->loop, watch); } static dbus_bool_t @@ -149,11 +153,10 @@ add_server_timeout (DBusTimeout *timeout, { DBusServer *server = data; BusContext *context; - + context = server_get_context (server); - return _dbus_loop_add_timeout (context->loop, - timeout, server_timeout_callback, server, NULL); + return _dbus_loop_add_timeout (context->loop, timeout); } static void @@ -162,11 +165,10 @@ remove_server_timeout (DBusTimeout *timeout, { DBusServer *server = data; BusContext *context; - + context = server_get_context (server); - - _dbus_loop_remove_timeout (context->loop, - timeout, server_timeout_callback, server); + + _dbus_loop_remove_timeout (context->loop, timeout); } static void @@ -175,7 +177,7 @@ new_connection_callback (DBusServer *server, void *data) { BusContext *context = data; - + if (!bus_connections_setup_connection (context->connections, new_connection)) { _dbus_verbose ("No memory to setup new connection\n"); @@ -199,7 +201,7 @@ new_connection_callback (DBusServer *server, dbus_connection_set_max_message_unix_fds (new_connection, context->limits.max_message_unix_fds); - + dbus_connection_set_allow_anonymous (new_connection, context->allow_anonymous); @@ -209,8 +211,8 @@ new_connection_callback (DBusServer *server, static void free_server_data (void *data) { - BusServerData *bd = data; - + BusServerData *bd = data; + dbus_free (bd); } @@ -233,21 +235,21 @@ setup_server (BusContext *context, } bd->context = context; - + if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms)) { BUS_SET_OOM (error); return FALSE; } - + dbus_server_set_new_connection_function (server, new_connection_callback, context, NULL); - + if (!dbus_server_set_watch_functions (server, add_server_watch, remove_server_watch, - NULL, + toggle_server_watch, server, NULL)) { @@ -264,7 +266,7 @@ setup_server (BusContext *context, BUS_SET_OOM (error); return FALSE; } - + return TRUE; } @@ -273,9 +275,11 @@ setup_server (BusContext *context, * when config files are reloaded. */ static dbus_bool_t -process_config_first_time_only (BusContext *context, - BusConfigParser *parser, - DBusError *error) +process_config_first_time_only (BusContext *context, + BusConfigParser *parser, + const DBusString *address, + BusContextFlags flags, + DBusError *error) { DBusString log_prefix; DBusList *link; @@ -290,26 +294,56 @@ process_config_first_time_only (BusContext *context, retval = FALSE; auth_mechanisms = NULL; + pidfile = NULL; + + _dbus_init_system_log (TRUE); + + if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION) + context->systemd_activation = TRUE; + else + context->systemd_activation = FALSE; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ - pidfile = bus_config_parser_get_pidfile (parser); + + if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE) + pidfile = bus_config_parser_get_pidfile (parser); + if (pidfile != NULL) { DBusString u; DBusStat stbuf; - + _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { +#ifdef DBUS_CYGWIN + DBusString p; + long /* int */ pid; + + _dbus_string_init (&p); + _dbus_file_get_contents(&p, &u, NULL); + _dbus_string_parse_int(&p, 0, &pid, NULL); + _dbus_string_free(&p); + + if ((kill((int)pid, 0))) { + dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS, + "pid %ld not running, removing stale pid file\n", + pid); + _dbus_delete_file(&u, NULL); + } else { +#endif dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; +#ifdef DBUS_CYGWIN + } +#endif } } @@ -345,11 +379,20 @@ process_config_first_time_only (BusContext *context, if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) - goto oom; + { + _dbus_credentials_unref (credentials); + goto oom; + } if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) - goto oom; + { + _dbus_credentials_unref (credentials); + goto oom; + } if (!_dbus_string_append (&log_prefix, "] ")) - goto oom; + { + _dbus_credentials_unref (credentials); + goto oom; + } _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) @@ -377,6 +420,7 @@ process_config_first_time_only (BusContext *context, if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); + i += 1; } } else @@ -385,30 +429,91 @@ process_config_first_time_only (BusContext *context, } /* Listen on our addresses */ - - addresses = bus_config_parser_get_addresses (parser); - - link = _dbus_list_get_first_link (addresses); - while (link != NULL) + + if (address) { - DBusServer *server; - - server = dbus_server_listen (link->data, error); - if (server == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (error); - goto failed; - } - else if (!setup_server (context, server, auth_mechanisms, error)) - { - _DBUS_ASSERT_ERROR_IS_SET (error); - goto failed; - } +#ifdef ENABLE_KDBUS_TRANSPORT + if(!strcmp(_dbus_string_get_const_data(address), "kdbus")) + { + DBusBusType type; + DBusServer* server; + char* bus_address; + + if(!strcmp (context->type, "system")) + type = DBUS_BUS_SYSTEM; + else if(!strcmp (context->type, "session")) + type = DBUS_BUS_SESSION; + else + type = DBUS_BUS_STARTER; + + bus_address = make_kdbus_bus(type, error); + if(bus_address == NULL) + goto failed; + + server = empty_server_init(bus_address); + if(server == NULL) + { + free(bus_address); + goto failed; + } + + if (!_dbus_list_append (&context->servers, server)) + { + free(bus_address); + goto oom; + } + + context->myKdbusConnection = daemon_as_client(type, bus_address, error); + if(context->myKdbusConnection == NULL) + goto failed; + } + else +#endif + { + DBusServer *server; + + server = dbus_server_listen (_dbus_string_get_const_data(address), error); + if (server == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + else if (!setup_server (context, server, auth_mechanisms, error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + + if (!_dbus_list_append (&context->servers, server)) + goto oom; + } + } + else + { + addresses = bus_config_parser_get_addresses (parser); - if (!_dbus_list_append (&context->servers, server)) - goto oom; + link = _dbus_list_get_first_link (addresses); + while (link != NULL) + { + DBusServer *server; + + server = dbus_server_listen (link->data, error); + if (server == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + else if (!setup_server (context, server, auth_mechanisms, error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + + if (!_dbus_list_append (&context->servers, server)) + goto oom; - link = _dbus_list_get_next_link (addresses, link); + link = _dbus_list_get_next_link (addresses, link); + } } context->fork = bus_config_parser_get_fork (parser); @@ -444,11 +549,10 @@ process_config_every_time (BusContext *context, DBusString full_address; DBusList *link; DBusList **dirs; - BusActivation *new_activation; char *addr; const char *servicehelper; char *s; - + dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -553,7 +657,7 @@ process_config_every_time (BusContext *context, failed: _dbus_string_free (&full_address); - + if (addr) dbus_free (addr); @@ -569,7 +673,6 @@ list_concat_new (DBusList **a, *result = NULL; - link = _dbus_list_get_first_link (a); for (link = _dbus_list_get_first_link (a); link; link = _dbus_list_get_next_link (a, link)) { if (!_dbus_list_append (result, link->data)) @@ -587,6 +690,24 @@ oom: return FALSE; } +static void +raise_file_descriptor_limit (BusContext *context) +{ + + /* I just picked this out of thin air; we need some extra + * descriptors for things like any internal pipes we create, + * inotify, connections to SELinux, etc. + */ + unsigned int arbitrary_extra_fds = 32; + unsigned int limit; + + limit = context->limits.max_completed_connections + + context->limits.max_incomplete_connections + + arbitrary_extra_fds; + + _dbus_request_file_descriptor_limit (limit); +} + static dbus_bool_t process_config_postinit (BusContext *context, BusConfigParser *parser, @@ -595,6 +716,8 @@ 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)) @@ -625,15 +748,18 @@ process_config_postinit (BusContext *context, BusContext* bus_context_new (const DBusString *config_file, - ForceForkSetting force_fork, + BusContextFlags flags, DBusPipe *print_addr_pipe, DBusPipe *print_pid_pipe, + const DBusString *address, DBusError *error) { - DBusString log_prefix; BusContext *context; BusConfigParser *parser; + _dbus_assert ((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 || + (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS) == 0); + _DBUS_ASSERT_ERROR_IS_CLEAR (error); context = NULL; @@ -653,6 +779,10 @@ bus_context_new (const DBusString *config_file, } context->refcount = 1; +#ifdef ENABLE_KDBUS_TRANSPORT + context->myKdbusConnection = NULL; +#endif + _dbus_generate_uuid (&context->uuid); if (!_dbus_string_copy_data (config_file, &context->config_file)) @@ -681,8 +811,8 @@ bus_context_new (const DBusString *config_file, _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } - - if (!process_config_first_time_only (context, parser, error)) + + if (!process_config_first_time_only (context, parser, address, flags, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; @@ -692,7 +822,7 @@ bus_context_new (const DBusString *config_file, _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } - + /* we need another ref of the server data slot for the context * to own */ @@ -709,14 +839,14 @@ bus_context_new (const DBusString *config_file, DBusString addr; const char *a = bus_context_get_address (context); int bytes; - + _dbus_assert (a != NULL); if (!_dbus_string_init (&addr)) { BUS_SET_OOM (error); goto failed; } - + if (!_dbus_string_append (&addr, a) || !_dbus_string_append (&addr, "\n")) { @@ -740,10 +870,10 @@ bus_context_new (const DBusString *config_file, if (!_dbus_pipe_is_stdout_or_stderr (print_addr_pipe)) _dbus_pipe_close (print_addr_pipe, NULL); - + _dbus_string_free (&addr); } - + context->connections = bus_connections_new (context); if (context->connections == NULL) { @@ -777,11 +907,12 @@ bus_context_new (const DBusString *config_file, if (context->pidfile) _dbus_string_init_const (&u, context->pidfile); - if ((force_fork != FORK_NEVER && context->fork) || force_fork == FORK_ALWAYS) + if (((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 && context->fork) || + (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS)) { _dbus_verbose ("Forking and becoming daemon\n"); - - if (!_dbus_become_daemon (context->pidfile ? &u : NULL, + + if (!_dbus_become_daemon (context->pidfile ? &u : NULL, print_pid_pipe, error, context->keep_umask)) @@ -793,7 +924,7 @@ bus_context_new (const DBusString *config_file, else { _dbus_verbose ("Fork not requested\n"); - + /* Need to write PID file and to PID pipe for ourselves, * not for the child process. This is a no-op if the pidfile * is NULL and print_pid_pipe is NULL. @@ -829,7 +960,7 @@ bus_context_new (const DBusString *config_file, bus_config_parser_unref (parser); parser = NULL; } - + /* Here we change our credentials if required, * as soon as we've set up our sockets and pidfile */ @@ -848,10 +979,43 @@ bus_context_new (const DBusString *config_file, } dbus_server_free_data_slot (&server_data_slot); - + +#ifdef ENABLE_KDBUS_TRANSPORT + if(context->myKdbusConnection) + { + DBusString unique_name; + + if(!bus_connections_setup_connection(context->connections, context->myKdbusConnection)) + { + _dbus_verbose ("Bus connections setup connection failed for myKdbusConnection!\n"); + dbus_connection_close (context->myKdbusConnection); + dbus_connection_unref (context->myKdbusConnection); + goto failed; + } + dbus_connection_set_route_peer_messages (context->myKdbusConnection, FALSE); + _dbus_string_init_const (&unique_name, ":1.1"); //dbus_bus_get_unique_name(context->myConnection)); this is without :1. + if(!bus_connection_complete (context->myKdbusConnection, &unique_name, error)) + { + _dbus_verbose ("Bus connection complete failed for myKdbusConnection!\n"); + goto failed; + } + + if(!register_daemon_name(context->myKdbusConnection)) + { + _dbus_verbose ("Registering org.freedesktop.DBus name for daemon failed!\n"); + goto failed; + } + if(!register_kdbus_starters(context->myKdbusConnection)) + { + _dbus_verbose ("Registering kdbus starters for dbus activatable names failed!\n"); + goto failed; + } + } +#endif + return context; - - failed: + + failed: if (parser != NULL) bus_config_parser_unref (parser); if (context != NULL) @@ -859,7 +1023,7 @@ bus_context_new (const DBusString *config_file, if (server_data_slot >= 0) dbus_server_free_data_slot (&server_data_slot); - + return NULL; } @@ -889,7 +1053,7 @@ bus_context_reload_config (BusContext *context, _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } - + if (!process_config_every_time (context, parser, TRUE, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); @@ -900,6 +1064,19 @@ bus_context_reload_config (BusContext *context, _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } + +#ifdef ENABLE_KDBUS_TRANSPORT + if(context->myKdbusConnection) + { + if(!update_kdbus_starters(context->myKdbusConnection)) + { + _dbus_verbose ("Update kdbus starters for dbus activatable names failed.\n"); + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + } +#endif + ret = TRUE; bus_context_log (context, DBUS_SYSTEM_LOG_INFO, "Reloaded configuration"); @@ -918,19 +1095,19 @@ shutdown_server (BusContext *context, if (server == NULL || !dbus_server_get_is_connected (server)) return; - + if (!dbus_server_set_watch_functions (server, NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting watch functions to NULL failed"); - + if (!dbus_server_set_timeout_functions (server, NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting timeout functions to NULL failed"); - + dbus_server_disconnect (server); } @@ -966,9 +1143,9 @@ bus_context_unref (BusContext *context) if (context->refcount == 0) { DBusList *link; - + _dbus_verbose ("Finalizing bus context %p\n", context); - + bus_context_shutdown (context); if (context->connections) @@ -976,13 +1153,13 @@ bus_context_unref (BusContext *context) bus_connections_unref (context->connections); context->connections = NULL; } - + if (context->registry) { bus_registry_unref (context->registry); context->registry = NULL; } - + if (context->activation) { bus_activation_unref (context->activation); @@ -993,7 +1170,7 @@ bus_context_unref (BusContext *context) while (link != NULL) { dbus_server_unref (link->data); - + link = _dbus_list_get_next_link (&context->servers, link); } _dbus_list_clear (&context->servers); @@ -1003,7 +1180,7 @@ bus_context_unref (BusContext *context) bus_policy_unref (context->policy); context->policy = NULL; } - + if (context->loop) { _dbus_loop_unref (context->loop); @@ -1033,7 +1210,7 @@ bus_context_unref (BusContext *context) */ _dbus_delete_file (&u, NULL); - dbus_free (context->pidfile); + dbus_free (context->pidfile); } dbus_free (context); @@ -1060,6 +1237,12 @@ bus_context_get_servicehelper (BusContext *context) return context->servicehelper; } +dbus_bool_t +bus_context_get_systemd_activation (BusContext *context) +{ + return context->systemd_activation; +} + BusRegistry* bus_context_get_registry (BusContext *context) { @@ -1129,7 +1312,7 @@ bus_context_create_client_policy (BusContext *context, int bus_context_get_activation_timeout (BusContext *context) { - + return context->limits.activation_timeout; } @@ -1187,6 +1370,13 @@ bus_context_get_reply_timeout (BusContext *context) return context->limits.reply_timeout; } +#ifdef ENABLE_KDBUS_TRANSPORT +dbus_bool_t bus_context_is_kdbus(BusContext* context) +{ + return context->myKdbusConnection != NULL; +} +#endif + void bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (3, 4); @@ -1196,7 +1386,14 @@ bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char va_list args; if (!context->syslog) - return; + { + /* we're not syslogging; just output to stderr */ + va_start (args, msg); + vfprintf (stderr, msg, args); + fprintf (stderr, "\n"); + va_end (args); + return; + } va_start (args, msg); @@ -1222,6 +1419,77 @@ out: va_end (args); } +static inline const char * +nonnull (const char *maybe_null, + const char *if_null) +{ + return (maybe_null ? maybe_null : if_null); +} + +/* + * Log something about a message, usually that it was rejected. + */ +static void +complain_about_message (BusContext *context, + const char *error_name, + const char *complaint, + int matched_rules, + DBusMessage *message, + DBusConnection *sender, + DBusConnection *proposed_recipient, + dbus_bool_t requested_reply, + dbus_bool_t log, + DBusError *error) +{ + DBusError stack_error = DBUS_ERROR_INIT; + const char *sender_name; + const char *sender_loginfo; + const char *proposed_recipient_loginfo; + + if (error == NULL && !log) + return; + + if (sender != NULL) + { + sender_name = bus_connection_get_name (sender); + sender_loginfo = bus_connection_get_loginfo (sender); + } + else + { + sender_name = "(unset)"; + sender_loginfo = "(bus)"; + } + + if (proposed_recipient != NULL) + proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient); + else + proposed_recipient_loginfo = "bus"; + + dbus_set_error (&stack_error, error_name, + "%s, %d matched rules; type=\"%s\", sender=\"%s\" (%s) " + "interface=\"%s\" member=\"%s\" error name=\"%s\" " + "requested_reply=\"%d\" destination=\"%s\" (%s)", + complaint, + matched_rules, + dbus_message_type_to_string (dbus_message_get_type (message)), + sender_name, + sender_loginfo, + nonnull (dbus_message_get_interface (message), "(unset)"), + nonnull (dbus_message_get_member (message), "(unset)"), + nonnull (dbus_message_get_error_name (message), "(unset)"), + requested_reply, + nonnull (dbus_message_get_destination (message), DBUS_SERVICE_DBUS), + proposed_recipient_loginfo); + + /* If we hit OOM while setting the error, this will syslog "out of memory" + * which is itself an indication that something is seriously wrong */ + if (log) + bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY, "%s", + stack_error.message); + + dbus_move_error (&stack_error, error); +} + /* * addressed_recipient is the recipient specified in the message. * @@ -1251,13 +1519,10 @@ bus_context_check_security_policy (BusContext *context, 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 (dest != NULL || type == DBUS_MESSAGE_TYPE_SIGNAL || @@ -1266,23 +1531,6 @@ bus_context_check_security_policy (BusContext *context, addressed_recipient != NULL || 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) { case DBUS_MESSAGE_TYPE_METHOD_CALL: @@ -1290,19 +1538,19 @@ bus_context_check_security_policy (BusContext *context, case DBUS_MESSAGE_TYPE_METHOD_RETURN: case DBUS_MESSAGE_TYPE_ERROR: break; - + default: _dbus_verbose ("security check disallowing message of unknown type %d\n", type); dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Message bus will not accept messages of unknown type\n"); - + return FALSE; } requested_reply = FALSE; - + if (sender != NULL) { /* First verify the SELinux access controls. If allowed then @@ -1317,30 +1565,23 @@ bus_context_check_security_policy (BusContext *context, { if (error != NULL && !dbus_error_is_set (error)) { - dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "An SELinux policy prevents this sender " - "from sending this message to this recipient " - "(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) ? - dbus_message_get_member (message) : "(unset)", - dbus_message_get_error_name (message) ? - dbus_message_get_error_name (message) : "(unset)", - dest ? dest : DBUS_SERVICE_DBUS); + /* don't syslog this, just set the error: avc_has_perm should + * have already written to either the audit log or syslog */ + complain_about_message (context, DBUS_ERROR_ACCESS_DENIED, + "An SELinux policy prevents this sender from sending this " + "message to this recipient", + 0, message, sender, proposed_recipient, FALSE, FALSE, error); _dbus_verbose ("SELinux security check denying send to service\n"); } return FALSE; } - + if (bus_connection_is_active (sender)) { sender_policy = bus_connection_get_policy (sender); _dbus_assert (sender_policy != NULL); - + /* Fill in requested_reply variable with TRUE if this is a * reply and the reply was pending. */ @@ -1349,8 +1590,8 @@ bus_context_check_security_policy (BusContext *context, if (proposed_recipient != NULL /* not to the bus driver */ && addressed_recipient == proposed_recipient /* not eavesdropping */) { - DBusError error2; - + DBusError error2; + dbus_error_init (&error2); requested_reply = bus_connections_check_reply (bus_connection_get_connections (sender), transaction, @@ -1386,7 +1627,7 @@ bus_context_check_security_policy (BusContext *context, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Client tried to send a message other than %s without being registered", "Hello"); - + return FALSE; } } @@ -1405,7 +1646,7 @@ bus_context_check_security_policy (BusContext *context, _dbus_assert ((sender != NULL && sender_policy != NULL) || (sender == NULL && sender_policy == NULL)); - + if (proposed_recipient != NULL) { /* only the bus driver can send to an inactive recipient (as it @@ -1430,11 +1671,11 @@ bus_context_check_security_policy (BusContext *context, } else recipient_policy = NULL; - + _dbus_assert ((proposed_recipient != NULL && recipient_policy != NULL) || (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, @@ -1443,60 +1684,23 @@ bus_context_check_security_policy (BusContext *context, proposed_recipient, message, &toggles, &log)) { - 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)", - 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 (context, DBUS_SYSTEM_LOG_SECURITY, 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); + complain_about_message (context, DBUS_ERROR_ACCESS_DENIED, + "Rejected send message", toggles, + message, sender, proposed_recipient, requested_reply, + (addressed_recipient == proposed_recipient), error); _dbus_verbose ("security policy disallowing message due to sender policy\n"); return FALSE; } if (log) - bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY, - "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); + { + /* We want to drop this message, and are only not doing so for backwards + * compatibility. */ + complain_about_message (context, DBUS_ERROR_ACCESS_DENIED, + "Would reject message", toggles, + message, sender, proposed_recipient, requested_reply, + TRUE, NULL); + } if (recipient_policy && !bus_client_policy_check_can_receive (recipient_policy, @@ -1506,41 +1710,10 @@ bus_context_check_security_policy (BusContext *context, addressed_recipient, proposed_recipient, message, &toggles)) { - 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)", - dbus_message_get_reply_serial (message), - 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 (context, DBUS_SYSTEM_LOG_SECURITY, 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); + complain_about_message (context, DBUS_ERROR_ACCESS_DENIED, + "Rejected receive message", toggles, + message, sender, proposed_recipient, requested_reply, + (addressed_recipient == proposed_recipient), NULL); _dbus_verbose ("security policy disallowing message due to recipient policy\n"); return FALSE; } @@ -1550,11 +1723,10 @@ bus_context_check_security_policy (BusContext *context, ((dbus_connection_get_outgoing_size (proposed_recipient) > context->limits.max_outgoing_bytes) || (dbus_connection_get_outgoing_unix_fds (proposed_recipient) > context->limits.max_outgoing_unix_fds))) { - dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, - "The destination service \"%s\" has a full message queue", - dest ? dest : (proposed_recipient ? - bus_connection_get_name (proposed_recipient) : - DBUS_SERVICE_DBUS)); + complain_about_message (context, DBUS_ERROR_LIMITS_EXCEEDED, + "Rejected: destination has a full message queue", + 0, message, sender, proposed_recipient, requested_reply, TRUE, + error); _dbus_verbose ("security policy disallowing message due to full message queue\n"); return FALSE; } @@ -1564,7 +1736,7 @@ bus_context_check_security_policy (BusContext *context, * connection). Only the addressed recipient may reply. */ if (type == DBUS_MESSAGE_TYPE_METHOD_CALL && - sender && + sender && addressed_recipient && addressed_recipient == proposed_recipient && /* not eavesdropping */ !bus_connections_expect_reply (bus_connection_get_connections (sender), @@ -1575,7 +1747,7 @@ bus_context_check_security_policy (BusContext *context, _dbus_verbose ("Failed to record reply expectation or problem with the message expecting a reply\n"); return FALSE; } - + _dbus_verbose ("security policy allowing message\n"); return TRUE; }