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,
306 DBusList **addresses;
307 BusConfigParser *parser;
308 DBusString full_address;
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 context = dbus_new0 (BusContext, 1);
344 context->refcount = 1;
346 /* we need another ref of the server data slot for the context
349 if (!server_data_slot_ref ())
350 _dbus_assert_not_reached ("second ref of server data slot failed");
352 #ifdef DBUS_BUILD_TESTS
353 context->activation_timeout = 6000; /* 6 seconds */
355 context->activation_timeout = 15000; /* 15 seconds */
358 /* Making this long risks making a DOS attack easier, but too short
359 * and legitimate auth will fail. If interactive auth (ask user for
360 * password) is allowed, then potentially it has to be quite long.
361 * Ultimately it needs to come from the configuration file.
363 context->auth_timeout = 3000; /* 3 seconds */
365 context->max_incomplete_connections = 32;
366 context->max_connections_per_user = 128;
368 /* Note that max_completed_connections / max_connections_per_user
369 * is the number of users that would have to work together to
370 * DOS all the other users.
372 context->max_completed_connections = 1024;
374 context->loop = bus_loop_new ();
375 if (context->loop == NULL)
381 /* Build an array of auth mechanisms */
383 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
384 len = _dbus_list_get_length (auth_mechanisms_list);
390 auth_mechanisms = dbus_new0 (char*, len + 1);
391 if (auth_mechanisms == NULL)
395 link = _dbus_list_get_first_link (auth_mechanisms_list);
398 auth_mechanisms[i] = _dbus_strdup (link->data);
399 if (auth_mechanisms[i] == NULL)
401 link = _dbus_list_get_next_link (auth_mechanisms_list, link);
406 auth_mechanisms = NULL;
409 /* Listen on our addresses */
411 addresses = bus_config_parser_get_addresses (parser);
413 link = _dbus_list_get_first_link (addresses);
418 server = dbus_server_listen (link->data, error);
421 else if (!setup_server (context, server, auth_mechanisms, error))
424 if (!_dbus_list_append (&context->servers, server))
430 link = _dbus_list_get_next_link (addresses, link);
433 /* Here we change our credentials if required,
434 * as soon as we've set up our sockets
436 user = bus_config_parser_get_user (parser);
439 DBusCredentials creds;
442 _dbus_string_init_const (&u, user);
444 if (!_dbus_credentials_from_username (&u, &creds) ||
448 dbus_set_error (error, DBUS_ERROR_FAILED,
449 "Could not get UID and GID for username \"%s\"",
454 if (!_dbus_change_identity (creds.uid, creds.gid, error))
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))
590 if (!_dbus_become_daemon (error))
594 bus_config_parser_unref (parser);
595 _dbus_string_free (&full_address);
596 dbus_free_string_array (auth_mechanisms);
597 server_data_slot_unref ();
603 bus_config_parser_unref (parser);
606 bus_context_unref (context);
608 _dbus_string_free (&full_address);
609 dbus_free_string_array (auth_mechanisms);
611 server_data_slot_unref ();
617 shutdown_server (BusContext *context,
620 if (server == NULL ||
621 !dbus_server_get_is_connected (server))
624 if (!dbus_server_set_watch_functions (server,
628 _dbus_assert_not_reached ("setting watch functions to NULL failed");
630 if (!dbus_server_set_timeout_functions (server,
634 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
636 dbus_server_disconnect (server);
640 bus_context_shutdown (BusContext *context)
644 link = _dbus_list_get_first_link (&context->servers);
647 shutdown_server (context, link->data);
649 link = _dbus_list_get_next_link (&context->servers, link);
654 bus_context_ref (BusContext *context)
656 _dbus_assert (context->refcount > 0);
657 context->refcount += 1;
661 bus_context_unref (BusContext *context)
663 _dbus_assert (context->refcount > 0);
664 context->refcount -= 1;
666 if (context->refcount == 0)
670 _dbus_verbose ("Finalizing bus context %p\n", context);
672 bus_context_shutdown (context);
674 if (context->connections)
676 bus_connections_unref (context->connections);
677 context->connections = NULL;
680 if (context->registry)
682 bus_registry_unref (context->registry);
683 context->registry = NULL;
686 if (context->activation)
688 bus_activation_unref (context->activation);
689 context->activation = NULL;
692 link = _dbus_list_get_first_link (&context->servers);
695 dbus_server_unref (link->data);
697 link = _dbus_list_get_next_link (&context->servers, link);
699 _dbus_list_clear (&context->servers);
701 if (context->rules_by_uid)
703 _dbus_hash_table_unref (context->rules_by_uid);
704 context->rules_by_uid = NULL;
707 if (context->rules_by_gid)
709 _dbus_hash_table_unref (context->rules_by_gid);
710 context->rules_by_gid = NULL;
715 bus_loop_unref (context->loop);
716 context->loop = NULL;
719 dbus_free (context->type);
720 dbus_free (context->address);
723 server_data_slot_unref ();
727 /* type may be NULL */
729 bus_context_get_type (BusContext *context)
731 return context->type;
735 bus_context_get_address (BusContext *context)
737 return context->address;
741 bus_context_get_registry (BusContext *context)
743 return context->registry;
747 bus_context_get_connections (BusContext *context)
749 return context->connections;
753 bus_context_get_activation (BusContext *context)
755 return context->activation;
759 bus_context_get_loop (BusContext *context)
761 return context->loop;
765 list_allows_user (dbus_bool_t def,
768 const unsigned long *group_ids,
776 link = _dbus_list_get_first_link (list);
779 BusPolicyRule *rule = link->data;
780 link = _dbus_list_get_next_link (list, link);
782 if (rule->type == BUS_POLICY_RULE_USER)
784 if (rule->d.user.uid != uid)
787 else if (rule->type == BUS_POLICY_RULE_GROUP)
792 while (i < n_group_ids)
794 if (rule->d.group.gid == group_ids[i])
799 if (i == n_group_ids)
805 allowed = rule->allow;
812 bus_context_allow_user (BusContext *context,
816 unsigned long *group_ids;
819 /* On OOM or error we always reject the user */
820 if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
822 _dbus_verbose ("Did not get any groups for UID %lu\n",
829 allowed = list_allows_user (allowed,
830 &context->default_rules,
832 group_ids, n_group_ids);
834 allowed = list_allows_user (allowed,
835 &context->mandatory_rules,
837 group_ids, n_group_ids);
839 dbus_free (group_ids);
845 add_list_to_policy (DBusList **list,
850 link = _dbus_list_get_first_link (list);
853 BusPolicyRule *rule = link->data;
854 link = _dbus_list_get_next_link (list, link);
858 case BUS_POLICY_RULE_USER:
859 case BUS_POLICY_RULE_GROUP:
860 /* These aren't per-connection policies */
863 case BUS_POLICY_RULE_OWN:
864 case BUS_POLICY_RULE_SEND:
865 case BUS_POLICY_RULE_RECEIVE:
866 /* These are per-connection */
867 if (!bus_policy_append_rule (policy, rule))
877 bus_context_create_connection_policy (BusContext *context,
878 DBusConnection *connection)
884 _dbus_assert (dbus_connection_get_is_authenticated (connection));
886 policy = bus_policy_new ();
890 if (!add_list_to_policy (&context->default_rules,
894 /* we avoid the overhead of looking up user's groups
895 * if we don't have any group rules anyway
897 if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
899 const unsigned long *groups;
903 if (!bus_connection_get_groups (connection, &groups, &n_groups))
909 list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
914 if (!add_list_to_policy (list, policy))
922 if (!dbus_connection_get_unix_user (connection, &uid))
925 list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
928 if (!add_list_to_policy (list, policy))
931 if (!add_list_to_policy (&context->mandatory_rules,
935 bus_policy_optimize (policy);
940 bus_policy_unref (policy);
945 bus_context_get_activation_timeout (BusContext *context)
948 return context->activation_timeout;