Commit cdac3e05 authored by Colin Walters's avatar Colin Walters

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.
parent a14c43cf
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
......
......@@ -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 */
......@@ -241,13 +241,40 @@ top_element_type (BusConfigParser *parser)
return ELEMENT_NONE;
}
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;
}
......
......@@ -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);
......
......@@ -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;
}
......@@ -656,88 +660,6 @@ bus_selinux_id_table_lookup (DBusHashTable *service_table,
return NULL;
}
/**
* 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.
......
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment