2004-11-07 Colin Walters <walters@verbum.org>
authorColin Walters <walters@verbum.org>
Sun, 7 Nov 2004 17:05:19 +0000 (17:05 +0000)
committerColin Walters <walters@verbum.org>
Sun, 7 Nov 2004 17:05:19 +0000 (17:05 +0000)
* 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.

ChangeLog
bus/bus.c
bus/config-parser.c
bus/config-parser.h
bus/main.c
bus/selinux.c
bus/selinux.h
bus/services.c
bus/services.h

index 1d16a35..872e7cb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index b34e635..65e396c 100644 (file)
--- 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
index ba1a434..074c621 100644 (file)
@@ -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;
 }
index 7500400..388704d 100644 (file)
@@ -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.
index 296aa63..40ec9a0 100644 (file)
@@ -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);
index 2ddbed7..0a3dec7 100644 (file)
@@ -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.
  */
index 1312252..71271fa 100644 (file)
@@ -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);
 
index fb27ea0..31041c3 100644 (file)
@@ -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
index e411aec..f075404 100644 (file)
@@ -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);