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