/* -*- 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 "dir-watch.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-credentials.h>
#include <dbus/dbus-internals.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;
  unsigned int fork : 1;
  unsigned int syslog : 1;
  unsigned int keep_umask : 1;
  unsigned int allow_anonymous : 1;
  unsigned int systemd_activation : 1;
};

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
server_watch_callback (DBusWatch     *watch,
                       unsigned int   condition,
                       void          *data)
{
  /* FIXME this can be done in dbus-mainloop.c
   * if the code in activation.c for the babysitter
   * watch handler is fixed.
   */

  return dbus_watch_handle (watch, condition);
}

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, server_watch_callback, server,
                               NULL);
}

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, server_watch_callback, server);
}


static void
server_timeout_callback (DBusTimeout   *timeout,
                         void          *data)
{
  /* can return FALSE on OOM but we just let it fire again later */
  dbus_timeout_handle (timeout);
}

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, server_timeout_callback, server, NULL);
}

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, server_timeout_callback, server);
}

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,
                                        NULL,
                                        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,
                                dbus_bool_t      systemd_activation,
				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;

  _dbus_init_system_log ();

  context->systemd_activation = systemd_activation;

  /* 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.
   */
  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);
        }
    }
  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;
  BusActivation *new_activation;
  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);

  /* 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)
{

  /* I just picked this out of thin air; we need some extra
   * descriptors for things like any internal pipes we create,
   * inotify, connections to SELinux, etc.
   */
  unsigned int arbitrary_extra_fds = 32;
  unsigned int limit;

  limit = context->limits.max_completed_connections +
    context->limits.max_incomplete_connections
    + arbitrary_extra_fds;

  _dbus_request_file_descriptor_limit (limit);
}

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,
                 ForceForkSetting  force_fork,
                 DBusPipe         *print_addr_pipe,
                 DBusPipe         *print_pid_pipe,
                 const DBusString *address,
                 dbus_bool_t      systemd_activation,
                 DBusError        *error)
{
  DBusString log_prefix;
  BusContext *context;
  BusConfigParser *parser;

  _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;

  _dbus_generate_uuid (&context->uuid);

  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->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, systemd_activation, 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 ((force_fork != FORK_NEVER && context->fork) || force_fork == 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 AVC initialization failed; check system log\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;
	}

#ifdef HAVE_SELINUX
      /* FIXME - why not just put this in full_init() below? */
      bus_selinux_audit_init ();
#endif
    }

  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);
	}
      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_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;
}

void
bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (3, 4);

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);
      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);
}

/*
 * 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 (context, DBUS_SYSTEM_LOG_SECURITY, "%s",
        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 *dest;
  BusClientPolicy *sender_policy;
  BusClientPolicy *recipient_policy;
  dbus_int32_t toggles;
  dbus_bool_t log;
  int type;
  dbus_bool_t requested_reply;
  const char *sender_name;
  const char *sender_loginfo;
  const char *proposed_recipient_loginfo;

  type = dbus_message_get_type (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)
    {
      /* 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;
        }

      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
        {
          /* 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))
    {
      const char *msg = "Rejected send message, %d matched rules; "
                        "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))";

      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), NULL);
      _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;
}
