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