dbus-cynara: Avoid dependency loop 21/13721/1
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 27 Mar 2018 09:05:46 +0000 (11:05 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Wed, 4 Apr 2018 19:19:22 +0000 (21:19 +0200)
The dependency loop appeared when compiling
with DISTRO_FEATURE ptest.

To avoid it, I restore the logic implemented before in
meta-intel-iot-security. I also remove unless files.

Bug-AGL: SPEC-1334

Change-Id: Ibe8b9359a65fec034df2534c5fceb4769e63aa99
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
21 files changed:
meta-agl/recipes-core/dbus/dbus-cynara_%.bbappend [new symlink]
meta-agl/recipes-core/dbus/dbus_%.bbappend
meta-app-framework/conf/include/agl-appfw-smack.inc
meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Fix-memleak-in-GetConnectionCredentials-handler.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Integration-of-Cynara-asynchronous-security-checks.patch [moved from meta-security/recipes-core/dbus-cynara/dbus/0001-Integration-of-Cynara-asynchronous-security-checks.patch with 100% similarity]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-Disable-message-dispatching-when-send-rule-result-is.patch [moved from meta-security/recipes-core/dbus-cynara/dbus/0002-Disable-message-dispatching-when-send-rule-result-is.patch with 100% similarity]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-New-a-sv-helper-for-using-byte-arrays-as-the-variant.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Add-LSM-agnostic-support-for-LinuxSecurityLabel-cred.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Handle-unavailability-of-policy-results-for-broadcas.patch [moved from meta-security/recipes-core/dbus-cynara/dbus/0003-Handle-unavailability-of-policy-results-for-broadcas.patch with 100% similarity]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Add-own-rule-result-unavailability-handling.patch [moved from meta-security/recipes-core/dbus-cynara/dbus/0004-Add-own-rule-result-unavailability-handling.patch with 100% similarity]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Integration-of-Cynara-asynchronous-security-checks.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Disable-message-dispatching-when-send-rule-result-is.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Perform-Cynara-runtime-policy-checks-by-default.patch [moved from meta-security/recipes-core/dbus-cynara/dbus/0005-Perform-Cynara-runtime-policy-checks-by-default.patch with 100% similarity]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Handle-unavailability-of-policy-results-for-broadcas.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Add-own-rule-result-unavailability-handling.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/0008-Add-GetConnectionSmackContext-D-Bus-daemon-method.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara/Perform-Cynara-runtime-policy-checks-by-default.patch [deleted file]
meta-security/recipes-core/dbus-cynara/dbus-cynara_1.10.20.bb [new file with mode: 0644]
meta-security/recipes-core/dbus-cynara/dbus_%.bbappend [new file with mode: 0644]
meta-security/recipes-core/dbus-cynara/dbus_1.10.20.bbappend [deleted file]

diff --git a/meta-agl/recipes-core/dbus/dbus-cynara_%.bbappend b/meta-agl/recipes-core/dbus/dbus-cynara_%.bbappend
new file mode 120000 (symlink)
index 0000000..fcdfb17
--- /dev/null
@@ -0,0 +1 @@
+dbus_%.bbappend
\ No newline at end of file
index e65fe9e..e63ea0f 100644 (file)
@@ -1,4 +1,4 @@
-FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
+FILESEXTRAPATHS_append := ":${THISDIR}/dbus"
 
 SRC_URI_append = "file://dbus.service \
                   file://dbus.socket \
index b6b998a..95092a9 100644 (file)
@@ -1,6 +1,6 @@
 # enable security features (smack, cynara) - required by Application Framework
 OVERRIDES .= ":with-lsm-smack"
-DISTRO_FEATURES_append = " smack xattr"
+DISTRO_FEATURES_append = " smack dbus-cynara xattr"
 
 # use tar-native to support SMACK extended attributes independently of host config
 IMAGE_CMD_TAR = "tar --xattrs --xattrs-include='*'"
diff --git a/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch b/meta-app-framework/recipes-security/cynara/cynara/0001-gcc-7-requires-include-functional-for-std-function.patch
deleted file mode 100644 (file)
index bd060b2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From 2169344adbb42ff580856204e2b290e3b04fd447 Mon Sep 17 00:00:00 2001
-From: Changhyeok Bae <changhyeok.bae@gmail.com>
-Date: Sun, 17 Dec 2017 15:28:28 +0000
-Subject: [PATCH] gcc-7 requires include <functional> for std::function
-
-Signed-off-by: Changhyeok Bae <changhyeok.bae@gmail.com>
----
- src/common/types/PolicyBucket.h | 1 +
- src/cyad/AdminPolicyParser.h    | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/src/common/types/PolicyBucket.h b/src/common/types/PolicyBucket.h
-index 029d3dd..1bceeca 100644
---- a/src/common/types/PolicyBucket.h
-+++ b/src/common/types/PolicyBucket.h
-@@ -30,6 +30,7 @@
- #include <set>
- #include <string>
- #include <vector>
-+#include <functional>
- #include <exceptions/NotImplementedException.h>
- #include <types/pointers.h>
-diff --git a/src/cyad/AdminPolicyParser.h b/src/cyad/AdminPolicyParser.h
-index 53dde23..f38c194 100644
---- a/src/cyad/AdminPolicyParser.h
-+++ b/src/cyad/AdminPolicyParser.h
-@@ -25,6 +25,7 @@
- #include <istream>
- #include <memory>
-+#include <functional>
- #include <cyad/CynaraAdminPolicies.h>
--- 
-2.7.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Fix-memleak-in-GetConnectionCredentials-handler.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Fix-memleak-in-GetConnectionCredentials-handler.patch
deleted file mode 100644 (file)
index 271ac48..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From eacdc525a1f7bfc534e248a5a946c08b6f4aab35 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Wed, 17 Jun 2015 18:53:41 +0100
-Subject: [PATCH 1/8] Fix memleak in GetConnectionCredentials handler
-
-Reply message was not unreferenced when GetConnectionCredentials
-handler was successful.
-
-Signed-off-by: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-[smcv: changed bus_message_unref() to dbus_message_unref()]
-Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=91008
----
- bus/driver.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/bus/driver.c b/bus/driver.c
-index f5d3ebe..888c7ca 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -1613,6 +1613,8 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
-       goto oom;
-     }
-+  dbus_message_unref (reply);
-+
-   return TRUE;
-  oom:
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-New-a-sv-helper-for-using-byte-arrays-as-the-variant.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-New-a-sv-helper-for-using-byte-arrays-as-the-variant.patch
deleted file mode 100644 (file)
index 64c8b9b..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-From 25cb15916402c55112cae2be0954d24afe74e2f2 Mon Sep 17 00:00:00 2001
-From: Tyler Hicks <tyhicks@canonical.com>
-Date: Thu, 13 Mar 2014 17:37:38 -0500
-Subject: [PATCH 2/8] New a{sv} helper for using byte arrays as the variant
-
-Create a new helper for using a byte array as the value in the mapping
-from string to variant.
-
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=75113
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89041
-Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
-Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
-Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
----
- dbus/dbus-asv-util.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- dbus/dbus-asv-util.h |  4 ++++
- 2 files changed, 58 insertions(+)
-
-diff --git a/dbus/dbus-asv-util.c b/dbus/dbus-asv-util.c
-index 583e41f..d3ac5e9 100644
---- a/dbus/dbus-asv-util.c
-+++ b/dbus/dbus-asv-util.c
-@@ -258,3 +258,57 @@ _dbus_asv_add_string (DBusMessageIter *arr_iter,
-   return TRUE;
- }
-+
-+/**
-+ * Create a new entry in an a{sv} (map from string to variant)
-+ * with a byte array value.
-+ *
-+ * If this function fails, the a{sv} must be abandoned, for instance
-+ * with _dbus_asv_abandon().
-+ *
-+ * @param arr_iter the iterator which is appending to the array
-+ * @param key a UTF-8 key for the map
-+ * @param value the value
-+ * @param n_elements the number of elements to append
-+ * @returns #TRUE on success, or #FALSE if not enough memory
-+ */
-+dbus_bool_t
-+_dbus_asv_add_byte_array (DBusMessageIter *arr_iter,
-+                          const char      *key,
-+                          const void      *value,
-+                          int              n_elements)
-+{
-+  DBusMessageIter entry_iter;
-+  DBusMessageIter var_iter;
-+  DBusMessageIter byte_array_iter;
-+
-+  if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, "ay", &var_iter))
-+    return FALSE;
-+
-+  if (!dbus_message_iter_open_container (&var_iter, DBUS_TYPE_ARRAY,
-+                                         DBUS_TYPE_BYTE_AS_STRING,
-+                                         &byte_array_iter))
-+    {
-+      _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
-+      return FALSE;
-+    }
-+
-+  if (!dbus_message_iter_append_fixed_array (&byte_array_iter, DBUS_TYPE_BYTE,
-+                                             &value, n_elements))
-+    {
-+      dbus_message_iter_abandon_container (&var_iter, &byte_array_iter);
-+      _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
-+      return FALSE;
-+    }
-+
-+  if (!dbus_message_iter_close_container (&var_iter, &byte_array_iter))
-+    {
-+      _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
-+      return FALSE;
-+    }
-+
-+  if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
-+    return FALSE;
-+
-+  return TRUE;
-+}
-diff --git a/dbus/dbus-asv-util.h b/dbus/dbus-asv-util.h
-index 0337260..277ab80 100644
---- a/dbus/dbus-asv-util.h
-+++ b/dbus/dbus-asv-util.h
-@@ -42,5 +42,9 @@ dbus_bool_t  _dbus_asv_add_uint32        (DBusMessageIter *arr_iter,
- dbus_bool_t  _dbus_asv_add_string        (DBusMessageIter *arr_iter,
-                                           const char      *key,
-                                           const char      *value);
-+dbus_bool_t  _dbus_asv_add_byte_array    (DBusMessageIter *arr_iter,
-+                                          const char      *key,
-+                                          const void      *value,
-+                                          int              n_elements);
- #endif
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Add-LSM-agnostic-support-for-LinuxSecurityLabel-cred.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Add-LSM-agnostic-support-for-LinuxSecurityLabel-cred.patch
deleted file mode 100644 (file)
index fcb8550..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-From 9da49d4eb6982c659fec988231baef8cd1b05be2 Mon Sep 17 00:00:00 2001
-From: Simon McVittie <simon.mcvittie@collabora.co.uk>
-Date: Wed, 11 Feb 2015 13:19:15 +0000
-Subject: [PATCH 3/8] Add LSM-agnostic support for LinuxSecurityLabel
- credential
-
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=89041
-Change-Id: I70512843d1a7661c87461b1b6d86fbfbda934ad5
-Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
-Acked-by: Stephen Smalley <sds@tycho.nsa.gov> (for SELinux)
-Acked-by: John Johansen <john.johansen@canonical.com> (for AppArmor)
-Acked-by: Casey Schaufler <casey@schaufler-ca.com> (for Smack)
-Tested-by: Tyler Hicks <tyhicks@canonical.com>
----
- bus/driver.c                    |  19 ++++++++
- dbus/dbus-auth.c                |  11 +++--
- dbus/dbus-connection-internal.h |   3 ++
- dbus/dbus-connection.c          |  26 ++++++++++
- dbus/dbus-credentials.c         |  68 ++++++++++++++++++++++++++
- dbus/dbus-credentials.h         |   4 ++
- dbus/dbus-sysdeps-unix.c        | 105 ++++++++++++++++++++++++++++++++++++++++
- dbus/dbus-transport.c           |  27 +++++++++++
- dbus/dbus-transport.h           |   3 ++
- 9 files changed, 262 insertions(+), 4 deletions(-)
-
-diff --git a/bus/driver.c b/bus/driver.c
-index 888c7ca..11706f8 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -34,6 +34,7 @@
- #include "utils.h"
- #include <dbus/dbus-asv-util.h>
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-string.h>
- #include <dbus/dbus-internals.h>
- #include <dbus/dbus-message.h>
-@@ -1567,6 +1568,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
-   DBusMessageIter reply_iter;
-   DBusMessageIter array_iter;
-   unsigned long ulong_val;
-+  char *s;
-   const char *service;
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -1601,6 +1603,23 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
-         goto oom;
-     }
-+  if (_dbus_connection_get_linux_security_label (conn, &s))
-+    {
-+      if (s == NULL)
-+        goto oom;
-+
-+      /* use the GVariant bytestring convention for strings of unknown
-+       * encoding: include the \0 in the payload, for zero-copy reading */
-+      if (!_dbus_asv_add_byte_array (&array_iter, "LinuxSecurityLabel",
-+                                     s, strlen (s) + 1))
-+        {
-+          dbus_free (s);
-+          goto oom;
-+        }
-+
-+      dbus_free (s);
-+    }
-+
-   if (!_dbus_asv_close (&reply_iter, &array_iter))
-     goto oom;
-diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
-index 6a07665..aee877d 100644
---- a/dbus/dbus-auth.c
-+++ b/dbus/dbus-auth.c
-@@ -1102,20 +1102,23 @@ handle_server_data_external_mech (DBusAuth         *auth,
-                                               auth->desired_identity))
-         return FALSE;
--      /* also copy process ID from the socket credentials
-+      /* also copy misc process info from the socket credentials
-        */
-       if (!_dbus_credentials_add_credential (auth->authorized_identity,
-                                              DBUS_CREDENTIAL_UNIX_PROCESS_ID,
-                                              auth->credentials))
-         return FALSE;
--      /* also copy audit data from the socket credentials
--       */
-       if (!_dbus_credentials_add_credential (auth->authorized_identity,
-                                              DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
-                                              auth->credentials))
-         return FALSE;
--      
-+
-+      if (!_dbus_credentials_add_credential (auth->authorized_identity,
-+                                             DBUS_CREDENTIAL_LINUX_SECURITY_LABEL,
-+                                             auth->credentials))
-+        return FALSE;
-+
-       if (!send_ok (auth))
-         return FALSE;
-diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
-index 2897404..64ef336 100644
---- a/dbus/dbus-connection-internal.h
-+++ b/dbus/dbus-connection-internal.h
-@@ -107,6 +107,9 @@ void              _dbus_connection_set_pending_fds_function       (DBusConnectio
-                                                                    DBusPendingFdsChangeFunction callback,
-                                                                    void *data);
-+dbus_bool_t       _dbus_connection_get_linux_security_label       (DBusConnection  *connection,
-+                                                                   char           **label_p);
-+
- /* if DBUS_ENABLE_STATS */
- void _dbus_connection_get_stats (DBusConnection *connection,
-                                  dbus_uint32_t  *in_messages,
-diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
-index b574207..8952b75 100644
---- a/dbus/dbus-connection.c
-+++ b/dbus/dbus-connection.c
-@@ -5322,6 +5322,32 @@ dbus_connection_set_unix_user_function (DBusConnection             *connection,
-     (* old_free_function) (old_data);
- }
-+/* Same calling convention as dbus_connection_get_windows_user */
-+dbus_bool_t
-+_dbus_connection_get_linux_security_label (DBusConnection  *connection,
-+                                           char           **label_p)
-+{
-+  dbus_bool_t result;
-+
-+  _dbus_assert (connection != NULL);
-+  _dbus_assert (label_p != NULL);
-+
-+  CONNECTION_LOCK (connection);
-+
-+  if (!_dbus_transport_try_to_authenticate (connection->transport))
-+    result = FALSE;
-+  else
-+    result = _dbus_transport_get_linux_security_label (connection->transport,
-+                                                       label_p);
-+#ifndef __linux__
-+  _dbus_assert (!result);
-+#endif
-+
-+  CONNECTION_UNLOCK (connection);
-+
-+  return result;
-+}
-+
- /**
-  * Gets the Windows user SID of the connection if known.  Returns
-  * #TRUE if the ID is filled in.  Always returns #FALSE on non-Windows
-diff --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c
-index 7325125..151bb00 100644
---- a/dbus/dbus-credentials.c
-+++ b/dbus/dbus-credentials.c
-@@ -50,6 +50,7 @@ struct DBusCredentials {
-   dbus_uid_t unix_uid;
-   dbus_pid_t pid;
-   char *windows_sid;
-+  char *linux_security_label;
-   void *adt_audit_data;
-   dbus_int32_t adt_audit_data_size;
- };
-@@ -79,6 +80,7 @@ _dbus_credentials_new (void)
-   creds->unix_uid = DBUS_UID_UNSET;
-   creds->pid = DBUS_PID_UNSET;
-   creds->windows_sid = NULL;
-+  creds->linux_security_label = NULL;
-   creds->adt_audit_data = NULL;
-   creds->adt_audit_data_size = 0;
-@@ -133,6 +135,7 @@ _dbus_credentials_unref (DBusCredentials    *credentials)
-   if (credentials->refcount == 0)
-     {
-       dbus_free (credentials->windows_sid);
-+      dbus_free (credentials->linux_security_label);
-       dbus_free (credentials->adt_audit_data);
-       dbus_free (credentials);
-     }
-@@ -193,6 +196,30 @@ _dbus_credentials_add_windows_sid (DBusCredentials    *credentials,
- }
- /**
-+ * Add a Linux security label, as used by LSMs such as SELinux, Smack and
-+ * AppArmor, to the credentials.
-+ *
-+ * @param credentials the object
-+ * @param label the label
-+ * @returns #FALSE if no memory
-+ */
-+dbus_bool_t
-+_dbus_credentials_add_linux_security_label (DBusCredentials    *credentials,
-+                                            const char         *label)
-+{
-+  char *copy;
-+
-+  copy = _dbus_strdup (label);
-+  if (copy == NULL)
-+    return FALSE;
-+
-+  dbus_free (credentials->linux_security_label);
-+  credentials->linux_security_label = copy;
-+
-+  return TRUE;
-+}
-+
-+/**
-  * Add ADT audit data to the credentials.
-  *
-  * @param credentials the object
-@@ -236,6 +263,8 @@ _dbus_credentials_include (DBusCredentials    *credentials,
-       return credentials->unix_uid != DBUS_UID_UNSET;
-     case DBUS_CREDENTIAL_WINDOWS_SID:
-       return credentials->windows_sid != NULL;
-+    case DBUS_CREDENTIAL_LINUX_SECURITY_LABEL:
-+      return credentials->linux_security_label != NULL;
-     case DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID:
-       return credentials->adt_audit_data != NULL;
-     }
-@@ -284,6 +313,19 @@ _dbus_credentials_get_windows_sid (DBusCredentials    *credentials)
- }
- /**
-+ * Gets the Linux security label (as used by LSMs) from the credentials,
-+ * or #NULL if the credentials object doesn't contain a security label.
-+ *
-+ * @param credentials the object
-+ * @returns the security label
-+ */
-+const char *
-+_dbus_credentials_get_linux_security_label (DBusCredentials *credentials)
-+{
-+  return credentials->linux_security_label;
-+}
-+
-+/**
-  * Gets the ADT audit data in the credentials, or #NULL if
-  * the credentials object doesn't contain ADT audit data.
-  *
-@@ -329,6 +371,10 @@ _dbus_credentials_are_superset (DBusCredentials    *credentials,
-     (possible_subset->windows_sid == NULL ||
-      (credentials->windows_sid && strcmp (possible_subset->windows_sid,
-                                           credentials->windows_sid) == 0)) &&
-+    (possible_subset->linux_security_label == NULL ||
-+     (credentials->linux_security_label != NULL &&
-+      strcmp (possible_subset->linux_security_label,
-+              credentials->linux_security_label) == 0)) &&
-     (possible_subset->adt_audit_data == NULL ||
-      (credentials->adt_audit_data && memcmp (possible_subset->adt_audit_data,
-                                              credentials->adt_audit_data,
-@@ -348,6 +394,7 @@ _dbus_credentials_are_empty (DBusCredentials    *credentials)
-     credentials->pid == DBUS_PID_UNSET &&
-     credentials->unix_uid == DBUS_UID_UNSET &&
-     credentials->windows_sid == NULL &&
-+    credentials->linux_security_label == NULL &&
-     credentials->adt_audit_data == NULL;
- }
-@@ -388,6 +435,9 @@ _dbus_credentials_add_credentials (DBusCredentials    *credentials,
-                                       DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
-                                       other_credentials) &&
-     _dbus_credentials_add_credential (credentials,
-+                                      DBUS_CREDENTIAL_LINUX_SECURITY_LABEL,
-+                                      other_credentials) &&
-+    _dbus_credentials_add_credential (credentials,
-                                       DBUS_CREDENTIAL_WINDOWS_SID,
-                                       other_credentials);
- }
-@@ -427,6 +477,13 @@ _dbus_credentials_add_credential (DBusCredentials    *credentials,
-       if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid))
-         return FALSE;
-     } 
-+  else if (which == DBUS_CREDENTIAL_LINUX_SECURITY_LABEL &&
-+           other_credentials->linux_security_label != NULL)
-+    {
-+      if (!_dbus_credentials_add_linux_security_label (credentials,
-+            other_credentials->linux_security_label))
-+        return FALSE;
-+    }
-   else if (which == DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID &&
-            other_credentials->adt_audit_data != NULL) 
-     {
-@@ -449,6 +506,8 @@ _dbus_credentials_clear (DBusCredentials    *credentials)
-   credentials->unix_uid = DBUS_UID_UNSET;
-   dbus_free (credentials->windows_sid);
-   credentials->windows_sid = NULL;
-+  dbus_free (credentials->linux_security_label);
-+  credentials->linux_security_label = NULL;
-   dbus_free (credentials->adt_audit_data);
-   credentials->adt_audit_data = NULL;
-   credentials->adt_audit_data_size = 0;
-@@ -540,6 +599,15 @@ _dbus_credentials_to_string_append (DBusCredentials    *credentials,
-   else
-     join = FALSE;
-+  if (credentials->linux_security_label != NULL)
-+    {
-+      if (!_dbus_string_append_printf (string, "%slsm='%s'",
-+                                       join ? " " : "",
-+                                       credentials->linux_security_label))
-+        goto oom;
-+      join = TRUE;
-+    }
-+
-   return TRUE;
- oom:
-   return FALSE;
-diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h
-index abcc4bb..ab74eac 100644
---- a/dbus/dbus-credentials.h
-+++ b/dbus/dbus-credentials.h
-@@ -34,6 +34,7 @@ typedef enum {
-   DBUS_CREDENTIAL_UNIX_PROCESS_ID,
-   DBUS_CREDENTIAL_UNIX_USER_ID,
-   DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
-+  DBUS_CREDENTIAL_LINUX_SECURITY_LABEL,
-   DBUS_CREDENTIAL_WINDOWS_SID
- } DBusCredentialType;
-@@ -47,6 +48,8 @@ dbus_bool_t      _dbus_credentials_add_unix_uid             (DBusCredentials
-                                                              dbus_uid_t          uid);
- dbus_bool_t      _dbus_credentials_add_windows_sid          (DBusCredentials    *credentials,
-                                                              const char         *windows_sid);
-+dbus_bool_t      _dbus_credentials_add_linux_security_label (DBusCredentials    *credentials,
-+                                                             const char         *label);
- dbus_bool_t      _dbus_credentials_add_adt_audit_data       (DBusCredentials    *credentials,
-                                                              void               *audit_data,
-                                                              dbus_int32_t        size);
-@@ -55,6 +58,7 @@ dbus_bool_t      _dbus_credentials_include                  (DBusCredentials
- dbus_pid_t       _dbus_credentials_get_pid                  (DBusCredentials    *credentials);
- dbus_uid_t       _dbus_credentials_get_unix_uid             (DBusCredentials    *credentials);
- const char*      _dbus_credentials_get_windows_sid          (DBusCredentials    *credentials);
-+const char *     _dbus_credentials_get_linux_security_label (DBusCredentials    *credentials);
- void *           _dbus_credentials_get_adt_audit_data       (DBusCredentials    *credentials);
- dbus_int32_t     _dbus_credentials_get_adt_audit_data_size  (DBusCredentials    *credentials);
- dbus_bool_t      _dbus_credentials_are_superset             (DBusCredentials    *credentials,
-diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
-index fe891ab..61af423 100644
---- a/dbus/dbus-sysdeps-unix.c
-+++ b/dbus/dbus-sysdeps-unix.c
-@@ -1639,6 +1639,105 @@ write_credentials_byte (int             server_fd,
-     }
- }
-+/* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
-+static dbus_bool_t
-+add_linux_security_label_to_credentials (int              client_fd,
-+                                         DBusCredentials *credentials)
-+{
-+#if defined(__linux__) && defined(SO_PEERSEC)
-+  DBusString buf;
-+  socklen_t len = 1024;
-+  dbus_bool_t oom = FALSE;
-+
-+  if (!_dbus_string_init_preallocated (&buf, len) ||
-+      !_dbus_string_set_length (&buf, len))
-+    return FALSE;
-+
-+  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
-+         _dbus_string_get_data (&buf), &len) < 0)
-+    {
-+      int e = errno;
-+
-+      _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
-+                     _dbus_strerror (e), (unsigned long) len);
-+
-+      if (e != ERANGE || len <= _dbus_string_get_length (&buf))
-+        {
-+          _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
-+                         _dbus_strerror (e));
-+          goto out;
-+        }
-+
-+      /* If not enough space, len is updated to be enough.
-+       * Try again with a large enough buffer. */
-+      if (!_dbus_string_set_length (&buf, len))
-+        {
-+          oom = TRUE;
-+          goto out;
-+        }
-+
-+      _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
-+    }
-+
-+  if (len <= 0)
-+    {
-+      _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
-+                     (unsigned long) len);
-+      goto out;
-+    }
-+
-+  if (len > _dbus_string_get_length (&buf))
-+    {
-+      _dbus_verbose ("%lu > %d", (unsigned long) len,
-+                     _dbus_string_get_length (&buf));
-+      _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
-+    }
-+
-+  if (_dbus_string_get_byte (&buf, len - 1) == 0)
-+    {
-+      /* the kernel included the trailing \0 in its count,
-+       * but DBusString always has an extra \0 after the data anyway */
-+      _dbus_verbose ("subtracting trailing \\0\n");
-+      len--;
-+    }
-+
-+  if (!_dbus_string_set_length (&buf, len))
-+    {
-+      _dbus_assert_not_reached ("shortening string should not lead to OOM");
-+      oom = TRUE;
-+      goto out;
-+    }
-+
-+  if (strlen (_dbus_string_get_const_data (&buf)) != len)
-+    {
-+      /* LSM people on the linux-security-module@ mailing list say this
-+       * should never happen: the label should be a bytestring with
-+       * an optional trailing \0 */
-+      _dbus_verbose ("security label from kernel had an embedded \\0, "
-+                     "ignoring it\n");
-+      goto out;
-+    }
-+
-+  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
-+                 (unsigned long) len,
-+                 _dbus_string_get_const_data (&buf));
-+
-+  if (!_dbus_credentials_add_linux_security_label (credentials,
-+        _dbus_string_get_const_data (&buf)))
-+    {
-+      oom = TRUE;
-+      goto out;
-+    }
-+
-+out:
-+  _dbus_string_free (&buf);
-+  return !oom;
-+#else
-+  /* no error */
-+  return TRUE;
-+#endif
-+}
-+
- /**
-  * Reads a single byte which must be nul (an error occurs otherwise),
-  * and reads unix credentials if available. Clears the credentials
-@@ -1922,6 +2021,12 @@ _dbus_read_credentials_socket  (int              client_fd,
-         }
-     }
-+  if (!add_linux_security_label_to_credentials (client_fd, credentials))
-+    {
-+      _DBUS_SET_OOM (error);
-+      return FALSE;
-+    }
-+
-   return TRUE;
- }
-diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
-index e9dcc56..a43e7bb 100644
---- a/dbus/dbus-transport.c
-+++ b/dbus/dbus-transport.c
-@@ -1425,6 +1425,33 @@ _dbus_transport_set_unix_user_function (DBusTransport             *transport,
-   transport->free_unix_user_data = free_data_function;
- }
-+dbus_bool_t
-+_dbus_transport_get_linux_security_label (DBusTransport  *transport,
-+                                          char          **label_p)
-+{
-+  DBusCredentials *auth_identity;
-+
-+  *label_p = NULL;
-+
-+  if (!transport->authenticated)
-+    return FALSE;
-+
-+  auth_identity = _dbus_auth_get_identity (transport->auth);
-+
-+  if (_dbus_credentials_include (auth_identity,
-+                                 DBUS_CREDENTIAL_LINUX_SECURITY_LABEL))
-+    {
-+      /* If no memory, we are supposed to return TRUE and set NULL */
-+      *label_p = _dbus_strdup (_dbus_credentials_get_linux_security_label (auth_identity));
-+
-+      return TRUE;
-+    }
-+  else
-+    {
-+      return FALSE;
-+    }
-+}
-+
- /**
-  * See dbus_connection_get_windows_user().
-  *
-diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
-index 39c74c4..843f231 100644
---- a/dbus/dbus-transport.h
-+++ b/dbus/dbus-transport.h
-@@ -87,6 +87,9 @@ void               _dbus_transport_set_unix_user_function (DBusTransport
-                                                            DBusFreeFunction           *old_free_data_function);
- dbus_bool_t        _dbus_transport_get_windows_user       (DBusTransport              *transport,
-                                                            char                      **windows_sid_p);
-+dbus_bool_t        _dbus_transport_get_linux_security_label (DBusTransport            *transport,
-+                                                           char                      **label_p);
-+
- void               _dbus_transport_set_windows_user_function (DBusTransport              *transport,
-                                                               DBusAllowWindowsUserFunction   function,
-                                                               void                       *data,
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Integration-of-Cynara-asynchronous-security-checks.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Integration-of-Cynara-asynchronous-security-checks.patch
deleted file mode 100644 (file)
index 70d5fc9..0000000
+++ /dev/null
@@ -1,2253 +0,0 @@
-From 4dcfb02f17247ff9de966b62182cd2e08f301238 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Thu, 27 Nov 2014 18:11:05 +0100
-Subject: [PATCH 4/8] Integration of Cynara asynchronous security checks
-
-This commit introduces basic framework for asynchronous policy
-checks and Cynara integration code. Functions for checking security
-policy can now return third value - BUS_RESULT_LATER denoting check
-result unavailability. Whenever policy checker cannot decide on the
-result of the check it is supposed to allocate DeferredMessage structure
-that will be passed to the upper layers which can decide what should be
-done in such situation.
-Proper handling of such case will be implemented in subsequent commits.
-Currently such return value results in message denial.
-
-Change-Id: I9bcbce34577e5dc2a3cecf6233a0a2b0e43e1108
----
- bus/Makefile.am                                    |   6 +
- bus/bus.c                                          | 134 +++++---
- bus/bus.h                                          |  58 ++--
- bus/check.c                                        | 215 ++++++++++++
- bus/check.h                                        |  68 ++++
- bus/config-parser-common.c                         |   6 +
- bus/config-parser-common.h                         |   1 +
- bus/config-parser.c                                |  71 +++-
- bus/connection.c                                   |  56 ++-
- bus/connection.h                                   |   5 +
- bus/cynara.c                                       | 374 +++++++++++++++++++++
- bus/cynara.h                                       |  37 ++
- bus/dispatch.c                                     |  51 ++-
- bus/policy.c                                       | 193 +++++++----
- bus/policy.h                                       |  51 ++-
- configure.ac                                       |  13 +
- test/Makefile.am                                   |   1 +
- test/data/invalid-config-files/badcheck-1.conf     |   9 +
- test/data/invalid-config-files/badcheck-2.conf     |   9 +
- test/data/valid-config-files/check-1.conf          |   9 +
- .../valid-config-files/debug-check-some.conf.in    |  18 +
- 22 files changed, 1211 insertions(+), 180 deletions(-)
- create mode 100644 bus/check.c
- create mode 100644 bus/check.h
- create mode 100644 bus/cynara.c
- create mode 100644 bus/cynara.h
- create mode 100644 test/data/invalid-config-files/badcheck-1.conf
- create mode 100644 test/data/invalid-config-files/badcheck-2.conf
- create mode 100644 test/data/valid-config-files/check-1.conf
- create mode 100644 test/data/valid-config-files/debug-check-some.conf.in
-
-diff --git a/bus/Makefile.am b/bus/Makefile.am
-index f335e30..b057d6b 100644
---- a/bus/Makefile.am
-+++ b/bus/Makefile.am
-@@ -7,6 +7,7 @@ DBUS_BUS_LIBS = \
-       $(THREAD_LIBS) \
-       $(ADT_LIBS) \
-       $(NETWORK_libs) \
-+      $(CYNARA_LIBS) \
-       $(NULL)
- DBUS_LAUNCHER_LIBS = \
-@@ -21,6 +22,7 @@ AM_CPPFLAGS = \
-       -DDBUS_SYSTEM_CONFIG_FILE=\""$(configdir)/system.conf"\" \
-       -DDBUS_COMPILATION \
-       -DDBUS_STATIC_BUILD \
-+      $(CYNARA_CFLAGS) \
-       $(NULL)
- # if assertions are enabled, improve backtraces
-@@ -60,12 +62,16 @@ BUS_SOURCES=                                       \
-       activation-exit-codes.h                 \
-       bus.c                                   \
-       bus.h                                   \
-+      check.c                                 \
-+      check.h                                 \
-       config-parser.c                         \
-       config-parser.h                         \
-       config-parser-common.c                  \
-       config-parser-common.h                  \
-       connection.c                            \
-       connection.h                            \
-+      cynara.c                                \
-+      cynara.h                                \
-       desktop-file.c                          \
-       desktop-file.h                          \
-       $(DIR_WATCH_SOURCE)                     \
-diff --git a/bus/bus.c b/bus/bus.c
-index f0d980e..ac9ea8d 100644
---- a/bus/bus.c
-+++ b/bus/bus.c
-@@ -35,6 +35,7 @@
- #include "signals.h"
- #include "selinux.h"
- #include "dir-watch.h"
-+#include "check.h"
- #include <dbus/dbus-list.h>
- #include <dbus/dbus-hash.h>
- #include <dbus/dbus-credentials.h>
-@@ -63,6 +64,7 @@ struct BusContext
-   BusRegistry *registry;
-   BusPolicy *policy;
-   BusMatchmaker *matchmaker;
-+  BusCheck *check;
-   BusLimits limits;
-   DBusRLimit *initial_fd_limit;
-   unsigned int fork : 1;
-@@ -962,6 +964,10 @@ bus_context_new (const DBusString *config_file,
- #endif
-     }
-+  context->check = bus_check_new(context, error);
-+  if (context->check == NULL)
-+      goto failed;
-+
-   dbus_server_free_data_slot (&server_data_slot);
-   return context;
-@@ -1086,6 +1092,12 @@ bus_context_unref (BusContext *context)
-       bus_context_shutdown (context);
-+      if (context->check)
-+        {
-+          bus_check_unref(context->check);
-+          context->check = NULL;
-+        }
-+
-       if (context->connections)
-         {
-           bus_connections_unref (context->connections);
-@@ -1215,6 +1227,12 @@ bus_context_get_loop (BusContext *context)
-   return context->loop;
- }
-+BusCheck*
-+bus_context_get_check (BusContext *context)
-+{
-+  return context->check;
-+}
-+
- dbus_bool_t
- bus_context_allow_unix_user (BusContext   *context,
-                              unsigned long uid)
-@@ -1386,6 +1404,7 @@ complain_about_message (BusContext     *context,
-                         DBusConnection *proposed_recipient,
-                         dbus_bool_t     requested_reply,
-                         dbus_bool_t     log,
-+                        const char     *privilege,
-                         DBusError      *error)
- {
-   DBusError stack_error = DBUS_ERROR_INIT;
-@@ -1415,7 +1434,8 @@ complain_about_message (BusContext     *context,
-   dbus_set_error (&stack_error, error_name,
-       "%s, %d matched rules; type=\"%s\", sender=\"%s\" (%s) "
-       "interface=\"%s\" member=\"%s\" error name=\"%s\" "
--      "requested_reply=\"%d\" destination=\"%s\" (%s)",
-+      "requested_reply=\"%d\" destination=\"%s\" (%s) "
-+      "privilege=\"%s\"",
-       complaint,
-       matched_rules,
-       dbus_message_type_to_string (dbus_message_get_type (message)),
-@@ -1426,7 +1446,8 @@ complain_about_message (BusContext     *context,
-       nonnull (dbus_message_get_error_name (message), "(unset)"),
-       requested_reply,
-       nonnull (dbus_message_get_destination (message), DBUS_SERVICE_DBUS),
--      proposed_recipient_loginfo);
-+      proposed_recipient_loginfo,
-+      nonnull (privilege, "(n/a)"));
-   /* If we hit OOM while setting the error, this will syslog "out of memory"
-    * which is itself an indication that something is seriously wrong */
-@@ -1450,14 +1471,15 @@ complain_about_message (BusContext     *context,
-  * NULL for addressed_recipient may mean the bus driver, or may mean
-  * no destination was specified in the message (e.g. a signal).
-  */
--dbus_bool_t
--bus_context_check_security_policy (BusContext     *context,
--                                   BusTransaction *transaction,
--                                   DBusConnection *sender,
--                                   DBusConnection *addressed_recipient,
--                                   DBusConnection *proposed_recipient,
--                                   DBusMessage    *message,
--                                   DBusError      *error)
-+BusResult
-+bus_context_check_security_policy (BusContext          *context,
-+                                   BusTransaction      *transaction,
-+                                   DBusConnection      *sender,
-+                                   DBusConnection      *addressed_recipient,
-+                                   DBusConnection      *proposed_recipient,
-+                                   DBusMessage         *message,
-+                                   DBusError           *error,
-+                                   BusDeferredMessage **deferred_message)
- {
-   const char *dest;
-   BusClientPolicy *sender_policy;
-@@ -1466,6 +1488,7 @@ bus_context_check_security_policy (BusContext     *context,
-   dbus_bool_t log;
-   int type;
-   dbus_bool_t requested_reply;
-+  const char *privilege;
-   type = dbus_message_get_type (message);
-   dest = dbus_message_get_destination (message);
-@@ -1493,7 +1516,7 @@ bus_context_check_security_policy (BusContext     *context,
-       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-                       "Message bus will not accept messages of unknown type\n");
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
-   requested_reply = FALSE;
-@@ -1517,11 +1540,11 @@ bus_context_check_security_policy (BusContext     *context,
-               complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
-                   "An SELinux policy prevents this sender from sending this "
-                   "message to this recipient",
--                  0, message, sender, proposed_recipient, FALSE, FALSE, error);
-+                  0, message, sender, proposed_recipient, FALSE, FALSE, NULL, error);
-               _dbus_verbose ("SELinux security check denying send to service\n");
-             }
--          return FALSE;
-+          return BUS_RESULT_FALSE;
-         }
-       if (bus_connection_is_active (sender))
-@@ -1547,7 +1570,7 @@ bus_context_check_security_policy (BusContext     *context,
-                   if (dbus_error_is_set (&error2))
-                     {
-                       dbus_move_error (&error2, error);
--                      return FALSE;
-+                      return BUS_RESULT_FALSE;
-                     }
-                 }
-             }
-@@ -1564,7 +1587,7 @@ bus_context_check_security_policy (BusContext     *context,
-             {
-               _dbus_verbose ("security check allowing %s message\n",
-                              "Hello");
--              return TRUE;
-+              return BUS_RESULT_TRUE;
-             }
-           else
-             {
-@@ -1575,7 +1598,7 @@ bus_context_check_security_policy (BusContext     *context,
-                               "Client tried to send a message other than %s without being registered",
-                               "Hello");
--              return FALSE;
-+              return BUS_RESULT_FALSE;
-             }
-         }
-     }
-@@ -1624,20 +1647,29 @@ bus_context_check_security_policy (BusContext     *context,
-                 (proposed_recipient == NULL && recipient_policy == NULL));
-   log = FALSE;
--  if (sender_policy &&
--      !bus_client_policy_check_can_send (sender_policy,
--                                         context->registry,
--                                         requested_reply,
--                                         proposed_recipient,
--                                         message, &toggles, &log))
--    {
--      complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
--          "Rejected send message", toggles,
--          message, sender, proposed_recipient, requested_reply,
--          (addressed_recipient == proposed_recipient), error);
--      _dbus_verbose ("security policy disallowing message due to sender policy\n");
--      return FALSE;
--    }
-+  if (sender_policy)
-+    {
-+      BusResult res = bus_client_policy_check_can_send (sender,
-+                                                        sender_policy,
-+                                                        context->registry,
-+                                                        requested_reply,
-+                                                        addressed_recipient,
-+                                                        proposed_recipient,
-+                                                        message, &toggles, &log, &privilege,
-+                                                        deferred_message);
-+      if (res == BUS_RESULT_FALSE)
-+        {
-+          complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
-+                                  "Rejected send message", toggles,
-+                                  message, sender, proposed_recipient, requested_reply,
-+                                  (addressed_recipient == proposed_recipient), privilege,
-+                                  error);
-+          _dbus_verbose ("security policy disallowing message due to sender policy\n");
-+          return BUS_RESULT_FALSE;
-+        }
-+      else if (res == BUS_RESULT_LATER)
-+        return BUS_RESULT_LATER;
-+  }
-   if (log)
-     {
-@@ -1646,23 +1678,29 @@ bus_context_check_security_policy (BusContext     *context,
-       complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
-           "Would reject message", toggles,
-           message, sender, proposed_recipient, requested_reply,
--          TRUE, NULL);
-+          TRUE, privilege, NULL);
-     }
--  if (recipient_policy &&
--      !bus_client_policy_check_can_receive (recipient_policy,
--                                            context->registry,
--                                            requested_reply,
--                                            sender,
--                                            addressed_recipient, proposed_recipient,
--                                            message, &toggles))
-+  if (recipient_policy)
-     {
--      complain_about_message (context, DBUS_ERROR_ACCESS_DENIED,
--          "Rejected receive message", toggles,
--          message, sender, proposed_recipient, requested_reply,
--          (addressed_recipient == proposed_recipient), error);
--      _dbus_verbose ("security policy disallowing message due to recipient policy\n");
--      return FALSE;
-+      BusResult res;
-+      res = bus_client_policy_check_can_receive (recipient_policy,
-+                                                 context->registry,
-+                                                 requested_reply,
-+                                                 sender,
-+                                                 addressed_recipient, proposed_recipient,
-+                                                 message, &toggles, &privilege, deferred_message);
-+      if (res == BUS_RESULT_FALSE)
-+        {
-+          complain_about_message(context, DBUS_ERROR_ACCESS_DENIED, "Rejected receive message",
-+              toggles, message, sender, proposed_recipient, requested_reply,
-+            (addressed_recipient == proposed_recipient), privilege, error);
-+          _dbus_verbose(
-+            "security policy disallowing message due to recipient policy\n");
-+          return BUS_RESULT_FALSE;
-+        }
-+      else if (res == BUS_RESULT_LATER)
-+        return BUS_RESULT_LATER;
-     }
-   /* See if limits on size have been exceeded */
-@@ -1672,10 +1710,10 @@ bus_context_check_security_policy (BusContext     *context,
-     {
-       complain_about_message (context, DBUS_ERROR_LIMITS_EXCEEDED,
-           "Rejected: destination has a full message queue",
--          0, message, sender, proposed_recipient, requested_reply, TRUE,
-+          0, message, sender, proposed_recipient, requested_reply, TRUE, NULL,
-           error);
-       _dbus_verbose ("security policy disallowing message due to full message queue\n");
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
-   /* Record that we will allow a reply here in the future (don't
-@@ -1692,11 +1730,11 @@ bus_context_check_security_policy (BusContext     *context,
-                                      message, error))
-     {
-       _dbus_verbose ("Failed to record reply expectation or problem with the message expecting a reply\n");
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
-   _dbus_verbose ("security policy allowing message\n");
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- }
- void
-diff --git a/bus/bus.h b/bus/bus.h
-index dac6ea5..78084dd 100644
---- a/bus/bus.h
-+++ b/bus/bus.h
-@@ -30,19 +30,35 @@
- #include <dbus/dbus-pipe.h>
- #include <dbus/dbus-sysdeps.h>
--typedef struct BusActivation    BusActivation;
--typedef struct BusConnections   BusConnections;
--typedef struct BusContext       BusContext;
--typedef struct BusPolicy        BusPolicy;
--typedef struct BusClientPolicy  BusClientPolicy;
--typedef struct BusPolicyRule    BusPolicyRule;
--typedef struct BusRegistry      BusRegistry;
--typedef struct BusSELinuxID     BusSELinuxID;
--typedef struct BusService       BusService;
--typedef struct BusOwner               BusOwner;
--typedef struct BusTransaction   BusTransaction;
--typedef struct BusMatchmaker    BusMatchmaker;
--typedef struct BusMatchRule     BusMatchRule;
-+typedef struct BusActivation      BusActivation;
-+typedef struct BusConnections     BusConnections;
-+typedef struct BusContext         BusContext;
-+typedef struct BusPolicy          BusPolicy;
-+typedef struct BusClientPolicy    BusClientPolicy;
-+typedef struct BusPolicyRule      BusPolicyRule;
-+typedef struct BusRegistry        BusRegistry;
-+typedef struct BusSELinuxID       BusSELinuxID;
-+typedef struct BusService         BusService;
-+typedef struct BusOwner           BusOwner;
-+typedef struct BusTransaction     BusTransaction;
-+typedef struct BusMatchmaker      BusMatchmaker;
-+typedef struct BusMatchRule       BusMatchRule;
-+typedef struct BusCheck           BusCheck;
-+typedef struct BusDeferredMessage BusDeferredMessage;
-+typedef struct BusCynara          BusCynara;
-+
-+/**
-+ * BusResult is defined as a pointer to a dummy structure to allow detection of type mismatches.
-+ * The disadvantage of such solution is that now BusResult variables cannot be used in switch
-+ * statement.
-+ * Additionally, BUS_RESULT_TRUE is defined as 0 instead of 1 to help detect type mismatches
-+ * at runtime.
-+ */
-+typedef const struct BusResultStruct { int dummy; } *BusResult;
-+
-+static const BusResult BUS_RESULT_TRUE  = (BusResult)0x0;
-+static const BusResult BUS_RESULT_FALSE = (BusResult)0x1;
-+static const BusResult BUS_RESULT_LATER = (BusResult)0x2;
- typedef struct
- {
-@@ -96,6 +112,7 @@ BusConnections*   bus_context_get_connections                    (BusContext
- BusActivation*    bus_context_get_activation                     (BusContext       *context);
- BusMatchmaker*    bus_context_get_matchmaker                     (BusContext       *context);
- DBusLoop*         bus_context_get_loop                           (BusContext       *context);
-+BusCheck *        bus_context_get_check                          (BusContext       *context);
- dbus_bool_t       bus_context_allow_unix_user                    (BusContext       *context,
-                                                                   unsigned long     uid);
- dbus_bool_t       bus_context_allow_windows_user                 (BusContext       *context,
-@@ -121,13 +138,14 @@ void              bus_context_log                                (BusContext
-                                                                   DBusSystemLogSeverity severity,
-                                                                   const char       *msg,
-                                                                   ...);
--dbus_bool_t       bus_context_check_security_policy              (BusContext       *context,
--                                                                  BusTransaction   *transaction,
--                                                                  DBusConnection   *sender,
--                                                                  DBusConnection   *addressed_recipient,
--                                                                  DBusConnection   *proposed_recipient,
--                                                                  DBusMessage      *message,
--                                                                  DBusError        *error);
- void              bus_context_check_all_watches                  (BusContext       *context);
-+BusResult         bus_context_check_security_policy              (BusContext          *context,
-+                                                                  BusTransaction      *transaction,
-+                                                                  DBusConnection      *sender,
-+                                                                  DBusConnection      *addressed_recipient,
-+                                                                  DBusConnection      *proposed_recipient,
-+                                                                  DBusMessage         *message,
-+                                                                  DBusError           *error,
-+                                                                  BusDeferredMessage **deferred_message);
- #endif /* BUS_BUS_H */
-diff --git a/bus/check.c b/bus/check.c
-new file mode 100644
-index 0000000..d2f418a
---- /dev/null
-+++ b/bus/check.c
-@@ -0,0 +1,215 @@
-+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-+/* check.c  Bus security policy runtime check
-+ *
-+ * Copyright (C) 2014  Intel, Inc.
-+ * Copyright (c) 2014  Samsung Electronics, Ltd.
-+ *
-+ * Licensed under the Academic Free License version 2.1
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-+ *
-+ */
-+
-+#include <config.h>
-+#include "check.h"
-+#include "connection.h"
-+#include "dispatch.h"
-+#include "cynara.h"
-+#include "utils.h"
-+#include <dbus/dbus-connection-internal.h>
-+#include <dbus/dbus-message-internal.h>
-+#include <dbus/dbus-internals.h>
-+
-+
-+typedef struct BusCheck
-+{
-+  int refcount;
-+
-+  BusContext *context;
-+  BusCynara *cynara;
-+} BusCheck;
-+
-+typedef struct BusDeferredMessage
-+{
-+  int refcount;
-+
-+  DBusMessage *message;
-+  DBusConnection *sender;
-+  DBusConnection *proposed_recipient;
-+  DBusConnection *addressed_recipient;
-+  dbus_bool_t full_dispatch;
-+  BusDeferredMessageStatus status;
-+  BusResult response;
-+  BusCheckResponseFunc response_callback;
-+} BusDeferredMessage;
-+
-+BusCheck *
-+bus_check_new (BusContext *context, DBusError *error)
-+{
-+  BusCheck *check;
-+
-+  check = dbus_new(BusCheck, 1);
-+  if (check == NULL)
-+    {
-+      BUS_SET_OOM(error);
-+      return NULL;
-+    }
-+
-+  check->refcount = 1;
-+  check->context = context;
-+  check->cynara = bus_cynara_new(check, error);
-+  if (dbus_error_is_set(error))
-+    {
-+      dbus_free(check);
-+      return NULL;
-+    }
-+
-+  return check;
-+}
-+
-+BusCheck *
-+bus_check_ref (BusCheck *check)
-+{
-+  _dbus_assert (check->refcount > 0);
-+  check->refcount += 1;
-+
-+  return check;
-+}
-+
-+void
-+bus_check_unref (BusCheck *check)
-+{
-+  _dbus_assert (check->refcount > 0);
-+
-+  check->refcount -= 1;
-+
-+  if (check->refcount == 0)
-+    {
-+      bus_cynara_unref(check->cynara);
-+      dbus_free(check);
-+    }
-+}
-+
-+BusContext *
-+bus_check_get_context (BusCheck *check)
-+{
-+  return check->context;
-+}
-+
-+BusCynara *
-+bus_check_get_cynara (BusCheck *check)
-+{
-+  return check->cynara;
-+}
-+
-+BusResult
-+bus_check_privilege (BusCheck *check,
-+                     DBusMessage *message,
-+                     DBusConnection *sender,
-+                     DBusConnection *addressed_recipient,
-+                     DBusConnection *proposed_recipient,
-+                     const char *privilege,
-+                     BusDeferredMessageStatus check_type,
-+                     BusDeferredMessage **deferred_message)
-+{
-+  BusResult result = BUS_RESULT_FALSE;
-+  BusCynara *cynara;
-+  DBusConnection *connection;
-+
-+  connection = check_type == BUS_DEFERRED_MESSAGE_CHECK_RECEIVE ? proposed_recipient : sender;
-+
-+  if (!dbus_connection_get_is_connected(connection))
-+    {
-+      return BUS_RESULT_FALSE;
-+    }
-+
-+  /* ask policy checkers */
-+#ifdef DBUS_ENABLE_CYNARA
-+  cynara = bus_check_get_cynara(check);
-+  result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
-+      proposed_recipient, privilege, check_type, deferred_message);
-+#endif
-+
-+  if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+    {
-+      (*deferred_message)->status |= check_type;
-+    }
-+  return result;
-+}
-+
-+BusDeferredMessage *bus_deferred_message_new (DBusMessage *message,
-+                                              DBusConnection *sender,
-+                                              DBusConnection *addressed_recipient,
-+                                              DBusConnection *proposed_recipient,
-+                                              BusResult response)
-+{
-+  BusDeferredMessage *deferred_message;
-+
-+  deferred_message = dbus_new(BusDeferredMessage, 1);
-+  if (deferred_message == NULL)
-+    {
-+      return NULL;
-+    }
-+
-+  deferred_message->refcount = 1;
-+  deferred_message->sender = sender != NULL ? dbus_connection_ref(sender) : NULL;
-+  deferred_message->addressed_recipient = addressed_recipient != NULL ? dbus_connection_ref(addressed_recipient) : NULL;
-+  deferred_message->proposed_recipient = proposed_recipient != NULL ? dbus_connection_ref(proposed_recipient) : NULL;
-+  deferred_message->message = dbus_message_ref(message);
-+  deferred_message->response = response;
-+  deferred_message->status = 0;
-+  deferred_message->full_dispatch = FALSE;
-+  deferred_message->response_callback = NULL;
-+
-+  return deferred_message;
-+}
-+
-+BusDeferredMessage *
-+bus_deferred_message_ref (BusDeferredMessage *deferred_message)
-+{
-+  _dbus_assert (deferred_message->refcount > 0);
-+  deferred_message->refcount += 1;
-+  return deferred_message;
-+}
-+
-+void
-+bus_deferred_message_unref (BusDeferredMessage *deferred_message)
-+{
-+  _dbus_assert (deferred_message->refcount > 0);
-+
-+  deferred_message->refcount -= 1;
-+
-+   if (deferred_message->refcount == 0)
-+     {
-+       dbus_message_unref(deferred_message->message);
-+       if (deferred_message->sender != NULL)
-+           dbus_connection_unref(deferred_message->sender);
-+       if (deferred_message->addressed_recipient != NULL)
-+           dbus_connection_unref(deferred_message->addressed_recipient);
-+       if (deferred_message->proposed_recipient != NULL)
-+           dbus_connection_unref(deferred_message->proposed_recipient);
-+       dbus_free(deferred_message);
-+     }
-+}
-+
-+void
-+bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
-+                                        BusResult result)
-+{
-+  if (deferred_message->response_callback != NULL)
-+    {
-+      deferred_message->response_callback(deferred_message, result);
-+    }
-+}
-diff --git a/bus/check.h b/bus/check.h
-new file mode 100644
-index 0000000..c3fcaf9
---- /dev/null
-+++ b/bus/check.h
-@@ -0,0 +1,68 @@
-+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-+/* check.h  Bus security policy runtime check
-+ *
-+ * Copyright (C) 2014  Intel, Inc.
-+ * Copyright (c) 2014  Samsung Electronics, Ltd.
-+ *
-+ * Licensed under the Academic Free License version 2.1
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-+ *
-+ */
-+
-+#ifndef BUS_CHECK_H
-+#define BUS_CHECK_H
-+
-+#include "bus.h"
-+#include "policy.h"
-+
-+
-+typedef void (*BusCheckResponseFunc) (BusDeferredMessage *message,
-+                                      BusResult result);
-+
-+typedef enum {
-+  BUS_DEFERRED_MESSAGE_CHECK_SEND      = 1 << 0,
-+  BUS_DEFERRED_MESSAGE_CHECK_RECEIVE   = 1 << 1,
-+  BUS_DEFERRED_MESSAGE_CHECK_OWN       = 1 << 2,
-+} BusDeferredMessageStatus;
-+
-+
-+BusCheck   *bus_check_new         (BusContext *context,
-+                                   DBusError *error);
-+BusCheck   *bus_check_ref         (BusCheck *check);
-+void        bus_check_unref       (BusCheck *check);
-+
-+BusContext *bus_check_get_context (BusCheck *check);
-+BusCynara  *bus_check_get_cynara  (BusCheck *check);
-+BusResult   bus_check_privilege   (BusCheck *check,
-+                                   DBusMessage *message,
-+                                   DBusConnection *sender,
-+                                   DBusConnection *addressed_recipient,
-+                                   DBusConnection *proposed_recipient,
-+                                   const char *privilege,
-+                                   BusDeferredMessageStatus check_type,
-+                                   BusDeferredMessage **deferred_message);
-+
-+BusDeferredMessage *bus_deferred_message_new                (DBusMessage *message,
-+                                                             DBusConnection *sender,
-+                                                             DBusConnection *addressed_recipient,
-+                                                             DBusConnection *proposed_recipient,
-+                                                             BusResult response);
-+
-+BusDeferredMessage *bus_deferred_message_ref                (BusDeferredMessage *deferred_message);
-+void                bus_deferred_message_unref              (BusDeferredMessage *deferred_message);
-+void                bus_deferred_message_response_received  (BusDeferredMessage *deferred_message,
-+                                                             BusResult result);
-+#endif /* BUS_CHECK_H */
-diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c
-index c522ff4..1cfe4c8 100644
---- a/bus/config-parser-common.c
-+++ b/bus/config-parser-common.c
-@@ -75,6 +75,10 @@ bus_config_parser_element_name_to_type (const char *name)
-     {
-       return ELEMENT_DENY;
-     }
-+  else if (strcmp (name, "check") == 0)
-+    {
-+      return ELEMENT_CHECK;
-+    }
-   else if (strcmp (name, "servicehelper") == 0)
-     {
-       return ELEMENT_SERVICEHELPER;
-@@ -155,6 +159,8 @@ bus_config_parser_element_type_to_name (ElementType type)
-       return "allow";
-     case ELEMENT_DENY:
-       return "deny";
-+    case ELEMENT_CHECK:
-+      return "check";
-     case ELEMENT_FORK:
-       return "fork";
-     case ELEMENT_PIDFILE:
-diff --git a/bus/config-parser-common.h b/bus/config-parser-common.h
-index 186bf4c..bff6fdb 100644
---- a/bus/config-parser-common.h
-+++ b/bus/config-parser-common.h
-@@ -36,6 +36,7 @@ typedef enum
-   ELEMENT_LIMIT,
-   ELEMENT_ALLOW,
-   ELEMENT_DENY,
-+  ELEMENT_CHECK,
-   ELEMENT_FORK,
-   ELEMENT_PIDFILE,
-   ELEMENT_SERVICEDIR,
-diff --git a/bus/config-parser.c b/bus/config-parser.c
-index ee2d4e7..73c9e6f 100644
---- a/bus/config-parser.c
-+++ b/bus/config-parser.c
-@@ -1150,7 +1150,7 @@ append_rule_from_element (BusConfigParser   *parser,
-                           const char        *element_name,
-                           const char       **attribute_names,
-                           const char       **attribute_values,
--                          dbus_bool_t        allow,
-+                          BusPolicyRuleAccess access,
-                           DBusError         *error)
- {
-   const char *log;
-@@ -1173,6 +1173,7 @@ append_rule_from_element (BusConfigParser   *parser,
-   const char *own_prefix;
-   const char *user;
-   const char *group;
-+  const char *privilege;
-   BusPolicyRule *rule;
-   
-@@ -1200,6 +1201,7 @@ append_rule_from_element (BusConfigParser   *parser,
-                           "user", &user,
-                           "group", &group,
-                           "log", &log,
-+                          "privilege", &privilege,
-                           NULL))
-     return FALSE;
-@@ -1208,6 +1210,7 @@ append_rule_from_element (BusConfigParser   *parser,
-         receive_interface || receive_member || receive_error || receive_sender ||
-         receive_type || receive_path || eavesdrop ||
-         send_requested_reply || receive_requested_reply ||
-+        privilege ||
-         own || own_prefix || user || group))
-     {
-       dbus_set_error (error, DBUS_ERROR_FAILED,
-@@ -1224,7 +1227,30 @@ append_rule_from_element (BusConfigParser   *parser,
-                       element_name);
-       return FALSE;
-     }
--  
-+
-+  if (access == BUS_POLICY_RULE_ACCESS_CHECK)
-+    {
-+      if (privilege == NULL || !*privilege)
-+        {
-+          dbus_set_error (error, DBUS_ERROR_FAILED,
-+                          "On element <%s>, you must specify the privilege to be checked.",
-+                          element_name);
-+          return FALSE;
-+        }
-+    }
-+  else
-+    {
-+      if (privilege != NULL && *privilege)
-+        {
-+          dbus_set_error (error, DBUS_ERROR_FAILED,
-+                          "On element <%s>, privilege %s is used outside of a check rule.",
-+                          element_name, privilege);
-+          return FALSE;
-+        }
-+      else
-+        privilege = NULL; /* replace (potentially) empty string with NULL pointer, it wouldn't be used anyway */
-+    }
-+
-   /* Allowed combinations of elements are:
-    *
-    *   base, must be all send or all receive:
-@@ -1398,7 +1424,7 @@ append_rule_from_element (BusConfigParser   *parser,
-           return FALSE;
-         }
-       
--      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
-+      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, access);
-       if (rule == NULL)
-         goto nomem;
-       
-@@ -1480,7 +1506,7 @@ append_rule_from_element (BusConfigParser   *parser,
-           return FALSE;
-         }
-       
--      rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
-+      rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, access);
-       if (rule == NULL)
-         goto nomem;
-@@ -1510,7 +1536,7 @@ append_rule_from_element (BusConfigParser   *parser,
-     }
-   else if (own || own_prefix)
-     {
--      rule = bus_policy_rule_new (BUS_POLICY_RULE_OWN, allow); 
-+      rule = bus_policy_rule_new (BUS_POLICY_RULE_OWN, access);
-       if (rule == NULL)
-         goto nomem;
-@@ -1536,7 +1562,7 @@ append_rule_from_element (BusConfigParser   *parser,
-     {      
-       if (IS_WILDCARD (user))
-         {
--          rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
-+          rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, access);
-           if (rule == NULL)
-             goto nomem;
-@@ -1551,7 +1577,7 @@ append_rule_from_element (BusConfigParser   *parser,
-       
-           if (_dbus_parse_unix_user_from_config (&username, &uid))
-             {
--              rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
-+              rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, access);
-               if (rule == NULL)
-                 goto nomem;
-@@ -1568,7 +1594,7 @@ append_rule_from_element (BusConfigParser   *parser,
-     {
-       if (IS_WILDCARD (group))
-         {
--          rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
-+          rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, access);
-           if (rule == NULL)
-             goto nomem;
-@@ -1583,7 +1609,7 @@ append_rule_from_element (BusConfigParser   *parser,
-           
-           if (_dbus_parse_unix_group_from_config (&groupname, &gid))
-             {
--              rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
-+              rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, access);
-               if (rule == NULL)
-                 goto nomem;
-@@ -1607,6 +1633,10 @@ append_rule_from_element (BusConfigParser   *parser,
-       _dbus_assert (pe != NULL);
-       _dbus_assert (pe->type == ELEMENT_POLICY);
-+      rule->privilege = _dbus_strdup (privilege);
-+      if (privilege && !rule->privilege)
-+        goto nomem;
-+
-       switch (pe->d.policy.type)
-         {
-         case POLICY_IGNORED:
-@@ -1681,7 +1711,7 @@ start_policy_child (BusConfigParser   *parser,
-     {
-       if (!append_rule_from_element (parser, element_name,
-                                      attribute_names, attribute_values,
--                                     TRUE, error))
-+                                     BUS_POLICY_RULE_ACCESS_ALLOW, error))
-         return FALSE;
-       
-       if (push_element (parser, ELEMENT_ALLOW) == NULL)
-@@ -1696,7 +1726,7 @@ start_policy_child (BusConfigParser   *parser,
-     {
-       if (!append_rule_from_element (parser, element_name,
-                                      attribute_names, attribute_values,
--                                     FALSE, error))
-+                                     BUS_POLICY_RULE_ACCESS_DENY, error))
-         return FALSE;
-       
-       if (push_element (parser, ELEMENT_DENY) == NULL)
-@@ -1707,6 +1737,21 @@ start_policy_child (BusConfigParser   *parser,
-       
-       return TRUE;
-     }
-+  else if (strcmp (element_name, "check") == 0)
-+    {
-+      if (!append_rule_from_element (parser, element_name,
-+                                     attribute_names, attribute_values,
-+                                     BUS_POLICY_RULE_ACCESS_CHECK, error))
-+        return FALSE;
-+
-+      if (push_element (parser, ELEMENT_CHECK) == NULL)
-+        {
-+          BUS_SET_OOM (error);
-+          return FALSE;
-+        }
-+
-+      return TRUE;
-+    }
-   else
-     {
-       dbus_set_error (error, DBUS_ERROR_FAILED,
-@@ -2066,6 +2111,7 @@ bus_config_parser_end_element (BusConfigParser   *parser,
-     case ELEMENT_POLICY:
-     case ELEMENT_ALLOW:
-     case ELEMENT_DENY:
-+    case ELEMENT_CHECK:
-     case ELEMENT_FORK:
-     case ELEMENT_SYSLOG:
-     case ELEMENT_KEEP_UMASK:
-@@ -2365,6 +2411,7 @@ bus_config_parser_content (BusConfigParser   *parser,
-     case ELEMENT_POLICY:
-     case ELEMENT_ALLOW:
-     case ELEMENT_DENY:
-+    case ELEMENT_CHECK:
-     case ELEMENT_FORK:
-     case ELEMENT_SYSLOG:
-     case ELEMENT_KEEP_UMASK:
-@@ -2829,6 +2876,8 @@ do_load (const DBusString *full_path,
-   dbus_error_init (&error);
-   parser = bus_config_load (full_path, TRUE, NULL, &error);
-+  if (dbus_error_is_set (&error))
-+    _dbus_verbose ("Failed to load file: %s\n", error.message);
-   if (parser == NULL)
-     {
-       _DBUS_ASSERT_ERROR_IS_SET (&error);
-diff --git a/bus/connection.c b/bus/connection.c
-index 7107434..a6d87e5 100644
---- a/bus/connection.c
-+++ b/bus/connection.c
-@@ -34,6 +34,10 @@
- #include <dbus/dbus-hash.h>
- #include <dbus/dbus-timeout.h>
- #include <dbus/dbus-connection-internal.h>
-+#ifdef DBUS_ENABLE_CYNARA
-+#include <stdlib.h>
-+#include <cynara-session.h>
-+#endif
- /* Trim executed commands to this length; we want to keep logs readable */
- #define MAX_LOG_COMMAND_LEN 50
-@@ -105,6 +109,9 @@ typedef struct
- #endif
-   int n_pending_unix_fds;
-   DBusTimeout *pending_unix_fds_timeout;
-+#ifdef DBUS_ENABLE_CYNARA
-+  char *cynara_session_id;
-+#endif
- } BusConnectionData;
- static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
-@@ -118,8 +125,8 @@ static dbus_bool_t expire_incomplete_timeout (void *data);
- #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
--static DBusLoop*
--connection_get_loop (DBusConnection *connection)
-+DBusLoop*
-+bus_connection_get_loop (DBusConnection *connection)
- {
-   BusConnectionData *d;
-@@ -331,7 +338,7 @@ add_connection_watch (DBusWatch      *watch,
- {
-   DBusConnection *connection = data;
--  return _dbus_loop_add_watch (connection_get_loop (connection), watch);
-+  return _dbus_loop_add_watch (bus_connection_get_loop (connection), watch);
- }
- static void
-@@ -340,7 +347,7 @@ remove_connection_watch (DBusWatch      *watch,
- {
-   DBusConnection *connection = data;
-   
--  _dbus_loop_remove_watch (connection_get_loop (connection), watch);
-+  _dbus_loop_remove_watch (bus_connection_get_loop (connection), watch);
- }
- static void
-@@ -349,7 +356,7 @@ toggle_connection_watch (DBusWatch      *watch,
- {
-   DBusConnection *connection = data;
--  _dbus_loop_toggle_watch (connection_get_loop (connection), watch);
-+  _dbus_loop_toggle_watch (bus_connection_get_loop (connection), watch);
- }
- static dbus_bool_t
-@@ -358,7 +365,7 @@ add_connection_timeout (DBusTimeout    *timeout,
- {
-   DBusConnection *connection = data;
-   
--  return _dbus_loop_add_timeout (connection_get_loop (connection), timeout);
-+  return _dbus_loop_add_timeout (bus_connection_get_loop (connection), timeout);
- }
- static void
-@@ -367,7 +374,7 @@ remove_connection_timeout (DBusTimeout    *timeout,
- {
-   DBusConnection *connection = data;
-   
--  _dbus_loop_remove_timeout (connection_get_loop (connection), timeout);
-+  _dbus_loop_remove_timeout (bus_connection_get_loop (connection), timeout);
- }
- static void
-@@ -425,6 +432,10 @@ free_connection_data (void *data)
-   
-   dbus_free (d->name);
-   
-+#ifdef DBUS_ENABLE_CYNARA
-+  free (d->cynara_session_id);
-+#endif
-+
-   dbus_free (d);
- }
-@@ -984,6 +995,22 @@ bus_connection_get_policy (DBusConnection *connection)
-   return d->policy;
- }
-+#ifdef DBUS_ENABLE_CYNARA
-+const char *bus_connection_get_cynara_session_id (DBusConnection *connection)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA (connection);
-+  _dbus_assert (d != NULL);
-+
-+  if (d->cynara_session_id == NULL)
-+    {
-+      unsigned long pid;
-+      if (dbus_connection_get_unix_process_id(connection, &pid))
-+        d->cynara_session_id = cynara_session_from_pid(pid);
-+    }
-+  return d->cynara_session_id;
-+}
-+#endif
-+
- static dbus_bool_t
- foreach_active (BusConnections               *connections,
-                 BusConnectionForeachFunction  function,
-@@ -2104,6 +2131,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-                                   DBusConnection *connection,
-                                   DBusMessage    *message)
- {
-+  BusResult res;
-   /* We have to set the sender to the driver, and have
-    * to check security policy since it was not done in
-    * dispatch.c
-@@ -2132,10 +2160,18 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-   /* If security policy doesn't allow the message, we silently
-    * eat it; the driver doesn't care about getting a reply.
-    */
--  if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
--                                          transaction,
--                                          NULL, connection, connection, message, NULL))
-+  res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
-+                                           transaction,
-+                                           NULL, connection, connection, message, NULL,
-+                                           NULL);
-+
-+  if (res == BUS_RESULT_FALSE)
-     return TRUE;
-+  else if (res == BUS_RESULT_LATER)
-+    {
-+      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
-+      return TRUE;
-+    }
-   return bus_transaction_send (transaction, connection, message);
- }
-diff --git a/bus/connection.h b/bus/connection.h
-index 6fbcd38..7433746 100644
---- a/bus/connection.h
-+++ b/bus/connection.h
-@@ -31,6 +31,7 @@
- typedef dbus_bool_t (* BusConnectionForeachFunction) (DBusConnection *connection, 
-                                                       void           *data);
-+DBusLoop*       bus_connection_get_loop           (DBusConnection *connection);
- BusConnections* bus_connections_new               (BusContext                   *context);
- BusConnections* bus_connections_ref               (BusConnections               *connections);
-@@ -116,6 +117,10 @@ dbus_bool_t      bus_connection_get_unix_groups  (DBusConnection       *connecti
-                                                   DBusError            *error);
- BusClientPolicy* bus_connection_get_policy  (DBusConnection       *connection);
-+#ifdef DBUS_ENABLE_CYNARA
-+const char *bus_connection_get_cynara_session_id (DBusConnection *connection);
-+#endif
-+
- /* transaction API so we can send or not send a block of messages as a whole */
- typedef void (* BusTransactionCancelFunction) (void *data);
-diff --git a/bus/cynara.c b/bus/cynara.c
-new file mode 100644
-index 0000000..57a4c45
---- /dev/null
-+++ b/bus/cynara.c
-@@ -0,0 +1,374 @@
-+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-+/* cynara.c  Cynara runtime privilege checking
-+ *
-+ * Copyright (c) 2014 Samsung Electronics, Ltd.
-+ *
-+ * Licensed under the Academic Free License version 2.1
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-+ *
-+ */
-+
-+#include <config.h>
-+#include "cynara.h"
-+#include "check.h"
-+#include "utils.h"
-+
-+#include <stdio.h>
-+
-+#include <dbus/dbus.h>
-+#include <dbus/dbus-watch.h>
-+#include <dbus/dbus-connection-internal.h>
-+#include <bus/connection.h>
-+#ifdef DBUS_ENABLE_CYNARA
-+#include <cynara-client-async.h>
-+#endif
-+
-+
-+#ifdef DBUS_ENABLE_CYNARA
-+typedef struct BusCynara
-+{
-+  int refcount;
-+
-+  BusContext   *context;
-+  BusCheck     *check;
-+  cynara_async *cynara;
-+  DBusWatch    *cynara_watch;
-+} BusCynara;
-+
-+#define USE_CYNARA_CACHE 1
-+#ifdef USE_CYNARA_CACHE
-+#define CYNARA_CACHE_SIZE 1000
-+#endif
-+
-+static dbus_bool_t bus_cynara_watch_callback(DBusWatch *watch,
-+                                             unsigned int flags,
-+                                             void *data);
-+
-+static void status_callback(int old_fd,
-+                            int new_fd,
-+                            cynara_async_status status,
-+                            void *user_status_data);
-+static void bus_cynara_check_response_callback (cynara_check_id check_id,
-+                                                cynara_async_call_cause cause,
-+                                                int response,
-+                                                void *user_response_data);
-+#endif
-+
-+
-+BusCynara *
-+bus_cynara_new(BusCheck *check, DBusError *error)
-+{
-+#ifdef DBUS_ENABLE_CYNARA
-+  BusContext *context;
-+  BusCynara *cynara;
-+  cynara_async_configuration *conf = NULL;
-+  int ret;
-+
-+  cynara = dbus_new(BusCynara, 1);
-+  if (cynara == NULL)
-+    {
-+      BUS_SET_OOM(error);
-+      return NULL;
-+    }
-+
-+  context = bus_check_get_context(check);
-+
-+  cynara->refcount = 1;
-+  cynara->check = check;
-+  cynara->context = context;
-+  cynara->cynara_watch = NULL;
-+
-+  ret = cynara_async_configuration_create(&conf);
-+  if (ret != CYNARA_API_SUCCESS)
-+    {
-+      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to create Cynara configuration");
-+      goto out;
-+    }
-+
-+#ifdef CYNARA_CACHE_SIZE
-+  ret = cynara_async_configuration_set_cache_size(conf, CYNARA_CACHE_SIZE);
-+  if (ret != CYNARA_API_SUCCESS)
-+    {
-+      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to Cynara cache size");
-+      goto out;
-+    }
-+#endif
-+
-+  ret = cynara_async_initialize(&cynara->cynara, conf, &status_callback, cynara);
-+  if (ret != CYNARA_API_SUCCESS)
-+    {
-+      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to initialize Cynara client");
-+      goto out;
-+    }
-+
-+out:
-+  cynara_async_configuration_destroy(conf);
-+  if (ret != CYNARA_API_SUCCESS)
-+    {
-+      dbus_free(cynara);
-+      return NULL;
-+    }
-+
-+  return cynara;
-+#else
-+  return NULL;
-+#endif
-+}
-+
-+BusCynara *
-+bus_cynara_ref (BusCynara *cynara)
-+{
-+#ifdef DBUS_ENABLE_CYNARA
-+  _dbus_assert (cynara->refcount > 0);
-+  cynara->refcount += 1;
-+
-+  return cynara;
-+#else
-+  return NULL;
-+#endif
-+}
-+
-+void
-+bus_cynara_unref (BusCynara *cynara)
-+{
-+#ifdef DBUS_ENABLE_CYNARA
-+  _dbus_assert (cynara->refcount > 0);
-+
-+  cynara->refcount -= 1;
-+
-+  if (cynara->refcount == 0)
-+    {
-+      cynara_async_finish(cynara->cynara);
-+      dbus_free(cynara);
-+    }
-+#endif
-+}
-+
-+BusResult
-+bus_cynara_check_privilege (BusCynara *cynara,
-+                            DBusMessage *message,
-+                            DBusConnection *sender,
-+                            DBusConnection *addressed_recipient,
-+                            DBusConnection *proposed_recipient,
-+                            const char *privilege,
-+                            BusDeferredMessageStatus check_type,
-+                            BusDeferredMessage **deferred_message_param)
-+{
-+#ifdef DBUS_ENABLE_CYNARA
-+  int result;
-+  unsigned long uid;
-+  char *label;
-+  const char *session_id;
-+  char user[32];
-+  cynara_check_id check_id;
-+  DBusConnection *connection = check_type == BUS_DEFERRED_MESSAGE_CHECK_RECEIVE ? proposed_recipient : sender;
-+  BusDeferredMessage *deferred_message;
-+  BusResult ret;
-+
-+  _dbus_assert(connection != NULL);
-+
-+  if (dbus_connection_get_unix_user(connection, &uid) == FALSE)
-+      return BUS_RESULT_FALSE;
-+
-+  if (_dbus_connection_get_linux_security_label(connection, &label) == FALSE || label == NULL)
-+    {
-+      _dbus_warn("Failed to obtain security label for connection\n");
-+      return BUS_RESULT_FALSE;
-+    }
-+
-+  session_id = bus_connection_get_cynara_session_id (connection);
-+  if (session_id == NULL)
-+    {
-+      ret = BUS_RESULT_FALSE;
-+      goto out;
-+    }
-+
-+  snprintf(user, sizeof(user), "%lu", uid);
-+
-+#if USE_CYNARA_CACHE
-+  result = cynara_async_check_cache(cynara->cynara, label, session_id, user, privilege);
-+#else
-+  result = CYNARA_API_CACHE_MISS;
-+#endif
-+
-+  switch (result)
-+  {
-+  case CYNARA_API_ACCESS_ALLOWED:
-+    _dbus_verbose("Cynara: got ALLOWED answer from cache (client=%s session_id=%s user=%s privilege=%s)\n",
-+               label, session_id, user, privilege);
-+    ret = BUS_RESULT_TRUE;
-+    break;
-+
-+  case CYNARA_API_ACCESS_DENIED:
-+    _dbus_verbose("Cynara: got DENIED answer from cache (client=%s session_id=%s user=%s privilege=%s)\n",
-+               label, session_id, user, privilege);
-+    ret = BUS_RESULT_FALSE;
-+    break;
-+
-+  case CYNARA_API_CACHE_MISS:
-+     deferred_message = bus_deferred_message_new(message, sender, addressed_recipient,
-+         proposed_recipient, BUS_RESULT_LATER);
-+     if (deferred_message == NULL)
-+       {
-+         _dbus_verbose("Failed to allocate memory for deferred message\n");
-+         ret = BUS_RESULT_FALSE;
-+         goto out;
-+       }
-+
-+    /* callback is supposed to unref deferred_message*/
-+    result = cynara_async_create_request(cynara->cynara, label, session_id, user, privilege, &check_id,
-+        &bus_cynara_check_response_callback, deferred_message);
-+    if (result == CYNARA_API_SUCCESS)
-+      {
-+        _dbus_verbose("Created Cynara request: client=%s session_id=%s user=%s privilege=%s check_id=%u "
-+            "deferred_message=%p\n", label, session_id, user, privilege, (unsigned int)check_id, deferred_message);
-+        if (deferred_message_param != NULL)
-+          *deferred_message_param = deferred_message;
-+        ret = BUS_RESULT_LATER;
-+      }
-+    else
-+      {
-+        _dbus_verbose("Error on cynara request create: %i\n", result);
-+        bus_deferred_message_unref(deferred_message);
-+        ret = BUS_RESULT_FALSE;
-+      }
-+    break;
-+  default:
-+    _dbus_verbose("Error when accessing Cynara cache: %i\n", result);
-+    ret = BUS_RESULT_FALSE;
-+  }
-+out:
-+  dbus_free(label);
-+  return ret;
-+
-+#else
-+  return BUS_RESULT_FALSE;
-+#endif
-+}
-+
-+
-+
-+#ifdef DBUS_ENABLE_CYNARA
-+static void
-+status_callback(int old_fd, int new_fd, cynara_async_status status,
-+                void *user_status_data)
-+{
-+  BusCynara *cynara = (BusCynara *)user_status_data;
-+  DBusLoop *loop = bus_context_get_loop(cynara->context);
-+
-+  if (cynara->cynara_watch != NULL)
-+    {
-+      _dbus_loop_remove_watch(loop, cynara->cynara_watch);
-+      _dbus_watch_invalidate(cynara->cynara_watch);
-+      _dbus_watch_unref(cynara->cynara_watch);
-+      cynara->cynara_watch = NULL;
-+    }
-+
-+  if (new_fd != -1)
-+    {
-+      unsigned int flags;
-+      DBusWatch *watch;
-+
-+      switch (status)
-+      {
-+      case CYNARA_STATUS_FOR_READ:
-+        flags = DBUS_WATCH_READABLE;
-+        break;
-+      case CYNARA_STATUS_FOR_RW:
-+        flags = DBUS_WATCH_READABLE | DBUS_WATCH_WRITABLE;
-+        break;
-+      default:
-+        /* Cynara passed unknown status - warn and add RW watch */
-+        _dbus_verbose("Cynara passed unknown status value: 0x%08X\n", (unsigned int)status);
-+        flags = DBUS_WATCH_READABLE | DBUS_WATCH_WRITABLE;
-+        break;
-+      }
-+
-+      watch = _dbus_watch_new(new_fd, flags, TRUE, &bus_cynara_watch_callback, cynara, NULL);
-+      if (watch != NULL)
-+        {
-+          if (_dbus_loop_add_watch(loop, watch) == TRUE)
-+            {
-+              cynara->cynara_watch = watch;
-+              return;
-+            }
-+
-+          _dbus_watch_invalidate(watch);
-+          _dbus_watch_unref(watch);
-+        }
-+
-+      /* It seems like not much can be done at this point. Cynara events won't be processed
-+       * until next Cynara function call triggering status callback */
-+      _dbus_verbose("Failed to add dbus watch\n");
-+    }
-+}
-+
-+static dbus_bool_t
-+bus_cynara_watch_callback(DBusWatch    *watch,
-+                          unsigned int  flags,
-+                          void         *data)
-+{
-+  BusCynara *cynara = (BusCynara *)data;
-+  int result = cynara_async_process(cynara->cynara);
-+  if (result != CYNARA_API_SUCCESS)
-+      _dbus_verbose("cynara_async_process returned %d\n", result);
-+
-+  return result != CYNARA_API_OUT_OF_MEMORY ? TRUE : FALSE;
-+}
-+
-+static inline const char *
-+call_cause_to_string(cynara_async_call_cause cause)
-+{
-+  switch (cause)
-+  {
-+  case CYNARA_CALL_CAUSE_ANSWER:
-+    return "ANSWER";
-+  case CYNARA_CALL_CAUSE_CANCEL:
-+    return "CANCEL";
-+  case CYNARA_CALL_CAUSE_FINISH:
-+    return "FINSIH";
-+  case CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE:
-+    return "SERVICE NOT AVAILABLE";
-+  default:
-+    return "INVALID";
-+  }
-+}
-+
-+static void
-+bus_cynara_check_response_callback (cynara_check_id check_id,
-+                                    cynara_async_call_cause cause,
-+                                    int response,
-+                                    void *user_response_data)
-+{
-+  BusDeferredMessage *deferred_message = user_response_data;
-+  BusResult result;
-+
-+  _dbus_verbose("Cynara callback: check_id=%u, cause=%s response=%i response_data=%p\n",
-+      (unsigned int)check_id, call_cause_to_string(cause), response, user_response_data);
-+
-+  if (deferred_message == NULL)
-+    return;
-+
-+  if (cause == CYNARA_CALL_CAUSE_ANSWER && response == CYNARA_API_ACCESS_ALLOWED)
-+    result = BUS_RESULT_TRUE;
-+  else
-+    result = BUS_RESULT_FALSE;
-+
-+  bus_deferred_message_response_received(deferred_message, result);
-+  bus_deferred_message_unref(deferred_message);
-+}
-+
-+#endif /* DBUS_ENABLE_CYNARA */
-diff --git a/bus/cynara.h b/bus/cynara.h
-new file mode 100644
-index 0000000..c4728bb
---- /dev/null
-+++ b/bus/cynara.h
-@@ -0,0 +1,37 @@
-+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-+/* cynara.h  Cynara runtime privilege checking
-+ *
-+ * Copyright (c) 2014 Samsung Electronics, Ltd.
-+ *
-+ * Licensed under the Academic Free License version 2.1
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-+ *
-+ */
-+
-+#include "bus.h"
-+#include "check.h"
-+
-+BusCynara *bus_cynara_new             (BusCheck *check, DBusError *error);
-+BusCynara *bus_cynara_ref             (BusCynara *cynara);
-+void       bus_cynara_unref           (BusCynara *cynara);
-+BusResult  bus_cynara_check_privilege (BusCynara *cynara,
-+                                       DBusMessage *message,
-+                                       DBusConnection *sender,
-+                                       DBusConnection *addressed_recipient,
-+                                       DBusConnection *proposed_recipient,
-+                                       const char *privilege,
-+                                       BusDeferredMessageStatus check_type,
-+                                       BusDeferredMessage **deferred_message);
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index 7a61953..ce4076d 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -25,6 +25,7 @@
- #include <config.h>
- #include "dispatch.h"
-+#include "check.h"
- #include "connection.h"
- #include "driver.h"
- #include "services.h"
-@@ -56,13 +57,14 @@ send_one_message (DBusConnection *connection,
-                   BusTransaction *transaction,
-                   DBusError      *error)
- {
--  if (!bus_context_check_security_policy (context, transaction,
--                                          sender,
--                                          addressed_recipient,
--                                          connection,
--                                          message,
--                                          NULL))
--    return TRUE; /* silently don't send it */
-+  BusDeferredMessage *deferred_message;
-+  BusResult result;
-+
-+  result = bus_context_check_security_policy (context, transaction, sender, addressed_recipient,
-+      connection, message, NULL, &deferred_message);
-+
-+  if (result != BUS_RESULT_TRUE)
-+      return TRUE; /* silently don't send it */
-   if (dbus_message_contains_unix_fds(message) &&
-       !dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD))
-@@ -92,6 +94,7 @@ bus_dispatch_matches (BusTransaction *transaction,
-   BusMatchmaker *matchmaker;
-   DBusList *link;
-   BusContext *context;
-+  BusDeferredMessage *deferred_message;
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -107,11 +110,21 @@ bus_dispatch_matches (BusTransaction *transaction,
-   /* First, send the message to the addressed_recipient, if there is one. */
-   if (addressed_recipient != NULL)
-     {
--      if (!bus_context_check_security_policy (context, transaction,
--                                              sender, addressed_recipient,
--                                              addressed_recipient,
--                                              message, error))
-+      BusResult res;
-+      res = bus_context_check_security_policy (context, transaction,
-+                                               sender, addressed_recipient,
-+                                               addressed_recipient,
-+                                               message, error,
-+                                               &deferred_message);
-+      if (res == BUS_RESULT_FALSE)
-         return FALSE;
-+      else if (res == BUS_RESULT_LATER)
-+        {
-+          dbus_set_error (error,
-+                          DBUS_ERROR_ACCESS_DENIED,
-+                          "Rejecting message because time is needed to check security policy");
-+          return FALSE;
-+        }
-       if (dbus_message_contains_unix_fds (message) &&
-           !dbus_connection_can_send_type (addressed_recipient,
-@@ -273,12 +286,24 @@ bus_dispatch (DBusConnection *connection,
-   if (service_name &&
-       strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
-     {
--      if (!bus_context_check_security_policy (context, transaction,
--                                              connection, NULL, NULL, message, &error))
-+      BusDeferredMessage *deferred_message;
-+      BusResult res;
-+      res = bus_context_check_security_policy (context, transaction,
-+                                               connection, NULL, NULL, message, &error,
-+                                               &deferred_message);
-+      if (res == BUS_RESULT_FALSE)
-         {
-           _dbus_verbose ("Security policy rejected message\n");
-           goto out;
-         }
-+      else if (res == BUS_RESULT_LATER)
-+        {
-+          dbus_set_error (&error,
-+                          DBUS_ERROR_ACCESS_DENIED,
-+                          "Rejecting message because time is needed to check security policy");
-+          _dbus_verbose ("Security policy needs time to check policy. Dropping message\n");
-+          goto out;
-+        }
-       _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
-       if (!bus_driver_handle_message (connection, transaction, message, &error))
-diff --git a/bus/policy.c b/bus/policy.c
-index 082f385..ec888df 100644
---- a/bus/policy.c
-+++ b/bus/policy.c
-@@ -22,6 +22,7 @@
-  */
- #include <config.h>
-+#include "check.h"
- #include "policy.h"
- #include "services.h"
- #include "test.h"
-@@ -32,7 +33,7 @@
- BusPolicyRule*
- bus_policy_rule_new (BusPolicyRuleType type,
--                     dbus_bool_t       allow)
-+                     BusPolicyRuleAccess access)
- {
-   BusPolicyRule *rule;
-@@ -42,7 +43,7 @@ bus_policy_rule_new (BusPolicyRuleType type,
-   rule->type = type;
-   rule->refcount = 1;
--  rule->allow = allow;
-+  rule->access = access;
-   switch (rule->type)
-     {
-@@ -54,18 +55,19 @@ bus_policy_rule_new (BusPolicyRuleType type,
-       break;
-     case BUS_POLICY_RULE_SEND:
-       rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
--
-       /* allow rules default to TRUE (only requested replies allowed)
-+       * check rules default to TRUE (only requested replies are checked)
-        * deny rules default to FALSE (only unrequested replies denied)
-        */
--      rule->d.send.requested_reply = rule->allow;
-+      rule->d.send.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
-       break;
-     case BUS_POLICY_RULE_RECEIVE:
-       rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
-       /* allow rules default to TRUE (only requested replies allowed)
-+       * check rules default to TRUE (only requested replies are checked)
-        * deny rules default to FALSE (only unrequested replies denied)
-        */
--      rule->d.receive.requested_reply = rule->allow;
-+      rule->d.receive.requested_reply = rule->access != BUS_POLICY_RULE_ACCESS_DENY;
-       break;
-     case BUS_POLICY_RULE_OWN:
-       break;
-@@ -117,7 +119,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
-         case BUS_POLICY_RULE_GROUP:
-           break;
-         }
--      
-+
-+      dbus_free (rule->privilege);
-       dbus_free (rule);
-     }
- }
-@@ -427,7 +430,10 @@ list_allows_user (dbus_bool_t           def,
-       else
-         continue;
--      allowed = rule->allow;
-+      /* We don't intend to support <check user="..." /> and <check group="..." />
-+         rules. They are treated like deny.
-+      */
-+      allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
-     }
-   
-   return allowed;
-@@ -862,18 +868,23 @@ bus_client_policy_append_rule (BusClientPolicy *policy,
-   return TRUE;
- }
--dbus_bool_t
--bus_client_policy_check_can_send (BusClientPolicy *policy,
--                                  BusRegistry     *registry,
--                                  dbus_bool_t      requested_reply,
--                                  DBusConnection  *receiver,
--                                  DBusMessage     *message,
--                                  dbus_int32_t    *toggles,
--                                  dbus_bool_t     *log)
-+BusResult
-+bus_client_policy_check_can_send (DBusConnection      *sender,
-+                                  BusClientPolicy     *policy,
-+                                  BusRegistry         *registry,
-+                                  dbus_bool_t          requested_reply,
-+                                  DBusConnection      *addressed_recipient,
-+                                  DBusConnection      *receiver,
-+                                  DBusMessage         *message,
-+                                  dbus_int32_t        *toggles,
-+                                  dbus_bool_t         *log,
-+                                  const char         **privilege_param,
-+                                  BusDeferredMessage **deferred_message)
- {
-   DBusList *link;
--  dbus_bool_t allowed;
--  
-+  BusResult result;
-+  const char *privilege;
-+
-   /* policy->rules is in the order the rules appeared
-    * in the config file, i.e. last rule that applies wins
-    */
-@@ -881,7 +892,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
-   _dbus_verbose ("  (policy) checking send rules\n");
-   *toggles = 0;
-   
--  allowed = FALSE;
-+  result = BUS_RESULT_FALSE;
-   link = _dbus_list_get_first_link (&policy->rules);
-   while (link != NULL)
-     {
-@@ -912,13 +923,14 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
-       /* If it's a reply, the requested_reply flag kicks in */
-       if (dbus_message_get_reply_serial (message) != 0)
-         {
--          /* for allow, requested_reply=true means the rule applies
--           * only when reply was requested. requested_reply=false means
--           * always allow.
-+          /* for allow or check requested_reply=true means the rule applies
-+           * only when reply was requested. requested_reply=false means the
-+           * rule always applies
-            */
--          if (!requested_reply && rule->allow && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
-+          if (!requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
-             {
--              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
-+              _dbus_verbose ("  (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
-+                  rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
-               continue;
-             }
-@@ -926,7 +938,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
-            * when the reply was not requested. requested_reply=true means the
-            * rule always applies.
-            */
--          if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
-+          if (requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.send.requested_reply)
-             {
-               _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
-               continue;
-@@ -949,13 +961,15 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
-           /* The interface is optional in messages. For allow rules, if the message
-            * has no interface we want to skip the rule (and thus not allow);
-            * for deny rules, if the message has no interface we want to use the
--           * rule (and thus deny).
-+           * rule (and thus deny). Check rules are meant to be used like allow
-+           * rules (they can grant access, but not remove it), so we treat it like
-+           * allow here.
-            */
-           dbus_bool_t no_interface;
-           no_interface = dbus_message_get_interface (message) == NULL;
-           
--          if ((no_interface && rule->allow) ||
-+          if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
-               (!no_interface && 
-                strcmp (dbus_message_get_interface (message),
-                        rule->d.send.interface) != 0))
-@@ -1029,33 +1043,63 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
-         }
-       /* Use this rule */
--      allowed = rule->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;
-+        }
-+
-       *log = rule->d.send.log;
-       (*toggles)++;
--      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
--                     allowed);
-+      _dbus_verbose ("  (policy) used rule, result now = %d\n",
-+                     result);
-     }
--  return allowed;
-+  if (result == BUS_RESULT_LATER)
-+    {
-+      BusContext *context = bus_connection_get_context(sender);
-+      BusCheck *check = bus_context_get_check(context);
-+
-+      result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
-+          privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
-+    }
-+  else
-+    privilege = NULL;
-+
-+  if (privilege_param != NULL)
-+    *privilege_param = privilege;
-+
-+  return result;
- }
- /* See docs on what the args mean on bus_context_check_security_policy()
-  * comment
-  */
--dbus_bool_t
--bus_client_policy_check_can_receive (BusClientPolicy *policy,
--                                     BusRegistry     *registry,
--                                     dbus_bool_t      requested_reply,
--                                     DBusConnection  *sender,
--                                     DBusConnection  *addressed_recipient,
--                                     DBusConnection  *proposed_recipient,
--                                     DBusMessage     *message,
--                                     dbus_int32_t    *toggles)
-+BusResult
-+bus_client_policy_check_can_receive (BusClientPolicy     *policy,
-+                                     BusRegistry         *registry,
-+                                     dbus_bool_t          requested_reply,
-+                                     DBusConnection      *sender,
-+                                     DBusConnection      *addressed_recipient,
-+                                     DBusConnection      *proposed_recipient,
-+                                     DBusMessage         *message,
-+                                     dbus_int32_t        *toggles,
-+                                     const char         **privilege_param,
-+                                     BusDeferredMessage **deferred_message)
- {
-   DBusList *link;
--  dbus_bool_t allowed;
-   dbus_bool_t eavesdropping;
-+  BusResult result;
-+  const char *privilege;
-   eavesdropping =
-     addressed_recipient != proposed_recipient &&
-@@ -1068,7 +1112,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-   _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
-   *toggles = 0;
-   
--  allowed = FALSE;
-+  result = BUS_RESULT_FALSE;
-   link = _dbus_list_get_first_link (&policy->rules);
-   while (link != NULL)
-     {
-@@ -1091,19 +1135,21 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-             }
-         }
--      /* for allow, eavesdrop=false means the rule doesn't apply when
--       * eavesdropping. eavesdrop=true means always allow.
-+
-+      /* for allow or check, eavesdrop=false means the rule doesn't apply when
-+       * eavesdropping. eavesdrop=true means the rule always applies
-        */
--      if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
-+      if (eavesdropping && rule->access != BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.eavesdrop)
-         {
--          _dbus_verbose ("  (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
-+          _dbus_verbose ("  (policy) skipping %s rule since it doesn't apply to eavesdropping\n",
-+              rule->access == BUS_POLICY_RULE_ACCESS_ALLOW ? "allow" : "check");
-           continue;
-         }
-       /* for deny, eavesdrop=true means the rule applies only when
-        * eavesdropping; eavesdrop=false means always deny.
-        */
--      if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
-+      if (!eavesdropping && rule->access == BUS_POLICY_RULE_ACCESS_DENY && rule->d.receive.eavesdrop)
-         {
-           _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
-           continue;
-@@ -1112,13 +1158,14 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-       /* If it's a reply, the requested_reply flag kicks in */
-       if (dbus_message_get_reply_serial (message) != 0)
-         {
--          /* for allow, requested_reply=true means the rule applies
--           * only when reply was requested. requested_reply=false means
--           * always allow.
-+          /* for allow or check requested_reply=true means the rule applies
-+           * only when reply was requested. requested_reply=false means the
-+           * rule always applies
-            */
--          if (!requested_reply && rule->allow && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop)
-+          if (!requested_reply && rule->access != BUS_POLICY_RULE_ACCESS_DENY && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
-             {
--              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
-+              _dbus_verbose ("  (policy) skipping %s rule since it only applies to requested replies and does not allow eavesdropping\n",
-+                  rule->access == BUS_POLICY_RULE_ACCESS_DENY ? "allow" : "deny");
-               continue;
-             }
-@@ -1126,7 +1173,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-            * when the reply was not requested. requested_reply=true means the
-            * rule always applies.
-            */
--          if (requested_reply && !rule->allow && !rule->d.receive.requested_reply)
-+          if (requested_reply && rule->access == BUS_POLICY_RULE_ACCESS_DENY && !rule->d.receive.requested_reply)
-             {
-               _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
-               continue;
-@@ -1149,13 +1196,13 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-           /* The interface is optional in messages. For allow rules, if the message
-            * has no interface we want to skip the rule (and thus not allow);
-            * for deny rules, if the message has no interface we want to use the
--           * rule (and thus deny).
-+           * rule (and thus deny). Check rules are treated like allow rules.
-            */
-           dbus_bool_t no_interface;
-           no_interface = dbus_message_get_interface (message) == NULL;
-           
--          if ((no_interface && rule->allow) ||
-+          if ((no_interface && rule->access != BUS_POLICY_RULE_ACCESS_DENY) ||
-               (!no_interface &&
-                strcmp (dbus_message_get_interface (message),
-                        rule->d.receive.interface) != 0))
-@@ -1230,14 +1277,42 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
-         }
-       
-       /* Use this rule */
--      allowed = rule->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;
-+      }
-+
-       (*toggles)++;
--      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
--                     allowed);
-+      _dbus_verbose ("  (policy) used rule, result now = %d\n",
-+                     result);
-     }
--  return allowed;
-+
-+  if (result == BUS_RESULT_LATER)
-+    {
-+      BusContext *context = bus_connection_get_context(proposed_recipient);
-+      BusCheck *check = bus_context_get_check(context);
-+
-+      result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
-+                 privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
-+    }
-+  else
-+      privilege = NULL;
-+
-+  if (privilege_param != NULL)
-+     *privilege_param = privilege;
-+
-+  return result;
- }
-@@ -1289,7 +1364,7 @@ bus_rules_check_can_own (DBusList *rules,
-         }
-       /* Use this rule */
--      allowed = rule->allow;
-+      allowed = rule->access == BUS_POLICY_RULE_ACCESS_ALLOW;
-     }
-   return allowed;
-diff --git a/bus/policy.h b/bus/policy.h
-index d1d3e72..e9f193a 100644
---- a/bus/policy.h
-+++ b/bus/policy.h
-@@ -39,6 +39,14 @@ typedef enum
-   BUS_POLICY_RULE_GROUP
- } BusPolicyRuleType;
-+typedef enum
-+{
-+  BUS_POLICY_RULE_ACCESS_DENY,
-+  BUS_POLICY_RULE_ACCESS_ALLOW,
-+  /** runtime check resulting in allow or deny */
-+  BUS_POLICY_RULE_ACCESS_CHECK
-+} BusPolicyRuleAccess;
-+
- /** determines whether the rule affects a connection, or some global item */
- #define BUS_POLICY_RULE_IS_PER_CLIENT(rule) (!((rule)->type == BUS_POLICY_RULE_USER || \
-                                                (rule)->type == BUS_POLICY_RULE_GROUP))
-@@ -49,8 +57,9 @@ struct BusPolicyRule
-   
-   BusPolicyRuleType type;
--  unsigned int allow : 1; /**< #TRUE if this allows, #FALSE if it denies */
--  
-+  unsigned int access : 2; /**< BusPolicyRuleAccess */
-+  char *privilege; /**< for BUS_POLICY_RULE_ACCESS_CHECK */
-+
-   union
-   {
-     struct
-@@ -106,7 +115,7 @@ struct BusPolicyRule
- };
- BusPolicyRule* bus_policy_rule_new   (BusPolicyRuleType type,
--                                      dbus_bool_t       allow);
-+                                      BusPolicyRuleAccess access);
- BusPolicyRule* bus_policy_rule_ref   (BusPolicyRule    *rule);
- void           bus_policy_rule_unref (BusPolicyRule    *rule);
-@@ -140,21 +149,27 @@ dbus_bool_t      bus_policy_merge                 (BusPolicy        *policy,
- BusClientPolicy* bus_client_policy_new               (void);
- BusClientPolicy* bus_client_policy_ref               (BusClientPolicy  *policy);
- void             bus_client_policy_unref             (BusClientPolicy  *policy);
--dbus_bool_t      bus_client_policy_check_can_send    (BusClientPolicy  *policy,
--                                                      BusRegistry      *registry,
--                                                      dbus_bool_t       requested_reply,
--                                                      DBusConnection   *receiver,
--                                                      DBusMessage      *message,
--                                                      dbus_int32_t     *toggles,
--                                                      dbus_bool_t      *log);
--dbus_bool_t      bus_client_policy_check_can_receive (BusClientPolicy  *policy,
--                                                      BusRegistry      *registry,
--                                                      dbus_bool_t       requested_reply,
--                                                      DBusConnection   *sender,
--                                                      DBusConnection   *addressed_recipient,
--                                                      DBusConnection   *proposed_recipient,
--                                                      DBusMessage      *message,
--                                                      dbus_int32_t     *toggles);
-+BusResult        bus_client_policy_check_can_send    (DBusConnection      *sender,
-+                                                      BusClientPolicy     *policy,
-+                                                      BusRegistry         *registry,
-+                                                      dbus_bool_t          requested_reply,
-+                                                      DBusConnection      *addressed_recipient,
-+                                                      DBusConnection      *receiver,
-+                                                      DBusMessage         *message,
-+                                                      dbus_int32_t        *toggles,
-+                                                      dbus_bool_t         *log,
-+                                                      const char         **privilege_param,
-+                                                      BusDeferredMessage **deferred_message);
-+BusResult        bus_client_policy_check_can_receive (BusClientPolicy     *policy,
-+                                                      BusRegistry         *registry,
-+                                                      dbus_bool_t          requested_reply,
-+                                                      DBusConnection      *sender,
-+                                                      DBusConnection      *addressed_recipient,
-+                                                      DBusConnection      *proposed_recipient,
-+                                                      DBusMessage         *message,
-+                                                      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);
- dbus_bool_t      bus_client_policy_append_rule       (BusClientPolicy  *policy,
-diff --git a/configure.ac b/configure.ac
-index eb803af..b131f30 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1748,6 +1748,18 @@ if test "x$enable_stats" = xyes; then
-     [Define to enable bus daemon usage statistics])
- fi
-+#enable cynara integration
-+AC_ARG_ENABLE([cynara], [AS_HELP_STRING([--enable-cynara], [enable Cynara integration])], [], [enable_cynara=no])
-+if test "x$enable_cynara" = xyes; then
-+  PKG_CHECK_MODULES([CYNARA], [cynara-client-async >= 0.6.0 cynara-session >= 0.6.0],
-+     [AC_DEFINE([DBUS_ENABLE_CYNARA], [1], [Define to enable Cynara privilege checks in dbus-daemon])],
-+     [AC_MSG_ERROR([libcynara-client-async and cynara-session are required to enable Cynara integration])])
-+fi
-+
-+AC_SUBST([CYNARA_CFLAGS])
-+AC_SUBST([CYNARA_LIBS])
-+
-+
- AC_CONFIG_FILES([
- Doxyfile
- dbus/versioninfo.rc
-@@ -1778,6 +1790,7 @@ dbus-1.pc
- dbus-1-uninstalled.pc
- test/data/valid-config-files/debug-allow-all.conf
- test/data/valid-config-files/debug-allow-all-sha1.conf
-+test/data/valid-config-files/debug-check-some.conf
- test/data/valid-config-files/incoming-limit.conf
- test/data/valid-config-files-system/debug-allow-all-pass.conf
- test/data/valid-config-files-system/debug-allow-all-fail.conf
-diff --git a/test/Makefile.am b/test/Makefile.am
-index e0ed3c8..ab63edc 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -254,6 +254,7 @@ in_data = \
-       data/valid-config-files-system/debug-allow-all-pass.conf.in \
-       data/valid-config-files/debug-allow-all-sha1.conf.in \
-       data/valid-config-files/debug-allow-all.conf.in \
-+      data/valid-config-files/debug-check-some.conf.in \
-       data/valid-config-files/incoming-limit.conf.in \
-       data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoExec.service.in \
-       data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in \
-diff --git a/test/data/invalid-config-files/badcheck-1.conf b/test/data/invalid-config-files/badcheck-1.conf
-new file mode 100644
-index 0000000..fad9f50
---- /dev/null
-+++ b/test/data/invalid-config-files/badcheck-1.conf
-@@ -0,0 +1,9 @@
-+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
-+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-+<busconfig>
-+  <user>mybususer</user>
-+  <listen>unix:path=/foo/bar</listen>
-+  <policy context="default">
-+    <allow privilege="foo" send_destination="*"/> <!-- extra privilege="foo" -->
-+  </policy>
-+</busconfig>
-diff --git a/test/data/invalid-config-files/badcheck-2.conf b/test/data/invalid-config-files/badcheck-2.conf
-new file mode 100644
-index 0000000..63c7ef2
---- /dev/null
-+++ b/test/data/invalid-config-files/badcheck-2.conf
-@@ -0,0 +1,9 @@
-+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
-+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-+<busconfig>
-+  <user>mybususer</user>
-+  <listen>unix:path=/foo/bar</listen>
-+  <policy context="default">
-+    <check send_destination="*"/> <!-- missing privilege="foo" -->
-+  </policy>
-+</busconfig>
-diff --git a/test/data/valid-config-files/check-1.conf b/test/data/valid-config-files/check-1.conf
-new file mode 100644
-index 0000000..ad71473
---- /dev/null
-+++ b/test/data/valid-config-files/check-1.conf
-@@ -0,0 +1,9 @@
-+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
-+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-+<busconfig>
-+  <user>mybususer</user>
-+  <listen>unix:path=/foo/bar</listen>
-+  <policy context="default">
-+    <check privilege="foo" send_destination="*"/>
-+  </policy>
-+</busconfig>
-diff --git a/test/data/valid-config-files/debug-check-some.conf.in b/test/data/valid-config-files/debug-check-some.conf.in
-new file mode 100644
-index 0000000..47ee854
---- /dev/null
-+++ b/test/data/valid-config-files/debug-check-some.conf.in
-@@ -0,0 +1,18 @@
-+<!-- Bus that listens on a debug pipe and doesn't create any restrictions -->
-+
-+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
-+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-+<busconfig>
-+  <listen>debug-pipe:name=test-server</listen>
-+  <listen>@TEST_LISTEN@</listen>
-+  <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir>
-+  <policy context="default">
-+    <allow send_interface="*"/>
-+    <allow receive_interface="*"/>
-+    <allow own="*"/>
-+    <allow user="*"/>
-+
-+    <deny send_interface="org.freedesktop.TestSuite" send_member="Echo"/>
-+    <check privilege="foo" send_interface="org.freedesktop.TestSuite" send_member="Echo"/>
-+  </policy>
-+</busconfig>
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Disable-message-dispatching-when-send-rule-result-is.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Disable-message-dispatching-when-send-rule-result-is.patch
deleted file mode 100644 (file)
index ca78714..0000000
+++ /dev/null
@@ -1,941 +0,0 @@
-From b1b87ad9f20b2052c28431b48e81073078a745ce Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Fri, 28 Nov 2014 12:07:39 +0100
-Subject: [PATCH 5/8] Disable message dispatching when send rule result is not
- known
-
-When unicast message is sent to addressed recipient and policy result
-is not available message dispatch from the sender is disabled.
-This also means that any further messages from the given connection are
-put into the incoming queue without being processed. If response is received
-message dispatching is resumed. This time answer is attached to the message
-which is now processed synchronously.
-Receive rule result unavailability is not yet handled - such messages are
-rejected. Also, if message is sent to non-addressed recipient and policy result
-is unknown, message is silently dropped.
-
-Change-Id: I57eccbf973525fd51369c7d4e58908292f44da80
----
- bus/activation.c                |  79 +++++++++++++++--
- bus/check.c                     | 109 ++++++++++++++++++++++--
- bus/check.h                     |  10 +++
- bus/cynara.c                    |   1 -
- bus/dispatch.c                  | 183 ++++++++++++++++++++++++++++++++++++----
- bus/dispatch.h                  |   2 +-
- bus/driver.c                    |  13 ++-
- dbus/dbus-connection-internal.h |   9 ++
- dbus/dbus-connection.c          | 125 +++++++++++++++++++++++++--
- dbus/dbus-list.c                |  29 +++++++
- dbus/dbus-list.h                |   2 +
- dbus/dbus-shared.h              |   3 +-
- 12 files changed, 522 insertions(+), 43 deletions(-)
-
-diff --git a/bus/activation.c b/bus/activation.c
-index ecd19bb..8c43941 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -31,6 +31,7 @@
- #include "services.h"
- #include "test.h"
- #include "utils.h"
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-internals.h>
- #include <dbus/dbus-hash.h>
- #include <dbus/dbus-list.h>
-@@ -91,6 +92,8 @@ struct BusPendingActivationEntry
-   DBusConnection *connection;
-   dbus_bool_t auto_activation;
-+
-+  dbus_bool_t is_put_back;
- };
- typedef struct
-@@ -1180,20 +1183,23 @@ bus_activation_send_pending_auto_activation_messages (BusActivation  *activation
-       BusPendingActivationEntry *entry = link->data;
-       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
--      if (entry->auto_activation && (entry->connection == NULL || dbus_connection_get_is_connected (entry->connection)))
-+      if (entry->auto_activation && !entry->is_put_back &&
-+          (entry->connection == NULL || dbus_connection_get_is_connected (entry->connection)))
-         {
-           DBusConnection *addressed_recipient;
-           DBusError error;
-+          BusResult res;
-           dbus_error_init (&error);
-           addressed_recipient = bus_service_get_primary_owners_connection (service);
-           /* Resume dispatching where we left off in bus_dispatch() */
--          if (!bus_dispatch_matches (transaction,
--                                     entry->connection,
--                                     addressed_recipient,
--                                     entry->activation_message, &error))
-+          res = bus_dispatch_matches (transaction,
-+                                      entry->connection,
-+                                      addressed_recipient,
-+                                      entry->activation_message, &error);
-+          if (res == BUS_RESULT_FALSE)
-             {
-               /* If permission is denied, we just want to return the error
-                * to the original method invoker; in particular, we don't
-@@ -1205,9 +1211,40 @@ bus_activation_send_pending_auto_activation_messages (BusActivation  *activation
-                   bus_connection_send_oom_error (entry->connection,
-                                                  entry->activation_message);
-                 }
-+            }
-+          else if (res == BUS_RESULT_LATER)
-+            {
-+              DBusList *putback_message_link = link;
-+              DBusMessage *last_inserted_message = NULL;
-+
-+              /* NULL entry->connection implies sending pending ActivationRequest message to systemd */
-+              if (entry->connection == NULL)
-+                {
-+                  _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly when sender is NULL");
-+                  link = next;
-+                  continue;
-+                }
--              link = next;
--              continue;
-+              /**
-+               * Getting here means that policy check result is not yet available and dispatching
-+               * messages from entry->connection has been disabled.
-+               * Let's put back all messages for the given connection in the incoming queue and mark
-+               * this entry as put back so they are not handled twice.
-+               */
-+              while (putback_message_link != NULL)
-+                {
-+                  BusPendingActivationEntry *putback_message = putback_message_link->data;
-+                  if (putback_message->connection == entry->connection)
-+                    {
-+                      if (!_dbus_connection_putback_message (putback_message->connection, last_inserted_message,
-+                            putback_message->activation_message, &error))
-+                        goto error;
-+                      last_inserted_message = putback_message->activation_message;
-+                      putback_message->is_put_back = TRUE;
-+                    }
-+
-+                  putback_message_link = _dbus_list_get_next_link(&pending_activation->entries, putback_message_link);
-+                }
-             }
-         }
-@@ -1225,6 +1262,19 @@ bus_activation_send_pending_auto_activation_messages (BusActivation  *activation
-   return TRUE;
-  error:
-+  /* remove all messages that have been put to connections' incoming queues */
-+  link = _dbus_list_get_first_link (&pending_activation->entries);
-+  while (link != NULL)
-+    {
-+      BusPendingActivationEntry *entry = link->data;
-+      if (entry->is_put_back)
-+        {
-+          _dbus_connection_remove_message(entry->connection, entry->activation_message);
-+          entry->is_put_back = FALSE;
-+        }
-+      link = _dbus_list_get_next_link(&pending_activation->entries, link);
-+    }
-+
-   return FALSE;
- }
-@@ -2009,13 +2059,24 @@ bus_activation_activate_service (BusActivation  *activation,
-           if (service != NULL)
-             {
-+              BusResult res;
-               bus_context_log (activation->context,
-                                DBUS_SYSTEM_LOG_INFO, "Activating via systemd: service name='%s' unit='%s'",
-                                service_name,
-                                entry->systemd_service);
-               /* Wonderful, systemd is connected, let's just send the msg */
--              retval = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
--                                             message, error);
-+              res = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
-+                                            message, error);
-+
-+              if (res == BUS_RESULT_TRUE)
-+                retval = TRUE;
-+              else if (res == BUS_RESULT_FALSE)
-+                retval = FALSE;
-+              else if (res == BUS_RESULT_LATER)
-+                {
-+                  _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
-+                  retval = FALSE;
-+                }
-             }
-           else
-             {
-diff --git a/bus/check.c b/bus/check.c
-index d2f418a..cd6a74b 100644
---- a/bus/check.c
-+++ b/bus/check.c
-@@ -55,6 +55,8 @@ typedef struct BusDeferredMessage
-   BusCheckResponseFunc response_callback;
- } BusDeferredMessage;
-+static dbus_int32_t deferred_message_data_slot = -1;
-+
- BusCheck *
- bus_check_new (BusContext *context, DBusError *error)
- {
-@@ -67,11 +69,19 @@ bus_check_new (BusContext *context, DBusError *error)
-       return NULL;
-     }
-+  if (!dbus_message_allocate_data_slot(&deferred_message_data_slot))
-+    {
-+      dbus_free(check);
-+      BUS_SET_OOM(error);
-+      return NULL;
-+    }
-+
-   check->refcount = 1;
-   check->context = context;
-   check->cynara = bus_cynara_new(check, error);
-   if (dbus_error_is_set(error))
-     {
-+      dbus_message_free_data_slot(&deferred_message_data_slot);
-       dbus_free(check);
-       return NULL;
-     }
-@@ -98,6 +108,7 @@ bus_check_unref (BusCheck *check)
-   if (check->refcount == 0)
-     {
-       bus_cynara_unref(check->cynara);
-+      dbus_message_free_data_slot(&deferred_message_data_slot);
-       dbus_free(check);
-     }
- }
-@@ -114,6 +125,45 @@ bus_check_get_cynara (BusCheck *check)
-   return check->cynara;
- }
-+static void
-+bus_check_enable_dispatch_callback (BusDeferredMessage *deferred_message,
-+                                    BusResult result)
-+{
-+  _dbus_verbose("bus_check_enable_dispatch_callback called deferred_message=%p\n", deferred_message);
-+
-+  deferred_message->response = result;
-+  _dbus_connection_enable_dispatch(deferred_message->sender);
-+}
-+
-+static void
-+deferred_message_free_function(void *data)
-+{
-+  BusDeferredMessage *deferred_message = (BusDeferredMessage *)data;
-+  bus_deferred_message_unref(deferred_message);
-+}
-+
-+void
-+bus_deferred_message_disable_sender (BusDeferredMessage *deferred_message)
-+{
-+  _dbus_assert(deferred_message != NULL);
-+  _dbus_assert(deferred_message->sender != NULL);
-+
-+  if (dbus_message_get_data(deferred_message->message, deferred_message_data_slot) == NULL)
-+    {
-+      if (dbus_message_set_data(deferred_message->message, deferred_message_data_slot, deferred_message,
-+          deferred_message_free_function))
-+        bus_deferred_message_ref(deferred_message);
-+    }
-+
-+  _dbus_connection_disable_dispatch(deferred_message->sender);
-+  deferred_message->response_callback = bus_check_enable_dispatch_callback;
-+}
-+
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+dbus_bool_t (*bus_check_test_override) (DBusConnection *connection,
-+                                        const char *privilege);
-+#endif
-+
- BusResult
- bus_check_privilege (BusCheck *check,
-                      DBusMessage *message,
-@@ -124,6 +174,7 @@ bus_check_privilege (BusCheck *check,
-                      BusDeferredMessageStatus check_type,
-                      BusDeferredMessage **deferred_message)
- {
-+  BusDeferredMessage *previous_deferred_message;
-   BusResult result = BUS_RESULT_FALSE;
-   BusCynara *cynara;
-   DBusConnection *connection;
-@@ -135,16 +186,54 @@ bus_check_privilege (BusCheck *check,
-       return BUS_RESULT_FALSE;
-     }
--  /* ask policy checkers */
--#ifdef DBUS_ENABLE_CYNARA
--  cynara = bus_check_get_cynara(check);
--  result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
--      proposed_recipient, privilege, check_type, deferred_message);
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+  if (bus_check_test_override)
-+    return bus_check_test_override (connection, privilege);
- #endif
--  if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+  previous_deferred_message = dbus_message_get_data(message, deferred_message_data_slot);
-+  /* check if message blocked at sender's queue is being processed */
-+  if (previous_deferred_message != NULL)
-+    {
-+      if ((check_type & BUS_DEFERRED_MESSAGE_CHECK_SEND) &&
-+          !(previous_deferred_message->status & BUS_DEFERRED_MESSAGE_CHECK_SEND))
-+        {
-+          /**
-+           * Message has been deferred due to receive or own rule which means that sending this message
-+           * is allowed - it must have been checked previously.
-+           * This might happen when client calls RequestName method which depending on security
-+           * policy might result in both "can_send" and "can_own" Cynara checks.
-+           */
-+          result = BUS_RESULT_TRUE;
-+        }
-+      else
-+        {
-+          result = previous_deferred_message->response;
-+          if (result == BUS_RESULT_LATER)
-+            {
-+              /* result is still not known - reuse deferred message object */
-+              if (deferred_message != NULL)
-+                *deferred_message = previous_deferred_message;
-+            }
-+          else
-+            {
-+              /* result is available - we can remove deferred message from the processed message */
-+              dbus_message_set_data(message, deferred_message_data_slot, NULL, NULL);
-+            }
-+        }
-+    }
-+  else
-     {
--      (*deferred_message)->status |= check_type;
-+      /* ask policy checkers */
-+#ifdef DBUS_ENABLE_CYNARA
-+      cynara = bus_check_get_cynara(check);
-+      result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
-+          proposed_recipient, privilege, check_type, deferred_message);
-+#endif
-+      if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+        {
-+          (*deferred_message)->status |= check_type;
-+        }
-     }
-   return result;
- }
-@@ -204,6 +293,12 @@ bus_deferred_message_unref (BusDeferredMessage *deferred_message)
-      }
- }
-+BusDeferredMessageStatus
-+bus_deferred_message_get_status (BusDeferredMessage *deferred_message)
-+{
-+  return deferred_message->status;
-+}
-+
- void
- bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
-                                         BusResult result)
-diff --git a/bus/check.h b/bus/check.h
-index c3fcaf9..f381789 100644
---- a/bus/check.h
-+++ b/bus/check.h
-@@ -55,6 +55,7 @@ BusResult   bus_check_privilege   (BusCheck *check,
-                                    BusDeferredMessageStatus check_type,
-                                    BusDeferredMessage **deferred_message);
-+
- BusDeferredMessage *bus_deferred_message_new                (DBusMessage *message,
-                                                              DBusConnection *sender,
-                                                              DBusConnection *addressed_recipient,
-@@ -65,4 +66,13 @@ BusDeferredMessage *bus_deferred_message_ref                (BusDeferredMessage
- void                bus_deferred_message_unref              (BusDeferredMessage *deferred_message);
- void                bus_deferred_message_response_received  (BusDeferredMessage *deferred_message,
-                                                              BusResult result);
-+void                bus_deferred_message_disable_sender     (BusDeferredMessage *deferred_message);
-+
-+BusDeferredMessageStatus  bus_deferred_message_get_status   (BusDeferredMessage *deferred_message);
-+
-+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-+extern dbus_bool_t (*bus_check_test_override) (DBusConnection *connection,
-+                                               const char *privilege);
-+#endif
-+
- #endif /* BUS_CHECK_H */
-diff --git a/bus/cynara.c b/bus/cynara.c
-index 57a4c45..77aed62 100644
---- a/bus/cynara.c
-+++ b/bus/cynara.c
-@@ -36,7 +36,6 @@
- #include <cynara-client-async.h>
- #endif
--
- #ifdef DBUS_ENABLE_CYNARA
- typedef struct BusCynara
- {
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index ce4076d..6b0eadc 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -81,7 +81,7 @@ send_one_message (DBusConnection *connection,
-   return TRUE;
- }
--dbus_bool_t
-+BusResult
- bus_dispatch_matches (BusTransaction *transaction,
-                       DBusConnection *sender,
-                       DBusConnection *addressed_recipient,
-@@ -117,13 +117,29 @@ bus_dispatch_matches (BusTransaction *transaction,
-                                                message, error,
-                                                &deferred_message);
-       if (res == BUS_RESULT_FALSE)
--        return FALSE;
-+        return BUS_RESULT_FALSE;
-       else if (res == BUS_RESULT_LATER)
-         {
--          dbus_set_error (error,
--                          DBUS_ERROR_ACCESS_DENIED,
--                          "Rejecting message because time is needed to check security policy");
--          return FALSE;
-+          BusDeferredMessageStatus status;
-+          status = bus_deferred_message_get_status(deferred_message);
-+
-+          if (status & BUS_DEFERRED_MESSAGE_CHECK_SEND)
-+            {
-+              /* send rule result not available - disable dispatching messages from the sender */
-+              bus_deferred_message_disable_sender(deferred_message);
-+              return BUS_RESULT_LATER;
-+            }
-+          else if (status & BUS_DEFERRED_MESSAGE_CHECK_RECEIVE)
-+            {
-+              dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-+                              "Rejecting message because time is needed to check security policy");
-+              return BUS_RESULT_FALSE;
-+            }
-+          else
-+            {
-+              _dbus_verbose("deferred message has no status field set to send or receive unexpectedly\n");
-+              return BUS_RESULT_FALSE;
-+            }
-         }
-       if (dbus_message_contains_unix_fds (message) &&
-@@ -134,14 +150,14 @@ bus_dispatch_matches (BusTransaction *transaction,
-                           DBUS_ERROR_NOT_SUPPORTED,
-                           "Tried to send message with Unix file descriptors"
-                           "to a client that doesn't support that.");
--          return FALSE;
--      }
-+          return BUS_RESULT_FALSE;
-+        }
-       /* Dispatch the message */
-       if (!bus_transaction_send (transaction, addressed_recipient, message))
-         {
-           BUS_SET_OOM (error);
--          return FALSE;
-+          return BUS_RESULT_FALSE;
-         }
-     }
-@@ -156,7 +172,7 @@ bus_dispatch_matches (BusTransaction *transaction,
-                                       &recipients))
-     {
-       BUS_SET_OOM (error);
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
-   link = _dbus_list_get_first_link (&recipients);
-@@ -178,10 +194,10 @@ bus_dispatch_matches (BusTransaction *transaction,
-   if (dbus_error_is_set (&tmp_error))
-     {
-       dbus_move_error (&tmp_error, error);
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
-   else
--    return TRUE;
-+    return BUS_RESULT_TRUE;
- }
- static DBusHandlerResult
-@@ -298,10 +314,12 @@ bus_dispatch (DBusConnection *connection,
-         }
-       else if (res == BUS_RESULT_LATER)
-         {
--          dbus_set_error (&error,
--                          DBUS_ERROR_ACCESS_DENIED,
--                          "Rejecting message because time is needed to check security policy");
--          _dbus_verbose ("Security policy needs time to check policy. Dropping message\n");
-+          /* Disable dispatching messages from the sender,
-+           * roll back and dispatch the message once the policy result is available */
-+          bus_deferred_message_disable_sender(deferred_message);
-+          bus_transaction_cancel_and_free (transaction);
-+          transaction = NULL;
-+          result = DBUS_HANDLER_RESULT_LATER;
-           goto out;
-         }
-@@ -366,8 +384,14 @@ bus_dispatch (DBusConnection *connection,
-    * addressed_recipient == NULL), and match it against other connections'
-    * match rules.
-    */
--  if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
--    goto out;
-+  if (BUS_RESULT_LATER == bus_dispatch_matches (transaction, connection, addressed_recipient,
-+                                                message, &error))
-+    {
-+      /* Roll back and dispatch the message once the policy result is available */
-+      bus_transaction_cancel_and_free (transaction);
-+      transaction = NULL;
-+      result = DBUS_HANDLER_RESULT_LATER;
-+    }
-  out:
-   if (dbus_error_is_set (&error))
-@@ -4714,9 +4738,132 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
-   return TRUE;
- }
-+typedef struct {
-+  DBusTimeout *timeout;
-+  DBusConnection *connection;
-+  dbus_bool_t timedout;
-+  int check_counter;
-+} BusTestCheckData;
-+
-+static BusTestCheckData *cdata;
-+
-+static dbus_bool_t
-+bus_dispatch_test_check_timeout (void *data)
-+{
-+  _dbus_verbose ("timeout triggered - pretend that privilege check result is available\n");
-+
-+  /* should only happen once during the test */
-+  _dbus_assert (!cdata->timedout);
-+  cdata->timedout = TRUE;
-+  _dbus_connection_enable_dispatch (cdata->connection);
-+
-+  /* don't call this again */
-+  _dbus_loop_remove_timeout (bus_connection_get_loop (cdata->connection),
-+                             cdata->timeout);
-+  dbus_connection_unref (cdata->connection);
-+  cdata->connection = NULL;
-+  return TRUE;
-+}
-+
-+static dbus_bool_t
-+bus_dispatch_test_check_override (DBusConnection *connection,
-+                                  const char *privilege)
-+{
-+  _dbus_verbose ("overriding privilege check %s #%d\n", privilege, cdata->check_counter);
-+  cdata->check_counter++;
-+  if (!cdata->timedout)
-+    {
-+      dbus_bool_t added;
-+
-+      /* Should be the first privilege check for the "Echo" method. */
-+      _dbus_assert (cdata->check_counter == 1);
-+      cdata->timeout = _dbus_timeout_new (1, bus_dispatch_test_check_timeout,
-+                                          NULL, NULL);
-+      _dbus_assert (cdata->timeout);
-+      added = _dbus_loop_add_timeout (bus_connection_get_loop (connection),
-+                                      cdata->timeout);
-+      _dbus_assert (added);
-+      cdata->connection = connection;
-+      dbus_connection_ref (connection);
-+      _dbus_connection_disable_dispatch (connection);
-+      return BUS_RESULT_LATER;
-+    }
-+  else
-+    {
-+      /* Should only be checked one more time, and this time succeeds. */
-+      _dbus_assert (cdata->check_counter == 2);
-+      return BUS_RESULT_TRUE;
-+    }
-+}
-+
-+static dbus_bool_t
-+bus_dispatch_test_check (const DBusString *test_data_dir)
-+{
-+  const char *filename = "valid-config-files/debug-check-some.conf";
-+  BusContext *context;
-+  DBusConnection *foo;
-+  DBusError error;
-+  dbus_bool_t result = TRUE;
-+  BusTestCheckData data;
-+
-+  /* save the config name for the activation helper */
-+  if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
-+    _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");
-+
-+  dbus_error_init (&error);
-+
-+  context = bus_context_new_test (test_data_dir, filename);
-+  if (context == NULL)
-+    return FALSE;
-+
-+  foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
-+  if (foo == NULL)
-+    _dbus_assert_not_reached ("could not alloc connection");
-+
-+  if (!bus_setup_debug_client (foo))
-+    _dbus_assert_not_reached ("could not set up connection");
-+
-+  spin_connection_until_authenticated (context, foo);
-+
-+  if (!check_hello_message (context, foo))
-+    _dbus_assert_not_reached ("hello message failed");
-+
-+  if (!check_double_hello_message (context, foo))
-+    _dbus_assert_not_reached ("double hello message failed");
-+
-+  if (!check_add_match_all (context, foo))
-+    _dbus_assert_not_reached ("AddMatch message failed");
-+
-+  /*
-+   * Cause bus_check_send_privilege() to return BUS_RESULT_LATER in the
-+   * first call, then BUS_RESULT_TRUE.
-+   */
-+  cdata = &data;
-+  memset (cdata, 0, sizeof(*cdata));
-+  bus_check_test_override = bus_dispatch_test_check_override;
-+
-+  result = check_existent_service_auto_start (context, foo);
-+
-+  _dbus_assert (cdata->check_counter == 2);
-+  _dbus_assert (cdata->timedout);
-+  _dbus_assert (cdata->timeout);
-+  _dbus_assert (!cdata->connection);
-+  _dbus_timeout_unref (cdata->timeout);
-+
-+  kill_client_connection_unchecked (foo);
-+
-+  bus_context_unref (context);
-+
-+  return result;
-+}
-+
- dbus_bool_t
- bus_dispatch_test (const DBusString *test_data_dir)
- {
-+  _dbus_verbose ("<check> tests\n");
-+  if (!bus_dispatch_test_check (test_data_dir))
-+    return FALSE;
-+
-   /* run normal activation tests */
-   _dbus_verbose ("Normal activation tests\n");
-   if (!bus_dispatch_test_conf (test_data_dir,
-diff --git a/bus/dispatch.h b/bus/dispatch.h
-index fb5ba7a..afba6a2 100644
---- a/bus/dispatch.h
-+++ b/bus/dispatch.h
-@@ -29,7 +29,7 @@
- dbus_bool_t bus_dispatch_add_connection    (DBusConnection *connection);
- void        bus_dispatch_remove_connection (DBusConnection *connection);
--dbus_bool_t bus_dispatch_matches           (BusTransaction *transaction,
-+BusResult   bus_dispatch_matches           (BusTransaction *transaction,
-                                             DBusConnection *sender,
-                                             DBusConnection *recipient,
-                                             DBusMessage    *message,
-diff --git a/bus/driver.c b/bus/driver.c
-index 11706f8..4dbce3d 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -97,6 +97,7 @@ bus_driver_send_service_owner_changed (const char     *service_name,
- {
-   DBusMessage *message;
-   dbus_bool_t retval;
-+  BusResult res;
-   const char *null_service;
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -129,7 +130,17 @@ bus_driver_send_service_owner_changed (const char     *service_name,
-   _dbus_assert (dbus_message_has_signature (message, "sss"));
--  retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
-+  res = bus_dispatch_matches (transaction, NULL, NULL, message, error);
-+  if (res == BUS_RESULT_TRUE)
-+    retval = TRUE;
-+  else if (res == BUS_RESULT_FALSE)
-+    retval = FALSE;
-+  else if (res == BUS_RESULT_LATER)
-+    {
-+      /* should never happen */
-+      _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
-+      retval = FALSE;
-+    }
-   dbus_message_unref (message);
-   return retval;
-diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
-index 64ef336..4fcd118 100644
---- a/dbus/dbus-connection-internal.h
-+++ b/dbus/dbus-connection-internal.h
-@@ -109,6 +109,15 @@ void              _dbus_connection_set_pending_fds_function       (DBusConnectio
- dbus_bool_t       _dbus_connection_get_linux_security_label       (DBusConnection  *connection,
-                                                                    char           **label_p);
-+void              _dbus_connection_enable_dispatch                (DBusConnection *connection);
-+void              _dbus_connection_disable_dispatch               (DBusConnection *connection);
-+dbus_bool_t       _dbus_connection_putback_message                (DBusConnection *connection,
-+                                                                   DBusMessage    *after_message,
-+                                                                   DBusMessage    *message,
-+                                                                   DBusError      *error);
-+
-+dbus_bool_t       _dbus_connection_remove_message                 (DBusConnection *connection,
-+                                                                   DBusMessage    *message);
- /* if DBUS_ENABLE_STATS */
- void _dbus_connection_get_stats (DBusConnection *connection,
-diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
-index 8952b75..5d8d943 100644
---- a/dbus/dbus-connection.c
-+++ b/dbus/dbus-connection.c
-@@ -311,7 +311,8 @@ struct DBusConnection
-    */
-   dbus_bool_t dispatch_acquired; /**< Someone has dispatch path (can drain incoming queue) */
-   dbus_bool_t io_path_acquired;  /**< Someone has transport io path (can use the transport to read/write messages) */
--  
-+
-+  unsigned int dispatch_disabled : 1;  /**< if true, then dispatching incoming messages is stopped until enabled again */
-   unsigned int shareable : 1; /**< #TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more than once */
-   
-   unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
-@@ -439,6 +440,39 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection)
-     (*connection->wakeup_main_function) (connection->wakeup_main_data);
- }
-+static void
-+_dbus_connection_set_dispatch(DBusConnection *connection,
-+                              dbus_bool_t disabled)
-+{
-+  CONNECTION_LOCK (connection);
-+  if (connection->dispatch_disabled != disabled)
-+    {
-+      DBusDispatchStatus status;
-+
-+      connection->dispatch_disabled = disabled;
-+      status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+      _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+    }
-+  else
-+    {
-+      CONNECTION_UNLOCK (connection);
-+    }
-+}
-+
-+
-+void
-+_dbus_connection_enable_dispatch (DBusConnection *connection)
-+{
-+  _dbus_connection_set_dispatch (connection, FALSE);
-+}
-+
-+void
-+ _dbus_connection_disable_dispatch (DBusConnection *connection)
-+{
-+  _dbus_connection_set_dispatch (connection, TRUE);
-+}
-+
-+
- #ifdef DBUS_ENABLE_EMBEDDED_TESTS
- /**
-  * Gets the locks so we can examine them
-@@ -4068,6 +4102,82 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
-       "_dbus_connection_putback_message_link_unlocked");
- }
-+dbus_bool_t
-+_dbus_connection_putback_message (DBusConnection *connection,
-+                                  DBusMessage    *after_message,
-+                                  DBusMessage    *message,
-+                                  DBusError      *error)
-+{
-+  DBusDispatchStatus status;
-+  DBusList *message_link = _dbus_list_alloc_link (message);
-+  DBusList *after_link;
-+  if (message_link == NULL)
-+    {
-+      _DBUS_SET_OOM (error);
-+      return FALSE;
-+    }
-+  dbus_message_ref (message);
-+
-+  CONNECTION_LOCK (connection);
-+  _dbus_connection_acquire_dispatch (connection);
-+  HAVE_LOCK_CHECK (connection);
-+
-+  after_link = _dbus_list_find_first(&connection->incoming_messages, after_message);
-+  _dbus_list_insert_after_link (&connection->incoming_messages, after_link, message_link);
-+  connection->n_incoming += 1;
-+
-+  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
-+                 message_link->data,
-+                 dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
-+                 dbus_message_get_interface (message_link->data) ?
-+                 dbus_message_get_interface (message_link->data) :
-+                 "no interface",
-+                 dbus_message_get_member (message_link->data) ?
-+                 dbus_message_get_member (message_link->data) :
-+                 "no member",
-+                 dbus_message_get_signature (message_link->data),
-+                 connection, connection->n_incoming);
-+
-+  _dbus_message_trace_ref (message_link->data, -1, -1,
-+      "_dbus_connection_putback_message");
-+
-+  _dbus_connection_release_dispatch (connection);
-+
-+  status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+
-+  return TRUE;
-+}
-+
-+dbus_bool_t
-+_dbus_connection_remove_message (DBusConnection *connection,
-+                                 DBusMessage *message)
-+{
-+  DBusDispatchStatus status;
-+  dbus_bool_t removed;
-+
-+  CONNECTION_LOCK (connection);
-+  _dbus_connection_acquire_dispatch (connection);
-+  HAVE_LOCK_CHECK (connection);
-+
-+  removed = _dbus_list_remove(&connection->incoming_messages, message);
-+
-+  if (removed)
-+    {
-+      connection->n_incoming -= 1;
-+      dbus_message_unref(message);
-+      _dbus_verbose ("Message %p removed from incoming queue\n", message);
-+    }
-+  else
-+      _dbus_verbose ("Message %p not found in the incoming queue\n", message);
-+
-+  _dbus_connection_release_dispatch (connection);
-+
-+  status = _dbus_connection_get_dispatch_status_unlocked (connection);
-+  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
-+  return removed;
-+}
-+
- /**
-  * Returns the first-received message from the incoming message queue,
-  * removing it from the queue. The caller owns a reference to the
-@@ -4251,8 +4361,9 @@ static DBusDispatchStatus
- _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
- {
-   HAVE_LOCK_CHECK (connection);
--  
--  if (connection->n_incoming > 0)
-+  if (connection->dispatch_disabled && dbus_connection_get_is_connected(connection))
-+    return DBUS_DISPATCH_COMPLETE;
-+  else if (connection->n_incoming > 0)
-     return DBUS_DISPATCH_DATA_REMAINS;
-   else if (!_dbus_transport_queue_messages (connection->transport))
-     return DBUS_DISPATCH_NEED_MEMORY;
-@@ -4689,6 +4800,8 @@ dbus_connection_dispatch (DBusConnection *connection)
-   
-   CONNECTION_LOCK (connection);
-+  if (result == DBUS_HANDLER_RESULT_LATER)
-+      goto out;
-   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-     {
-       _dbus_verbose ("No memory\n");
-@@ -4811,9 +4924,11 @@ dbus_connection_dispatch (DBusConnection *connection)
-                  connection);
-   
-  out:
--  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-+  if (result == DBUS_HANDLER_RESULT_LATER ||
-+      result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-     {
--      _dbus_verbose ("out of memory\n");
-+      if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
-+        _dbus_verbose ("out of memory\n");
-       
-       /* Put message back, and we'll start over.
-        * Yes this means handlers must be idempotent if they
-diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c
-index c4c1856..f84918b 100644
---- a/dbus/dbus-list.c
-+++ b/dbus/dbus-list.c
-@@ -459,6 +459,35 @@ _dbus_list_remove_last (DBusList **list,
- }
- /**
-+ * Finds a value in the list. Returns the first link
-+ * with value equal to the given data pointer.
-+ * This is a linear-time operation.
-+ * Returns #NULL if no value found that matches.
-+ *
-+ * @param list address of the list head.
-+ * @param data the value to find.
-+ * @returns the link if found
-+ */
-+DBusList*
-+_dbus_list_find_first (DBusList **list,
-+                       void      *data)
-+{
-+  DBusList *link;
-+
-+  link = _dbus_list_get_first_link (list);
-+
-+  while (link != NULL)
-+    {
-+      if (link->data == data)
-+        return link;
-+
-+      link = _dbus_list_get_next_link (list, link);
-+    }
-+
-+  return NULL;
-+}
-+
-+/**
-  * Finds a value in the list. Returns the last link
-  * with value equal to the given data pointer.
-  * This is a linear-time operation.
-diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h
-index 910d738..abe8331 100644
---- a/dbus/dbus-list.h
-+++ b/dbus/dbus-list.h
-@@ -59,6 +59,8 @@ dbus_bool_t _dbus_list_remove_last        (DBusList **list,
-                                            void      *data);
- void        _dbus_list_remove_link        (DBusList **list,
-                                            DBusList  *link);
-+DBusList*   _dbus_list_find_first         (DBusList **list,
-+                                           void      *data);
- DBusList*   _dbus_list_find_last          (DBusList **list,
-                                            void      *data);
- void        _dbus_list_clear              (DBusList **list);
-diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h
-index 6a57670..5371d88 100644
---- a/dbus/dbus-shared.h
-+++ b/dbus/dbus-shared.h
-@@ -67,7 +67,8 @@ typedef enum
- {
-   DBUS_HANDLER_RESULT_HANDLED,         /**< Message has had its effect - no need to run more handlers. */ 
-   DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
--  DBUS_HANDLER_RESULT_NEED_MEMORY      /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
-+  DBUS_HANDLER_RESULT_NEED_MEMORY,     /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
-+  DBUS_HANDLER_RESULT_LATER            /**< Message dispatch deferred due to pending policy check */
- } DBusHandlerResult;
- /* Bus names */
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Handle-unavailability-of-policy-results-for-broadcas.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Handle-unavailability-of-policy-results-for-broadcas.patch
deleted file mode 100644 (file)
index 66f4e14..0000000
+++ /dev/null
@@ -1,1071 +0,0 @@
-From 1e231194610892dd4360224998d91336097b05a1 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Fri, 28 Nov 2014 12:39:33 +0100
-Subject: [PATCH 6/8] Handle unavailability of policy results for broadcasts
- and receive rules
-
-When message is sent to the addressed recipient and receive rule
-result is unavailable we don't want to block the sender
-as it most likely will be the privileged service, so instead we queue
-it at the recipient. Any further messages sent to it will be queued to
-maintain message order. Once the answer from Cynara arrives messages are
-dispatched from the recipient queue. In such case full dispatch is
-performed - messages are sent to addressed recipient and other
-interested connections.
-Messages sent to non-addressed recipients (eavesdroppers or broadcast
-message recipients) are handled in a similar way. The difference is
-that it is not full dispatch meaning message is sent to a single recipient.
-
-Change-Id: Iecd5395f75a4c7811fa97247a37d8fc4d42e8814
----
- bus/activation.c |   4 +-
- bus/bus.c        |  50 +++++++--
- bus/bus.h        |  19 ++++
- bus/check.c      | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- bus/check.h      |  25 +++++
- bus/connection.c | 166 ++++++++++++++++++++++++++++--
- bus/connection.h |  19 +++-
- bus/dispatch.c   | 122 ++++++++++++++++++----
- bus/dispatch.h   |  11 +-
- bus/driver.c     |   2 +-
- bus/policy.c     |   6 ++
- 11 files changed, 685 insertions(+), 46 deletions(-)
-
-diff --git a/bus/activation.c b/bus/activation.c
-index 8c43941..308bf41 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -1198,7 +1198,7 @@ bus_activation_send_pending_auto_activation_messages (BusActivation  *activation
-           res = bus_dispatch_matches (transaction,
-                                       entry->connection,
-                                       addressed_recipient,
--                                      entry->activation_message, &error);
-+                                      entry->activation_message, NULL, &error);
-           if (res == BUS_RESULT_FALSE)
-             {
-               /* If permission is denied, we just want to return the error
-@@ -2066,7 +2066,7 @@ bus_activation_activate_service (BusActivation  *activation,
-                                entry->systemd_service);
-               /* Wonderful, systemd is connected, let's just send the msg */
-               res = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
--                                            message, error);
-+                                          message, NULL, error);
-               if (res == BUS_RESULT_TRUE)
-                 retval = TRUE;
-diff --git a/bus/bus.c b/bus/bus.c
-index ac9ea8d..b478b8e 100644
---- a/bus/bus.c
-+++ b/bus/bus.c
-@@ -1704,17 +1704,9 @@ bus_context_check_security_policy (BusContext          *context,
-     }
-   /* See if limits on size have been exceeded */
--  if (proposed_recipient &&
--      ((dbus_connection_get_outgoing_size (proposed_recipient) > context->limits.max_outgoing_bytes) ||
--       (dbus_connection_get_outgoing_unix_fds (proposed_recipient) > context->limits.max_outgoing_unix_fds)))
--    {
--      complain_about_message (context, DBUS_ERROR_LIMITS_EXCEEDED,
--          "Rejected: destination has a full message queue",
--          0, message, sender, proposed_recipient, requested_reply, TRUE, NULL,
--          error);
--      _dbus_verbose ("security policy disallowing message due to full message queue\n");
-+  if (!bus_context_check_recipient_message_limits(context, proposed_recipient, sender, message,
-+      requested_reply, error))
-       return BUS_RESULT_FALSE;
--    }
-   /* Record that we will allow a reply here in the future (don't
-    * bother if the recipient is the bus or this is an eavesdropping
-@@ -1769,3 +1761,41 @@ bus_context_check_all_watches (BusContext *context)
-       _dbus_server_toggle_all_watches (server, enabled);
-     }
- }
-+
-+void
-+bus_context_complain_about_message (BusContext     *context,
-+                                    const char     *error_name,
-+                                    const char     *complaint,
-+                                    int             matched_rules,
-+                                    DBusMessage    *message,
-+                                    DBusConnection *sender,
-+                                    DBusConnection *proposed_recipient,
-+                                    dbus_bool_t     requested_reply,
-+                                    dbus_bool_t     log,
-+                                    const char     *privilege,
-+                                    DBusError      *error)
-+{
-+  complain_about_message(context, error_name, complaint, matched_rules, message, sender,
-+      proposed_recipient, requested_reply, log, privilege, error);
-+}
-+
-+dbus_bool_t bus_context_check_recipient_message_limits (BusContext *context,
-+                                                        DBusConnection *recipient,
-+                                                        DBusConnection *sender,
-+                                                        DBusMessage *message,
-+                                                        dbus_bool_t requested_reply,
-+                                                        DBusError *error)
-+{
-+  if (recipient &&
-+       ((dbus_connection_get_outgoing_size (recipient) > context->limits.max_outgoing_bytes) ||
-+        (dbus_connection_get_outgoing_unix_fds (recipient) > context->limits.max_outgoing_unix_fds)))
-+     {
-+       complain_about_message (context, DBUS_ERROR_LIMITS_EXCEEDED,
-+           "Rejected: destination has a full message queue",
-+           0, message, sender, recipient, requested_reply, TRUE, NULL,
-+           error);
-+       _dbus_verbose ("security policy disallowing message due to full message queue\n");
-+       return FALSE;
-+     }
-+  return TRUE;
-+}
-diff --git a/bus/bus.h b/bus/bus.h
-index 78084dd..27a5e49 100644
---- a/bus/bus.h
-+++ b/bus/bus.h
-@@ -148,4 +148,23 @@ BusResult         bus_context_check_security_policy              (BusContext
-                                                                   DBusError           *error,
-                                                                   BusDeferredMessage **deferred_message);
-+dbus_bool_t       bus_context_check_recipient_message_limits     (BusContext *context,
-+                                                                  DBusConnection *recipient,
-+                                                                  DBusConnection *sender,
-+                                                                  DBusMessage *message,
-+                                                                  dbus_bool_t requested_reply,
-+                                                                  DBusError *error);
-+void              bus_context_complain_about_message             (BusContext     *context,
-+                                                                  const char     *error_name,
-+                                                                  const char     *complaint,
-+                                                                  int             matched_rules,
-+                                                                  DBusMessage    *message,
-+                                                                  DBusConnection *sender,
-+                                                                  DBusConnection *proposed_recipient,
-+                                                                  dbus_bool_t     requested_reply,
-+                                                                  dbus_bool_t     log,
-+                                                                  const char     *privilege,
-+                                                                  DBusError      *error);
-+
-+
- #endif /* BUS_BUS_H */
-diff --git a/bus/check.c b/bus/check.c
-index cd6a74b..733763a 100644
---- a/bus/check.c
-+++ b/bus/check.c
-@@ -49,6 +49,9 @@ typedef struct BusDeferredMessage
-   DBusConnection *sender;
-   DBusConnection *proposed_recipient;
-   DBusConnection *addressed_recipient;
-+  dbus_bool_t requested_reply;
-+  int matched_rules;
-+  const char *privilege;
-   dbus_bool_t full_dispatch;
-   BusDeferredMessageStatus status;
-   BusResult response;
-@@ -136,6 +139,89 @@ bus_check_enable_dispatch_callback (BusDeferredMessage *deferred_message,
- }
- static void
-+bus_check_queued_message_reply_callback (BusDeferredMessage *deferred_message,
-+                                         BusResult result)
-+{
-+  int status;
-+
-+  _dbus_verbose("bus_check_queued_message_reply_callback called message=%p\n", deferred_message);
-+
-+  if (!bus_connection_is_active(deferred_message->proposed_recipient))
-+    return;
-+
-+  status = deferred_message->status;
-+
-+  deferred_message->status = 0; /* mark message as not waiting for response */
-+  deferred_message->response = result;
-+
-+  /*
-+   * If send rule allows us to send message we still need to check receive rules.
-+   */
-+  if ((status & BUS_DEFERRED_MESSAGE_CHECK_SEND) && (result == BUS_RESULT_TRUE))
-+    {
-+      int toggles;
-+      BusContext *context;
-+      BusRegistry *registry;
-+      BusClientPolicy *recipient_policy;
-+      BusDeferredMessage *deferred_message_receive;
-+
-+      context = bus_connection_get_context(deferred_message->proposed_recipient);
-+      registry = bus_context_get_registry(context);
-+      recipient_policy = bus_connection_get_policy(deferred_message->proposed_recipient);
-+
-+      deferred_message->response = bus_client_policy_check_can_receive(recipient_policy, registry,
-+          deferred_message->requested_reply, deferred_message->sender,
-+          deferred_message->addressed_recipient, deferred_message->proposed_recipient, deferred_message->message,
-+          &toggles, NULL, &deferred_message_receive);
-+      if (deferred_message->response == BUS_RESULT_LATER)
-+        {
-+          /* replace deferred message associated with send check with the one associated with
-+           * receive check */
-+          if (!bus_deferred_message_replace(deferred_message, deferred_message_receive))
-+            {
-+              /* failed to replace deferred message (due to oom). Set it to rejected */
-+              deferred_message->response = BUS_RESULT_FALSE;
-+            }
-+        }
-+    }
-+
-+  bus_connection_dispatch_deferred(deferred_message->proposed_recipient);
-+}
-+
-+static void
-+queue_deferred_message_cancel_transaction_hook (void *data)
-+{
-+  BusDeferredMessage *deferred_message = (BusDeferredMessage *)data;
-+  bus_connection_remove_deferred_message(deferred_message->proposed_recipient, deferred_message);
-+}
-+
-+
-+dbus_bool_t
-+bus_deferred_message_queue_at_recipient (BusDeferredMessage *deferred_message,
-+                                         BusTransaction *transaction,
-+                                         dbus_bool_t full_dispatch,
-+                                         dbus_bool_t prepend)
-+{
-+  _dbus_assert(deferred_message != NULL);
-+  _dbus_assert(deferred_message->proposed_recipient != NULL);
-+
-+  if (!bus_connection_queue_deferred_message(deferred_message->proposed_recipient,
-+         deferred_message, prepend))
-+    return FALSE;
-+
-+  if (!bus_transaction_add_cancel_hook(transaction, queue_deferred_message_cancel_transaction_hook,
-+      deferred_message, NULL))
-+    {
-+      bus_connection_remove_deferred_message(deferred_message->proposed_recipient, deferred_message);
-+      return FALSE;
-+    }
-+  deferred_message->response_callback = bus_check_queued_message_reply_callback;
-+  deferred_message->full_dispatch = full_dispatch;
-+
-+  return TRUE;
-+}
-+
-+static void
- deferred_message_free_function(void *data)
- {
-   BusDeferredMessage *deferred_message = (BusDeferredMessage *)data;
-@@ -159,6 +245,20 @@ bus_deferred_message_disable_sender (BusDeferredMessage *deferred_message)
-   deferred_message->response_callback = bus_check_enable_dispatch_callback;
- }
-+void
-+bus_deferred_message_set_policy_check_info (BusDeferredMessage *deferred_message,
-+                                            dbus_bool_t requested_reply,
-+                                            int matched_rules,
-+                                            const char *privilege)
-+{
-+  _dbus_assert(deferred_message != NULL);
-+
-+  deferred_message->requested_reply = requested_reply;
-+  deferred_message->matched_rules = matched_rules;
-+  deferred_message->privilege = privilege;
-+}
-+
-+
- #ifdef DBUS_ENABLE_EMBEDDED_TESTS
- dbus_bool_t (*bus_check_test_override) (DBusConnection *connection,
-                                         const char *privilege);
-@@ -257,6 +357,9 @@ BusDeferredMessage *bus_deferred_message_new (DBusMessage *message,
-   deferred_message->addressed_recipient = addressed_recipient != NULL ? dbus_connection_ref(addressed_recipient) : NULL;
-   deferred_message->proposed_recipient = proposed_recipient != NULL ? dbus_connection_ref(proposed_recipient) : NULL;
-   deferred_message->message = dbus_message_ref(message);
-+  deferred_message->requested_reply = FALSE;
-+  deferred_message->matched_rules = 0;
-+  deferred_message->privilege = NULL;
-   deferred_message->response = response;
-   deferred_message->status = 0;
-   deferred_message->full_dispatch = FALSE;
-@@ -293,12 +396,215 @@ bus_deferred_message_unref (BusDeferredMessage *deferred_message)
-      }
- }
-+dbus_bool_t
-+bus_deferred_message_check_message_limits (BusDeferredMessage *deferred_message, DBusError *error)
-+{
-+  BusContext *context = bus_connection_get_context(deferred_message->proposed_recipient);
-+
-+  return bus_context_check_recipient_message_limits(context, deferred_message->proposed_recipient,
-+      deferred_message->sender, deferred_message->message, deferred_message->requested_reply,
-+      error);
-+}
-+
-+dbus_bool_t
-+bus_deferred_message_expect_method_reply(BusDeferredMessage *deferred_message, BusTransaction *transaction, DBusError *error)
-+{
-+  int type = dbus_message_get_type(deferred_message->message);
-+  if (type == DBUS_MESSAGE_TYPE_METHOD_CALL &&
-+        deferred_message->sender &&
-+        deferred_message->addressed_recipient &&
-+        deferred_message->addressed_recipient == deferred_message->proposed_recipient && /* not eavesdropping */
-+        !bus_connections_expect_reply (bus_connection_get_connections (deferred_message->sender),
-+                                       transaction,
-+                                       deferred_message->sender, deferred_message->addressed_recipient,
-+                                       deferred_message->message, error))
-+    {
-+      _dbus_verbose ("Failed to record reply expectation or problem with the message expecting a reply\n");
-+      return FALSE;
-+    }
-+  return TRUE;
-+}
-+
-+void
-+bus_deferred_message_create_error(BusDeferredMessage *deferred_message,
-+    const char *error_message, DBusError *error)
-+{
-+  BusContext *context;
-+  _dbus_assert (deferred_message->status == 0 && deferred_message->response == BUS_RESULT_FALSE);
-+
-+  if (deferred_message->sender == NULL)
-+    return; /* error won't be sent to bus driver anyway */
-+
-+  context = bus_connection_get_context(deferred_message->sender);
-+  bus_context_complain_about_message(context, DBUS_ERROR_ACCESS_DENIED, "Rejected message",
-+      deferred_message->matched_rules, deferred_message->message, deferred_message->sender,
-+      deferred_message->proposed_recipient, deferred_message->requested_reply, FALSE,
-+      deferred_message->privilege, error);
-+}
-+
-+BusResult
-+bus_deferred_message_dispatch (BusDeferredMessage *deferred_message)
-+{
-+  BusContext *context = bus_connection_get_context (deferred_message->proposed_recipient);
-+  BusTransaction *transaction = bus_transaction_new (context);
-+  BusResult result = BUS_RESULT_TRUE;
-+  DBusError error;
-+
-+  if (transaction == NULL)
-+    {
-+      return BUS_RESULT_FALSE;
-+    }
-+
-+  dbus_error_init(&error);
-+
-+  if (!deferred_message->full_dispatch)
-+    {
-+      result = deferred_message->response;
-+      if (result == BUS_RESULT_TRUE)
-+        {
-+          if (!bus_context_check_recipient_message_limits(context, deferred_message->proposed_recipient,
-+               deferred_message->sender, deferred_message->message, deferred_message->requested_reply, &error))
-+              result = BUS_RESULT_FALSE;
-+        }
-+      else if (result == BUS_RESULT_LATER)
-+        {
-+          BusDeferredMessage *deferred_message2;
-+          result = bus_context_check_security_policy (context, transaction,
-+                                                      deferred_message->sender,
-+                                                      deferred_message->addressed_recipient,
-+                                                      deferred_message->proposed_recipient,
-+                                                      deferred_message->message, NULL,
-+                                                      &deferred_message2);
-+
-+          if (result == BUS_RESULT_LATER)
-+            {
-+              /* prepend at recipient */
-+              if (!bus_deferred_message_queue_at_recipient(deferred_message2, transaction,
-+                  FALSE, TRUE))
-+                result = BUS_RESULT_FALSE;
-+            }
-+        }
-+
-+      /* silently drop messages on access denial */
-+      if (result == BUS_RESULT_TRUE)
-+        {
-+          if (!bus_transaction_send (transaction, deferred_message->proposed_recipient, deferred_message->message, TRUE))
-+            result = BUS_RESULT_FALSE;
-+        }
-+
-+      bus_transaction_execute_and_free(transaction);
-+
-+      goto out;
-+    }
-+
-+  /* do not attempt to send message if sender has disconnected */
-+  if (deferred_message->sender != NULL && !bus_connection_is_active(deferred_message->sender))
-+    {
-+      bus_transaction_cancel_and_free(transaction);
-+      result = BUS_RESULT_FALSE;
-+      goto out;
-+    }
-+
-+  result = bus_dispatch_matches(transaction, deferred_message->sender,
-+      deferred_message->addressed_recipient, deferred_message->message, deferred_message, &error);
-+
-+  if (result == BUS_RESULT_LATER)
-+    {
-+      /* Message deferring was already done in bus_dispatch_matches */
-+      bus_transaction_cancel_and_free(transaction);
-+      goto out;
-+    }
-+
-+  /* this part is a copy & paste from bus_dispatch function. Probably can be moved to a function */
-+  if (dbus_error_is_set (&error))
-+    {
-+      if (!dbus_connection_get_is_connected (deferred_message->sender))
-+        {
-+          /* If we disconnected it, we won't bother to send it any error
-+           * messages.
-+           */
-+          _dbus_verbose ("Not sending error to connection we disconnected\n");
-+        }
-+      else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
-+        {
-+          bus_connection_send_oom_error (deferred_message->sender, deferred_message->message);
-+
-+          /* cancel transaction due to OOM */
-+          if (transaction != NULL)
-+            {
-+              bus_transaction_cancel_and_free (transaction);
-+              transaction = NULL;
-+            }
-+        }
-+      else
-+        {
-+          /* Try to send the real error, if no mem to do that, send
-+           * the OOM error
-+           */
-+          _dbus_assert (transaction != NULL);
-+          if (!bus_transaction_send_error_reply (transaction, deferred_message->sender,
-+                                                 &error, deferred_message->message))
-+            {
-+              bus_connection_send_oom_error (deferred_message->sender, deferred_message->message);
-+
-+              /* cancel transaction due to OOM */
-+              if (transaction != NULL)
-+                {
-+                  bus_transaction_cancel_and_free (transaction);
-+                  transaction = NULL;
-+                }
-+            }
-+        }
-+    }
-+
-+  if (transaction != NULL)
-+    {
-+      bus_transaction_execute_and_free (transaction);
-+    }
-+
-+out:
-+  dbus_error_free(&error);
-+
-+  return result;
-+}
-+
-+dbus_bool_t
-+bus_deferred_message_replace (BusDeferredMessage *old_message, BusDeferredMessage *new_message)
-+{
-+  if (bus_connection_replace_deferred_message(old_message->proposed_recipient,
-+        old_message, new_message))
-+    {
-+      new_message->response_callback = old_message->response_callback;
-+      new_message->full_dispatch = old_message->full_dispatch;
-+      return TRUE;
-+    }
-+  return FALSE;
-+}
-+
-+dbus_bool_t
-+bus_deferred_message_waits_for_check(BusDeferredMessage *deferred_message)
-+{
-+  return deferred_message->status != 0;
-+}
-+
-+DBusConnection *
-+bus_deferred_message_get_recipient(BusDeferredMessage *deferred_message)
-+{
-+  return deferred_message->proposed_recipient;
-+}
-+
- BusDeferredMessageStatus
- bus_deferred_message_get_status (BusDeferredMessage *deferred_message)
- {
-   return deferred_message->status;
- }
-+BusResult
-+bus_deferred_message_get_response (BusDeferredMessage *deferred_message)
-+{
-+  return deferred_message->response;
-+}
-+
- void
- bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
-                                         BusResult result)
-@@ -308,3 +614,4 @@ bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
-       deferred_message->response_callback(deferred_message, result);
-     }
- }
-+
-diff --git a/bus/check.h b/bus/check.h
-index f381789..3c6b2a1 100644
---- a/bus/check.h
-+++ b/bus/check.h
-@@ -64,12 +64,37 @@ BusDeferredMessage *bus_deferred_message_new                (DBusMessage *messag
- BusDeferredMessage *bus_deferred_message_ref                (BusDeferredMessage *deferred_message);
- void                bus_deferred_message_unref              (BusDeferredMessage *deferred_message);
-+BusResult           bus_deferred_message_dispatch           (BusDeferredMessage *deferred_message);
-+dbus_bool_t         bus_deferred_message_waits_for_check    (BusDeferredMessage *deferred_message);
-+DBusConnection     *bus_deferred_message_get_recipient      (BusDeferredMessage *deferred_message);
- void                bus_deferred_message_response_received  (BusDeferredMessage *deferred_message,
-                                                              BusResult result);
-+dbus_bool_t         bus_deferred_message_queue_at_recipient (BusDeferredMessage *deferred_message,
-+                                                             BusTransaction *transaction,
-+                                                             dbus_bool_t full_dispatch,
-+                                                             dbus_bool_t prepend);
-+dbus_bool_t         bus_deferred_message_replace            (BusDeferredMessage *old_message,
-+                                                             BusDeferredMessage *new_message);
- void                bus_deferred_message_disable_sender     (BusDeferredMessage *deferred_message);
-+BusResult           bus_deferred_message_get_response       (BusDeferredMessage *deferred_message);
- BusDeferredMessageStatus  bus_deferred_message_get_status   (BusDeferredMessage *deferred_message);
-+
-+dbus_bool_t         bus_deferred_message_expect_method_reply (BusDeferredMessage *deferred_message,
-+                                                              BusTransaction *transaction,
-+                                                              DBusError *error);
-+void                bus_deferred_message_create_error        (BusDeferredMessage *deferred_message,
-+                                                              const char *error_message,
-+                                                              DBusError *error);
-+void                bus_deferred_message_set_policy_check_info (BusDeferredMessage *deferred_message,
-+                                                                dbus_bool_t requested_reply,
-+                                                                int matched_rules,
-+                                                                const char *privilege);
-+dbus_bool_t         bus_deferred_message_check_message_limits (BusDeferredMessage *deferred_message,
-+                                                               DBusError *error);
-+
-+
- #ifdef DBUS_ENABLE_EMBEDDED_TESTS
- extern dbus_bool_t (*bus_check_test_override) (DBusConnection *connection,
-                                                const char *privilege);
-diff --git a/bus/connection.c b/bus/connection.c
-index a6d87e5..d2ebe82 100644
---- a/bus/connection.c
-+++ b/bus/connection.c
-@@ -30,10 +30,12 @@
- #include "signals.h"
- #include "expirelist.h"
- #include "selinux.h"
-+#include "check.h"
- #include <dbus/dbus-list.h>
- #include <dbus/dbus-hash.h>
- #include <dbus/dbus-timeout.h>
- #include <dbus/dbus-connection-internal.h>
-+#include <dbus/dbus-message-internal.h>
- #ifdef DBUS_ENABLE_CYNARA
- #include <stdlib.h>
- #include <cynara-session.h>
-@@ -95,6 +97,7 @@ typedef struct
-   DBusMessage *oom_message;
-   DBusPreallocatedSend *oom_preallocated;
-   BusClientPolicy *policy;
-+  DBusList *deferred_messages;  /**< Queue of messages deferred due to pending policy check */
-   char *cached_loginfo_string;
-   BusSELinuxID *selinux_id;
-@@ -256,6 +259,8 @@ bus_connection_disconnected (DBusConnection *connection)
-       bus_transaction_execute_and_free (transaction);
-     }
-+  bus_connection_clear_deferred_messages(connection);
-+
-   bus_dispatch_remove_connection (connection);
-   
-   /* no more watching */
-@@ -2132,6 +2137,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-                                   DBusMessage    *message)
- {
-   BusResult res;
-+  BusDeferredMessage *deferred_message;
-   /* We have to set the sender to the driver, and have
-    * to check security policy since it was not done in
-    * dispatch.c
-@@ -2163,23 +2169,25 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-   res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
-                                            transaction,
-                                            NULL, connection, connection, message, NULL,
--                                           NULL);
-+                                           &deferred_message);
-   if (res == BUS_RESULT_FALSE)
-     return TRUE;
-   else if (res == BUS_RESULT_LATER)
-     {
--      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
--      return TRUE;
-+      if (!bus_deferred_message_queue_at_recipient(deferred_message, transaction, FALSE, FALSE))
-+        return FALSE;
-+      return TRUE; /* pretend to have sent it */
-     }
--  return bus_transaction_send (transaction, connection, message);
-+  return bus_transaction_send (transaction, connection, message, FALSE);
- }
- dbus_bool_t
- bus_transaction_send (BusTransaction *transaction,
-                       DBusConnection *connection,
--                      DBusMessage    *message)
-+                      DBusMessage    *message,
-+                      dbus_bool_t     deferred_dispatch)
- {
-   MessageToSend *to_send;
-   BusConnectionData *d;
-@@ -2205,7 +2213,28 @@ bus_transaction_send (BusTransaction *transaction,
-   
-   d = BUS_CONNECTION_DATA (connection);
-   _dbus_assert (d != NULL);
--  
-+
-+  if (!deferred_dispatch && d->deferred_messages != NULL)
-+    {
-+      BusDeferredMessage *deferred_message;
-+      dbus_bool_t success;
-+      /* sender and addressed recipient are not required at this point as we only need to send message
-+       * to a single recipient without performing policy check. */
-+      deferred_message = bus_deferred_message_new (message,
-+                                                   NULL,
-+                                                   NULL,
-+                                                   connection,
-+                                                   BUS_RESULT_TRUE);
-+      if (deferred_message == NULL)
-+        return FALSE;
-+
-+      success = bus_deferred_message_queue_at_recipient(deferred_message, transaction,
-+          FALSE, FALSE);
-+      bus_deferred_message_unref(deferred_message);
-+
-+      return success;
-+    }
-+
-   to_send = dbus_new (MessageToSend, 1);
-   if (to_send == NULL)
-     {
-@@ -2457,6 +2486,131 @@ bus_transaction_add_cancel_hook (BusTransaction               *transaction,
-   return TRUE;
- }
-+void
-+bus_connection_dispatch_deferred (DBusConnection *connection)
-+{
-+  BusDeferredMessage *message;
-+
-+  _dbus_return_if_fail (connection != NULL);
-+
-+  while ((message = bus_connection_pop_deferred_message(connection)) != NULL)
-+    {
-+      bus_deferred_message_dispatch(message);
-+      bus_deferred_message_unref(message);
-+    }
-+}
-+
-+dbus_bool_t
-+bus_connection_has_deferred_messages (DBusConnection *connection)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+  return d->deferred_messages != NULL ? TRUE : FALSE;
-+}
-+
-+dbus_bool_t
-+bus_connection_queue_deferred_message (DBusConnection *connection,
-+                                       BusDeferredMessage *message,
-+                                       dbus_bool_t prepend)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+  dbus_bool_t success;
-+  if (prepend)
-+    success = _dbus_list_prepend(&d->deferred_messages, message);
-+  else
-+    success = _dbus_list_append(&d->deferred_messages, message);
-+
-+  if (success)
-+    {
-+      bus_deferred_message_ref(message);
-+      return TRUE;
-+    }
-+
-+  return FALSE;
-+}
-+
-+dbus_bool_t
-+bus_connection_replace_deferred_message (DBusConnection *connection,
-+                                         BusDeferredMessage *oldMessage,
-+                                         BusDeferredMessage *newMessage)
-+{
-+  DBusList *link;
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+
-+  link = _dbus_list_find_first(&d->deferred_messages, oldMessage);
-+  if (link == NULL)
-+    return FALSE;
-+
-+  if (!_dbus_list_insert_after(&d->deferred_messages, link, newMessage))
-+    return FALSE;
-+
-+  bus_deferred_message_ref(newMessage);
-+  _dbus_list_remove_link(&d->deferred_messages, link);
-+  bus_deferred_message_unref(oldMessage);
-+  return TRUE;
-+}
-+
-+BusDeferredMessage *
-+bus_connection_pop_deferred_message (DBusConnection *connection)
-+{
-+  DBusList *link;
-+  BusDeferredMessage *message;
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+
-+  link =_dbus_list_get_first_link(&d->deferred_messages);
-+  if (link != NULL)
-+    {
-+      message = link->data;
-+      if (!bus_deferred_message_waits_for_check(message))
-+        {
-+          _dbus_list_remove_link(&d->deferred_messages, link);
-+          return message;
-+        }
-+    }
-+
-+  return NULL;
-+}
-+
-+dbus_bool_t
-+bus_connection_putback_deferred_message (DBusConnection *connection, BusDeferredMessage *message)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+  if (_dbus_list_prepend(&d->deferred_messages, message))
-+    {
-+      return TRUE;
-+    }
-+  return FALSE;
-+}
-+
-+void
-+bus_connection_clear_deferred_messages (DBusConnection *connection)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+  DBusList *link;
-+  DBusList *next;
-+  BusDeferredMessage *message;
-+
-+  link =_dbus_list_get_first_link(&d->deferred_messages);
-+  while (link != NULL)
-+    {
-+      next = _dbus_list_get_next_link (&d->deferred_messages, link);
-+      message = link->data;
-+
-+      bus_deferred_message_unref(message);
-+      _dbus_list_remove_link(&d->deferred_messages, link);
-+
-+      link = next;
-+    }
-+}
-+
-+void
-+bus_connection_remove_deferred_message (DBusConnection *connection,
-+                                        BusDeferredMessage *message)
-+{
-+  BusConnectionData *d = BUS_CONNECTION_DATA(connection);
-+  if (_dbus_list_remove(&d->deferred_messages, message))
-+    bus_deferred_message_unref(message);
-+}
-+
- int
- bus_connections_get_n_active (BusConnections *connections)
- {
-diff --git a/bus/connection.h b/bus/connection.h
-index 7433746..8d49b25 100644
---- a/bus/connection.h
-+++ b/bus/connection.h
-@@ -82,6 +82,22 @@ dbus_bool_t bus_connection_preallocate_oom_error (DBusConnection *connection);
- void        bus_connection_send_oom_error        (DBusConnection *connection,
-                                                   DBusMessage    *in_reply_to);
-+dbus_bool_t         bus_connection_has_deferred_messages    (DBusConnection *connection);
-+dbus_bool_t         bus_connection_queue_deferred_message   (DBusConnection *connection,
-+                                                             BusDeferredMessage *message,
-+                                                             dbus_bool_t prepend);
-+BusDeferredMessage *bus_connection_pop_deferred_message     (DBusConnection *connection);
-+dbus_bool_t         bus_connection_putback_deferred_message (DBusConnection *connection,
-+                                                             BusDeferredMessage *message);
-+void                bus_connection_remove_deferred_message  (DBusConnection *connection,
-+                                                             BusDeferredMessage *message);
-+dbus_bool_t         bus_connection_replace_deferred_message (DBusConnection *connection,
-+                                                             BusDeferredMessage *oldMessage,
-+                                                             BusDeferredMessage *newMessage);
-+void                bus_connection_dispatch_deferred        (DBusConnection *connection);
-+void                bus_connection_clear_deferred_messages  (DBusConnection *connection);
-+
-+
- /* called by signals.c */
- dbus_bool_t bus_connection_add_match_rule      (DBusConnection *connection,
-                                                 BusMatchRule   *rule);
-@@ -129,7 +145,8 @@ BusTransaction* bus_transaction_new              (BusContext                   *
- BusContext*     bus_transaction_get_context      (BusTransaction               *transaction);
- dbus_bool_t     bus_transaction_send             (BusTransaction               *transaction,
-                                                   DBusConnection               *connection,
--                                                  DBusMessage                  *message);
-+                                                  DBusMessage                  *message,
-+                                                  dbus_bool_t                   deferred_dispatch);
- dbus_bool_t     bus_transaction_send_from_driver (BusTransaction               *transaction,
-                                                   DBusConnection               *connection,
-                                                   DBusMessage                  *message);
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index 6b0eadc..9972e76 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -33,8 +33,10 @@
- #include "utils.h"
- #include "bus.h"
- #include "signals.h"
-+#include "dispatch.h"
- #include "test.h"
- #include <dbus/dbus-internals.h>
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-misc.h>
- #include <string.h>
-@@ -63,16 +65,26 @@ send_one_message (DBusConnection *connection,
-   result = bus_context_check_security_policy (context, transaction, sender, addressed_recipient,
-       connection, message, NULL, &deferred_message);
--  if (result != BUS_RESULT_TRUE)
-+  if (result == BUS_RESULT_FALSE)
-       return TRUE; /* silently don't send it */
-   if (dbus_message_contains_unix_fds(message) &&
-       !dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD))
-     return TRUE; /* silently don't send it */
-+  if (result == BUS_RESULT_LATER)
-+    {
-+      if (!bus_deferred_message_queue_at_recipient(deferred_message, transaction, FALSE, FALSE))
-+        {
-+          BUS_SET_OOM (error);
-+          return FALSE;
-+        }
-+      return TRUE; /* pretend to have sent it */
-+    }
-+
-   if (!bus_transaction_send (transaction,
-                              connection,
--                             message))
-+                             message, FALSE))
-     {
-       BUS_SET_OOM (error);
-       return FALSE;
-@@ -82,11 +94,12 @@ send_one_message (DBusConnection *connection,
- }
- BusResult
--bus_dispatch_matches (BusTransaction *transaction,
--                      DBusConnection *sender,
--                      DBusConnection *addressed_recipient,
--                      DBusMessage    *message,
--                      DBusError      *error)
-+bus_dispatch_matches (BusTransaction     *transaction,
-+                      DBusConnection     *sender,
-+                      DBusConnection     *addressed_recipient,
-+                      DBusMessage        *message,
-+                      BusDeferredMessage *dispatched_deferred_message,
-+                      DBusError          *error)
- {
-   DBusError tmp_error;
-   BusConnections *connections;
-@@ -110,17 +123,78 @@ bus_dispatch_matches (BusTransaction *transaction,
-   /* First, send the message to the addressed_recipient, if there is one. */
-   if (addressed_recipient != NULL)
-     {
--      BusResult res;
--      res = bus_context_check_security_policy (context, transaction,
--                                               sender, addressed_recipient,
--                                               addressed_recipient,
--                                               message, error,
--                                               &deferred_message);
--      if (res == BUS_RESULT_FALSE)
-+      BusResult result;
-+      /* To maintain message order message needs to be appended at the recipient if there are already
-+       *  deferred messages and we are not doing deferred dispatch
-+       */
-+      if (dispatched_deferred_message == NULL && bus_connection_has_deferred_messages(addressed_recipient))
-+        {
-+          deferred_message = bus_deferred_message_new(message, sender,
-+              addressed_recipient, addressed_recipient, BUS_RESULT_LATER);
-+
-+          if (deferred_message == NULL)
-+            {
-+              BUS_SET_OOM(error);
-+              return BUS_RESULT_FALSE;
-+            }
-+
-+          if (!bus_deferred_message_queue_at_recipient(deferred_message, transaction, TRUE, FALSE))
-+            {
-+              bus_deferred_message_unref(deferred_message);
-+              BUS_SET_OOM(error);
-+              return BUS_RESULT_FALSE;
-+            }
-+
-+          bus_deferred_message_unref(deferred_message);
-+          return BUS_RESULT_TRUE; /* pretend to have sent it */
-+        }
-+
-+      if (dispatched_deferred_message != NULL)
-+        {
-+          result = bus_deferred_message_get_response(dispatched_deferred_message);
-+          if (result == BUS_RESULT_TRUE)
-+            {
-+              /* if we know the result of policy check we still need to check if message limits
-+               * are not exceeded. It is also required to add entry in expected replies list if
-+               * this is a method call
-+               */
-+              if (!bus_deferred_message_check_message_limits(dispatched_deferred_message, error))
-+                return BUS_RESULT_FALSE;
-+
-+              if (!bus_deferred_message_expect_method_reply(dispatched_deferred_message, transaction, error))
-+                return BUS_RESULT_FALSE;
-+            }
-+          else if (result == BUS_RESULT_FALSE)
-+            {
-+              bus_deferred_message_create_error(dispatched_deferred_message, "Rejected message", error);
-+              return BUS_RESULT_FALSE;
-+            }
-+        }
-+      else
-+        result = BUS_RESULT_LATER;
-+
-+      if (result == BUS_RESULT_LATER)
-+        result = bus_context_check_security_policy(context, transaction,
-+            sender, addressed_recipient, addressed_recipient, message, error,
-+            &deferred_message);
-+
-+      if (result == BUS_RESULT_FALSE)
-         return BUS_RESULT_FALSE;
--      else if (res == BUS_RESULT_LATER)
-+      else if (result == BUS_RESULT_LATER)
-         {
-           BusDeferredMessageStatus status;
-+
-+          if (dispatched_deferred_message != NULL)
-+            {
-+              /* for deferred dispatch prepend message at the recipient */
-+              if (!bus_deferred_message_queue_at_recipient(deferred_message, transaction, TRUE, TRUE))
-+                {
-+                  BUS_SET_OOM(error);
-+                  return BUS_RESULT_FALSE;
-+                }
-+              return BUS_RESULT_TRUE; /* pretend to have sent it */
-+            }
-+
-           status = bus_deferred_message_get_status(deferred_message);
-           if (status & BUS_DEFERRED_MESSAGE_CHECK_SEND)
-@@ -131,13 +205,18 @@ bus_dispatch_matches (BusTransaction *transaction,
-             }
-           else if (status & BUS_DEFERRED_MESSAGE_CHECK_RECEIVE)
-             {
--              dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
--                              "Rejecting message because time is needed to check security policy");
--              return BUS_RESULT_FALSE;
-+              /* receive rule result not available - queue message at the recipient */
-+              if (!bus_deferred_message_queue_at_recipient(deferred_message, transaction, TRUE, FALSE))
-+                {
-+                  BUS_SET_OOM(error);
-+                  return BUS_RESULT_FALSE;
-+                }
-+
-+              return BUS_RESULT_TRUE; /* pretend to have sent it */
-             }
-           else
-             {
--              _dbus_verbose("deferred message has no status field set to send or receive unexpectedly\n");
-+              _dbus_verbose("deferred message has no status field set unexpectedly\n");
-               return BUS_RESULT_FALSE;
-             }
-         }
-@@ -154,7 +233,8 @@ bus_dispatch_matches (BusTransaction *transaction,
-         }
-       /* Dispatch the message */
--      if (!bus_transaction_send (transaction, addressed_recipient, message))
-+      if (!bus_transaction_send(transaction, addressed_recipient, message,
-+          dispatched_deferred_message != NULL ? TRUE : FALSE))
-         {
-           BUS_SET_OOM (error);
-           return BUS_RESULT_FALSE;
-@@ -385,7 +465,7 @@ bus_dispatch (DBusConnection *connection,
-    * match rules.
-    */
-   if (BUS_RESULT_LATER == bus_dispatch_matches (transaction, connection, addressed_recipient,
--                                                message, &error))
-+                                                message, NULL, &error))
-     {
-       /* Roll back and dispatch the message once the policy result is available */
-       bus_transaction_cancel_and_free (transaction);
-diff --git a/bus/dispatch.h b/bus/dispatch.h
-index afba6a2..f6102e8 100644
---- a/bus/dispatch.h
-+++ b/bus/dispatch.h
-@@ -29,10 +29,11 @@
- dbus_bool_t bus_dispatch_add_connection    (DBusConnection *connection);
- void        bus_dispatch_remove_connection (DBusConnection *connection);
--BusResult   bus_dispatch_matches           (BusTransaction *transaction,
--                                            DBusConnection *sender,
--                                            DBusConnection *recipient,
--                                            DBusMessage    *message,
--                                            DBusError      *error);
-+BusResult   bus_dispatch_matches           (BusTransaction     *transaction,
-+                                            DBusConnection     *sender,
-+                                            DBusConnection     *recipient,
-+                                            DBusMessage        *message,
-+                                            BusDeferredMessage *dispatched_deferred_message,
-+                                            DBusError           *error);
- #endif /* BUS_DISPATCH_H */
-diff --git a/bus/driver.c b/bus/driver.c
-index 4dbce3d..2fb1385 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -130,7 +130,7 @@ bus_driver_send_service_owner_changed (const char     *service_name,
-   _dbus_assert (dbus_message_has_signature (message, "sss"));
--  res = bus_dispatch_matches (transaction, NULL, NULL, message, error);
-+  res = bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error);
-   if (res == BUS_RESULT_TRUE)
-     retval = TRUE;
-   else if (res == BUS_RESULT_FALSE)
-diff --git a/bus/policy.c b/bus/policy.c
-index ec888df..448147f 100644
---- a/bus/policy.c
-+++ b/bus/policy.c
-@@ -1071,6 +1071,9 @@ bus_client_policy_check_can_send (DBusConnection      *sender,
-       result = bus_check_privilege(check, message, sender, addressed_recipient, receiver,
-           privilege, BUS_DEFERRED_MESSAGE_CHECK_SEND, deferred_message);
-+      if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+        bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
-+            *toggles, privilege);
-     }
-   else
-     privilege = NULL;
-@@ -1305,6 +1308,9 @@ bus_client_policy_check_can_receive (BusClientPolicy     *policy,
-       result = bus_check_privilege(check, message, sender, addressed_recipient, proposed_recipient,
-                  privilege, BUS_DEFERRED_MESSAGE_CHECK_RECEIVE, deferred_message);
-+      if (result == BUS_RESULT_LATER && deferred_message != NULL)
-+        bus_deferred_message_set_policy_check_info(*deferred_message, requested_reply,
-+                    *toggles, privilege);
-     }
-   else
-       privilege = NULL;
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Add-own-rule-result-unavailability-handling.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Add-own-rule-result-unavailability-handling.patch
deleted file mode 100644 (file)
index e1b1e62..0000000
+++ /dev/null
@@ -1,1142 +0,0 @@
-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
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0008-Add-GetConnectionSmackContext-D-Bus-daemon-method.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0008-Add-GetConnectionSmackContext-D-Bus-daemon-method.patch
deleted file mode 100644 (file)
index 43a1ef6..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-From 6c9997fb1cdff4281166e8c2fb8276018b1025dd Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Mon, 15 Jun 2015 11:46:47 +0200
-Subject: [PATCH 8/8] Add "GetConnectionSmackContext" D-Bus daemon method
-
-This method is used to obtain smack label of given D-Bus client.
-Note that it is deprecated and is included only for compatilibity with
-existing D-Bus users. GetConnectionCredentials should be used to obtain
-client's credentials.
-
-Change-Id: Idf9648032ca5cbd9605ffab055e6384baa4eb9b4
----
- bus/driver.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 63 insertions(+)
-
-diff --git a/bus/driver.c b/bus/driver.c
-index 9708f49..4e76224 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -1759,6 +1759,65 @@ bus_driver_handle_get_id (DBusConnection *connection,
-   return BUS_RESULT_FALSE;
- }
-+static BusResult
-+bus_driver_handle_get_connection_smack_context (DBusConnection *connection,
-+                                                BusTransaction *transaction,
-+                                                DBusMessage    *message,
-+                                                DBusError      *error)
-+{
-+  DBusConnection *conn;
-+  DBusMessage *reply = NULL;
-+  char *label = NULL;
-+  const char *service;
-+
-+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-+
-+  conn = bus_driver_get_conn_helper (connection, message, "credentials",
-+                                     &service, error);
-+  if (conn == NULL)
-+    goto err;
-+
-+  reply = dbus_message_new_method_return (message);
-+  if (reply == NULL)
-+    goto oom;
-+
-+  if (!_dbus_connection_get_linux_security_label (conn, &label))
-+   {
-+      dbus_set_error (error, DBUS_ERROR_FAILED,
-+                      "Failed to get smack label of connection",
-+                      conn);
-+      goto err;
-+   }
-+
-+  if (label == NULL)
-+    goto oom;
-+
-+  if (!dbus_message_append_args (reply,
-+                                 DBUS_TYPE_STRING, &label,
-+                                 DBUS_TYPE_INVALID))
-+    goto oom;
-+
-+  if (!bus_transaction_send_from_driver (transaction, connection, reply))
-+    goto oom;
-+
-+  dbus_message_unref (reply);
-+  dbus_free(label);
-+
-+  return BUS_RESULT_TRUE;
-+
-+oom:
-+  BUS_SET_OOM (error);
-+
-+err:
-+  if (reply != NULL)
-+    dbus_message_unref (reply);
-+
-+  dbus_free(label);
-+
-+  return BUS_RESULT_FALSE;
-+}
-+
-+
- typedef struct
- {
-   const char *name;
-@@ -1849,6 +1908,10 @@ static const MessageHandler dbus_message_handlers[] = {
-     bus_driver_handle_get_id },
-   { "GetConnectionCredentials", "s", "a{sv}",
-     bus_driver_handle_get_connection_credentials },
-+  { "GetConnectionSmackContext", /* deprecated - you should use GetConnectionCredentials instead */
-+    DBUS_TYPE_STRING_AS_STRING,
-+    DBUS_TYPE_STRING_AS_STRING,
-+    bus_driver_handle_get_connection_smack_context },
-   { NULL, NULL, NULL, NULL }
- };
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/Perform-Cynara-runtime-policy-checks-by-default.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/Perform-Cynara-runtime-policy-checks-by-default.patch
deleted file mode 100644 (file)
index e573fb3..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-From e8610297cf7031e94eb314a2e8c11246f4405403 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Tue, 23 Jun 2015 11:08:48 +0200
-Subject: [PATCH] Perform Cynara runtime policy checks by default
-
-This change introduces http://tizen.org/privilege/internal/dbus privilege
-which is supposed to be available only to trusted system resources.
-Checks for this privilege are used in place of certain allow rules to
-make security policy more strict.
-
-For system bus sending and receiving signals now requires
-http://tizen.org/privilege/internal/dbus privilege. Requesting name
-ownership and sending methods is still denied by default.
-
-For session bus http://tizen.org/privilege/internal/dbus privilege
-is now required for requesting name, calling methods, sending and receiving
-signals.
-
-Services are supposed to override these default settings to implement their
-own security policy.
-
-Change-Id: Ifb4a160bf6e0638404e0295a2e4fa3077efd881c
-Signed-off-by: Jacek Bukarewicz <j.bukarewicz@samsung.com>
----
- bus/session.conf.in | 32 ++++++++++++++++++++++++++------
- bus/system.conf.in  | 22 ++++++++++++++++------
- 2 files changed, 42 insertions(+), 12 deletions(-)
-
-diff --git a/bus/session.conf.in b/bus/session.conf.in
-index 74d9d1f..fa5c232 100644
---- a/bus/session.conf.in
-+++ b/bus/session.conf.in
-@@ -17,12 +17,32 @@
-   <standard_session_servicedirs />
-   <policy context="default">
--    <!-- Allow everything to be sent -->
--    <allow send_destination="*" eavesdrop="true"/>
--    <!-- Allow everything to be received -->
--    <allow eavesdrop="true"/>
--    <!-- Allow anyone to own anything -->
--    <allow own="*"/>
-+    <!-- By default clients require internal/dbus privilege to communicate
-+         with D-Bus services and to claim name ownership. This is internal privilege that
-+         is only accessible to trusted system services -->
-+    <check own="*"                  privilege="http://tizen.org/privilege/internal/dbus" />
-+    <check send_type="method_call"  privilege="http://tizen.org/privilege/internal/dbus" />
-+    <check send_type="signal"       privilege="http://tizen.org/privilege/internal/dbus" />
-+    <check receive_type="signal"    privilege="http://tizen.org/privilege/internal/dbus" />
-+
-+    <!-- Reply messages (method returns, errors) are allowed
-+         by default -->
-+    <allow send_requested_reply="true" send_type="method_return"/>
-+    <allow send_requested_reply="true" send_type="error"/>
-+
-+    <!-- All messages but signals may be received by default -->
-+    <allow receive_type="method_call"/>
-+    <allow receive_type="method_return"/>
-+    <allow receive_type="error"/>
-+
-+    <!-- Allow anyone to talk to the message bus -->
-+    <allow send_destination="org.freedesktop.DBus"/>
-+    <allow receive_sender="org.freedesktop.DBus"/>
-+
-+    <!-- But disallow some specific bus services -->
-+    <deny send_destination="org.freedesktop.DBus"
-+          send_interface="org.freedesktop.DBus"
-+          send_member="UpdateActivationEnvironment"/>
-   </policy>
-   <!-- Config files are placed here that among other things, 
-diff --git a/bus/system.conf.in b/bus/system.conf.in
-index 92f4cc4..dd16947 100644
---- a/bus/system.conf.in
-+++ b/bus/system.conf.in
-@@ -50,21 +50,31 @@
-     <deny own="*"/>
-     <deny send_type="method_call"/>
--    <!-- Signals and reply messages (method returns, errors) are allowed
-+    <!-- By default clients require internal/dbus privilege to send and receive signaks.
-+         This is internal privilege that is only accessible to trusted system services -->
-+    <check send_type="signal"       privilege="http://tizen.org/privilege/internal/dbus" />
-+    <check receive_type="signal"    privilege="http://tizen.org/privilege/internal/dbus" />
-+
-+    <!-- Reply messages (method returns, errors) are allowed
-          by default -->
--    <allow send_type="signal"/>
-     <allow send_requested_reply="true" send_type="method_return"/>
-     <allow send_requested_reply="true" send_type="error"/>
--    <!-- All messages may be received by default -->
-+    <!-- All messages but signals may be received by default -->
-     <allow receive_type="method_call"/>
-     <allow receive_type="method_return"/>
-     <allow receive_type="error"/>
--    <allow receive_type="signal"/>
--    <!-- Allow anyone to talk to the message bus -->
-+    <!-- If there is a need specific bus services could be protected by Cynara as well.
-+         However, this can lead to deadlock during the boot process when such check is made and
-+         Cynara is not yet activated (systemd calls protected method synchronously,
-+         dbus daemon tries to consult Cynara, Cynara waits for systemd activation).
-+         Therefore it is advised to allow root processes to use bus services.
-+         Currently anyone is allowed to talk to the message bus -->
-     <allow send_destination="org.freedesktop.DBus"/>
--    <!-- But disallow some specific bus services -->
-+    <allow receive_sender="org.freedesktop.DBus"/>
-+
-+    <!-- Disallow some specific bus services -->
-     <deny send_destination="org.freedesktop.DBus"
-           send_interface="org.freedesktop.DBus"
-           send_member="UpdateActivationEnvironment"/>
--- 
-2.1.4
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara_1.10.20.bb b/meta-security/recipes-core/dbus-cynara/dbus-cynara_1.10.20.bb
new file mode 100644 (file)
index 0000000..c46298e
--- /dev/null
@@ -0,0 +1,39 @@
+require ${COREBASE}/meta/recipes-core/dbus/dbus_1.10.20.bb
+
+FILESEXTRAPATHS_prepend := "${COREBASE}/meta/recipes-core/dbus/dbus:${THISDIR}/dbus-cynara:"
+S = "${WORKDIR}/dbus-${PV}"
+
+SRC_URI_append = "\
+   file://0001-Integration-of-Cynara-asynchronous-security-checks.patch \
+   file://0002-Disable-message-dispatching-when-send-rule-result-is.patch \
+   file://0003-Handle-unavailability-of-policy-results-for-broadcas.patch \
+   file://0004-Add-own-rule-result-unavailability-handling.patch \
+   file://0005-Perform-Cynara-runtime-policy-checks-by-default.patch \
+"
+
+DEPENDS += "cynara smack"
+EXTRA_OECONF += "--enable-cynara --disable-selinux"
+
+inherit distro_features_check
+REQUIRED_DISTRO_FEATURES += "smack"
+
+# Only the main package gets created here, everything else remains in the
+# normal dbus recipe.
+do_install_append () {
+    for i in ${@' '.join([d.getVar('D', True) + x for x in (' '.join([d.getVar('FILES_${PN}-' + p, True) or '' for p in ['lib', 'dev', 'staticdev', 'doc', 'locale', 'ptest']])).split()])}; do
+        rm -rf $i
+    done
+
+    # Try to remove empty directories, starting with the
+    # longest path (= deepest directory) first.
+    # Find needs a valid current directory. Somehow the directory
+    # we get called in is gone by the time that we get invoked.
+    ( cd ${D}
+      for i in `find . -type d | sort -r`; do
+        rmdir $i || true
+      done
+    )
+}
+
+# Avoid warning about dbus and dbus-cynara providing dbus-x11.
+RPROVIDES_${PN}_remove = "${OLDPKGNAME}"
diff --git a/meta-security/recipes-core/dbus-cynara/dbus_%.bbappend b/meta-security/recipes-core/dbus-cynara/dbus_%.bbappend
new file mode 100644 (file)
index 0000000..78df8ec
--- /dev/null
@@ -0,0 +1,36 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/dbus-cynara:"
+SRC_URI_append = "\
+   file://0001-Integration-of-Cynara-asynchronous-security-checks.patch \
+   file://0002-Disable-message-dispatching-when-send-rule-result-is.patch \
+   file://0003-Handle-unavailability-of-policy-results-for-broadcas.patch \
+   file://0004-Add-own-rule-result-unavailability-handling.patch \
+   file://0005-Perform-Cynara-runtime-policy-checks-by-default.patch \
+"
+
+# Optionally, compilation of the main package with the daemon gets moved into
+# dbus-cynara. That is necessary to break a dependency cycle once the
+# daemon gets compiled with Cynara support (dbus -> cynara -> systemd
+# -> dbus).
+do_install_append_class-target () {
+    if ${@bb.utils.contains('DISTRO_FEATURES', 'dbus-cynara', 'true', 'false', d)}; then
+        for i in ${@' '.join([d.getVar('D', True) + x for x in (d.getVar('FILES_${PN}', True) or '').split()])}; do
+            rm -rf $i
+        done
+
+        # Try to remove empty directories, starting with the
+        # longest path (= deepest directory) first.
+        # Find needs a valid current directory. Somehow the directory
+        # we get called in is gone by the time that we get invoked.
+        ( cd ${D}
+          for i in `find . -type d | sort -r`; do
+            rmdir $i || true
+          done
+        )
+    fi
+}
+
+# The main package will be empty, but we want to have it created
+# anyway because of the dependencies on it. Installing it will pull in
+# the replacement dbus-cynara package.
+ALLOW_EMPTY_${PN}_class-target = "1"
+RDEPENDS_${PN}_append_class-target = "${@bb.utils.contains('DISTRO_FEATURES', 'dbus-cynara', ' dbus-cynara', '', d)}"
diff --git a/meta-security/recipes-core/dbus-cynara/dbus_1.10.20.bbappend b/meta-security/recipes-core/dbus-cynara/dbus_1.10.20.bbappend
deleted file mode 100644 (file)
index 34064ba..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
-
-SRC_URI_append = "\
-   file://0001-Integration-of-Cynara-asynchronous-security-checks.patch \
-   file://0002-Disable-message-dispatching-when-send-rule-result-is.patch \
-   file://0003-Handle-unavailability-of-policy-results-for-broadcas.patch \
-   file://0004-Add-own-rule-result-unavailability-handling.patch \
-   file://0005-Perform-Cynara-runtime-policy-checks-by-default.patch \
-"
-
-DEPENDS_append_class-target = " cynara"
-EXTRA_OECONF_append_class-target = " --disable-selinux --enable-cynara"
-