From 6cab35d83bda92540ca7b24ef874d871542a37c2 Mon Sep 17 00:00:00 2001
From: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
Date: Tue, 5 Nov 2019 12:17:23 +0100
Subject: Declare layer compatibility with zeus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For the uprev to YP 3.0 zeus we need to update the layer compatibility.

Change-Id: Ib762915305588c39400c3c8343152b4ecbfa4556
Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
---
 meta-security/conf/layer.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'meta-security')

diff --git a/meta-security/conf/layer.conf b/meta-security/conf/layer.conf
index 16dae3989..608cf62ed 100644
--- a/meta-security/conf/layer.conf
+++ b/meta-security/conf/layer.conf
@@ -11,4 +11,4 @@ BBFILE_COLLECTIONS += "security-smack"
 BBFILE_PATTERN_security-smack := "^${LAYERDIR}/"
 BBFILE_PRIORITY_security-smack = "60"
 
-LAYERSERIES_COMPAT_security-smack = "thud"
+LAYERSERIES_COMPAT_security-smack = "zeus"
-- 
cgit 


From 2d0270f656766b76763a3661355742f9ccef63ab Mon Sep 17 00:00:00 2001
From: Scott Murray <scott.murray@konsulko.com>
Date: Wed, 22 Jan 2020 13:17:36 -0500
Subject: meta-security: remove keyutils recipe

Remove keyutils 1.5.8 recipe since meta-oe has a newer 1.6 recipe.

Bug-AGL: SPEC-2932

Change-Id: I0a0d2507922c0d705eb064577c0a2a8fcc081d3f
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
---
 .../keyutils/keyutils-arm-remove-m32-m64.patch     | 19 ----------
 .../keyutils/keyutils_fix_library_install.patch    | 30 ---------------
 .../keyutils/keyutils_fix_x86-64_cflags.patch      | 13 -------
 .../keyutils/keyutils_fix_x86_cflags.patch         | 13 -------
 .../recipes-security/keyutils/keyutils_1.5.8.bb    | 44 ----------------------
 5 files changed, 119 deletions(-)
 delete mode 100644 meta-security/recipes-security/keyutils/keyutils/keyutils-arm-remove-m32-m64.patch
 delete mode 100644 meta-security/recipes-security/keyutils/keyutils/keyutils_fix_library_install.patch
 delete mode 100644 meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch
 delete mode 100644 meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86_cflags.patch
 delete mode 100644 meta-security/recipes-security/keyutils/keyutils_1.5.8.bb

(limited to 'meta-security')

diff --git a/meta-security/recipes-security/keyutils/keyutils/keyutils-arm-remove-m32-m64.patch b/meta-security/recipes-security/keyutils/keyutils/keyutils-arm-remove-m32-m64.patch
deleted file mode 100644
index a049fd23f..000000000
--- a/meta-security/recipes-security/keyutils/keyutils/keyutils-arm-remove-m32-m64.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-Index: keyutils-1.5.5/Makefile
-===================================================================
---- keyutils-1.5.5.orig/Makefile	2011-12-20 11:05:10.000000000 +0200
-+++ keyutils-1.5.5/Makefile	2011-12-20 11:06:27.000000000 +0200
-@@ -58,12 +58,12 @@
- LNS		:= ln -sf
- 
- ifeq ($(BUILDFOR),32-bit)
--CFLAGS		+= -m32
-+#CFLAGS		+= -m32
- LIBDIR		:= /usr/lib
- USRLIBDIR	:= /usr/lib
- else
- ifeq ($(BUILDFOR),64-bit)
--CFLAGS		+= -m64
-+#CFLAGS		+= -m64
- LIBDIR		:= /usr/lib
- USRLIBDIR	:= /usr/lib
- endif
diff --git a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_library_install.patch b/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_library_install.patch
deleted file mode 100644
index adf064304..000000000
--- a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_library_install.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Index: keyutils-1.5.5/Makefile
-===================================================================
---- keyutils-1.5.5.orig/Makefile	2011-11-30 17:27:43.000000000 +0200
-+++ keyutils-1.5.5/Makefile	2011-12-21 16:05:53.000000000 +0200
-@@ -59,13 +59,13 @@
- 
- ifeq ($(BUILDFOR),32-bit)
- CFLAGS		+= -m32
--LIBDIR		:= /lib
-+LIBDIR		:= /usr/lib
- USRLIBDIR	:= /usr/lib
- else
- ifeq ($(BUILDFOR),64-bit)
- CFLAGS		+= -m64
--LIBDIR		:= /lib64
--USRLIBDIR	:= /usr/lib64
-+LIBDIR		:= /usr/lib
-+USRLIBDIR	:= /usr/lib
- endif
- endif
- 
-@@ -152,7 +152,7 @@
- 	$(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
- 	$(LNS) $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
- 	mkdir -p $(DESTDIR)$(USRLIBDIR)
--	$(LNS) $(LIBDIR)/$(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB)
-+	$(LNS) $(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB)
- 	$(INSTALL) -D keyctl $(DESTDIR)$(BINDIR)/keyctl
- 	$(INSTALL) -D request-key $(DESTDIR)$(SBINDIR)/request-key
- 	$(INSTALL) -D request-key-debug.sh $(DESTDIR)$(SHAREDIR)/request-key-debug.sh
diff --git a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch b/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch
deleted file mode 100644
index 8dd224505..000000000
--- a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: git/Makefile
-===================================================================
---- git.orig/Makefile	2012-11-16 15:40:05.258723425 +0200
-+++ git/Makefile	2012-11-16 15:41:08.978725491 +0200
-@@ -53,7 +53,7 @@
- ###############################################################################
- LIBDIR		:= $(shell ldd /usr/bin/make | grep '\(/libc\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!')
- USRLIBDIR	:= $(patsubst /lib/%,/usr/lib/%,$(LIBDIR))
--BUILDFOR	:= $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
-+BUILDFOR	:= 64-bit
- 
- LNS		:= ln -sf
- 
diff --git a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86_cflags.patch b/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86_cflags.patch
deleted file mode 100644
index 573c429b8..000000000
--- a/meta-security/recipes-security/keyutils/keyutils/keyutils_fix_x86_cflags.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: git/Makefile
-===================================================================
---- git.orig/Makefile	2012-11-16 15:40:05.258723425 +0200
-+++ git/Makefile	2012-11-16 15:41:08.978725491 +0200
-@@ -53,7 +53,7 @@
- ###############################################################################
- LIBDIR		:= $(shell ldd /usr/bin/make | grep '\(/libc\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!')
- USRLIBDIR	:= $(patsubst /lib/%,/usr/lib/%,$(LIBDIR))
--BUILDFOR	:= $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
-+BUILDFOR	:= 32-bit
- 
- LNS		:= ln -sf
- 
diff --git a/meta-security/recipes-security/keyutils/keyutils_1.5.8.bb b/meta-security/recipes-security/keyutils/keyutils_1.5.8.bb
deleted file mode 100644
index 46b2b622a..000000000
--- a/meta-security/recipes-security/keyutils/keyutils_1.5.8.bb
+++ /dev/null
@@ -1,44 +0,0 @@
-SUMMARY = "Linux Key Management Utilities"
-DESCRIPTION = "Keyutils is a set of utilities for managing the key retention \
-facility in the kernel, which can be used by filesystems, block devices and \
-more to gain and retain the authorization and encryption keys required to \
-perform secure operations."
-SECTION = "base"
-LICENSE = "GPLv2"
-LIC_FILES_CHKSUM = "file://LICENCE.GPL;md5=5f6e72824f5da505c1f4a7197f004b45"
-
-PR = "r1"
-
-SRCREV = "dd64114721edca5808872190e7e2e927ee2e994c"
-
-SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git;protocol=git \
-          file://keyutils_fix_library_install.patch \
-          "
-SRC_URI_append_arm = " file://keyutils-arm-remove-m32-m64.patch"
-SRC_URI_append_x86 = " file://keyutils_fix_x86_cflags.patch"
-SRC_URI_append_x86-64 = " file://keyutils_fix_x86-64_cflags.patch"
-
-S = "${WORKDIR}/git"
-
-INSTALL_FLAGS = " \
-BINDIR=${bindir} \
-SBINDIR=${sbindir} \
-INCLUDEDIR=${includedir} \
-ETCDIR=${sysconfdir} \
-LIBDIR=${libdir} \
-USRLIBDIR=${libdir} \
-SHAREDIR=${datadir} \
-MAN1=${mandir}/man1 \
-MAN3=${mandir}/man3 \
-MAN5=${mandir}/man5 \
-MAN8=${mandir}/man8 \
-DESTDIR=${D}"
-
-do_install() {
-    cd ${S} && oe_runmake ${INSTALL_FLAGS} install
-
-    # Debugging script of unknown value, not packaged.
-    rm -f "${D}${datadir}/request-key-debug.sh"
-}
-
-BBCLASSEXTEND = "native"
-- 
cgit 


From 96bca6489f4193e84e74e93b87d0c7a89ca3d200 Mon Sep 17 00:00:00 2001
From: Scott Murray <scott.murray@konsulko.com>
Date: Wed, 22 Jan 2020 17:00:28 -0500
Subject: meta-security meta-app-framework: handle xmlsec1 upgrade

Remove now unneeded meta-security xmlsec1 bbappend, and update the
bbappend in meta-app-framework to work with the new xmlsec1 1.2.28
recipe in oe-core.

Bug-AGL: SPEC-2932

Change-Id: If57b7c9fa2a4d2b8f9470dd67e95b4579d1210c7
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
---
 meta-security/recipes-security/xmlsec1/xmlsec1_%.bbappend | 3 ---
 1 file changed, 3 deletions(-)
 delete mode 100644 meta-security/recipes-security/xmlsec1/xmlsec1_%.bbappend

(limited to 'meta-security')

diff --git a/meta-security/recipes-security/xmlsec1/xmlsec1_%.bbappend b/meta-security/recipes-security/xmlsec1/xmlsec1_%.bbappend
deleted file mode 100644
index 9c6080fcf..000000000
--- a/meta-security/recipes-security/xmlsec1/xmlsec1_%.bbappend
+++ /dev/null
@@ -1,3 +0,0 @@
-# remove the EXTRA_OECONF from the recipe to
-# avoid an build error in >= YP SUMO
-EXTRA_OECONF = ""
-- 
cgit 


From 9c0f950122472154f3a87cb231b832a6b5d0617f Mon Sep 17 00:00:00 2001
From: Scott Murray <scott.murray@konsulko.com>
Date: Wed, 22 Jan 2020 18:36:32 -0500
Subject: meta-security: handle systemd upgrade

Rename systemd bbappend to work with newer 243.2 version in oe-core.
A wildcard is now used to reduce the need to rename the bbappend on
future upgrades, as the additions it makes have not changed recently.

Bug-AGL: SPEC-2932

Change-Id: Ie6413710e861b8dbf082bcae3d7592f1009927d5
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
---
 .../recipes-core/systemd/systemd_2%.bbappend       | 40 ++++++++++++++++++++++
 .../recipes-core/systemd/systemd_239.bbappend      | 40 ----------------------
 2 files changed, 40 insertions(+), 40 deletions(-)
 create mode 100644 meta-security/recipes-core/systemd/systemd_2%.bbappend
 delete mode 100644 meta-security/recipes-core/systemd/systemd_239.bbappend

(limited to 'meta-security')

diff --git a/meta-security/recipes-core/systemd/systemd_2%.bbappend b/meta-security/recipes-core/systemd/systemd_2%.bbappend
new file mode 100644
index 000000000..789c05f83
--- /dev/null
+++ b/meta-security/recipes-core/systemd/systemd_2%.bbappend
@@ -0,0 +1,40 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+# Ensures systemd runs with label "System"
+EXTRA_OEMESON_append_with-lsm-smack = " -Dsmack-run-label=System"
+
+##################################################################################
+# Maintaining trivial, non-upstreamable configuration changes as patches
+# is tedious. But in same cases (like early mounting of special directories)
+# the configuration has to be in code. We make these changes here directly.
+##################################################################################
+do_patch[prefuncs] += "patch_systemd"
+do_patch[vardeps] += "patch_systemd"
+patch_systemd() {
+    # Handling of /run and /sys/fs/cgroup. Make /run a transmuting directory to
+    # enable systemd communications with services in the User domain.
+    # Original patch by Michael Demeter <michael.demeter@intel.com>.
+    #
+    # We simplify the patching by touching only lines which check the result of
+    # mac_smack_use(). Those are the ones which are used when Smack is active.
+    #
+    # smackfsroot=* on /sys/fs/cgroup may be upstreamable, but smackfstransmute=System::Run
+    # is too distro specific (depends on Smack rules) and thus has to remain here.
+    sed -i -e 's;\("/sys/fs/cgroup", *"[^"]*", *"[^"]*\)\(.*mac_smack_use.*\);\1,smackfsroot=*\2;' \
+           -e 's;\("/run", *"[^"]*", *"[^"]*\)\(.*mac_smack_use.*\);\1,smackfstransmute=System::Run\2;' \
+           ${S}/src/core/mount-setup.c
+}
+
+##################################################################################
+# What follows is temporary.
+# This is a solution to the Bug-AGL SPEC-539
+# (see https://jira.automotivelinux.org/browse/SPEC-539).
+#
+# It renames the file "touchscreen.rules" to "55-touchscreen.rules"
+# This comes with the recipe systemd_230/234 of poky (meta/recipes-core/systemd)
+# It should be removed when poky changes.
+##################################################################################
+do_install_prepend() {
+	mv ${WORKDIR}/touchscreen.rules ${WORKDIR}/55-touchscreen.rules || true
+}
+
diff --git a/meta-security/recipes-core/systemd/systemd_239.bbappend b/meta-security/recipes-core/systemd/systemd_239.bbappend
deleted file mode 100644
index 789c05f83..000000000
--- a/meta-security/recipes-core/systemd/systemd_239.bbappend
+++ /dev/null
@@ -1,40 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-
-# Ensures systemd runs with label "System"
-EXTRA_OEMESON_append_with-lsm-smack = " -Dsmack-run-label=System"
-
-##################################################################################
-# Maintaining trivial, non-upstreamable configuration changes as patches
-# is tedious. But in same cases (like early mounting of special directories)
-# the configuration has to be in code. We make these changes here directly.
-##################################################################################
-do_patch[prefuncs] += "patch_systemd"
-do_patch[vardeps] += "patch_systemd"
-patch_systemd() {
-    # Handling of /run and /sys/fs/cgroup. Make /run a transmuting directory to
-    # enable systemd communications with services in the User domain.
-    # Original patch by Michael Demeter <michael.demeter@intel.com>.
-    #
-    # We simplify the patching by touching only lines which check the result of
-    # mac_smack_use(). Those are the ones which are used when Smack is active.
-    #
-    # smackfsroot=* on /sys/fs/cgroup may be upstreamable, but smackfstransmute=System::Run
-    # is too distro specific (depends on Smack rules) and thus has to remain here.
-    sed -i -e 's;\("/sys/fs/cgroup", *"[^"]*", *"[^"]*\)\(.*mac_smack_use.*\);\1,smackfsroot=*\2;' \
-           -e 's;\("/run", *"[^"]*", *"[^"]*\)\(.*mac_smack_use.*\);\1,smackfstransmute=System::Run\2;' \
-           ${S}/src/core/mount-setup.c
-}
-
-##################################################################################
-# What follows is temporary.
-# This is a solution to the Bug-AGL SPEC-539
-# (see https://jira.automotivelinux.org/browse/SPEC-539).
-#
-# It renames the file "touchscreen.rules" to "55-touchscreen.rules"
-# This comes with the recipe systemd_230/234 of poky (meta/recipes-core/systemd)
-# It should be removed when poky changes.
-##################################################################################
-do_install_prepend() {
-	mv ${WORKDIR}/touchscreen.rules ${WORKDIR}/55-touchscreen.rules || true
-}
-
-- 
cgit 


From 377512d344dbdfea93060ee5c00f923c69c884b2 Mon Sep 17 00:00:00 2001
From: Scott Murray <scott.murray@konsulko.com>
Date: Mon, 27 Jan 2020 14:32:18 -0500
Subject: meta-security: disable dbus-cynara patches
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Rename meta-security dbus bbappend for new 1.2.16 version, and disable
the Cynara support patches until they can be updated by José Bollo.

Bug-AGL: SPEC-2932

Change-Id: Ia2211ad8147381898e47392fe857278189b670d3
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
---
 .../recipes-core/dbus-cynara/dbus_1.12.10.bbappend      | 15 ---------------
 .../recipes-core/dbus-cynara/dbus_1.12.16.bbappend      | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 15 deletions(-)
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus_1.12.10.bbappend
 create mode 100644 meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend

(limited to 'meta-security')

diff --git a/meta-security/recipes-core/dbus-cynara/dbus_1.12.10.bbappend b/meta-security/recipes-core/dbus-cynara/dbus_1.12.10.bbappend
deleted file mode 100644
index 5cbf65ef6..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus_1.12.10.bbappend
+++ /dev/null
@@ -1,15 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/dbus-cynara:"
-
-SRC_URI_append_class-target = "\
-   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 \
-   file://0006-Fix-gcc-8-warnings.patch \
-   file://0007-Fix-SIGSEGV-on-disconnections.patch \
-"
-
-DEPENDS_append_class-target = " cynara smack"
-EXTRA_OECONF_append_class-target = " ${@bb.utils.contains('DISTRO_FEATURES','smack','--enable-cynara --disable-selinux','',d)}"
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend b/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend
new file mode 100644
index 000000000..ce2bd0822
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend
@@ -0,0 +1,17 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/dbus-cynara:"
+
+#SRC_URI_append_class-target = "\
+#   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 \
+#   file://0006-Fix-gcc-8-warnings.patch \
+#   file://0007-Fix-SIGSEGV-on-disconnections.patch \
+#"
+SRC_URI_append_class-target = "\
+"
+
+#DEPENDS_append_class-target = " cynara smack"
+#EXTRA_OECONF_append_class-target = " ${@bb.utils.contains('DISTRO_FEATURES','smack','--enable-cynara --disable-selinux','',d)}"
+
-- 
cgit 


From ffe584b58889bad79004f3916f858299d8b7b385 Mon Sep 17 00:00:00 2001
From: José Bollo <jose.bollo@iot.bzh>
Date: Tue, 4 Feb 2020 18:02:26 +0100
Subject: meta-security: activates dbus-cynagora
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change-Id: Ia82ef9c5693c5eb4ba147bb7ead54f2608cb5dd4
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
---
 ...on-of-Cynara-asynchronous-security-checks.patch | 2309 ++++++++++++++++++++
 ...sage-dispatching-when-send-rule-result-is.patch |  967 ++++++++
 ...ailability-of-policy-results-for-broadcas.patch | 1095 ++++++++++
 ...d-own-rule-result-unavailability-handling.patch | 1505 +++++++++++++
 ...m-Cynara-runtime-policy-checks-by-default.patch |  180 ++
 .../0006-Fix-SIGSEGV-on-disconnections.patch       |  109 +
 .../0007-Switch-from-cynara-to-cynagora.patch      | 1048 +++++++++
 .../dbus-cynagora/dbus_1.12.16.bbappend            |   15 +
 ...on-of-Cynara-asynchronous-security-checks.patch | 2232 -------------------
 ...sage-dispatching-when-send-rule-result-is.patch |  949 --------
 ...ailability-of-policy-results-for-broadcas.patch | 1082 ---------
 ...d-own-rule-result-unavailability-handling.patch | 1493 -------------
 ...m-Cynara-runtime-policy-checks-by-default.patch |  175 --
 .../dbus-cynara/0006-Fix-gcc-8-warnings.patch      |  134 --
 .../0007-Fix-SIGSEGV-on-disconnections.patch       |  109 -
 .../recipes-core/dbus-cynara/dbus_1.12.16.bbappend |   17 -
 16 files changed, 7228 insertions(+), 6191 deletions(-)
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0001-Integration-of-Cynara-asynchronous-security-checks.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0004-Add-own-rule-result-unavailability-handling.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0006-Fix-SIGSEGV-on-disconnections.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0007-Switch-from-cynara-to-cynagora.patch
 create mode 100644 meta-security/recipes-core/dbus-cynagora/dbus_1.12.16.bbappend
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Integration-of-Cynara-asynchronous-security-checks.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-Disable-message-dispatching-when-send-rule-result-is.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Add-own-rule-result-unavailability-handling.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Fix-gcc-8-warnings.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Fix-SIGSEGV-on-disconnections.patch
 delete mode 100644 meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend

(limited to 'meta-security')

diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0001-Integration-of-Cynara-asynchronous-security-checks.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0001-Integration-of-Cynara-asynchronous-security-checks.patch
new file mode 100644
index 000000000..55cedb9c7
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0001-Integration-of-Cynara-asynchronous-security-checks.patch
@@ -0,0 +1,2309 @@
+From ea4b650366261e4257e4b0fb95e7f48e30ef36f0 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 1/8] Integration of Cynara asynchronous security checks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Cherry picked from 4dcfb02f17247ff9de966b62182cd2e08f301238
+by José Bollo.
+
+Updated for dbus 1.10.20 by Scott Murray and José Bollo
+Updated for dbus 1.12.16 by José Bollo
+
+Change-Id: I9bcbce34577e5dc2a3cecf6233a0a2b0e43e1108
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+---
+ bus/Makefile.am                               |   6 +
+ bus/activation.c                              |   5 +-
+ bus/bus.c                                     | 124 ++++--
+ bus/bus.h                                     |  22 +-
+ bus/check.c                                   | 217 ++++++++++
+ bus/check.h                                   |  68 ++++
+ bus/config-parser-common.c                    |   6 +
+ bus/config-parser-common.h                    |   1 +
+ bus/config-parser-trivial.c                   |   2 +
+ bus/config-parser.c                           |  72 +++-
+ bus/connection.c                              |  57 ++-
+ bus/connection.h                              |   4 +
+ bus/cynara.c                                  | 374 ++++++++++++++++++
+ bus/cynara.h                                  |  37 ++
+ bus/dispatch.c                                |  46 ++-
+ bus/driver.h                                  |   2 +
+ bus/policy.c                                  | 195 ++++++---
+ bus/policy.h                                  |  29 +-
+ configure.ac                                  |  12 +
+ test/Makefile.am                              |   1 +
+ .../data/invalid-config-files/badcheck-1.conf |   9 +
+ .../data/invalid-config-files/badcheck-2.conf |   9 +
+ test/data/valid-config-files/check-1.conf     |   9 +
+ .../debug-check-some.conf.in                  |  18 +
+ 24 files changed, 1181 insertions(+), 144 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 c917063..2a8a72c 100644
+--- a/bus/Makefile.am
++++ b/bus/Makefile.am
+@@ -13,6 +13,7 @@ DBUS_BUS_LIBS = \
+ 	$(THREAD_LIBS) \
+ 	$(ADT_LIBS) \
+ 	$(NETWORK_libs) \
++	$(CYNARA_LIBS) \
+ 	$(NULL)
+ 
+ DBUS_LAUNCHER_LIBS = \
+@@ -30,6 +31,7 @@ AM_CPPFLAGS = \
+ 	$(APPARMOR_CFLAGS) \
+ 	-DDBUS_SYSTEM_CONFIG_FILE=\""$(dbusdatadir)/system.conf"\" \
+ 	-DDBUS_COMPILATION \
++	$(CYNARA_CFLAGS) \
+ 	$(NULL)
+ 
+ # if assertions are enabled, improve backtraces
+@@ -90,6 +92,8 @@ BUS_SOURCES=					\
+ 	audit.h					\
+ 	bus.c					\
+ 	bus.h					\
++	check.c					\
++	check.h					\
+ 	config-loader-expat.c			\
+ 	config-parser.c				\
+ 	config-parser.h				\
+@@ -97,6 +101,8 @@ BUS_SOURCES=					\
+ 	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/activation.c b/bus/activation.c
+index 99404b9..f9c6c62 100644
+--- a/bus/activation.c
++++ b/bus/activation.c
+@@ -1789,14 +1789,15 @@ bus_activation_activate_service (BusActivation  *activation,
+ 
+   if (auto_activation &&
+       entry != NULL &&
+-      !bus_context_check_security_policy (activation->context,
++      BUS_RESULT_TRUE != bus_context_check_security_policy (activation->context,
+         transaction,
+         connection, /* sender */
+         NULL, /* addressed recipient */
+         NULL, /* proposed recipient */
+         activation_message,
+         entry,
+-        error))
++        error,
++        NULL))
+     {
+       _DBUS_ASSERT_ERROR_IS_SET (error);
+       _dbus_verbose ("activation not authorized: %s: %s\n",
+diff --git a/bus/bus.c b/bus/bus.c
+index 2ad8e78..6fc45d0 100644
+--- a/bus/bus.c
++++ b/bus/bus.c
+@@ -38,6 +38,7 @@
+ #include "apparmor.h"
+ #include "audit.h"
+ #include "dir-watch.h"
++#include "check.h"
+ #include <dbus/dbus-auth.h>
+ #include <dbus/dbus-list.h>
+ #include <dbus/dbus-hash.h>
+@@ -67,6 +68,7 @@ struct BusContext
+   BusRegistry *registry;
+   BusPolicy *policy;
+   BusMatchmaker *matchmaker;
++  BusCheck *check;
+   BusLimits limits;
+   DBusRLimit *initial_fd_limit;
+   unsigned int fork : 1;
+@@ -1003,6 +1005,10 @@ bus_context_new (const DBusString *config_file,
+       parser = NULL;
+     }
+ 
++  context->check = bus_check_new(context, error);
++  if (context->check == NULL)
++      goto failed;
++
+   dbus_server_free_data_slot (&server_data_slot);
+ 
+   return context;
+@@ -1127,6 +1133,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);
+@@ -1256,6 +1268,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)
+@@ -1451,6 +1469,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;
+@@ -1480,7 +1499,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)),
+@@ -1491,7 +1511,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 */
+@@ -1519,7 +1540,7 @@ 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
++BusResult
+ bus_context_check_security_policy (BusContext     *context,
+                                    BusTransaction *transaction,
+                                    DBusConnection *sender,
+@@ -1527,7 +1548,8 @@ bus_context_check_security_policy (BusContext     *context,
+                                    DBusConnection *proposed_recipient,
+                                    DBusMessage    *message,
+                                    BusActivationEntry *activation_entry,
+-                                   DBusError      *error)
++                                   DBusError      *error,
++                                   BusDeferredMessage **deferred_message)
+ {
+   const char *src, *dest;
+   BusClientPolicy *sender_policy;
+@@ -1536,6 +1558,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);
+   src = dbus_message_get_sender (message);
+@@ -1565,7 +1588,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;
+@@ -1595,7 +1618,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;
+                     }
+                 }
+             }
+@@ -1624,11 +1647,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;
+         }
+ 
+       /* next verify AppArmor access controls.  If allowed then
+@@ -1646,7 +1669,7 @@ bus_context_check_security_policy (BusContext     *context,
+                                      src ? src : DBUS_SERVICE_DBUS,
+                                      activation_entry,
+                                      error))
+-        return FALSE;
++        return BUS_RESULT_FALSE;
+ 
+       if (!bus_connection_is_active (sender))
+         {
+@@ -1660,7 +1683,7 @@ bus_context_check_security_policy (BusContext     *context,
+             {
+               _dbus_verbose ("security check allowing %s message\n",
+                              "Hello");
+-              return TRUE;
++              return BUS_RESULT_TRUE;
+             }
+           else
+             {
+@@ -1671,7 +1694,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;
+             }
+         }
+     }
+@@ -1720,20 +1743,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)
+     {
+@@ -1742,23 +1774,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 */
+@@ -1768,10 +1806,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
+@@ -1792,11 +1830,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 2e0de82..82c32c8 100644
+--- a/bus/bus.h
++++ b/bus/bus.h
+@@ -45,6 +45,22 @@ typedef struct BusTransaction   BusTransaction;
+ typedef struct BusMatchmaker    BusMatchmaker;
+ typedef struct BusMatchRule     BusMatchRule;
+ typedef struct BusActivationEntry BusActivationEntry;
++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
+ {
+@@ -101,6 +117,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,
+@@ -136,14 +153,15 @@ void              bus_context_log_and_set_error                  (BusContext
+                                                                   const char       *name,
+                                                                   const char       *msg,
+                                                                   ...) _DBUS_GNUC_PRINTF (5, 6);
+-dbus_bool_t       bus_context_check_security_policy              (BusContext       *context,
++BusResult         bus_context_check_security_policy              (BusContext       *context,
+                                                                   BusTransaction   *transaction,
+                                                                   DBusConnection   *sender,
+                                                                   DBusConnection   *addressed_recipient,
+                                                                   DBusConnection   *proposed_recipient,
+                                                                   DBusMessage      *message,
+                                                                   BusActivationEntry *activation_entry,
+-                                                                  DBusError        *error);
++                                                                  DBusError        *error,
++                                                                  BusDeferredMessage **deferred_message);
+ void              bus_context_check_all_watches                  (BusContext       *context);
+ 
+ #endif /* BUS_BUS_H */
+diff --git a/bus/check.c b/bus/check.c
+new file mode 100644
+index 0000000..5b72d31
+--- /dev/null
++++ b/bus/check.c
+@@ -0,0 +1,217 @@
++/* -*- 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;
++#ifdef DBUS_ENABLE_CYNARA
++  BusCynara *cynara;
++#endif
++  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 c1c4191..e2f253d 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;
+@@ -159,6 +163,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 382a014..9e026d1 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-trivial.c b/bus/config-parser-trivial.c
+index dd65c6d..23dedb4 100644
+--- a/bus/config-parser-trivial.c
++++ b/bus/config-parser-trivial.c
+@@ -194,6 +194,7 @@ bus_config_parser_start_element (BusConfigParser   *parser,
+     case ELEMENT_POLICY:
+     case ELEMENT_LIMIT:
+     case ELEMENT_ALLOW:
++    case ELEMENT_CHECK:
+     case ELEMENT_DENY:
+     case ELEMENT_FORK:
+     case ELEMENT_PIDFILE:
+@@ -316,6 +317,7 @@ bus_config_parser_content (BusConfigParser   *parser,
+     case ELEMENT_POLICY:
+     case ELEMENT_LIMIT:
+     case ELEMENT_ALLOW:
++    case ELEMENT_CHECK:
+     case ELEMENT_DENY:
+     case ELEMENT_FORK:
+     case ELEMENT_PIDFILE:
+diff --git a/bus/config-parser.c b/bus/config-parser.c
+index be27d38..7f91469 100644
+--- a/bus/config-parser.c
++++ b/bus/config-parser.c
+@@ -1318,7 +1318,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;
+@@ -1360,6 +1360,7 @@ append_rule_from_element (BusConfigParser   *parser,
+   const char *own_prefix;
+   const char *user;
+   const char *group;
++  const char *privilege;
+ 
+   BusPolicyRule *rule;
+ 
+@@ -1390,6 +1391,7 @@ append_rule_from_element (BusConfigParser   *parser,
+                           "user", &user,
+                           "group", &group,
+                           "log", &log,
++                          "privilege", &privilege,
+                           NULL))
+     return FALSE;
+ 
+@@ -1422,6 +1424,7 @@ append_rule_from_element (BusConfigParser   *parser,
+ 
+   if (!(any_send_attribute ||
+         any_receive_attribute ||
++        privilege ||
+         own || own_prefix || user || group))
+     {
+       dbus_set_error (error, DBUS_ERROR_FAILED,
+@@ -1438,7 +1441,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:
+@@ -1589,7 +1615,7 @@ append_rule_from_element (BusConfigParser   *parser,
+                                 error))
+         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;
+       
+@@ -1694,7 +1720,7 @@ append_rule_from_element (BusConfigParser   *parser,
+                                 error))
+         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;
+ 
+@@ -1726,7 +1752,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;
+ 
+@@ -1752,7 +1778,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;
+ 
+@@ -1767,7 +1793,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;
+ 
+@@ -1784,7 +1810,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;
+ 
+@@ -1799,7 +1825,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;
+ 
+@@ -1823,6 +1849,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:
+@@ -1898,7 +1928,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)
+@@ -1913,7 +1943,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)
+@@ -1922,6 +1952,21 @@ start_policy_child (BusConfigParser   *parser,
+           return FALSE;
+         }
+       
++      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
+@@ -2284,6 +2329,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:
+@@ -2600,6 +2646,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:
+@@ -3127,6 +3174,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);
+@@ -3359,6 +3408,7 @@ elements_equal (const Element *a,
+     case ELEMENT_LISTEN:
+     case ELEMENT_AUTH:
+     case ELEMENT_ALLOW:
++    case ELEMENT_CHECK:
+     case ELEMENT_DENY:
+     case ELEMENT_FORK:
+     case ELEMENT_PIDFILE:
+diff --git a/bus/connection.c b/bus/connection.c
+index 53605fa..b348d42 100644
+--- a/bus/connection.c
++++ b/bus/connection.c
+@@ -36,6 +36,10 @@
+ #include <dbus/dbus-timeout.h>
+ #include <dbus/dbus-connection-internal.h>
+ #include <dbus/dbus-internals.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
+@@ -116,6 +120,9 @@ typedef struct
+ 
+   /** non-NULL if and only if this is a monitor */
+   DBusList *link_in_monitors;
++#ifdef DBUS_ENABLE_CYNARA
++  char *cynara_session_id;
++#endif
+ } BusConnectionData;
+ 
+ static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
+@@ -129,8 +136,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;
+ 
+@@ -354,7 +361,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
+@@ -363,7 +370,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
+@@ -372,7 +379,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
+@@ -381,7 +388,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
+@@ -390,7 +397,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
+@@ -448,6 +455,10 @@ free_connection_data (void *data)
+   
+   dbus_free (d->name);
+   
++#ifdef DBUS_ENABLE_CYNARA
++  free (d->cynara_session_id);
++#endif
++
+   dbus_free (d);
+ }
+ 
+@@ -1078,6 +1089,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,
+@@ -2333,6 +2360,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+                                   DBusMessage    *message)
+ {
+   DBusError error = DBUS_ERROR_INIT;
++  BusResult res;
+ 
+   /* We have to set the sender to the driver, and have
+    * to check security policy since it was not done in
+@@ -2370,10 +2398,11 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+    * if we're actively capturing messages, it's nice to log that we
+    * tried to send it and did not allow ourselves to do so.
+    */
+-  if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
+-                                          transaction,
+-                                          NULL, connection, connection,
+-                                          message, NULL, &error))
++  res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
++                                           transaction,
++                                           NULL, connection, connection, message, NULL,
++                                           &error, NULL);
++  if (res == BUS_RESULT_FALSE)
+     {
+       if (!bus_transaction_capture_error_reply (transaction, connection,
+                                                 &error, message))
+@@ -2388,6 +2417,12 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+       dbus_error_free (&error);
+       return TRUE;
+     }
++  else if (res == BUS_RESULT_LATER)
++    {
++      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
++      dbus_error_free (&error);
++      return TRUE;
++    }
+ 
+   return bus_transaction_send (transaction, connection, message);
+ }
+diff --git a/bus/connection.h b/bus/connection.h
+index 9e253ae..71078ea 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);
+@@ -124,6 +125,9 @@ dbus_bool_t bus_connection_be_monitor (DBusConnection  *connection,
+                                        BusTransaction  *transaction,
+                                        DBusList       **rules,
+                                        DBusError       *error);
++#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 */
+ 
+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 19228be..d3867f7 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"
+@@ -64,14 +65,18 @@ send_one_message (DBusConnection *connection,
+                   DBusError      *error)
+ {
+   DBusError stack_error = DBUS_ERROR_INIT;
++  BusDeferredMessage *deferred_message;
++  BusResult result;
+ 
+-  if (!bus_context_check_security_policy (context, transaction,
++  result = bus_context_check_security_policy (context, transaction,
+                                           sender,
+                                           addressed_recipient,
+                                           connection,
+                                           message,
+                                           NULL,
+-                                          &stack_error))
++                                          &stack_error,
++                                          &deferred_message);
++  if (result != BUS_RESULT_TRUE)
+     {
+       if (!bus_transaction_capture_error_reply (transaction, sender,
+                                                 &stack_error, message))
+@@ -130,6 +135,8 @@ bus_dispatch_matches (BusTransaction *transaction,
+   BusMatchmaker *matchmaker;
+   DBusList *link;
+   BusContext *context;
++  BusDeferredMessage *deferred_message;
++  BusResult res;
+ 
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ 
+@@ -145,11 +152,20 @@ 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, NULL, error))
++      res = bus_context_check_security_policy (context, transaction,
++                                               sender, addressed_recipient,
++                                               addressed_recipient,
++                                               message, NULL, 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,
+@@ -374,19 +390,31 @@ bus_dispatch (DBusConnection *connection,
+   if (service_name &&
+       strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
+     {
++      BusDeferredMessage *deferred_message;
++      BusResult res;
++
+       if (!bus_transaction_capture (transaction, connection, NULL, message))
+         {
+           BUS_SET_OOM (&error);
+           goto out;
+         }
+ 
+-      if (!bus_context_check_security_policy (context, transaction,
+-                                              connection, NULL, NULL, message,
+-                                              NULL, &error))
++      res = bus_context_check_security_policy (context, transaction,
++                                               connection, NULL, NULL, message, NULL,
++                                               &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/driver.h b/bus/driver.h
+index ac1289d..a7297ad 100644
+--- a/bus/driver.h
++++ b/bus/driver.h
+@@ -66,5 +66,7 @@ dbus_bool_t bus_driver_send_ack_reply     (DBusConnection  *connection,
+                                            BusTransaction  *transaction,
+                                            DBusMessage     *message,
+                                            DBusError       *error);
++dbus_bool_t bus_driver_check_message_is_for_us (DBusMessage *message,
++                                                DBusError   *error);
+ 
+ #endif /* BUS_DRIVER_H */
+diff --git a/bus/policy.c b/bus/policy.c
+index a37be80..7de92c6 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"
+@@ -33,7 +34,7 @@
+ 
+ BusPolicyRule*
+ bus_policy_rule_new (BusPolicyRuleType type,
+-                     dbus_bool_t       allow)
++                     BusPolicyRuleAccess access)
+ {
+   BusPolicyRule *rule;
+ 
+@@ -43,7 +44,7 @@ bus_policy_rule_new (BusPolicyRuleType type,
+ 
+   rule->type = type;
+   rule->refcount = 1;
+-  rule->allow = allow;
++  rule->access = access;
+ 
+   switch (rule->type)
+     {
+@@ -55,18 +56,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;
+@@ -122,7 +124,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
+         default:
+           _dbus_assert_not_reached ("invalid rule");
+         }
+-      
++
++      dbus_free (rule->privilege);
+       dbus_free (rule);
+     }
+ }
+@@ -435,7 +438,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;
+@@ -873,18 +879,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
+    */
+@@ -892,7 +903,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)
+     {
+@@ -923,13 +934,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;
+             }
+ 
+@@ -937,7 +949,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;
+@@ -960,13 +972,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))
+@@ -1079,33 +1093,64 @@ 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:
++        default:
++          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",
++                     (int)(intptr_t)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 &&
+@@ -1118,7 +1163,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)
+     {
+@@ -1141,19 +1186,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;
+@@ -1162,13 +1209,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;
+             }
+ 
+@@ -1176,7 +1224,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;
+@@ -1199,13 +1247,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))
+@@ -1295,14 +1343,43 @@ 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:
++        default:
++          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",
++                     (int)(intptr_t)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;
+ }
+ 
+ 
+@@ -1354,7 +1431,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 ec43ffa..f839d23 100644
+--- a/bus/policy.h
++++ b/bus/policy.h
+@@ -46,6 +46,14 @@ typedef enum
+   BUS_POLICY_TRISTATE_TRUE
+ } BusPolicyTristate;
+ 
++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))
+@@ -56,8 +64,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
+@@ -118,7 +127,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);
+ 
+@@ -152,21 +161,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,
++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);
+-dbus_bool_t      bus_client_policy_check_can_receive (BusClientPolicy  *policy,
++                                                      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);
++                                                      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 d1e3a29..11b5ffd 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1742,6 +1742,17 @@ AC_ARG_ENABLE([user-session],
+ AM_CONDITIONAL([DBUS_ENABLE_USER_SESSION],
+   [test "x$enable_user_session" = xyes])
+ 
++#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/Version
+@@ -1824,6 +1835,7 @@ echo "
+         Building bus stats API:   ${enable_stats}
+         Building SELinux support: ${have_selinux}
+         Building AppArmor support: ${have_apparmor}
++        Building Cynara support:  ${enable_cynara}
+         Building inotify support: ${have_inotify}
+         Building kqueue support:  ${have_kqueue}
+         Building systemd support: ${have_systemd}
+diff --git a/test/Makefile.am b/test/Makefile.am
+index af1e13b..e6f50e1 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -439,6 +439,7 @@ in_data = \
+ 	data/valid-config-files/debug-allow-all.conf.in \
+ 	data/valid-config-files/finite-timeout.conf.in \
+ 	data/valid-config-files/forbidding.conf.in \
++	data/valid-config-files/debug-check-some.conf.in \
+ 	data/valid-config-files/incoming-limit.conf.in \
+ 	data/valid-config-files/max-completed-connections.conf.in \
+ 	data/valid-config-files/max-connections-per-user.conf.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.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
new file mode 100644
index 000000000..bac8cf97f
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0002-Disable-message-dispatching-when-send-rule-result-is.patch
@@ -0,0 +1,967 @@
+From c2f4ba585c777b731df6b6b8a165b6cc4dc5d639 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 2/8] Disable message dispatching when send rule result is not
+ known
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Cherry-picked from b1b87ad9f20b2052c28431b48e81073078a745ce
+by Jose Bollo.
+
+Updated for dbus 1.10.20 by Scott Murray and José Bollo
+
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+---
+ bus/activation.c                |  76 +++++++++++--
+ bus/check.c                     | 109 +++++++++++++++++--
+ bus/check.h                     |  10 ++
+ bus/cynara.c                    |   1 -
+ bus/dispatch.c                  | 184 ++++++++++++++++++++++++++++----
+ bus/dispatch.h                  |   2 +-
+ bus/driver.c                    |  12 ++-
+ dbus/dbus-connection-internal.h |  15 +++
+ dbus/dbus-connection.c          | 125 +++++++++++++++++++++-
+ dbus/dbus-list.c                |  29 +++++
+ dbus/dbus-list.h                |   3 +
+ dbus/dbus-shared.h              |   3 +-
+ 12 files changed, 528 insertions(+), 41 deletions(-)
+
+diff --git a/bus/activation.c b/bus/activation.c
+index f9c6c62..8301b59 100644
+--- a/bus/activation.c
++++ b/bus/activation.c
+@@ -32,6 +32,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>
+@@ -94,6 +95,8 @@ struct BusPendingActivationEntry
+   DBusConnection *connection;
+ 
+   dbus_bool_t auto_activation;
++
++  dbus_bool_t is_put_back;
+ };
+ 
+ typedef struct
+@@ -1241,20 +1244,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
+@@ -1266,11 +1272,44 @@ bus_activation_send_pending_auto_activation_messages (BusActivation  *activation
+                   bus_connection_send_oom_error (entry->connection,
+                                                  entry->activation_message);
+                 }
+-
+               dbus_error_free (&error);
+               link = next;
+               continue;
+             }
++          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;
++                }
++
++              /**
++               * 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);
++                }
++            }
+         }
+ 
+       link = next;
+@@ -1287,6 +1326,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;
+ }
+ 
+@@ -2079,6 +2131,7 @@ 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' requested by '%s' (%s)",
+                                service_name,
+@@ -2086,8 +2139,17 @@ bus_activation_activate_service (BusActivation  *activation,
+                                bus_connection_get_name (connection),
+                                bus_connection_get_loginfo (connection));
+               /* Wonderful, systemd is connected, let's just send the msg */
+-              retval = bus_dispatch_matches (activation_transaction, NULL,
++              res = bus_dispatch_matches (activation_transaction, NULL,
+                                              systemd, message, error);
++
++              if (res == BUS_RESULT_TRUE)
++                retval = TRUE;
++              else
++                {
++                  retval = FALSE;
++                  if (res == BUS_RESULT_LATER)
++                    _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
++                }
+             }
+           else
+             {
+diff --git a/bus/check.c b/bus/check.c
+index 5b72d31..4b8a699 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
++BusResult (*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;
+ #ifdef DBUS_ENABLE_CYNARA
+   BusCynara *cynara;
+@@ -137,16 +188,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;
+ }
+@@ -206,6 +295,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..d177549 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 BusResult (*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 d3867f7..50a22a3 100644
+--- a/bus/dispatch.c
++++ b/bus/dispatch.c
+@@ -35,6 +35,7 @@
+ #include "signals.h"
+ #include "test.h"
+ #include <dbus/dbus-internals.h>
++#include <dbus/dbus-connection-internal.h>
+ #include <dbus/dbus-misc.h>
+ #include <string.h>
+ 
+@@ -122,7 +123,7 @@ send_one_message (DBusConnection *connection,
+   return TRUE;
+ }
+ 
+-dbus_bool_t
++BusResult
+ bus_dispatch_matches (BusTransaction *transaction,
+                       DBusConnection *sender,
+                       DBusConnection *addressed_recipient,
+@@ -158,13 +159,29 @@ bus_dispatch_matches (BusTransaction *transaction,
+                                                message, NULL, 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) &&
+@@ -175,14 +192,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;
+         }
+     }
+ 
+@@ -197,7 +214,7 @@ bus_dispatch_matches (BusTransaction *transaction,
+                                       &recipients))
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+ 
+   link = _dbus_list_get_first_link (&recipients);
+@@ -219,10 +236,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
+@@ -409,10 +426,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;
+         }
+ 
+@@ -514,8 +533,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))
+@@ -5060,9 +5085,132 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
+ }
+ #endif
+ 
++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 BusResult
++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 (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 cd0a714..f414f64 100644
+--- a/bus/driver.c
++++ b/bus/driver.c
+@@ -218,6 +218,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);
+@@ -253,7 +254,16 @@ bus_driver_send_service_owner_changed (const char     *service_name,
+   if (!bus_transaction_capture (transaction, NULL, NULL, message))
+     goto oom;
+ 
+-  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
++    {
++      retval = FALSE;
++      if (res == BUS_RESULT_LATER)
++        /* should never happen */
++        _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
++    }
+   dbus_message_unref (message);
+ 
+   return retval;
+diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
+index 4835732..94b1c95 100644
+--- a/dbus/dbus-connection-internal.h
++++ b/dbus/dbus-connection-internal.h
+@@ -118,6 +118,21 @@ DBUS_PRIVATE_EXPORT
+ dbus_bool_t       _dbus_connection_get_linux_security_label       (DBusConnection  *connection,
+                                                                    char           **label_p);
+ 
++DBUS_PRIVATE_EXPORT
++void              _dbus_connection_enable_dispatch                (DBusConnection *connection);
++DBUS_PRIVATE_EXPORT
++void              _dbus_connection_disable_dispatch               (DBusConnection *connection);
++
++DBUS_PRIVATE_EXPORT
++dbus_bool_t       _dbus_connection_putback_message                (DBusConnection *connection,
++                                                                   DBusMessage    *after_message,
++                                                                   DBusMessage    *message,
++                                                                   DBusError      *error);
++
++DBUS_PRIVATE_EXPORT
++dbus_bool_t       _dbus_connection_remove_message                 (DBusConnection *connection,
++                                                                   DBusMessage    *message);
++
+ /* if DBUS_ENABLE_STATS */
+ DBUS_PRIVATE_EXPORT
+ void _dbus_connection_get_stats (DBusConnection *connection,
+diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
+index c525b6d..958968c 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
+@@ -4069,6 +4103,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
+@@ -4252,8 +4362,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_unlocked(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;
+@@ -4716,6 +4827,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");
+@@ -4838,9 +4951,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 8e713c0..32ea871 100644
+--- a/dbus/dbus-list.c
++++ b/dbus/dbus-list.c
+@@ -458,6 +458,35 @@ _dbus_list_remove_last (DBusList **list,
+     return FALSE;
+ }
+ 
++/**
++ * 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.
+diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h
+index 9350a0d..fee9f1b 100644
+--- a/dbus/dbus-list.h
++++ b/dbus/dbus-list.h
+@@ -68,6 +68,9 @@ DBUS_PRIVATE_EXPORT
+ void        _dbus_list_remove_link        (DBusList **list,
+                                            DBusList  *link);
+ DBUS_PRIVATE_EXPORT
++DBusList*   _dbus_list_find_first         (DBusList **list,
++                                           void      *data);
++DBUS_PRIVATE_EXPORT
+ DBusList*   _dbus_list_find_last          (DBusList **list,
+                                            void      *data);
+ DBUS_PRIVATE_EXPORT
+diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h
+index 7ab9103..e5bfbed 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.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0003-Handle-unavailability-of-policy-results-for-broadcas.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
new file mode 100644
index 000000000..7d89a7496
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
@@ -0,0 +1,1095 @@
+From 9d39aa9dd55680529d721a0389ce9ef579bb669a 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 3/8] Handle unavailability of policy results for broadcasts
+ and receive rules
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Cherry picked from 1e231194610892dd4360224998d91336097b05a1 by Jose Bollo
+
+Updated for dbus 1.10.20 by Scott Murray and José Bollo
+
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+---
+ bus/activation.c |   4 +-
+ bus/bus.c        |  50 ++++++--
+ bus/bus.h        |  19 +++
+ bus/check.c      | 307 +++++++++++++++++++++++++++++++++++++++++++++++
+ bus/check.h      |  25 ++++
+ bus/connection.c | 168 ++++++++++++++++++++++++--
+ bus/connection.h |  19 ++-
+ bus/dispatch.c   | 115 +++++++++++++++---
+ bus/dispatch.h   |  11 +-
+ bus/driver.c     |   2 +-
+ bus/policy.c     |   6 +
+ 11 files changed, 683 insertions(+), 43 deletions(-)
+
+diff --git a/bus/activation.c b/bus/activation.c
+index 8301b59..d4b597c 100644
+--- a/bus/activation.c
++++ b/bus/activation.c
+@@ -1259,7 +1259,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
+@@ -2140,7 +2140,7 @@ bus_activation_activate_service (BusActivation  *activation,
+                                bus_connection_get_loginfo (connection));
+               /* Wonderful, systemd is connected, let's just send the msg */
+               res = bus_dispatch_matches (activation_transaction, NULL,
+-                                             systemd, message, error);
++                                             systemd, message, NULL, error);
+ 
+               if (res == BUS_RESULT_TRUE)
+                 retval = TRUE;
+diff --git a/bus/bus.c b/bus/bus.c
+index 6fc45d0..0aa700b 100644
+--- a/bus/bus.c
++++ b/bus/bus.c
+@@ -1800,17 +1800,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
+@@ -1869,3 +1861,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 82c32c8..1b08f7c 100644
+--- a/bus/bus.h
++++ b/bus/bus.h
+@@ -164,4 +164,23 @@ BusResult         bus_context_check_security_policy              (BusContext
+                                                                   BusDeferredMessage **deferred_message);
+ void              bus_context_check_all_watches                  (BusContext       *context);
+ 
++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 4b8a699..f3d283f 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;
+@@ -135,6 +138,89 @@ bus_check_enable_dispatch_callback (BusDeferredMessage *deferred_message,
+   _dbus_connection_enable_dispatch(deferred_message->sender);
+ }
+ 
++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)
+ {
+@@ -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
+ BusResult (*bus_check_test_override) (DBusConnection *connection,
+                                         const char *privilege);
+@@ -259,6 +359,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;
+@@ -295,12 +398,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, 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)
+@@ -310,3 +616,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 d177549..9c13c18 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 BusResult (*bus_check_test_override) (DBusConnection *connection,
+                                                const char *privilege);
+diff --git a/bus/connection.c b/bus/connection.c
+index b348d42..ee93384 100644
+--- a/bus/connection.c
++++ b/bus/connection.c
+@@ -31,11 +31,13 @@
+ #include "expirelist.h"
+ #include "selinux.h"
+ #include "apparmor.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-internals.h>
++#include <dbus/dbus-message-internal.h>
+ #ifdef DBUS_ENABLE_CYNARA
+ #include <stdlib.h>
+ #include <cynara-session.h>
+@@ -102,6 +104,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;
+@@ -268,6 +271,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 */
+@@ -2307,7 +2312,7 @@ bus_transaction_capture (BusTransaction *transaction,
+     {
+       DBusConnection *recipient = link->data;
+ 
+-      if (!bus_transaction_send (transaction, recipient, message))
++      if (!bus_transaction_send (transaction, recipient, message, FALSE))
+         goto out;
+     }
+ 
+@@ -2361,6 +2366,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+ {
+   DBusError error = DBUS_ERROR_INIT;
+   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
+@@ -2401,7 +2407,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+   res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
+                                            transaction,
+                                            NULL, connection, connection, message, NULL,
+-                                           &error, NULL);
++                                           &error, &deferred_message);
+   if (res == BUS_RESULT_FALSE)
+     {
+       if (!bus_transaction_capture_error_reply (transaction, connection,
+@@ -2419,18 +2425,20 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
+     }
+   else if (res == BUS_RESULT_LATER)
+     {
+-      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
+       dbus_error_free (&error);
+-      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;
+@@ -2456,7 +2464,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)
+     {
+@@ -2708,6 +2737,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 71078ea..97dae96 100644
+--- a/bus/connection.h
++++ b/bus/connection.h
+@@ -85,6 +85,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);
+@@ -137,7 +153,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_capture          (BusTransaction               *transaction,
+                                                   DBusConnection               *connection,
+                                                   DBusConnection               *addressed_recipient,
+diff --git a/bus/dispatch.c b/bus/dispatch.c
+index 50a22a3..7d30ce4 100644
+--- a/bus/dispatch.c
++++ b/bus/dispatch.c
+@@ -33,6 +33,7 @@
+ #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>
+@@ -77,7 +78,7 @@ send_one_message (DBusConnection *connection,
+                                           NULL,
+                                           &stack_error,
+                                           &deferred_message);
+-  if (result != BUS_RESULT_TRUE)
++  if (result == BUS_RESULT_FALSE)
+     {
+       if (!bus_transaction_capture_error_reply (transaction, sender,
+                                                 &stack_error, message))
+@@ -112,9 +113,19 @@ send_one_message (DBusConnection *connection,
+       return TRUE; /* don't send it but don't return an error either */
+     }
+ 
++  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;
+@@ -124,11 +135,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;
+@@ -137,7 +149,6 @@ bus_dispatch_matches (BusTransaction *transaction,
+   DBusList *link;
+   BusContext *context;
+   BusDeferredMessage *deferred_message;
+-  BusResult res;
+ 
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ 
+@@ -153,16 +164,80 @@ bus_dispatch_matches (BusTransaction *transaction,
+   /* First, send the message to the addressed_recipient, if there is one. */
+   if (addressed_recipient != NULL)
+     {
+-      res = bus_context_check_security_policy (context, transaction,
++      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, NULL, error,
+                                                &deferred_message);
+-      if (res == BUS_RESULT_FALSE)
++
++      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)
+@@ -173,13 +248,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;
+             }
+         }
+@@ -196,7 +276,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;
+@@ -534,7 +615,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 f414f64..d89a658 100644
+--- a/bus/driver.c
++++ b/bus/driver.c
+@@ -254,7 +254,7 @@ bus_driver_send_service_owner_changed (const char     *service_name,
+   if (!bus_transaction_capture (transaction, NULL, NULL, message))
+     goto oom;
+ 
+-  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
+diff --git a/bus/policy.c b/bus/policy.c
+index 7de92c6..483cc97 100644
+--- a/bus/policy.c
++++ b/bus/policy.c
+@@ -1122,6 +1122,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;
+@@ -1372,6 +1375,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.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0004-Add-own-rule-result-unavailability-handling.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0004-Add-own-rule-result-unavailability-handling.patch
new file mode 100644
index 000000000..9953dcaac
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0004-Add-own-rule-result-unavailability-handling.patch
@@ -0,0 +1,1505 @@
+From 28ada62c98d74285dc22b66650b09b6c8f2c28c4 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 4/8] Add own rule result unavailability handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Cherry-picked from 35ef89cd6777ea2430077fc621d21bd01df92349 by Jose.bollo
+
+Updated for dbus 1.10.20 by Scott Murray and José Bollo
+
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+---
+ bus/dispatch.c |  11 +-
+ bus/driver.c   | 334 ++++++++++++++++++++++++++++---------------------
+ bus/driver.h   |   2 +-
+ bus/policy.c   |  52 ++++++--
+ bus/policy.h   |   6 +-
+ bus/services.c |  26 ++--
+ bus/services.h |   3 +-
+ bus/stats.c    |  23 ++--
+ bus/stats.h    |   6 +-
+ 9 files changed, 283 insertions(+), 180 deletions(-)
+
+diff --git a/bus/dispatch.c b/bus/dispatch.c
+index 7d30ce4..4b84c21 100644
+--- a/bus/dispatch.c
++++ b/bus/dispatch.c
+@@ -517,8 +517,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 d89a658..aaeb3b2 100644
+--- a/bus/driver.c
++++ b/bus/driver.c
+@@ -420,7 +420,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,
+@@ -428,7 +428,7 @@ bus_driver_handle_hello (DBusConnection *connection,
+ {
+   DBusString unique_name;
+   BusService *service;
+-  dbus_bool_t retval;
++  BusResult retval;
+   BusRegistry *registry;
+   BusConnections *connections;
+   DBusError tmp_error;
+@@ -442,7 +442,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
+@@ -464,16 +464,16 @@ bus_driver_handle_hello (DBusConnection *connection,
+       bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s (%s=%d)",
+           tmp_error.message, limit_name, limit);
+       dbus_move_error (&tmp_error, 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);
+ 
+@@ -506,7 +506,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);
+@@ -558,7 +558,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,
+@@ -580,14 +580,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);
+@@ -599,7 +599,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;
+     }
+ 
+   {
+@@ -611,7 +611,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;
+       }
+   }
+ 
+@@ -624,7 +624,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;
+     }
+@@ -635,23 +635,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,
+@@ -673,14 +673,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);
+@@ -692,7 +692,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;
+     }
+ 
+   {
+@@ -704,7 +704,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;
+       }
+   }
+ 
+@@ -717,7 +717,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;
+     }
+@@ -728,23 +728,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,
+@@ -755,7 +755,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);
+@@ -766,20 +767,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)
+@@ -800,7 +805,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
+       goto out;
+     }
+ 
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+ 
+  out:
+   if (reply)
+@@ -808,7 +813,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,
+@@ -818,7 +823,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);
+@@ -828,11 +833,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);
+@@ -861,7 +866,7 @@ bus_driver_handle_release_service (DBusConnection *connection,
+       goto out;
+     }
+ 
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+ 
+  out:
+   if (reply)
+@@ -869,7 +874,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,
+@@ -880,7 +885,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);
+@@ -890,9 +895,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)
+     {
+@@ -926,7 +931,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
+       goto out;
+     }
+ 
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+ 
+  out:
+   if (reply)
+@@ -935,7 +940,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,
+@@ -943,7 +948,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);
+@@ -957,10 +962,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))
+@@ -970,7 +975,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
+       goto out;
+     }
+ 
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+ 
+  out:
+   return retval;
+@@ -1072,13 +1077,13 @@ bus_driver_send_or_activate (BusTransaction *transaction,
+   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;
+   BusContext *context;
+   DBusMessageIter iter;
+@@ -1100,7 +1105,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+                       "Cannot change activation environment "
+                       "on a system bus.");
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+ 
+   activation = bus_connection_get_activation (connection);
+@@ -1114,7 +1119,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+ 
+   dbus_message_iter_recurse (&iter, &dict_iter);
+ 
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+   systemd_message = NULL;
+ 
+   /* Then loop through the sent dictionary, add the location of
+@@ -1279,7 +1284,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
+   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
+     goto out;
+ 
+-  retval = TRUE;
++  retval = BUS_RESULT_TRUE;
+ 
+  out:
+   if (systemd_message != NULL)
+@@ -1289,7 +1294,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,
+@@ -1371,16 +1376,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,
+@@ -1423,16 +1428,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,
+@@ -1502,7 +1507,7 @@ bus_driver_handle_get_service_owner (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_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,
+@@ -1606,7 +1611,7 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
+ 
+   dbus_message_unref (reply);
+ 
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+  oom:
+   BUS_SET_OOM (error);
+@@ -1619,10 +1624,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,
+@@ -1679,7 +1684,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);
+@@ -1688,10 +1693,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,
+@@ -1748,7 +1753,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);
+@@ -1757,10 +1762,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,
+@@ -1811,7 +1816,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);
+@@ -1820,10 +1825,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,
+@@ -1872,7 +1877,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);
+@@ -1881,10 +1886,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,
+@@ -1998,7 +2003,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
+ 
+   dbus_message_unref (reply);
+ 
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+  oom:
+   BUS_SET_OOM (error);
+@@ -2012,10 +2017,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,
+@@ -2040,7 +2045,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);
+@@ -2049,11 +2054,11 @@ 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;
+ }
+ 
+ #ifdef DBUS_ENABLE_VERBOSE_MODE
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_enable_verbose (DBusConnection *connection,
+                                   BusTransaction *transaction,
+                                   DBusMessage    *message,
+@@ -2073,7 +2078,7 @@ bus_driver_handle_enable_verbose (DBusConnection *connection,
+     _dbus_set_verbose(TRUE);
+ 
+     dbus_message_unref (reply);
+-    return TRUE;
++    return BUS_RESULT_TRUE;
+ 
+    oom:
+     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -2082,10 +2087,10 @@ bus_driver_handle_enable_verbose (DBusConnection *connection,
+ 
+     if (reply)
+       dbus_message_unref (reply);
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_disable_verbose (DBusConnection *connection,
+                                    BusTransaction *transaction,
+                                    DBusMessage    *message,
+@@ -2105,7 +2110,7 @@ bus_driver_handle_disable_verbose (DBusConnection *connection,
+     _dbus_set_verbose(FALSE);
+ 
+     dbus_message_unref (reply);
+-    return TRUE;
++    return BUS_RESULT_TRUE;
+ 
+    oom:
+     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -2114,11 +2119,11 @@ bus_driver_handle_disable_verbose (DBusConnection *connection,
+ 
+     if (reply)
+       dbus_message_unref (reply);
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ }
+ #endif
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_id (DBusConnection *connection,
+                           BusTransaction *transaction,
+                           DBusMessage    *message,
+@@ -2134,7 +2139,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;
+@@ -2160,7 +2165,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);
+@@ -2170,10 +2175,10 @@ bus_driver_handle_get_id (DBusConnection *connection,
+   if (reply)
+     dbus_message_unref (reply);
+   _dbus_string_free (&uuid);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_become_monitor (DBusConnection *connection,
+                                   BusTransaction *transaction,
+                                   DBusMessage    *message,
+@@ -2189,7 +2194,7 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
+   int i;
+   int n_match_rules;
+   dbus_uint32_t flags;
+-  dbus_bool_t ret = FALSE;
++  BusResult ret = BUS_RESULT_FALSE;
+ 
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ 
+@@ -2262,10 +2267,10 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
+   if (!bus_connection_be_monitor (connection, transaction, &rules, error))
+     goto out;
+ 
+-  ret = TRUE;
++  ret = BUS_RESULT_TRUE;
+ 
+ out:
+-  if (ret)
++  if (ret == BUS_RESULT_TRUE)
+     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+   else
+     _DBUS_ASSERT_ERROR_IS_SET (error);
+@@ -2281,7 +2286,7 @@ out:
+   return ret;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_machine_id (DBusConnection *connection,
+                                   BusTransaction *transaction,
+                                   DBusMessage *message,
+@@ -2296,7 +2301,7 @@ bus_driver_handle_get_machine_id (DBusConnection *connection,
+   if (!_dbus_string_init (&uuid))
+     {
+       BUS_SET_OOM (error);
+-      return FALSE;
++      return BUS_RESULT_FALSE;
+     }
+ 
+   if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
+@@ -2321,7 +2326,7 @@ bus_driver_handle_get_machine_id (DBusConnection *connection,
+ 
+   _dbus_string_free (&uuid);
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+ oom:
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -2335,29 +2340,30 @@ fail:
+     dbus_message_unref (reply);
+ 
+   _dbus_string_free (&uuid);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_ping (DBusConnection *connection,
+                         BusTransaction *transaction,
+                         DBusMessage *message,
+                         DBusError *error)
+ {
+-  return bus_driver_send_ack_reply (connection, transaction, message, error);
++  return bus_driver_send_ack_reply (connection, transaction, message, error) == TRUE
++               ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
+ }
+ 
+-static dbus_bool_t bus_driver_handle_get (DBusConnection *connection,
++static BusResult bus_driver_handle_get (DBusConnection *connection,
+                                           BusTransaction *transaction,
+                                           DBusMessage *message,
+                                           DBusError *error);
+ 
+-static dbus_bool_t bus_driver_handle_get_all (DBusConnection *connection,
++static BusResult bus_driver_handle_get_all (DBusConnection *connection,
+                                               BusTransaction *transaction,
+                                               DBusMessage *message,
+                                               DBusError *error);
+ 
+-static dbus_bool_t bus_driver_handle_set (DBusConnection *connection,
++static BusResult bus_driver_handle_set (DBusConnection *connection,
+                                           BusTransaction *transaction,
+                                           DBusMessage *message,
+                                           DBusError *error);
+@@ -2389,10 +2395,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);
+   MethodFlags flags;
+ } MessageHandler;
+ 
+@@ -2511,7 +2517,7 @@ static const PropertyHandler dbus_property_handlers[] = {
+   { 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 properties_message_handlers[] = {
+@@ -2763,7 +2769,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,
+@@ -2784,13 +2790,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;
+     }
+ 
+   is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
+@@ -2815,7 +2821,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);
+@@ -2825,10 +2831,42 @@ bus_driver_handle_introspect (DBusConnection *connection,
+ 
+   _dbus_string_free (&xml);
+ 
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
++/*
++ * Set @error and return FALSE if the message is not directed to the
++ * dbus-daemon by its canonical object path. This is hardening against
++ * system services with poorly-written security policy files, which
++ * might allow sending dangerously broad equivalence classes of messages
++ * such as "anything with this assumed-to-be-safe object path".
++ *
++ * dbus-daemon is unusual in that it normally ignores the object path
++ * of incoming messages; we need to keep that behaviour for the "read"
++ * read-only method calls like GetConnectionUnixUser for backwards
++ * compatibility, but it seems safer to be more restrictive for things
++ * intended to be root-only or privileged-developers-only.
++ *
++ * It is possible that there are other system services with the same
++ * quirk as dbus-daemon.
++ */
+ dbus_bool_t
++bus_driver_check_message_is_for_us (DBusMessage *message,
++                                    DBusError   *error)
++{
++  if (!dbus_message_has_path (message, DBUS_PATH_DBUS))
++    {
++      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
++          "Method '%s' is only available at the canonical object path '%s'",
++          dbus_message_get_member (message), DBUS_PATH_DBUS);
++
++      return FALSE;
++    }
++
++  return TRUE;
++}
++
++BusResult
+ bus_driver_handle_message (DBusConnection *connection,
+                            BusTransaction *transaction,
+ 			   DBusMessage    *message,
+@@ -2839,6 +2877,7 @@ bus_driver_handle_message (DBusConnection *connection,
+   const MessageHandler *mh;
+   dbus_bool_t found_interface = FALSE;
+   dbus_bool_t is_canonical_path;
++  BusResult res;
+ 
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ 
+@@ -2854,7 +2893,7 @@ bus_driver_handle_message (DBusConnection *connection,
+                                                   transaction,
+                                                   message,
+                                                   error))
+-        return FALSE;
++        return BUS_RESULT_FALSE;
+ 
+       context = bus_connection_get_context (connection);
+       systemd = bus_driver_get_owner_of_name (connection,
+@@ -2871,7 +2910,7 @@ bus_driver_handle_message (DBusConnection *connection,
+                            attacker ? attacker : "(unauthenticated)",
+                            bus_connection_get_loginfo (connection));
+           /* ignore it */
+-          return TRUE;
++          return BUS_RESULT_TRUE;
+         }
+ 
+       if (!bus_context_get_systemd_activation (context))
+@@ -2879,16 +2918,16 @@ bus_driver_handle_message (DBusConnection *connection,
+           bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
+                            "Ignoring unexpected ActivationFailure message "
+                            "while not using systemd activation");
+-          return FALSE;
++          return BUS_RESULT_FALSE;
+         }
+ 
+-      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" */
+@@ -2953,20 +2992,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;
+             }
+         }
+     }
+@@ -2978,7 +3024,7 @@ bus_driver_handle_message (DBusConnection *connection,
+                   "%s does not understand message %s",
+                   DBUS_SERVICE_DBUS, name);
+ 
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+ void
+@@ -3099,7 +3145,7 @@ interface_handler_find_property (const InterfaceHandler *ih,
+   return NULL;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get (DBusConnection *connection,
+                        BusTransaction *transaction,
+                        DBusMessage    *message,
+@@ -3120,18 +3166,18 @@ bus_driver_handle_get (DBusConnection *connection,
+                               DBUS_TYPE_STRING, &iface,
+                               DBUS_TYPE_STRING, &prop,
+                               DBUS_TYPE_INVALID))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   /* We only implement Properties on /org/freedesktop/DBus so far. */
+   ih = bus_driver_find_interface (iface, TRUE, error);
+ 
+   if (ih == NULL)
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   handler = interface_handler_find_property (ih, prop, error);
+ 
+   if (handler == NULL)
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   context = bus_transaction_get_context (transaction);
+ 
+@@ -3159,17 +3205,17 @@ bus_driver_handle_get (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;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_get_all (DBusConnection *connection,
+                            BusTransaction *transaction,
+                            DBusMessage    *message,
+@@ -3188,13 +3234,13 @@ bus_driver_handle_get_all (DBusConnection *connection,
+   if (!dbus_message_get_args (message, error,
+                               DBUS_TYPE_STRING, &iface,
+                               DBUS_TYPE_INVALID))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   /* We only implement Properties on /org/freedesktop/DBus so far. */
+   ih = bus_driver_find_interface (iface, TRUE, error);
+ 
+   if (ih == NULL)
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   context = bus_transaction_get_context (transaction);
+ 
+@@ -3229,7 +3275,7 @@ bus_driver_handle_get_all (DBusConnection *connection,
+     goto oom;
+ 
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+ oom_abandon_message:
+   _dbus_asv_abandon (&reply_iter, &array_iter);
+@@ -3239,10 +3285,10 @@ oom:
+     dbus_message_unref (reply);
+ 
+   BUS_SET_OOM (error);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+-static dbus_bool_t
++static BusResult
+ bus_driver_handle_set (DBusConnection *connection,
+                        BusTransaction *transaction,
+                        DBusMessage    *message,
+@@ -3271,15 +3317,15 @@ bus_driver_handle_set (DBusConnection *connection,
+   ih = bus_driver_find_interface (iface, TRUE, error);
+ 
+   if (ih == NULL)
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   handler = interface_handler_find_property (ih, prop, error);
+ 
+   if (handler == NULL)
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   /* We don't implement any properties that can be set yet. */
+   dbus_set_error (error, DBUS_ERROR_PROPERTY_READ_ONLY,
+                   "Property '%s.%s' cannot be set", iface, prop);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+diff --git a/bus/driver.h b/bus/driver.h
+index a7297ad..05e9886 100644
+--- a/bus/driver.h
++++ b/bus/driver.h
+@@ -35,7 +35,7 @@ typedef enum
+ } BusDriverFound;
+ 
+ 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 483cc97..f6f4d85 100644
+--- a/bus/policy.c
++++ b/bus/policy.c
+@@ -1390,18 +1390,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)
+     {
+@@ -1437,17 +1440,46 @@ 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;
++      default:
++      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
+@@ -1455,7 +1487,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) == BUS_RESULT_TRUE;
+ }
+ #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
+ 
+diff --git a/bus/policy.h b/bus/policy.h
+index f839d23..28ce8f2 100644
+--- a/bus/policy.h
++++ b/bus/policy.h
+@@ -182,8 +182,10 @@ BusResult        bus_client_policy_check_can_receive (BusClientPolicy  *policy,
+                                                       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 127edda..586af18 100644
+--- a/bus/services.c
++++ b/bus/services.c
+@@ -376,16 +376,17 @@ 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;
+@@ -393,8 +394,9 @@ bus_registry_acquire_service (BusRegistry      *registry,
+   BusSELinuxID *sid;
+   BusOwner *primary_owner;
+   int limit;
++  BusResult res;
+ 
+-  retval = FALSE;
++  retval = BUS_RESULT_FALSE;
+ 
+   if (!_dbus_validate_bus_name (service_name, 0,
+                                 _dbus_string_get_length (service_name)))
+@@ -467,7 +469,8 @@ bus_registry_acquire_service (BusRegistry      *registry,
+                                             _dbus_string_get_const_data (service_name), error))
+     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 "
+@@ -478,6 +481,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;
++    }
+ 
+   limit = bus_context_get_max_services_per_connection (registry->context);
+ 
+@@ -603,11 +611,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 1582255..c25be98 100644
+--- a/bus/stats.c
++++ b/bus/stats.c
+@@ -36,7 +36,7 @@
+ 
+ #ifdef DBUS_ENABLE_STATS
+ 
+-dbus_bool_t
++BusResult
+ bus_stats_handle_get_stats (DBusConnection *connection,
+                             BusTransaction *transaction,
+                             DBusMessage    *message,
+@@ -51,6 +51,9 @@ bus_stats_handle_get_stats (DBusConnection *connection,
+ 
+   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ 
++  if (!bus_driver_check_message_is_for_us (message, error))
++    return BUS_RESULT_FALSE;
++
+   context = bus_transaction_get_context (transaction);
+   connections = bus_context_get_connections (context);
+ 
+@@ -104,17 +107,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,
+@@ -209,7 +212,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
+     goto oom;
+ 
+   dbus_message_unref (reply);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+ oom:
+   BUS_SET_OOM (error);
+@@ -218,11 +221,11 @@ failed:
+   if (reply != NULL)
+     dbus_message_unref (reply);
+ 
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+ 
+-dbus_bool_t
++BusResult
+ bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
+                                       BusTransaction *transaction,
+                                       DBusMessage    *message,
+@@ -246,7 +249,7 @@ bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
+   matchmaker = bus_context_get_matchmaker (context);
+ 
+   if (!bus_registry_list_services (registry, &services, &services_len))
+-    return FALSE;
++    return BUS_RESULT_FALSE;
+ 
+   reply = dbus_message_new_method_return (message);
+   if (reply == NULL)
+@@ -325,7 +328,7 @@ bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
+ 
+   dbus_message_unref (reply);
+   dbus_free_string_array (services);
+-  return TRUE;
++  return BUS_RESULT_TRUE;
+ 
+ oom:
+   if (reply != NULL)
+@@ -334,7 +337,7 @@ oom:
+   dbus_free_string_array (services);
+ 
+   BUS_SET_OOM (error);
+-  return FALSE;
++  return BUS_RESULT_FALSE;
+ }
+ 
+ #endif
+diff --git a/bus/stats.h b/bus/stats.h
+index dcb022c..683fa17 100644
+--- a/bus/stats.h
++++ b/bus/stats.h
+@@ -25,17 +25,17 @@
+ 
+ #define BUS_INTERFACE_STATS "org.freedesktop.DBus.Debug.Stats"
+ 
+-dbus_bool_t bus_stats_handle_get_stats (DBusConnection *connection,
++BusResult bus_stats_handle_get_stats (DBusConnection *connection,
+                                         BusTransaction *transaction,
+                                         DBusMessage    *message,
+                                         DBusError      *error);
+ 
+-dbus_bool_t bus_stats_handle_get_connection_stats (DBusConnection *connection,
++BusResult bus_stats_handle_get_connection_stats (DBusConnection *connection,
+                                                    BusTransaction *transaction,
+                                                    DBusMessage    *message,
+                                                    DBusError      *error);
+ 
+-dbus_bool_t bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
++BusResult bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
+                                                   BusTransaction *transaction,
+                                                   DBusMessage    *message,
+                                                   DBusError      *error);
+-- 
+2.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0005-Perform-Cynara-runtime-policy-checks-by-default.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
new file mode 100644
index 000000000..5f7e96a3b
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
@@ -0,0 +1,180 @@
+From 1f7ba56c9ced669951061d13b06e31d96a170e37 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 5/8] Perform Cynara runtime policy checks by default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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.
+
+Cherry picked from e8610297cf7031e94eb314a2e8c11246f4405403 by Jose Bollo
+
+Updated for dbus 1.10.20 by Scott Murray and José Bollo
+
+Signed-off-by: Jacek Bukarewicz <j.bukarewicz@samsung.com>
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+---
+ bus/activation.c    | 42 ++++++++++++++++++++++++++----------------
+ bus/session.conf.in | 32 ++++++++++++++++++++++++++------
+ bus/system.conf.in  | 19 +++++++++++++++----
+ 3 files changed, 67 insertions(+), 26 deletions(-)
+
+diff --git a/bus/activation.c b/bus/activation.c
+index d4b597c..8aabeaa 100644
+--- a/bus/activation.c
++++ b/bus/activation.c
+@@ -1840,22 +1840,32 @@ bus_activation_activate_service (BusActivation  *activation,
+     }
+ 
+   if (auto_activation &&
+-      entry != NULL &&
+-      BUS_RESULT_TRUE != bus_context_check_security_policy (activation->context,
+-        transaction,
+-        connection, /* sender */
+-        NULL, /* addressed recipient */
+-        NULL, /* proposed recipient */
+-        activation_message,
+-        entry,
+-        error,
+-        NULL))
+-    {
+-      _DBUS_ASSERT_ERROR_IS_SET (error);
+-      _dbus_verbose ("activation not authorized: %s: %s\n",
+-          error != NULL ? error->name : "(error ignored)",
+-          error != NULL ? error->message : "(error ignored)");
+-      return FALSE;
++      entry != NULL)
++   {
++      BusResult result;
++
++      result = bus_context_check_security_policy (activation->context,
++                      transaction,
++                      connection, /* sender */
++                      NULL, /* addressed recipient */
++                      NULL, /* proposed recipient */
++                      activation_message,
++                      entry,
++                      error,
++                      NULL);
++      if (result == BUS_RESULT_FALSE)
++        {
++          _DBUS_ASSERT_ERROR_IS_SET (error);
++          _dbus_verbose ("activation not authorized: %s: %s\n",
++              error != NULL ? error->name : "(error ignored)",
++              error != NULL ? error->message : "(error ignored)");
++          return FALSE;
++        }
++      if (result == BUS_RESULT_LATER)
++        {
++          /* TODO */
++          _dbus_verbose ("ALERT FIX ME!!!!!!!!!!!!!!!");
++        }
+     }
+ 
+   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
+diff --git a/bus/session.conf.in b/bus/session.conf.in
+index affa7f1..157dfb4 100644
+--- a/bus/session.conf.in
++++ b/bus/session.conf.in
+@@ -27,12 +27,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>
+ 
+   <!-- Include legacy configuration location -->
+diff --git a/bus/system.conf.in b/bus/system.conf.in
+index f139b55..19d0c04 100644
+--- a/bus/system.conf.in
++++ b/bus/system.conf.in
+@@ -50,17 +50,20 @@
+     <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 -->
+     <allow send_destination="org.freedesktop.DBus"
+@@ -69,6 +72,14 @@
+            send_interface="org.freedesktop.DBus.Introspectable"/>
+     <allow send_destination="org.freedesktop.DBus"
+            send_interface="org.freedesktop.DBus.Properties"/>
++    <!-- 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 receive_sender="org.freedesktop.DBus"/>
++
+     <!-- But disallow some specific bus services -->
+     <deny send_destination="org.freedesktop.DBus"
+           send_interface="org.freedesktop.DBus"
+-- 
+2.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0006-Fix-SIGSEGV-on-disconnections.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0006-Fix-SIGSEGV-on-disconnections.patch
new file mode 100644
index 000000000..e51ad7ce4
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0006-Fix-SIGSEGV-on-disconnections.patch
@@ -0,0 +1,109 @@
+From 28077faa11827e1ca7a7245ffd62ee78091b6bd2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jose.bollo@iot.bzh>
+Date: Fri, 16 Aug 2019 13:29:23 +0200
+Subject: [PATCH 6/8] Fix SIGSEGV on disconnections
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Sometime, at start of the system, dbus-daemon was crashing
+because a pending authorisation were reactivating a closed
+connection.
+
+Also, clean unused function.
+
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+---
+ bus/check.c      |  5 +++++
+ bus/check.h      |  1 +
+ bus/connection.c | 14 +++-----------
+ bus/connection.h |  3 ---
+ 4 files changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/bus/check.c b/bus/check.c
+index f3d283f..b73d08b 100644
+--- a/bus/check.c
++++ b/bus/check.c
+@@ -617,3 +617,8 @@ bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
+     }
+ }
+ 
++void
++bus_deferred_message_abort (BusDeferredMessage *deferred_message)
++{
++  deferred_message->response_callback = NULL;
++}
+diff --git a/bus/check.h b/bus/check.h
+index 9c13c18..d718a69 100644
+--- a/bus/check.h
++++ b/bus/check.h
+@@ -93,6 +93,7 @@ void                bus_deferred_message_set_policy_check_info (BusDeferredMessa
+                                                                 const char *privilege);
+ dbus_bool_t         bus_deferred_message_check_message_limits (BusDeferredMessage *deferred_message,
+                                                                DBusError *error);
++void                bus_deferred_message_abort                (BusDeferredMessage *deferred_message);
+ 
+ 
+ #ifdef DBUS_ENABLE_EMBEDDED_TESTS
+diff --git a/bus/connection.c b/bus/connection.c
+index ee93384..b520d57 100644
+--- a/bus/connection.c
++++ b/bus/connection.c
+@@ -47,6 +47,7 @@
+ #define MAX_LOG_COMMAND_LEN 50
+ 
+ static void bus_connection_remove_transactions (DBusConnection *connection);
++static void bus_connection_clear_deferred_messages (DBusConnection *connection);
+ 
+ typedef struct
+ {
+@@ -2821,17 +2822,7 @@ bus_connection_pop_deferred_message (DBusConnection *connection)
+   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;
+-}
+-
++static
+ void
+ bus_connection_clear_deferred_messages (DBusConnection *connection)
+ {
+@@ -2846,6 +2837,7 @@ bus_connection_clear_deferred_messages (DBusConnection *connection)
+       next = _dbus_list_get_next_link (&d->deferred_messages, link);
+       message = link->data;
+ 
++      bus_deferred_message_abort(message);
+       bus_deferred_message_unref(message);
+       _dbus_list_remove_link(&d->deferred_messages, link);
+ 
+diff --git a/bus/connection.h b/bus/connection.h
+index 97dae96..6af7bf1 100644
+--- a/bus/connection.h
++++ b/bus/connection.h
+@@ -90,15 +90,12 @@ dbus_bool_t         bus_connection_queue_deferred_message   (DBusConnection *con
+                                                              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 */
+-- 
+2.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0007-Switch-from-cynara-to-cynagora.patch b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0007-Switch-from-cynara-to-cynagora.patch
new file mode 100644
index 000000000..7a69efcd2
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus-cynagora/0007-Switch-from-cynara-to-cynagora.patch
@@ -0,0 +1,1048 @@
+From 43cc361a5c32c81c0f93451bdb0ef781cd19a1cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jose.bollo@iot.bzh>
+Date: Tue, 4 Feb 2020 12:23:36 +0100
+Subject: [PATCH 7/8] Switch from cynara to cynagora
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+---
+ bus/Makefile.am                    |   8 +-
+ bus/bus.h                          |   2 +-
+ bus/check.c                        |  26 +-
+ bus/check.h                        |   2 +-
+ bus/connection.c                   |  27 ---
+ bus/connection.h                   |   3 -
+ bus/cynagora-check.c               | 330 +++++++++++++++++++++++++
+ bus/{cynara.h => cynagora-check.h} |  10 +-
+ bus/cynara.c                       | 373 -----------------------------
+ bus/system.conf.in                 |   6 +-
+ configure.ac                       |  18 +-
+ 11 files changed, 366 insertions(+), 439 deletions(-)
+ create mode 100644 bus/cynagora-check.c
+ rename bus/{cynara.h => cynagora-check.h} (81%)
+ delete mode 100644 bus/cynara.c
+
+diff --git a/bus/Makefile.am b/bus/Makefile.am
+index 2a8a72c..1720048 100644
+--- a/bus/Makefile.am
++++ b/bus/Makefile.am
+@@ -13,7 +13,7 @@ DBUS_BUS_LIBS = \
+ 	$(THREAD_LIBS) \
+ 	$(ADT_LIBS) \
+ 	$(NETWORK_libs) \
+-	$(CYNARA_LIBS) \
++	$(CYNAGORA_LIBS) \
+ 	$(NULL)
+ 
+ DBUS_LAUNCHER_LIBS = \
+@@ -31,7 +31,7 @@ AM_CPPFLAGS = \
+ 	$(APPARMOR_CFLAGS) \
+ 	-DDBUS_SYSTEM_CONFIG_FILE=\""$(dbusdatadir)/system.conf"\" \
+ 	-DDBUS_COMPILATION \
+-	$(CYNARA_CFLAGS) \
++	$(CYNAGORA_CFLAGS) \
+ 	$(NULL)
+ 
+ # if assertions are enabled, improve backtraces
+@@ -101,8 +101,8 @@ BUS_SOURCES=					\
+ 	config-parser-common.h			\
+ 	connection.c				\
+ 	connection.h				\
+-	cynara.c				\
+-	cynara.h				\
++	cynagora-check.c			\
++	cynagora-check.h			\
+ 	desktop-file.c				\
+ 	desktop-file.h				\
+ 	$(DIR_WATCH_SOURCE)			\
+diff --git a/bus/bus.h b/bus/bus.h
+index 1b08f7c..e167d9e 100644
+--- a/bus/bus.h
++++ b/bus/bus.h
+@@ -47,7 +47,7 @@ typedef struct BusMatchRule     BusMatchRule;
+ typedef struct BusActivationEntry BusActivationEntry;
+ typedef struct BusCheck         BusCheck;
+ typedef struct BusDeferredMessage BusDeferredMessage;
+-typedef struct BusCynara        BusCynara;
++typedef struct BusCynagora        BusCynagora;
+ 
+ /**
+  * BusResult is defined as a pointer to a dummy structure to allow detection of type mismatches.
+diff --git a/bus/check.c b/bus/check.c
+index b73d08b..ec30770 100644
+--- a/bus/check.c
++++ b/bus/check.c
+@@ -26,7 +26,7 @@
+ #include "check.h"
+ #include "connection.h"
+ #include "dispatch.h"
+-#include "cynara.h"
++#include "cynagora-check.h"
+ #include "utils.h"
+ #include <dbus/dbus-connection-internal.h>
+ #include <dbus/dbus-message-internal.h>
+@@ -38,7 +38,7 @@ typedef struct BusCheck
+   int refcount;
+ 
+   BusContext *context;
+-  BusCynara *cynara;
++  BusCynagora *cynagora;
+ } BusCheck;
+ 
+ typedef struct BusDeferredMessage
+@@ -81,7 +81,7 @@ bus_check_new (BusContext *context, DBusError *error)
+ 
+   check->refcount = 1;
+   check->context = context;
+-  check->cynara = bus_cynara_new(check, error);
++  check->cynagora = bus_cynagora_new(check, error);
+   if (dbus_error_is_set(error))
+     {
+       dbus_message_free_data_slot(&deferred_message_data_slot);
+@@ -110,7 +110,7 @@ bus_check_unref (BusCheck *check)
+ 
+   if (check->refcount == 0)
+     {
+-      bus_cynara_unref(check->cynara);
++      bus_cynagora_unref(check->cynagora);
+       dbus_message_free_data_slot(&deferred_message_data_slot);
+       dbus_free(check);
+     }
+@@ -122,10 +122,10 @@ bus_check_get_context (BusCheck *check)
+   return check->context;
+ }
+ 
+-BusCynara *
+-bus_check_get_cynara (BusCheck *check)
++BusCynagora *
++bus_check_get_cynagora (BusCheck *check)
+ {
+-  return check->cynara;
++  return check->cynagora;
+ }
+ 
+ static void
+@@ -276,8 +276,8 @@ bus_check_privilege (BusCheck *check,
+ {
+   BusDeferredMessage *previous_deferred_message;
+   BusResult result = BUS_RESULT_FALSE;
+-#ifdef DBUS_ENABLE_CYNARA
+-  BusCynara *cynara;
++#ifdef DBUS_ENABLE_CYNAGORA
++  BusCynagora *cynagora;
+ #endif
+   DBusConnection *connection;
+ 
+@@ -304,7 +304,7 @@ bus_check_privilege (BusCheck *check,
+            * 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.
++           * policy might result in both "can_send" and "can_own" Cynagora checks.
+            */
+           result = BUS_RESULT_TRUE;
+         }
+@@ -327,9 +327,9 @@ bus_check_privilege (BusCheck *check,
+   else
+     {
+       /* ask policy checkers */
+-#ifdef DBUS_ENABLE_CYNARA
+-      cynara = bus_check_get_cynara(check);
+-      result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
++#ifdef DBUS_ENABLE_CYNAGORA
++      cynagora = bus_check_get_cynagora(check);
++      result = bus_cynagora_check_privilege(cynagora, message, sender, addressed_recipient,
+           proposed_recipient, privilege, check_type, deferred_message);
+ #endif
+       if (result == BUS_RESULT_LATER && deferred_message != NULL)
+diff --git a/bus/check.h b/bus/check.h
+index d718a69..ab63c18 100644
+--- a/bus/check.h
++++ b/bus/check.h
+@@ -45,7 +45,7 @@ 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);
++BusCynagora  *bus_check_get_cynagora  (BusCheck *check);
+ BusResult   bus_check_privilege   (BusCheck *check,
+                                    DBusMessage *message,
+                                    DBusConnection *sender,
+diff --git a/bus/connection.c b/bus/connection.c
+index b520d57..48910e0 100644
+--- a/bus/connection.c
++++ b/bus/connection.c
+@@ -38,10 +38,6 @@
+ #include <dbus/dbus-connection-internal.h>
+ #include <dbus/dbus-internals.h>
+ #include <dbus/dbus-message-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
+@@ -124,9 +120,6 @@ typedef struct
+ 
+   /** non-NULL if and only if this is a monitor */
+   DBusList *link_in_monitors;
+-#ifdef DBUS_ENABLE_CYNARA
+-  char *cynara_session_id;
+-#endif
+ } BusConnectionData;
+ 
+ static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
+@@ -461,10 +454,6 @@ free_connection_data (void *data)
+   
+   dbus_free (d->name);
+   
+-#ifdef DBUS_ENABLE_CYNARA
+-  free (d->cynara_session_id);
+-#endif
+-
+   dbus_free (d);
+ }
+ 
+@@ -1095,22 +1084,6 @@ 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,
+diff --git a/bus/connection.h b/bus/connection.h
+index 6af7bf1..3116bcf 100644
+--- a/bus/connection.h
++++ b/bus/connection.h
+@@ -138,9 +138,6 @@ dbus_bool_t bus_connection_be_monitor (DBusConnection  *connection,
+                                        BusTransaction  *transaction,
+                                        DBusList       **rules,
+                                        DBusError       *error);
+-#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 */
+ 
+diff --git a/bus/cynagora-check.c b/bus/cynagora-check.c
+new file mode 100644
+index 0000000..6c0c635
+--- /dev/null
++++ b/bus/cynagora-check.c
+@@ -0,0 +1,330 @@
++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
++/* cynagora.c  Cynagora 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 "cynagora-check.h"
++#include "check.h"
++#include "utils.h"
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <errno.h>
++
++#include <dbus/dbus.h>
++#include <dbus/dbus-watch.h>
++#include <dbus/dbus-connection-internal.h>
++#include <bus/connection.h>
++
++#ifndef DBUS_ENABLE_CYNAGORA
++
++BusCynagora *
++bus_cynagora_new(BusCheck *check, DBusError *error)
++{
++  return NULL;
++}
++
++BusCynagora *
++bus_cynagora_ref (BusCynagora *cynagora)
++{
++  return NULL;
++}
++
++void
++bus_cynagora_unref (BusCynagora *cynagora)
++{
++}
++
++BusResult
++bus_cynagora_check_privilege (BusCynagora *cynagora,
++                            DBusMessage *message,
++                            DBusConnection *sender,
++                            DBusConnection *addressed_recipient,
++                            DBusConnection *proposed_recipient,
++                            const char *privilege,
++                            BusDeferredMessageStatus check_type,
++                            BusDeferredMessage **deferred_message_param)
++{
++  return BUS_RESULT_FALSE;
++}
++
++#endif
++
++#ifdef DBUS_ENABLE_CYNAGORA
++
++#include <time.h>
++#include <sys/epoll.h>
++
++#include <cynagora.h>
++
++#ifndef CYNAGORA_CACHE_SIZE
++#define CYNAGORA_CACHE_SIZE 8000
++#endif
++
++typedef struct BusCynagora
++{
++  int refcount;
++
++  BusContext   *context;
++  BusCheck     *check;
++  cynagora_t   *cynagora;
++  DBusWatch    *cynagora_watch;
++} BusCynagora;
++
++static int async_callback(void *closure,
++                          int op,
++                          int fd,
++                          uint32_t events);
++
++BusCynagora *
++bus_cynagora_new(BusCheck *check, DBusError *error)
++{
++  BusContext *context;
++  BusCynagora *cynagora;
++  int ret;
++
++  cynagora = dbus_new(BusCynagora, 1);
++  if (cynagora == NULL)
++    {
++      BUS_SET_OOM(error);
++      return NULL;
++    }
++
++  context = bus_check_get_context(check);
++
++  cynagora->refcount = 1;
++  cynagora->check = check;
++  cynagora->context = context;
++  cynagora->cynagora_watch = NULL;
++
++  ret = cynagora_create(&cynagora->cynagora, cynagora_Check, CYNAGORA_CACHE_SIZE, NULL);
++  if (ret < 0)
++    {
++      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to create Cynagora configuration");
++    }
++  else
++    {
++      ret = cynagora_async_setup(cynagora->cynagora, async_callback, cynagora);
++      if (ret < 0)
++        {
++          dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to initialize Cynagora client");
++        }
++        else
++        {
++          return cynagora;
++        }
++        cynagora_destroy(cynagora->cynagora);
++    }
++
++  dbus_free(cynagora);
++  return NULL;
++}
++
++BusCynagora *
++bus_cynagora_ref (BusCynagora *cynagora)
++{
++  _dbus_assert (cynagora->refcount > 0);
++  cynagora->refcount += 1;
++
++  return cynagora;
++}
++
++void
++bus_cynagora_unref (BusCynagora *cynagora)
++{
++  _dbus_assert (cynagora->refcount > 0);
++
++  cynagora->refcount -= 1;
++
++  if (cynagora->refcount == 0)
++    {
++      cynagora_destroy(cynagora->cynagora);
++      dbus_free(cynagora);
++    }
++}
++
++static void
++async_check_callback (void *closure, int status)
++{
++  BusDeferredMessage *deferred_message = closure;
++  BusResult result;
++
++  if (deferred_message == NULL)
++    return;
++
++  if (status == 1)
++    result = BUS_RESULT_TRUE;
++  else
++    result = BUS_RESULT_FALSE;
++
++  bus_deferred_message_response_received(deferred_message, result);
++  bus_deferred_message_unref(deferred_message);
++}
++
++BusResult
++bus_cynagora_check_privilege (BusCynagora *cynagora,
++                            DBusMessage *message,
++                            DBusConnection *sender,
++                            DBusConnection *addressed_recipient,
++                            DBusConnection *proposed_recipient,
++                            const char *permission,
++                            BusDeferredMessageStatus check_type,
++                            BusDeferredMessage **deferred_message_param)
++{
++  int result;
++  unsigned long uid;
++  unsigned long pid;
++  char *label;
++  char user[32];
++  char session[32];
++  DBusConnection *connection = check_type == BUS_DEFERRED_MESSAGE_CHECK_RECEIVE ? proposed_recipient : sender;
++  BusDeferredMessage *deferred_message;
++  BusResult ret;
++  cynagora_key_t key;
++
++  _dbus_assert(connection != NULL);
++
++  if (dbus_connection_get_unix_user(connection, &uid) == FALSE)
++      return BUS_RESULT_FALSE;
++
++  if (dbus_connection_get_unix_process_id(connection, &pid) == 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;
++    }
++
++  snprintf(user, sizeof(user), "%lu", uid);
++  snprintf(session, sizeof(session), "%lu", pid);
++
++  key.client = label;
++  key.session = session;
++  key.user = user;
++  key.permission = permission;
++
++  result = cynagora_cache_check(cynagora->cynagora, &key);
++  switch (result)
++  {
++  case 1:
++    _dbus_verbose("Cynagora: got ALLOWED answer from cache (client=%s session_id=%s user=%s permission=%s)\n",
++               label, session_id, user, permission);
++    ret = BUS_RESULT_TRUE;
++    break;
++
++  case 0:
++    _dbus_verbose("Cynagora: got DENIED answer from cache (client=%s session_id=%s user=%s permission=%s)\n",
++               label, session_id, user, permission);
++    ret = BUS_RESULT_FALSE;
++    break;
++
++  default:
++     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 = cynagora_async_check(cynagora->cynagora, &key, 1, 0, async_check_callback, deferred_message);
++    if (result == 0)
++      {
++        _dbus_verbose("Created Cynagora request: client=%s session_id=%s user=%s permission=%s "
++            "deferred_message=%p\n", label, session_id, user, permission, deferred_message);
++        if (deferred_message_param != NULL)
++          *deferred_message_param = deferred_message;
++        ret = BUS_RESULT_LATER;
++      }
++    else
++      {
++        _dbus_verbose("Error on cynagora request create: %i\n", result);
++        bus_deferred_message_unref(deferred_message);
++        ret = BUS_RESULT_FALSE;
++      }
++    break;
++  }
++out:
++  dbus_free(label);
++  return ret;
++}
++
++static dbus_bool_t
++watch_handler_callback(DBusWatch    *watch,
++                       unsigned int  flags,
++                       void         *data)
++{
++  BusCynagora *cynagora = (BusCynagora *)data;
++  int result = cynagora_async_process(cynagora->cynagora);
++  if (result < 0)
++      _dbus_verbose("cynagora_async_process returned %d\n", result);
++
++  return result != -ENOMEM ? TRUE : FALSE;
++}
++
++static int
++async_callback(void *closure, int op, int fd, uint32_t events)
++{
++  BusCynagora *cynagora = (BusCynagora *)closure;
++  DBusLoop *loop = bus_context_get_loop(cynagora->context);
++  unsigned int flags;
++  DBusWatch *watch;
++
++  /* compute flags */
++  flags = 0;
++  if (events & EPOLLIN)
++    flags |= DBUS_WATCH_READABLE;
++  if (events & EPOLLOUT)
++    flags |= DBUS_WATCH_WRITABLE;
++
++  /* remove the watch if needed */
++  watch = cynagora->cynagora_watch;
++  if (watch != NULL)
++    {
++      cynagora->cynagora_watch = NULL;
++      _dbus_loop_remove_watch(loop, watch);
++      _dbus_watch_invalidate(watch);
++      _dbus_watch_unref(watch);
++    }
++
++  /* create the watch if needed */
++  watch = cynagora->cynagora_watch;
++  if (op != EPOLL_CTL_DEL)
++    {
++      watch = _dbus_watch_new(fd, flags, TRUE, watch_handler_callback, cynagora, NULL);
++      if (watch == NULL)
++        return -ENOMEM;
++      if (_dbus_loop_add_watch(loop, watch) != TRUE)
++        {
++          _dbus_watch_invalidate(watch);
++          _dbus_watch_unref(watch);
++          return -ENOMEM;
++        }
++      cynagora->cynagora_watch = watch;
++    }
++  return 0;
++}
++
++#endif /* DBUS_ENABLE_CYNAGORA */
+diff --git a/bus/cynara.h b/bus/cynagora-check.h
+similarity index 81%
+rename from bus/cynara.h
+rename to bus/cynagora-check.h
+index c4728bb..c0892c3 100644
+--- a/bus/cynara.h
++++ b/bus/cynagora-check.h
+@@ -1,5 +1,5 @@
+ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+-/* cynara.h  Cynara runtime privilege checking
++/* cynagora.h  Cynagora runtime privilege checking
+  *
+  * Copyright (c) 2014 Samsung Electronics, Ltd.
+  *
+@@ -24,10 +24,10 @@
+ #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,
++BusCynagora *bus_cynagora_new             (BusCheck *check, DBusError *error);
++BusCynagora *bus_cynagora_ref             (BusCynagora *cynagora);
++void       bus_cynagora_unref           (BusCynagora *cynagora);
++BusResult  bus_cynagora_check_privilege (BusCynagora *cynagora,
+                                        DBusMessage *message,
+                                        DBusConnection *sender,
+                                        DBusConnection *addressed_recipient,
+diff --git a/bus/cynara.c b/bus/cynara.c
+deleted file mode 100644
+index 77aed62..0000000
+--- a/bus/cynara.c
++++ /dev/null
+@@ -1,373 +0,0 @@
+-/* -*- 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/system.conf.in b/bus/system.conf.in
+index 19d0c04..81c39c8 100644
+--- a/bus/system.conf.in
++++ b/bus/system.conf.in
+@@ -72,10 +72,10 @@
+            send_interface="org.freedesktop.DBus.Introspectable"/>
+     <allow send_destination="org.freedesktop.DBus"
+            send_interface="org.freedesktop.DBus.Properties"/>
+-    <!-- If there is a need specific bus services could be protected by Cynara as well.
++    <!-- If there is a need specific bus services could be protected by Cynagora 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).
++         Cynagora is not yet activated (systemd calls protected method synchronously,
++         dbus daemon tries to consult Cynagora, Cynagora 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 receive_sender="org.freedesktop.DBus"/>
+diff --git a/configure.ac b/configure.ac
+index 11b5ffd..df9341c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1742,16 +1742,16 @@ AC_ARG_ENABLE([user-session],
+ AM_CONDITIONAL([DBUS_ENABLE_USER_SESSION],
+   [test "x$enable_user_session" = xyes])
+ 
+-#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])])
++#enable cynagora integration
++AC_ARG_ENABLE([cynagora], [AS_HELP_STRING([--enable-cynagora], [enable Cynagora integration])], [], [enable_cynagora=no])
++if test "x$enable_cynagora" = xyes; then
++  PKG_CHECK_MODULES([CYNAGORA], [cynagora],
++     [AC_DEFINE([DBUS_ENABLE_CYNAGORA], [1], [Define to enable Cynagora privilege checks in dbus-daemon])],
++     [AC_MSG_ERROR([libcynagora is required to enable Cynagora integration])])
+ fi
+ 
+-AC_SUBST([CYNARA_CFLAGS])
+-AC_SUBST([CYNARA_LIBS])
++AC_SUBST([CYNAGORA_CFLAGS])
++AC_SUBST([CYNAGORA_LIBS])
+ 
+ AC_CONFIG_FILES([
+ Doxyfile
+@@ -1835,7 +1835,7 @@ echo "
+         Building bus stats API:   ${enable_stats}
+         Building SELinux support: ${have_selinux}
+         Building AppArmor support: ${have_apparmor}
+-        Building Cynara support:  ${enable_cynara}
++        Building Cynagora support: ${enable_cynagora}
+         Building inotify support: ${have_inotify}
+         Building kqueue support:  ${have_kqueue}
+         Building systemd support: ${have_systemd}
+-- 
+2.21.1
+
diff --git a/meta-security/recipes-core/dbus-cynagora/dbus_1.12.16.bbappend b/meta-security/recipes-core/dbus-cynagora/dbus_1.12.16.bbappend
new file mode 100644
index 000000000..177a117b8
--- /dev/null
+++ b/meta-security/recipes-core/dbus-cynagora/dbus_1.12.16.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/dbus-cynagora:"
+
+SRC_URI_append_class-target = "\
+   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 \
+   file://0006-Fix-SIGSEGV-on-disconnections.patch \
+   file://0007-Switch-from-cynara-to-cynagora.patch \
+"
+
+DEPENDS_append_class-target = " cynagora smack"
+EXTRA_OECONF_append_class-target = " ${@bb.utils.contains('DISTRO_FEATURES','smack','--enable-cynagora --disable-selinux','',d)}"
+
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Integration-of-Cynara-asynchronous-security-checks.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Integration-of-Cynara-asynchronous-security-checks.patch
deleted file mode 100644
index 69d13ac35..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0001-Integration-of-Cynara-asynchronous-security-checks.patch
+++ /dev/null
@@ -1,2232 +0,0 @@
-From 6c498a9b0f4122d1ac49d603f9968b6d85830cdb Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Thu, 27 Nov 2014 18:11:05 +0100
-Subject: Integration of Cynara asynchronous security checks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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.
-
-Cherry picked from 4dcfb02f17247ff9de966b62182cd2e08f301238
-by José Bollo.
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Change-Id: I9bcbce34577e5dc2a3cecf6233a0a2b0e43e1108
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-diff --git a/bus/Makefile.am b/bus/Makefile.am
-index 9ae3071..46afb31 100644
---- a/bus/Makefile.am
-+++ b/bus/Makefile.am
-@@ -13,6 +13,7 @@ DBUS_BUS_LIBS = \
- 	$(THREAD_LIBS) \
- 	$(ADT_LIBS) \
- 	$(NETWORK_libs) \
-+	$(CYNARA_LIBS) \
- 	$(NULL)
- 
- DBUS_LAUNCHER_LIBS = \
-@@ -30,6 +31,7 @@ AM_CPPFLAGS = \
- 	$(APPARMOR_CFLAGS) \
- 	-DDBUS_SYSTEM_CONFIG_FILE=\""$(dbusdatadir)/system.conf"\" \
- 	-DDBUS_COMPILATION \
-+	$(CYNARA_CFLAGS) \
- 	$(NULL)
- 
- # if assertions are enabled, improve backtraces
-@@ -90,6 +92,8 @@ BUS_SOURCES=					\
- 	audit.h					\
- 	bus.c					\
- 	bus.h					\
-+	check.c					\
-+	check.h					\
- 	config-loader-expat.c			\
- 	config-parser.c				\
- 	config-parser.h				\
-@@ -97,6 +101,8 @@ BUS_SOURCES=					\
- 	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/activation.c b/bus/activation.c
-index 6f009f5..f8a02eb 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -1788,14 +1788,15 @@ bus_activation_activate_service (BusActivation  *activation,
- 
-   if (auto_activation &&
-       entry != NULL &&
--      !bus_context_check_security_policy (activation->context,
-+      BUS_RESULT_TRUE != bus_context_check_security_policy (activation->context,
-         transaction,
-         connection, /* sender */
-         NULL, /* addressed recipient */
-         NULL, /* proposed recipient */
-         activation_message,
-         entry,
--        error))
-+        error,
-+        NULL))
-     {
-       _DBUS_ASSERT_ERROR_IS_SET (error);
-       _dbus_verbose ("activation not authorized: %s: %s\n",
-diff --git a/bus/bus.c b/bus/bus.c
-index 30ce4e1..237efe3 100644
---- a/bus/bus.c
-+++ b/bus/bus.c
-@@ -38,6 +38,7 @@
- #include "apparmor.h"
- #include "audit.h"
- #include "dir-watch.h"
-+#include "check.h"
- #include <dbus/dbus-auth.h>
- #include <dbus/dbus-list.h>
- #include <dbus/dbus-hash.h>
-@@ -67,6 +68,7 @@ struct BusContext
-   BusRegistry *registry;
-   BusPolicy *policy;
-   BusMatchmaker *matchmaker;
-+  BusCheck *check;
-   BusLimits limits;
-   DBusRLimit *initial_fd_limit;
-   unsigned int fork : 1;
-@@ -1003,6 +1005,10 @@ bus_context_new (const DBusString *config_file,
-       parser = NULL;
-     }
- 
-+  context->check = bus_check_new(context, error);
-+  if (context->check == NULL)
-+      goto failed;
-+
-   dbus_server_free_data_slot (&server_data_slot);
- 
-   return context;
-@@ -1127,6 +1133,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);
-@@ -1256,6 +1268,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)
-@@ -1451,6 +1469,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;
-@@ -1480,7 +1499,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)),
-@@ -1491,7 +1511,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 */
-@@ -1519,7 +1540,7 @@ 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
-+BusResult
- bus_context_check_security_policy (BusContext     *context,
-                                    BusTransaction *transaction,
-                                    DBusConnection *sender,
-@@ -1527,7 +1548,8 @@ bus_context_check_security_policy (BusContext     *context,
-                                    DBusConnection *proposed_recipient,
-                                    DBusMessage    *message,
-                                    BusActivationEntry *activation_entry,
--                                   DBusError      *error)
-+                                   DBusError      *error,
-+                                   BusDeferredMessage **deferred_message)
- {
-   const char *src, *dest;
-   BusClientPolicy *sender_policy;
-@@ -1536,6 +1558,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);
-   src = dbus_message_get_sender (message);
-@@ -1565,7 +1588,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;
-@@ -1595,7 +1618,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;
-                     }
-                 }
-             }
-@@ -1624,11 +1647,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;
-         }
- 
-       /* next verify AppArmor access controls.  If allowed then
-@@ -1646,7 +1669,7 @@ bus_context_check_security_policy (BusContext     *context,
-                                      src ? src : DBUS_SERVICE_DBUS,
-                                      activation_entry,
-                                      error))
--        return FALSE;
-+        return BUS_RESULT_FALSE;
- 
-       if (!bus_connection_is_active (sender))
-         {
-@@ -1660,7 +1683,7 @@ bus_context_check_security_policy (BusContext     *context,
-             {
-               _dbus_verbose ("security check allowing %s message\n",
-                              "Hello");
--              return TRUE;
-+              return BUS_RESULT_TRUE;
-             }
-           else
-             {
-@@ -1671,7 +1694,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;
-             }
-         }
-     }
-@@ -1720,20 +1743,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)
-     {
-@@ -1742,23 +1774,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 */
-@@ -1768,10 +1806,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
-@@ -1792,11 +1830,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 2e0de82..82c32c8 100644
---- a/bus/bus.h
-+++ b/bus/bus.h
-@@ -45,6 +45,22 @@ typedef struct BusTransaction   BusTransaction;
- typedef struct BusMatchmaker    BusMatchmaker;
- typedef struct BusMatchRule     BusMatchRule;
- typedef struct BusActivationEntry BusActivationEntry;
-+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
- {
-@@ -101,6 +117,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,
-@@ -136,14 +153,15 @@ void              bus_context_log_and_set_error                  (BusContext
-                                                                   const char       *name,
-                                                                   const char       *msg,
-                                                                   ...) _DBUS_GNUC_PRINTF (5, 6);
--dbus_bool_t       bus_context_check_security_policy              (BusContext       *context,
-+BusResult         bus_context_check_security_policy              (BusContext       *context,
-                                                                   BusTransaction   *transaction,
-                                                                   DBusConnection   *sender,
-                                                                   DBusConnection   *addressed_recipient,
-                                                                   DBusConnection   *proposed_recipient,
-                                                                   DBusMessage      *message,
-                                                                   BusActivationEntry *activation_entry,
--                                                                  DBusError        *error);
-+                                                                  DBusError        *error,
-+                                                                  BusDeferredMessage **deferred_message);
- void              bus_context_check_all_watches                  (BusContext       *context);
- 
- #endif /* BUS_BUS_H */
-diff --git a/bus/check.c b/bus/check.c
-new file mode 100644
-index 0000000..5b72d31
---- /dev/null
-+++ b/bus/check.c
-@@ -0,0 +1,217 @@
-+/* -*- 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;
-+#ifdef DBUS_ENABLE_CYNARA
-+  BusCynara *cynara;
-+#endif
-+  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 c1c4191..e2f253d 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;
-@@ -159,6 +163,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 382a014..9e026d1 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 be27d38..b5f1dd1 100644
---- a/bus/config-parser.c
-+++ b/bus/config-parser.c
-@@ -1318,7 +1318,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;
-@@ -1360,6 +1360,7 @@ append_rule_from_element (BusConfigParser   *parser,
-   const char *own_prefix;
-   const char *user;
-   const char *group;
-+  const char *privilege;
- 
-   BusPolicyRule *rule;
- 
-@@ -1390,6 +1391,7 @@ append_rule_from_element (BusConfigParser   *parser,
-                           "user", &user,
-                           "group", &group,
-                           "log", &log,
-+                          "privilege", &privilege,
-                           NULL))
-     return FALSE;
- 
-@@ -1422,6 +1424,7 @@ append_rule_from_element (BusConfigParser   *parser,
- 
-   if (!(any_send_attribute ||
-         any_receive_attribute ||
-+        privilege ||
-         own || own_prefix || user || group))
-     {
-       dbus_set_error (error, DBUS_ERROR_FAILED,
-@@ -1438,7 +1441,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:
-@@ -1589,7 +1615,7 @@ append_rule_from_element (BusConfigParser   *parser,
-                                 error))
-         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;
-       
-@@ -1694,7 +1720,7 @@ append_rule_from_element (BusConfigParser   *parser,
-                                 error))
-         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;
- 
-@@ -1726,7 +1752,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;
- 
-@@ -1752,7 +1778,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;
- 
-@@ -1767,7 +1793,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;
- 
-@@ -1784,7 +1810,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;
- 
-@@ -1799,7 +1825,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;
- 
-@@ -1823,6 +1849,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:
-@@ -1898,7 +1928,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)
-@@ -1913,7 +1943,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)
-@@ -1922,6 +1952,21 @@ start_policy_child (BusConfigParser   *parser,
-           return FALSE;
-         }
-       
-+      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
-@@ -2284,6 +2329,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:
-@@ -2600,6 +2646,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:
-@@ -3127,6 +3174,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 53605fa..b348d42 100644
---- a/bus/connection.c
-+++ b/bus/connection.c
-@@ -36,6 +36,10 @@
- #include <dbus/dbus-timeout.h>
- #include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-internals.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
-@@ -116,6 +120,9 @@ typedef struct
- 
-   /** non-NULL if and only if this is a monitor */
-   DBusList *link_in_monitors;
-+#ifdef DBUS_ENABLE_CYNARA
-+  char *cynara_session_id;
-+#endif
- } BusConnectionData;
- 
- static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
-@@ -129,8 +136,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;
- 
-@@ -354,7 +361,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
-@@ -363,7 +370,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
-@@ -372,7 +379,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
-@@ -381,7 +388,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
-@@ -390,7 +397,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
-@@ -448,6 +455,10 @@ free_connection_data (void *data)
-   
-   dbus_free (d->name);
-   
-+#ifdef DBUS_ENABLE_CYNARA
-+  free (d->cynara_session_id);
-+#endif
-+
-   dbus_free (d);
- }
- 
-@@ -1078,6 +1089,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,
-@@ -2333,6 +2360,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-                                   DBusMessage    *message)
- {
-   DBusError error = DBUS_ERROR_INIT;
-+  BusResult res;
- 
-   /* We have to set the sender to the driver, and have
-    * to check security policy since it was not done in
-@@ -2370,10 +2398,11 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-    * if we're actively capturing messages, it's nice to log that we
-    * tried to send it and did not allow ourselves to do so.
-    */
--  if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
--                                          transaction,
--                                          NULL, connection, connection,
--                                          message, NULL, &error))
-+  res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
-+                                           transaction,
-+                                           NULL, connection, connection, message, NULL,
-+                                           &error, NULL);
-+  if (res == BUS_RESULT_FALSE)
-     {
-       if (!bus_transaction_capture_error_reply (transaction, connection,
-                                                 &error, message))
-@@ -2388,6 +2417,12 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-       dbus_error_free (&error);
-       return TRUE;
-     }
-+  else if (res == BUS_RESULT_LATER)
-+    {
-+      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
-+      dbus_error_free (&error);
-+      return TRUE;
-+    }
- 
-   return bus_transaction_send (transaction, connection, message);
- }
-diff --git a/bus/connection.h b/bus/connection.h
-index 9e253ae..71078ea 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);
-@@ -124,6 +125,9 @@ dbus_bool_t bus_connection_be_monitor (DBusConnection  *connection,
-                                        BusTransaction  *transaction,
-                                        DBusList       **rules,
-                                        DBusError       *error);
-+#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 */
- 
-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 7000
-+#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 19228be..d3867f7 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"
-@@ -64,14 +65,18 @@ send_one_message (DBusConnection *connection,
-                   DBusError      *error)
- {
-   DBusError stack_error = DBUS_ERROR_INIT;
-+  BusDeferredMessage *deferred_message;
-+  BusResult result;
- 
--  if (!bus_context_check_security_policy (context, transaction,
-+  result = bus_context_check_security_policy (context, transaction,
-                                           sender,
-                                           addressed_recipient,
-                                           connection,
-                                           message,
-                                           NULL,
--                                          &stack_error))
-+                                          &stack_error,
-+                                          &deferred_message);
-+  if (result != BUS_RESULT_TRUE)
-     {
-       if (!bus_transaction_capture_error_reply (transaction, sender,
-                                                 &stack_error, message))
-@@ -130,6 +135,8 @@ bus_dispatch_matches (BusTransaction *transaction,
-   BusMatchmaker *matchmaker;
-   DBusList *link;
-   BusContext *context;
-+  BusDeferredMessage *deferred_message;
-+  BusResult res;
- 
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- 
-@@ -145,11 +152,20 @@ 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, NULL, error))
-+      res = bus_context_check_security_policy (context, transaction,
-+                                               sender, addressed_recipient,
-+                                               addressed_recipient,
-+                                               message, NULL, 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,
-@@ -374,19 +390,31 @@ bus_dispatch (DBusConnection *connection,
-   if (service_name &&
-       strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
-     {
-+      BusDeferredMessage *deferred_message;
-+      BusResult res;
-+
-       if (!bus_transaction_capture (transaction, connection, NULL, message))
-         {
-           BUS_SET_OOM (&error);
-           goto out;
-         }
- 
--      if (!bus_context_check_security_policy (context, transaction,
--                                              connection, NULL, NULL, message,
--                                              NULL, &error))
-+      res = bus_context_check_security_policy (context, transaction,
-+                                               connection, NULL, NULL, message, NULL,
-+                                               &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 a37be80..7ee1ce5 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"
-@@ -33,7 +34,7 @@
- 
- BusPolicyRule*
- bus_policy_rule_new (BusPolicyRuleType type,
--                     dbus_bool_t       allow)
-+                     BusPolicyRuleAccess access)
- {
-   BusPolicyRule *rule;
- 
-@@ -43,7 +44,7 @@ bus_policy_rule_new (BusPolicyRuleType type,
- 
-   rule->type = type;
-   rule->refcount = 1;
--  rule->allow = allow;
-+  rule->access = access;
- 
-   switch (rule->type)
-     {
-@@ -55,18 +56,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;
-@@ -122,7 +124,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
-         default:
-           _dbus_assert_not_reached ("invalid rule");
-         }
--      
-+
-+      dbus_free (rule->privilege);
-       dbus_free (rule);
-     }
- }
-@@ -435,7 +438,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;
-@@ -873,18 +879,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
-    */
-@@ -892,7 +903,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)
-     {
-@@ -923,13 +934,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;
-             }
- 
-@@ -937,7 +949,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;
-@@ -960,13 +972,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))
-@@ -1079,33 +1093,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",
-+                     (int)(intptr_t)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 &&
-@@ -1118,7 +1162,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)
-     {
-@@ -1141,19 +1185,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;
-@@ -1162,13 +1208,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;
-             }
- 
-@@ -1176,7 +1223,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;
-@@ -1199,13 +1246,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))
-@@ -1295,14 +1342,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",
-+                     (int)(intptr_t)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;
- }
- 
- 
-@@ -1354,7 +1429,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 ec43ffa..f839d23 100644
---- a/bus/policy.h
-+++ b/bus/policy.h
-@@ -46,6 +46,14 @@ typedef enum
-   BUS_POLICY_TRISTATE_TRUE
- } BusPolicyTristate;
- 
-+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))
-@@ -56,8 +64,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
-@@ -118,7 +127,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);
- 
-@@ -152,21 +161,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,
-+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);
--dbus_bool_t      bus_client_policy_check_can_receive (BusClientPolicy  *policy,
-+                                                      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);
-+                                                      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 81028ba..f21d1b2 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1770,6 +1770,17 @@ AC_ARG_ENABLE([user-session],
- AM_CONDITIONAL([DBUS_ENABLE_USER_SESSION],
-   [test "x$enable_user_session" = xyes])
- 
-+#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/Version
-@@ -1852,6 +1863,7 @@ echo "
-         Building bus stats API:   ${enable_stats}
-         Building SELinux support: ${have_selinux}
-         Building AppArmor support: ${have_apparmor}
-+        Building Cynara support:  ${enable_cynara}
-         Building inotify support: ${have_inotify}
-         Building kqueue support:  ${have_kqueue}
-         Building systemd support: ${have_systemd}
-diff --git a/test/Makefile.am b/test/Makefile.am
-index 6a6e1a3..ce84dbc 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -439,6 +439,7 @@ in_data = \
- 	data/valid-config-files/debug-allow-all.conf.in \
- 	data/valid-config-files/finite-timeout.conf.in \
- 	data/valid-config-files/forbidding.conf.in \
-+	data/valid-config-files/debug-check-some.conf.in \
- 	data/valid-config-files/incoming-limit.conf.in \
- 	data/valid-config-files/max-completed-connections.conf.in \
- 	data/valid-config-files/max-connections-per-user.conf.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.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-Disable-message-dispatching-when-send-rule-result-is.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-Disable-message-dispatching-when-send-rule-result-is.patch
deleted file mode 100644
index ebbd531ff..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0002-Disable-message-dispatching-when-send-rule-result-is.patch
+++ /dev/null
@@ -1,949 +0,0 @@
-From aae977a0c4bb1c25640c7056166fbc4e76ef1db6 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Fri, 28 Nov 2014 12:07:39 +0100
-Subject: Disable message dispatching when send rule result is not known
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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.
-
-Cherry-picked from b1b87ad9f20b2052c28431b48e81073078a745ce
-by Jose Bollo.
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-diff --git a/bus/activation.c b/bus/activation.c
-index f8a02eb..005047f 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -32,6 +32,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>
-@@ -94,6 +95,8 @@ struct BusPendingActivationEntry
-   DBusConnection *connection;
- 
-   dbus_bool_t auto_activation;
-+
-+  dbus_bool_t is_put_back;
- };
- 
- typedef struct
-@@ -1241,20 +1244,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
-@@ -1266,9 +1272,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);
-+                }
-             }
-         }
- 
-@@ -1286,6 +1323,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;
- }
- 
-@@ -2078,6 +2128,7 @@ 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' requested by '%s' (%s)",
-                                service_name,
-@@ -2085,8 +2136,17 @@ bus_activation_activate_service (BusActivation  *activation,
-                                bus_connection_get_name (connection),
-                                bus_connection_get_loginfo (connection));
-               /* Wonderful, systemd is connected, let's just send the msg */
--              retval = bus_dispatch_matches (activation_transaction, NULL,
-+              res = bus_dispatch_matches (activation_transaction, NULL,
-                                              systemd, message, error);
-+
-+              if (res == BUS_RESULT_TRUE)
-+                retval = TRUE;
-+              else
-+                {
-+                  retval = FALSE;
-+                  if (res == BUS_RESULT_LATER)
-+                    _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
-+                }
-             }
-           else
-             {
-diff --git a/bus/check.c b/bus/check.c
-index 5b72d31..4b8a699 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
-+BusResult (*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;
- #ifdef DBUS_ENABLE_CYNARA
-   BusCynara *cynara;
-@@ -137,16 +188,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;
- }
-@@ -206,6 +295,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..d177549 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 BusResult (*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 d3867f7..50a22a3 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -35,6 +35,7 @@
- #include "signals.h"
- #include "test.h"
- #include <dbus/dbus-internals.h>
-+#include <dbus/dbus-connection-internal.h>
- #include <dbus/dbus-misc.h>
- #include <string.h>
- 
-@@ -122,7 +123,7 @@ send_one_message (DBusConnection *connection,
-   return TRUE;
- }
- 
--dbus_bool_t
-+BusResult
- bus_dispatch_matches (BusTransaction *transaction,
-                       DBusConnection *sender,
-                       DBusConnection *addressed_recipient,
-@@ -158,13 +159,29 @@ bus_dispatch_matches (BusTransaction *transaction,
-                                                message, NULL, 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) &&
-@@ -175,14 +192,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;
-         }
-     }
- 
-@@ -197,7 +214,7 @@ bus_dispatch_matches (BusTransaction *transaction,
-                                       &recipients))
-     {
-       BUS_SET_OOM (error);
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
- 
-   link = _dbus_list_get_first_link (&recipients);
-@@ -219,10 +236,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
-@@ -409,10 +426,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;
-         }
- 
-@@ -514,8 +533,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))
-@@ -5060,9 +5085,132 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
- }
- #endif
- 
-+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 BusResult
-+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 (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 cd0a714..f414f64 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -218,6 +218,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);
-@@ -253,7 +254,16 @@ bus_driver_send_service_owner_changed (const char     *service_name,
-   if (!bus_transaction_capture (transaction, NULL, NULL, message))
-     goto oom;
- 
--  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
-+    {
-+      retval = FALSE;
-+      if (res == BUS_RESULT_LATER)
-+        /* should never happen */
-+        _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
-+    }
-   dbus_message_unref (message);
- 
-   return retval;
-diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
-index 4835732..94b1c95 100644
---- a/dbus/dbus-connection-internal.h
-+++ b/dbus/dbus-connection-internal.h
-@@ -118,6 +118,21 @@ DBUS_PRIVATE_EXPORT
- dbus_bool_t       _dbus_connection_get_linux_security_label       (DBusConnection  *connection,
-                                                                    char           **label_p);
- 
-+DBUS_PRIVATE_EXPORT
-+void              _dbus_connection_enable_dispatch                (DBusConnection *connection);
-+DBUS_PRIVATE_EXPORT
-+void              _dbus_connection_disable_dispatch               (DBusConnection *connection);
-+
-+DBUS_PRIVATE_EXPORT
-+dbus_bool_t       _dbus_connection_putback_message                (DBusConnection *connection,
-+                                                                   DBusMessage    *after_message,
-+                                                                   DBusMessage    *message,
-+                                                                   DBusError      *error);
-+
-+DBUS_PRIVATE_EXPORT
-+dbus_bool_t       _dbus_connection_remove_message                 (DBusConnection *connection,
-+                                                                   DBusMessage    *message);
-+
- /* if DBUS_ENABLE_STATS */
- DBUS_PRIVATE_EXPORT
- void _dbus_connection_get_stats (DBusConnection *connection,
-diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
-index c525b6d..958968c 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
-@@ -4069,6 +4103,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
-@@ -4252,8 +4362,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_unlocked(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;
-@@ -4716,6 +4827,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");
-@@ -4838,9 +4951,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 8e713c0..32ea871 100644
---- a/dbus/dbus-list.c
-+++ b/dbus/dbus-list.c
-@@ -458,6 +458,35 @@ _dbus_list_remove_last (DBusList **list,
-     return FALSE;
- }
- 
-+/**
-+ * 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.
-diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h
-index 9350a0d..fee9f1b 100644
---- a/dbus/dbus-list.h
-+++ b/dbus/dbus-list.h
-@@ -68,6 +68,9 @@ DBUS_PRIVATE_EXPORT
- void        _dbus_list_remove_link        (DBusList **list,
-                                            DBusList  *link);
- DBUS_PRIVATE_EXPORT
-+DBusList*   _dbus_list_find_first         (DBusList **list,
-+                                           void      *data);
-+DBUS_PRIVATE_EXPORT
- DBusList*   _dbus_list_find_last          (DBusList **list,
-                                            void      *data);
- DBUS_PRIVATE_EXPORT
-diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h
-index 7ab9103..e5bfbed 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.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Handle-unavailability-of-policy-results-for-broadcas.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
deleted file mode 100644
index 1c2ab2bcb..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0003-Handle-unavailability-of-policy-results-for-broadcas.patch
+++ /dev/null
@@ -1,1082 +0,0 @@
-From fdc3d7086c8f7a623e3da80e559708545b9201fc Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Fri, 28 Nov 2014 12:39:33 +0100
-Subject: Handle unavailability of policy results for broadcasts and receive
- rules
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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.
-
-Cherry picked from 1e231194610892dd4360224998d91336097b05a1 by Jose Bollo
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-diff --git a/bus/activation.c b/bus/activation.c
-index 005047f..ffdc6fc 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -1259,7 +1259,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
-@@ -2137,7 +2137,7 @@ bus_activation_activate_service (BusActivation  *activation,
-                                bus_connection_get_loginfo (connection));
-               /* Wonderful, systemd is connected, let's just send the msg */
-               res = bus_dispatch_matches (activation_transaction, NULL,
--                                             systemd, message, error);
-+                                             systemd, message, NULL, error);
- 
-               if (res == BUS_RESULT_TRUE)
-                 retval = TRUE;
-diff --git a/bus/bus.c b/bus/bus.c
-index 237efe3..5bb5637 100644
---- a/bus/bus.c
-+++ b/bus/bus.c
-@@ -1800,17 +1800,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
-@@ -1869,3 +1861,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 82c32c8..1b08f7c 100644
---- a/bus/bus.h
-+++ b/bus/bus.h
-@@ -164,4 +164,23 @@ BusResult         bus_context_check_security_policy              (BusContext
-                                                                   BusDeferredMessage **deferred_message);
- void              bus_context_check_all_watches                  (BusContext       *context);
- 
-+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 4b8a699..f3d283f 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;
-@@ -135,6 +138,89 @@ bus_check_enable_dispatch_callback (BusDeferredMessage *deferred_message,
-   _dbus_connection_enable_dispatch(deferred_message->sender);
- }
- 
-+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)
- {
-@@ -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
- BusResult (*bus_check_test_override) (DBusConnection *connection,
-                                         const char *privilege);
-@@ -259,6 +359,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;
-@@ -295,12 +398,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, 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)
-@@ -310,3 +616,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 d177549..9c13c18 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 BusResult (*bus_check_test_override) (DBusConnection *connection,
-                                                const char *privilege);
-diff --git a/bus/connection.c b/bus/connection.c
-index b348d42..ee93384 100644
---- a/bus/connection.c
-+++ b/bus/connection.c
-@@ -31,11 +31,13 @@
- #include "expirelist.h"
- #include "selinux.h"
- #include "apparmor.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-internals.h>
-+#include <dbus/dbus-message-internal.h>
- #ifdef DBUS_ENABLE_CYNARA
- #include <stdlib.h>
- #include <cynara-session.h>
-@@ -102,6 +104,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;
-@@ -268,6 +271,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 */
-@@ -2307,7 +2312,7 @@ bus_transaction_capture (BusTransaction *transaction,
-     {
-       DBusConnection *recipient = link->data;
- 
--      if (!bus_transaction_send (transaction, recipient, message))
-+      if (!bus_transaction_send (transaction, recipient, message, FALSE))
-         goto out;
-     }
- 
-@@ -2361,6 +2366,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
- {
-   DBusError error = DBUS_ERROR_INIT;
-   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
-@@ -2401,7 +2407,7 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-   res = bus_context_check_security_policy (bus_transaction_get_context (transaction),
-                                            transaction,
-                                            NULL, connection, connection, message, NULL,
--                                           &error, NULL);
-+                                           &error, &deferred_message);
-   if (res == BUS_RESULT_FALSE)
-     {
-       if (!bus_transaction_capture_error_reply (transaction, connection,
-@@ -2419,18 +2425,20 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
-     }
-   else if (res == BUS_RESULT_LATER)
-     {
--      _dbus_verbose ("Cannot delay sending message from bus driver, dropping it\n");
-       dbus_error_free (&error);
--      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;
-@@ -2456,7 +2464,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)
-     {
-@@ -2708,6 +2737,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 71078ea..97dae96 100644
---- a/bus/connection.h
-+++ b/bus/connection.h
-@@ -85,6 +85,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);
-@@ -137,7 +153,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_capture          (BusTransaction               *transaction,
-                                                   DBusConnection               *connection,
-                                                   DBusConnection               *addressed_recipient,
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index 50a22a3..7d30ce4 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -33,6 +33,7 @@
- #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>
-@@ -77,7 +78,7 @@ send_one_message (DBusConnection *connection,
-                                           NULL,
-                                           &stack_error,
-                                           &deferred_message);
--  if (result != BUS_RESULT_TRUE)
-+  if (result == BUS_RESULT_FALSE)
-     {
-       if (!bus_transaction_capture_error_reply (transaction, sender,
-                                                 &stack_error, message))
-@@ -112,9 +113,19 @@ send_one_message (DBusConnection *connection,
-       return TRUE; /* don't send it but don't return an error either */
-     }
- 
-+  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;
-@@ -124,11 +135,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;
-@@ -137,7 +149,6 @@ bus_dispatch_matches (BusTransaction *transaction,
-   DBusList *link;
-   BusContext *context;
-   BusDeferredMessage *deferred_message;
--  BusResult res;
- 
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- 
-@@ -153,16 +164,80 @@ bus_dispatch_matches (BusTransaction *transaction,
-   /* First, send the message to the addressed_recipient, if there is one. */
-   if (addressed_recipient != NULL)
-     {
--      res = bus_context_check_security_policy (context, transaction,
-+      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, NULL, error,
-                                                &deferred_message);
--      if (res == BUS_RESULT_FALSE)
-+
-+      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)
-@@ -173,13 +248,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;
-             }
-         }
-@@ -196,7 +276,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;
-@@ -534,7 +615,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 f414f64..d89a658 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -254,7 +254,7 @@ bus_driver_send_service_owner_changed (const char     *service_name,
-   if (!bus_transaction_capture (transaction, NULL, NULL, message))
-     goto oom;
- 
--  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
-diff --git a/bus/policy.c b/bus/policy.c
-index 7ee1ce5..b1fab0d 100644
---- a/bus/policy.c
-+++ b/bus/policy.c
-@@ -1121,6 +1121,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;
-@@ -1370,6 +1373,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.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Add-own-rule-result-unavailability-handling.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Add-own-rule-result-unavailability-handling.patch
deleted file mode 100644
index 9cb744def..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0004-Add-own-rule-result-unavailability-handling.patch
+++ /dev/null
@@ -1,1493 +0,0 @@
-From e7ae85429aa3e6d80df13b3a5a492d9ccbf42518 Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Thu, 27 Nov 2014 11:26:21 +0100
-Subject: Add own rule result unavailability handling
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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.
-
-Cherry-picked from 35ef89cd6777ea2430077fc621d21bd01df92349 by Jose.bollo
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-diff --git a/bus/dispatch.c b/bus/dispatch.c
-index 7d30ce4..4b84c21 100644
---- a/bus/dispatch.c
-+++ b/bus/dispatch.c
-@@ -517,8 +517,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 d89a658..aaeb3b2 100644
---- a/bus/driver.c
-+++ b/bus/driver.c
-@@ -420,7 +420,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,
-@@ -428,7 +428,7 @@ bus_driver_handle_hello (DBusConnection *connection,
- {
-   DBusString unique_name;
-   BusService *service;
--  dbus_bool_t retval;
-+  BusResult retval;
-   BusRegistry *registry;
-   BusConnections *connections;
-   DBusError tmp_error;
-@@ -442,7 +442,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
-@@ -464,16 +464,16 @@ bus_driver_handle_hello (DBusConnection *connection,
-       bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s (%s=%d)",
-           tmp_error.message, limit_name, limit);
-       dbus_move_error (&tmp_error, 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);
- 
-@@ -506,7 +506,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);
-@@ -558,7 +558,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,
-@@ -580,14 +580,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);
-@@ -599,7 +599,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;
-     }
- 
-   {
-@@ -611,7 +611,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;
-       }
-   }
- 
-@@ -624,7 +624,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;
-     }
-@@ -635,23 +635,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,
-@@ -673,14 +673,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);
-@@ -692,7 +692,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;
-     }
- 
-   {
-@@ -704,7 +704,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;
-       }
-   }
- 
-@@ -717,7 +717,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;
-     }
-@@ -728,23 +728,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,
-@@ -755,7 +755,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);
-@@ -766,20 +767,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)
-@@ -800,7 +805,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
-       goto out;
-     }
- 
--  retval = TRUE;
-+  retval = BUS_RESULT_TRUE;
- 
-  out:
-   if (reply)
-@@ -808,7 +813,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,
-@@ -818,7 +823,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);
-@@ -828,11 +833,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);
-@@ -861,7 +866,7 @@ bus_driver_handle_release_service (DBusConnection *connection,
-       goto out;
-     }
- 
--  retval = TRUE;
-+  retval = BUS_RESULT_TRUE;
- 
-  out:
-   if (reply)
-@@ -869,7 +874,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,
-@@ -880,7 +885,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);
-@@ -890,9 +895,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)
-     {
-@@ -926,7 +931,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
-       goto out;
-     }
- 
--  retval = TRUE;
-+  retval = BUS_RESULT_TRUE;
- 
-  out:
-   if (reply)
-@@ -935,7 +940,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,
-@@ -943,7 +948,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);
-@@ -957,10 +962,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))
-@@ -970,7 +975,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
-       goto out;
-     }
- 
--  retval = TRUE;
-+  retval = BUS_RESULT_TRUE;
- 
-  out:
-   return retval;
-@@ -1072,13 +1077,13 @@ bus_driver_send_or_activate (BusTransaction *transaction,
-   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;
-   BusContext *context;
-   DBusMessageIter iter;
-@@ -1100,7 +1105,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
-       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-                       "Cannot change activation environment "
-                       "on a system bus.");
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
- 
-   activation = bus_connection_get_activation (connection);
-@@ -1114,7 +1119,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
- 
-   dbus_message_iter_recurse (&iter, &dict_iter);
- 
--  retval = FALSE;
-+  retval = BUS_RESULT_FALSE;
-   systemd_message = NULL;
- 
-   /* Then loop through the sent dictionary, add the location of
-@@ -1279,7 +1284,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
-   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
-     goto out;
- 
--  retval = TRUE;
-+  retval = BUS_RESULT_TRUE;
- 
-  out:
-   if (systemd_message != NULL)
-@@ -1289,7 +1294,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,
-@@ -1371,16 +1376,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,
-@@ -1423,16 +1428,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,
-@@ -1502,7 +1507,7 @@ bus_driver_handle_get_service_owner (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_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,
-@@ -1606,7 +1611,7 @@ bus_driver_handle_list_queued_owners (DBusConnection *connection,
- 
-   dbus_message_unref (reply);
- 
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
-  oom:
-   BUS_SET_OOM (error);
-@@ -1619,10 +1624,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,
-@@ -1679,7 +1684,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);
-@@ -1688,10 +1693,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,
-@@ -1748,7 +1753,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);
-@@ -1757,10 +1762,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,
-@@ -1811,7 +1816,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);
-@@ -1820,10 +1825,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,
-@@ -1872,7 +1877,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);
-@@ -1881,10 +1886,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,
-@@ -1998,7 +2003,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
- 
-   dbus_message_unref (reply);
- 
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
-  oom:
-   BUS_SET_OOM (error);
-@@ -2012,10 +2017,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,
-@@ -2040,7 +2045,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);
-@@ -2049,11 +2054,11 @@ 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;
- }
- 
- #ifdef DBUS_ENABLE_VERBOSE_MODE
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_enable_verbose (DBusConnection *connection,
-                                   BusTransaction *transaction,
-                                   DBusMessage    *message,
-@@ -2073,7 +2078,7 @@ bus_driver_handle_enable_verbose (DBusConnection *connection,
-     _dbus_set_verbose(TRUE);
- 
-     dbus_message_unref (reply);
--    return TRUE;
-+    return BUS_RESULT_TRUE;
- 
-    oom:
-     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -2082,10 +2087,10 @@ bus_driver_handle_enable_verbose (DBusConnection *connection,
- 
-     if (reply)
-       dbus_message_unref (reply);
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_disable_verbose (DBusConnection *connection,
-                                    BusTransaction *transaction,
-                                    DBusMessage    *message,
-@@ -2105,7 +2110,7 @@ bus_driver_handle_disable_verbose (DBusConnection *connection,
-     _dbus_set_verbose(FALSE);
- 
-     dbus_message_unref (reply);
--    return TRUE;
-+    return BUS_RESULT_TRUE;
- 
-    oom:
-     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -2114,11 +2119,11 @@ bus_driver_handle_disable_verbose (DBusConnection *connection,
- 
-     if (reply)
-       dbus_message_unref (reply);
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- }
- #endif
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_get_id (DBusConnection *connection,
-                           BusTransaction *transaction,
-                           DBusMessage    *message,
-@@ -2134,7 +2139,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;
-@@ -2160,7 +2165,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);
-@@ -2170,10 +2175,10 @@ bus_driver_handle_get_id (DBusConnection *connection,
-   if (reply)
-     dbus_message_unref (reply);
-   _dbus_string_free (&uuid);
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_become_monitor (DBusConnection *connection,
-                                   BusTransaction *transaction,
-                                   DBusMessage    *message,
-@@ -2189,7 +2194,7 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
-   int i;
-   int n_match_rules;
-   dbus_uint32_t flags;
--  dbus_bool_t ret = FALSE;
-+  BusResult ret = BUS_RESULT_FALSE;
- 
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- 
-@@ -2262,10 +2267,10 @@ bus_driver_handle_become_monitor (DBusConnection *connection,
-   if (!bus_connection_be_monitor (connection, transaction, &rules, error))
-     goto out;
- 
--  ret = TRUE;
-+  ret = BUS_RESULT_TRUE;
- 
- out:
--  if (ret)
-+  if (ret == BUS_RESULT_TRUE)
-     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-   else
-     _DBUS_ASSERT_ERROR_IS_SET (error);
-@@ -2281,7 +2286,7 @@ out:
-   return ret;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_get_machine_id (DBusConnection *connection,
-                                   BusTransaction *transaction,
-                                   DBusMessage *message,
-@@ -2296,7 +2301,7 @@ bus_driver_handle_get_machine_id (DBusConnection *connection,
-   if (!_dbus_string_init (&uuid))
-     {
-       BUS_SET_OOM (error);
--      return FALSE;
-+      return BUS_RESULT_FALSE;
-     }
- 
-   if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
-@@ -2321,7 +2326,7 @@ bus_driver_handle_get_machine_id (DBusConnection *connection,
- 
-   _dbus_string_free (&uuid);
-   dbus_message_unref (reply);
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
- oom:
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-@@ -2335,29 +2340,30 @@ fail:
-     dbus_message_unref (reply);
- 
-   _dbus_string_free (&uuid);
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_ping (DBusConnection *connection,
-                         BusTransaction *transaction,
-                         DBusMessage *message,
-                         DBusError *error)
- {
--  return bus_driver_send_ack_reply (connection, transaction, message, error);
-+  return bus_driver_send_ack_reply (connection, transaction, message, error) == TRUE
-+               ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
- }
- 
--static dbus_bool_t bus_driver_handle_get (DBusConnection *connection,
-+static BusResult bus_driver_handle_get (DBusConnection *connection,
-                                           BusTransaction *transaction,
-                                           DBusMessage *message,
-                                           DBusError *error);
- 
--static dbus_bool_t bus_driver_handle_get_all (DBusConnection *connection,
-+static BusResult bus_driver_handle_get_all (DBusConnection *connection,
-                                               BusTransaction *transaction,
-                                               DBusMessage *message,
-                                               DBusError *error);
- 
--static dbus_bool_t bus_driver_handle_set (DBusConnection *connection,
-+static BusResult bus_driver_handle_set (DBusConnection *connection,
-                                           BusTransaction *transaction,
-                                           DBusMessage *message,
-                                           DBusError *error);
-@@ -2389,10 +2395,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);
-   MethodFlags flags;
- } MessageHandler;
- 
-@@ -2511,7 +2517,7 @@ static const PropertyHandler dbus_property_handlers[] = {
-   { 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 properties_message_handlers[] = {
-@@ -2763,7 +2769,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,
-@@ -2784,13 +2790,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;
-     }
- 
-   is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
-@@ -2815,7 +2821,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);
-@@ -2825,10 +2831,42 @@ bus_driver_handle_introspect (DBusConnection *connection,
- 
-   _dbus_string_free (&xml);
- 
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
-+/*
-+ * Set @error and return FALSE if the message is not directed to the
-+ * dbus-daemon by its canonical object path. This is hardening against
-+ * system services with poorly-written security policy files, which
-+ * might allow sending dangerously broad equivalence classes of messages
-+ * such as "anything with this assumed-to-be-safe object path".
-+ *
-+ * dbus-daemon is unusual in that it normally ignores the object path
-+ * of incoming messages; we need to keep that behaviour for the "read"
-+ * read-only method calls like GetConnectionUnixUser for backwards
-+ * compatibility, but it seems safer to be more restrictive for things
-+ * intended to be root-only or privileged-developers-only.
-+ *
-+ * It is possible that there are other system services with the same
-+ * quirk as dbus-daemon.
-+ */
- dbus_bool_t
-+bus_driver_check_message_is_for_us (DBusMessage *message,
-+                                    DBusError   *error)
-+{
-+  if (!dbus_message_has_path (message, DBUS_PATH_DBUS))
-+    {
-+      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-+          "Method '%s' is only available at the canonical object path '%s'",
-+          dbus_message_get_member (message), DBUS_PATH_DBUS);
-+
-+      return FALSE;
-+    }
-+
-+  return TRUE;
-+}
-+
-+BusResult
- bus_driver_handle_message (DBusConnection *connection,
-                            BusTransaction *transaction,
- 			   DBusMessage    *message,
-@@ -2839,6 +2877,7 @@ bus_driver_handle_message (DBusConnection *connection,
-   const MessageHandler *mh;
-   dbus_bool_t found_interface = FALSE;
-   dbus_bool_t is_canonical_path;
-+  BusResult res;
- 
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- 
-@@ -2854,7 +2893,7 @@ bus_driver_handle_message (DBusConnection *connection,
-                                                   transaction,
-                                                   message,
-                                                   error))
--        return FALSE;
-+        return BUS_RESULT_FALSE;
- 
-       context = bus_connection_get_context (connection);
-       systemd = bus_driver_get_owner_of_name (connection,
-@@ -2871,7 +2910,7 @@ bus_driver_handle_message (DBusConnection *connection,
-                            attacker ? attacker : "(unauthenticated)",
-                            bus_connection_get_loginfo (connection));
-           /* ignore it */
--          return TRUE;
-+          return BUS_RESULT_TRUE;
-         }
- 
-       if (!bus_context_get_systemd_activation (context))
-@@ -2879,16 +2918,16 @@ bus_driver_handle_message (DBusConnection *connection,
-           bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
-                            "Ignoring unexpected ActivationFailure message "
-                            "while not using systemd activation");
--          return FALSE;
-+          return BUS_RESULT_FALSE;
-         }
- 
--      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" */
-@@ -2953,20 +2992,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;
-             }
-         }
-     }
-@@ -2978,7 +3024,7 @@ bus_driver_handle_message (DBusConnection *connection,
-                   "%s does not understand message %s",
-                   DBUS_SERVICE_DBUS, name);
- 
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
- void
-@@ -3099,7 +3145,7 @@ interface_handler_find_property (const InterfaceHandler *ih,
-   return NULL;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_get (DBusConnection *connection,
-                        BusTransaction *transaction,
-                        DBusMessage    *message,
-@@ -3120,18 +3166,18 @@ bus_driver_handle_get (DBusConnection *connection,
-                               DBUS_TYPE_STRING, &iface,
-                               DBUS_TYPE_STRING, &prop,
-                               DBUS_TYPE_INVALID))
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   /* We only implement Properties on /org/freedesktop/DBus so far. */
-   ih = bus_driver_find_interface (iface, TRUE, error);
- 
-   if (ih == NULL)
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   handler = interface_handler_find_property (ih, prop, error);
- 
-   if (handler == NULL)
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   context = bus_transaction_get_context (transaction);
- 
-@@ -3159,17 +3205,17 @@ bus_driver_handle_get (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;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_get_all (DBusConnection *connection,
-                            BusTransaction *transaction,
-                            DBusMessage    *message,
-@@ -3188,13 +3234,13 @@ bus_driver_handle_get_all (DBusConnection *connection,
-   if (!dbus_message_get_args (message, error,
-                               DBUS_TYPE_STRING, &iface,
-                               DBUS_TYPE_INVALID))
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   /* We only implement Properties on /org/freedesktop/DBus so far. */
-   ih = bus_driver_find_interface (iface, TRUE, error);
- 
-   if (ih == NULL)
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   context = bus_transaction_get_context (transaction);
- 
-@@ -3229,7 +3275,7 @@ bus_driver_handle_get_all (DBusConnection *connection,
-     goto oom;
- 
-   dbus_message_unref (reply);
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
- oom_abandon_message:
-   _dbus_asv_abandon (&reply_iter, &array_iter);
-@@ -3239,10 +3285,10 @@ oom:
-     dbus_message_unref (reply);
- 
-   BUS_SET_OOM (error);
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
--static dbus_bool_t
-+static BusResult
- bus_driver_handle_set (DBusConnection *connection,
-                        BusTransaction *transaction,
-                        DBusMessage    *message,
-@@ -3271,15 +3317,15 @@ bus_driver_handle_set (DBusConnection *connection,
-   ih = bus_driver_find_interface (iface, TRUE, error);
- 
-   if (ih == NULL)
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   handler = interface_handler_find_property (ih, prop, error);
- 
-   if (handler == NULL)
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   /* We don't implement any properties that can be set yet. */
-   dbus_set_error (error, DBUS_ERROR_PROPERTY_READ_ONLY,
-                   "Property '%s.%s' cannot be set", iface, prop);
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
-diff --git a/bus/driver.h b/bus/driver.h
-index ac1289d..183c28b 100644
---- a/bus/driver.h
-+++ b/bus/driver.h
-@@ -35,7 +35,7 @@ typedef enum
- } BusDriverFound;
- 
- 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 b1fab0d..27b66d1 100644
---- a/bus/policy.c
-+++ b/bus/policy.c
-@@ -1388,18 +1388,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)
-     {
-@@ -1435,17 +1438,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
-@@ -1453,7 +1484,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) == BUS_RESULT_TRUE;
- }
- #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
- 
-diff --git a/bus/policy.h b/bus/policy.h
-index f839d23..28ce8f2 100644
---- a/bus/policy.h
-+++ b/bus/policy.h
-@@ -182,8 +182,10 @@ BusResult        bus_client_policy_check_can_receive (BusClientPolicy  *policy,
-                                                       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 127edda..586af18 100644
---- a/bus/services.c
-+++ b/bus/services.c
-@@ -376,16 +376,17 @@ 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;
-@@ -393,8 +394,9 @@ bus_registry_acquire_service (BusRegistry      *registry,
-   BusSELinuxID *sid;
-   BusOwner *primary_owner;
-   int limit;
-+  BusResult res;
- 
--  retval = FALSE;
-+  retval = BUS_RESULT_FALSE;
- 
-   if (!_dbus_validate_bus_name (service_name, 0,
-                                 _dbus_string_get_length (service_name)))
-@@ -467,7 +469,8 @@ bus_registry_acquire_service (BusRegistry      *registry,
-                                             _dbus_string_get_const_data (service_name), error))
-     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 "
-@@ -478,6 +481,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;
-+    }
- 
-   limit = bus_context_get_max_services_per_connection (registry->context);
- 
-@@ -603,11 +611,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 1582255..c25be98 100644
---- a/bus/stats.c
-+++ b/bus/stats.c
-@@ -36,7 +36,7 @@
- 
- #ifdef DBUS_ENABLE_STATS
- 
--dbus_bool_t
-+BusResult
- bus_stats_handle_get_stats (DBusConnection *connection,
-                             BusTransaction *transaction,
-                             DBusMessage    *message,
-@@ -51,6 +51,9 @@ bus_stats_handle_get_stats (DBusConnection *connection,
- 
-   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- 
-+  if (!bus_driver_check_message_is_for_us (message, error))
-+    return BUS_RESULT_FALSE;
-+
-   context = bus_transaction_get_context (transaction);
-   connections = bus_context_get_connections (context);
- 
-@@ -104,17 +107,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,
-@@ -209,7 +212,7 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
-     goto oom;
- 
-   dbus_message_unref (reply);
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
- oom:
-   BUS_SET_OOM (error);
-@@ -218,11 +221,11 @@ failed:
-   if (reply != NULL)
-     dbus_message_unref (reply);
- 
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
- 
--dbus_bool_t
-+BusResult
- bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
-                                       BusTransaction *transaction,
-                                       DBusMessage    *message,
-@@ -246,7 +249,7 @@ bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
-   matchmaker = bus_context_get_matchmaker (context);
- 
-   if (!bus_registry_list_services (registry, &services, &services_len))
--    return FALSE;
-+    return BUS_RESULT_FALSE;
- 
-   reply = dbus_message_new_method_return (message);
-   if (reply == NULL)
-@@ -325,7 +328,7 @@ bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
- 
-   dbus_message_unref (reply);
-   dbus_free_string_array (services);
--  return TRUE;
-+  return BUS_RESULT_TRUE;
- 
- oom:
-   if (reply != NULL)
-@@ -334,7 +337,7 @@ oom:
-   dbus_free_string_array (services);
- 
-   BUS_SET_OOM (error);
--  return FALSE;
-+  return BUS_RESULT_FALSE;
- }
- 
- #endif
-diff --git a/bus/stats.h b/bus/stats.h
-index dcb022c..683fa17 100644
---- a/bus/stats.h
-+++ b/bus/stats.h
-@@ -25,17 +25,17 @@
- 
- #define BUS_INTERFACE_STATS "org.freedesktop.DBus.Debug.Stats"
- 
--dbus_bool_t bus_stats_handle_get_stats (DBusConnection *connection,
-+BusResult bus_stats_handle_get_stats (DBusConnection *connection,
-                                         BusTransaction *transaction,
-                                         DBusMessage    *message,
-                                         DBusError      *error);
- 
--dbus_bool_t bus_stats_handle_get_connection_stats (DBusConnection *connection,
-+BusResult bus_stats_handle_get_connection_stats (DBusConnection *connection,
-                                                    BusTransaction *transaction,
-                                                    DBusMessage    *message,
-                                                    DBusError      *error);
- 
--dbus_bool_t bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
-+BusResult bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
-                                                   BusTransaction *transaction,
-                                                   DBusMessage    *message,
-                                                   DBusError      *error);
--- 
-2.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Perform-Cynara-runtime-policy-checks-by-default.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
deleted file mode 100644
index 8ce441b05..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0005-Perform-Cynara-runtime-policy-checks-by-default.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 69ba571e0daa0a7a9aa6c6b5be5d3338a89d144a Mon Sep 17 00:00:00 2001
-From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Date: Tue, 23 Jun 2015 11:08:48 +0200
-Subject: Perform Cynara runtime policy checks by default
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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.
-
-Cherry picked from e8610297cf7031e94eb314a2e8c11246f4405403 by Jose Bollo
-
-Updated for dbus 1.10.20 by Scott Murray and José Bollo
-
-Signed-off-by: Jacek Bukarewicz <j.bukarewicz@samsung.com>
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-
-diff --git a/bus/activation.c b/bus/activation.c
-index ffdc6fc..6a95b95 100644
---- a/bus/activation.c
-+++ b/bus/activation.c
-@@ -1837,22 +1837,32 @@ bus_activation_activate_service (BusActivation  *activation,
-     }
- 
-   if (auto_activation &&
--      entry != NULL &&
--      BUS_RESULT_TRUE != bus_context_check_security_policy (activation->context,
--        transaction,
--        connection, /* sender */
--        NULL, /* addressed recipient */
--        NULL, /* proposed recipient */
--        activation_message,
--        entry,
--        error,
--        NULL))
--    {
--      _DBUS_ASSERT_ERROR_IS_SET (error);
--      _dbus_verbose ("activation not authorized: %s: %s\n",
--          error != NULL ? error->name : "(error ignored)",
--          error != NULL ? error->message : "(error ignored)");
--      return FALSE;
-+      entry != NULL)
-+   {
-+      BusResult result;
-+
-+      result = bus_context_check_security_policy (activation->context,
-+                      transaction,
-+                      connection, /* sender */
-+                      NULL, /* addressed recipient */
-+                      NULL, /* proposed recipient */
-+                      activation_message,
-+                      entry,
-+                      error,
-+                      NULL);
-+      if (result == BUS_RESULT_FALSE)
-+        {
-+          _DBUS_ASSERT_ERROR_IS_SET (error);
-+          _dbus_verbose ("activation not authorized: %s: %s\n",
-+              error != NULL ? error->name : "(error ignored)",
-+              error != NULL ? error->message : "(error ignored)");
-+          return FALSE;
-+        }
-+      if (result == BUS_RESULT_LATER)
-+        {
-+          /* TODO */
-+          _dbus_verbose ("ALERT FIX ME!!!!!!!!!!!!!!!");
-+        }
-     }
- 
-   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
-diff --git a/bus/session.conf.in b/bus/session.conf.in
-index affa7f1..157dfb4 100644
---- a/bus/session.conf.in
-+++ b/bus/session.conf.in
-@@ -27,12 +27,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>
- 
-   <!-- Include legacy configuration location -->
-diff --git a/bus/system.conf.in b/bus/system.conf.in
-index f139b55..19d0c04 100644
---- a/bus/system.conf.in
-+++ b/bus/system.conf.in
-@@ -50,17 +50,20 @@
-     <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 -->
-     <allow send_destination="org.freedesktop.DBus"
-@@ -69,6 +72,14 @@
-            send_interface="org.freedesktop.DBus.Introspectable"/>
-     <allow send_destination="org.freedesktop.DBus"
-            send_interface="org.freedesktop.DBus.Properties"/>
-+    <!-- 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 receive_sender="org.freedesktop.DBus"/>
-+
-     <!-- But disallow some specific bus services -->
-     <deny send_destination="org.freedesktop.DBus"
-           send_interface="org.freedesktop.DBus"
--- 
-2.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Fix-gcc-8-warnings.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Fix-gcc-8-warnings.patch
deleted file mode 100644
index 30fac9693..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0006-Fix-gcc-8-warnings.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From 988958f40a2e0575df3d4d48101612713737a5db Mon Sep 17 00:00:00 2001
-From: Jose Bollo <jose.bollo@iot.bzh>
-Date: Wed, 29 May 2019 16:32:50 +0200
-Subject: Fix gcc 8 warnings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Compiling with -Werror isn't possible without adaptation
-of the code.
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-
-diff --git a/bus/config-parser-trivial.c b/bus/config-parser-trivial.c
-index dd65c6d..23dedb4 100644
---- a/bus/config-parser-trivial.c
-+++ b/bus/config-parser-trivial.c
-@@ -194,6 +194,7 @@ bus_config_parser_start_element (BusConfigParser   *parser,
-     case ELEMENT_POLICY:
-     case ELEMENT_LIMIT:
-     case ELEMENT_ALLOW:
-+    case ELEMENT_CHECK:
-     case ELEMENT_DENY:
-     case ELEMENT_FORK:
-     case ELEMENT_PIDFILE:
-@@ -316,6 +317,7 @@ bus_config_parser_content (BusConfigParser   *parser,
-     case ELEMENT_POLICY:
-     case ELEMENT_LIMIT:
-     case ELEMENT_ALLOW:
-+    case ELEMENT_CHECK:
-     case ELEMENT_DENY:
-     case ELEMENT_FORK:
-     case ELEMENT_PIDFILE:
-diff --git a/bus/config-parser.c b/bus/config-parser.c
-index b5f1dd1..7f91469 100644
---- a/bus/config-parser.c
-+++ b/bus/config-parser.c
-@@ -3408,6 +3408,7 @@ elements_equal (const Element *a,
-     case ELEMENT_LISTEN:
-     case ELEMENT_AUTH:
-     case ELEMENT_ALLOW:
-+    case ELEMENT_CHECK:
-     case ELEMENT_DENY:
-     case ELEMENT_FORK:
-     case ELEMENT_PIDFILE:
-diff --git a/bus/desktop-file.c b/bus/desktop-file.c
-index 4459858..4a27ee3 100644
---- a/bus/desktop-file.c
-+++ b/bus/desktop-file.c
-@@ -382,7 +382,7 @@ is_valid_section_name (const char *name)
- 
-   while (*name)
-     {
--      if (!((*name >= 'A' && *name <= 'Z') || (*name >= 'a' || *name <= 'z') ||
-+      if (!((*name >= ' ' && *name <= '~' && *name != '[' && *name != ']') ||
- 	    *name == '\n' || *name == '\t'))
- 	return FALSE;
-       
-diff --git a/bus/driver.h b/bus/driver.h
-index 183c28b..05e9886 100644
---- a/bus/driver.h
-+++ b/bus/driver.h
-@@ -66,5 +66,7 @@ dbus_bool_t bus_driver_send_ack_reply     (DBusConnection  *connection,
-                                            BusTransaction  *transaction,
-                                            DBusMessage     *message,
-                                            DBusError       *error);
-+dbus_bool_t bus_driver_check_message_is_for_us (DBusMessage *message,
-+                                                DBusError   *error);
- 
- #endif /* BUS_DRIVER_H */
-diff --git a/bus/policy.c b/bus/policy.c
-index 27b66d1..c4c3d4b 100644
---- a/bus/policy.c
-+++ b/bus/policy.c
-@@ -1098,6 +1098,7 @@ bus_client_policy_check_can_send (DBusConnection      *sender,
-         case BUS_POLICY_RULE_ACCESS_ALLOW:
-           result = BUS_RESULT_TRUE;
-           break;
-+        default:
-         case BUS_POLICY_RULE_ACCESS_DENY:
-           result = BUS_RESULT_FALSE;
-           break;
-@@ -1350,6 +1351,7 @@ bus_client_policy_check_can_receive (BusClientPolicy     *policy,
-         case BUS_POLICY_RULE_ACCESS_ALLOW:
-           result = BUS_RESULT_TRUE;
-           break;
-+        default:
-         case BUS_POLICY_RULE_ACCESS_DENY:
-           result = BUS_RESULT_FALSE;
-           break;
-@@ -1443,6 +1445,7 @@ bus_rules_check_can_own (DBusList *rules,
-       case BUS_POLICY_RULE_ACCESS_ALLOW:
-         result = BUS_RESULT_TRUE;
-         break;
-+      default:
-       case BUS_POLICY_RULE_ACCESS_DENY:
-         result = BUS_RESULT_FALSE;
-         break;
-diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
-index 565e089..b96c735 100644
---- a/dbus/dbus-sysdeps-unix.c
-+++ b/dbus/dbus-sysdeps-unix.c
-@@ -4364,7 +4364,11 @@ _dbus_daemon_unpublish_session_bus_address (void)
- dbus_bool_t
- _dbus_get_is_errno_eagain_or_ewouldblock (int e)
- {
-+#if EAGAIN != EWOULDBLOCK
-   return e == EAGAIN || e == EWOULDBLOCK;
-+#else
-+  return e == EAGAIN;
-+#endif
- }
- 
- /**
-diff --git a/tools/dbus-send.c b/tools/dbus-send.c
-index 6fb65fe..d853b39 100644
---- a/tools/dbus-send.c
-+++ b/tools/dbus-send.c
-@@ -293,10 +293,12 @@ main (int argc, char *argv[])
-             {
-               is_bus = TRUE;
-             }
-+#if 0
-           else if (arg[2] == 'p') /* peer */
-             {
-               is_bus = FALSE;
-             }
-+#endif
-           else /* address; keeping backwards compatibility */
-             {
-               is_bus = FALSE;
--- 
-2.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Fix-SIGSEGV-on-disconnections.patch b/meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Fix-SIGSEGV-on-disconnections.patch
deleted file mode 100644
index b5ee138ed..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus-cynara/0007-Fix-SIGSEGV-on-disconnections.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 2a1c1c3f9264f53abc439ec44b33fdca8ffbb803 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jose.bollo@iot.bzh>
-Date: Fri, 16 Aug 2019 13:29:23 +0200
-Subject: [PATCH 7/8] Fix SIGSEGV on disconnections
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Sometime, at start of the system, dbus-daemon was crashing
-because a pending authorisation were reactivating a closed
-connection.
-
-Also, clean unused function.
-
-Signed-off-by: José Bollo <jose.bollo@iot.bzh>
----
- bus/check.c      |  5 +++++
- bus/check.h      |  1 +
- bus/connection.c | 14 +++-----------
- bus/connection.h |  3 ---
- 4 files changed, 9 insertions(+), 14 deletions(-)
-
-diff --git a/bus/check.c b/bus/check.c
-index f3d283f..b73d08b 100644
---- a/bus/check.c
-+++ b/bus/check.c
-@@ -617,3 +617,8 @@ bus_deferred_message_response_received (BusDeferredMessage *deferred_message,
-     }
- }
- 
-+void
-+bus_deferred_message_abort (BusDeferredMessage *deferred_message)
-+{
-+  deferred_message->response_callback = NULL;
-+}
-diff --git a/bus/check.h b/bus/check.h
-index 9c13c18..d718a69 100644
---- a/bus/check.h
-+++ b/bus/check.h
-@@ -93,6 +93,7 @@ void                bus_deferred_message_set_policy_check_info (BusDeferredMessa
-                                                                 const char *privilege);
- dbus_bool_t         bus_deferred_message_check_message_limits (BusDeferredMessage *deferred_message,
-                                                                DBusError *error);
-+void                bus_deferred_message_abort                (BusDeferredMessage *deferred_message);
- 
- 
- #ifdef DBUS_ENABLE_EMBEDDED_TESTS
-diff --git a/bus/connection.c b/bus/connection.c
-index ee93384..b520d57 100644
---- a/bus/connection.c
-+++ b/bus/connection.c
-@@ -47,6 +47,7 @@
- #define MAX_LOG_COMMAND_LEN 50
- 
- static void bus_connection_remove_transactions (DBusConnection *connection);
-+static void bus_connection_clear_deferred_messages (DBusConnection *connection);
- 
- typedef struct
- {
-@@ -2821,17 +2822,7 @@ bus_connection_pop_deferred_message (DBusConnection *connection)
-   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;
--}
--
-+static
- void
- bus_connection_clear_deferred_messages (DBusConnection *connection)
- {
-@@ -2846,6 +2837,7 @@ bus_connection_clear_deferred_messages (DBusConnection *connection)
-       next = _dbus_list_get_next_link (&d->deferred_messages, link);
-       message = link->data;
- 
-+      bus_deferred_message_abort(message);
-       bus_deferred_message_unref(message);
-       _dbus_list_remove_link(&d->deferred_messages, link);
- 
-diff --git a/bus/connection.h b/bus/connection.h
-index 97dae96..6af7bf1 100644
---- a/bus/connection.h
-+++ b/bus/connection.h
-@@ -90,15 +90,12 @@ dbus_bool_t         bus_connection_queue_deferred_message   (DBusConnection *con
-                                                              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 */
--- 
-2.17.2
-
diff --git a/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend b/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend
deleted file mode 100644
index ce2bd0822..000000000
--- a/meta-security/recipes-core/dbus-cynara/dbus_1.12.16.bbappend
+++ /dev/null
@@ -1,17 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/dbus-cynara:"
-
-#SRC_URI_append_class-target = "\
-#   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 \
-#   file://0006-Fix-gcc-8-warnings.patch \
-#   file://0007-Fix-SIGSEGV-on-disconnections.patch \
-#"
-SRC_URI_append_class-target = "\
-"
-
-#DEPENDS_append_class-target = " cynara smack"
-#EXTRA_OECONF_append_class-target = " ${@bb.utils.contains('DISTRO_FEATURES','smack','--enable-cynara --disable-selinux','',d)}"
-
-- 
cgit