diff --git a/src/access/genpolkit.pl b/src/access/genpolkit.pl index e074c90eb67af3c9a8cd4b666b0aa289d21213c9..f8f20caf6577eea41335ed3a3b64266ab59bb842 100755 --- a/src/access/genpolkit.pl +++ b/src/access/genpolkit.pl @@ -21,7 +21,7 @@ use strict; use warnings; my @objects = ( - "CONNECT", "DOMAIN", "INTERFACE", + "CONNECT", "DOMAIN", "INTERFACE", "NETWORK_PORT", "NETWORK","NODE_DEVICE", "NWFILTER_BINDING", "NWFILTER", "SECRET", "STORAGE_POOL", "STORAGE_VOL", ); diff --git a/src/access/viraccessdriver.h b/src/access/viraccessdriver.h index 9fe7428e0e4a7de358cddb57b103098fcc14ede9..363d75965cc37c5d057cd77f732e510a31df8039 100644 --- a/src/access/viraccessdriver.h +++ b/src/access/viraccessdriver.h @@ -38,6 +38,11 @@ typedef int (*virAccessDriverCheckNetworkDrv)(virAccessManagerPtr manager, const char *driverName, virNetworkDefPtr network, virAccessPermNetwork av); +typedef int (*virAccessDriverCheckNetworkPortDrv)(virAccessManagerPtr manager, + const char *driverName, + virNetworkDefPtr network, + virNetworkPortDefPtr port, + virAccessPermNetworkPort av); typedef int (*virAccessDriverCheckNodeDeviceDrv)(virAccessManagerPtr manager, const char *driverName, virNodeDeviceDefPtr nodedev, @@ -81,6 +86,7 @@ struct _virAccessDriver { virAccessDriverCheckDomainDrv checkDomain; virAccessDriverCheckInterfaceDrv checkInterface; virAccessDriverCheckNetworkDrv checkNetwork; + virAccessDriverCheckNetworkPortDrv checkNetworkPort; virAccessDriverCheckNodeDeviceDrv checkNodeDevice; virAccessDriverCheckNWFilterDrv checkNWFilter; virAccessDriverCheckNWFilterBindingDrv checkNWFilterBinding; diff --git a/src/access/viraccessdrivernop.c b/src/access/viraccessdrivernop.c index 98ef9206c587e721a9b355577a98e33ded1780b8..5e9d9db75996620ea2433f8e5121481659def669 100644 --- a/src/access/viraccessdrivernop.c +++ b/src/access/viraccessdrivernop.c @@ -57,6 +57,16 @@ virAccessDriverNopCheckNetwork(virAccessManagerPtr manager ATTRIBUTE_UNUSED, return 1; /* Allow */ } +static int +virAccessDriverNopCheckNetworkPort(virAccessManagerPtr manager ATTRIBUTE_UNUSED, + const char *driverName ATTRIBUTE_UNUSED, + virNetworkDefPtr network ATTRIBUTE_UNUSED, + virNetworkPortDefPtr port ATTRIBUTE_UNUSED, + virAccessPermNetworkPort perm ATTRIBUTE_UNUSED) +{ + return 1; /* Allow */ +} + static int virAccessDriverNopCheckNodeDevice(virAccessManagerPtr manager ATTRIBUTE_UNUSED, const char *driverName ATTRIBUTE_UNUSED, @@ -119,6 +129,7 @@ virAccessDriver accessDriverNop = { .checkDomain = virAccessDriverNopCheckDomain, .checkInterface = virAccessDriverNopCheckInterface, .checkNetwork = virAccessDriverNopCheckNetwork, + .checkNetworkPort = virAccessDriverNopCheckNetworkPort, .checkNodeDevice = virAccessDriverNopCheckNodeDevice, .checkNWFilter = virAccessDriverNopCheckNWFilter, .checkNWFilterBinding = virAccessDriverNopCheckNWFilterBinding, diff --git a/src/access/viraccessdriverpolkit.c b/src/access/viraccessdriverpolkit.c index 6954d74a150d18edc4b4f2b46cc1f7f8a67d18d9..b1473cd0a43e8e85cb46aef05ebc4e9563e3a0f8 100644 --- a/src/access/viraccessdriverpolkit.c +++ b/src/access/viraccessdriverpolkit.c @@ -237,6 +237,31 @@ virAccessDriverPolkitCheckNetwork(virAccessManagerPtr manager, attrs); } +static int +virAccessDriverPolkitCheckNetworkPort(virAccessManagerPtr manager, + const char *driverName, + virNetworkDefPtr network, + virNetworkPortDefPtr port, + virAccessPermNetworkPort perm) +{ + char uuidstr1[VIR_UUID_STRING_BUFLEN]; + char uuidstr2[VIR_UUID_STRING_BUFLEN]; + const char *attrs[] = { + "connect_driver", driverName, + "network_name", network->name, + "network_uuid", uuidstr1, + "port_uuid", uuidstr2, + NULL, + }; + virUUIDFormat(network->uuid, uuidstr1); + virUUIDFormat(port->uuid, uuidstr2); + + return virAccessDriverPolkitCheck(manager, + "network-port", + virAccessPermNetworkPortTypeToString(perm), + attrs); +} + static int virAccessDriverPolkitCheckNodeDevice(virAccessManagerPtr manager, const char *driverName, @@ -427,6 +452,7 @@ virAccessDriver accessDriverPolkit = { .checkDomain = virAccessDriverPolkitCheckDomain, .checkInterface = virAccessDriverPolkitCheckInterface, .checkNetwork = virAccessDriverPolkitCheckNetwork, + .checkNetworkPort = virAccessDriverPolkitCheckNetworkPort, .checkNodeDevice = virAccessDriverPolkitCheckNodeDevice, .checkNWFilter = virAccessDriverPolkitCheckNWFilter, .checkNWFilterBinding = virAccessDriverPolkitCheckNWFilterBinding, diff --git a/src/access/viraccessdriverstack.c b/src/access/viraccessdriverstack.c index 0ffc6abaf303d346dda7780deaf63c3f384afb9f..238caef1150468731839a2111ceaa0e80d6e7fa2 100644 --- a/src/access/viraccessdriverstack.c +++ b/src/access/viraccessdriverstack.c @@ -151,6 +151,30 @@ virAccessDriverStackCheckNetwork(virAccessManagerPtr manager, return ret; } +static int +virAccessDriverStackCheckNetworkPort(virAccessManagerPtr manager, + const char *driverName, + virNetworkDefPtr network, + virNetworkPortDefPtr port, + virAccessPermNetworkPort perm) +{ + virAccessDriverStackPrivatePtr priv = virAccessManagerGetPrivateData(manager); + int ret = 1; + size_t i; + + for (i = 0; i < priv->managersLen; i++) { + int rv; + /* We do not short-circuit on first denial - always check all drivers */ + rv = virAccessManagerCheckNetworkPort(priv->managers[i], driverName, network, port, perm); + if (rv == 0 && ret != -1) + ret = 0; + else if (rv < 0) + ret = -1; + } + + return ret; +} + static int virAccessDriverStackCheckNodeDevice(virAccessManagerPtr manager, const char *driverName, @@ -298,6 +322,7 @@ virAccessDriver accessDriverStack = { .checkDomain = virAccessDriverStackCheckDomain, .checkInterface = virAccessDriverStackCheckInterface, .checkNetwork = virAccessDriverStackCheckNetwork, + .checkNetworkPort = virAccessDriverStackCheckNetworkPort, .checkNodeDevice = virAccessDriverStackCheckNodeDevice, .checkNWFilter = virAccessDriverStackCheckNWFilter, .checkNWFilterBinding = virAccessDriverStackCheckNWFilterBinding, diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c index f5d62604cf99eb8fab4e425f5bfda912ae27898c..24d9713cfdf83131839aa73021ccab4f321a9b5a 100644 --- a/src/access/viraccessmanager.c +++ b/src/access/viraccessmanager.c @@ -268,6 +268,22 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager, return virAccessManagerSanitizeError(ret, driverName); } +int virAccessManagerCheckNetworkPort(virAccessManagerPtr manager, + const char *driverName, + virNetworkDefPtr network, + virNetworkPortDefPtr port, + virAccessPermNetworkPort perm) +{ + int ret = 0; + VIR_DEBUG("manager=%p(name=%s) driver=%s network=%p port=%p perm=%d", + manager, manager->drv->name, driverName, network, port, perm); + + if (manager->drv->checkNetworkPort) + ret = manager->drv->checkNetworkPort(manager, driverName, network, port, perm); + + return virAccessManagerSanitizeError(ret, driverName); +} + int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, const char *driverName, virNodeDeviceDefPtr nodedev, diff --git a/src/access/viraccessmanager.h b/src/access/viraccessmanager.h index 6da41b0823167ff45c2dd8285a6959e43c5452f4..2c02db4bf2b7227fba323c2f5d41713835fb408d 100644 --- a/src/access/viraccessmanager.h +++ b/src/access/viraccessmanager.h @@ -29,6 +29,7 @@ #include "conf/secret_conf.h" #include "conf/interface_conf.h" #include "conf/virnwfilterbindingdef.h" +#include "conf/virnetworkportdef.h" #include "access/viraccessperm.h" typedef struct _virAccessManager virAccessManager; @@ -65,6 +66,11 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager, const char *driverName, virNetworkDefPtr network, virAccessPermNetwork perm); +int virAccessManagerCheckNetworkPort(virAccessManagerPtr manager, + const char *driverName, + virNetworkDefPtr network, + virNetworkPortDefPtr port, + virAccessPermNetworkPort perm); int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, const char *driverName, virNodeDeviceDefPtr nodedev, diff --git a/src/access/viraccessperm.c b/src/access/viraccessperm.c index 67f751ef9c423fc55262a67224915a798a5fb50d..74993e9f29ecdbd4312fb3f39f52d828767530e0 100644 --- a/src/access/viraccessperm.c +++ b/src/access/viraccessperm.c @@ -57,6 +57,12 @@ VIR_ENUM_IMPL(virAccessPermNetwork, VIR_ACCESS_PERM_NETWORK_LAST, "getattr", "read", "write", "save", "delete", "start", "stop", + "search_ports", +); + +VIR_ENUM_IMPL(virAccessPermNetworkPort, + VIR_ACCESS_PERM_NETWORK_PORT_LAST, + "getattr", "read", "write", "create", "delete", ); VIR_ENUM_IMPL(virAccessPermNodeDevice, diff --git a/src/access/viraccessperm.h b/src/access/viraccessperm.h index 8b63d75cf7dcb36b123caa191b732b680a41246a..d4b9c69c1e1c1fe7d38a906da41bbc413b113850 100644 --- a/src/access/viraccessperm.h +++ b/src/access/viraccessperm.h @@ -404,6 +404,12 @@ typedef enum { */ VIR_ACCESS_PERM_NETWORK_START, + /** + * @desc: List network ports + * @message: Listing network ports requires authorization + */ + VIR_ACCESS_PERM_NETWORK_SEARCH_PORTS, + /** * @desc: Stop network * @message: Stopping network requires authorization @@ -413,6 +419,43 @@ typedef enum { VIR_ACCESS_PERM_NETWORK_LAST } virAccessPermNetwork; +typedef enum { + + /** + * @desc: Access network port + * @message: Accessing network port requires authorization + * @anonymous: 1 + */ + VIR_ACCESS_PERM_NETWORK_PORT_GETATTR, + + /** + * @desc: Read network port + * @message: Reading network port configuration requires authorization + * @anonymous: 1 + */ + VIR_ACCESS_PERM_NETWORK_PORT_READ, + + /** + * @desc: Read network port + * @message: Writing network port configuration requires authorization + */ + VIR_ACCESS_PERM_NETWORK_PORT_WRITE, + + /** + * @desc: Create network port + * @message: Creating network port configuration requires authorization + */ + VIR_ACCESS_PERM_NETWORK_PORT_CREATE, + + /** + * @desc: Delete network port + * @message: Deleting network port configuration requires authorization + */ + VIR_ACCESS_PERM_NETWORK_PORT_DELETE, + + VIR_ACCESS_PERM_NETWORK_PORT_LAST +} virAccessPermNetworkPort; + typedef enum { /** @@ -692,6 +735,7 @@ VIR_ENUM_DECL(virAccessPermConnect); VIR_ENUM_DECL(virAccessPermDomain); VIR_ENUM_DECL(virAccessPermInterface); VIR_ENUM_DECL(virAccessPermNetwork); +VIR_ENUM_DECL(virAccessPermNetworkPort); VIR_ENUM_DECL(virAccessPermNodeDevice); VIR_ENUM_DECL(virAccessPermNWFilter); VIR_ENUM_DECL(virAccessPermNWFilterBinding);