bus.c revision df008ef97deacd5bb00ac335e5d8671798fa09dd
1/* -*- mode: C; c-file-style: "gnu" -*- */
2/* bus.c  message bus context object
3 *
4 * Copyright (C) 2003 Red Hat, Inc.
5 *
6 * Licensed under the Academic Free License version 1.2
7 *
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.
12 *
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.
17 *
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
21 *
22 */
23
24#include "bus.h"
25#include "activation.h"
26#include "connection.h"
27#include "services.h"
28#include "utils.h"
29#include "policy.h"
30#include "config-parser.h"
31#include <dbus/dbus-list.h>
32#include <dbus/dbus-hash.h>
33#include <dbus/dbus-internals.h>
34
35struct BusContext
36{
37  int refcount;
38  char *type;
39  char *address;
40  DBusLoop *loop;
41  DBusList *servers;
42  BusConnections *connections;
43  BusActivation *activation;
44  BusRegistry *registry;
45  DBusList *default_rules;       /**< Default policy rules */
46  DBusList *mandatory_rules;     /**< Mandatory policy rules */
47  DBusHashTable *rules_by_uid;   /**< per-UID policy rules */
48  DBusHashTable *rules_by_gid;   /**< per-GID policy rules */
49  int activation_timeout;        /**< How long to wait for an activation to time out */
50  int auth_timeout;              /**< How long to wait for an authentication to time out */
51  int max_completed_connections;    /**< Max number of authorized connections */
52  int max_incomplete_connections;   /**< Max number of incomplete connections */
53  int max_connections_per_user;     /**< Max number of connections auth'd as same user */
54};
55
56static int server_data_slot = -1;
57static int server_data_slot_refcount = 0;
58
59typedef struct
60{
61  BusContext *context;
62} BusServerData;
63
64#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
65
66static dbus_bool_t
67server_data_slot_ref (void)
68{
69  if (server_data_slot < 0)
70    {
71      server_data_slot = dbus_server_allocate_data_slot ();
72
73      if (server_data_slot < 0)
74        return FALSE;
75
76      _dbus_assert (server_data_slot_refcount == 0);
77    }
78
79  server_data_slot_refcount += 1;
80
81  return TRUE;
82}
83
84static void
85server_data_slot_unref (void)
86{
87  _dbus_assert (server_data_slot_refcount > 0);
88
89  server_data_slot_refcount -= 1;
90
91  if (server_data_slot_refcount == 0)
92    {
93      dbus_server_free_data_slot (server_data_slot);
94      server_data_slot = -1;
95    }
96}
97
98static BusContext*
99server_get_context (DBusServer *server)
100{
101  BusContext *context;
102  BusServerData *bd;
103
104  if (!server_data_slot_ref ())
105    return NULL;
106
107  bd = BUS_SERVER_DATA (server);
108  if (bd == NULL)
109    {
110      server_data_slot_unref ();
111      return NULL;
112    }
113
114  context = bd->context;
115
116  server_data_slot_unref ();
117
118  return context;
119}
120
121static dbus_bool_t
122server_watch_callback (DBusWatch     *watch,
123                       unsigned int   condition,
124                       void          *data)
125{
126  DBusServer *server = data;
127
128  return dbus_server_handle_watch (server, watch, condition);
129}
130
131static dbus_bool_t
132add_server_watch (DBusWatch  *watch,
133                  void       *data)
134{
135  DBusServer *server = data;
136  BusContext *context;
137
138  context = server_get_context (server);
139
140  return _dbus_loop_add_watch (context->loop,
141                               watch, server_watch_callback, server,
142                               NULL);
143}
144
145static void
146remove_server_watch (DBusWatch  *watch,
147                     void       *data)
148{
149  DBusServer *server = data;
150  BusContext *context;
151
152  context = server_get_context (server);
153
154  _dbus_loop_remove_watch (context->loop,
155                           watch, server_watch_callback, server);
156}
157
158
159static void
160server_timeout_callback (DBusTimeout   *timeout,
161                         void          *data)
162{
163  /* can return FALSE on OOM but we just let it fire again later */
164  dbus_timeout_handle (timeout);
165}
166
167static dbus_bool_t
168add_server_timeout (DBusTimeout *timeout,
169                    void        *data)
170{
171  DBusServer *server = data;
172  BusContext *context;
173
174  context = server_get_context (server);
175
176  return _dbus_loop_add_timeout (context->loop,
177                                 timeout, server_timeout_callback, server, NULL);
178}
179
180static void
181remove_server_timeout (DBusTimeout *timeout,
182                       void        *data)
183{
184  DBusServer *server = data;
185  BusContext *context;
186
187  context = server_get_context (server);
188
189  _dbus_loop_remove_timeout (context->loop,
190                             timeout, server_timeout_callback, server);
191}
192
193static void
194new_connection_callback (DBusServer     *server,
195                         DBusConnection *new_connection,
196                         void           *data)
197{
198  BusContext *context = data;
199
200  if (!bus_connections_setup_connection (context->connections, new_connection))
201    {
202      _dbus_verbose ("No memory to setup new connection\n");
203
204      /* if we don't do this, it will get unref'd without
205       * being disconnected... kind of strange really
206       * that we have to do this, people won't get it right
207       * in general.
208       */
209      dbus_connection_disconnect (new_connection);
210    }
211
212  /* on OOM, we won't have ref'd the connection so it will die. */
213}
214
215static void
216free_rule_func (void *data,
217                void *user_data)
218{
219  BusPolicyRule *rule = data;
220
221  bus_policy_rule_unref (rule);
222}
223
224static void
225free_rule_list_func (void *data)
226{
227  DBusList **list = data;
228
229  _dbus_list_foreach (list, free_rule_func, NULL);
230
231  _dbus_list_clear (list);
232
233  dbus_free (list);
234}
235
236static void
237free_server_data (void *data)
238{
239  BusServerData *bd = data;
240
241  dbus_free (bd);
242}
243
244static dbus_bool_t
245setup_server (BusContext *context,
246              DBusServer *server,
247              char      **auth_mechanisms,
248              DBusError  *error)
249{
250  BusServerData *bd;
251
252  bd = dbus_new0 (BusServerData, 1);
253  if (!dbus_server_set_data (server,
254                             server_data_slot,
255                             bd, free_server_data))
256    {
257      dbus_free (bd);
258      BUS_SET_OOM (error);
259      return FALSE;
260    }
261
262  bd->context = context;
263
264  if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
265    {
266      BUS_SET_OOM (error);
267      return FALSE;
268    }
269
270  dbus_server_set_new_connection_function (server,
271                                           new_connection_callback,
272                                           context, NULL);
273
274  if (!dbus_server_set_watch_functions (server,
275                                        add_server_watch,
276                                        remove_server_watch,
277                                        NULL,
278                                        server,
279                                        NULL))
280    {
281      BUS_SET_OOM (error);
282      return FALSE;
283    }
284
285  if (!dbus_server_set_timeout_functions (server,
286                                          add_server_timeout,
287                                          remove_server_timeout,
288                                          NULL,
289                                          server, NULL))
290    {
291      BUS_SET_OOM (error);
292      return FALSE;
293    }
294
295  return TRUE;
296}
297
298BusContext*
299bus_context_new (const DBusString *config_file,
300                 int               print_addr_fd,
301                 DBusError        *error)
302{
303  BusContext *context;
304  DBusList *link;
305  DBusList **addresses;
306  BusConfigParser *parser;
307  DBusString full_address;
308  const char *user, *pidfile;
309  char **auth_mechanisms;
310  DBusList **auth_mechanisms_list;
311  int len;
312
313  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
314
315  if (!_dbus_string_init (&full_address))
316    {
317      BUS_SET_OOM (error);
318      return NULL;
319    }
320
321  if (!server_data_slot_ref ())
322    {
323      BUS_SET_OOM (error);
324      _dbus_string_free (&full_address);
325      return NULL;
326    }
327
328  parser = NULL;
329  context = NULL;
330  auth_mechanisms = NULL;
331
332  parser = bus_config_load (config_file, error);
333  if (parser == NULL)
334    goto failed;
335
336  /* Check for an existing pid file. Of course this is a race;
337   * we'd have to use fcntl() locks on the pid file to
338   * avoid that. But we want to check for the pid file
339   * before overwriting any existing sockets, etc.
340   */
341  pidfile = bus_config_parser_get_pidfile (parser);
342  if (pidfile != NULL)
343    {
344      DBusString u;
345      DBusStat stbuf;
346      DBusError tmp_error;
347
348      dbus_error_init (&tmp_error);
349      _dbus_string_init_const (&u, pidfile);
350
351      if (_dbus_stat (&u, &stbuf, &tmp_error))
352	{
353	  dbus_set_error (error, DBUS_ERROR_FAILED,
354			  "The pid file \"%s\" exists, if the message bus is not running, remove this file",
355			  pidfile);
356	  dbus_error_free (&tmp_error);
357	  goto failed;
358	}
359    }
360
361  context = dbus_new0 (BusContext, 1);
362  if (context == NULL)
363    {
364      BUS_SET_OOM (error);
365      goto failed;
366    }
367
368  context->refcount = 1;
369
370  /* we need another ref of the server data slot for the context
371   * to own
372   */
373  if (!server_data_slot_ref ())
374    _dbus_assert_not_reached ("second ref of server data slot failed");
375
376#ifdef DBUS_BUILD_TESTS
377  context->activation_timeout = 6000;  /* 6 seconds */
378#else
379  context->activation_timeout = 15000; /* 15 seconds */
380#endif
381
382  /* Making this long risks making a DOS attack easier, but too short
383   * and legitimate auth will fail.  If interactive auth (ask user for
384   * password) is allowed, then potentially it has to be quite long.
385   * Ultimately it needs to come from the configuration file.
386   */
387  context->auth_timeout = 3000; /* 3 seconds */
388
389  context->max_incomplete_connections = 32;
390  context->max_connections_per_user = 128;
391
392  /* Note that max_completed_connections / max_connections_per_user
393   * is the number of users that would have to work together to
394   * DOS all the other users.
395   */
396  context->max_completed_connections = 1024;
397
398  context->loop = _dbus_loop_new ();
399  if (context->loop == NULL)
400    {
401      BUS_SET_OOM (error);
402      goto failed;
403    }
404
405  /* Build an array of auth mechanisms */
406
407  auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
408  len = _dbus_list_get_length (auth_mechanisms_list);
409
410  if (len > 0)
411    {
412      int i;
413
414      auth_mechanisms = dbus_new0 (char*, len + 1);
415      if (auth_mechanisms == NULL)
416        goto failed;
417
418      i = 0;
419      link = _dbus_list_get_first_link (auth_mechanisms_list);
420      while (link != NULL)
421        {
422          auth_mechanisms[i] = _dbus_strdup (link->data);
423          if (auth_mechanisms[i] == NULL)
424            goto failed;
425          link = _dbus_list_get_next_link (auth_mechanisms_list, link);
426        }
427    }
428  else
429    {
430      auth_mechanisms = NULL;
431    }
432
433  /* Listen on our addresses */
434
435  addresses = bus_config_parser_get_addresses (parser);
436
437  link = _dbus_list_get_first_link (addresses);
438  while (link != NULL)
439    {
440      DBusServer *server;
441
442      server = dbus_server_listen (link->data, error);
443      if (server == NULL)
444        goto failed;
445      else if (!setup_server (context, server, auth_mechanisms, error))
446        goto failed;
447
448      if (!_dbus_list_append (&context->servers, server))
449        {
450          BUS_SET_OOM (error);
451          goto failed;
452        }
453
454      link = _dbus_list_get_next_link (addresses, link);
455    }
456
457  /* Here we change our credentials if required,
458   * as soon as we've set up our sockets
459   */
460  user = bus_config_parser_get_user (parser);
461  if (user != NULL)
462    {
463      DBusCredentials creds;
464      DBusString u;
465
466      _dbus_string_init_const (&u, user);
467
468      if (!_dbus_credentials_from_username (&u, &creds) ||
469          creds.uid < 0 ||
470          creds.gid < 0)
471        {
472          dbus_set_error (error, DBUS_ERROR_FAILED,
473                          "Could not get UID and GID for username \"%s\"",
474                          user);
475          goto failed;
476        }
477
478      if (!_dbus_change_identity (creds.uid, creds.gid, error))
479        goto failed;
480    }
481
482  /* note that type may be NULL */
483  context->type = _dbus_strdup (bus_config_parser_get_type (parser));
484
485  /* We have to build the address backward, so that
486   * <listen> later in the config file have priority
487   */
488  link = _dbus_list_get_last_link (&context->servers);
489  while (link != NULL)
490    {
491      char *addr;
492
493      addr = dbus_server_get_address (link->data);
494      if (addr == NULL)
495        {
496          BUS_SET_OOM (error);
497          goto failed;
498        }
499
500      if (_dbus_string_get_length (&full_address) > 0)
501        {
502          if (!_dbus_string_append (&full_address, ";"))
503            {
504              BUS_SET_OOM (error);
505              goto failed;
506            }
507        }
508
509      if (!_dbus_string_append (&full_address, addr))
510        {
511          BUS_SET_OOM (error);
512          goto failed;
513        }
514
515      dbus_free (addr);
516
517      link = _dbus_list_get_prev_link (&context->servers, link);
518    }
519
520  if (!_dbus_string_copy_data (&full_address, &context->address))
521    {
522      BUS_SET_OOM (error);
523      goto failed;
524    }
525
526  /* Note that we don't know whether the print_addr_fd is
527   * one of the sockets we're using to listen on, or some
528   * other random thing. But I think the answer is "don't do
529   * that then"
530   */
531  if (print_addr_fd >= 0)
532    {
533      DBusString addr;
534      const char *a = bus_context_get_address (context);
535      int bytes;
536
537      _dbus_assert (a != NULL);
538      if (!_dbus_string_init (&addr))
539        {
540          BUS_SET_OOM (error);
541          goto failed;
542        }
543
544      if (!_dbus_string_append (&addr, a) ||
545          !_dbus_string_append (&addr, "\n"))
546        {
547          _dbus_string_free (&addr);
548          BUS_SET_OOM (error);
549          goto failed;
550        }
551
552      bytes = _dbus_string_get_length (&addr);
553      if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
554        {
555          dbus_set_error (error, DBUS_ERROR_FAILED,
556                          "Printing message bus address: %s\n",
557                          _dbus_strerror (errno));
558          _dbus_string_free (&addr);
559          goto failed;
560        }
561
562      if (print_addr_fd > 2)
563        _dbus_close (print_addr_fd, NULL);
564
565      _dbus_string_free (&addr);
566    }
567
568  /* Create activation subsystem */
569
570  context->activation = bus_activation_new (context, &full_address,
571                                            bus_config_parser_get_service_dirs (parser),
572                                            error);
573  if (context->activation == NULL)
574    {
575      _DBUS_ASSERT_ERROR_IS_SET (error);
576      goto failed;
577    }
578
579  context->connections = bus_connections_new (context);
580  if (context->connections == NULL)
581    {
582      BUS_SET_OOM (error);
583      goto failed;
584    }
585
586  context->registry = bus_registry_new (context);
587  if (context->registry == NULL)
588    {
589      BUS_SET_OOM (error);
590      goto failed;
591    }
592
593  context->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
594                                                NULL,
595                                                free_rule_list_func);
596  if (context->rules_by_uid == NULL)
597    {
598      BUS_SET_OOM (error);
599      goto failed;
600    }
601
602  context->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
603                                                NULL,
604                                                free_rule_list_func);
605  if (context->rules_by_gid == NULL)
606    {
607      BUS_SET_OOM (error);
608      goto failed;
609    }
610
611  /* Now become a daemon if appropriate */
612  if (bus_config_parser_get_fork (parser))
613    {
614      DBusString u;
615
616      if (pidfile)
617        _dbus_string_init_const (&u, pidfile);
618
619      if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
620        goto failed;
621    }
622  else
623    {
624      /* Need to write PID file for ourselves, not for the child process */
625      if (pidfile != NULL)
626        {
627          DBusString u;
628
629          _dbus_string_init_const (&u, pidfile);
630
631          if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
632            goto failed;
633        }
634    }
635
636  bus_config_parser_unref (parser);
637  _dbus_string_free (&full_address);
638  dbus_free_string_array (auth_mechanisms);
639  server_data_slot_unref ();
640
641  return context;
642
643 failed:
644  if (parser != NULL)
645    bus_config_parser_unref (parser);
646
647  if (context != NULL)
648    bus_context_unref (context);
649
650  _dbus_string_free (&full_address);
651  dbus_free_string_array (auth_mechanisms);
652
653  server_data_slot_unref ();
654
655  return NULL;
656}
657
658static void
659shutdown_server (BusContext *context,
660                 DBusServer *server)
661{
662  if (server == NULL ||
663      !dbus_server_get_is_connected (server))
664    return;
665
666  if (!dbus_server_set_watch_functions (server,
667                                        NULL, NULL, NULL,
668                                        context,
669                                        NULL))
670    _dbus_assert_not_reached ("setting watch functions to NULL failed");
671
672  if (!dbus_server_set_timeout_functions (server,
673                                          NULL, NULL, NULL,
674                                          context,
675                                          NULL))
676    _dbus_assert_not_reached ("setting timeout functions to NULL failed");
677
678  dbus_server_disconnect (server);
679}
680
681void
682bus_context_shutdown (BusContext  *context)
683{
684  DBusList *link;
685
686  link = _dbus_list_get_first_link (&context->servers);
687  while (link != NULL)
688    {
689      shutdown_server (context, link->data);
690
691      link = _dbus_list_get_next_link (&context->servers, link);
692    }
693}
694
695void
696bus_context_ref (BusContext *context)
697{
698  _dbus_assert (context->refcount > 0);
699  context->refcount += 1;
700}
701
702void
703bus_context_unref (BusContext *context)
704{
705  _dbus_assert (context->refcount > 0);
706  context->refcount -= 1;
707
708  if (context->refcount == 0)
709    {
710      DBusList *link;
711
712      _dbus_verbose ("Finalizing bus context %p\n", context);
713
714      bus_context_shutdown (context);
715
716      if (context->connections)
717        {
718          bus_connections_unref (context->connections);
719          context->connections = NULL;
720        }
721
722      if (context->registry)
723        {
724          bus_registry_unref (context->registry);
725          context->registry = NULL;
726        }
727
728      if (context->activation)
729        {
730          bus_activation_unref (context->activation);
731          context->activation = NULL;
732        }
733
734      link = _dbus_list_get_first_link (&context->servers);
735      while (link != NULL)
736        {
737          dbus_server_unref (link->data);
738
739          link = _dbus_list_get_next_link (&context->servers, link);
740        }
741      _dbus_list_clear (&context->servers);
742
743      if (context->rules_by_uid)
744        {
745          _dbus_hash_table_unref (context->rules_by_uid);
746          context->rules_by_uid = NULL;
747        }
748
749      if (context->rules_by_gid)
750        {
751          _dbus_hash_table_unref (context->rules_by_gid);
752          context->rules_by_gid = NULL;
753        }
754
755      if (context->loop)
756        {
757          _dbus_loop_unref (context->loop);
758          context->loop = NULL;
759        }
760
761      dbus_free (context->type);
762      dbus_free (context->address);
763      dbus_free (context);
764
765      server_data_slot_unref ();
766    }
767}
768
769/* type may be NULL */
770const char*
771bus_context_get_type (BusContext *context)
772{
773  return context->type;
774}
775
776const char*
777bus_context_get_address (BusContext *context)
778{
779  return context->address;
780}
781
782BusRegistry*
783bus_context_get_registry (BusContext  *context)
784{
785  return context->registry;
786}
787
788BusConnections*
789bus_context_get_connections (BusContext  *context)
790{
791  return context->connections;
792}
793
794BusActivation*
795bus_context_get_activation (BusContext  *context)
796{
797  return context->activation;
798}
799
800DBusLoop*
801bus_context_get_loop (BusContext *context)
802{
803  return context->loop;
804}
805
806static dbus_bool_t
807list_allows_user (dbus_bool_t           def,
808                  DBusList            **list,
809                  unsigned long         uid,
810                  const unsigned long  *group_ids,
811                  int                   n_group_ids)
812{
813  DBusList *link;
814  dbus_bool_t allowed;
815
816  allowed = def;
817
818  link = _dbus_list_get_first_link (list);
819  while (link != NULL)
820    {
821      BusPolicyRule *rule = link->data;
822      link = _dbus_list_get_next_link (list, link);
823
824      if (rule->type == BUS_POLICY_RULE_USER)
825        {
826          if (rule->d.user.uid != uid)
827            continue;
828        }
829      else if (rule->type == BUS_POLICY_RULE_GROUP)
830        {
831          int i;
832
833          i = 0;
834          while (i < n_group_ids)
835            {
836              if (rule->d.group.gid == group_ids[i])
837                break;
838              ++i;
839            }
840
841          if (i == n_group_ids)
842            continue;
843        }
844      else
845        continue;
846
847      allowed = rule->allow;
848    }
849
850  return allowed;
851}
852
853dbus_bool_t
854bus_context_allow_user (BusContext   *context,
855                        unsigned long uid)
856{
857  dbus_bool_t allowed;
858  unsigned long *group_ids;
859  int n_group_ids;
860
861  /* On OOM or error we always reject the user */
862  if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
863    {
864      _dbus_verbose ("Did not get any groups for UID %lu\n",
865                     uid);
866      return FALSE;
867    }
868
869  allowed = FALSE;
870
871  allowed = list_allows_user (allowed,
872                              &context->default_rules,
873                              uid,
874                              group_ids, n_group_ids);
875
876  allowed = list_allows_user (allowed,
877                              &context->mandatory_rules,
878                              uid,
879                              group_ids, n_group_ids);
880
881  dbus_free (group_ids);
882
883  return allowed;
884}
885
886static dbus_bool_t
887add_list_to_policy (DBusList       **list,
888                    BusPolicy       *policy)
889{
890  DBusList *link;
891
892  link = _dbus_list_get_first_link (list);
893  while (link != NULL)
894    {
895      BusPolicyRule *rule = link->data;
896      link = _dbus_list_get_next_link (list, link);
897
898      switch (rule->type)
899        {
900        case BUS_POLICY_RULE_USER:
901        case BUS_POLICY_RULE_GROUP:
902          /* These aren't per-connection policies */
903          break;
904
905        case BUS_POLICY_RULE_OWN:
906        case BUS_POLICY_RULE_SEND:
907        case BUS_POLICY_RULE_RECEIVE:
908          /* These are per-connection */
909          if (!bus_policy_append_rule (policy, rule))
910            return FALSE;
911          break;
912        }
913    }
914
915  return TRUE;
916}
917
918BusPolicy*
919bus_context_create_connection_policy (BusContext      *context,
920                                      DBusConnection  *connection)
921{
922  BusPolicy *policy;
923  unsigned long uid;
924  DBusList **list;
925
926  _dbus_assert (dbus_connection_get_is_authenticated (connection));
927
928  policy = bus_policy_new ();
929  if (policy == NULL)
930    return NULL;
931
932  if (!add_list_to_policy (&context->default_rules,
933                                      policy))
934    goto failed;
935
936  /* we avoid the overhead of looking up user's groups
937   * if we don't have any group rules anyway
938   */
939  if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
940    {
941      const unsigned long *groups;
942      int n_groups;
943      int i;
944
945      if (!bus_connection_get_groups (connection, &groups, &n_groups))
946        goto failed;
947
948      i = 0;
949      while (i < n_groups)
950        {
951          list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
952                                                groups[i]);
953
954          if (list != NULL)
955            {
956              if (!add_list_to_policy (list, policy))
957                goto failed;
958            }
959
960          ++i;
961        }
962    }
963
964  if (!dbus_connection_get_unix_user (connection, &uid))
965    goto failed;
966
967  list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
968                                        uid);
969
970  if (!add_list_to_policy (list, policy))
971    goto failed;
972
973  if (!add_list_to_policy (&context->mandatory_rules,
974                           policy))
975    goto failed;
976
977  bus_policy_optimize (policy);
978
979  return policy;
980
981 failed:
982  bus_policy_unref (policy);
983  return NULL;
984}
985
986int
987bus_context_get_activation_timeout (BusContext *context)
988{
989
990  return context->activation_timeout;
991}
992