1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* bus.c message bus context object
4 * Copyright (C) 2003 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "activation.h"
26 #include "connection.h"
30 #include "config-parser.h"
31 #include <dbus/dbus-list.h>
32 #include <dbus/dbus-hash.h>
33 #include <dbus/dbus-internals.h>
43 BusConnections *connections;
44 BusActivation *activation;
45 BusRegistry *registry;
47 int activation_timeout; /**< How long to wait for an activation to time out */
48 int auth_timeout; /**< How long to wait for an authentication to time out */
49 int max_completed_connections; /**< Max number of authorized connections */
50 int max_incomplete_connections; /**< Max number of incomplete connections */
51 int max_connections_per_user; /**< Max number of connections auth'd as same user */
54 static int server_data_slot = -1;
55 static int server_data_slot_refcount = 0;
62 #define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
65 server_data_slot_ref (void)
67 if (server_data_slot < 0)
69 server_data_slot = dbus_server_allocate_data_slot ();
71 if (server_data_slot < 0)
74 _dbus_assert (server_data_slot_refcount == 0);
77 server_data_slot_refcount += 1;
83 server_data_slot_unref (void)
85 _dbus_assert (server_data_slot_refcount > 0);
87 server_data_slot_refcount -= 1;
89 if (server_data_slot_refcount == 0)
91 dbus_server_free_data_slot (server_data_slot);
92 server_data_slot = -1;
97 server_get_context (DBusServer *server)
102 if (!server_data_slot_ref ())
105 bd = BUS_SERVER_DATA (server);
108 server_data_slot_unref ();
112 context = bd->context;
114 server_data_slot_unref ();
120 server_watch_callback (DBusWatch *watch,
121 unsigned int condition,
124 DBusServer *server = data;
126 return dbus_server_handle_watch (server, watch, condition);
130 add_server_watch (DBusWatch *watch,
133 DBusServer *server = data;
136 context = server_get_context (server);
138 return _dbus_loop_add_watch (context->loop,
139 watch, server_watch_callback, server,
144 remove_server_watch (DBusWatch *watch,
147 DBusServer *server = data;
150 context = server_get_context (server);
152 _dbus_loop_remove_watch (context->loop,
153 watch, server_watch_callback, server);
158 server_timeout_callback (DBusTimeout *timeout,
161 /* can return FALSE on OOM but we just let it fire again later */
162 dbus_timeout_handle (timeout);
166 add_server_timeout (DBusTimeout *timeout,
169 DBusServer *server = data;
172 context = server_get_context (server);
174 return _dbus_loop_add_timeout (context->loop,
175 timeout, server_timeout_callback, server, NULL);
179 remove_server_timeout (DBusTimeout *timeout,
182 DBusServer *server = data;
185 context = server_get_context (server);
187 _dbus_loop_remove_timeout (context->loop,
188 timeout, server_timeout_callback, server);
192 new_connection_callback (DBusServer *server,
193 DBusConnection *new_connection,
196 BusContext *context = data;
198 if (!bus_connections_setup_connection (context->connections, new_connection))
200 _dbus_verbose ("No memory to setup new connection\n");
202 /* if we don't do this, it will get unref'd without
203 * being disconnected... kind of strange really
204 * that we have to do this, people won't get it right
207 dbus_connection_disconnect (new_connection);
210 /* on OOM, we won't have ref'd the connection so it will die. */
214 free_server_data (void *data)
216 BusServerData *bd = data;
222 setup_server (BusContext *context,
224 char **auth_mechanisms,
229 bd = dbus_new0 (BusServerData, 1);
230 if (!dbus_server_set_data (server,
232 bd, free_server_data))
239 bd->context = context;
241 if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
247 dbus_server_set_new_connection_function (server,
248 new_connection_callback,
251 if (!dbus_server_set_watch_functions (server,
262 if (!dbus_server_set_timeout_functions (server,
264 remove_server_timeout,
276 bus_context_new (const DBusString *config_file,
282 DBusList **addresses;
283 BusConfigParser *parser;
284 DBusString full_address;
285 const char *user, *pidfile;
286 char **auth_mechanisms;
287 DBusList **auth_mechanisms_list;
290 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
292 if (!_dbus_string_init (&full_address))
298 if (!server_data_slot_ref ())
301 _dbus_string_free (&full_address);
307 auth_mechanisms = NULL;
309 parser = bus_config_load (config_file, error);
313 /* Check for an existing pid file. Of course this is a race;
314 * we'd have to use fcntl() locks on the pid file to
315 * avoid that. But we want to check for the pid file
316 * before overwriting any existing sockets, etc.
318 pidfile = bus_config_parser_get_pidfile (parser);
325 dbus_error_init (&tmp_error);
326 _dbus_string_init_const (&u, pidfile);
328 if (_dbus_stat (&u, &stbuf, &tmp_error))
330 dbus_set_error (error, DBUS_ERROR_FAILED,
331 "The pid file \"%s\" exists, if the message bus is not running, remove this file",
333 dbus_error_free (&tmp_error);
338 context = dbus_new0 (BusContext, 1);
345 context->refcount = 1;
347 /* we need another ref of the server data slot for the context
350 if (!server_data_slot_ref ())
351 _dbus_assert_not_reached ("second ref of server data slot failed");
353 #ifdef DBUS_BUILD_TESTS
354 context->activation_timeout = 6000; /* 6 seconds */
356 context->activation_timeout = 15000; /* 15 seconds */
359 /* Making this long risks making a DOS attack easier, but too short
360 * and legitimate auth will fail. If interactive auth (ask user for
361 * password) is allowed, then potentially it has to be quite long.
362 * Ultimately it needs to come from the configuration file.
364 context->auth_timeout = 3000; /* 3 seconds */
366 context->max_incomplete_connections = 32;
367 context->max_connections_per_user = 128;
369 /* Note that max_completed_connections / max_connections_per_user
370 * is the number of users that would have to work together to
371 * DOS all the other users.
373 context->max_completed_connections = 1024;
375 context->loop = _dbus_loop_new ();
376 if (context->loop == NULL)
382 /* Build an array of auth mechanisms */
384 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
385 len = _dbus_list_get_length (auth_mechanisms_list);
391 auth_mechanisms = dbus_new0 (char*, len + 1);
392 if (auth_mechanisms == NULL)
396 link = _dbus_list_get_first_link (auth_mechanisms_list);
399 auth_mechanisms[i] = _dbus_strdup (link->data);
400 if (auth_mechanisms[i] == NULL)
402 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
407 auth_mechanisms = NULL;
410 /* Listen on our addresses */
412 addresses = bus_config_parser_get_addresses (parser);
414 link = _dbus_list_get_first_link (addresses);
419 server = dbus_server_listen (link->data, error);
422 else if (!setup_server (context, server, auth_mechanisms, error))
425 if (!_dbus_list_append (&context->servers, server))
431 link = _dbus_list_get_next_link (addresses, link);
434 /* note that type may be NULL */
435 context->type = _dbus_strdup (bus_config_parser_get_type (parser));
437 /* We have to build the address backward, so that
438 * <listen> later in the config file have priority
440 link = _dbus_list_get_last_link (&context->servers);
445 addr = dbus_server_get_address (link->data);
452 if (_dbus_string_get_length (&full_address) > 0)
454 if (!_dbus_string_append (&full_address, ";"))
461 if (!_dbus_string_append (&full_address, addr))
469 link = _dbus_list_get_prev_link (&context->servers, link);
472 if (!_dbus_string_copy_data (&full_address, &context->address))
478 /* Note that we don't know whether the print_addr_fd is
479 * one of the sockets we're using to listen on, or some
480 * other random thing. But I think the answer is "don't do
483 if (print_addr_fd >= 0)
486 const char *a = bus_context_get_address (context);
489 _dbus_assert (a != NULL);
490 if (!_dbus_string_init (&addr))
496 if (!_dbus_string_append (&addr, a) ||
497 !_dbus_string_append (&addr, "\n"))
499 _dbus_string_free (&addr);
504 bytes = _dbus_string_get_length (&addr);
505 if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
507 dbus_set_error (error, DBUS_ERROR_FAILED,
508 "Printing message bus address: %s\n",
509 _dbus_strerror (errno));
510 _dbus_string_free (&addr);
514 if (print_addr_fd > 2)
515 _dbus_close (print_addr_fd, NULL);
517 _dbus_string_free (&addr);
520 /* Create activation subsystem */
522 context->activation = bus_activation_new (context, &full_address,
523 bus_config_parser_get_service_dirs (parser),
525 if (context->activation == NULL)
527 _DBUS_ASSERT_ERROR_IS_SET (error);
531 context->connections = bus_connections_new (context);
532 if (context->connections == NULL)
538 context->registry = bus_registry_new (context);
539 if (context->registry == NULL)
545 context->policy = bus_config_parser_steal_policy (parser);
546 _dbus_assert (context->policy != NULL);
548 /* Now become a daemon if appropriate */
549 if (bus_config_parser_get_fork (parser))
554 _dbus_string_init_const (&u, pidfile);
556 if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
561 /* Need to write PID file for ourselves, not for the child process */
566 _dbus_string_init_const (&u, pidfile);
568 if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
573 /* keep around the pid filename so we can delete it later */
574 context->pidfile = _dbus_strdup (pidfile);
576 /* Here we change our credentials if required,
577 * as soon as we've set up our sockets and pidfile
579 user = bus_config_parser_get_user (parser);
582 DBusCredentials creds;
585 _dbus_string_init_const (&u, user);
587 if (!_dbus_credentials_from_username (&u, &creds) ||
591 dbus_set_error (error, DBUS_ERROR_FAILED,
592 "Could not get UID and GID for username \"%s\"",
597 if (!_dbus_change_identity (creds.uid, creds.gid, error))
601 bus_config_parser_unref (parser);
602 _dbus_string_free (&full_address);
603 dbus_free_string_array (auth_mechanisms);
604 server_data_slot_unref ();
610 bus_config_parser_unref (parser);
613 bus_context_unref (context);
615 _dbus_string_free (&full_address);
616 dbus_free_string_array (auth_mechanisms);
618 server_data_slot_unref ();
624 shutdown_server (BusContext *context,
627 if (server == NULL ||
628 !dbus_server_get_is_connected (server))
631 if (!dbus_server_set_watch_functions (server,
635 _dbus_assert_not_reached ("setting watch functions to NULL failed");
637 if (!dbus_server_set_timeout_functions (server,
641 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
643 dbus_server_disconnect (server);
647 bus_context_shutdown (BusContext *context)
651 link = _dbus_list_get_first_link (&context->servers);
654 shutdown_server (context, link->data);
656 link = _dbus_list_get_next_link (&context->servers, link);
661 bus_context_ref (BusContext *context)
663 _dbus_assert (context->refcount > 0);
664 context->refcount += 1;
668 bus_context_unref (BusContext *context)
670 _dbus_assert (context->refcount > 0);
671 context->refcount -= 1;
673 if (context->refcount == 0)
677 _dbus_verbose ("Finalizing bus context %p\n", context);
679 bus_context_shutdown (context);
681 if (context->connections)
683 bus_connections_unref (context->connections);
684 context->connections = NULL;
687 if (context->registry)
689 bus_registry_unref (context->registry);
690 context->registry = NULL;
693 if (context->activation)
695 bus_activation_unref (context->activation);
696 context->activation = NULL;
699 link = _dbus_list_get_first_link (&context->servers);
702 dbus_server_unref (link->data);
704 link = _dbus_list_get_next_link (&context->servers, link);
706 _dbus_list_clear (&context->servers);
710 bus_policy_unref (context->policy);
711 context->policy = NULL;
716 _dbus_loop_unref (context->loop);
717 context->loop = NULL;
720 dbus_free (context->type);
721 dbus_free (context->address);
723 if (context->pidfile)
726 _dbus_string_init_const (&u, context->pidfile);
728 /* Deliberately ignore errors here, since there's not much
729 * we can do about it, and we're exiting anyways.
731 _dbus_delete_file (&u, NULL);
733 dbus_free (context->pidfile);
738 server_data_slot_unref ();
742 /* type may be NULL */
744 bus_context_get_type (BusContext *context)
746 return context->type;
750 bus_context_get_address (BusContext *context)
752 return context->address;
756 bus_context_get_registry (BusContext *context)
758 return context->registry;
762 bus_context_get_connections (BusContext *context)
764 return context->connections;
768 bus_context_get_activation (BusContext *context)
770 return context->activation;
774 bus_context_get_loop (BusContext *context)
776 return context->loop;
780 bus_context_allow_user (BusContext *context,
783 return bus_policy_allow_user (context->policy, uid);
787 bus_context_create_client_policy (BusContext *context,
788 DBusConnection *connection)
790 return bus_policy_create_client_policy (context->policy, connection);
794 bus_context_get_activation_timeout (BusContext *context)
797 return context->activation_timeout;
801 bus_context_check_security_policy (BusContext *context,
802 DBusConnection *sender,
803 DBusConnection *recipient,
804 DBusMessage *message,
807 BusClientPolicy *sender_policy;
808 BusClientPolicy *recipient_policy;
810 /* NULL sender/receiver means the bus driver */
814 _dbus_assert (dbus_connection_get_is_authenticated (sender));
815 sender_policy = bus_connection_get_policy (sender);
818 sender_policy = NULL;
820 if (recipient != NULL)
822 _dbus_assert (dbus_connection_get_is_authenticated (recipient));
823 recipient_policy = bus_connection_get_policy (recipient);
826 recipient_policy = NULL;
829 !bus_client_policy_check_can_send (sender_policy,
830 context->registry, recipient,
833 const char *dest = dbus_message_get_service (message);
834 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
835 "A security policy in place prevents this sender "
836 "from sending this message to this recipient, "
837 "see message bus configuration file (rejected message "
838 "had name \"%s\" destination \"%s\")",
839 dbus_message_get_name (message),
840 dest ? dest : DBUS_SERVICE_DBUS);
844 if (recipient_policy &&
845 !bus_client_policy_check_can_receive (recipient_policy,
846 context->registry, sender,
849 const char *dest = dbus_message_get_service (message);
850 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
851 "A security policy in place prevents this recipient "
852 "from receiving this message from this sender, "
853 "see message bus configuration file (rejected message "
854 "had name \"%s\" destination \"%s\")",
855 dbus_message_get_name (message),
856 dest ? dest : DBUS_SERVICE_DBUS);