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;
51 static int server_data_slot = -1;
52 static int server_data_slot_refcount = 0;
59 #define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
62 server_data_slot_ref (void)
64 if (server_data_slot < 0)
66 server_data_slot = dbus_server_allocate_data_slot ();
68 if (server_data_slot < 0)
71 _dbus_assert (server_data_slot_refcount == 0);
74 server_data_slot_refcount += 1;
80 server_data_slot_unref (void)
82 _dbus_assert (server_data_slot_refcount > 0);
84 server_data_slot_refcount -= 1;
86 if (server_data_slot_refcount == 0)
88 dbus_server_free_data_slot (server_data_slot);
89 server_data_slot = -1;
94 server_get_context (DBusServer *server)
99 if (!server_data_slot_ref ())
102 bd = BUS_SERVER_DATA (server);
105 server_data_slot_unref ();
109 context = bd->context;
111 server_data_slot_unref ();
117 server_watch_callback (DBusWatch *watch,
118 unsigned int condition,
121 /* FIXME this can be done in dbus-mainloop.c
122 * if the code in activation.c for the babysitter
123 * watch handler is fixed.
126 return dbus_watch_handle (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 dbus_connection_set_max_received_size (new_connection,
211 context->limits.max_incoming_bytes);
213 dbus_connection_set_max_message_size (new_connection,
214 context->limits.max_message_size);
216 /* on OOM, we won't have ref'd the connection so it will die. */
220 free_server_data (void *data)
222 BusServerData *bd = data;
228 setup_server (BusContext *context,
230 char **auth_mechanisms,
235 bd = dbus_new0 (BusServerData, 1);
236 if (!dbus_server_set_data (server,
238 bd, free_server_data))
245 bd->context = context;
247 if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
253 dbus_server_set_new_connection_function (server,
254 new_connection_callback,
257 if (!dbus_server_set_watch_functions (server,
268 if (!dbus_server_set_timeout_functions (server,
270 remove_server_timeout,
282 bus_context_new (const DBusString *config_file,
288 DBusList **addresses;
289 BusConfigParser *parser;
290 DBusString full_address;
291 const char *user, *pidfile;
292 char **auth_mechanisms;
293 DBusList **auth_mechanisms_list;
296 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
298 if (!_dbus_string_init (&full_address))
304 if (!server_data_slot_ref ())
307 _dbus_string_free (&full_address);
313 auth_mechanisms = NULL;
315 parser = bus_config_load (config_file, error);
319 /* Check for an existing pid file. Of course this is a race;
320 * we'd have to use fcntl() locks on the pid file to
321 * avoid that. But we want to check for the pid file
322 * before overwriting any existing sockets, etc.
324 pidfile = bus_config_parser_get_pidfile (parser);
331 dbus_error_init (&tmp_error);
332 _dbus_string_init_const (&u, pidfile);
334 if (_dbus_stat (&u, &stbuf, &tmp_error))
336 dbus_set_error (error, DBUS_ERROR_FAILED,
337 "The pid file \"%s\" exists, if the message bus is not running, remove this file",
339 dbus_error_free (&tmp_error);
344 context = dbus_new0 (BusContext, 1);
351 context->refcount = 1;
353 /* get our limits and timeout lengths */
354 bus_config_parser_get_limits (parser, &context->limits);
356 /* we need another ref of the server data slot for the context
359 if (!server_data_slot_ref ())
360 _dbus_assert_not_reached ("second ref of server data slot failed");
362 context->user_database = _dbus_user_database_new ();
363 if (context->user_database == NULL)
369 context->loop = _dbus_loop_new ();
370 if (context->loop == NULL)
376 /* Build an array of auth mechanisms */
378 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
379 len = _dbus_list_get_length (auth_mechanisms_list);
385 auth_mechanisms = dbus_new0 (char*, len + 1);
386 if (auth_mechanisms == NULL)
390 link = _dbus_list_get_first_link (auth_mechanisms_list);
393 auth_mechanisms[i] = _dbus_strdup (link->data);
394 if (auth_mechanisms[i] == NULL)
396 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
401 auth_mechanisms = NULL;
404 /* Listen on our addresses */
406 addresses = bus_config_parser_get_addresses (parser);
408 link = _dbus_list_get_first_link (addresses);
413 server = dbus_server_listen (link->data, error);
416 else if (!setup_server (context, server, auth_mechanisms, error))
419 if (!_dbus_list_append (&context->servers, server))
425 link = _dbus_list_get_next_link (addresses, link);
428 /* note that type may be NULL */
429 context->type = _dbus_strdup (bus_config_parser_get_type (parser));
431 /* We have to build the address backward, so that
432 * <listen> later in the config file have priority
434 link = _dbus_list_get_last_link (&context->servers);
439 addr = dbus_server_get_address (link->data);
446 if (_dbus_string_get_length (&full_address) > 0)
448 if (!_dbus_string_append (&full_address, ";"))
455 if (!_dbus_string_append (&full_address, addr))
463 link = _dbus_list_get_prev_link (&context->servers, link);
466 if (!_dbus_string_copy_data (&full_address, &context->address))
472 /* Note that we don't know whether the print_addr_fd is
473 * one of the sockets we're using to listen on, or some
474 * other random thing. But I think the answer is "don't do
477 if (print_addr_fd >= 0)
480 const char *a = bus_context_get_address (context);
483 _dbus_assert (a != NULL);
484 if (!_dbus_string_init (&addr))
490 if (!_dbus_string_append (&addr, a) ||
491 !_dbus_string_append (&addr, "\n"))
493 _dbus_string_free (&addr);
498 bytes = _dbus_string_get_length (&addr);
499 if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
501 dbus_set_error (error, DBUS_ERROR_FAILED,
502 "Printing message bus address: %s\n",
503 _dbus_strerror (errno));
504 _dbus_string_free (&addr);
508 if (print_addr_fd > 2)
509 _dbus_close (print_addr_fd, NULL);
511 _dbus_string_free (&addr);
514 /* Create activation subsystem */
516 context->activation = bus_activation_new (context, &full_address,
517 bus_config_parser_get_service_dirs (parser),
519 if (context->activation == NULL)
521 _DBUS_ASSERT_ERROR_IS_SET (error);
525 context->connections = bus_connections_new (context);
526 if (context->connections == NULL)
532 context->registry = bus_registry_new (context);
533 if (context->registry == NULL)
539 context->policy = bus_config_parser_steal_policy (parser);
540 _dbus_assert (context->policy != NULL);
542 /* Now become a daemon if appropriate */
543 if (bus_config_parser_get_fork (parser))
548 _dbus_string_init_const (&u, pidfile);
550 if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
555 /* Need to write PID file for ourselves, not for the child process */
560 _dbus_string_init_const (&u, pidfile);
562 if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
567 /* keep around the pid filename so we can delete it later */
568 context->pidfile = _dbus_strdup (pidfile);
570 /* Here we change our credentials if required,
571 * as soon as we've set up our sockets and pidfile
573 user = bus_config_parser_get_user (parser);
576 DBusCredentials creds;
579 _dbus_string_init_const (&u, user);
581 if (!_dbus_credentials_from_username (&u, &creds) ||
585 dbus_set_error (error, DBUS_ERROR_FAILED,
586 "Could not get UID and GID for username \"%s\"",
591 if (!_dbus_change_identity (creds.uid, creds.gid, error))
595 bus_config_parser_unref (parser);
596 _dbus_string_free (&full_address);
597 dbus_free_string_array (auth_mechanisms);
598 server_data_slot_unref ();
604 bus_config_parser_unref (parser);
607 bus_context_unref (context);
609 _dbus_string_free (&full_address);
610 dbus_free_string_array (auth_mechanisms);
612 server_data_slot_unref ();
618 shutdown_server (BusContext *context,
621 if (server == NULL ||
622 !dbus_server_get_is_connected (server))
625 if (!dbus_server_set_watch_functions (server,
629 _dbus_assert_not_reached ("setting watch functions to NULL failed");
631 if (!dbus_server_set_timeout_functions (server,
635 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
637 dbus_server_disconnect (server);
641 bus_context_shutdown (BusContext *context)
645 link = _dbus_list_get_first_link (&context->servers);
648 shutdown_server (context, link->data);
650 link = _dbus_list_get_next_link (&context->servers, link);
655 bus_context_ref (BusContext *context)
657 _dbus_assert (context->refcount > 0);
658 context->refcount += 1;
662 bus_context_unref (BusContext *context)
664 _dbus_assert (context->refcount > 0);
665 context->refcount -= 1;
667 if (context->refcount == 0)
671 _dbus_verbose ("Finalizing bus context %p\n", context);
673 bus_context_shutdown (context);
675 if (context->connections)
677 bus_connections_unref (context->connections);
678 context->connections = NULL;
681 if (context->registry)
683 bus_registry_unref (context->registry);
684 context->registry = NULL;
687 if (context->activation)
689 bus_activation_unref (context->activation);
690 context->activation = NULL;
693 link = _dbus_list_get_first_link (&context->servers);
696 dbus_server_unref (link->data);
698 link = _dbus_list_get_next_link (&context->servers, link);
700 _dbus_list_clear (&context->servers);
704 bus_policy_unref (context->policy);
705 context->policy = NULL;
710 _dbus_loop_unref (context->loop);
711 context->loop = NULL;
714 dbus_free (context->type);
715 dbus_free (context->address);
717 if (context->pidfile)
720 _dbus_string_init_const (&u, context->pidfile);
722 /* Deliberately ignore errors here, since there's not much
723 * we can do about it, and we're exiting anyways.
725 _dbus_delete_file (&u, NULL);
727 dbus_free (context->pidfile);
730 _dbus_user_database_unref (context->user_database);
734 server_data_slot_unref ();
738 /* type may be NULL */
740 bus_context_get_type (BusContext *context)
742 return context->type;
746 bus_context_get_address (BusContext *context)
748 return context->address;
752 bus_context_get_registry (BusContext *context)
754 return context->registry;
758 bus_context_get_connections (BusContext *context)
760 return context->connections;
764 bus_context_get_activation (BusContext *context)
766 return context->activation;
770 bus_context_get_loop (BusContext *context)
772 return context->loop;
776 bus_context_get_user_database (BusContext *context)
778 return context->user_database;
782 bus_context_allow_user (BusContext *context,
785 return bus_policy_allow_user (context->policy,
786 context->user_database,
791 bus_context_create_client_policy (BusContext *context,
792 DBusConnection *connection)
794 return bus_policy_create_client_policy (context->policy, connection);
798 bus_context_get_activation_timeout (BusContext *context)
801 return context->limits.activation_timeout;
805 bus_context_get_auth_timeout (BusContext *context)
807 return context->limits.auth_timeout;
811 bus_context_get_max_completed_connections (BusContext *context)
813 return context->limits.max_completed_connections;
817 bus_context_get_max_incomplete_connections (BusContext *context)
819 return context->limits.max_incomplete_connections;
823 bus_context_get_max_connections_per_user (BusContext *context)
825 return context->limits.max_connections_per_user;
829 bus_context_check_security_policy (BusContext *context,
830 DBusConnection *sender,
831 DBusConnection *recipient,
832 DBusMessage *message,
835 BusClientPolicy *sender_policy;
836 BusClientPolicy *recipient_policy;
838 /* NULL sender/receiver means the bus driver */
842 _dbus_assert (dbus_connection_get_is_authenticated (sender));
843 sender_policy = bus_connection_get_policy (sender);
846 sender_policy = NULL;
848 if (recipient != NULL)
850 _dbus_assert (dbus_connection_get_is_authenticated (recipient));
851 recipient_policy = bus_connection_get_policy (recipient);
854 recipient_policy = NULL;
857 !bus_client_policy_check_can_send (sender_policy,
858 context->registry, recipient,
861 const char *dest = dbus_message_get_destination (message);
862 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
863 "A security policy in place prevents this sender "
864 "from sending this message to this recipient, "
865 "see message bus configuration file (rejected message "
866 "had name \"%s\" destination \"%s\")",
867 dbus_message_get_name (message),
868 dest ? dest : DBUS_SERVICE_DBUS);
872 if (recipient_policy &&
873 !bus_client_policy_check_can_receive (recipient_policy,
874 context->registry, sender,
877 const char *dest = dbus_message_get_destination (message);
878 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
879 "A security policy in place prevents this recipient "
880 "from receiving this message from this sender, "
881 "see message bus configuration file (rejected message "
882 "had name \"%s\" destination \"%s\")",
883 dbus_message_get_name (message),
884 dest ? dest : DBUS_SERVICE_DBUS);
888 /* See if limits on size have been exceeded */
890 dbus_connection_get_outgoing_size (recipient) >
891 context->limits.max_outgoing_bytes)
893 const char *dest = dbus_message_get_destination (message);
894 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
895 "The destination service \"%s\" has a full message queue",
896 dest ? dest : DBUS_SERVICE_DBUS);