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
26 #include "activation.h"
27 #include "connection.h"
31 #include "config-parser.h"
32 #include <dbus/dbus-list.h>
33 #include <dbus/dbus-hash.h>
34 #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 bus_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 bus_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 bus_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 bus_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,
305 DBusList **addresses;
306 BusConfigParser *parser;
307 DBusString full_address;
309 char **auth_mechanisms;
310 DBusList **auth_mechanisms_list;
313 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
315 if (!_dbus_string_init (&full_address))
321 if (!server_data_slot_ref ())
324 _dbus_string_free (&full_address);
330 auth_mechanisms = NULL;
332 parser = bus_config_load (config_file, error);
336 context = dbus_new0 (BusContext, 1);
343 context->refcount = 1;
345 /* we need another ref of the server data slot for the context
348 if (!server_data_slot_ref ())
349 _dbus_assert_not_reached ("second ref of server data slot failed");
351 #ifdef DBUS_BUILD_TESTS
352 context->activation_timeout = 6000; /* 6 seconds */
354 context->activation_timeout = 15000; /* 15 seconds */
357 /* Making this long risks making a DOS attack easier, but too short
358 * and legitimate auth will fail. If interactive auth (ask user for
359 * password) is allowed, then potentially it has to be quite long.
360 * Ultimately it needs to come from the configuration file.
362 context->auth_timeout = 3000; /* 3 seconds */
364 context->max_incomplete_connections = 32;
365 context->max_connections_per_user = 128;
367 /* Note that max_completed_connections / max_connections_per_user
368 * is the number of users that would have to work together to
369 * DOS all the other users.
371 context->max_completed_connections = 1024;
373 context->loop = bus_loop_new ();
374 if (context->loop == NULL)
380 /* Build an array of auth mechanisms */
382 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
383 len = _dbus_list_get_length (auth_mechanisms_list);
389 auth_mechanisms = dbus_new0 (char*, len + 1);
390 if (auth_mechanisms == NULL)
394 link = _dbus_list_get_first_link (auth_mechanisms_list);
397 auth_mechanisms[i] = _dbus_strdup (link->data);
398 if (auth_mechanisms[i] == NULL)
400 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
405 auth_mechanisms = NULL;
408 /* Listen on our addresses */
410 addresses = bus_config_parser_get_addresses (parser);
412 link = _dbus_list_get_first_link (addresses);
417 server = dbus_server_listen (link->data, error);
420 else if (!setup_server (context, server, auth_mechanisms, error))
423 if (!_dbus_list_append (&context->servers, server))
429 link = _dbus_list_get_next_link (addresses, link);
432 /* Here we change our credentials if required,
433 * as soon as we've set up our sockets
435 user = bus_config_parser_get_user (parser);
438 DBusCredentials creds;
441 _dbus_string_init_const (&u, user);
443 if (!_dbus_credentials_from_username (&u, &creds) ||
447 dbus_set_error (error, DBUS_ERROR_FAILED,
448 "Could not get UID and GID for username \"%s\"",
453 if (!_dbus_change_identity (creds.uid, creds.gid, error))
457 /* note that type may be NULL */
458 context->type = _dbus_strdup (bus_config_parser_get_type (parser));
460 /* We have to build the address backward, so that
461 * <listen> later in the config file have priority
463 link = _dbus_list_get_last_link (&context->servers);
468 addr = dbus_server_get_address (link->data);
475 if (_dbus_string_get_length (&full_address) > 0)
477 if (!_dbus_string_append (&full_address, ";"))
484 if (!_dbus_string_append (&full_address, addr))
492 link = _dbus_list_get_prev_link (&context->servers, link);
495 if (!_dbus_string_copy_data (&full_address, &context->address))
501 /* Create activation subsystem */
503 context->activation = bus_activation_new (context, &full_address,
504 bus_config_parser_get_service_dirs (parser),
506 if (context->activation == NULL)
508 _DBUS_ASSERT_ERROR_IS_SET (error);
512 context->connections = bus_connections_new (context);
513 if (context->connections == NULL)
519 context->registry = bus_registry_new (context);
520 if (context->registry == NULL)
526 context->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
528 free_rule_list_func);
529 if (context->rules_by_uid == NULL)
535 context->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
537 free_rule_list_func);
538 if (context->rules_by_gid == NULL)
544 /* Now become a daemon if appropriate */
545 if (bus_config_parser_get_fork (parser))
547 if (!_dbus_become_daemon (error))
551 bus_config_parser_unref (parser);
552 _dbus_string_free (&full_address);
553 dbus_free_string_array (auth_mechanisms);
554 server_data_slot_unref ();
560 bus_config_parser_unref (parser);
563 bus_context_unref (context);
565 _dbus_string_free (&full_address);
566 dbus_free_string_array (auth_mechanisms);
568 server_data_slot_unref ();
574 shutdown_server (BusContext *context,
577 if (server == NULL ||
578 !dbus_server_get_is_connected (server))
581 if (!dbus_server_set_watch_functions (server,
585 _dbus_assert_not_reached ("setting watch functions to NULL failed");
587 if (!dbus_server_set_timeout_functions (server,
591 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
593 dbus_server_disconnect (server);
597 bus_context_shutdown (BusContext *context)
601 link = _dbus_list_get_first_link (&context->servers);
604 shutdown_server (context, link->data);
606 link = _dbus_list_get_next_link (&context->servers, link);
611 bus_context_ref (BusContext *context)
613 _dbus_assert (context->refcount > 0);
614 context->refcount += 1;
618 bus_context_unref (BusContext *context)
620 _dbus_assert (context->refcount > 0);
621 context->refcount -= 1;
623 if (context->refcount == 0)
627 _dbus_verbose ("Finalizing bus context %p\n", context);
629 bus_context_shutdown (context);
631 if (context->connections)
633 bus_connections_unref (context->connections);
634 context->connections = NULL;
637 if (context->registry)
639 bus_registry_unref (context->registry);
640 context->registry = NULL;
643 if (context->activation)
645 bus_activation_unref (context->activation);
646 context->activation = NULL;
649 link = _dbus_list_get_first_link (&context->servers);
652 dbus_server_unref (link->data);
654 link = _dbus_list_get_next_link (&context->servers, link);
656 _dbus_list_clear (&context->servers);
658 if (context->rules_by_uid)
660 _dbus_hash_table_unref (context->rules_by_uid);
661 context->rules_by_uid = NULL;
664 if (context->rules_by_gid)
666 _dbus_hash_table_unref (context->rules_by_gid);
667 context->rules_by_gid = NULL;
672 bus_loop_unref (context->loop);
673 context->loop = NULL;
676 dbus_free (context->type);
677 dbus_free (context->address);
680 server_data_slot_unref ();
684 /* type may be NULL */
686 bus_context_get_type (BusContext *context)
688 return context->type;
692 bus_context_get_address (BusContext *context)
694 return context->address;
698 bus_context_get_registry (BusContext *context)
700 return context->registry;
704 bus_context_get_connections (BusContext *context)
706 return context->connections;
710 bus_context_get_activation (BusContext *context)
712 return context->activation;
716 bus_context_get_loop (BusContext *context)
718 return context->loop;
722 list_allows_user (dbus_bool_t def,
725 const unsigned long *group_ids,
733 link = _dbus_list_get_first_link (list);
736 BusPolicyRule *rule = link->data;
737 link = _dbus_list_get_next_link (list, link);
739 if (rule->type == BUS_POLICY_RULE_USER)
741 if (rule->d.user.uid != uid)
744 else if (rule->type == BUS_POLICY_RULE_GROUP)
749 while (i < n_group_ids)
751 if (rule->d.group.gid == group_ids[i])
756 if (i == n_group_ids)
762 allowed = rule->allow;
769 bus_context_allow_user (BusContext *context,
773 unsigned long *group_ids;
776 /* On OOM or error we always reject the user */
777 if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
779 _dbus_verbose ("Did not get any groups for UID %lu\n",
786 allowed = list_allows_user (allowed,
787 &context->default_rules,
789 group_ids, n_group_ids);
791 allowed = list_allows_user (allowed,
792 &context->mandatory_rules,
794 group_ids, n_group_ids);
796 dbus_free (group_ids);
802 add_list_to_policy (DBusList **list,
807 link = _dbus_list_get_first_link (list);
810 BusPolicyRule *rule = link->data;
811 link = _dbus_list_get_next_link (list, link);
815 case BUS_POLICY_RULE_USER:
816 case BUS_POLICY_RULE_GROUP:
817 /* These aren't per-connection policies */
820 case BUS_POLICY_RULE_OWN:
821 case BUS_POLICY_RULE_SEND:
822 case BUS_POLICY_RULE_RECEIVE:
823 /* These are per-connection */
824 if (!bus_policy_append_rule (policy, rule))
834 bus_context_create_connection_policy (BusContext *context,
835 DBusConnection *connection)
841 _dbus_assert (dbus_connection_get_is_authenticated (connection));
843 policy = bus_policy_new ();
847 if (!add_list_to_policy (&context->default_rules,
851 /* we avoid the overhead of looking up user's groups
852 * if we don't have any group rules anyway
854 if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
856 const unsigned long *groups;
860 if (!bus_connection_get_groups (connection, &groups, &n_groups))
866 list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
871 if (!add_list_to_policy (list, policy))
879 if (!dbus_connection_get_unix_user (connection, &uid))
882 list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
885 if (!add_list_to_policy (list, policy))
888 if (!add_list_to_policy (&context->mandatory_rules,
892 bus_policy_optimize (policy);
897 bus_policy_unref (policy);
902 bus_context_get_activation_timeout (BusContext *context)
905 return context->activation_timeout;