dbus-daemon: prepare activation for async security checks 05/193005/2
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 7 Nov 2018 10:26:11 +0000 (11:26 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Thu, 15 Nov 2018 03:18:32 +0000 (03:18 +0000)
This commit prepares activation function (bus_activation_acivate_service())
for returning BUS_RESULT_LATER from security check introduced
in next commits.

Change-Id: I5b37d06fc5f7e563d52ed7207b5e416bedd666e6

bus/activation.c
bus/activation.h
bus/dispatch.c
bus/driver.c

index b29cc2d..6d8a7c7 100644 (file)
@@ -1765,14 +1765,15 @@ child_setup (void *user_data)
 }
 
 
-dbus_bool_t
+BusResult
 bus_activation_activate_service (BusActivation  *activation,
                                  DBusConnection *connection,
                                  BusTransaction *transaction,
                                  dbus_bool_t     auto_activation,
                                  DBusMessage    *activation_message,
                                  const char     *service_name,
-                                 DBusError      *error)
+                                 DBusError      *error,
+                                 BusDeferredMessage **deferred_message)
 {
   DBusError tmp_error;
   BusActivationEntry *entry;
@@ -1784,7 +1785,7 @@ bus_activation_activate_service (BusActivation  *activation,
   char **argv;
   char **envp = NULL;
   int argc;
-  dbus_bool_t retval = FALSE;
+  BusResult retval = BUS_RESULT_FALSE;
   dbus_bool_t was_pending_activation;
   DBusString command;
 
@@ -1796,12 +1797,12 @@ bus_activation_activate_service (BusActivation  *activation,
       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                       "The maximum number of pending activations has been reached, activation of %s failed",
                       service_name);
-      return FALSE;
+      return BUS_RESULT_FALSE;
     }
 
   entry = activation_find_entry (activation, service_name, error);
   if (!entry)
-    return FALSE;
+    return BUS_RESULT_FALSE;
 
   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
    * call us if the service is already active.
@@ -1813,6 +1814,7 @@ bus_activation_activate_service (BusActivation  *activation,
       if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
         {
           dbus_uint32_t result;
+          dbus_bool_t send_retval;
 
           _dbus_verbose ("Service \"%s\" is already active\n", service_name);
 
@@ -1822,7 +1824,7 @@ bus_activation_activate_service (BusActivation  *activation,
             {
               _dbus_verbose ("No memory to create reply to activate message\n");
               BUS_SET_OOM (error);
-              return FALSE;
+              return BUS_RESULT_FALSE;
             }
 
           result = DBUS_START_REPLY_ALREADY_RUNNING;
@@ -1834,18 +1836,19 @@ bus_activation_activate_service (BusActivation  *activation,
               _dbus_verbose ("No memory to set args of reply to activate message\n");
               BUS_SET_OOM (error);
               dbus_message_unref (message);
-              return FALSE;
+              return BUS_RESULT_FALSE;
             }
 
-          retval = bus_transaction_send_from_driver (transaction, connection, message);
+          send_retval = bus_transaction_send_from_driver (transaction, connection, message);
           dbus_message_unref (message);
-          if (!retval)
+          if (!send_retval)
             {
               _dbus_verbose ("Failed to send reply\n");
               BUS_SET_OOM (error);
+              return BUS_RESULT_FALSE;
             }
 
-          return retval;
+          return BUS_RESULT_TRUE;
         }
     }
 
@@ -1854,7 +1857,7 @@ bus_activation_activate_service (BusActivation  *activation,
     {
       _dbus_verbose ("Failed to create pending activation entry\n");
       BUS_SET_OOM (error);
-      return FALSE;
+      return BUS_RESULT_FALSE;
     }
 
   pending_activation_entry->auto_activation = auto_activation;
@@ -1876,7 +1879,7 @@ bus_activation_activate_service (BusActivation  *activation,
 
           BUS_SET_OOM (error);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       pending_activation->n_entries += 1;
@@ -1891,7 +1894,7 @@ bus_activation_activate_service (BusActivation  *activation,
 
           BUS_SET_OOM (error);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       pending_activation->activation = activation;
@@ -1905,7 +1908,7 @@ bus_activation_activate_service (BusActivation  *activation,
           BUS_SET_OOM (error);
           bus_pending_activation_unref (pending_activation);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       pending_activation->exec = _dbus_strdup (entry->exec);
@@ -1927,7 +1930,7 @@ bus_activation_activate_service (BusActivation  *activation,
               BUS_SET_OOM (error);
               bus_pending_activation_unref (pending_activation);
               bus_pending_activation_entry_free (pending_activation_entry);
-              return FALSE;
+              return BUS_RESULT_FALSE;
             }
         }
 
@@ -1943,7 +1946,7 @@ bus_activation_activate_service (BusActivation  *activation,
           BUS_SET_OOM (error);
           bus_pending_activation_unref (pending_activation);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
@@ -1954,7 +1957,7 @@ bus_activation_activate_service (BusActivation  *activation,
           BUS_SET_OOM (error);
           bus_pending_activation_unref (pending_activation);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       pending_activation->timeout_added = TRUE;
@@ -1966,7 +1969,7 @@ bus_activation_activate_service (BusActivation  *activation,
           BUS_SET_OOM (error);
           bus_pending_activation_unref (pending_activation);
           bus_pending_activation_entry_free (pending_activation_entry);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
 
       pending_activation->n_entries += 1;
@@ -1980,7 +1983,7 @@ bus_activation_activate_service (BusActivation  *activation,
 
           BUS_SET_OOM (error);
           bus_pending_activation_unref (pending_activation);
-          return FALSE;
+          return BUS_RESULT_FALSE;
         }
     }
 
@@ -1992,7 +1995,7 @@ bus_activation_activate_service (BusActivation  *activation,
     }
 
   if (was_pending_activation)
-    return TRUE;
+    return BUS_RESULT_TRUE;
 
   if (bus_context_get_systemd_activation (activation->context))
     {
@@ -2000,7 +2003,7 @@ bus_activation_activate_service (BusActivation  *activation,
           /* systemd itself is missing apparently. That can happen
              only during early startup. Let's just wait until systemd
              connects to us and do nothing. */
-        return TRUE;
+        return BUS_RESULT_TRUE;
 
       if (entry->systemd_service)
         {
@@ -2074,21 +2077,11 @@ bus_activation_activate_service (BusActivation  *activation,
                                service_name,
                                entry->systemd_service);
               /* Wonderful, systemd is connected, let's just send the msg */
-              switch (bus_dispatch_matches (activation_transaction, NULL,
+              retval = bus_dispatch_matches (activation_transaction, NULL,
                                             bus_service_get_primary_owners_connection (service),
-                                            message, NULL, error))
-                {
-                case BUS_RESULT_TRUE:
-                  retval = TRUE;
-                  break;
-                case BUS_RESULT_FALSE:
-                  retval = FALSE;
-                  break;
-                case BUS_RESULT_LATER:
-                  _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
-                  retval = FALSE;
-                  break;
-                }
+                                            message, NULL, error);
+              if (BUS_RESULT_LATER == retval)
+                _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
             }
           else
             {
@@ -2098,12 +2091,12 @@ bus_activation_activate_service (BusActivation  *activation,
                                entry->systemd_service);
               /* systemd is not around, let's "activate" it. */
               retval = bus_activation_activate_service (activation, NULL, activation_transaction, TRUE,
-                                                        message, "org.freedesktop.systemd1", error);
+                                                        message, "org.freedesktop.systemd1", error, deferred_message);
             }
 
           dbus_message_unref (message);
 
-          if (!retval)
+          if (retval != BUS_RESULT_TRUE)
             {
               bus_context_log (activation->context,
                                DBUS_SYSTEM_LOG_INFO, "Failed to activate via systemd: service name='%s' unit='%s'",
@@ -2116,7 +2109,7 @@ bus_activation_activate_service (BusActivation  *activation,
             }
 
           bus_transaction_execute_and_free (activation_transaction);
-          return TRUE;
+          return BUS_RESULT_TRUE;
         }
 
       /* OK, we have no configured systemd service, hence let's
@@ -2252,13 +2245,13 @@ bus_activation_activate_service (BusActivation  *activation,
       goto cancel_pending_activation;
     }
 
-  return TRUE;
+  return BUS_RESULT_TRUE;
 
 cancel_pending_activation:
   _DBUS_ASSERT_ERROR_IS_SET (error);
   _dbus_hash_table_remove_string (activation->pending_activations,
                                   pending_activation->service_name);
-  return FALSE;
+  return BUS_RESULT_FALSE;
 }
 
 dbus_bool_t
index fc5d426..c24f85d 100644 (file)
@@ -49,7 +49,8 @@ dbus_bool_t    bus_activation_activate_service (BusActivation     *activation,
                                                dbus_bool_t        auto_activation,
                                                DBusMessage       *activation_message,
                                                const char        *service_name,
-                                               DBusError         *error);
+                                               DBusError         *error,
+                                               BusDeferredMessage **deferred_message);
 dbus_bool_t    bus_activation_service_created  (BusActivation     *activation,
                                                const char        *service_name,
                                                BusTransaction    *transaction,
index 4ac9893..67763b9 100644 (file)
@@ -549,18 +549,30 @@ bus_dispatch (DBusConnection *connection,
       if (service == NULL && dbus_message_get_auto_start (message))
         {
           BusActivation *activation;
+          BusDeferredMessage *deferred_message;
+
           /* We can't do the security policy check here, since the addressed
            * recipient service doesn't exist yet. We do it before sending the
            * message after the service has been created.
            */
           activation = bus_connection_get_activation (connection);
 
-          if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
-                                                message, service_name, &error))
+          switch (bus_activation_activate_service (activation, connection, transaction, TRUE,
+                                                message, service_name, &error,
+                                                &deferred_message))
             {
+            case BUS_RESULT_FALSE:
               _DBUS_ASSERT_ERROR_IS_SET (&error);
               _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
-              goto out;
+              break;
+            case BUS_RESULT_LATER:
+              bus_deferred_message_disable_sender(deferred_message);
+              bus_transaction_cancel_and_free (transaction);
+              transaction = NULL;
+              result = DBUS_HANDLER_RESULT_LATER;
+              break;
+            case BUS_RESULT_TRUE:
+              break;
             }
 
           goto out;
index c01c4b4..d5c662c 100644 (file)
@@ -970,7 +970,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
   retval = BUS_RESULT_FALSE;
 
   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
-                                        message, name, error))
+                                        message, name, error, NULL))
     {
       _DBUS_ASSERT_ERROR_IS_SET (error);
       _dbus_verbose ("bus_activation_activate_service() failed\n");
@@ -1055,7 +1055,7 @@ bus_driver_send_or_activate (BusTransaction *transaction,
         }
 
       if (!bus_activation_activate_service (activation, NULL, transaction, TRUE,
-                                            message, service_name, error))
+                                            message, service_name, error, NULL))
         {
           _DBUS_ASSERT_ERROR_IS_SET (error);
           _dbus_verbose ("bus_activation_activate_service() failed");