/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* bus.c  message bus context object
 *
 * Copyright (C) 2003, 2004 Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "bus.h"

#include <stdio.h>

#include "activation.h"
#include "connection.h"
#include "services.h"
#include "utils.h"
#include "policy.h"
#include "config-parser.h"
#include "signals.h"
#include "selinux.h"
#include "apparmor.h"
#include "audit.h"
#include "dir-watch.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-credentials.h>
#include <dbus/dbus-internals.h>
#include <dbus/dbus-server-protected.h>

#ifdef DBUS_CYGWIN
#include <signal.h>
#endif

struct BusContext
{
  int refcount;
  DBusGUID uuid;
  char *config_file;
  char *type;
  char *servicehelper;
  char *address;
  char *pidfile;
  char *user;
  char *log_prefix;
  DBusLoop *loop;
  DBusList *servers;
  BusConnections *connections;
  BusActivation *activation;
  BusRegistry *registry;
  BusPolicy *policy;
  BusMatchmaker *matchmaker;
  BusLimits limits;
  DBusRLimit *initial_fd_limit;
  unsigned int fork : 1;
  unsigned int syslog : 1;
  unsigned int keep_umask : 1;
  unsigned int allow_anonymous : 1;
  unsigned int systemd_activation : 1;
  dbus_bool_t watches_enabled;
};

static dbus_int32_t server_data_slot = -1;

typedef struct
{
  BusContext *context;
} BusServerData;

#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))

static BusContext*
server_get_context (DBusServer *server)
{
  BusContext *context;
  BusServerData *bd;

  if (!dbus_server_allocate_data_slot (&server_data_slot))
    return NULL;

  bd = BUS_SERVER_DATA (server);
  if (bd == NULL)
    {
      dbus_server_free_data_slot (&server_data_slot);
      return NULL;
    }

  context = bd->context;

  dbus_server_free_data_slot (&server_data_slot);

  return context;
}

static dbus_bool_t
add_server_watch (DBusWatch  *watch,
                  void       *data)
{
  DBusServer *server = data;
  BusContext *context;

  context = server_get_context (server);

  return _dbus_loop_add_watch (context->loop, watch);
}

static void
remove_server_watch (DBusWatch  *watch,
                     void       *data)
{
  DBusServer *server = data;
  BusContext *context;

  context = server_get_context (server);

  _dbus_loop_remove_watch (context->loop, watch);
}

static void
toggle_server_watch (DBusWatch  *watch,
                     void       *data)
{
  DBusServer *server = data;
  BusContext *context;

  context = server_get_context (server);

  _dbus_loop_toggle_watch (context->loop, watch);
}

static dbus_bool_t
add_server_timeout (DBusTimeout *timeout,
                    void        *data)
{
  DBusServer *server = data;
  BusContext *context;

  context = server_get_context (server);

  return _dbus_loop_add_timeout (context->loop, timeout);
}

static void
remove_server_timeout (DBusTimeout *timeout,
                       void        *data)
{
  DBusServer *server = data;
  BusContext *context;

  context = server_get_context (server);

  _dbus_loop_remove_timeout (context->loop, timeout);
}

static void
new_connection_callback (DBusServer     *server,
                         DBusConnection *new_connection,
                         void           *data)
{
  BusContext *context = data;

  if (!bus_connections_setup_connection (context->connections, new_connection))
    {
      _dbus_verbose ("No memory to setup new connection\n");

      /* if we don't do this, it will get unref'd without
       * being disconnected... kind of strange really
       * that we have to do this, people won't get it right
       * in general.
       */
      dbus_connection_close (new_connection);
    }

  dbus_connection_set_max_received_size (new_connection,
                                         context->limits.max_incoming_bytes);

  dbus_connection_set_max_message_size (new_connection,
                                        context->limits.max_message_size);

  dbus_connection_set_max_received_unix_fds (new_connection,
                                         context->limits.max_incoming_unix_fds);

  dbus_connection_set_max_message_unix_fds (new_connection,
                                        context->limits.max_message_unix_fds);

  dbus_connection_set_allow_anonymous (new_connection,
                                       context->allow_anonymous);

  /* on OOM, we won't have ref'd the connection so it will die. */
}

static void
free_server_data (void *data)
{
  BusServerData *bd = data;

  dbus_free (bd);
}

static dbus_bool_t
setup_server (BusContext *context,
              DBusServer *server,
              char      **auth_mechanisms,
              DBusError  *error)
{
  BusServerData *bd;

  bd = dbus_new0 (BusServerData, 1);
  if (bd == NULL || !dbus_server_set_data (server,
                                           server_data_slot,
                                           bd, free_server_data))
    {
      dbus_free (bd);
      BUS_SET_OOM (error);
      return FALSE;
    }

  bd->context = context;

  if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  dbus_server_set_new_connection_function (server,
                                           new_connection_callback,
                                           context, NULL);

  if (!dbus_server_set_watch_functions (server,
                                        add_server_watch,
                                        remove_server_watch,
                                        toggle_server_watch,
                                        server,
                                        NULL))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  if (!dbus_server_set_timeout_functions (server,
                                          add_server_timeout,
                                          remove_server_timeout,
                                          NULL,
                                          server, NULL))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  return TRUE;
}

/* This code only gets executed the first time the
 * config files are parsed.  It is not executed
 * when config files are reloaded.
 */
static dbus_bool_t
process_config_first_time_only (BusContext       *context,
				BusConfigParser  *parser,
                                const DBusString *address,
                                BusContextFlags   flags,
				DBusError        *error)
{
  DBusString log_prefix;
  DBusList *link;
  DBusList **addresses;
  const char *user, *pidfile;
  char **auth_mechanisms;
  DBusList **auth_mechanisms_list;
  int len;
  dbus_bool_t retval;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  retval = FALSE;
  auth_mechanisms = NULL;
  pidfile = NULL;

  _dbus_init_system_log (TRUE);

  if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION)
    context->systemd_activation = TRUE;
  else
    context->systemd_activation = FALSE;

  /* Check for an existing pid file. Of course this is a race;
   * we'd have to use fcntl() locks on the pid file to
   * avoid that. But we want to check for the pid file
   * before overwriting any existing sockets, etc.
   */

  if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE)
    pidfile = bus_config_parser_get_pidfile (parser);

  if (pidfile != NULL)
    {
      DBusString u;
      DBusStat stbuf;

      _dbus_string_init_const (&u, pidfile);

      if (_dbus_stat (&u, &stbuf, NULL))
        {
#ifdef DBUS_CYGWIN
          DBusString p;
          long /* int */ pid;

          _dbus_string_init (&p);
          _dbus_file_get_contents(&p, &u, NULL);
          _dbus_string_parse_int(&p, 0, &pid, NULL);
          _dbus_string_free(&p);

          if ((kill((int)pid, 0))) {
            dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS,
                           "pid %ld not running, removing stale pid file\n",
                           pid);
            _dbus_delete_file(&u, NULL);
          } else {
#endif
          dbus_set_error (error, DBUS_ERROR_FAILED,
		                  "The pid file \"%s\" exists, if the message bus is not running, remove this file",
                          pidfile);
	      goto failed;
#ifdef DBUS_CYGWIN
          }
#endif
        }
    }

  /* keep around the pid filename so we can delete it later */
  context->pidfile = _dbus_strdup (pidfile);

  /* note that type may be NULL */
  context->type = _dbus_strdup (bus_config_parser_get_type (parser));
  if (bus_config_parser_get_type (parser) != NULL && context->type == NULL)
    goto oom;

  user = bus_config_parser_get_user (parser);
  if (user != NULL)
    {
      context->user = _dbus_strdup (user);
      if (context->user == NULL)
        goto oom;
    }

  /* Set up the prefix for syslog messages */
  if (!_dbus_string_init (&log_prefix))
    goto oom;
  if (context->type && !strcmp (context->type, "system"))
    {
      if (!_dbus_string_append (&log_prefix, "[system] "))
        goto oom;
    }
  else if (context->type && !strcmp (context->type, "session"))
    {
      DBusCredentials *credentials;

      credentials = _dbus_credentials_new_from_current_process ();
      if (!credentials)
        goto oom;
      if (!_dbus_string_append (&log_prefix, "[session "))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      if (!_dbus_credentials_to_string_append (credentials, &log_prefix))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      if (!_dbus_string_append (&log_prefix, "] "))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      _dbus_credentials_unref (credentials);
    }
  if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix))
    goto oom;
  _dbus_string_free (&log_prefix);

  /* Build an array of auth mechanisms */

  auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
  len = _dbus_list_get_length (auth_mechanisms_list);

  if (len > 0)
    {
      int i;

      auth_mechanisms = dbus_new0 (char*, len + 1);
      if (auth_mechanisms == NULL)
        goto oom;

      i = 0;
      link = _dbus_list_get_first_link (auth_mechanisms_list);
      while (link != NULL)
        {
          auth_mechanisms[i] = _dbus_strdup (link->data);
          if (auth_mechanisms[i] == NULL)
            goto oom;
          link = _dbus_list_get_next_link (auth_mechanisms_list, link);
          i += 1;
        }
    }
  else
    {
      auth_mechanisms = NULL;
    }

  /* Listen on our addresses */

  if (address)
    {
      DBusServer *server;

      server = dbus_server_listen (_dbus_string_get_const_data(address), error);
      if (server == NULL)
        {
          _DBUS_ASSERT_ERROR_IS_SET (error);
          goto failed;
        }
      else if (!setup_server (context, server, auth_mechanisms, error))
        {
          _DBUS_ASSERT_ERROR_IS_SET (error);
          goto failed;
        }

      if (!_dbus_list_append (&context->servers, server))
        goto oom;
    }
  else
    {
      addresses = bus_config_parser_get_addresses (parser);

      link = _dbus_list_get_first_link (addresses);
      while (link != NULL)
        {
          DBusServer *server;

          server = dbus_server_listen (link->data, error);
          if (server == NULL)
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              goto failed;
            }
          else if (!setup_server (context, server, auth_mechanisms, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              goto failed;
            }

          if (!_dbus_list_append (&context->servers, server))
            goto oom;

          link = _dbus_list_get_next_link (addresses, link);
        }
    }

  context->fork = bus_config_parser_get_fork (parser);
  context->syslog = bus_config_parser_get_syslog (parser);
  context->keep_umask = bus_config_parser_get_keep_umask (parser);
  context->allow_anonymous = bus_config_parser_get_allow_anonymous (parser);

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  retval = TRUE;

 failed:
  dbus_free_string_array (auth_mechanisms);
  return retval;

 oom:
  BUS_SET_OOM (error);
  dbus_free_string_array (auth_mechanisms);
  return FALSE;
}

/* This code gets executed every time the config files
 * are parsed: both during BusContext construction
 * and on reloads. This function is slightly screwy
 * since it can do a "half reload" in out-of-memory
 * situations. Realistically, unlikely to ever matter.
 */
static dbus_bool_t
process_config_every_time (BusContext      *context,
			   BusConfigParser *parser,
			   dbus_bool_t      is_reload,
			   DBusError       *error)
{
  DBusString full_address;
  DBusList *link;
  DBusList **dirs;
  char *addr;
  const char *servicehelper;
  char *s;

  dbus_bool_t retval;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  addr = NULL;
  retval = FALSE;

  if (!_dbus_string_init (&full_address))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  /* get our limits and timeout lengths */
  bus_config_parser_get_limits (parser, &context->limits);

  if (context->policy)
    bus_policy_unref (context->policy);
  context->policy = bus_config_parser_steal_policy (parser);
  _dbus_assert (context->policy != NULL);

  /* context->connections is NULL when creating new BusContext */
  if (context->connections)
    {
      _dbus_verbose ("Reload policy rules for completed connections\n");
      retval = bus_connections_reload_policy (context->connections, error);
      if (!retval)
        {
          _DBUS_ASSERT_ERROR_IS_SET (error);
          goto failed;
        }
    }

  /* We have to build the address backward, so that
   * <listen> later in the config file have priority
   */
  link = _dbus_list_get_last_link (&context->servers);
  while (link != NULL)
    {
      addr = dbus_server_get_address (link->data);
      if (addr == NULL)
        {
          BUS_SET_OOM (error);
          goto failed;
        }

      if (_dbus_string_get_length (&full_address) > 0)
        {
          if (!_dbus_string_append (&full_address, ";"))
            {
              BUS_SET_OOM (error);
              goto failed;
            }
        }

      if (!_dbus_string_append (&full_address, addr))
        {
          BUS_SET_OOM (error);
          goto failed;
        }

      dbus_free (addr);
      addr = NULL;

      link = _dbus_list_get_prev_link (&context->servers, link);
    }

  if (is_reload)
    dbus_free (context->address);

  if (!_dbus_string_copy_data (&full_address, &context->address))
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  /* get the service directories */
  dirs = bus_config_parser_get_service_dirs (parser);

  /* and the service helper */
  servicehelper = bus_config_parser_get_servicehelper (parser);

  s = _dbus_strdup(servicehelper);
  if (s == NULL && servicehelper != NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }
  else
    {
      dbus_free(context->servicehelper);
      context->servicehelper = s;
    }

  /* Create activation subsystem */
  if (context->activation)
    {
      if (!bus_activation_reload (context->activation, &full_address, dirs, error))
        goto failed;
    }
  else
    {
      context->activation = bus_activation_new (context, &full_address, dirs, error);
    }

  if (context->activation == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  retval = TRUE;

 failed:
  _dbus_string_free (&full_address);

  if (addr)
    dbus_free (addr);

  return retval;
}

static dbus_bool_t
list_concat_new (DBusList **a,
                 DBusList **b,
                 DBusList **result)
{
  DBusList *link;

  *result = NULL;

  for (link = _dbus_list_get_first_link (a); link; link = _dbus_list_get_next_link (a, link))
    {
      if (!_dbus_list_append (result, link->data))
        goto oom;
    }
  for (link = _dbus_list_get_first_link (b); link; link = _dbus_list_get_next_link (b, link))
    {
      if (!_dbus_list_append (result, link->data))
        goto oom;
    }

  return TRUE;
oom:
  _dbus_list_clear (result);
  return FALSE;
}

static void
raise_file_descriptor_limit (BusContext      *context)
{
#ifdef DBUS_UNIX
  DBusError error = DBUS_ERROR_INIT;

  /* we only do this once */
  if (context->initial_fd_limit != NULL)
    return;

  context->initial_fd_limit = _dbus_rlimit_save_fd_limit (&error);

  if (context->initial_fd_limit == NULL)
    {
      bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
                       "%s: %s", error.name, error.message);
      dbus_error_free (&error);
      return;
    }

  /* We used to compute a suitable rlimit based on the configured number
   * of connections, but that breaks down as soon as we allow fd-passing,
   * because each connection is allowed to pass 64 fds to us, and if
   * they all did, we'd hit kernel limits. We now hard-code 64k as a
   * good limit, like systemd does: that's enough to avoid DoS from
   * anything short of multiple uids conspiring against us.
   */
  if (!_dbus_rlimit_raise_fd_limit_if_privileged (65536, &error))
    {
      bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
                       "%s: %s", error.name, error.message);
      dbus_error_free (&error);
      return;
    }
#endif
}

static dbus_bool_t
process_config_postinit (BusContext      *context,
			 BusConfigParser *parser,
			 DBusError       *error)
{
  DBusHashTable *service_context_table;
  DBusList *watched_dirs = NULL;

  raise_file_descriptor_limit (context);

  service_context_table = bus_config_parser_steal_service_context_table (parser);
  if (!bus_registry_set_service_context_table (context->registry,
					       service_context_table))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  _dbus_hash_table_unref (service_context_table);

  /* We need to monitor both the configuration directories and directories
   * containing .service files.
   */
  if (!list_concat_new (bus_config_parser_get_conf_dirs (parser),
                        bus_config_parser_get_service_dirs (parser),
                        &watched_dirs))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  bus_set_watched_dirs (context, &watched_dirs);

  _dbus_list_clear (&watched_dirs);

  return TRUE;
}

BusContext*
bus_context_new (const DBusString *config_file,
                 BusContextFlags   flags,
                 DBusPipe         *print_addr_pipe,
                 DBusPipe         *print_pid_pipe,
                 const DBusString *address,
                 DBusError        *error)
{
  BusContext *context;
  BusConfigParser *parser;

  _dbus_assert ((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 ||
                (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS) == 0);

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  context = NULL;
  parser = NULL;

  if (!dbus_server_allocate_data_slot (&server_data_slot))
    {
      BUS_SET_OOM (error);
      return NULL;
    }

  context = dbus_new0 (BusContext, 1);
  if (context == NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }
  context->refcount = 1;

  if (!_dbus_generate_uuid (&context->uuid, error))
    goto failed;

  if (!_dbus_string_copy_data (config_file, &context->config_file))
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  context->loop = _dbus_loop_new ();
  if (context->loop == NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  context->watches_enabled = TRUE;

  context->registry = bus_registry_new (context);
  if (context->registry == NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  parser = bus_config_load (config_file, TRUE, NULL, error);
  if (parser == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  if (!process_config_first_time_only (context, parser, address, flags, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }
  if (!process_config_every_time (context, parser, FALSE, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  /* we need another ref of the server data slot for the context
   * to own
   */
  if (!dbus_server_allocate_data_slot (&server_data_slot))
    _dbus_assert_not_reached ("second ref of server data slot failed");

  /* Note that we don't know whether the print_addr_pipe is
   * one of the sockets we're using to listen on, or some
   * other random thing. But I think the answer is "don't do
   * that then"
   */
  if (print_addr_pipe != NULL && _dbus_pipe_is_valid (print_addr_pipe))
    {
      DBusString addr;
      const char *a = bus_context_get_address (context);
      int bytes;

      _dbus_assert (a != NULL);
      if (!_dbus_string_init (&addr))
        {
          BUS_SET_OOM (error);
          goto failed;
        }

      if (!_dbus_string_append (&addr, a) ||
          !_dbus_string_append (&addr, "\n"))
        {
          _dbus_string_free (&addr);
          BUS_SET_OOM (error);
          goto failed;
        }

      bytes = _dbus_string_get_length (&addr);
      if (_dbus_pipe_write (print_addr_pipe, &addr, 0, bytes, error) != bytes)
        {
          /* pipe write returns an error on failure but not short write */
          if (error != NULL && !dbus_error_is_set (error))
            {
              dbus_set_error (error, DBUS_ERROR_FAILED,
                              "Printing message bus address: did not write all bytes\n");
            }
          _dbus_string_free (&addr);
          goto failed;
        }

      if (!_dbus_pipe_is_stdout_or_stderr (print_addr_pipe))
        _dbus_pipe_close (print_addr_pipe, NULL);

      _dbus_string_free (&addr);
    }

  context->connections = bus_connections_new (context);
  if (context->connections == NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  context->matchmaker = bus_matchmaker_new ();
  if (context->matchmaker == NULL)
    {
      BUS_SET_OOM (error);
      goto failed;
    }

  /* check user before we fork */
  if (context->user != NULL)
    {
      if (!_dbus_verify_daemon_user (context->user))
        {
          dbus_set_error (error, DBUS_ERROR_FAILED,
                          "Could not get UID and GID for username \"%s\"",
                          context->user);
          goto failed;
        }
    }

  /* Now become a daemon if appropriate and write out pid file in any case */
  {
    DBusString u;

    if (context->pidfile)
      _dbus_string_init_const (&u, context->pidfile);

    if (((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 && context->fork) ||
        (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS))
      {
        _dbus_verbose ("Forking and becoming daemon\n");

        if (!_dbus_become_daemon (context->pidfile ? &u : NULL,
                                  print_pid_pipe,
                                  error,
                                  context->keep_umask))
          {
            _DBUS_ASSERT_ERROR_IS_SET (error);
            goto failed;
          }
      }
    else
      {
        _dbus_verbose ("Fork not requested\n");

        /* Need to write PID file and to PID pipe for ourselves,
         * not for the child process. This is a no-op if the pidfile
         * is NULL and print_pid_pipe is NULL.
         */
        if (!_dbus_write_pid_to_file_and_pipe (context->pidfile ? &u : NULL,
                                               print_pid_pipe,
                                               _dbus_getpid (),
                                               error))
          {
            _DBUS_ASSERT_ERROR_IS_SET (error);
            goto failed;
          }
      }
  }

  if (print_pid_pipe && _dbus_pipe_is_valid (print_pid_pipe) &&
      !_dbus_pipe_is_stdout_or_stderr (print_pid_pipe))
    _dbus_pipe_close (print_pid_pipe, NULL);

  if (!bus_selinux_full_init ())
    {
      bus_context_log (context, DBUS_SYSTEM_LOG_FATAL, "SELinux enabled but D-Bus initialization failed; check system log\n");
    }

  if (!bus_apparmor_full_init (error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  if (bus_apparmor_enabled ())
    {
      /* Only print AppArmor mediation message when syslog support is enabled */
      if (context->syslog)
        bus_context_log (context, DBUS_SYSTEM_LOG_INFO,
                         "AppArmor D-Bus mediation is enabled\n");
    }

  if (!process_config_postinit (context, parser, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  if (parser != NULL)
    {
      bus_config_parser_unref (parser);
      parser = NULL;
    }

  /* Here we change our credentials if required,
   * as soon as we've set up our sockets and pidfile
   */
  if (context->user != NULL)
    {
      if (!_dbus_change_to_daemon_user (context->user, error))
	{
	  _DBUS_ASSERT_ERROR_IS_SET (error);
	  goto failed;
	}
    }

  bus_audit_init (context);

  dbus_server_free_data_slot (&server_data_slot);

  return context;

 failed:
  if (parser != NULL)
    bus_config_parser_unref (parser);
  if (context != NULL)
    bus_context_unref (context);

  if (server_data_slot >= 0)
    dbus_server_free_data_slot (&server_data_slot);

  return NULL;
}

dbus_bool_t
bus_context_get_id (BusContext       *context,
                    DBusString       *uuid)
{
  return _dbus_uuid_encode (&context->uuid, uuid);
}

dbus_bool_t
bus_context_reload_config (BusContext *context,
			   DBusError  *error)
{
  BusConfigParser *parser;
  DBusString config_file;
  dbus_bool_t ret;

  /* Flush the user database cache */
  _dbus_flush_caches ();

  ret = FALSE;
  _dbus_string_init_const (&config_file, context->config_file);
  parser = bus_config_load (&config_file, TRUE, NULL, error);
  if (parser == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }

  if (!process_config_every_time (context, parser, TRUE, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }
  if (!process_config_postinit (context, parser, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed;
    }
  ret = TRUE;

  bus_context_log (context, DBUS_SYSTEM_LOG_INFO, "Reloaded configuration");
 failed:
  if (!ret)
    bus_context_log (context, DBUS_SYSTEM_LOG_INFO, "Unable to reload configuration: %s", error->message);
  if (parser != NULL)
    bus_config_parser_unref (parser);
  return ret;
}

static void
shutdown_server (BusContext *context,
                 DBusServer *server)
{
  if (server == NULL ||
      !dbus_server_get_is_connected (server))
    return;

  if (!dbus_server_set_watch_functions (server,
                                        NULL, NULL, NULL,
                                        context,
                                        NULL))
    _dbus_assert_not_reached ("setting watch functions to NULL failed");

  if (!dbus_server_set_timeout_functions (server,
                                          NULL, NULL, NULL,
                                          context,
                                          NULL))
    _dbus_assert_not_reached ("setting timeout functions to NULL failed");

  dbus_server_disconnect (server);
}

void
bus_context_shutdown (BusContext  *context)
{
  DBusList *link;

  link = _dbus_list_get_first_link (&context->servers);
  while (link != NULL)
    {
      shutdown_server (context, link->data);

      link = _dbus_list_get_next_link (&context->servers, link);
    }
}

BusContext *
bus_context_ref (BusContext *context)
{
  _dbus_assert (context->refcount > 0);
  context->refcount += 1;

  return context;
}

void
bus_context_unref (BusContext *context)
{
  _dbus_assert (context->refcount > 0);
  context->refcount -= 1;

  if (context->refcount == 0)
    {
      DBusList *link;

      _dbus_verbose ("Finalizing bus context %p\n", context);

      bus_context_shutdown (context);

      if (context->connections)
        {
          bus_connections_unref (context->connections);
          context->connections = NULL;
        }

      if (context->registry)
        {
          bus_registry_unref (context->registry);
          context->registry = NULL;
        }

      if (context->activation)
        {
          bus_activation_unref (context->activation);
          context->activation = NULL;
        }

      link = _dbus_list_get_first_link (&context->servers);
      while (link != NULL)
        {
          dbus_server_unref (link->data);

          link = _dbus_list_get_next_link (&context->servers, link);
        }
      _dbus_list_clear (&context->servers);

      if (context->policy)
        {
          bus_policy_unref (context->policy);
          context->policy = NULL;
        }

      if (context->loop)
        {
          _dbus_loop_unref (context->loop);
          context->loop = NULL;
        }

      if (context->matchmaker)
        {
          bus_matchmaker_unref (context->matchmaker);
          context->matchmaker = NULL;
        }

      dbus_free (context->config_file);
      dbus_free (context->log_prefix);
      dbus_free (context->type);
      dbus_free (context->address);
      dbus_free (context->user);
      dbus_free (context->servicehelper);

      if (context->pidfile)
	{
          DBusString u;
          _dbus_string_init_const (&u, context->pidfile);

          /* Deliberately ignore errors here, since there's not much
	   * we can do about it, and we're exiting anyways.
	   */
	  _dbus_delete_file (&u, NULL);

          dbus_free (context->pidfile);
	}

      if (context->initial_fd_limit)
        _dbus_rlimit_free (context->initial_fd_limit);

      dbus_free (context);

      dbus_server_free_data_slot (&server_data_slot);
    }
}

/* type may be NULL */
const char*
bus_context_get_type (BusContext *context)
{
  return context->type;
}

const char*
bus_context_get_address (BusContext *context)
{
  return context->address;
}

const char*
bus_context_get_servicehelper (BusContext *context)
{
  return context->servicehelper;
}

dbus_bool_t
bus_context_get_systemd_activation (BusContext *context)
{
  return context->systemd_activation;
}

BusRegistry*
bus_context_get_registry (BusContext  *context)
{
  return context->registry;
}

BusConnections*
bus_context_get_connections (BusContext  *context)
{
  return context->connections;
}

BusActivation*
bus_context_get_activation (BusContext  *context)
{
  return context->activation;
}

BusMatchmaker*
bus_context_get_matchmaker (BusContext  *context)
{
  return context->matchmaker;
}

DBusLoop*
bus_context_get_loop (BusContext *context)
{
  return context->loop;
}

dbus_bool_t
bus_context_allow_unix_user (BusContext   *context,
                             unsigned long uid)
{
  return bus_policy_allow_unix_user (context->policy,
                                     uid);
}

/* For now this is never actually called because the default
 * DBusConnection behavior of 'same user that owns the bus can connect'
 * is all it would do.
 */
dbus_bool_t
bus_context_allow_windows_user (BusContext       *context,
                                const char       *windows_sid)
{
  return bus_policy_allow_windows_user (context->policy,
                                        windows_sid);
}

BusPolicy *
bus_context_get_policy (BusContext *context)
{
  return context->policy;
}

BusClientPolicy*
bus_context_create_client_policy (BusContext      *context,
                                  DBusConnection  *connection,
                                  DBusError       *error)
{
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  return bus_policy_create_client_policy (context->policy, connection,
                                          error);
}

int
bus_context_get_activation_timeout (BusContext *context)
{

  return context->limits.activation_timeout;
}

int
bus_context_get_auth_timeout (BusContext *context)
{
  return context->limits.auth_timeout;
}

int
bus_context_get_pending_fd_timeout (BusContext *context)
{
  return context->limits.pending_fd_timeout;
}

int
bus_context_get_max_completed_connections (BusContext *context)
{
  return context->limits.max_completed_connections;
}

int
bus_context_get_max_incomplete_connections (BusContext *context)
{
  return context->limits.max_incomplete_connections;
}

int
bus_context_get_max_connections_per_user (BusContext *context)
{
  return context->limits.max_connections_per_user;
}

int
bus_context_get_max_pending_activations (BusContext *context)
{
  return context->limits.max_pending_activations;
}

int
bus_context_get_max_services_per_connection (BusContext *context)
{
  return context->limits.max_services_per_connection;
}

int
bus_context_get_max_match_rules_per_connection (BusContext *context)
{
  return context->limits.max_match_rules_per_connection;
}

int
bus_context_get_max_replies_per_connection (BusContext *context)
{
  return context->limits.max_replies_per_connection;
}

int
bus_context_get_reply_timeout (BusContext *context)
{
  return context->limits.reply_timeout;
}

DBusRLimit *
bus_context_get_initial_fd_limit (BusContext *context)
{
  return context->initial_fd_limit;
}

void
bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...)
{
  va_list args;

  if (!context->syslog)
    {
      /* we're not syslogging; just output to stderr */
      va_start (args, msg);
      vfprintf (stderr, msg, args);
      fprintf (stderr, "\n");
      va_end (args);

      if (severity == DBUS_SYSTEM_LOG_FATAL)
        _dbus_exit (1);

      return;
    }

  va_start (args, msg);

  if (context->log_prefix)
    {
      DBusString full_msg;

      if (!_dbus_string_init (&full_msg))
        goto out;
      if (!_dbus_string_append (&full_msg, context->log_prefix))
        goto oom_out;
      if (!_dbus_string_append_printf_valist (&full_msg, msg, args))
        goto oom_out;

      _dbus_system_log (severity, "%s", _dbus_string_get_const_data (&full_msg));
    oom_out:
      _dbus_string_free (&full_msg);
    }
  else
    _dbus_system_logv (severity, msg, args);

out:
  va_end (args);
}

static inline const char *
nonnull (const char *maybe_null,
         const char *if_null)
{
  return (maybe_null ? maybe_null : if_null);
}

void
bus_context_log_literal (BusContext            *context,
                         DBusSystemLogSeverity  severity,
                         const char            *msg)
{
  if (!context->syslog)
    {
      fputs (msg, stderr);
      fputc ('\n', stderr);

      if (severity == DBUS_SYSTEM_LOG_FATAL)
        _dbus_exit (1);
    }
  else
    {
      _dbus_system_log (severity, "%s%s", nonnull (context->log_prefix, ""),
                        msg);
    }
}

void
bus_context_log_and_set_error (BusContext            *context,
                               DBusSystemLogSeverity  severity,
                               DBusError             *error,
                               const char            *name,
                               const char            *msg,
                               ...)
{
  DBusError stack_error = DBUS_ERROR_INIT;
  va_list args;

  va_start (args, msg);
  _dbus_set_error_valist (&stack_error, name, msg, args);
  va_end (args);

  /* If we hit OOM while setting the error, this will syslog "out of memory"
   * which is itself an indication that something is seriously wrong */
  bus_context_log_literal (context, DBUS_SYSTEM_LOG_SECURITY,
                           stack_error.message);

  dbus_move_error (&stack_error, error);
}

/*
 * Log something about a message, usually that it was rejected.
 */
static void
complain_about_message (BusContext     *context,
                        const char     *error_name,
                        const char     *complaint,
                        int             matched_rules,
                        DBusMessage    *message,
                        DBusConnection *sender,
                        DBusConnection *proposed_recipient,
                        dbus_bool_t     requested_reply,
                        dbus_bool_t     log,
                        DBusError      *error)
{
  DBusError stack_error = DBUS_ERROR_INIT;
  const char *sender_name;
  const char *sender_loginfo;
  const char *proposed_recipient_loginfo;

  if (error == NULL && !log)
    return;

  if (sender != NULL)
    {
      sender_name = bus_connection_get_name (sender);
      sender_loginfo = bus_connection_get_loginfo (sender);
    }
  else
    {
      sender_name = "(unset)";
      sender_loginfo = "(bus)";
    }

  if (proposed_recipient != NULL)
    proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient);
  else
    proposed_recipient_loginfo = "bus";

  dbus_set_error (&stack_error, error_name,
      "%s, %d matched rules; type=\"%s\", sender=\"%s\" (%s) "
      "interface=\"%s\" member=\"%s\" error name=\"%s\" "
      "requested_reply=\"%d\" destination=\"%s\" (%s)",
      complaint,
      matched_rules,
      dbus_message_type_to_string (dbus_message_get_type (message)),
      sender_name,
      sender_loginfo,
      nonnull (dbus_message_get_interface (message), "(unset)"),
      nonnull (dbus_message_get_member (message), "(unset)"),
      nonnull (dbus_message_get_error_name (message), "(unset)"),
      requested_reply,
      nonnull (dbus_message_get_destination (message), DBUS_SERVICE_DBUS),
      proposed_recipient_loginfo);

  /* If we hit OOM while setting the error, this will syslog "out of memory"
   * which is itself an indication that something is seriously wrong */
  if (log)
    bus_context_log_literal (context, DBUS_SYSTEM_LOG_SECURITY,
        stack_error.message);

  dbus_move_error (&stack_error, error);
}

/*
 * addressed_recipient is the recipient specified in the message.
 *
 * proposed_recipient is the recipient we're considering sending
 * to right this second, and may be an eavesdropper.
 *
 * sender is the sender of the message.
 *
 * NULL for proposed_recipient or sender definitely means the bus driver.
 *
 * NULL for addressed_recipient may mean the bus driver, or may mean
 * no destination was specified in the message (e.g. a signal).
 */
dbus_bool_t
bus_context_check_security_policy (BusContext     *context,
                                   BusTransaction *transaction,
                                   DBusConnection *sender,
                                   DBusConnection *addressed_recipient,
                                   DBusConnection *proposed_recipient,
                                   DBusMessage    *message,
                                   DBusError      *error)
{
  const char *src, *dest;
  BusClientPolicy *sender_policy;
  BusClientPolicy *recipient_policy;
  dbus_int32_t toggles;
  dbus_bool_t log;
  int type;
  dbus_bool_t requested_reply;

  type = dbus_message_get_type (message);
  src = dbus_message_get_sender (message);
  dest = dbus_message_get_destination (message);

  /* dispatch.c was supposed to ensure these invariants */
  _dbus_assert (dest != NULL ||
                type == DBUS_MESSAGE_TYPE_SIGNAL ||
                (sender == NULL && !bus_connection_is_active (proposed_recipient)));
  _dbus_assert (type == DBUS_MESSAGE_TYPE_SIGNAL ||
                addressed_recipient != NULL ||
                strcmp (dest, DBUS_SERVICE_DBUS) == 0);

  switch (type)
    {
    case DBUS_MESSAGE_TYPE_METHOD_CALL:
    case DBUS_MESSAGE_TYPE_SIGNAL:
    case DBUS_MESSAGE_TYPE_METHOD_RETURN:
    case DBUS_MESSAGE_TYPE_ERROR:
      break;

    default:
      _dbus_verbose ("security check disallowing message of unknown type %d\n",
                     type);

      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
                      "Message bus will not accept messages of unknown type\n");

      return FALSE;
    }

  requested_reply = FALSE;

  if (sender != NULL)
    {
      if (bus_connection_is_active (sender))
        {
          sender_policy = bus_connection_get_policy (sender);
          _dbus_assert (sender_policy != NULL);

          /* Fill in requested_reply variable with TRUE if this is a
           * reply and the reply was pending.
           */
          if (dbus_message_get_reply_serial (message) != 0)
            {
              if (proposed_recipient != NULL /* not to the bus driver */ &&
                  addressed_recipient == proposed_recipient /* not eavesdropping */)
                {
                  DBusError error2;

                  dbus_error_init (&error2);
                  requested_reply = bus_connections_check_reply (bus_connection_get_connections (sender),
                                                                 transaction,
                                                                 sender, addressed_recipient, message,
                                                                 &error2);
                  if (dbus_error_is_set (&error2))
                    {
                      dbus_move_error (&error2, error);
                      return FALSE;
                    }
                }
            }
        }
      else
        {
          sender_policy = NULL;
        }

      /* First verify the SELinux access controls.  If allowed then
       * go on with the standard checks.
       */
      if (!bus_selinux_allows_send (sender, proposed_recipient,
				    dbus_message_type_to_string (dbus_message_get_type (message)),
				    dbus_message_get_interface (message),
				    dbus_message_get_member (message),
				    dbus_message_get_error_name (message),
				    dest ? dest : DBUS_SERVICE_DBUS, error))
        {
          if (error != NULL && !dbus_error_is_set (error))
            {
              /* don't syslog this, just set the error: avc_has_perm should
               * have already written to either the audit log or syslog */
              complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
                  "An SELinux policy prevents this sender from sending this "
                  "message to this recipient",
                  0, message, sender, proposed_recipient, FALSE, FALSE, error);
              _dbus_verbose ("SELinux security check denying send to service\n");
            }

          return FALSE;
        }

      /* next verify AppArmor access controls.  If allowed then
       * go on with the standard checks.
       */
      if (!bus_apparmor_allows_send (sender, proposed_recipient,
                                     requested_reply,
                                     bus_context_get_type (context),
                                     dbus_message_get_type (message),
                                     dbus_message_get_path (message),
                                     dbus_message_get_interface (message),
                                     dbus_message_get_member (message),
                                     dbus_message_get_error_name (message),
                                     dest ? dest : DBUS_SERVICE_DBUS,
                                     src ? src : DBUS_SERVICE_DBUS,
                                     error))
        return FALSE;

      if (!bus_connection_is_active (sender))
        {
          /* Policy for inactive connections is that they can only send
           * the hello message to the bus driver
           */
          if (proposed_recipient == NULL &&
              dbus_message_is_method_call (message,
                                           DBUS_INTERFACE_DBUS,
                                           "Hello"))
            {
              _dbus_verbose ("security check allowing %s message\n",
                             "Hello");
              return TRUE;
            }
          else
            {
              _dbus_verbose ("security check disallowing non-%s message\n",
                             "Hello");

              dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
                              "Client tried to send a message other than %s without being registered",
                              "Hello");

              return FALSE;
            }
        }
    }
  else
    {
      sender_policy = NULL;

      /* If the sender is the bus driver, we assume any reply was a
       * requested reply as bus driver won't send bogus ones
       */
      if (addressed_recipient == proposed_recipient /* not eavesdropping */ &&
          dbus_message_get_reply_serial (message) != 0)
        requested_reply = TRUE;
    }

  _dbus_assert ((sender != NULL && sender_policy != NULL) ||
                (sender == NULL && sender_policy == NULL));

  if (proposed_recipient != NULL)
    {
      /* only the bus driver can send to an inactive recipient (as it
       * owns no services, so other apps can't address it). Inactive
       * recipients can receive any message.
       */
      if (bus_connection_is_active (proposed_recipient))
        {
          recipient_policy = bus_connection_get_policy (proposed_recipient);
          _dbus_assert (recipient_policy != NULL);
        }
      else if (sender == NULL)
        {
          _dbus_verbose ("security check using NULL recipient policy for message from bus\n");
          recipient_policy = NULL;
        }
      else
        {
          _dbus_assert_not_reached ("a message was somehow sent to an inactive recipient from a source other than the message bus\n");
          recipient_policy = NULL;
        }
    }
  else
    recipient_policy = NULL;

  _dbus_assert ((proposed_recipient != NULL && recipient_policy != NULL) ||
                (proposed_recipient != NULL && sender == NULL && recipient_policy == NULL) ||
                (proposed_recipient == NULL && recipient_policy == NULL));

  log = FALSE;
  if (sender_policy &&
      !bus_client_policy_check_can_send (sender_policy,
                                         context->registry,
                                         requested_reply,
                                         proposed_recipient,
                                         message, &toggles, &log))
    {
      complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
          "Rejected send message", toggles,
          message, sender, proposed_recipient, requested_reply,
          (addressed_recipient == proposed_recipient), error);
      _dbus_verbose ("security policy disallowing message due to sender policy\n");
      return FALSE;
    }

  if (log)
    {
      /* We want to drop this message, and are only not doing so for backwards
       * compatibility. */
      complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
          "Would reject message", toggles,
          message, sender, proposed_recipient, requested_reply,
          TRUE, NULL);
    }

  if (recipient_policy &&
      !bus_client_policy_check_can_receive (recipient_policy,
                                            context->registry,
                                            requested_reply,
                                            sender,
                                            addressed_recipient, proposed_recipient,
                                            message, &toggles))
    {
      complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
          "Rejected receive message", toggles,
          message, sender, proposed_recipient, requested_reply,
          (addressed_recipient == proposed_recipient), error);
      _dbus_verbose ("security policy disallowing message due to recipient policy\n");
      return FALSE;
    }

  /* See if limits on size have been exceeded */
  if (proposed_recipient &&
      ((dbus_connection_get_outgoing_size (proposed_recipient) > context->limits.max_outgoing_bytes) ||
       (dbus_connection_get_outgoing_unix_fds (proposed_recipient) > context->limits.max_outgoing_unix_fds)))
    {
      complain_about_message (context, DBUS_ERROR_LIMITS_EXCEEDED,
          "Rejected: destination has a full message queue",
          0, message, sender, proposed_recipient, requested_reply, TRUE,
          error);
      _dbus_verbose ("security policy disallowing message due to full message queue\n");
      return FALSE;
    }

  /* Record that we will allow a reply here in the future (don't
   * bother if the recipient is the bus or this is an eavesdropping
   * connection). Only the addressed recipient may reply.
   */
  if (type == DBUS_MESSAGE_TYPE_METHOD_CALL &&
      sender &&
      addressed_recipient &&
      addressed_recipient == proposed_recipient && /* not eavesdropping */
      !bus_connections_expect_reply (bus_connection_get_connections (sender),
                                     transaction,
                                     sender, addressed_recipient,
                                     message, error))
    {
      _dbus_verbose ("Failed to record reply expectation or problem with the message expecting a reply\n");
      return FALSE;
    }

  _dbus_verbose ("security policy allowing message\n");
  return TRUE;
}

void
bus_context_check_all_watches (BusContext *context)
{
  DBusList *link;
  dbus_bool_t enabled = TRUE;

  if (bus_connections_get_n_incomplete (context->connections) >=
      bus_context_get_max_incomplete_connections (context))
    {
      enabled = FALSE;
    }

  if (context->watches_enabled == enabled)
    return;

  context->watches_enabled = enabled;

  for (link = _dbus_list_get_first_link (&context->servers);
       link != NULL;
       link = _dbus_list_get_next_link (&context->servers, link))
    {
      /* A BusContext might contains several DBusServer (if there are
       * several <listen> configuration items) and a DBusServer might
       * contain several DBusWatch in its DBusWatchList (if getaddrinfo
       * returns several addresses on a dual IPv4-IPv6 stack or if
       * systemd passes several fds).
       * We want to enable/disable them all.
       */
      DBusServer *server = link->data;
      _dbus_server_toggle_all_watches (server, enabled);
    }
}
