2003-04-06 Havoc Pennington <hp@pobox.com>
[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 "loop.h"
26 #include "activation.h"
27 #include "connection.h"
28 #include "services.h"
29 #include "utils.h"
30 #include "policy.h"
31 #include "config-parser.h"
32 #include <dbus/dbus-list.h>
33 #include <dbus/dbus-hash.h>
34 #include <dbus/dbus-internals.h>
35
36 struct BusContext
37 {
38   int refcount;
39   char *type;
40   char *address;
41   BusLoop *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 bus_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   bus_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 bus_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   bus_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;
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   context = dbus_new0 (BusContext, 1);
338   if (context == NULL)
339     {
340       BUS_SET_OOM (error);
341       goto failed;
342     }
343   
344   context->refcount = 1;
345
346   /* we need another ref of the server data slot for the context
347    * to own
348    */
349   if (!server_data_slot_ref ())
350     _dbus_assert_not_reached ("second ref of server data slot failed");
351   
352 #ifdef DBUS_BUILD_TESTS
353   context->activation_timeout = 6000;  /* 6 seconds */
354 #else
355   context->activation_timeout = 15000; /* 15 seconds */
356 #endif
357
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.
362    */     
363   context->auth_timeout = 3000; /* 3 seconds */
364
365   context->max_incomplete_connections = 32;
366   context->max_connections_per_user = 128;
367
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.
371    */
372   context->max_completed_connections = 1024;
373   
374   context->loop = bus_loop_new ();
375   if (context->loop == NULL)
376     {
377       BUS_SET_OOM (error);
378       goto failed;
379     }
380   
381   /* Build an array of auth mechanisms */
382   
383   auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
384   len = _dbus_list_get_length (auth_mechanisms_list);
385
386   if (len > 0)
387     {
388       int i;
389
390       auth_mechanisms = dbus_new0 (char*, len + 1);
391       if (auth_mechanisms == NULL)
392         goto failed;
393       
394       i = 0;
395       link = _dbus_list_get_first_link (auth_mechanisms_list);
396       while (link != NULL)
397         {
398           auth_mechanisms[i] = _dbus_strdup (link->data);
399           if (auth_mechanisms[i] == NULL)
400             goto failed;
401           link = _dbus_list_get_next_link (auth_mechanisms_list, link);
402         }
403     }
404   else
405     {
406       auth_mechanisms = NULL;
407     }
408
409   /* Listen on our addresses */
410   
411   addresses = bus_config_parser_get_addresses (parser);  
412   
413   link = _dbus_list_get_first_link (addresses);
414   while (link != NULL)
415     {
416       DBusServer *server;
417       
418       server = dbus_server_listen (link->data, error);
419       if (server == NULL)
420         goto failed;
421       else if (!setup_server (context, server, auth_mechanisms, error))
422         goto failed;
423
424       if (!_dbus_list_append (&context->servers, server))
425         {
426           BUS_SET_OOM (error);
427           goto failed;
428         }          
429       
430       link = _dbus_list_get_next_link (addresses, link);
431     }
432
433   /* Here we change our credentials if required,
434    * as soon as we've set up our sockets
435    */
436   user = bus_config_parser_get_user (parser);
437   if (user != NULL)
438     {
439       DBusCredentials creds;
440       DBusString u;
441
442       _dbus_string_init_const (&u, user);
443
444       if (!_dbus_credentials_from_username (&u, &creds) ||
445           creds.uid < 0 ||
446           creds.gid < 0)
447         {
448           dbus_set_error (error, DBUS_ERROR_FAILED,
449                           "Could not get UID and GID for username \"%s\"",
450                           user);
451           goto failed;
452         }
453       
454       if (!_dbus_change_identity (creds.uid, creds.gid, error))
455         goto failed;
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       if (!_dbus_become_daemon (error))
591         goto failed;
592     }
593   
594   bus_config_parser_unref (parser);
595   _dbus_string_free (&full_address);
596   dbus_free_string_array (auth_mechanisms);
597   server_data_slot_unref ();
598   
599   return context;
600   
601  failed:  
602   if (parser != NULL)
603     bus_config_parser_unref (parser);
604
605   if (context != NULL)
606     bus_context_unref (context);
607
608   _dbus_string_free (&full_address);
609   dbus_free_string_array (auth_mechanisms);
610
611   server_data_slot_unref ();
612   
613   return NULL;
614 }
615
616 static void
617 shutdown_server (BusContext *context,
618                  DBusServer *server)
619 {
620   if (server == NULL ||
621       !dbus_server_get_is_connected (server))
622     return;
623   
624   if (!dbus_server_set_watch_functions (server,
625                                         NULL, NULL, NULL,
626                                         context,
627                                         NULL))
628     _dbus_assert_not_reached ("setting watch functions to NULL failed");
629   
630   if (!dbus_server_set_timeout_functions (server,
631                                           NULL, NULL, NULL,
632                                           context,
633                                           NULL))
634     _dbus_assert_not_reached ("setting timeout functions to NULL failed");
635   
636   dbus_server_disconnect (server);
637 }
638
639 void
640 bus_context_shutdown (BusContext  *context)
641 {
642   DBusList *link;
643
644   link = _dbus_list_get_first_link (&context->servers);
645   while (link != NULL)
646     {
647       shutdown_server (context, link->data);
648
649       link = _dbus_list_get_next_link (&context->servers, link);
650     }
651 }
652
653 void
654 bus_context_ref (BusContext *context)
655 {
656   _dbus_assert (context->refcount > 0);
657   context->refcount += 1;
658 }
659
660 void
661 bus_context_unref (BusContext *context)
662 {
663   _dbus_assert (context->refcount > 0);
664   context->refcount -= 1;
665
666   if (context->refcount == 0)
667     {
668       DBusList *link;
669       
670       _dbus_verbose ("Finalizing bus context %p\n", context);
671       
672       bus_context_shutdown (context);
673
674       if (context->connections)
675         {
676           bus_connections_unref (context->connections);
677           context->connections = NULL;
678         }
679       
680       if (context->registry)
681         {
682           bus_registry_unref (context->registry);
683           context->registry = NULL;
684         }
685       
686       if (context->activation)
687         {
688           bus_activation_unref (context->activation);
689           context->activation = NULL;
690         }
691
692       link = _dbus_list_get_first_link (&context->servers);
693       while (link != NULL)
694         {
695           dbus_server_unref (link->data);
696           
697           link = _dbus_list_get_next_link (&context->servers, link);
698         }
699       _dbus_list_clear (&context->servers);
700
701       if (context->rules_by_uid)
702         {
703           _dbus_hash_table_unref (context->rules_by_uid);
704           context->rules_by_uid = NULL;
705         }
706
707       if (context->rules_by_gid)
708         {
709           _dbus_hash_table_unref (context->rules_by_gid);
710           context->rules_by_gid = NULL;
711         }
712
713       if (context->loop)
714         {
715           bus_loop_unref (context->loop);
716           context->loop = NULL;
717         }
718       
719       dbus_free (context->type);
720       dbus_free (context->address);
721       dbus_free (context);
722
723       server_data_slot_unref ();
724     }
725 }
726
727 /* type may be NULL */
728 const char*
729 bus_context_get_type (BusContext *context)
730 {
731   return context->type;
732 }
733
734 const char*
735 bus_context_get_address (BusContext *context)
736 {
737   return context->address;
738 }
739
740 BusRegistry*
741 bus_context_get_registry (BusContext  *context)
742 {
743   return context->registry;
744 }
745
746 BusConnections*
747 bus_context_get_connections (BusContext  *context)
748 {
749   return context->connections;
750 }
751
752 BusActivation*
753 bus_context_get_activation (BusContext  *context)
754 {
755   return context->activation;
756 }
757
758 BusLoop*
759 bus_context_get_loop (BusContext *context)
760 {
761   return context->loop;
762 }
763
764 static dbus_bool_t
765 list_allows_user (dbus_bool_t           def,
766                   DBusList            **list,
767                   unsigned long         uid,
768                   const unsigned long  *group_ids,
769                   int                   n_group_ids)
770 {
771   DBusList *link;
772   dbus_bool_t allowed;
773   
774   allowed = def;
775
776   link = _dbus_list_get_first_link (list);
777   while (link != NULL)
778     {
779       BusPolicyRule *rule = link->data;
780       link = _dbus_list_get_next_link (list, link);
781       
782       if (rule->type == BUS_POLICY_RULE_USER)
783         {
784           if (rule->d.user.uid != uid)
785             continue;
786         }
787       else if (rule->type == BUS_POLICY_RULE_GROUP)
788         {
789           int i;
790
791           i = 0;
792           while (i < n_group_ids)
793             {
794               if (rule->d.group.gid == group_ids[i])
795                 break;
796               ++i;
797             }
798
799           if (i == n_group_ids)
800             continue;
801         }
802       else
803         continue;
804
805       allowed = rule->allow;
806     }
807   
808   return allowed;
809 }
810
811 dbus_bool_t
812 bus_context_allow_user (BusContext   *context,
813                         unsigned long uid)
814 {
815   dbus_bool_t allowed;
816   unsigned long *group_ids;
817   int n_group_ids;
818
819   /* On OOM or error we always reject the user */
820   if (!_dbus_get_groups (uid, &group_ids, &n_group_ids))
821     {
822       _dbus_verbose ("Did not get any groups for UID %lu\n",
823                      uid);
824       return FALSE;
825     }
826   
827   allowed = FALSE;
828
829   allowed = list_allows_user (allowed,
830                               &context->default_rules,
831                               uid,
832                               group_ids, n_group_ids);
833
834   allowed = list_allows_user (allowed,
835                               &context->mandatory_rules,
836                               uid,
837                               group_ids, n_group_ids);
838
839   dbus_free (group_ids);
840
841   return allowed;
842 }
843
844 static dbus_bool_t
845 add_list_to_policy (DBusList       **list,
846                     BusPolicy       *policy)
847 {
848   DBusList *link;
849
850   link = _dbus_list_get_first_link (list);
851   while (link != NULL)
852     {
853       BusPolicyRule *rule = link->data;
854       link = _dbus_list_get_next_link (list, link);
855
856       switch (rule->type)
857         {
858         case BUS_POLICY_RULE_USER:
859         case BUS_POLICY_RULE_GROUP:
860           /* These aren't per-connection policies */
861           break;
862
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))
868             return FALSE;
869           break;
870         }
871     }
872   
873   return TRUE;
874 }
875
876 BusPolicy*
877 bus_context_create_connection_policy (BusContext      *context,
878                                       DBusConnection  *connection)
879 {
880   BusPolicy *policy;
881   unsigned long uid;
882   DBusList **list;
883
884   _dbus_assert (dbus_connection_get_is_authenticated (connection));
885   
886   policy = bus_policy_new ();
887   if (policy == NULL)
888     return NULL;
889
890   if (!add_list_to_policy (&context->default_rules,
891                                       policy))
892     goto failed;
893
894   /* we avoid the overhead of looking up user's groups
895    * if we don't have any group rules anyway
896    */
897   if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0)
898     {
899       const unsigned long *groups;
900       int n_groups;
901       int i;
902       
903       if (!bus_connection_get_groups (connection, &groups, &n_groups))
904         goto failed;
905       
906       i = 0;
907       while (i < n_groups)
908         {
909           list = _dbus_hash_table_lookup_ulong (context->rules_by_gid,
910                                                 groups[i]);
911           
912           if (list != NULL)
913             {
914               if (!add_list_to_policy (list, policy))
915                 goto failed;
916             }
917           
918           ++i;
919         }
920     }
921
922   if (!dbus_connection_get_unix_user (connection, &uid))
923     goto failed;
924
925   list = _dbus_hash_table_lookup_ulong (context->rules_by_uid,
926                                         uid);
927
928   if (!add_list_to_policy (list, policy))
929     goto failed;
930   
931   if (!add_list_to_policy (&context->mandatory_rules,
932                            policy))
933     goto failed;
934
935   bus_policy_optimize (policy);
936   
937   return policy;
938   
939  failed:
940   bus_policy_unref (policy);
941   return NULL;
942 }
943
944 int
945 bus_context_get_activation_timeout (BusContext *context)
946 {
947   
948   return context->activation_timeout;
949 }