bus: Assign a serial number for messages from the driver
[platform/upstream/dbus.git] / bus / main.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* main.c  main() for message bus
3  *
4  * Copyright (C) 2003 Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <config.h>
25 #include "bus.h"
26 #include "driver.h"
27 #include <dbus/dbus-internals.h>
28 #include <dbus/dbus-watch.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #ifdef HAVE_SIGNAL_H
33 #include <signal.h>
34 #endif
35 #ifdef HAVE_ERRNO_H
36 #include <errno.h>
37 #endif
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>     /* for write() and STDERR_FILENO */
40 #endif
41 #include "selinux.h"
42 #include "apparmor.h"
43 #include "audit.h"
44
45 #ifdef DBUS_UNIX
46 #include <dbus/dbus-sysdeps-unix.h>
47 #endif
48
49 static BusContext *context;
50
51 #ifdef DBUS_UNIX
52
53 /* Despite its name and its unidirectional nature, this is actually
54  * a socket pair. */
55 static DBusSocket reload_pipe[2];
56 #define RELOAD_READ_END 0
57 #define RELOAD_WRITE_END 1
58
59 static void close_reload_pipe (DBusWatch **);
60
61 typedef enum
62  {
63    ACTION_RELOAD = 'r',
64    ACTION_QUIT = 'q'
65  } SignalAction;
66
67 static void
68 signal_handler (int sig)
69 {
70   /* Signal handlers that might set errno must save and restore the errno
71    * that the interrupted function might have been relying on. */
72   int saved_errno = errno;
73
74   switch (sig)
75     {
76     case SIGHUP:
77       {
78         DBusString str;
79         char action[2] = { ACTION_RELOAD, '\0' };
80
81         _dbus_string_init_const (&str, action);
82         if ((reload_pipe[RELOAD_WRITE_END].fd > 0) &&
83             !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
84           {
85             /* If we receive SIGHUP often enough to fill the pipe buffer (4096
86              * times on old Linux, 65536 on modern Linux) before it can be
87              * drained, let's just warn and ignore. The configuration will be
88              * reloaded while draining the pipe buffer, which is what we
89              * wanted. It's harmless that it will be reloaded fewer times than
90              * we asked for, since the reload is delayed anyway, so new changes
91              * will be picked up.
92              *
93              * We use write() because _dbus_warn uses vfprintf, which isn't
94              * async-signal-safe.
95              *
96              * This is necessarily Unix-specific, but so are POSIX signals,
97              * so... */
98             static const char message[] =
99               "Unable to write to reload pipe - buffer full?\n";
100
101             if (write (STDERR_FILENO, message, strlen (message)) !=
102                 (ssize_t) strlen (message))
103               {
104                 /* ignore failure to write out a warning */
105               }
106           }
107       }
108       break;
109
110     case SIGTERM:
111       {
112         DBusString str;
113         char action[2] = { ACTION_QUIT, '\0' };
114         _dbus_string_init_const (&str, action);
115         if ((reload_pipe[RELOAD_WRITE_END].fd < 0) ||
116             !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
117           {
118             /* If we can't write to the socket, dying seems a more
119              * important response to SIGTERM than cleaning up sockets,
120              * so we exit. We'd use exit(), but that's not async-signal-safe,
121              * so we'll have to resort to _exit(). */
122             static const char message[] =
123               "Unable to write termination signal to pipe - buffer full?\n"
124               "Will exit instead.\n";
125
126             if (write (STDERR_FILENO, message, strlen (message)) !=
127                 (ssize_t) strlen (message))
128               {
129                 /* ignore failure to write out a warning */
130               }
131             _exit (1);
132           }
133       }
134       break;
135
136     default:
137       /* can't happen unless this signal handler gets used for a wrong
138        * signal, but keep -Wswitch-default happy */
139       break;
140     }
141
142   errno = saved_errno;
143 }
144 #endif /* DBUS_UNIX */
145
146 static void usage (void) _DBUS_GNUC_NORETURN;
147
148 static void
149 usage (void)
150 {
151   fprintf (stderr,
152       DBUS_DAEMON_NAME
153       " [--version]"
154       " [--session]"
155       " [--system]"
156       " [--config-file=FILE]"
157       " [--print-address[=DESCRIPTOR]]"
158       " [--print-pid[=DESCRIPTOR]]"
159       " [--introspect]"
160       " [--address=ADDRESS]"
161       " [--nopidfile]"
162       " [--nosyslog]"
163       " [--syslog]"
164       " [--syslog-only]"
165       " [--nofork]"
166 #ifdef DBUS_UNIX
167       " [--fork]"
168       " [--systemd-activation]"
169 #endif
170       "\n");
171   exit (1);
172 }
173
174 static void version (void) _DBUS_GNUC_NORETURN;
175
176 static void
177 version (void)
178 {
179   printf ("D-Bus Message Bus Daemon %s\n"
180           "Copyright (C) 2002, 2003 Red Hat, Inc., CodeFactory AB, and others\n"
181           "This is free software; see the source for copying conditions.\n"
182           "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
183           DBUS_VERSION_STRING);
184   exit (0);
185 }
186
187 static void introspect (void) _DBUS_GNUC_NORETURN;
188
189 static void
190 introspect (void)
191 {
192   DBusString xml;
193   const char *v_STRING;
194
195   if (!_dbus_string_init (&xml))
196     goto oom;
197
198   if (!bus_driver_generate_introspect_string (&xml, TRUE, NULL))
199     {
200       _dbus_string_free (&xml);
201       goto oom;
202     }
203
204   v_STRING = _dbus_string_get_const_data (&xml);
205   printf ("%s\n", v_STRING);
206
207   exit (0);
208
209  oom:
210   _dbus_warn ("Can not introspect - Out of memory");
211   exit (1);
212 }
213
214 static void
215 check_two_config_files (const DBusString *config_file,
216                         const char       *extra_arg)
217 {
218   if (_dbus_string_get_length (config_file) > 0)
219     {
220       fprintf (stderr, "--%s specified but configuration file %s already requested\n",
221                extra_arg, _dbus_string_get_const_data (config_file));
222       exit (1);
223     }
224 }
225
226 static void
227 check_two_addresses (const DBusString *address,
228                      const char       *extra_arg)
229 {
230   if (_dbus_string_get_length (address) > 0)
231     {
232       fprintf (stderr, "--%s specified but address %s already requested\n",
233                extra_arg, _dbus_string_get_const_data (address));
234       exit (1);
235     }
236 }
237
238 static void
239 check_two_addr_descriptors (const DBusString *addr_fd,
240                             const char       *extra_arg)
241 {
242   if (_dbus_string_get_length (addr_fd) > 0)
243     {
244       fprintf (stderr, "--%s specified but printing address to %s already requested\n",
245                extra_arg, _dbus_string_get_const_data (addr_fd));
246       exit (1);
247     }
248 }
249
250 static void
251 check_two_pid_descriptors (const DBusString *pid_fd,
252                            const char       *extra_arg)
253 {
254   if (_dbus_string_get_length (pid_fd) > 0)
255     {
256       fprintf (stderr, "--%s specified but printing pid to %s already requested\n",
257                extra_arg, _dbus_string_get_const_data (pid_fd));
258       exit (1);
259     }
260 }
261
262 #ifdef DBUS_UNIX
263 static dbus_bool_t
264 handle_reload_watch (DBusWatch    *watch,
265                      unsigned int  flags,
266                      void         *data)
267 {
268   DBusError error;
269   DBusString str;
270   char *action_str;
271   char action = '\0';
272
273   while (!_dbus_string_init (&str))
274     _dbus_wait_for_memory ();
275
276   if ((reload_pipe[RELOAD_READ_END].fd > 0) &&
277       _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
278     {
279       _dbus_warn ("Couldn't read from reload pipe.");
280       close_reload_pipe (&watch);
281       return TRUE;
282     }
283
284   action_str = _dbus_string_get_data (&str);
285   if (action_str != NULL)
286     {
287       action = action_str[0];
288     }
289   _dbus_string_free (&str);
290
291   /* this can only fail if we don't understand the config file
292    * or OOM.  Either way we should just stick with the currently
293    * loaded config.
294    */
295   dbus_error_init (&error);
296
297   switch (action)
298     {
299     case ACTION_RELOAD:
300       if (! bus_context_reload_config (context, &error))
301         {
302           _DBUS_ASSERT_ERROR_IS_SET (&error);
303           _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
304                         dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
305           _dbus_warn ("Unable to reload configuration: %s",
306                       error.message);
307           dbus_error_free (&error);
308         }
309       break;
310
311     case ACTION_QUIT:
312       {
313         DBusLoop *loop;
314         /*
315          * On OSs without abstract sockets, we want to quit
316          * gracefully rather than being killed by SIGTERM,
317          * so that DBusServer gets a chance to clean up the
318          * sockets from the filesystem. fd.o #38656
319          */
320         loop = bus_context_get_loop (context);
321         if (loop != NULL)
322           {
323             _dbus_loop_quit (loop);
324           }
325       }
326       break;
327
328     default:
329       break;
330     }
331
332   return TRUE;
333 }
334
335 static void
336 setup_reload_pipe (DBusLoop *loop)
337 {
338   DBusError error;
339   DBusWatch *watch;
340
341   dbus_error_init (&error);
342
343   if (!_dbus_socketpair (&reload_pipe[0], &reload_pipe[1],
344                          TRUE, &error))
345     {
346       _dbus_warn ("Unable to create reload pipe: %s",
347                   error.message);
348       dbus_error_free (&error);
349       exit (1);
350     }
351
352   watch = _dbus_watch_new (_dbus_socket_get_pollable (reload_pipe[RELOAD_READ_END]),
353                            DBUS_WATCH_READABLE, TRUE,
354                            handle_reload_watch, NULL, NULL);
355
356   if (watch == NULL)
357     {
358       _dbus_warn ("Unable to create reload watch: %s",
359                   error.message);
360       dbus_error_free (&error);
361       exit (1);
362     }
363
364   if (!_dbus_loop_add_watch (loop, watch))
365     {
366       _dbus_warn ("Unable to add reload watch to main loop: %s",
367                   error.message);
368       dbus_error_free (&error);
369       exit (1);
370     }
371
372 }
373
374 static void
375 close_reload_pipe (DBusWatch **watch)
376 {
377     _dbus_loop_remove_watch (bus_context_get_loop (context), *watch);
378     _dbus_watch_invalidate (*watch);
379     _dbus_watch_unref (*watch);
380     *watch = NULL;
381
382     _dbus_close_socket (reload_pipe[RELOAD_READ_END], NULL);
383     _dbus_socket_invalidate (&reload_pipe[RELOAD_READ_END]);
384
385     _dbus_close_socket (reload_pipe[RELOAD_WRITE_END], NULL);
386     _dbus_socket_invalidate (&reload_pipe[RELOAD_WRITE_END]);
387 }
388 #endif /* DBUS_UNIX */
389
390 int
391 main (int argc, char **argv)
392 {
393   DBusError error;
394   DBusString config_file;
395   DBusString address;
396   DBusString addr_fd;
397   DBusString pid_fd;
398   const char *prev_arg;
399   DBusPipe print_addr_pipe;
400   DBusPipe print_pid_pipe;
401   int i;
402   dbus_bool_t print_address;
403   dbus_bool_t print_pid;
404   BusContextFlags flags;
405 #ifdef DBUS_UNIX
406   const char *error_str;
407
408   /* Redirect stdin from /dev/null since we will never need it, and
409    * redirect stdout and stderr to /dev/null if not already open.
410    *
411    * We should do this as the very first thing, to ensure that when we
412    * create other file descriptors (for example for epoll, inotify or
413    * a socket), they never get assigned as fd 0, 1 or 2. If they were,
414    * which could happen if our caller had (incorrectly) closed those
415    * standard fds, they'd get closed when we daemonize - for example,
416    * closing our listening socket would stop us listening, and closing
417    * a Linux epoll socket would cause the main loop to fail. */
418   if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
419     {
420       fprintf (stderr,
421                "dbus-daemon: fatal error setting up standard fds: %s: %s\n",
422                error_str, _dbus_strerror (errno));
423       return 1;
424     }
425 #endif
426
427   if (!_dbus_string_init (&config_file))
428     return 1;
429
430   if (!_dbus_string_init (&address))
431     return 1;
432
433   if (!_dbus_string_init (&addr_fd))
434     return 1;
435
436   if (!_dbus_string_init (&pid_fd))
437     return 1;
438
439   print_address = FALSE;
440   print_pid = FALSE;
441
442   flags = BUS_CONTEXT_FLAG_WRITE_PID_FILE;
443
444   prev_arg = NULL;
445   i = 1;
446   while (i < argc)
447     {
448       const char *arg = argv[i];
449
450       if (strcmp (arg, "--help") == 0 ||
451           strcmp (arg, "-h") == 0 ||
452           strcmp (arg, "-?") == 0)
453         {
454           usage ();
455         }
456       else if (strcmp (arg, "--version") == 0)
457         {
458           version ();
459         }
460       else if (strcmp (arg, "--introspect") == 0)
461         {
462           introspect ();
463         }
464       else if (strcmp (arg, "--nosyslog") == 0)
465         {
466           flags &= ~BUS_CONTEXT_FLAG_SYSLOG_ALWAYS;
467           flags |= BUS_CONTEXT_FLAG_SYSLOG_NEVER;
468         }
469       else if (strcmp (arg, "--syslog") == 0)
470         {
471           flags &= ~BUS_CONTEXT_FLAG_SYSLOG_NEVER;
472           flags |= BUS_CONTEXT_FLAG_SYSLOG_ALWAYS;
473         }
474       else if (strcmp (arg, "--syslog-only") == 0)
475         {
476           flags &= ~BUS_CONTEXT_FLAG_SYSLOG_NEVER;
477           flags |= (BUS_CONTEXT_FLAG_SYSLOG_ALWAYS|BUS_CONTEXT_FLAG_SYSLOG_ONLY);
478         }
479       else if (strcmp (arg, "--nofork") == 0)
480         {
481           flags &= ~BUS_CONTEXT_FLAG_FORK_ALWAYS;
482           flags |= BUS_CONTEXT_FLAG_FORK_NEVER;
483         }
484 #ifdef DBUS_UNIX
485       else if (strcmp (arg, "--fork") == 0)
486         {
487           flags &= ~BUS_CONTEXT_FLAG_FORK_NEVER;
488           flags |= BUS_CONTEXT_FLAG_FORK_ALWAYS;
489         }
490       else if (strcmp (arg, "--systemd-activation") == 0)
491         {
492           flags |= BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION;
493         }
494 #endif
495       else if (strcmp (arg, "--nopidfile") == 0)
496         {
497           flags &= ~BUS_CONTEXT_FLAG_WRITE_PID_FILE;
498         }
499       else if (strcmp (arg, "--system") == 0)
500         {
501           check_two_config_files (&config_file, "system");
502
503           if (!_dbus_get_system_config_file (&config_file))
504             exit (1);
505         }
506       else if (strcmp (arg, "--session") == 0)
507         {
508           check_two_config_files (&config_file, "session");
509
510           if (!_dbus_get_session_config_file (&config_file))
511             exit (1);
512         }
513       else if (strstr (arg, "--config-file=") == arg)
514         {
515           const char *file;
516
517           check_two_config_files (&config_file, "config-file");
518
519           file = strchr (arg, '=');
520           ++file;
521
522           if (!_dbus_string_append (&config_file, file))
523             exit (1);
524         }
525       else if (prev_arg &&
526                strcmp (prev_arg, "--config-file") == 0)
527         {
528           check_two_config_files (&config_file, "config-file");
529
530           if (!_dbus_string_append (&config_file, arg))
531             exit (1);
532         }
533       else if (strcmp (arg, "--config-file") == 0)
534         {
535           /* wait for next arg */
536         }
537       else if (strstr (arg, "--address=") == arg)
538         {
539           const char *file;
540
541           check_two_addresses (&address, "address");
542
543           file = strchr (arg, '=');
544           ++file;
545
546           if (!_dbus_string_append (&address, file))
547             exit (1);
548         }
549       else if (prev_arg &&
550                strcmp (prev_arg, "--address") == 0)
551         {
552           check_two_addresses (&address, "address");
553
554           if (!_dbus_string_append (&address, arg))
555             exit (1);
556         }
557       else if (strcmp (arg, "--address") == 0)
558         {
559           /* wait for next arg */
560         }
561       else if (strstr (arg, "--print-address=") == arg)
562         {
563           const char *desc;
564
565           check_two_addr_descriptors (&addr_fd, "print-address");
566
567           desc = strchr (arg, '=');
568           ++desc;
569
570           if (!_dbus_string_append (&addr_fd, desc))
571             exit (1);
572
573           print_address = TRUE;
574         }
575       else if (prev_arg &&
576                strcmp (prev_arg, "--print-address") == 0)
577         {
578           check_two_addr_descriptors (&addr_fd, "print-address");
579
580           if (!_dbus_string_append (&addr_fd, arg))
581             exit (1);
582
583           print_address = TRUE;
584         }
585       else if (strcmp (arg, "--print-address") == 0)
586         {
587           print_address = TRUE; /* and we'll get the next arg if appropriate */
588         }
589       else if (strstr (arg, "--print-pid=") == arg)
590         {
591           const char *desc;
592
593           check_two_pid_descriptors (&pid_fd, "print-pid");
594
595           desc = strchr (arg, '=');
596           ++desc;
597
598           if (!_dbus_string_append (&pid_fd, desc))
599             exit (1);
600
601           print_pid = TRUE;
602         }
603       else if (prev_arg &&
604                strcmp (prev_arg, "--print-pid") == 0)
605         {
606           check_two_pid_descriptors (&pid_fd, "print-pid");
607
608           if (!_dbus_string_append (&pid_fd, arg))
609             exit (1);
610
611           print_pid = TRUE;
612         }
613       else if (strcmp (arg, "--print-pid") == 0)
614         {
615           print_pid = TRUE; /* and we'll get the next arg if appropriate */
616         }
617       else
618         {
619           usage ();
620         }
621
622       prev_arg = arg;
623
624       ++i;
625     }
626
627   if (_dbus_string_get_length (&config_file) == 0)
628     {
629       fprintf (stderr, "No configuration file specified.\n");
630       usage ();
631     }
632
633   _dbus_pipe_invalidate (&print_addr_pipe);
634   if (print_address)
635     {
636       _dbus_pipe_init_stdout (&print_addr_pipe);
637       if (_dbus_string_get_length (&addr_fd) > 0)
638         {
639           long val;
640           int end;
641           if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) ||
642               end != _dbus_string_get_length (&addr_fd) ||
643               val < 0 || val > _DBUS_INT_MAX)
644             {
645               fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
646                        _dbus_string_get_const_data (&addr_fd));
647               exit (1);
648             }
649
650           _dbus_pipe_init (&print_addr_pipe, val);
651         }
652     }
653   _dbus_string_free (&addr_fd);
654
655   _dbus_pipe_invalidate (&print_pid_pipe);
656   if (print_pid)
657     {
658       _dbus_pipe_init_stdout (&print_pid_pipe);
659       if (_dbus_string_get_length (&pid_fd) > 0)
660         {
661           long val;
662           int end;
663           if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) ||
664               end != _dbus_string_get_length (&pid_fd) ||
665               val < 0 || val > _DBUS_INT_MAX)
666             {
667               fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
668                        _dbus_string_get_const_data (&pid_fd));
669               exit (1);
670             }
671
672           _dbus_pipe_init (&print_pid_pipe, val);
673         }
674     }
675   _dbus_string_free (&pid_fd);
676
677   if (!bus_selinux_pre_init ())
678     {
679       _dbus_warn ("SELinux pre-initialization failed");
680       exit (1);
681     }
682
683   if (!bus_apparmor_pre_init ())
684     {
685       _dbus_warn ("AppArmor pre-initialization failed: out of memory");
686       exit (1);
687     }
688
689   dbus_error_init (&error);
690   context = bus_context_new (&config_file, flags,
691                              &print_addr_pipe, &print_pid_pipe,
692                              _dbus_string_get_length(&address) > 0 ? &address : NULL,
693                              &error);
694   _dbus_string_free (&config_file);
695   _dbus_string_free (&address);
696   if (context == NULL)
697     {
698       _dbus_warn ("Failed to start message bus: %s",
699                   error.message);
700       dbus_error_free (&error);
701       exit (1);
702     }
703
704   /* bus_context_new() closes the print_addr_pipe and
705    * print_pid_pipe
706    */
707
708 #ifdef DBUS_UNIX
709   setup_reload_pipe (bus_context_get_loop (context));
710
711   /* POSIX signals are Unix-specific, and _dbus_set_signal_handler is
712    * unimplemented (and probably unimplementable) on Windows, so there's
713    * no point in trying to make the handler portable to non-Unix. */
714
715   _dbus_set_signal_handler (SIGTERM, signal_handler);
716   _dbus_set_signal_handler (SIGHUP, signal_handler);
717 #endif /* DBUS_UNIX */
718
719   dbus_set_protocol_version (DBUS_MAJOR_PROTOCOL_VERSION);
720
721   _dbus_verbose ("We are on D-Bus...\n");
722   _dbus_loop_run (bus_context_get_loop (context));
723
724   bus_context_shutdown (context);
725   bus_context_unref (context);
726   bus_selinux_shutdown ();
727   bus_apparmor_shutdown ();
728   bus_audit_shutdown ();
729
730   return 0;
731 }