Integrate parts of meta-intel-iot-security
[AGL/meta-agl.git] / meta-security / recipes-core / dbus / dbus-cynara / 0007-Add-own-rule-result-unavailability-handling.patch
diff --git a/meta-security/recipes-core/dbus/dbus-cynara/0007-Add-own-rule-result-unavailability-handling.patch b/meta-security/recipes-core/dbus/dbus-cynara/0007-Add-own-rule-result-unavailability-handling.patch
new file mode 100644 (file)
index 0000000..e1b1e62
--- /dev/null
@@ -0,0 +1,1142 @@
+From 35ef89cd6777ea2430077fc621d21bd01df92349 Mon Sep 17 00:00:00 2001
+From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
+Date: Thu, 27 Nov 2014 11:26:21 +0100
+Subject: [PATCH 7/8] Add own rule result unavailability handling
+
+Own rule result unavailability is handled like send rules - dispatching
+messages from the sender is blocked and resumed when result becomes
+available.
+
+Handler of "RequestName" method needs to return BUS_RESULT_LATER when
+policy result is not known therefore its return type is modified.
+Since bus message handlers are put into function pointer array other
+message handler function singatures are also affected.
+
+Change-Id: I4c2cbd4585e41fccd8a30f825a8f0d342ab56755
+---
+ bus/dispatch.c |  11 ++-
+ bus/driver.c   | 227 ++++++++++++++++++++++++++++++---------------------------
+ bus/driver.h   |   2 +-
+ bus/policy.c   |  51 ++++++++++---
+ bus/policy.h   |   6 +-
+ bus/services.c |  26 +++++--
+ bus/services.h |   3 +-
+ bus/stats.c    |  16 ++--
+ 8 files changed, 204 insertions(+), 138 deletions(-)
+
+diff --git a/bus/dispatch.c b/bus/dispatch.c
+index 9972e76..d3b970f 100644
+--- a/bus/dispatch.c
++++ b/bus/dispatch.c
+@@ -404,8 +404,17 @@ bus_dispatch (DBusConnection *connection,
+         }
+       _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
+-      if (!bus_driver_handle_message (connection, transaction, message, &error))
++      res = bus_driver_handle_message (connection, transaction, message, &error);
++      if (res == BUS_RESULT_FALSE)
+         goto out;
++      else if (res == BUS_RESULT_LATER)
++        {
++          /* connection has been disabled in message handler */
++          bus_transaction_cancel_and_free (transaction);
++          transaction = NULL;
++          result = DBUS_HANDLER_RESULT_LATER;
++          goto out;
++        }
+     }
+   else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
+     {
+diff --git a/bus/driver.c b/bus/driver.c
+index 2fb1385..9708f49 100644
+--- a/bus/driver.c
++++ b/bus/driver.c
+@@ -297,7 +297,7 @@ create_unique_client_name (BusRegistry *registry,
+   return TRUE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_hello (DBusConnection *connection,
+                          BusTransaction *transaction,
+                          DBusMessage    *message,
+@@ -305,7 +305,7 @@ bus_driver_handle_hello (DBusConnection *connection,
+ {
+   DBusString unique_name;
+   BusService *service;
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusRegistry *registry;
+   BusConnections *connections;
+@@ -316,7 +316,7 @@ bus_driver_handle_hello (DBusConnection *connection,
+       /* We already handled an Hello message for this connection. */
+       dbus_set_error (error, DBUS_ERROR_FAILED,
+                       "Already handled an Hello message");
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   /* Note that when these limits are exceeded we don't disconnect the
+@@ -330,16 +330,16 @@ bus_driver_handle_hello (DBusConnection *connection,
+                                      error))
+     {
+       _DBUS_ASSERT_ERROR_IS_SET (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!_dbus_string_init (&unique_name))
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   registry = bus_connection_get_registry (connection);
+@@ -372,7 +372,7 @@ bus_driver_handle_hello (DBusConnection *connection,
+     goto out_0;
+   _dbus_assert (bus_connection_is_active (connection));
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out_0:
+   _dbus_string_free (&unique_name);
+@@ -424,7 +424,7 @@ bus_driver_send_welcome_message (DBusConnection *connection,
+     }
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_list_services (DBusConnection *connection,
+                                  BusTransaction *transaction,
+                                  DBusMessage    *message,
+@@ -446,14 +446,14 @@ bus_driver_handle_list_services (DBusConnection *connection,
+   if (reply == NULL)
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!bus_registry_list_services (registry, &services, &len))
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   dbus_message_iter_init_append (reply, &iter);
+@@ -465,7 +465,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
+       dbus_free_string_array (services);
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   {
+@@ -477,7 +477,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
+         dbus_free_string_array (services);
+         dbus_message_unref (reply);
+         BUS_SET_OOM (error);
+-        return FALSE;
++        return BUS_RESULT_FALSE;
+       }
+   }
+@@ -490,7 +490,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
+           dbus_free_string_array (services);
+           dbus_message_unref (reply);
+           BUS_SET_OOM (error);
+-          return FALSE;
++          return BUS_RESULT_FALSE;
+         }
+       ++i;
+     }
+@@ -501,23 +501,23 @@ bus_driver_handle_list_services (DBusConnection *connection,
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!bus_transaction_send_from_driver (transaction, connection, reply))
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   else
+     {
+       dbus_message_unref (reply);
+-      return TRUE;
++      return BUS_RESULT_TRUE;
+     }
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+                                            BusTransaction *transaction,
+                                            DBusMessage    *message,
+@@ -539,14 +539,14 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+   if (reply == NULL)
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!bus_activation_list_services (activation, &services, &len))
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   dbus_message_iter_init_append (reply, &iter);
+@@ -558,7 +558,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+       dbus_free_string_array (services);
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   {
+@@ -570,7 +570,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+       dbus_free_string_array (services);
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+       }
+   }
+@@ -583,7 +583,7 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+         dbus_free_string_array (services);
+         dbus_message_unref (reply);
+         BUS_SET_OOM (error);
+-        return FALSE;
++        return BUS_RESULT_FALSE;
+       }
+       ++i;
+     }
+@@ -594,23 +594,23 @@ bus_driver_handle_list_activatable_services (DBusConnection *connection,
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!bus_transaction_send_from_driver (transaction, connection, reply))
+     {
+       dbus_message_unref (reply);
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   else
+     {
+       dbus_message_unref (reply);
+-      return TRUE;
++      return BUS_RESULT_TRUE;
+     }
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_acquire_service (DBusConnection *connection,
+                                    BusTransaction *transaction,
+                                    DBusMessage    *message,
+@@ -621,7 +621,8 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
+   const char *name;
+   dbus_uint32_t service_reply;
+   dbus_uint32_t flags;
+-  dbus_bool_t retval;
++  BusResult retval;
++  BusResult res;
+   BusRegistry *registry;
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -632,20 +633,24 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
+                               DBUS_TYPE_STRING, &name,
+                               DBUS_TYPE_UINT32, &flags,
+                               DBUS_TYPE_INVALID))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   reply = NULL;
+   _dbus_string_init_const (&service_name, name);
+-  if (!bus_registry_acquire_service (registry, connection,
+-                                     &service_name, flags,
+-                                     &service_reply, transaction,
+-                                     error))
+-    goto out;
++  res = bus_registry_acquire_service (registry, connection, message,
++                                       &service_name, flags,
++                                       &service_reply, transaction,
++                                       error);
++  if (res != BUS_RESULT_TRUE)
++    {
++      retval = res;
++      goto out;
++    }
+   reply = dbus_message_new_method_return (message);
+   if (reply == NULL)
+@@ -666,7 +671,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
+       goto out;
+     }
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out:
+   if (reply)
+@@ -674,7 +679,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
+   return retval;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_release_service (DBusConnection *connection,
+                                    BusTransaction *transaction,
+                                    DBusMessage    *message,
+@@ -684,7 +689,7 @@ bus_driver_handle_release_service (DBusConnection *connection,
+   DBusString service_name;
+   const char *name;
+   dbus_uint32_t service_reply;
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusRegistry *registry;
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -694,11 +699,11 @@ bus_driver_handle_release_service (DBusConnection *connection,
+   if (!dbus_message_get_args (message, error,
+                               DBUS_TYPE_STRING, &name,
+                               DBUS_TYPE_INVALID))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+   _dbus_verbose ("Trying to release name %s\n", name);
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   reply = NULL;
+   _dbus_string_init_const (&service_name, name);
+@@ -727,7 +732,7 @@ bus_driver_handle_release_service (DBusConnection *connection,
+       goto out;
+     }
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out:
+   if (reply)
+@@ -735,7 +740,7 @@ bus_driver_handle_release_service (DBusConnection *connection,
+   return retval;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_service_exists (DBusConnection *connection,
+                                   BusTransaction *transaction,
+                                   DBusMessage    *message,
+@@ -746,7 +751,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
+   BusService *service;
+   dbus_bool_t service_exists;
+   const char *name;
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusRegistry *registry;
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -756,9 +761,9 @@ bus_driver_handle_service_exists (DBusConnection *connection,
+   if (!dbus_message_get_args (message, error,
+                               DBUS_TYPE_STRING, &name,
+                               DBUS_TYPE_INVALID))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
+     {
+@@ -792,7 +797,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
+       goto out;
+     }
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out:
+   if (reply)
+@@ -801,7 +806,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
+   return retval;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_activate_service (DBusConnection *connection,
+                                     BusTransaction *transaction,
+                                     DBusMessage    *message,
+@@ -809,7 +814,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
+ {
+   dbus_uint32_t flags;
+   const char *name;
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusActivation *activation;
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -823,10 +828,10 @@ bus_driver_handle_activate_service (DBusConnection *connection,
+     {
+       _DBUS_ASSERT_ERROR_IS_SET (error);
+       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
+                                         message, name, error))
+@@ -836,7 +841,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
+       goto out;
+     }
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out:
+   return retval;
+@@ -872,13 +877,13 @@ send_ack_reply (DBusConnection *connection,
+   return TRUE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+                                                  BusTransaction *transaction,
+                                                  DBusMessage    *message,
+                                                  DBusError      *error)
+ {
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusActivation *activation;
+   DBusMessageIter iter;
+   DBusMessageIter dict_iter;
+@@ -939,7 +944,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+   dbus_message_iter_recurse (&iter, &dict_iter);
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   /* Then loop through the sent dictionary, add the location of
+    * the environment keys and values to lists. The result will
+@@ -1026,7 +1031,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+                        message, error))
+     goto out;
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+  out:
+   _dbus_list_clear (&keys);
+@@ -1034,7 +1039,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+   return retval;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_add_match (DBusConnection *connection,
+                              BusTransaction *transaction,
+                              DBusMessage    *message,
+@@ -1093,16 +1098,16 @@ bus_driver_handle_add_match (DBusConnection *connection,
+   bus_match_rule_unref (rule);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  failed:
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (rule)
+     bus_match_rule_unref (rule);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_remove_match (DBusConnection *connection,
+                                 BusTransaction *transaction,
+                                 DBusMessage    *message,
+@@ -1146,16 +1151,16 @@ bus_driver_handle_remove_match (DBusConnection *connection,
+   bus_match_rule_unref (rule);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  failed:
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (rule)
+     bus_match_rule_unref (rule);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_service_owner (DBusConnection *connection,
+                                    BusTransaction *transaction,
+                                    DBusMessage    *message,
+@@ -1225,7 +1230,7 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1234,10 +1239,10 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_list_queued_owners (DBusConnection *connection,
+                                     BusTransaction *transaction,
+                                     DBusMessage    *message,
+@@ -1328,7 +1333,7 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1341,10 +1346,10 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
+   if (base_names)
+     _dbus_list_clear (&base_names);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
+                                             BusTransaction *transaction,
+                                             DBusMessage    *message,
+@@ -1389,7 +1394,7 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1398,10 +1403,10 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
+                                                 BusTransaction *transaction,
+                                                 DBusMessage    *message,
+@@ -1446,7 +1451,7 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1455,10 +1460,10 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
+                                             BusTransaction *transaction,
+                                             DBusMessage    *message,
+@@ -1502,7 +1507,7 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1511,10 +1516,10 @@ bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
+                                                          BusTransaction *transaction,
+                                                          DBusMessage    *message,
+@@ -1556,7 +1561,7 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1565,10 +1570,10 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
+                                               BusTransaction *transaction,
+                                               DBusMessage    *message,
+@@ -1645,7 +1650,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1659,10 +1664,10 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
+       dbus_message_unref (reply);
+     }
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_reload_config (DBusConnection *connection,
+                                BusTransaction *transaction,
+                                DBusMessage    *message,
+@@ -1687,7 +1692,7 @@ bus_driver_handle_reload_config (DBusConnection *connection,
+     goto oom;
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -1696,10 +1701,10 @@ bus_driver_handle_reload_config (DBusConnection *connection,
+   _DBUS_ASSERT_ERROR_IS_SET (error);
+   if (reply)
+     dbus_message_unref (reply);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_id (DBusConnection *connection,
+                           BusTransaction *transaction,
+                           DBusMessage    *message,
+@@ -1715,7 +1720,7 @@ bus_driver_handle_get_id (DBusConnection *connection,
+   if (!_dbus_string_init (&uuid))
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   reply = NULL;
+@@ -1741,7 +1746,7 @@ bus_driver_handle_get_id (DBusConnection *connection,
+   _dbus_string_free (&uuid);
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -1751,7 +1756,7 @@ bus_driver_handle_get_id (DBusConnection *connection,
+   if (reply)
+     dbus_message_unref (reply);
+   _dbus_string_free (&uuid);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ typedef struct
+@@ -1759,10 +1764,10 @@ typedef struct
+   const char *name;
+   const char *in_args;
+   const char *out_args;
+-  dbus_bool_t (* handler) (DBusConnection *connection,
+-                           BusTransaction *transaction,
+-                           DBusMessage    *message,
+-                           DBusError      *error);
++  BusResult (* handler) (DBusConnection *connection,
++                         BusTransaction *transaction,
++                         DBusMessage    *message,
++                         DBusError      *error);
+ } MessageHandler;
+ /* For speed it might be useful to sort this in order of
+@@ -1847,7 +1852,7 @@ static const MessageHandler dbus_message_handlers[] = {
+   { NULL, NULL, NULL, NULL }
+ };
+-static dbus_bool_t bus_driver_handle_introspect (DBusConnection *,
++static BusResult bus_driver_handle_introspect (DBusConnection *,
+     BusTransaction *, DBusMessage *, DBusError *);
+ static const MessageHandler introspectable_message_handlers[] = {
+@@ -1973,7 +1978,7 @@ bus_driver_generate_introspect_string (DBusString *xml)
+   return TRUE;
+ }
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_introspect (DBusConnection *connection,
+                               BusTransaction *transaction,
+                               DBusMessage    *message,
+@@ -1993,13 +1998,13 @@ bus_driver_handle_introspect (DBusConnection *connection,
+                              DBUS_TYPE_INVALID))
+     {
+       _DBUS_ASSERT_ERROR_IS_SET (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!_dbus_string_init (&xml))
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   if (!bus_driver_generate_introspect_string (&xml))
+@@ -2022,7 +2027,7 @@ bus_driver_handle_introspect (DBusConnection *connection,
+   dbus_message_unref (reply);
+   _dbus_string_free (&xml);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+  oom:
+   BUS_SET_OOM (error);
+@@ -2032,7 +2037,7 @@ bus_driver_handle_introspect (DBusConnection *connection,
+   _dbus_string_free (&xml);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ /*
+@@ -2067,7 +2072,7 @@ bus_driver_check_message_is_for_us (DBusMessage *message,
+   return TRUE;
+ }
+-dbus_bool_t
++BusResult
+ bus_driver_handle_message (DBusConnection *connection,
+                            BusTransaction *transaction,
+                          DBusMessage    *message,
+@@ -2077,6 +2082,7 @@ bus_driver_handle_message (DBusConnection *connection,
+   const InterfaceHandler *ih;
+   const MessageHandler *mh;
+   dbus_bool_t found_interface = FALSE;
++  BusResult res;
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -2085,13 +2091,13 @@ bus_driver_handle_message (DBusConnection *connection,
+       BusContext *context;
+       context = bus_connection_get_context (connection);
+-      return dbus_activation_systemd_failure(bus_context_get_activation(context), message);
++      return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
+     }
+   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+     {
+       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
+-      return TRUE; /* we just ignore this */
++      return BUS_RESULT_TRUE; /* we just ignore this */
+     }
+   /* may be NULL, which means "any interface will do" */
+@@ -2133,20 +2139,27 @@ bus_driver_handle_message (DBusConnection *connection,
+                               name, dbus_message_get_signature (message),
+                               mh->in_args);
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+-              return FALSE;
++              return BUS_RESULT_FALSE;
+             }
+-          if ((* mh->handler) (connection, transaction, message, error))
++          res = (* mh->handler) (connection, transaction, message, error);
++          if (res == BUS_RESULT_TRUE)
+             {
+               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+               _dbus_verbose ("Driver handler succeeded\n");
+-              return TRUE;
++              return BUS_RESULT_TRUE;
+             }
+-          else
++          else if (res == BUS_RESULT_FALSE)
+             {
+               _DBUS_ASSERT_ERROR_IS_SET (error);
+               _dbus_verbose ("Driver handler returned failure\n");
+-              return FALSE;
++              return BUS_RESULT_FALSE;
++            }
++          else if (res == BUS_RESULT_LATER)
++            {
++              _DBUS_ASSERT_ERROR_IS_CLEAR (error);
++              _dbus_verbose ("Driver handler delayed message processing due to policy check\n");
++              return BUS_RESULT_LATER;
+             }
+         }
+     }
+@@ -2158,7 +2171,7 @@ bus_driver_handle_message (DBusConnection *connection,
+                   "%s does not understand message %s",
+                   DBUS_SERVICE_DBUS, name);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ void
+diff --git a/bus/driver.h b/bus/driver.h
+index 201709c..3ff4ff1 100644
+--- a/bus/driver.h
++++ b/bus/driver.h
+@@ -28,7 +28,7 @@
+ #include "connection.h"
+ void        bus_driver_remove_connection     (DBusConnection *connection);
+-dbus_bool_t bus_driver_handle_message        (DBusConnection *connection,
++BusResult   bus_driver_handle_message        (DBusConnection *connection,
+                                               BusTransaction *transaction,
+                                               DBusMessage    *message,
+                                               DBusError      *error);
+diff --git a/bus/policy.c b/bus/policy.c
+index 448147f..3672ff9 100644
+--- a/bus/policy.c
++++ b/bus/policy.c
+@@ -1323,18 +1323,21 @@ bus_client_policy_check_can_receive (BusClientPolicy     *policy,
+-static dbus_bool_t
++static BusResult
+ bus_rules_check_can_own (DBusList *rules,
+-                         const DBusString *service_name)
++                         const DBusString *service_name,
++                         DBusConnection   *connection,
++                         DBusMessage      *message)
+ {
+   DBusList *link;
+-  dbus_bool_t allowed;
++  BusResult result;
++  const char *privilege;
+   
+   /* rules is in the order the rules appeared
+    * in the config file, i.e. last rule that applies wins
+    */
+-  allowed = FALSE;
++  result = BUS_RESULT_FALSE;
+   link = _dbus_list_get_first_link (&rules);
+   while (link != NULL)
+     {
+@@ -1370,17 +1373,45 @@ bus_rules_check_can_own (DBusList *rules,
+         }
+       /* Use this rule */
+-      allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
++      switch (rule->access)
++      {
++      case BUS_POLICY_RULE_ACCESS_ALLOW:
++        result = BUS_RESULT_TRUE;
++        break;
++      case BUS_POLICY_RULE_ACCESS_DENY:
++        result = BUS_RESULT_FALSE;
++        break;
++      case BUS_POLICY_RULE_ACCESS_CHECK:
++        result = BUS_RESULT_LATER;
++        privilege = rule->privilege;
++        break;
++      }
+     }
+-  return allowed;
++  if (result == BUS_RESULT_LATER)
++    {
++      BusContext *context = bus_connection_get_context(connection);
++      BusCheck *check = bus_context_get_check(context);
++      BusDeferredMessage *deferred_message;
++
++      result = bus_check_privilege(check, message, connection, NULL, NULL,
++          privilege, BUS_DEFERRED_MESSAGE_CHECK_OWN, &deferred_message);
++      if (result == BUS_RESULT_LATER)
++        {
++          bus_deferred_message_disable_sender(deferred_message);
++        }
++    }
++
++  return result;
+ }
+-dbus_bool_t
++BusResult
+ bus_client_policy_check_can_own (BusClientPolicy  *policy,
+-                                 const DBusString *service_name)
++                                 const DBusString *service_name,
++                                 DBusConnection   *connection,
++                                 DBusMessage      *message)
+ {
+-  return bus_rules_check_can_own (policy->rules, service_name);
++  return bus_rules_check_can_own (policy->rules, service_name, connection, message);
+ }
+ #ifdef DBUS_ENABLE_EMBEDDED_TESTS
+@@ -1388,7 +1419,7 @@ dbus_bool_t
+ bus_policy_check_can_own (BusPolicy  *policy,
+                           const DBusString *service_name)
+ {
+-  return bus_rules_check_can_own (policy->default_rules, service_name);
++  return bus_rules_check_can_own (policy->default_rules, service_name, NULL, NULL);
+ }
+ #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
+diff --git a/bus/policy.h b/bus/policy.h
+index e9f193a..1f23431 100644
+--- a/bus/policy.h
++++ b/bus/policy.h
+@@ -170,8 +170,10 @@ BusResult        bus_client_policy_check_can_receive (BusClientPolicy     *polic
+                                                       dbus_int32_t        *toggles,
+                                                       const char         **privilege_param,
+                                                       BusDeferredMessage **deferred_message);
+-dbus_bool_t      bus_client_policy_check_can_own     (BusClientPolicy  *policy,
+-                                                      const DBusString *service_name);
++BusResult        bus_client_policy_check_can_own     (BusClientPolicy  *policy,
++                                                      const DBusString *service_name,
++                                                      DBusConnection   *connection,
++                                                      DBusMessage      *message);
+ dbus_bool_t      bus_client_policy_append_rule       (BusClientPolicy  *policy,
+                                                       BusPolicyRule    *rule);
+ void             bus_client_policy_optimize          (BusClientPolicy  *policy);
+diff --git a/bus/services.c b/bus/services.c
+index 584485b..f25fdf3 100644
+--- a/bus/services.c
++++ b/bus/services.c
+@@ -374,24 +374,26 @@ bus_registry_list_services (BusRegistry *registry,
+   return FALSE;
+ }
+-dbus_bool_t
++BusResult
+ bus_registry_acquire_service (BusRegistry      *registry,
+                               DBusConnection   *connection,
++                              DBusMessage      *message,
+                               const DBusString *service_name,
+                               dbus_uint32_t     flags,
+                               dbus_uint32_t    *result,
+                               BusTransaction   *transaction,
+                               DBusError        *error)
+ {
+-  dbus_bool_t retval;
++  BusResult retval;
+   DBusConnection *old_owner_conn;
+   BusClientPolicy *policy;
+   BusService *service;
+   BusActivation  *activation;
+   BusSELinuxID *sid;
+   BusOwner *primary_owner;
++  BusResult res;
+  
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   if (!_dbus_validate_bus_name (service_name, 0,
+                                 _dbus_string_get_length (service_name)))
+@@ -459,7 +461,8 @@ bus_registry_acquire_service (BusRegistry      *registry,
+       goto out;
+     }
+   
+-  if (!bus_client_policy_check_can_own (policy, service_name))
++  res = bus_client_policy_check_can_own (policy, service_name, connection, message);
++  if (res == BUS_RESULT_FALSE)
+     {
+       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+                       "Connection \"%s\" is not allowed to own the service \"%s\" due "
+@@ -470,6 +473,11 @@ bus_registry_acquire_service (BusRegistry      *registry,
+                       _dbus_string_get_const_data (service_name));
+       goto out;
+     }
++  else if (res == BUS_RESULT_LATER)
++    {
++      retval = BUS_RESULT_LATER;
++      goto out;
++    }
+   if (bus_connection_get_n_services_owned (connection) >=
+       bus_context_get_max_services_per_connection (registry->context))
+@@ -586,11 +594,13 @@ bus_registry_acquire_service (BusRegistry      *registry,
+     }
+   activation = bus_context_get_activation (registry->context);
+-  retval = bus_activation_send_pending_auto_activation_messages (activation,
++  
++  if (bus_activation_send_pending_auto_activation_messages (activation,
+                                                                service,
+-                                                               transaction);
+-  if (!retval)
+-    BUS_SET_OOM (error);
++                                                               transaction))
++      retval = BUS_RESULT_TRUE;
++  else
++      BUS_SET_OOM (error);
+   
+  out:
+   return retval;
+diff --git a/bus/services.h b/bus/services.h
+index 056dd9f..3df3dd7 100644
+--- a/bus/services.h
++++ b/bus/services.h
+@@ -50,8 +50,9 @@ void         bus_registry_foreach         (BusRegistry                 *registry
+ dbus_bool_t  bus_registry_list_services   (BusRegistry                 *registry,
+                                            char                      ***listp,
+                                            int                         *array_len);
+-dbus_bool_t  bus_registry_acquire_service (BusRegistry                 *registry,
++BusResult    bus_registry_acquire_service (BusRegistry                 *registry,
+                                            DBusConnection              *connection,
++                                           DBusMessage                 *message,
+                                            const DBusString            *service_name,
+                                            dbus_uint32_t                flags,
+                                            dbus_uint32_t               *result,
+diff --git a/bus/stats.c b/bus/stats.c
+index 20321e5..61dc428 100644
+--- a/bus/stats.c
++++ b/bus/stats.c
+@@ -35,7 +35,7 @@
+ #ifdef DBUS_ENABLE_STATS
+-dbus_bool_t
++BusResult
+ bus_stats_handle_get_stats (DBusConnection *connection,
+                             BusTransaction *transaction,
+                             DBusMessage    *message,
+@@ -106,17 +106,17 @@ bus_stats_handle_get_stats (DBusConnection *connection,
+     goto oom;
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ oom:
+   if (reply != NULL)
+     dbus_message_unref (reply);
+   BUS_SET_OOM (error);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+-dbus_bool_t
++BusResult
+ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
+                                        BusTransaction *transaction,
+                                        DBusMessage    *message,
+@@ -143,7 +143,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
+   if (! dbus_message_get_args (message, error,
+                                DBUS_TYPE_STRING, &bus_name,
+                                DBUS_TYPE_INVALID))
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+   _dbus_string_init_const (&bus_name_str, bus_name);
+   service = bus_registry_lookup (registry, &bus_name_str);
+@@ -152,7 +152,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
+     {
+       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
+                       "Bus name '%s' has no owner", bus_name);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+   stats_connection = bus_service_get_primary_owners_connection (service);
+@@ -214,14 +214,14 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
+     goto oom;
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ oom:
+   if (reply != NULL)
+     dbus_message_unref (reply);
+   BUS_SET_OOM (error);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ #endif
+-- 
+2.1.4
+