diff options
author | Colin Walters <walters@verbum.org> | 2004-11-07 17:05:19 +0000 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2004-11-07 17:05:19 +0000 |
commit | cdac3e058b922431f387351fd8ebf60a764485d1 (patch) | |
tree | a92b8fa08c2657b6339d9590be5309ff627d1512 | |
parent | a14c43cf3ab7a2636146410e52be5e421fc0aaf9 (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.
-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); |