diff options
| -rw-r--r-- | ChangeLog | 41 | ||||
| -rw-r--r-- | bus/bus.c | 117 | ||||
| -rw-r--r-- | bus/config-parser.c | 68 | ||||
| -rw-r--r-- | bus/config-parser.h | 2 | ||||
| -rw-r--r-- | bus/main.c | 6 | ||||
| -rw-r--r-- | bus/selinux.c | 96 | ||||
| -rw-r--r-- | bus/selinux.h | 2 | ||||
| -rw-r--r-- | bus/services.c | 30 | ||||
| -rw-r--r-- | bus/services.h | 4 | 
9 files changed, 199 insertions, 167 deletions
@@ -1,3 +1,44 @@ +2004-11-07  Colin Walters  <walters@verbum.org> + +	* bus/bus.c (load_config): Break into three +	separate functions: process_config_first_time_only, +	process_config_every_time, and process_config_postinit. +	(process_config_every_time): Move call of +	bus_registry_set_service_context_table into +	process_config_postinit. +	(process_config_postinit): New function, does +	any processing that needs to happen late +	in initialization (and also on reload). +	(bus_context_new): Instead of calling load_config, +	open config parser here and call process_config_first_time_only +	and process_config_every_time directly.  Later, after +	we have forked but before changing UID, +	invoke bus_selinux_full_init, and then call +	process_config_postinit. +	(bus_context_reload_config): As in bus_context_new, +	load parse file inside here, and call process_config_every_time +	and process_config_postinit. + +	* bus/services.h, bus/services.c +	(bus_registry_set_service_context_table): Rename +	from bus_registry_set_sid_table.  Take string hash from config +	parser, and convert them here into SIDs. + +	* bus/config-parser.c (struct BusConfigParser): Have +	config parser only store a mapping of service->context +	string. +	(merge_service_context_hash): New function. +	(merge_included): Merge context string hashes instead +	of using bus_selinux_id_table_union. +	(bus_config_parser_new): Don't use bus_selinux_id_table_new; +	simply create a new string hash. +	(bus_config_parser_unref): Unref it. +	(start_selinux_child): Simply insert strings into hash, +	don't call bus_selinux_id_table_copy_over. + +	* bus/selinux.h, bus/selinux.c (bus_selinux_id_table_union) +	(bus_selinux_id_table_copy_over): Delete. +  2004-11-03  Colin Walters  <walters@verbum.org>  	* bus/selinux.c (bus_selinux_pre_init): Kill some unused @@ -401,7 +401,6 @@ process_config_every_time (BusContext      *context,  {    DBusString full_address;    DBusList *link; -  DBusHashTable *service_sid_table;    dbus_bool_t retval; @@ -479,11 +478,6 @@ process_config_every_time (BusContext      *context,        goto failed;      } -  service_sid_table = bus_config_parser_steal_service_sid_table (parser); -  bus_registry_set_service_sid_table (context->registry, -                                      service_sid_table); -  _dbus_hash_table_unref (service_sid_table); -      _DBUS_ASSERT_ERROR_IS_CLEAR (error);    retval = TRUE; @@ -493,46 +487,22 @@ process_config_every_time (BusContext      *context,  }  static dbus_bool_t -load_config (BusContext *context, -	     dbus_bool_t is_reload, -	     DBusError  *error) +process_config_postinit (BusContext *context, +			 BusConfigParser *parser, +			 DBusError *error)  { -  BusConfigParser *parser; -  DBusString config_file; -  dbus_bool_t retval; - -  _DBUS_ASSERT_ERROR_IS_CLEAR (error); +  DBusHashTable *service_context_table; -  retval = FALSE; -  parser = NULL; - -  _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 (!is_reload && !process_config_first_time_only (context, parser, error)) +  service_context_table = bus_config_parser_steal_service_context_table (parser); +  if (!bus_registry_set_service_context_table (context->registry, +					       service_context_table))      { -      _DBUS_ASSERT_ERROR_IS_SET (error); -      goto failed; -    } - -  if (!process_config_every_time (context, parser, is_reload, error)) -    { -      _DBUS_ASSERT_ERROR_IS_SET (error); -      goto failed; +      BUS_SET_OOM (error); +      return FALSE;      } -  _DBUS_ASSERT_ERROR_IS_CLEAR (error); -  retval = TRUE; - - failed: -  if (parser) -    bus_config_parser_unref (parser); -  return retval; +  _dbus_hash_table_unref (service_context_table); +  return TRUE;  }  BusContext* @@ -543,9 +513,13 @@ bus_context_new (const DBusString *config_file,                   DBusError        *error)  {    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); @@ -579,8 +553,20 @@ bus_context_new (const DBusString *config_file,        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 (!load_config (context, FALSE, error)) +  if (!process_config_first_time_only (context, parser, 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; @@ -723,6 +709,19 @@ bus_context_new (const DBusString *config_file,        _dbus_string_free (&pid);      } + +  if (!bus_selinux_full_init ()) +    { +      _dbus_warn ("SELinux initialization failed\n"); +    } + +  if (!process_config_postinit (context, parser, error)) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      goto failed; +    } +  if (parser != NULL) +    bus_config_parser_unref (parser);    /* Here we change our credentials if required,     * as soon as we've set up our sockets and pidfile @@ -756,6 +755,8 @@ bus_context_new (const DBusString *config_file,    return context;   failed:   +  if (parser != NULL) +    bus_config_parser_unref (parser);    if (context != NULL)      bus_context_unref (context); @@ -769,9 +770,35 @@ dbus_bool_t  bus_context_reload_config (BusContext *context,  			   DBusError  *error)  { -  return load_config (context, -		      TRUE, /* yes, we are re-loading */ -		      error); +  BusConfigParser *parser; +  DBusString config_file; +  dbus_bool_t ret; + +  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; + + failed:   +  if (parser != NULL) +    bus_config_parser_unref (parser); +  return ret;  }  static void diff --git a/bus/config-parser.c b/bus/config-parser.c index ba1a434d..074c6218 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -123,7 +123,7 @@ struct BusConfigParser    DBusList *included_files;  /**< Included files stack */ -  DBusHashTable *service_sid_table; /**< Map service names to SELinux contexts */ +  DBusHashTable *service_context_table; /**< Map service names to SELinux contexts */    unsigned int fork : 1; /**< TRUE to fork into daemon mode */ @@ -242,12 +242,39 @@ top_element_type (BusConfigParser *parser)  }  static dbus_bool_t +merge_service_context_hash (DBusHashTable *dest, +			    DBusHashTable *from) +{ +  DBusHashIter iter; +   +  _dbus_hash_iter_init (from, &iter); +  while (_dbus_hash_iter_next (&iter)) +    { +      const char *service = _dbus_hash_iter_get_string_key (&iter); +      const char *context = _dbus_hash_iter_get_value (&iter); +      char *service_copy; +      char *context_copy; + +      service_copy = _dbus_strdup (service); +      if (service_copy == NULL) +        return FALSE; +      context_copy = _dbus_strdup (context); +      if (context_copy == NULL) +        return FALSE; +       +      if (!_dbus_hash_table_insert_string (dest, service_copy, context_copy)) +	return FALSE; +    } + +  return TRUE; +} + +static dbus_bool_t  merge_included (BusConfigParser *parser,                  BusConfigParser *included,                  DBusError       *error)  {    DBusList *link; -  DBusHashTable *table;    if (!bus_policy_merge (parser->policy,                           included->policy)) @@ -256,16 +283,12 @@ merge_included (BusConfigParser *parser,        return FALSE;      } -  table = bus_selinux_id_table_union (parser->service_sid_table, -                                      included->service_sid_table); -  if (table == NULL) +  if (!merge_service_context_hash (parser->service_context_table, +				   included->service_context_table))      {        BUS_SET_OOM (error);        return FALSE;      } - -  _dbus_hash_table_unref (parser->service_sid_table); -  parser->service_sid_table = table;    if (included->user != NULL)      { @@ -342,7 +365,9 @@ bus_config_parser_new (const DBusString      *basedir,    if (((parser->policy = bus_policy_new ()) == NULL) ||        !_dbus_string_copy (basedir, 0, &parser->basedir, 0) || -      ((parser->service_sid_table = bus_selinux_id_table_new ()) == NULL)) +      ((parser->service_context_table = _dbus_hash_table_new (DBUS_HASH_STRING, +							      dbus_free, +							      dbus_free)) == NULL))      {        if (parser->policy)          bus_policy_unref (parser->policy); @@ -454,8 +479,8 @@ bus_config_parser_unref (BusConfigParser *parser)        if (parser->policy)          bus_policy_unref (parser->policy); -      if (parser->service_sid_table) -        _dbus_hash_table_unref (parser->service_sid_table); +      if (parser->service_context_table) +        _dbus_hash_table_unref (parser->service_context_table);        dbus_free (parser);      } @@ -1510,6 +1535,8 @@ start_selinux_child (BusConfigParser   *parser,      {        const char *own;        const char *context; +      char *own_copy; +      char *context_copy;        if (!locate_attributes (parser, "associate",                                attribute_names, @@ -1533,8 +1560,15 @@ start_selinux_child (BusConfigParser   *parser,            return FALSE;          } -      if (!bus_selinux_id_table_insert (parser->service_sid_table, -                                        own, context)) +      own_copy = _dbus_strdup (own); +      if (own_copy == NULL) +        return FALSE; +      context_copy = _dbus_strdup (context); +      if (context_copy == NULL) +        return FALSE; + +      if (!_dbus_hash_table_insert_string (parser->service_context_table, +					   own_copy, context_copy))          {            BUS_SET_OOM (error);            return FALSE; @@ -2359,15 +2393,15 @@ bus_config_parser_get_limits (BusConfigParser *parser,  }  DBusHashTable* -bus_config_parser_steal_service_sid_table (BusConfigParser *parser) +bus_config_parser_steal_service_context_table (BusConfigParser *parser)  {    DBusHashTable *table; -  _dbus_assert (parser->service_sid_table != NULL); /* can only steal once */ +  _dbus_assert (parser->service_context_table != NULL); /* can only steal once */ -  table = parser->service_sid_table; +  table = parser->service_context_table; -  parser->service_sid_table = NULL; +  parser->service_context_table = NULL;    return table;  } diff --git a/bus/config-parser.h b/bus/config-parser.h index 75004000..388704db 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -71,7 +71,7 @@ BusPolicy*  bus_config_parser_steal_policy     (BusConfigParser *parser);  void        bus_config_parser_get_limits       (BusConfigParser *parser,                                                  BusLimits       *limits); -DBusHashTable* bus_config_parser_steal_service_sid_table (BusConfigParser *parser); +DBusHashTable* bus_config_parser_steal_service_context_table (BusConfigParser *parser);  /* Loader functions (backended off one of the XML parsers).  Returns a   * finished ConfigParser. @@ -396,12 +396,6 @@ main (int argc, char **argv)        exit (1);      } -  if (!bus_selinux_full_init ()) -    { -      _dbus_warn ("SELinux initialization failed\n"); -      exit (1); -    } -    setup_reload_pipe (bus_context_get_loop (context));    _dbus_set_signal_handler (SIGHUP, signal_handler); diff --git a/bus/selinux.c b/bus/selinux.c index 2ddbed71..0a3dec70 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -504,11 +504,11 @@ bus_selinux_init_connection_id (DBusConnection *connection,          BUS_SET_OOM (error);        else          dbus_set_error (error, DBUS_ERROR_FAILED, -                        "Error getting SID from context: %s\n", -                        _dbus_strerror (errno)); +                        "Error getting SID from context \"%s\": %s\n", +			con, _dbus_strerror (errno)); -      _dbus_warn ("Error getting SID from context: %s\n", -                  _dbus_strerror (errno)); +      _dbus_warn ("Error getting SID from context \"%s\": %s\n", +		  con, _dbus_strerror (errno));        freecon (con);        return NULL; @@ -582,7 +582,11 @@ bus_selinux_id_table_insert (DBusHashTable *service_table,    if (avc_context_to_sid ((char *) service_context, &sid) < 0)      { -      _dbus_assert (errno == ENOMEM); +      if (errno == ENOMEM) +        return FALSE; +      _dbus_warn ("Error getting SID from context \"%s\": %s\n", +		  (char *) service_context, +                  _dbus_strerror (errno));        goto out;      } @@ -657,88 +661,6 @@ bus_selinux_id_table_lookup (DBusHashTable    *service_table,  }  /** - * Copy security ID table mapping from one table into another. - * - * @param dest the table to copy into - * @param override the table to copy from - * @returns #FALSE if out of memory - */ -#ifdef HAVE_SELINUX -static dbus_bool_t -bus_selinux_id_table_copy_over (DBusHashTable    *dest, -                                DBusHashTable    *override) -{ -  const char *key; -  char *key_copy; -  BusSELinuxID *sid; -  DBusHashIter iter; -   -  _dbus_hash_iter_init (override, &iter); -  while (_dbus_hash_iter_next (&iter)) -    { -      key = _dbus_hash_iter_get_string_key (&iter); -      sid = _dbus_hash_iter_get_value (&iter); - -      key_copy = _dbus_strdup (key); -      if (key_copy == NULL) -        return FALSE; - -      if (!_dbus_hash_table_insert_string (dest, -                                           key_copy, -                                           sid)) -        { -          dbus_free (key_copy); -          return FALSE; -        } - -      bus_selinux_id_ref (sid); -    } - -  return TRUE; -} -#endif /* HAVE_SELINUX */ - -/** - * Creates the union of the two tables (each table maps a service - * name to a security ID). In case of the same service name in - * both tables, the security ID from "override" will be used. - * - * @param base the base table - * @param override the table that takes precedence in the merge - * @returns the new table, or #NULL if out of memory - */ -DBusHashTable* -bus_selinux_id_table_union (DBusHashTable    *base, -                            DBusHashTable    *override) -{ -  DBusHashTable *combined_table; - -  combined_table = bus_selinux_id_table_new (); - -  if (combined_table == NULL) -    return NULL; -   -#ifdef HAVE_SELINUX  -  if (!selinux_enabled) -    return combined_table; - -  if (!bus_selinux_id_table_copy_over (combined_table, base)) -    { -      _dbus_hash_table_unref (combined_table); -      return NULL; -    } - -  if (!bus_selinux_id_table_copy_over (combined_table, override)) -    { -      _dbus_hash_table_unref (combined_table); -      return NULL; -    } -#endif /* HAVE_SELINUX */ -   -  return combined_table; -} - -/**   * Get the SELinux policy root.  This is used to find the D-BUS   * specific config file within the policy.   */ diff --git a/bus/selinux.h b/bus/selinux.h index 13122520..71271fab 100644 --- a/bus/selinux.h +++ b/bus/selinux.h @@ -42,8 +42,6 @@ BusSELinuxID*  bus_selinux_id_table_lookup (DBusHashTable    *service_table,  dbus_bool_t    bus_selinux_id_table_insert (DBusHashTable    *service_table,                                              const char       *service_name,                                              const char       *service_context); -DBusHashTable* bus_selinux_id_table_union  (DBusHashTable    *base, -                                            DBusHashTable    *override);  void           bus_selinux_id_table_print  (DBusHashTable    *service_table);  const char*    bus_selinux_get_policy_root (void); diff --git a/bus/services.c b/bus/services.c index fb27ea0f..31041c37 100644 --- a/bus/services.c +++ b/bus/services.c @@ -417,17 +417,33 @@ bus_registry_acquire_service (BusRegistry      *registry,    return retval;  } -void -bus_registry_set_service_sid_table (BusRegistry   *registry, -                                    DBusHashTable *table) +dbus_bool_t +bus_registry_set_service_context_table (BusRegistry   *registry, +					DBusHashTable *table)  { -  _dbus_assert (registry->service_sid_table != table); +  DBusHashTable *new_table; +  DBusHashIter iter; +   +  new_table = bus_selinux_id_table_new (); +  if (!new_table) +    return FALSE; + +  _dbus_hash_iter_init (table, &iter); +  while (_dbus_hash_iter_next (&iter)) +    { +      const char *service = _dbus_hash_iter_get_string_key (&iter); +      const char *context = _dbus_hash_iter_get_value (&iter); + +      if (!bus_selinux_id_table_insert (new_table, +					service, +					context)) +	return FALSE; +    }    if (registry->service_sid_table)      _dbus_hash_table_unref (registry->service_sid_table); - -  registry->service_sid_table = table; -  _dbus_hash_table_ref (table); +  registry->service_sid_table = new_table; +  return TRUE;  }  static void diff --git a/bus/services.h b/bus/services.h index e411aecc..f0754043 100644 --- a/bus/services.h +++ b/bus/services.h @@ -56,8 +56,8 @@ dbus_bool_t  bus_registry_acquire_service (BusRegistry                 *registry                                             dbus_uint32_t               *result,                                             BusTransaction              *transaction,                                             DBusError                   *error); -void         bus_registry_set_service_sid_table (BusRegistry           *registry, -                                                 DBusHashTable         *table); +dbus_bool_t  bus_registry_set_service_context_table (BusRegistry           *registry, +						     DBusHashTable         *table);  BusService*     bus_service_ref                      (BusService     *service);  void            bus_service_unref                    (BusService     *service);  | 
