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