summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2004-11-07 17:05:19 +0000
committerColin Walters <walters@verbum.org>2004-11-07 17:05:19 +0000
commitcdac3e058b922431f387351fd8ebf60a764485d1 (patch)
treea92b8fa08c2657b6339d9590be5309ff627d1512 /bus
parenta14c43cf3ab7a2636146410e52be5e421fc0aaf9 (diff)
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.
Diffstat (limited to 'bus')
-rw-r--r--bus/bus.c117
-rw-r--r--bus/config-parser.c68
-rw-r--r--bus/config-parser.h2
-rw-r--r--bus/main.c6
-rw-r--r--bus/selinux.c96
-rw-r--r--bus/selinux.h2
-rw-r--r--bus/services.c30
-rw-r--r--bus/services.h4
8 files changed, 158 insertions, 167 deletions
diff --git a/bus/bus.c b/bus/bus.c
index b34e635c..65e396c3 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -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.
diff --git a/bus/main.c b/bus/main.c
index 296aa63c..40ec9a07 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -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);