From 323049a089281e1165b38e735e255e1d231bbfc7 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 26 Jun 2013 18:47:48 +0100 Subject: [PATCH] Add access control filtering of storage objects Ensure that all APIs which list storage objects filter them against the access control system. Signed-off-by: Daniel P. Berrange --- src/conf/storage_conf.c | 12 ++++--- src/conf/storage_conf.h | 11 ++++--- src/libvirt_private.syms | 2 +- src/storage/storage_driver.c | 62 ++++++++++++++++++++++++------------ src/test/test_driver.c | 3 +- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 288e265e4a..2539c45256 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -2203,10 +2203,11 @@ virStoragePoolMatch(virStoragePoolObjPtr poolobj, #undef MATCH int -virStoragePoolList(virConnectPtr conn, - virStoragePoolObjList poolobjs, - virStoragePoolPtr **pools, - unsigned int flags) +virStoragePoolObjListExport(virConnectPtr conn, + virStoragePoolObjList poolobjs, + virStoragePoolPtr **pools, + virStoragePoolObjListFilter filter, + unsigned int flags) { virStoragePoolPtr *tmp_pools = NULL; virStoragePoolPtr pool = NULL; @@ -2224,7 +2225,8 @@ virStoragePoolList(virConnectPtr conn, for (i = 0; i < poolobjs.count; i++) { virStoragePoolObjPtr poolobj = poolobjs.objs[i]; virStoragePoolObjLock(poolobj); - if (virStoragePoolMatch(poolobj, flags)) { + if ((!filter || filter(conn, poolobj->def)) && + virStoragePoolMatch(poolobj, flags)) { if (pools) { if (!(pool = virGetStoragePool(conn, poolobj->def->name, diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 3af59df48c..c183427b71 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -357,6 +357,8 @@ struct _virStoragePoolSourceList { virStoragePoolSourcePtr sources; }; +typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn, + virStoragePoolDefPtr def); static inline int virStoragePoolObjIsActive(virStoragePoolObjPtr pool) @@ -570,9 +572,10 @@ VIR_ENUM_DECL(virStoragePartedFsType) VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART | \ VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE) -int virStoragePoolList(virConnectPtr conn, - virStoragePoolObjList poolobjs, - virStoragePoolPtr **pools, - unsigned int flags); +int virStoragePoolObjListExport(virConnectPtr conn, + virStoragePoolObjList poolobjs, + virStoragePoolPtr **pools, + virStoragePoolObjListFilter filter, + unsigned int flags); #endif /* __VIR_STORAGE_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3bc9da01b4..0881af43ad 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -650,7 +650,6 @@ virStoragePoolDefParseString; virStoragePoolFormatDiskTypeToString; virStoragePoolFormatFileSystemNetTypeToString; virStoragePoolFormatFileSystemTypeToString; -virStoragePoolList; virStoragePoolLoadAllConfigs; virStoragePoolObjAssignDef; virStoragePoolObjClearVols; @@ -658,6 +657,7 @@ virStoragePoolObjDeleteDef; virStoragePoolObjFindByName; virStoragePoolObjFindByUUID; virStoragePoolObjIsDuplicate; +virStoragePoolObjListExport; virStoragePoolObjListFree; virStoragePoolObjLock; virStoragePoolObjRemove; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index cc8eaa9838..02f7b69893 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -348,10 +348,12 @@ storageConnectNumOfStoragePools(virConnectPtr conn) { storageDriverLock(driver); for (i = 0; i < driver->pools.count; i++) { - virStoragePoolObjLock(driver->pools.objs[i]); - if (virStoragePoolObjIsActive(driver->pools.objs[i])) + virStoragePoolObjPtr obj = driver->pools.objs[i]; + virStoragePoolObjLock(obj); + if (virConnectNumOfStoragePoolsCheckACL(conn, obj->def) && + virStoragePoolObjIsActive(obj)) nactive++; - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjUnlock(obj); } storageDriverUnlock(driver); @@ -370,15 +372,17 @@ storageConnectListStoragePools(virConnectPtr conn, storageDriverLock(driver); for (i = 0; i < driver->pools.count && got < nnames; i++) { - virStoragePoolObjLock(driver->pools.objs[i]); - if (virStoragePoolObjIsActive(driver->pools.objs[i])) { - if (VIR_STRDUP(names[got], driver->pools.objs[i]->def->name) < 0) { - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjPtr obj = driver->pools.objs[i]; + virStoragePoolObjLock(obj); + if (virConnectListStoragePoolsCheckACL(conn, obj->def) && + virStoragePoolObjIsActive(obj)) { + if (VIR_STRDUP(names[got], obj->def->name) < 0) { + virStoragePoolObjUnlock(obj); goto cleanup; } got++; } - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjUnlock(obj); } storageDriverUnlock(driver); return got; @@ -401,10 +405,12 @@ storageConnectNumOfDefinedStoragePools(virConnectPtr conn) { storageDriverLock(driver); for (i = 0; i < driver->pools.count; i++) { - virStoragePoolObjLock(driver->pools.objs[i]); - if (!virStoragePoolObjIsActive(driver->pools.objs[i])) + virStoragePoolObjPtr obj = driver->pools.objs[i]; + virStoragePoolObjLock(obj); + if (virConnectNumOfDefinedStoragePoolsCheckACL(conn, obj->def) && + !virStoragePoolObjIsActive(obj)) nactive++; - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjUnlock(obj); } storageDriverUnlock(driver); @@ -423,15 +429,17 @@ storageConnectListDefinedStoragePools(virConnectPtr conn, storageDriverLock(driver); for (i = 0; i < driver->pools.count && got < nnames; i++) { - virStoragePoolObjLock(driver->pools.objs[i]); - if (!virStoragePoolObjIsActive(driver->pools.objs[i])) { - if (VIR_STRDUP(names[got], driver->pools.objs[i]->def->name) < 0) { - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjPtr obj = driver->pools.objs[i]; + virStoragePoolObjLock(obj); + if (virConnectListDefinedStoragePoolsCheckACL(conn, obj->def) && + !virStoragePoolObjIsActive(obj)) { + if (VIR_STRDUP(names[got], obj->def->name) < 0) { + virStoragePoolObjUnlock(obj); goto cleanup; } got++; } - virStoragePoolObjUnlock(driver->pools.objs[i]); + virStoragePoolObjUnlock(obj); } storageDriverUnlock(driver); return got; @@ -1152,7 +1160,7 @@ static int storagePoolNumOfVolumes(virStoragePoolPtr obj) { virStorageDriverStatePtr driver = obj->conn->storagePrivateData; virStoragePoolObjPtr pool; - int ret = -1; + int ret = -1, i; storageDriverLock(driver); pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); @@ -1172,7 +1180,12 @@ storagePoolNumOfVolumes(virStoragePoolPtr obj) { _("storage pool '%s' is not active"), pool->def->name); goto cleanup; } - ret = pool->volumes.count; + ret = 0; + for (i = 0; i < pool->volumes.count; i++) { + if (virStoragePoolNumOfVolumesCheckACL(obj->conn, pool->def, + pool->volumes.objs[i])) + ret++; + } cleanup: if (pool) @@ -1210,6 +1223,9 @@ storagePoolListVolumes(virStoragePoolPtr obj, } for (i = 0; i < pool->volumes.count && n < maxnames; i++) { + if (!virStoragePoolListVolumesCheckACL(obj->conn, pool->def, + pool->volumes.objs[i])) + continue; if (VIR_STRDUP(names[n++], pool->volumes.objs[i]->name) < 0) goto cleanup; } @@ -1268,11 +1284,14 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, } if (VIR_ALLOC_N(tmp_vols, obj->volumes.count + 1) < 0) { - virReportOOMError(); - goto cleanup; + virReportOOMError(); + goto cleanup; } for (i = 0; i < obj->volumes.count; i++) { + if (!virStoragePoolListAllVolumesCheckACL(pool->conn, obj->def, + obj->volumes.objs[i])) + continue; if (!(vol = virGetStorageVol(pool->conn, obj->def->name, obj->volumes.objs[i]->name, obj->volumes.objs[i]->key, @@ -2511,7 +2530,8 @@ storageConnectListAllStoragePools(virConnectPtr conn, goto cleanup; storageDriverLock(driver); - ret = virStoragePoolList(conn, driver->pools, pools, flags); + ret = virStoragePoolObjListExport(conn, driver->pools, pools, + virConnectListAllStoragePoolsCheckACL, flags); storageDriverUnlock(driver); cleanup: diff --git a/src/test/test_driver.c b/src/test/test_driver.c index d4c339e3cb..80a84d5114 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -4052,7 +4052,8 @@ testConnectListAllStoragePools(virConnectPtr conn, virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1); testDriverLock(privconn); - ret = virStoragePoolList(conn, privconn->pools, pools, flags); + ret = virStoragePoolObjListExport(conn, privconn->pools, pools, + NULL, flags); testDriverUnlock(privconn); return ret;