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 DBusUserDatabase *user_database;
48 long max_incoming_bytes; /**< How many incoming messages for a connection */
49 long max_outgoing_bytes; /**< How many outgoing bytes can be queued for a connection */
50 long max_message_size; /**< Max size of a single message in bytes */
51 int activation_timeout; /**< How long to wait for an activation to time out */
52 int auth_timeout; /**< How long to wait for an authentication to time out */
53 int max_completed_connections; /**< Max number of authorized connections */
54 int max_incomplete_connections; /**< Max number of incomplete connections */
55 int max_connections_per_user; /**< Max number of connections auth'd as same user */
58 static int server_data_slot = -1;
59 static int server_data_slot_refcount = 0;
66 #define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
69 server_data_slot_ref (void)
71 if (server_data_slot < 0)
73 server_data_slot = dbus_server_allocate_data_slot ();
75 if (server_data_slot < 0)
78 _dbus_assert (server_data_slot_refcount == 0);
81 server_data_slot_refcount += 1;
87 server_data_slot_unref (void)
89 _dbus_assert (server_data_slot_refcount > 0);
91 server_data_slot_refcount -= 1;
93 if (server_data_slot_refcount == 0)
95 dbus_server_free_data_slot (server_data_slot);
96 server_data_slot = -1;
101 server_get_context (DBusServer *server)
106 if (!server_data_slot_ref ())
109 bd = BUS_SERVER_DATA (server);
112 server_data_slot_unref ();
116 context = bd->context;
118 server_data_slot_unref ();
124 server_watch_callback (DBusWatch *watch,
125 unsigned int condition,
128 /* FIXME this can be done in dbus-mainloop.c
129 * if the code in activation.c for the babysitter
130 * watch handler is fixed.
133 return dbus_watch_handle (watch, condition);
137 add_server_watch (DBusWatch *watch,
140 DBusServer *server = data;
143 context = server_get_context (server);
145 return _dbus_loop_add_watch (context->loop,
146 watch, server_watch_callback, server,
151 remove_server_watch (DBusWatch *watch,
154 DBusServer *server = data;
157 context = server_get_context (server);
159 _dbus_loop_remove_watch (context->loop,
160 watch, server_watch_callback, server);
165 server_timeout_callback (DBusTimeout *timeout,
168 /* can return FALSE on OOM but we just let it fire again later */
169 dbus_timeout_handle (timeout);
173 add_server_timeout (DBusTimeout *timeout,
176 DBusServer *server = data;
179 context = server_get_context (server);
181 return _dbus_loop_add_timeout (context->loop,
182 timeout, server_timeout_callback, server, NULL);
186 remove_server_timeout (DBusTimeout *timeout,
189 DBusServer *server = data;
192 context = server_get_context (server);
194 _dbus_loop_remove_timeout (context->loop,
195 timeout, server_timeout_callback, server);
199 new_connection_callback (DBusServer *server,
200 DBusConnection *new_connection,
203 BusContext *context = data;
205 if (!bus_connections_setup_connection (context->connections, new_connection))
207 _dbus_verbose ("No memory to setup new connection\n");
209 /* if we don't do this, it will get unref'd without
210 * being disconnected... kind of strange really
211 * that we have to do this, people won't get it right
214 dbus_connection_disconnect (new_connection);
217 dbus_connection_set_max_received_size (new_connection,
218 context->max_incoming_bytes);
220 dbus_connection_set_max_message_size (new_connection,
221 context->max_message_size);
223 /* on OOM, we won't have ref'd the connection so it will die. */
227 free_server_data (void *data)
229 BusServerData *bd = data;
235 setup_server (BusContext *context,
237 char **auth_mechanisms,
242 bd = dbus_new0 (BusServerData, 1);
243 if (!dbus_server_set_data (server,
245 bd, free_server_data))
252 bd->context = context;
254 if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
260 dbus_server_set_new_connection_function (server,
261 new_connection_callback,
264 if (!dbus_server_set_watch_functions (server,
275 if (!dbus_server_set_timeout_functions (server,
277 remove_server_timeout,
289 bus_context_new (const DBusString *config_file,
295 DBusList **addresses;
296 BusConfigParser *parser;
297 DBusString full_address;
298 const char *user, *pidfile;
299 char **auth_mechanisms;
300 DBusList **auth_mechanisms_list;
303 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
305 if (!_dbus_string_init (&full_address))
311 if (!server_data_slot_ref ())
314 _dbus_string_free (&full_address);
320 auth_mechanisms = NULL;
322 parser = bus_config_load (config_file, error);
326 /* Check for an existing pid file. Of course this is a race;
327 * we'd have to use fcntl() locks on the pid file to
328 * avoid that. But we want to check for the pid file
329 * before overwriting any existing sockets, etc.
331 pidfile = bus_config_parser_get_pidfile (parser);
338 dbus_error_init (&tmp_error);
339 _dbus_string_init_const (&u, pidfile);
341 if (_dbus_stat (&u, &stbuf, &tmp_error))
343 dbus_set_error (error, DBUS_ERROR_FAILED,
344 "The pid file \"%s\" exists, if the message bus is not running, remove this file",
346 dbus_error_free (&tmp_error);
351 context = dbus_new0 (BusContext, 1);
358 context->refcount = 1;
360 /* we need another ref of the server data slot for the context
363 if (!server_data_slot_ref ())
364 _dbus_assert_not_reached ("second ref of server data slot failed");
366 /* Make up some numbers! woot! */
367 context->max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
368 context->max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
369 context->max_message_size = _DBUS_ONE_MEGABYTE * 32;
371 #ifdef DBUS_BUILD_TESTS
372 context->activation_timeout = 6000; /* 6 seconds */
374 context->activation_timeout = 15000; /* 15 seconds */
377 /* Making this long risks making a DOS attack easier, but too short
378 * and legitimate auth will fail. If interactive auth (ask user for
379 * password) is allowed, then potentially it has to be quite long.
380 * Ultimately it needs to come from the configuration file.
382 context->auth_timeout = 3000; /* 3 seconds */
384 context->max_incomplete_connections = 32;
385 context->max_connections_per_user = 128;
387 /* Note that max_completed_connections / max_connections_per_user
388 * is the number of users that would have to work together to
389 * DOS all the other users.
391 context->max_completed_connections = 1024;
393 context->user_database = _dbus_user_database_new ();
394 if (context->user_database == NULL)
400 context->loop = _dbus_loop_new ();
401 if (context->loop == NULL)
407 /* Build an array of auth mechanisms */
409 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
410 len = _dbus_list_get_length (auth_mechanisms_list);
416 auth_mechanisms = dbus_new0 (char*, len + 1);
417 if (auth_mechanisms == NULL)
421 link = _dbus_list_get_first_link (auth_mechanisms_list);
424 auth_mechanisms[i] = _dbus_strdup (link->data);
425 if (auth_mechanisms[i] == NULL)
427 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
432 auth_mechanisms = NULL;
435 /* Listen on our addresses */
437 addresses = bus_config_parser_get_addresses (parser);
439 link = _dbus_list_get_first_link (addresses);
444 server = dbus_server_listen (link->data, error);
447 else if (!setup_server (context, server, auth_mechanisms, error))
450 if (!_dbus_list_append (&context->servers, server))
456 link = _dbus_list_get_next_link (addresses, link);
459 /* note that type may be NULL */
460 context->type = _dbus_strdup (bus_config_parser_get_type (parser));
462 /* We have to build the address backward, so that
463 * <listen> later in the config file have priority
465 link = _dbus_list_get_last_link (&context->servers);
470 addr = dbus_server_get_address (link->data);
477 if (_dbus_string_get_length (&full_address) > 0)
479 if (!_dbus_string_append (&full_address, ";"))
486 if (!_dbus_string_append (&full_address, addr))
494 link = _dbus_list_get_prev_link (&context->servers, link);
497 if (!_dbus_string_copy_data (&full_address, &context->address))
503 /* Note that we don't know whether the print_addr_fd is
504 * one of the sockets we're using to listen on, or some
505 * other random thing. But I think the answer is "don't do
508 if (print_addr_fd >= 0)
511 const char *a = bus_context_get_address (context);
514 _dbus_assert (a != NULL);
515 if (!_dbus_string_init (&addr))
521 if (!_dbus_string_append (&addr, a) ||
522 !_dbus_string_append (&addr, "\n"))
524 _dbus_string_free (&addr);
529 bytes = _dbus_string_get_length (&addr);
530 if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
532 dbus_set_error (error, DBUS_ERROR_FAILED,
533 "Printing message bus address: %s\n",
534 _dbus_strerror (errno));
535 _dbus_string_free (&addr);
539 if (print_addr_fd > 2)
540 _dbus_close (print_addr_fd, NULL);
542 _dbus_string_free (&addr);
545 /* Create activation subsystem */
547 context->activation = bus_activation_new (context, &full_address,
548 bus_config_parser_get_service_dirs (parser),
550 if (context->activation == NULL)
552 _DBUS_ASSERT_ERROR_IS_SET (error);
556 context->connections = bus_connections_new (context);
557 if (context->connections == NULL)
563 context->registry = bus_registry_new (context);
564 if (context->registry == NULL)
570 context->policy = bus_config_parser_steal_policy (parser);
571 _dbus_assert (context->policy != NULL);
573 /* Now become a daemon if appropriate */
574 if (bus_config_parser_get_fork (parser))
579 _dbus_string_init_const (&u, pidfile);
581 if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
586 /* Need to write PID file for ourselves, not for the child process */
591 _dbus_string_init_const (&u, pidfile);
593 if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
598 /* keep around the pid filename so we can delete it later */
599 context->pidfile = _dbus_strdup (pidfile);
601 /* Here we change our credentials if required,
602 * as soon as we've set up our sockets and pidfile
604 user = bus_config_parser_get_user (parser);
607 DBusCredentials creds;
610 _dbus_string_init_const (&u, user);
612 if (!_dbus_credentials_from_username (&u, &creds) ||
616 dbus_set_error (error, DBUS_ERROR_FAILED,
617 "Could not get UID and GID for username \"%s\"",
622 if (!_dbus_change_identity (creds.uid, creds.gid, error))
626 bus_config_parser_unref (parser);
627 _dbus_string_free (&full_address);
628 dbus_free_string_array (auth_mechanisms);
629 server_data_slot_unref ();
635 bus_config_parser_unref (parser);
638 bus_context_unref (context);
640 _dbus_string_free (&full_address);
641 dbus_free_string_array (auth_mechanisms);
643 server_data_slot_unref ();
649 shutdown_server (BusContext *context,
652 if (server == NULL ||
653 !dbus_server_get_is_connected (server))
656 if (!dbus_server_set_watch_functions (server,
660 _dbus_assert_not_reached ("setting watch functions to NULL failed");
662 if (!dbus_server_set_timeout_functions (server,
666 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
668 dbus_server_disconnect (server);
672 bus_context_shutdown (BusContext *context)
676 link = _dbus_list_get_first_link (&context->servers);
679 shutdown_server (context, link->data);
681 link = _dbus_list_get_next_link (&context->servers, link);
686 bus_context_ref (BusContext *context)
688 _dbus_assert (context->refcount > 0);
689 context->refcount += 1;
693 bus_context_unref (BusContext *context)
695 _dbus_assert (context->refcount > 0);
696 context->refcount -= 1;
698 if (context->refcount == 0)
702 _dbus_verbose ("Finalizing bus context %p\n", context);
704 bus_context_shutdown (context);
706 if (context->connections)
708 bus_connections_unref (context->connections);
709 context->connections = NULL;
712 if (context->registry)
714 bus_registry_unref (context->registry);
715 context->registry = NULL;
718 if (context->activation)
720 bus_activation_unref (context->activation);
721 context->activation = NULL;
724 link = _dbus_list_get_first_link (&context->servers);
727 dbus_server_unref (link->data);
729 link = _dbus_list_get_next_link (&context->servers, link);
731 _dbus_list_clear (&context->servers);
735 bus_policy_unref (context->policy);
736 context->policy = NULL;
741 _dbus_loop_unref (context->loop);
742 context->loop = NULL;
745 dbus_free (context->type);
746 dbus_free (context->address);
748 if (context->pidfile)
751 _dbus_string_init_const (&u, context->pidfile);
753 /* Deliberately ignore errors here, since there's not much
754 * we can do about it, and we're exiting anyways.
756 _dbus_delete_file (&u, NULL);
758 dbus_free (context->pidfile);
761 _dbus_user_database_unref (context->user_database);
765 server_data_slot_unref ();
769 /* type may be NULL */
771 bus_context_get_type (BusContext *context)
773 return context->type;
777 bus_context_get_address (BusContext *context)
779 return context->address;
783 bus_context_get_registry (BusContext *context)
785 return context->registry;
789 bus_context_get_connections (BusContext *context)
791 return context->connections;
795 bus_context_get_activation (BusContext *context)
797 return context->activation;
801 bus_context_get_loop (BusContext *context)
803 return context->loop;
807 bus_context_get_user_database (BusContext *context)
809 return context->user_database;
813 bus_context_allow_user (BusContext *context,
816 return bus_policy_allow_user (context->policy,
817 context->user_database,
822 bus_context_create_client_policy (BusContext *context,
823 DBusConnection *connection)
825 return bus_policy_create_client_policy (context->policy, connection);
829 bus_context_get_activation_timeout (BusContext *context)
832 return context->activation_timeout;
836 bus_context_get_auth_timeout (BusContext *context)
838 return context->auth_timeout;
842 bus_context_get_max_completed_connections (BusContext *context)
844 return context->max_completed_connections;
848 bus_context_get_max_incomplete_connections (BusContext *context)
850 return context->max_incomplete_connections;
854 bus_context_get_max_connections_per_user (BusContext *context)
856 return context->max_connections_per_user;
860 bus_context_check_security_policy (BusContext *context,
861 DBusConnection *sender,
862 DBusConnection *recipient,
863 DBusMessage *message,
866 BusClientPolicy *sender_policy;
867 BusClientPolicy *recipient_policy;
869 /* NULL sender/receiver means the bus driver */
873 _dbus_assert (dbus_connection_get_is_authenticated (sender));
874 sender_policy = bus_connection_get_policy (sender);
877 sender_policy = NULL;
879 if (recipient != NULL)
881 _dbus_assert (dbus_connection_get_is_authenticated (recipient));
882 recipient_policy = bus_connection_get_policy (recipient);
885 recipient_policy = NULL;
888 !bus_client_policy_check_can_send (sender_policy,
889 context->registry, recipient,
892 const char *dest = dbus_message_get_destination (message);
893 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
894 "A security policy in place prevents this sender "
895 "from sending this message to this recipient, "
896 "see message bus configuration file (rejected message "
897 "had name \"%s\" destination \"%s\")",
898 dbus_message_get_name (message),
899 dest ? dest : DBUS_SERVICE_DBUS);
903 if (recipient_policy &&
904 !bus_client_policy_check_can_receive (recipient_policy,
905 context->registry, sender,
908 const char *dest = dbus_message_get_destination (message);
909 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
910 "A security policy in place prevents this recipient "
911 "from receiving this message from this sender, "
912 "see message bus configuration file (rejected message "
913 "had name \"%s\" destination \"%s\")",
914 dbus_message_get_name (message),
915 dest ? dest : DBUS_SERVICE_DBUS);
919 /* See if limits on size have been exceeded */
921 dbus_connection_get_outgoing_size (recipient) >
922 context->max_outgoing_bytes)
924 const char *dest = dbus_message_get_destination (message);
925 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
926 "The destination service \"%s\" has a full message queue",
927 dest ? dest : DBUS_SERVICE_DBUS);