c401cc
From 8b9eacdac94b871ba66d515029a9f88c17b13352 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <8b9eacdac94b871ba66d515029a9f88c17b13352.1390394207.git.jdenemar@redhat.com>
c401cc
From: Eric Blake <eblake@redhat.com>
c401cc
Date: Thu, 16 Jan 2014 13:16:37 -0700
c401cc
Subject: [PATCH] event: filter global events by domain:getattr ACL
c401cc
c401cc
CVE-2014-0028
c401cc
c401cc
Ever since ACL filtering was added in commit 7639736 (v1.1.1), a
c401cc
user could still use event registration to obtain access to a
c401cc
domain that they could not normally access via virDomainLookup*
c401cc
or virConnectListAllDomains and friends.  We already have the
c401cc
framework in the RPC generator for creating the filter, and
c401cc
previous cleanup patches got us to the point that we can now
c401cc
wire the filter through the entire object event stack.
c401cc
c401cc
Furthermore, whether or not domain:getattr is honored, use of
c401cc
global events is a form of obtaining a list of networks, which
c401cc
is covered by connect:search_domains added in a93cd08 (v1.1.0).
c401cc
Ideally, we'd have a way to enforce connect:search_domains when
c401cc
doing global registrations while omitting that check on a
c401cc
per-domain registration.  But this patch just unconditionally
c401cc
requires connect:search_domains, even when no list could be
c401cc
obtained, based on the following observations:
c401cc
1. Administrators are unlikely to grant domain:getattr for one
c401cc
or all domains while still denying connect:search_domains - a
c401cc
user that is able to manage domains will want to be able to
c401cc
manage them efficiently, but efficient management includes being
c401cc
able to list the domains they can access.  The idea of denying
c401cc
connect:search_domains while still granting access to individual
c401cc
domains is therefore not adding any real security, but just
c401cc
serves as a layer of obscurity to annoy the end user.
c401cc
2. In the current implementation, domain events are filtered
c401cc
on the client; the server has no idea if a domain filter was
c401cc
requested, and must therefore assume that all domain event
c401cc
requests are global.  Even if we fix the RPC protocol to
c401cc
allow for server-side filtering for newer client/server combos,
c401cc
making the connect:serach_domains ACL check conditional on
c401cc
whether the domain argument was NULL won't benefit older clients.
c401cc
Therefore, we choose to document that connect:search_domains
c401cc
is a pre-requisite to any domain event management.
c401cc
c401cc
Network events need the same treatment, with the obvious
c401cc
change of using connect:search_networks and network:getattr.
c401cc
c401cc
* src/access/viraccessperm.h
c401cc
(VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)
c401cc
(VIR_ACCESS_PERM_CONNECT_SEARCH_NETWORKS): Document additional
c401cc
effect of the permission.
c401cc
* src/conf/domain_event.h (virDomainEventStateRegister)
c401cc
(virDomainEventStateRegisterID): Add new parameter.
c401cc
* src/conf/network_event.h (virNetworkEventStateRegisterID):
c401cc
Likewise.
c401cc
* src/conf/object_event_private.h (virObjectEventStateRegisterID):
c401cc
Likewise.
c401cc
* src/conf/object_event.c (_virObjectEventCallback): Track a filter.
c401cc
(virObjectEventDispatchMatchCallback): Use filter.
c401cc
(virObjectEventCallbackListAddID): Register filter.
c401cc
* src/conf/domain_event.c (virDomainEventFilter): New function.
c401cc
(virDomainEventStateRegister, virDomainEventStateRegisterID):
c401cc
Adjust callers.
c401cc
* src/conf/network_event.c (virNetworkEventFilter): New function.
c401cc
(virNetworkEventStateRegisterID): Adjust caller.
c401cc
* src/remote/remote_protocol.x
c401cc
(REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER)
c401cc
(REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY)
c401cc
(REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY): Generate a
c401cc
filter, and require connect:search_domains instead of weaker
c401cc
connect:read.
c401cc
* src/test/test_driver.c (testConnectDomainEventRegister)
c401cc
(testConnectDomainEventRegisterAny)
c401cc
(testConnectNetworkEventRegisterAny): Update callers.
c401cc
* src/remote/remote_driver.c (remoteConnectDomainEventRegister)
c401cc
(remoteConnectDomainEventRegisterAny): Likewise.
c401cc
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
c401cc
(xenUnifiedConnectDomainEventRegisterAny): Likewise.
c401cc
* src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc): Likewise.
c401cc
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
c401cc
(libxlConnectDomainEventRegisterAny): Likewise.
c401cc
* src/qemu/qemu_driver.c (qemuConnectDomainEventRegister)
c401cc
(qemuConnectDomainEventRegisterAny): Likewise.
c401cc
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
c401cc
(umlConnectDomainEventRegisterAny): Likewise.
c401cc
* src/network/bridge_driver.c
c401cc
(networkConnectNetworkEventRegisterAny): Likewise.
c401cc
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
c401cc
(lxcConnectDomainEventRegisterAny): Likewise.
c401cc
c401cc
Signed-off-by: Eric Blake <eblake@redhat.com>
c401cc
(cherry picked from commit f9f56340539d609cdc2e9d4ab812b9f146c3f100)
c401cc
c401cc
Conflicts:
c401cc
	src/conf/object_event.c - not backporting event refactoring
c401cc
	src/conf/object_event_private.h - likewise
c401cc
	src/conf/network_event.c - not backporting network events
c401cc
	src/conf/network_event.h - likewise
c401cc
	src/network/bridge_driver.c - likewise
c401cc
	src/access/viraccessperm.h - likewise
c401cc
	src/remote/remote_protocol.x - likewise
c401cc
	src/conf/domain_event.c - includes code that upstream has in object_event
c401cc
	src/conf/domain_event.h - context
c401cc
	src/libxl/libxl_driver.c - context
c401cc
	src/lxc/lxc_driver.c - context
c401cc
	src/remote/remote_driver.c - context, not backporting network events
c401cc
	src/test/test_driver.c - context, not backporting network events
c401cc
	src/uml/uml_driver.c - context
c401cc
	src/xen/xen_driver.c - context
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/access/viraccessperm.h   |  4 +--
c401cc
 src/conf/domain_event.c      | 69 ++++++++++++++++++++++++++++++++++++++++++--
c401cc
 src/conf/domain_event.h      |  8 +++--
c401cc
 src/libxl/libxl_driver.c     |  2 ++
c401cc
 src/lxc/lxc_driver.c         |  2 ++
c401cc
 src/qemu/qemu_driver.c       |  2 ++
c401cc
 src/remote/remote_driver.c   |  4 +--
c401cc
 src/remote/remote_protocol.x |  8 +++--
c401cc
 src/test/test_driver.c       |  4 +--
c401cc
 src/uml/uml_driver.c         |  2 ++
c401cc
 src/vbox/vbox_tmpl.c         |  4 +--
c401cc
 src/xen/xen_driver.c         |  2 ++
c401cc
 12 files changed, 94 insertions(+), 17 deletions(-)
c401cc
c401cc
diff --git a/src/access/viraccessperm.h b/src/access/viraccessperm.h
c401cc
index fdc461b..1036b08 100644
c401cc
--- a/src/access/viraccessperm.h
c401cc
+++ b/src/access/viraccessperm.h
c401cc
@@ -1,7 +1,7 @@
c401cc
 /*
c401cc
  * viraccessperm.h: access control permissions
c401cc
  *
c401cc
- * Copyright (C) 2012-2013 Red Hat, Inc.
c401cc
+ * Copyright (C) 2012-2014 Red Hat, Inc.
c401cc
  *
c401cc
  * This library is free software; you can redistribute it and/or
c401cc
  * modify it under the terms of the GNU Lesser General Public
c401cc
@@ -47,7 +47,7 @@ typedef enum {
c401cc
 
c401cc
     /**
c401cc
      * @desc: List domains
c401cc
-     * @message: Listing domains requires authorization
c401cc
+     * @message: Listing domains or using domain events requires authorization
c401cc
      * @anonymous: 1
c401cc
      */
c401cc
     VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS,
c401cc
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
c401cc
index de55d08..1736aa0 100644
c401cc
--- a/src/conf/domain_event.c
c401cc
+++ b/src/conf/domain_event.c
c401cc
@@ -32,6 +32,20 @@
c401cc
 
c401cc
 #define VIR_FROM_THIS VIR_FROM_NONE
c401cc
 
c401cc
+/**
c401cc
+ * virObjectEventCallbackFilter:
c401cc
+ * @conn: the connection pointer
c401cc
+ * @event: the event about to be dispatched
c401cc
+ * @opaque: opaque data registered with the filter
c401cc
+ *
c401cc
+ * Callback to do final filtering for a reason not tracked directly by
c401cc
+ * virObjectEventStateRegisterID().  Return false if @event must not
c401cc
+ * be sent to @conn.
c401cc
+ */
c401cc
+typedef bool (*virObjectEventCallbackFilter)(virConnectPtr conn,
c401cc
+                                             virDomainEventPtr event,
c401cc
+                                             void *opaque);
c401cc
+
c401cc
 struct _virDomainMeta {
c401cc
     int id;
c401cc
     char *name;
c401cc
@@ -68,6 +82,8 @@ struct _virDomainEventCallback {
c401cc
     int eventID;
c401cc
     virConnectPtr conn;
c401cc
     virDomainMetaPtr dom;
c401cc
+    virObjectEventCallbackFilter filter;
c401cc
+    void *filter_opaque;
c401cc
     virConnectDomainEventGenericCallback cb;
c401cc
     void *opaque;
c401cc
     virFreeCallback freecb;
c401cc
@@ -344,6 +360,9 @@ virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList)
c401cc
  * virDomainEventCallbackListAddID:
c401cc
  * @conn: pointer to the connection
c401cc
  * @cbList: the list
c401cc
+ * @dom: optional domain to filter on
c401cc
+ * @filter optional last-ditch filter callback
c401cc
+ * @filter_opaque: opaque data to pass to @filter
c401cc
  * @eventID: the event ID
c401cc
  * @callback: the callback to add
c401cc
  * @opaque: opaque data tio pass to callback
c401cc
@@ -355,6 +374,8 @@ static int
c401cc
 virDomainEventCallbackListAddID(virConnectPtr conn,
c401cc
                                 virDomainEventCallbackListPtr cbList,
c401cc
                                 virDomainPtr dom,
c401cc
+                                virObjectEventCallbackFilter filter,
c401cc
+                                void *filter_opaque,
c401cc
                                 int eventID,
c401cc
                                 virConnectDomainEventGenericCallback callback,
c401cc
                                 void *opaque,
c401cc
@@ -401,6 +422,8 @@ virDomainEventCallbackListAddID(virConnectPtr conn,
c401cc
         memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
c401cc
         event->dom->id = dom->id;
c401cc
     }
c401cc
+    event->filter = filter;
c401cc
+    event->filter_opaque = filter_opaque;
c401cc
 
c401cc
     /* Make space on list */
c401cc
     if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
c401cc
@@ -440,6 +463,8 @@ error:
c401cc
  * virDomainEventCallbackListAdd:
c401cc
  * @conn: pointer to the connection
c401cc
  * @cbList: the list
c401cc
+ * @filter optional last-ditch filter callback
c401cc
+ * @filter_opaque: opaque data to pass to @filter
c401cc
  * @callback: the callback to add
c401cc
  * @opaque: opaque data tio pass to callback
c401cc
  *
c401cc
@@ -448,11 +473,14 @@ error:
c401cc
 static int
c401cc
 virDomainEventCallbackListAdd(virConnectPtr conn,
c401cc
                               virDomainEventCallbackListPtr cbList,
c401cc
+                              virObjectEventCallbackFilter filter,
c401cc
+                              void *filter_opaque,
c401cc
                               virConnectDomainEventCallback callback,
c401cc
                               void *opaque,
c401cc
                               virFreeCallback freecb)
c401cc
 {
c401cc
     return virDomainEventCallbackListAddID(conn, cbList, NULL,
c401cc
+                                           filter, filter_opaque,
c401cc
                                            VIR_DOMAIN_EVENT_ID_LIFECYCLE,
c401cc
                                            VIR_DOMAIN_EVENT_CALLBACK(callback),
c401cc
                                            opaque, freecb, NULL);
c401cc
@@ -680,6 +708,32 @@ static virDomainEventPtr virDomainEventNewInternal(int eventID,
c401cc
     return event;
c401cc
 }
c401cc
 
c401cc
+
c401cc
+/**
c401cc
+ * virDomainEventFilter:
c401cc
+ * @conn: pointer to the connection
c401cc
+ * @event: the event to check
c401cc
+ * @opaque: opaque data holding ACL filter to use
c401cc
+ *
c401cc
+ * Internal function to run ACL filtering before dispatching an event
c401cc
+ */
c401cc
+static bool
c401cc
+virDomainEventFilter(virConnectPtr conn, virDomainEventPtr event,
c401cc
+                     void *opaque)
c401cc
+{
c401cc
+    virDomainDef dom;
c401cc
+    virDomainObjListFilter filter = opaque;
c401cc
+
c401cc
+    /* For now, we just create a virDomainDef with enough contents to
c401cc
+     * satisfy what viraccessdriverpolkit.c references.  This is a bit
c401cc
+     * fragile, but I don't know of anything better.  */
c401cc
+    dom.name = event->dom.name;
c401cc
+    memcpy(dom.uuid, event->dom.uuid, VIR_UUID_BUFLEN);
c401cc
+
c401cc
+    return (filter)(conn, &dom;;
c401cc
+}
c401cc
+
c401cc
+
c401cc
 virDomainEventPtr virDomainEventNew(int id, const char *name,
c401cc
                                     const unsigned char *uuid,
c401cc
                                     int type, int detail)
c401cc
@@ -1381,6 +1435,9 @@ static int virDomainEventDispatchMatchCallback(virDomainEventPtr event,
c401cc
     if (cb->eventID != event->eventID)
c401cc
         return 0;
c401cc
 
c401cc
+    if (cb->filter && !(cb->filter)(cb->conn, event, cb->filter_opaque))
c401cc
+        return 0;
c401cc
+
c401cc
     if (cb->dom) {
c401cc
         /* Deliberately ignoring 'id' for matching, since that
c401cc
          * will cause problems when a domain switches between
c401cc
@@ -1510,6 +1567,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state)
c401cc
  * virDomainEventStateRegister:
c401cc
  * @conn: connection to associate with callback
c401cc
  * @state: domain event state
c401cc
+ * @filter: optional ACL filter to limit which events can be sent
c401cc
  * @callback: function to remove from event
c401cc
  * @opaque: data blob to pass to callback
c401cc
  * @freecb: callback to free @opaque
c401cc
@@ -1522,6 +1580,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state)
c401cc
 int
c401cc
 virDomainEventStateRegister(virConnectPtr conn,
c401cc
                             virDomainEventStatePtr state,
c401cc
+                            virDomainObjListFilter filter,
c401cc
                             virConnectDomainEventCallback callback,
c401cc
                             void *opaque,
c401cc
                             virFreeCallback freecb)
c401cc
@@ -1542,7 +1601,8 @@ virDomainEventStateRegister(virConnectPtr conn,
c401cc
     }
c401cc
 
c401cc
     ret = virDomainEventCallbackListAdd(conn, state->callbacks,
c401cc
-                                        callback, opaque, freecb);
c401cc
+                                        filter ? virDomainEventFilter : NULL,
c401cc
+                                        filter, callback, opaque, freecb);
c401cc
 
c401cc
     if (ret == -1 &&
c401cc
         state->callbacks->count == 0 &&
c401cc
@@ -1561,6 +1621,7 @@ cleanup:
c401cc
  * virDomainEventStateRegisterID:
c401cc
  * @conn: connection to associate with callback
c401cc
  * @state: domain event state
c401cc
+ * @filter: optional ACL filter to limit which events can be sent
c401cc
  * @eventID: ID of the event type to register for
c401cc
  * @cb: function to remove from event
c401cc
  * @opaque: data blob to pass to callback
c401cc
@@ -1575,6 +1636,7 @@ cleanup:
c401cc
 int
c401cc
 virDomainEventStateRegisterID(virConnectPtr conn,
c401cc
                               virDomainEventStatePtr state,
c401cc
+                              virDomainObjListFilter filter,
c401cc
                               virDomainPtr dom,
c401cc
                               int eventID,
c401cc
                               virConnectDomainEventGenericCallback cb,
c401cc
@@ -1597,8 +1659,9 @@ virDomainEventStateRegisterID(virConnectPtr conn,
c401cc
         goto cleanup;
c401cc
     }
c401cc
 
c401cc
-    ret = virDomainEventCallbackListAddID(conn, state->callbacks,
c401cc
-                                          dom, eventID, cb, opaque, freecb,
c401cc
+    ret = virDomainEventCallbackListAddID(conn, state->callbacks, dom,
c401cc
+                                          filter ? virDomainEventFilter : NULL,
c401cc
+                                          filter, eventID, cb, opaque, freecb,
c401cc
                                           callbackID);
c401cc
 
c401cc
     if (ret == -1 &&
c401cc
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
c401cc
index f6b957d..9dc65e2 100644
c401cc
--- a/src/conf/domain_event.h
c401cc
+++ b/src/conf/domain_event.h
c401cc
@@ -1,7 +1,7 @@
c401cc
 /*
c401cc
  * domain_event.h: domain event queue processing helpers
c401cc
  *
c401cc
- * Copyright (C) 2012 Red Hat, Inc.
c401cc
+ * Copyright (C) 2012-2014 Red Hat, Inc.
c401cc
  * Copyright (C) 2008 VirtualIron
c401cc
  *
c401cc
  * This library is free software; you can redistribute it and/or
c401cc
@@ -149,19 +149,21 @@ virDomainEventStateQueue(virDomainEventStatePtr state,
c401cc
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
c401cc
 int virDomainEventStateRegister(virConnectPtr conn,
c401cc
                                 virDomainEventStatePtr state,
c401cc
+                                virDomainObjListFilter filter,
c401cc
                                 virConnectDomainEventCallback callback,
c401cc
                                 void *opaque,
c401cc
                                 virFreeCallback freecb)
c401cc
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
c401cc
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
c401cc
 int virDomainEventStateRegisterID(virConnectPtr conn,
c401cc
                                   virDomainEventStatePtr state,
c401cc
+                                  virDomainObjListFilter filter,
c401cc
                                   virDomainPtr dom,
c401cc
                                   int eventID,
c401cc
                                   virConnectDomainEventGenericCallback cb,
c401cc
                                   void *opaque,
c401cc
                                   virFreeCallback freecb,
c401cc
                                   int *callbackID)
c401cc
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5);
c401cc
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6);
c401cc
 int
c401cc
 virDomainEventStateDeregister(virConnectPtr conn,
c401cc
                               virDomainEventStatePtr state,
c401cc
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
c401cc
index eb252d0..5036a42 100644
c401cc
--- a/src/libxl/libxl_driver.c
c401cc
+++ b/src/libxl/libxl_driver.c
c401cc
@@ -4148,6 +4148,7 @@ libxlConnectDomainEventRegister(virConnectPtr conn,
c401cc
     libxlDriverLock(driver);
c401cc
     ret = virDomainEventStateRegister(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterCheckACL,
c401cc
                                       callback, opaque, freecb);
c401cc
     libxlDriverUnlock(driver);
c401cc
 
c401cc
@@ -4738,6 +4739,7 @@ libxlConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eve
c401cc
     libxlDriverLock(driver);
c401cc
     if (virDomainEventStateRegisterID(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterAnyCheckACL,
c401cc
                                       dom, eventID, callback, opaque,
c401cc
                                       freecb, &ret) < 0)
c401cc
         ret = -1;
c401cc
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
c401cc
index 5144137..cddf9d3 100644
c401cc
--- a/src/lxc/lxc_driver.c
c401cc
+++ b/src/lxc/lxc_driver.c
c401cc
@@ -1294,6 +1294,7 @@ lxcConnectDomainEventRegister(virConnectPtr conn,
c401cc
 
c401cc
     ret = virDomainEventStateRegister(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterCheckACL,
c401cc
                                       callback, opaque, freecb);
c401cc
 
c401cc
     return ret;
c401cc
@@ -1334,6 +1335,7 @@ lxcConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
 
c401cc
     if (virDomainEventStateRegisterID(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterAnyCheckACL,
c401cc
                                       dom, eventID,
c401cc
                                       callback, opaque, freecb, &ret) < 0)
c401cc
         ret = -1;
c401cc
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
c401cc
index b542414..e2919a4 100644
c401cc
--- a/src/qemu/qemu_driver.c
c401cc
+++ b/src/qemu/qemu_driver.c
c401cc
@@ -10233,6 +10233,7 @@ qemuConnectDomainEventRegister(virConnectPtr conn,
c401cc
 
c401cc
     if (virDomainEventStateRegister(conn,
c401cc
                                     driver->domainEventState,
c401cc
+                                    virConnectDomainEventRegisterCheckACL,
c401cc
                                     callback, opaque, freecb) < 0)
c401cc
         goto cleanup;
c401cc
 
c401cc
@@ -10281,6 +10282,7 @@ qemuConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
 
c401cc
     if (virDomainEventStateRegisterID(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterAnyCheckACL,
c401cc
                                       dom, eventID,
c401cc
                                       callback, opaque, freecb, &ret) < 0)
c401cc
         ret = -1;
c401cc
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
c401cc
index 557b408..b32aa73 100644
c401cc
--- a/src/remote/remote_driver.c
c401cc
+++ b/src/remote/remote_driver.c
c401cc
@@ -4311,7 +4311,7 @@ static int remoteConnectDomainEventRegister(virConnectPtr conn,
c401cc
 
c401cc
     remoteDriverLock(priv);
c401cc
 
c401cc
-    if ((count = virDomainEventStateRegister(conn, priv->domainEventState,
c401cc
+    if ((count = virDomainEventStateRegister(conn, priv->domainEventState, NULL,
c401cc
                                              callback, opaque, freecb)) < 0) {
c401cc
          virReportError(VIR_ERR_RPC, "%s", _("adding cb to list"));
c401cc
          goto done;
c401cc
@@ -5097,7 +5097,7 @@ static int remoteConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
     remoteDriverLock(priv);
c401cc
 
c401cc
     if ((count = virDomainEventStateRegisterID(conn,
c401cc
-                                               priv->domainEventState,
c401cc
+                                               priv->domainEventState, NULL,
c401cc
                                                dom, eventID,
c401cc
                                                callback, opaque, freecb,
c401cc
                                                &callbackID)) < 0) {
c401cc
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
c401cc
index c7181da..ab8216e 100644
c401cc
--- a/src/remote/remote_protocol.x
c401cc
+++ b/src/remote/remote_protocol.x
c401cc
@@ -1952,7 +1952,7 @@ struct remote_node_device_destroy_args {
c401cc
 
c401cc
 /*
c401cc
  * Events Register/Deregister:
c401cc
- * It would seem rpcgen does not like both args, and ret
c401cc
+ * It would seem rpcgen does not like both args and ret
c401cc
  * to be null. It will not generate the prototype otherwise.
c401cc
  * Pass back a redundant boolean to force prototype generation.
c401cc
  */
c401cc
@@ -3606,7 +3606,8 @@ enum remote_procedure {
c401cc
     /**
c401cc
      * @generate: none
c401cc
      * @priority: high
c401cc
-     * @acl: connect:read
c401cc
+     * @acl: connect:search_domains
c401cc
+     * @aclfilter: domain:getattr
c401cc
      */
c401cc
     REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER = 105,
c401cc
 
c401cc
@@ -4038,7 +4039,8 @@ enum remote_procedure {
c401cc
     /**
c401cc
      * @generate: none
c401cc
      * @priority: high
c401cc
-     * @acl: connect:read
c401cc
+     * @acl: connect:search_domains
c401cc
+     * @aclfilter: domain:getattr
c401cc
      */
c401cc
     REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY = 167,
c401cc
 
c401cc
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
c401cc
index f7eaf06..cfc9401 100644
c401cc
--- a/src/test/test_driver.c
c401cc
+++ b/src/test/test_driver.c
c401cc
@@ -5571,7 +5571,7 @@ testConnectDomainEventRegister(virConnectPtr conn,
c401cc
 
c401cc
     testDriverLock(driver);
c401cc
     ret = virDomainEventStateRegister(conn,
c401cc
-                                      driver->domainEventState,
c401cc
+                                      driver->domainEventState, NULL,
c401cc
                                       callback, opaque, freecb);
c401cc
     testDriverUnlock(driver);
c401cc
 
c401cc
@@ -5609,7 +5609,7 @@ testConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
 
c401cc
     testDriverLock(driver);
c401cc
     if (virDomainEventStateRegisterID(conn,
c401cc
-                                      driver->domainEventState,
c401cc
+                                      driver->domainEventState, NULL,
c401cc
                                       dom, eventID,
c401cc
                                       callback, opaque, freecb, &ret) < 0)
c401cc
         ret = -1;
c401cc
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
c401cc
index eb02542..cf7f334 100644
c401cc
--- a/src/uml/uml_driver.c
c401cc
+++ b/src/uml/uml_driver.c
c401cc
@@ -2617,6 +2617,7 @@ umlConnectDomainEventRegister(virConnectPtr conn,
c401cc
     umlDriverLock(driver);
c401cc
     ret = virDomainEventStateRegister(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterCheckACL,
c401cc
                                       callback, opaque, freecb);
c401cc
     umlDriverUnlock(driver);
c401cc
 
c401cc
@@ -2659,6 +2660,7 @@ umlConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
     umlDriverLock(driver);
c401cc
     if (virDomainEventStateRegisterID(conn,
c401cc
                                       driver->domainEventState,
c401cc
+                                      virConnectDomainEventRegisterAnyCheckACL,
c401cc
                                       dom, eventID,
c401cc
                                       callback, opaque, freecb, &ret) < 0)
c401cc
         ret = -1;
c401cc
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
c401cc
index 3e9f0d9..c62db87 100644
c401cc
--- a/src/vbox/vbox_tmpl.c
c401cc
+++ b/src/vbox/vbox_tmpl.c
c401cc
@@ -7264,7 +7264,7 @@ static int vboxConnectDomainEventRegister(virConnectPtr conn,
c401cc
              * later you can iterate over them
c401cc
              */
c401cc
 
c401cc
-            ret = virDomainEventStateRegister(conn, data->domainEvents,
c401cc
+            ret = virDomainEventStateRegister(conn, data->domainEvents, NULL,
c401cc
                                               callback, opaque, freecb);
c401cc
             VIR_DEBUG("virDomainEventStateRegister (ret = %d) (conn: %p, "
c401cc
                       "callback: %p, opaque: %p, "
c401cc
@@ -7356,7 +7356,7 @@ static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
              * later you can iterate over them
c401cc
              */
c401cc
 
c401cc
-            if (virDomainEventStateRegisterID(conn, data->domainEvents,
c401cc
+            if (virDomainEventStateRegisterID(conn, data->domainEvents, NULL,
c401cc
                                               dom, eventID,
c401cc
                                               callback, opaque, freecb, &ret) < 0)
c401cc
                 ret = -1;
c401cc
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
c401cc
index 4ae38d3..878dc65 100644
c401cc
--- a/src/xen/xen_driver.c
c401cc
+++ b/src/xen/xen_driver.c
c401cc
@@ -2267,6 +2267,7 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
c401cc
     }
c401cc
 
c401cc
     ret = virDomainEventStateRegister(conn, priv->domainEvents,
c401cc
+                                      virConnectDomainEventRegisterCheckACL,
c401cc
                                       callback, opaque, freefunc);
c401cc
 
c401cc
     xenUnifiedUnlock(priv);
c401cc
@@ -2324,6 +2325,7 @@ xenUnifiedConnectDomainEventRegisterAny(virConnectPtr conn,
c401cc
     }
c401cc
 
c401cc
     if (virDomainEventStateRegisterID(conn, priv->domainEvents,
c401cc
+                                      virConnectDomainEventRegisterAnyCheckACL,
c401cc
                                       dom, eventID,
c401cc
                                       callback, opaque, freefunc, &ret) < 0)
c401cc
         ret = -1;
c401cc
-- 
c401cc
1.8.5.3
c401cc