mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-03 11:51:11 +00:00
event: filter global events by domain:getattr ACL [CVE-2014-0028]
Ever since ACL filtering was added in commit7639736
(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 ina93cd08
(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>
This commit is contained in:
parent
8d9d098b6d
commit
f9f5634053
@ -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,14 +47,14 @@ 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,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @desc: List networks
|
* @desc: List networks
|
||||||
* @message: Listing networks requires authorization
|
* @message: Listing networks or using network events requires authorization
|
||||||
* @anonymous: 1
|
* @anonymous: 1
|
||||||
*/
|
*/
|
||||||
VIR_ACCESS_PERM_CONNECT_SEARCH_NETWORKS,
|
VIR_ACCESS_PERM_CONNECT_SEARCH_NETWORKS,
|
||||||
|
@ -360,6 +360,30 @@ virDomainEventDeviceRemovedDispose(void *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, virObjectEventPtr 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->meta.name;
|
||||||
|
memcpy(dom.uuid, event->meta.uuid, VIR_UUID_BUFLEN);
|
||||||
|
|
||||||
|
return (filter)(conn, &dom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
virDomainEventNew(virClassPtr klass,
|
virDomainEventNew(virClassPtr klass,
|
||||||
int eventID,
|
int eventID,
|
||||||
@ -1265,6 +1289,7 @@ cleanup:
|
|||||||
* virDomainEventStateRegister:
|
* virDomainEventStateRegister:
|
||||||
* @conn: connection to associate with callback
|
* @conn: connection to associate with callback
|
||||||
* @state: object event state
|
* @state: object event state
|
||||||
|
* @filter: optional ACL filter to limit which events can be sent
|
||||||
* @callback: the callback to add
|
* @callback: the callback to add
|
||||||
* @opaque: data blob to pass to @callback
|
* @opaque: data blob to pass to @callback
|
||||||
* @freecb: callback to free @opaque
|
* @freecb: callback to free @opaque
|
||||||
@ -1277,6 +1302,7 @@ cleanup:
|
|||||||
int
|
int
|
||||||
virDomainEventStateRegister(virConnectPtr conn,
|
virDomainEventStateRegister(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
|
virDomainObjListFilter filter,
|
||||||
virConnectDomainEventCallback callback,
|
virConnectDomainEventCallback callback,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
virFreeCallback freecb)
|
virFreeCallback freecb)
|
||||||
@ -1285,7 +1311,8 @@ virDomainEventStateRegister(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return virObjectEventStateRegisterID(conn, state, NULL,
|
return virObjectEventStateRegisterID(conn, state, NULL,
|
||||||
virDomainEventClass,
|
filter ? virDomainEventFilter : NULL,
|
||||||
|
filter, virDomainEventClass,
|
||||||
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
||||||
VIR_OBJECT_EVENT_CALLBACK(callback),
|
VIR_OBJECT_EVENT_CALLBACK(callback),
|
||||||
opaque, freecb, NULL, false);
|
opaque, freecb, NULL, false);
|
||||||
@ -1296,6 +1323,7 @@ virDomainEventStateRegister(virConnectPtr conn,
|
|||||||
* virDomainEventStateRegisterID:
|
* virDomainEventStateRegisterID:
|
||||||
* @conn: connection to associate with callback
|
* @conn: connection to associate with callback
|
||||||
* @state: object event state
|
* @state: object event state
|
||||||
|
* @filter: optional ACL filter to limit which events can be sent
|
||||||
* @dom: optional domain for filtering the event
|
* @dom: optional domain for filtering the event
|
||||||
* @eventID: ID of the event type to register for
|
* @eventID: ID of the event type to register for
|
||||||
* @cb: function to invoke when event fires
|
* @cb: function to invoke when event fires
|
||||||
@ -1312,6 +1340,7 @@ virDomainEventStateRegister(virConnectPtr conn,
|
|||||||
int
|
int
|
||||||
virDomainEventStateRegisterID(virConnectPtr conn,
|
virDomainEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
|
virDomainObjListFilter filter,
|
||||||
virDomainPtr dom,
|
virDomainPtr dom,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectDomainEventGenericCallback cb,
|
virConnectDomainEventGenericCallback cb,
|
||||||
@ -1323,7 +1352,8 @@ virDomainEventStateRegisterID(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
|
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
|
||||||
virDomainEventClass, eventID,
|
filter ? virDomainEventFilter : NULL,
|
||||||
|
filter, virDomainEventClass, eventID,
|
||||||
VIR_OBJECT_EVENT_CALLBACK(cb),
|
VIR_OBJECT_EVENT_CALLBACK(cb),
|
||||||
opaque, freecb, callbackID, false);
|
opaque, freecb, callbackID, false);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
* Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
* Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||||
*
|
*
|
||||||
@ -177,20 +177,24 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
|
|||||||
int
|
int
|
||||||
virDomainEventStateRegister(virConnectPtr conn,
|
virDomainEventStateRegister(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr 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
|
int
|
||||||
virDomainEventStateRegisterID(virConnectPtr conn,
|
virDomainEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr 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,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
|
@ -121,10 +121,36 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetworkEventFilter:
|
||||||
|
* @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
|
||||||
|
virNetworkEventFilter(virConnectPtr conn, virObjectEventPtr event,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virNetworkDef net;
|
||||||
|
virNetworkObjListFilter filter = opaque;
|
||||||
|
|
||||||
|
/* For now, we just create a virNetworkDef with enough contents to
|
||||||
|
* satisfy what viraccessdriverpolkit.c references. This is a bit
|
||||||
|
* fragile, but I don't know of anything better. */
|
||||||
|
net.name = event->meta.name;
|
||||||
|
memcpy(net.uuid, event->meta.uuid, VIR_UUID_BUFLEN);
|
||||||
|
|
||||||
|
return (filter)(conn, &net);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNetworkEventStateRegisterID:
|
* virNetworkEventStateRegisterID:
|
||||||
* @conn: connection to associate with callback
|
* @conn: connection to associate with callback
|
||||||
* @state: object event state
|
* @state: object event state
|
||||||
|
* @filter: optional ACL filter to limit which events can be sent
|
||||||
* @net: network to filter on or NULL for all networks
|
* @net: network to filter on or NULL for all networks
|
||||||
* @eventID: ID of the event type to register for
|
* @eventID: ID of the event type to register for
|
||||||
* @cb: function to invoke when event occurs
|
* @cb: function to invoke when event occurs
|
||||||
@ -141,6 +167,7 @@ cleanup:
|
|||||||
int
|
int
|
||||||
virNetworkEventStateRegisterID(virConnectPtr conn,
|
virNetworkEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
|
virNetworkObjListFilter filter,
|
||||||
virNetworkPtr net,
|
virNetworkPtr net,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectNetworkEventGenericCallback cb,
|
virConnectNetworkEventGenericCallback cb,
|
||||||
@ -152,7 +179,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
|
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
|
||||||
virNetworkEventClass, eventID,
|
filter ? virNetworkEventFilter : NULL,
|
||||||
|
filter, virNetworkEventClass, eventID,
|
||||||
VIR_OBJECT_EVENT_CALLBACK(cb),
|
VIR_OBJECT_EVENT_CALLBACK(cb),
|
||||||
opaque, freecb, callbackID, false);
|
opaque, freecb, callbackID, false);
|
||||||
}
|
}
|
||||||
@ -190,6 +218,7 @@ virNetworkEventStateRegisterClient(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
|
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
|
||||||
|
NULL, NULL,
|
||||||
virNetworkEventClass, eventID,
|
virNetworkEventClass, eventID,
|
||||||
VIR_OBJECT_EVENT_CALLBACK(cb),
|
VIR_OBJECT_EVENT_CALLBACK(cb),
|
||||||
opaque, freecb, callbackID, true);
|
opaque, freecb, callbackID, true);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "object_event.h"
|
#include "object_event.h"
|
||||||
#include "object_event_private.h"
|
#include "object_event_private.h"
|
||||||
|
#include "network_conf.h"
|
||||||
|
|
||||||
#ifndef __NETWORK_EVENT_H__
|
#ifndef __NETWORK_EVENT_H__
|
||||||
# define __NETWORK_EVENT_H__
|
# define __NETWORK_EVENT_H__
|
||||||
@ -31,14 +32,15 @@
|
|||||||
int
|
int
|
||||||
virNetworkEventStateRegisterID(virConnectPtr conn,
|
virNetworkEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
|
virNetworkObjListFilter filter,
|
||||||
virNetworkPtr net,
|
virNetworkPtr net,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectNetworkEventGenericCallback cb,
|
virConnectNetworkEventGenericCallback 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)
|
||||||
ATTRIBUTE_NONNULL(8);
|
ATTRIBUTE_NONNULL(9);
|
||||||
|
|
||||||
int
|
int
|
||||||
virNetworkEventStateRegisterClient(virConnectPtr conn,
|
virNetworkEventStateRegisterClient(virConnectPtr conn,
|
||||||
|
@ -69,6 +69,8 @@ struct _virObjectEventCallback {
|
|||||||
int remoteID;
|
int remoteID;
|
||||||
bool uuid_filter;
|
bool uuid_filter;
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
virObjectEventCallbackFilter filter;
|
||||||
|
void *filter_opaque;
|
||||||
virConnectObjectEventGenericCallback cb;
|
virConnectObjectEventGenericCallback cb;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
virFreeCallback freecb;
|
virFreeCallback freecb;
|
||||||
@ -350,7 +352,9 @@ virObjectEventCallbackLookup(virConnectPtr conn,
|
|||||||
* virObjectEventCallbackListAddID:
|
* virObjectEventCallbackListAddID:
|
||||||
* @conn: pointer to the connection
|
* @conn: pointer to the connection
|
||||||
* @cbList: the list
|
* @cbList: the list
|
||||||
* @uuid: the uuid of the object to filter on
|
* @uuid: the optional uuid of the object to filter on
|
||||||
|
* @filter: optional last-ditch filter callback
|
||||||
|
* @filter_opaque: opaque data to pass to @filter
|
||||||
* @klass: the base event class
|
* @klass: the base event class
|
||||||
* @eventID: the event ID
|
* @eventID: the event ID
|
||||||
* @callback: the callback to add
|
* @callback: the callback to add
|
||||||
@ -365,6 +369,8 @@ static int
|
|||||||
virObjectEventCallbackListAddID(virConnectPtr conn,
|
virObjectEventCallbackListAddID(virConnectPtr conn,
|
||||||
virObjectEventCallbackListPtr cbList,
|
virObjectEventCallbackListPtr cbList,
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN],
|
unsigned char uuid[VIR_UUID_BUFLEN],
|
||||||
|
virObjectEventCallbackFilter filter,
|
||||||
|
void *filter_opaque,
|
||||||
virClassPtr klass,
|
virClassPtr klass,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectObjectEventGenericCallback callback,
|
virConnectObjectEventGenericCallback callback,
|
||||||
@ -377,9 +383,10 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
int remoteID = -1;
|
int remoteID = -1;
|
||||||
|
|
||||||
VIR_DEBUG("conn=%p cblist=%p uuid=%p "
|
VIR_DEBUG("conn=%p cblist=%p uuid=%p filter=%p filter_opaque=%p "
|
||||||
"klass=%p eventID=%d callback=%p opaque=%p",
|
"klass=%p eventID=%d callback=%p opaque=%p",
|
||||||
conn, cbList, uuid, klass, eventID, callback, opaque);
|
conn, cbList, uuid, filter, filter_opaque,
|
||||||
|
klass, eventID, callback, opaque);
|
||||||
|
|
||||||
/* Check incoming */
|
/* Check incoming */
|
||||||
if (!cbList) {
|
if (!cbList) {
|
||||||
@ -414,6 +421,8 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
|
|||||||
event->uuid_filter = true;
|
event->uuid_filter = true;
|
||||||
memcpy(event->uuid, uuid, VIR_UUID_BUFLEN);
|
memcpy(event->uuid, uuid, VIR_UUID_BUFLEN);
|
||||||
}
|
}
|
||||||
|
event->filter = filter;
|
||||||
|
event->filter_opaque = filter_opaque;
|
||||||
|
|
||||||
if (callbackID)
|
if (callbackID)
|
||||||
*callbackID = event->callbackID;
|
*callbackID = event->callbackID;
|
||||||
@ -675,6 +684,9 @@ virObjectEventDispatchMatchCallback(virObjectEventPtr event,
|
|||||||
if (cb->remoteID != event->remoteID)
|
if (cb->remoteID != event->remoteID)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (cb->filter && !(cb->filter)(cb->conn, event, cb->filter_opaque))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (cb->uuid_filter) {
|
if (cb->uuid_filter) {
|
||||||
/* 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
|
||||||
@ -848,6 +860,8 @@ int
|
|||||||
virObjectEventStateRegisterID(virConnectPtr conn,
|
virObjectEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
unsigned char *uuid,
|
unsigned char *uuid,
|
||||||
|
virObjectEventCallbackFilter filter,
|
||||||
|
void *filter_opaque,
|
||||||
virClassPtr klass,
|
virClassPtr klass,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectObjectEventGenericCallback cb,
|
virConnectObjectEventGenericCallback cb,
|
||||||
@ -872,7 +886,8 @@ virObjectEventStateRegisterID(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = virObjectEventCallbackListAddID(conn, state->callbacks,
|
ret = virObjectEventCallbackListAddID(conn, state->callbacks,
|
||||||
uuid, klass, eventID,
|
uuid, filter, filter_opaque,
|
||||||
|
klass, eventID,
|
||||||
cb, opaque, freecb,
|
cb, opaque, freecb,
|
||||||
callbackID, serverFilter);
|
callbackID, serverFilter);
|
||||||
|
|
||||||
|
@ -52,6 +52,20 @@ struct _virObjectEvent {
|
|||||||
virObjectEventDispatchFunc dispatch;
|
virObjectEventDispatchFunc dispatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
virObjectEventPtr event,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
virClassPtr
|
virClassPtr
|
||||||
virClassForObjectEvent(void);
|
virClassForObjectEvent(void);
|
||||||
|
|
||||||
@ -59,6 +73,8 @@ int
|
|||||||
virObjectEventStateRegisterID(virConnectPtr conn,
|
virObjectEventStateRegisterID(virConnectPtr conn,
|
||||||
virObjectEventStatePtr state,
|
virObjectEventStatePtr state,
|
||||||
unsigned char *uuid,
|
unsigned char *uuid,
|
||||||
|
virObjectEventCallbackFilter filter,
|
||||||
|
void *filter_opaque,
|
||||||
virClassPtr klass,
|
virClassPtr klass,
|
||||||
int eventID,
|
int eventID,
|
||||||
virConnectObjectEventGenericCallback cb,
|
virConnectObjectEventGenericCallback cb,
|
||||||
@ -66,8 +82,8 @@ virObjectEventStateRegisterID(virConnectPtr conn,
|
|||||||
virFreeCallback freecb,
|
virFreeCallback freecb,
|
||||||
int *callbackID,
|
int *callbackID,
|
||||||
bool remoteFilter)
|
bool remoteFilter)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6)
|
||||||
ATTRIBUTE_NONNULL(6);
|
ATTRIBUTE_NONNULL(8);
|
||||||
|
|
||||||
int
|
int
|
||||||
virObjectEventStateCallbackID(virConnectPtr conn,
|
virObjectEventStateCallbackID(virConnectPtr conn,
|
||||||
|
@ -3654,6 +3654,7 @@ libxlConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
|
|
||||||
if (virDomainEventStateRegister(conn,
|
if (virDomainEventStateRegister(conn,
|
||||||
driver->domainEventState,
|
driver->domainEventState,
|
||||||
|
virConnectDomainEventRegisterCheckACL,
|
||||||
callback, opaque, freecb) < 0)
|
callback, opaque, freecb) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -4259,6 +4260,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;
|
||||||
|
@ -1293,6 +1293,7 @@ lxcConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
|
|
||||||
if (virDomainEventStateRegister(conn,
|
if (virDomainEventStateRegister(conn,
|
||||||
driver->domainEventState,
|
driver->domainEventState,
|
||||||
|
virConnectDomainEventRegisterCheckACL,
|
||||||
callback, opaque, freecb) < 0)
|
callback, opaque, freecb) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -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;
|
||||||
|
@ -2310,6 +2310,7 @@ networkConnectNetworkEventRegisterAny(virConnectPtr conn,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virNetworkEventStateRegisterID(conn, driver->networkEventState,
|
if (virNetworkEventStateRegisterID(conn, driver->networkEventState,
|
||||||
|
virConnectNetworkEventRegisterAnyCheckACL,
|
||||||
net, eventID, callback,
|
net, eventID, callback,
|
||||||
opaque, freecb, &ret) < 0)
|
opaque, freecb, &ret) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -9959,6 +9959,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;
|
||||||
|
|
||||||
@ -10007,6 +10008,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;
|
||||||
|
@ -4427,7 +4427,7 @@ remoteConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
|
|
||||||
remoteDriverLock(priv);
|
remoteDriverLock(priv);
|
||||||
|
|
||||||
if ((count = virDomainEventStateRegister(conn, priv->eventState,
|
if ((count = virDomainEventStateRegister(conn, priv->eventState, NULL,
|
||||||
callback, opaque, freecb)) < 0)
|
callback, opaque, freecb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -5245,7 +5245,7 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn,
|
|||||||
|
|
||||||
remoteDriverLock(priv);
|
remoteDriverLock(priv);
|
||||||
|
|
||||||
if ((count = virDomainEventStateRegisterID(conn, priv->eventState,
|
if ((count = virDomainEventStateRegisterID(conn, priv->eventState, NULL,
|
||||||
dom, eventID,
|
dom, eventID,
|
||||||
callback, opaque, freecb,
|
callback, opaque, freecb,
|
||||||
&callbackID)) < 0)
|
&callbackID)) < 0)
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
@ -3642,7 +3642,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,
|
||||||
|
|
||||||
@ -4074,7 +4075,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,
|
||||||
|
|
||||||
@ -5045,7 +5047,8 @@ enum remote_procedure {
|
|||||||
/**
|
/**
|
||||||
* @generate: none
|
* @generate: none
|
||||||
* @priority: high
|
* @priority: high
|
||||||
* @acl: connect:read
|
* @acl: connect:search_networks
|
||||||
|
* @aclfilter: network:getattr
|
||||||
*/
|
*/
|
||||||
REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY = 313,
|
REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY = 313,
|
||||||
|
|
||||||
|
@ -6145,7 +6145,7 @@ testConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
testDriverLock(driver);
|
testDriverLock(driver);
|
||||||
if (virDomainEventStateRegister(conn, driver->eventState,
|
if (virDomainEventStateRegister(conn, driver->eventState, NULL,
|
||||||
callback, opaque, freecb) < 0)
|
callback, opaque, freecb) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
testDriverUnlock(driver);
|
testDriverUnlock(driver);
|
||||||
@ -6183,7 +6183,7 @@ testConnectDomainEventRegisterAny(virConnectPtr conn,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
testDriverLock(driver);
|
testDriverLock(driver);
|
||||||
if (virDomainEventStateRegisterID(conn, driver->eventState,
|
if (virDomainEventStateRegisterID(conn, driver->eventState, NULL,
|
||||||
dom, eventID,
|
dom, eventID,
|
||||||
callback, opaque, freecb, &ret) < 0)
|
callback, opaque, freecb, &ret) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -6221,7 +6221,7 @@ testConnectNetworkEventRegisterAny(virConnectPtr conn,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
testDriverLock(driver);
|
testDriverLock(driver);
|
||||||
if (virNetworkEventStateRegisterID(conn, driver->eventState,
|
if (virNetworkEventStateRegisterID(conn, driver->eventState, NULL,
|
||||||
net, eventID, callback,
|
net, eventID, callback,
|
||||||
opaque, freecb, &ret) < 0)
|
opaque, freecb, &ret) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -2618,6 +2618,7 @@ umlConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
umlDriverLock(driver);
|
umlDriverLock(driver);
|
||||||
if (virDomainEventStateRegister(conn,
|
if (virDomainEventStateRegister(conn,
|
||||||
driver->domainEventState,
|
driver->domainEventState,
|
||||||
|
virConnectDomainEventRegisterCheckACL,
|
||||||
callback, opaque, freecb) < 0)
|
callback, opaque, freecb) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
umlDriverUnlock(driver);
|
umlDriverUnlock(driver);
|
||||||
@ -2662,6 +2663,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;
|
||||||
|
@ -7328,7 +7328,7 @@ 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("virObjectEventStateRegister (ret = %d) (conn: %p, "
|
VIR_DEBUG("virObjectEventStateRegister (ret = %d) (conn: %p, "
|
||||||
"callback: %p, opaque: %p, "
|
"callback: %p, opaque: %p, "
|
||||||
@ -7425,7 +7425,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;
|
||||||
|
@ -2323,6 +2323,7 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (virDomainEventStateRegister(conn, priv->domainEvents,
|
if (virDomainEventStateRegister(conn, priv->domainEvents,
|
||||||
|
virConnectDomainEventRegisterCheckACL,
|
||||||
callback, opaque, freefunc) < 0)
|
callback, opaque, freefunc) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
@ -2382,6 +2383,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;
|
||||||
|
Loading…
Reference in New Issue
Block a user