event: filter global events by domain:getattr ACL [CVE-2014-0028]

Ever since ACL filtering was added in commit 7639736 (v1.1.1), a
user could still use event registration to obtain access to a
domain that they could not normally access via virDomainLookup*
or virConnectListAllDomains and friends.  We already have the
framework in the RPC generator for creating the filter, and
previous cleanup patches got us to the point that we can now
wire the filter through the entire object event stack.

Furthermore, whether or not domain:getattr is honored, use of
global events is a form of obtaining a list of networks, which
is covered by connect:search_domains added in a93cd08 (v1.1.0).
Ideally, we'd have a way to enforce connect:search_domains when
doing global registrations while omitting that check on a
per-domain registration.  But this patch just unconditionally
requires connect:search_domains, even when no list could be
obtained, based on the following observations:
1. Administrators are unlikely to grant domain:getattr for one
or all domains while still denying connect:search_domains - a
user that is able to manage domains will want to be able to
manage them efficiently, but efficient management includes being
able to list the domains they can access.  The idea of denying
connect:search_domains while still granting access to individual
domains is therefore not adding any real security, but just
serves as a layer of obscurity to annoy the end user.
2. In the current implementation, domain events are filtered
on the client; the server has no idea if a domain filter was
requested, and must therefore assume that all domain event
requests are global.  Even if we fix the RPC protocol to
allow for server-side filtering for newer client/server combos,
making the connect:serach_domains ACL check conditional on
whether the domain argument was NULL won't benefit older clients.
Therefore, we choose to document that connect:search_domains
is a pre-requisite to any domain event management.

Network events need the same treatment, with the obvious
change of using connect:search_networks and network:getattr.

* src/access/viraccessperm.h
(VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)
(VIR_ACCESS_PERM_CONNECT_SEARCH_NETWORKS): Document additional
effect of the permission.
* src/conf/domain_event.h (virDomainEventStateRegister)
(virDomainEventStateRegisterID): Add new parameter.
* src/conf/network_event.h (virNetworkEventStateRegisterID):
Likewise.
* src/conf/object_event_private.h (virObjectEventStateRegisterID):
Likewise.
* src/conf/object_event.c (_virObjectEventCallback): Track a filter.
(virObjectEventDispatchMatchCallback): Use filter.
(virObjectEventCallbackListAddID): Register filter.
* src/conf/domain_event.c (virDomainEventFilter): New function.
(virDomainEventStateRegister, virDomainEventStateRegisterID):
Adjust callers.
* src/conf/network_event.c (virNetworkEventFilter): New function.
(virNetworkEventStateRegisterID): Adjust caller.
* src/remote/remote_protocol.x
(REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER)
(REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY)
(REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY): Generate a
filter, and require connect:search_domains instead of weaker
connect:read.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventRegisterAny)
(testConnectNetworkEventRegisterAny): Update callers.
* src/remote/remote_driver.c (remoteConnectDomainEventRegister)
(remoteConnectDomainEventRegisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventRegisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc): Likewise.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventRegisterAny): Likewise.
* src/qemu/qemu_driver.c (qemuConnectDomainEventRegister)
(qemuConnectDomainEventRegisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventRegisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventRegisterAny): Likewise.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventRegisterAny): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit f9f5634053)

Conflicts:
	src/conf/object_event.c - not backporting event refactoring
	src/conf/object_event_private.h - likewise
	src/conf/network_event.c - not backporting network events
	src/conf/network_event.h - likewise
	src/network/bridge_driver.c - likewise
	src/access/viraccessperm.h - likewise
	src/remote/remote_protocol.x - likewise
	src/conf/domain_event.c - includes code that upstream has in object_event
	src/conf/domain_event.h - context
	src/libxl/libxl_driver.c - context
	src/lxc/lxc_driver.c - context
	src/remote/remote_driver.c - context, not backporting network events
	src/test/test_driver.c - context, not backporting network events
	src/uml/uml_driver.c - context
	src/xen/xen_driver.c - context
This commit is contained in:
Eric Blake 2014-01-14 10:29:34 -07:00
parent 271c0e7b43
commit 51afa9a255
12 changed files with 94 additions and 17 deletions

View File

@ -1,7 +1,7 @@
/* /*
* viraccessperm.h: access control permissions * viraccessperm.h: access control permissions
* *
* Copyright (C) 2012-2013 Red Hat, Inc. * Copyright (C) 2012-2014 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -47,7 +47,7 @@ typedef enum {
/** /**
* @desc: List domains * @desc: List domains
* @message: Listing domains requires authorization * @message: Listing domains or using domain events requires authorization
* @anonymous: 1 * @anonymous: 1
*/ */
VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS, VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS,

View File

@ -32,6 +32,20 @@
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
/**
* virObjectEventCallbackFilter:
* @conn: the connection pointer
* @event: the event about to be dispatched
* @opaque: opaque data registered with the filter
*
* Callback to do final filtering for a reason not tracked directly by
* virObjectEventStateRegisterID(). Return false if @event must not
* be sent to @conn.
*/
typedef bool (*virObjectEventCallbackFilter)(virConnectPtr conn,
virDomainEventPtr event,
void *opaque);
struct _virDomainMeta { struct _virDomainMeta {
int id; int id;
char *name; char *name;
@ -68,6 +82,8 @@ struct _virDomainEventCallback {
int eventID; int eventID;
virConnectPtr conn; virConnectPtr conn;
virDomainMetaPtr dom; virDomainMetaPtr dom;
virObjectEventCallbackFilter filter;
void *filter_opaque;
virConnectDomainEventGenericCallback cb; virConnectDomainEventGenericCallback cb;
void *opaque; void *opaque;
virFreeCallback freecb; virFreeCallback freecb;
@ -344,6 +360,9 @@ virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList)
* virDomainEventCallbackListAddID: * virDomainEventCallbackListAddID:
* @conn: pointer to the connection * @conn: pointer to the connection
* @cbList: the list * @cbList: the list
* @dom: optional domain to filter on
* @filter optional last-ditch filter callback
* @filter_opaque: opaque data to pass to @filter
* @eventID: the event ID * @eventID: the event ID
* @callback: the callback to add * @callback: the callback to add
* @opaque: opaque data tio pass to callback * @opaque: opaque data tio pass to callback
@ -355,6 +374,8 @@ static int
virDomainEventCallbackListAddID(virConnectPtr conn, virDomainEventCallbackListAddID(virConnectPtr conn,
virDomainEventCallbackListPtr cbList, virDomainEventCallbackListPtr cbList,
virDomainPtr dom, virDomainPtr dom,
virObjectEventCallbackFilter filter,
void *filter_opaque,
int eventID, int eventID,
virConnectDomainEventGenericCallback callback, virConnectDomainEventGenericCallback callback,
void *opaque, void *opaque,
@ -401,6 +422,8 @@ virDomainEventCallbackListAddID(virConnectPtr conn,
memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN); memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
event->dom->id = dom->id; event->dom->id = dom->id;
} }
event->filter = filter;
event->filter_opaque = filter_opaque;
/* Make space on list */ /* Make space on list */
if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0) if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
@ -440,6 +463,8 @@ error:
* virDomainEventCallbackListAdd: * virDomainEventCallbackListAdd:
* @conn: pointer to the connection * @conn: pointer to the connection
* @cbList: the list * @cbList: the list
* @filter optional last-ditch filter callback
* @filter_opaque: opaque data to pass to @filter
* @callback: the callback to add * @callback: the callback to add
* @opaque: opaque data tio pass to callback * @opaque: opaque data tio pass to callback
* *
@ -448,11 +473,14 @@ error:
static int static int
virDomainEventCallbackListAdd(virConnectPtr conn, virDomainEventCallbackListAdd(virConnectPtr conn,
virDomainEventCallbackListPtr cbList, virDomainEventCallbackListPtr cbList,
virObjectEventCallbackFilter filter,
void *filter_opaque,
virConnectDomainEventCallback callback, virConnectDomainEventCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb)
{ {
return virDomainEventCallbackListAddID(conn, cbList, NULL, return virDomainEventCallbackListAddID(conn, cbList, NULL,
filter, filter_opaque,
VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), VIR_DOMAIN_EVENT_CALLBACK(callback),
opaque, freecb, NULL); opaque, freecb, NULL);
@ -680,6 +708,32 @@ static virDomainEventPtr virDomainEventNewInternal(int eventID,
return event; return event;
} }
/**
* virDomainEventFilter:
* @conn: pointer to the connection
* @event: the event to check
* @opaque: opaque data holding ACL filter to use
*
* Internal function to run ACL filtering before dispatching an event
*/
static bool
virDomainEventFilter(virConnectPtr conn, virDomainEventPtr event,
void *opaque)
{
virDomainDef dom;
virDomainObjListFilter filter = opaque;
/* For now, we just create a virDomainDef with enough contents to
* satisfy what viraccessdriverpolkit.c references. This is a bit
* fragile, but I don't know of anything better. */
dom.name = event->dom.name;
memcpy(dom.uuid, event->dom.uuid, VIR_UUID_BUFLEN);
return (filter)(conn, &dom);
}
virDomainEventPtr virDomainEventNew(int id, const char *name, virDomainEventPtr virDomainEventNew(int id, const char *name,
const unsigned char *uuid, const unsigned char *uuid,
int type, int detail) int type, int detail)
@ -1381,6 +1435,9 @@ static int virDomainEventDispatchMatchCallback(virDomainEventPtr event,
if (cb->eventID != event->eventID) if (cb->eventID != event->eventID)
return 0; return 0;
if (cb->filter && !(cb->filter)(cb->conn, event, cb->filter_opaque))
return 0;
if (cb->dom) { if (cb->dom) {
/* Deliberately ignoring 'id' for matching, since that /* Deliberately ignoring 'id' for matching, since that
* will cause problems when a domain switches between * will cause problems when a domain switches between
@ -1510,6 +1567,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state)
* virDomainEventStateRegister: * virDomainEventStateRegister:
* @conn: connection to associate with callback * @conn: connection to associate with callback
* @state: domain event state * @state: domain event state
* @filter: optional ACL filter to limit which events can be sent
* @callback: function to remove from event * @callback: function to remove from event
* @opaque: data blob to pass to callback * @opaque: data blob to pass to callback
* @freecb: callback to free @opaque * @freecb: callback to free @opaque
@ -1522,6 +1580,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state)
int int
virDomainEventStateRegister(virConnectPtr conn, virDomainEventStateRegister(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
virDomainObjListFilter filter,
virConnectDomainEventCallback callback, virConnectDomainEventCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb)
@ -1542,7 +1601,8 @@ virDomainEventStateRegister(virConnectPtr conn,
} }
ret = virDomainEventCallbackListAdd(conn, state->callbacks, ret = virDomainEventCallbackListAdd(conn, state->callbacks,
callback, opaque, freecb); filter ? virDomainEventFilter : NULL,
filter, callback, opaque, freecb);
if (ret == -1 && if (ret == -1 &&
state->callbacks->count == 0 && state->callbacks->count == 0 &&
@ -1561,6 +1621,7 @@ cleanup:
* virDomainEventStateRegisterID: * virDomainEventStateRegisterID:
* @conn: connection to associate with callback * @conn: connection to associate with callback
* @state: domain event state * @state: domain event state
* @filter: optional ACL filter to limit which events can be sent
* @eventID: ID of the event type to register for * @eventID: ID of the event type to register for
* @cb: function to remove from event * @cb: function to remove from event
* @opaque: data blob to pass to callback * @opaque: data blob to pass to callback
@ -1575,6 +1636,7 @@ cleanup:
int int
virDomainEventStateRegisterID(virConnectPtr conn, virDomainEventStateRegisterID(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
virDomainObjListFilter filter,
virDomainPtr dom, virDomainPtr dom,
int eventID, int eventID,
virConnectDomainEventGenericCallback cb, virConnectDomainEventGenericCallback cb,
@ -1597,8 +1659,9 @@ virDomainEventStateRegisterID(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
ret = virDomainEventCallbackListAddID(conn, state->callbacks, ret = virDomainEventCallbackListAddID(conn, state->callbacks, dom,
dom, eventID, cb, opaque, freecb, filter ? virDomainEventFilter : NULL,
filter, eventID, cb, opaque, freecb,
callbackID); callbackID);
if (ret == -1 && if (ret == -1 &&

View File

@ -1,7 +1,7 @@
/* /*
* domain_event.h: domain event queue processing helpers * domain_event.h: domain event queue processing helpers
* *
* Copyright (C) 2012 Red Hat, Inc. * Copyright (C) 2012-2014 Red Hat, Inc.
* Copyright (C) 2008 VirtualIron * Copyright (C) 2008 VirtualIron
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -149,19 +149,21 @@ virDomainEventStateQueue(virDomainEventStatePtr state,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int virDomainEventStateRegister(virConnectPtr conn, int virDomainEventStateRegister(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
virDomainObjListFilter filter,
virConnectDomainEventCallback callback, virConnectDomainEventCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
int virDomainEventStateRegisterID(virConnectPtr conn, int virDomainEventStateRegisterID(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
virDomainObjListFilter filter,
virDomainPtr dom, virDomainPtr dom,
int eventID, int eventID,
virConnectDomainEventGenericCallback cb, virConnectDomainEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
int *callbackID) int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6);
int int
virDomainEventStateDeregister(virConnectPtr conn, virDomainEventStateDeregister(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,

View File

@ -3518,6 +3518,7 @@ libxlConnectDomainEventRegister(virConnectPtr conn,
ret = virDomainEventStateRegister(conn, ret = virDomainEventStateRegister(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb); callback, opaque, freecb);
return ret; return ret;
@ -4117,6 +4118,7 @@ libxlConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eve
if (virDomainEventStateRegisterID(conn, if (virDomainEventStateRegisterID(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, callback, opaque, dom, eventID, callback, opaque,
freecb, &ret) < 0) freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -1294,6 +1294,7 @@ lxcConnectDomainEventRegister(virConnectPtr conn,
ret = virDomainEventStateRegister(conn, ret = virDomainEventStateRegister(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb); callback, opaque, freecb);
return ret; return ret;
@ -1334,6 +1335,7 @@ lxcConnectDomainEventRegisterAny(virConnectPtr conn,
if (virDomainEventStateRegisterID(conn, if (virDomainEventStateRegisterID(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, dom, eventID,
callback, opaque, freecb, &ret) < 0) callback, opaque, freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -9861,6 +9861,7 @@ qemuConnectDomainEventRegister(virConnectPtr conn,
if (virDomainEventStateRegister(conn, if (virDomainEventStateRegister(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb) < 0) callback, opaque, freecb) < 0)
goto cleanup; goto cleanup;
@ -9909,6 +9910,7 @@ qemuConnectDomainEventRegisterAny(virConnectPtr conn,
if (virDomainEventStateRegisterID(conn, if (virDomainEventStateRegisterID(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, dom, eventID,
callback, opaque, freecb, &ret) < 0) callback, opaque, freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -4311,7 +4311,7 @@ static int remoteConnectDomainEventRegister(virConnectPtr conn,
remoteDriverLock(priv); remoteDriverLock(priv);
if ((count = virDomainEventStateRegister(conn, priv->domainEventState, if ((count = virDomainEventStateRegister(conn, priv->domainEventState, NULL,
callback, opaque, freecb)) < 0) { callback, opaque, freecb)) < 0) {
virReportError(VIR_ERR_RPC, "%s", _("adding cb to list")); virReportError(VIR_ERR_RPC, "%s", _("adding cb to list"));
goto done; goto done;
@ -5097,7 +5097,7 @@ static int remoteConnectDomainEventRegisterAny(virConnectPtr conn,
remoteDriverLock(priv); remoteDriverLock(priv);
if ((count = virDomainEventStateRegisterID(conn, if ((count = virDomainEventStateRegisterID(conn,
priv->domainEventState, priv->domainEventState, NULL,
dom, eventID, dom, eventID,
callback, opaque, freecb, callback, opaque, freecb,
&callbackID)) < 0) { &callbackID)) < 0) {

View File

@ -1955,7 +1955,7 @@ struct remote_node_device_destroy_args {
/* /*
* Events Register/Deregister: * Events Register/Deregister:
* It would seem rpcgen does not like both args, and ret * It would seem rpcgen does not like both args and ret
* to be null. It will not generate the prototype otherwise. * to be null. It will not generate the prototype otherwise.
* Pass back a redundant boolean to force prototype generation. * Pass back a redundant boolean to force prototype generation.
*/ */
@ -3620,7 +3620,8 @@ enum remote_procedure {
/** /**
* @generate: none * @generate: none
* @priority: high * @priority: high
* @acl: connect:read * @acl: connect:search_domains
* @aclfilter: domain:getattr
*/ */
REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER = 105, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER = 105,
@ -4052,7 +4053,8 @@ enum remote_procedure {
/** /**
* @generate: none * @generate: none
* @priority: high * @priority: high
* @acl: connect:read * @acl: connect:search_domains
* @aclfilter: domain:getattr
*/ */
REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY = 167, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY = 167,

View File

@ -5772,7 +5772,7 @@ testConnectDomainEventRegister(virConnectPtr conn,
testDriverLock(driver); testDriverLock(driver);
ret = virDomainEventStateRegister(conn, ret = virDomainEventStateRegister(conn,
driver->domainEventState, driver->domainEventState, NULL,
callback, opaque, freecb); callback, opaque, freecb);
testDriverUnlock(driver); testDriverUnlock(driver);
@ -5810,7 +5810,7 @@ testConnectDomainEventRegisterAny(virConnectPtr conn,
testDriverLock(driver); testDriverLock(driver);
if (virDomainEventStateRegisterID(conn, if (virDomainEventStateRegisterID(conn,
driver->domainEventState, driver->domainEventState, NULL,
dom, eventID, dom, eventID,
callback, opaque, freecb, &ret) < 0) callback, opaque, freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -2617,6 +2617,7 @@ umlConnectDomainEventRegister(virConnectPtr conn,
umlDriverLock(driver); umlDriverLock(driver);
ret = virDomainEventStateRegister(conn, ret = virDomainEventStateRegister(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb); callback, opaque, freecb);
umlDriverUnlock(driver); umlDriverUnlock(driver);
@ -2659,6 +2660,7 @@ umlConnectDomainEventRegisterAny(virConnectPtr conn,
umlDriverLock(driver); umlDriverLock(driver);
if (virDomainEventStateRegisterID(conn, if (virDomainEventStateRegisterID(conn,
driver->domainEventState, driver->domainEventState,
virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, dom, eventID,
callback, opaque, freecb, &ret) < 0) callback, opaque, freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -7265,7 +7265,7 @@ static int vboxConnectDomainEventRegister(virConnectPtr conn,
* later you can iterate over them * later you can iterate over them
*/ */
ret = virDomainEventStateRegister(conn, data->domainEvents, ret = virDomainEventStateRegister(conn, data->domainEvents, NULL,
callback, opaque, freecb); callback, opaque, freecb);
VIR_DEBUG("virDomainEventStateRegister (ret = %d) (conn: %p, " VIR_DEBUG("virDomainEventStateRegister (ret = %d) (conn: %p, "
"callback: %p, opaque: %p, " "callback: %p, opaque: %p, "
@ -7357,7 +7357,7 @@ static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
* later you can iterate over them * later you can iterate over them
*/ */
if (virDomainEventStateRegisterID(conn, data->domainEvents, if (virDomainEventStateRegisterID(conn, data->domainEvents, NULL,
dom, eventID, dom, eventID,
callback, opaque, freecb, &ret) < 0) callback, opaque, freecb, &ret) < 0)
ret = -1; ret = -1;

View File

@ -2316,6 +2316,7 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
} }
ret = virDomainEventStateRegister(conn, priv->domainEvents, ret = virDomainEventStateRegister(conn, priv->domainEvents,
virConnectDomainEventRegisterCheckACL,
callback, opaque, freefunc); callback, opaque, freefunc);
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
@ -2373,6 +2374,7 @@ xenUnifiedConnectDomainEventRegisterAny(virConnectPtr conn,
} }
if (virDomainEventStateRegisterID(conn, priv->domainEvents, if (virDomainEventStateRegisterID(conn, priv->domainEvents,
virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, dom, eventID,
callback, opaque, freefunc, &ret) < 0) callback, opaque, freefunc, &ret) < 0)
ret = -1; ret = -1;