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;
46 DBusList *default_rules; /**< Default policy rules */
47 DBusList *mandatory_rules; /**< Mandatory policy rules */
48 DBusHashTable *rules_by_uid; /**< per-UID policy rules */
49 DBusHashTable *rules_by_gid; /**< per-GID policy rules */
50 int activation_timeout; /**< How long to wait for an activation to time out */
51 int auth_timeout; /**< How long to wait for an authentication to time out */
52 int max_completed_connections; /**< Max number of authorized connections */
53 int max_incomplete_connections; /**< Max number of incomplete connections */
54 int max_connections_per_user; /**< Max number of connections auth'd as same user */
57 static int server_data_slot = -1;
58 static int server_data_slot_refcount = 0;
65 #define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
68 server_data_slot_ref (void)
70 if (server_data_slot < 0)
72 server_data_slot = dbus_server_allocate_data_slot ();
74 if (server_data_slot < 0)
77 _dbus_assert (server_data_slot_refcount == 0);
80 server_data_slot_refcount += 1;
86 server_data_slot_unref (void)
88 _dbus_assert (server_data_slot_refcount > 0);
90 server_data_slot_refcount -= 1;
92 if (server_data_slot_refcount == 0)
94 dbus_server_free_data_slot (server_data_slot);
95 server_data_slot = -1;
100 server_get_context (DBusServer *server)
105 if (!server_data_slot_ref ())
108 bd = BUS_SERVER_DATA (server);
111 server_data_slot_unref ();
115 context = bd->context;
117 server_data_slot_unref ();
123 server_watch_callback (DBusWatch *watch,
124 unsigned int condition,
127 DBusServer *server = data;
129 return dbus_server_handle_watch (server, watch, condition);
133 add_server_watch (DBusWatch *watch,
136 DBusServer *server = data;
139 context = server_get_context (server);
141 return _dbus_loop_add_watch (context->loop,
142 watch, server_watch_callback, server,
147 remove_server_watch (DBusWatch *watch,
150 DBusServer *server = data;
153 context = server_get_context (server);
155 _dbus_loop_remove_watch (context->loop,
156 watch, server_watch_callback, server);
161 server_timeout_callback (DBusTimeout *timeout,
164 /* can return FALSE on OOM but we just let it fire again later */
165 dbus_timeout_handle (timeout);
169 add_server_timeout (DBusTimeout *timeout,
172 DBusServer *server = data;
175 context = server_get_context (server);
177 return _dbus_loop_add_timeout (context->loop,
178 timeout, server_timeout_callback, server, NULL);
182 remove_server_timeout (DBusTimeout *timeout,
185 DBusServer *server = data;
188 context = server_get_context (server);
190 _dbus_loop_remove_timeout (context->loop,
191 timeout, server_timeout_callback, server);
195 new_connection_callback (DBusServer *server,
196 DBusConnection *new_connection,
199 BusContext *context = data;
201 if (!bus_connections_setup_connection (context->connections, new_connection))
203 _dbus_verbose ("No memory to setup new connection\n");
205 /* if we don't do this, it will get unref'd without
206 * being disconnected... kind of strange really
207 * that we have to do this, people won't get it right
210 dbus_connection_disconnect (new_connection);
213 /* on OOM, we won't have ref'd the connection so it will die. */
217 free_rule_func (void *data,
220 BusPolicyRule *rule = data;
222 bus_policy_rule_unref (rule);
226 free_rule_list_func (void *data)
228 DBusList **list = data;
230 _dbus_list_foreach (list, free_rule_func, NULL);
232 _dbus_list_clear (list);
238 free_server_data (void *data)
240 BusServerData *bd = data;
246 setup_server (BusContext *context,
248 char **auth_mechanisms,
253 bd = dbus_new0 (BusServerData, 1);
254 if (!dbus_server_set_data (server,
256 bd, free_server_data))
263 bd->context = context;
265 if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
271 dbus_server_set_new_connection_function (server,
272 new_connection_callback,
275 if (!dbus_server_set_watch_functions (server,
286 if (!dbus_server_set_timeout_functions (server,
288 remove_server_timeout,
300 bus_context_new (const DBusString *config_file,
306 DBusList **addresses;
307 BusConfigParser *parser;
308 DBusString full_address;
309 const char *user, *pidfile;
310 char **auth_mechanisms;
311 DBusList **auth_mechanisms_list;
314 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
316 if (!_dbus_string_init (&full_address))
322 if (!server_data_slot_ref ())
325 _dbus_string_free (&full_address);
331 auth_mechanisms = NULL;
333 parser = bus_config_load (config_file, error);
337 /* Check for an existing pid file. Of course this is a race;
338 * we'd have to use fcntl() locks on the pid file to
339 * avoid that. But we want to check for the pid file
340 * before overwriting any existing sockets, etc.
342 pidfile = bus_config_parser_get_pidfile (parser);
349 dbus_error_init (&tmp_error);
350 _dbus_string_init_const (&u, pidfile);
352 if (_dbus_stat (&u, &stbuf, &tmp_error))
354 dbus_set_error (error, DBUS_ERROR_FAILED,
355 "The pid file \"%s\" exists, if the message bus is not running, remove this file",
357 dbus_error_free (&tmp_error);
362 context = dbus_new0 (BusContext, 1);
369 context->refcount = 1;
371 /* we need another ref of the server data slot for the context
374 if (!server_data_slot_ref ())
375 _dbus_assert_not_reached ("second ref of server data slot failed");
377 #ifdef DBUS_BUILD_TESTS
378 context->activation_timeout = 6000; /* 6 seconds */
380 context->activation_timeout = 15000; /* 15 seconds */
383 /* Making this long risks making a DOS attack easier, but too short
384 * and legitimate auth will fail. If interactive auth (ask user for
385 * password) is allowed, then potentially it has to be quite long.
386 * Ultimately it needs to come from the configuration file.
388 context->auth_timeout = 3000; /* 3 seconds */
390 context->max_incomplete_connections = 32;
391 context->max_connections_per_user = 128;
393 /* Note that max_completed_connections / max_connections_per_user
394 * is the number of users that would have to work together to
395 * DOS all the other users.
397 context->max_completed_connections = 1024;
399 context->loop = _dbus_loop_new ();
400 if (context->loop == NULL)
406 /* Build an array of auth mechanisms */
408 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
409 len = _dbus_list_get_length (auth_mechanisms_list);
415 auth_mechanisms = dbus_new0 (char*, len + 1);
416 if (auth_mechanisms == NULL)
420 link = _dbus_list_get_first_link (auth_mechanisms_list);
423 auth_mechanisms[i] = _dbus_strdup (link->data);
424 if (auth_mechanisms[i] == NULL)
426 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
431 auth_mechanisms = NULL;
434 /* Listen on our addresses */
436 addresses = bus_config_parser_get_addresses (parser);
438 link = _dbus_list_get_first_link (addresses);
443 server = dbus_server_listen (link->data, error);
446 else if (!setup_server (context, server, auth_mechanisms, error))
449 if (!_dbus_list_append (&context->servers, server))
455 link = _dbus_list_get_next_link (addresses, link);
458 /* note that type may be NULL */
459 context->type = _dbus_strdup (bus_config_parser_get_type (parser));
461 /* We have to build the address backward, so that
462 * <listen> later in the config file have priority
464 link = _dbus_list_get_last_link (&context->servers);
469 addr = dbus_server_get_address (link->data);
476 if (_dbus_string_get_length (&full_address) > 0)
478 if (!_dbus_string_append (&full_address, ";"))
485 if (!_dbus_string_append (&full_address, addr))
493 link = _dbus_list_get_prev_link (&context->servers, link);
496 if (!_dbus_string_copy_data (&full_address, &context->address))
502 /* Note that we don't know whether the print_addr_fd is
503 * one of the sockets we're using to listen on, or some
504 * other random thing. But I think the answer is "don't do
507 if (print_addr_fd >= 0)
510 const char *a = bus_context_get_address (context);
513 _dbus_assert (a != NULL);
514 if (!_dbus_string_init (&addr))
520 if (!_dbus_string_append (&addr, a) ||
521 !_dbus_string_append (&addr, "\n"))
523 _dbus_string_free (&addr);
528 bytes = _dbus_string_get_length (&addr);
529 if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
531 dbus_set_error (error, DBUS_ERROR_FAILED,
532 "Printing message bus address: %s\n",
533 _dbus_strerror (errno));
534 _dbus_string_free (&addr);
538 if (print_addr_fd > 2)
539 _dbus_close (print_addr_fd, NULL);
541 _dbus_string_free (&addr);
544 /* Create activation subsystem */
546 context->activation = bus_activation_new (context, &full_address,
547 bus_config_parser_get_service_dirs (parser),
549 if (context->activation == NULL)
551 _DBUS_ASSERT_ERROR_IS_SET (error);
555 context->connections = bus_connections_new (context);
556 if (context->connections == NULL)
562 context->registry = bus_registry_new (context);
563 if (context->registry == NULL)
569 context->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
571 free_rule_list_func);
572 if (context->rules_by_uid == NULL)
578 context->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
580 free_rule_list_func);
581 if (context->rules_by_gid == NULL)
587 /* Now become a daemon if appropriate */
588 if (bus_config_parser_get_fork (parser))
593 _dbus_string_init_const (&u, pidfile);
595 if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
600 /* Need to write PID file for ourselves, not for the child process */
605 _dbus_string_init_const (&u, pidfile);
607 if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
612 /* keep around the pid filename so we can delete it later */
613 context->pidfile = _dbus_strdup (pidfile);
615 /* Here we change our credentials if required,
616 * as soon as we've set up our sockets and pidfile
618 user = bus_config_parser_get_user (parser);
621 DBusCredentials creds;
624 _dbus_string_init_const (&u, user);
626 if (!_dbus_credentials_from_username (&u, &creds) ||
630 dbus_set_error (error, DBUS_ERROR_FAILED,
631 "Could not get UID and GID for username \"%s\"",
636 if (!_dbus_change_identity (creds.uid, creds.gid, error))
640 bus_config_parser_unref (parser);
641 _dbus_string_free (&full_address);
642 dbus_free_string_array (auth_mechanisms);
643 server_data_slot_unref ();
649 bus_config_parser_unref (parser);
652 bus_context_unref (context);
654 _dbus_string_free (&full_address);
655 dbus_free_string_array (auth_mechanisms);
657 server_data_slot_unref ();
663 shutdown_server (BusContext *context,
666 if (server == NULL ||
667 !dbus_server_get_is_connected (server))
670 if (!dbus_server_set_watch_functions (server,
674 _dbus_assert_not_reached ("setting watch functions to NULL failed");
676 if (!dbus_server_set_timeout_functions (server,
680 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
682 dbus_server_disconnect (server);
686 bus_context_shutdown (BusContext *context)
690 link = _dbus_list_get_first_link (&context->servers);
693 shutdown_server (context, link->data);
695 link = _dbus_list_get_next_link (&context->servers, link);
700 bus_context_ref (BusContext *context)
702 _dbus_assert (context->refcount > 0);
703 context->refcount += 1;
707 bus_context_unref (BusContext *context)
709 _dbus_assert (context->refcount > 0);
710 context->refcount -= 1;
712 if (context->refcount == 0)
716 _dbus_verbose ("Finalizing bus context %p\n", context);
718 bus_context_shutdown (context);
720 if (context->connections)
722 bus_connections_unref (context->connections);
723 context->connections = NULL;
726 if (context->registry)
728 bus_registry_unref (context->registry);
729 context->registry = NULL;
732 if (context->activation)
734 bus_activation_unref (context->activation);
735 context->activation = NULL;
738 link = _dbus_list_get_first_link (&context->servers);
741 dbus_server_unref (link->data);
743 link = _dbus_list_get_next_link (&context->servers, link);
745 _dbus_list_clear (&context->servers);
747 if (context->rules_by_uid)
749 _dbus_hash_table_unref (context->rules_by_uid);
750 context->rules_by_uid = NULL;
753 if (context->rules_by_gid)
755 _dbus_hash_table_unref (context->rules_by_gid);
756 context->rules_by_gid = NULL;
761 _dbus_loop_unref (context->loop);
762 context->loop = NULL;
765 dbus_free (context->type);
766 dbus_free (context->address);
768 if (context->pidfile)
771 _dbus_string_init_const (&u, context->pidfile);
773 /* Deliberately ignore errors here, since there's not much
774 * we can do about it, and we're exiting anyways.
776 _dbus_delete_file (&u, NULL);
778 dbus_free (context->pidfile);
783 server_data_slot_unref ();
787 /* type may be NULL */
789 bus_context_get_type (BusContext *context)
791 return context->type;
795 bus_context_get_address (BusContext *context)
797 return context->address;
801 bus_context_get_registry (BusContext *context)
803 return context->registry;
807 bus_context_get_connections (BusContext *context)
809 return context->connections;
813 bus_context_get_activation (BusContext *context)
815 return context->activation;
819 bus_context_get_loop (BusContext *context)
821 return context->loop;
825 list_allows_user (dbus_bool_t def,
828 const unsigned long *group_ids,
836 link = _dbus_list_get_first_link (list);
839 BusPolicyRule *rule = link->data;
840 link = _dbus_list_get_next_link (list, link);
842 if (rule->type == BUS_POLICY_RULE_USER)
844 if (rule->d.user.uid != uid)
847 else if (rule->type == BUS_POLICY_RULE_GROUP)
852 while (i < n_group_ids)
854 if (rule->d.group.gid == group_ids[i])
859 if (i == n_group_ids)
865 allowed = rule->allow;
872 bus_context_allow_user (BusContext *context,
876 unsigned long *group_ids;
879 /* On OOM or error we always reject the user */
880 if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
882 _dbus_verbose ("Did not get any groups for UID %lu\n",
889 allowed = list_allows_user (allowed,
890 &context->default_rules,
892 group_ids, n_group_ids);
894 allowed = list_allows_user (allowed,
895 &context->mandatory_rules,
897 group_ids, n_group_ids);
899 dbus_free (group_ids);
905 add_list_to_policy (DBusList **list,
910 link = _dbus_list_get_first_link (list);
913 BusPolicyRule *rule = link->data;
914 link = _dbus_list_get_next_link (list, link);
918 case BUS_POLICY_RULE_USER:
919 case BUS_POLICY_RULE_GROUP:
920 /* These aren't per-connection policies */
923 case BUS_POLICY_RULE_OWN:
924 case BUS_POLICY_RULE_SEND:
925 case BUS_POLICY_RULE_RECEIVE:
926 /* These are per-connection */
927 if (!bus_policy_append_rule (policy, rule))
937 bus_context_create_connection_policy (BusContext *context,
938 DBusConnection *connection)
944 _dbus_assert (dbus_connection_get_is_authenticated (connection));
946 policy = bus_policy_new ();
950 if (!add_list_to_policy (&context->default_rules,
954 /* we avoid the overhead of looking up user's groups
955 * if we don't have any group rules anyway
957 if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
959 const unsigned long *groups;
963 if (!bus_connection_get_groups (connection, &groups, &n_groups))
969 list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
974 if (!add_list_to_policy (list, policy))
982 if (!dbus_connection_get_unix_user (connection, &uid))
985 list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
988 if (!add_list_to_policy (list, policy))
991 if (!add_list_to_policy (&context->mandatory_rules,
995 bus_policy_optimize (policy);
1000 bus_policy_unref (policy);
1005 bus_context_get_activation_timeout (BusContext *context)
1008 return context->activation_timeout;