From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Inserts the minimal access control checks to the QEMU driver to protect usage of virDomainObjPtr objects. --- src/qemu/qemu_driver.c | 626 +++++++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_migration.c | 5 + 2 files changed, 605 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 751c3c7..ea090a6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1202,6 +1202,11 @@ static virDomainPtr qemudDomainLookupByID(virConnectPtr conn, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_GETATTR)) + goto cleanup; + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) dom->id = vm->def->id; @@ -1229,6 +1234,11 @@ static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_GETATTR)) + goto cleanup; + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) dom->id = vm->def->id; @@ -1254,6 +1264,11 @@ static virDomainPtr qemudDomainLookupByName(virConnectPtr conn, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_GETATTR)) + goto cleanup; + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) dom->id = vm->def->id; @@ -1267,72 +1282,90 @@ cleanup: static int qemuDomainIsActive(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; - virDomainObjPtr obj; + virDomainObjPtr vm; int ret = -1; qemuDriverLock(driver); - obj = virDomainFindByUUID(&driver->domains, dom->uuid); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); - if (!obj) { + if (!vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(dom->uuid, uuidstr); qemuReportError(VIR_ERR_NO_DOMAIN, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } - ret = virDomainObjIsActive(obj); + + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + + ret = virDomainObjIsActive(vm); cleanup: - if (obj) - virDomainObjUnlock(obj); + if (vm) + virDomainObjUnlock(vm); return ret; } static int qemuDomainIsPersistent(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; - virDomainObjPtr obj; + virDomainObjPtr vm; int ret = -1; qemuDriverLock(driver); - obj = virDomainFindByUUID(&driver->domains, dom->uuid); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); - if (!obj) { + if (!vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(dom->uuid, uuidstr); qemuReportError(VIR_ERR_NO_DOMAIN, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } - ret = obj->persistent; + + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + + ret = vm->persistent; cleanup: - if (obj) - virDomainObjUnlock(obj); + if (vm) + virDomainObjUnlock(vm); return ret; } static int qemuDomainIsUpdated(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; - virDomainObjPtr obj; + virDomainObjPtr vm; int ret = -1; qemuDriverLock(driver); - obj = virDomainFindByUUID(&driver->domains, dom->uuid); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); - if (!obj) { + if (!vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(dom->uuid, uuidstr); qemuReportError(VIR_ERR_NO_DOMAIN, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } - ret = obj->updated; + + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + + ret = vm->updated; cleanup: - if (obj) - virDomainObjUnlock(obj); + if (vm) + virDomainObjUnlock(vm); return ret; } @@ -1354,10 +1387,12 @@ cleanup: static int qemudListDomains(virConnectPtr conn, int *ids, int nids) { struct qemud_driver *driver = conn->privateData; - int n; + int n = -1; qemuDriverLock(driver); - n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids); + if (virAccessManagerCheckConnect(driver->accessManager, + VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)) + n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids); qemuDriverUnlock(driver); return n; @@ -1365,10 +1400,12 @@ static int qemudListDomains(virConnectPtr conn, int *ids, int nids) { static int qemudNumDomains(virConnectPtr conn) { struct qemud_driver *driver = conn->privateData; - int n; + int n = -1; qemuDriverLock(driver); - n = virDomainObjListNumOfDomains(&driver->domains, 1); + if (virAccessManagerCheckConnect(driver->accessManager, + VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)) + n = virDomainObjListNumOfDomains(&driver->domains, 1); qemuDriverUnlock(driver); return n; @@ -1401,6 +1438,15 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (virSecurityManagerVerify(driver->securityManager, def) < 0) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_START)) + goto cleanup; + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; @@ -1491,6 +1537,11 @@ static int qemudDomainSuspend(virDomainPtr dom) { goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SUSPEND)) + goto cleanup; + priv = vm->privateData; if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) { @@ -1553,6 +1604,11 @@ static int qemudDomainResume(virDomainPtr dom) { goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SUSPEND)) + goto cleanup; + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -1613,6 +1669,11 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SHUTDOWN)) + goto cleanup; + priv = vm->privateData; if ((flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT) || @@ -1694,6 +1755,11 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_REBOOT)) + goto cleanup; + priv = vm->privateData; if ((flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT) || @@ -1785,6 +1851,11 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_RESET)) + goto cleanup; + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -1847,6 +1918,11 @@ qemuDomainDestroyFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_STOP)) + goto cleanup; + priv = vm->privateData; qemuDomainSetFakeReboot(driver, vm, false); @@ -1931,6 +2007,11 @@ static char *qemudDomainGetOSType(virDomainPtr dom) { goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!(type = strdup(vm->def->os.type))) virReportOOMError(); @@ -1960,6 +2041,11 @@ qemuDomainGetMaxMemory(virDomainPtr dom) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + ret = vm->def->mem.max_balloon; cleanup: @@ -1991,6 +2077,17 @@ static int qemudDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -2093,6 +2190,11 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_INJECT_NMI)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -2170,6 +2272,11 @@ static int qemuDomainSendKey(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SEND_KEY)) + goto cleanup; + priv = vm->privateData; if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) @@ -2216,6 +2323,11 @@ static int qemudDomainGetInfo(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + info->state = virDomainObjGetState(vm, NULL); if (!virDomainObjIsActive(vm)) { @@ -2303,6 +2415,11 @@ qemuDomainGetState(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + *state = virDomainObjGetState(vm, reason); ret = 0; @@ -2336,6 +2453,11 @@ qemuDomainGetControlInfo(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -2840,6 +2962,15 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_STOP)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_HIBERNATE)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -2899,6 +3030,15 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_STOP)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_HIBERNATE)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -2950,6 +3090,11 @@ qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + name = qemuDomainManagedSavePath(driver, vm); if (name == NULL) goto cleanup; @@ -2984,6 +3129,11 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + name = qemuDomainManagedSavePath(driver, vm); if (name == NULL) goto cleanup; @@ -3110,6 +3260,21 @@ static int qemudDomainCoreDump(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_CORE_DUMP)) + goto cleanup; + if (!(flags & VIR_DUMP_LIVE) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SUSPEND)) + goto cleanup; + if ((flags & VIR_DUMP_CRASH) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_STOP)) + goto cleanup; + if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, QEMU_ASYNC_JOB_DUMP) < 0) goto cleanup; @@ -3220,6 +3385,11 @@ qemuDomainScreenshot(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SCREENSHOT)) + goto cleanup; + priv = vm->privateData; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) @@ -3446,6 +3616,16 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -3564,6 +3744,16 @@ qemudDomainPinVcpuFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -3697,6 +3887,11 @@ qemudDomainGetVcpuPinInfo(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &targetDef) < 0) goto cleanup; @@ -3776,6 +3971,11 @@ qemudDomainGetVcpus(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -3867,6 +4067,11 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &def) < 0) goto cleanup; @@ -3908,6 +4113,11 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainVirtTypeToString(vm->def->virtType)) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("unknown virt type in domain definition '%d'"), @@ -4281,6 +4491,11 @@ qemuDomainRestoreFlags(virConnectPtr conn, if (fd < 0) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_START)) + goto cleanup; + if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0) goto cleanup; @@ -4345,6 +4560,11 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, if (fd < 0) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + ret = qemuDomainDefFormatXML(driver, def, flags); cleanup: @@ -4387,6 +4607,15 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + xml = qemuDomainDefFormatXML(driver, def, (VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE)); if (!xml) @@ -4501,6 +4730,16 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if ((flags & VIR_DOMAIN_XML_SECURE) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ_SECURE)) + goto cleanup; + /* Refresh current memory based on balloon info if supported */ if ((vm->def->memballoon != NULL) && (vm->def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) && @@ -4717,20 +4956,24 @@ cleanup: static int qemudListDefinedDomains(virConnectPtr conn, char **const names, int nnames) { struct qemud_driver *driver = conn->privateData; - int n; + int n = -1; qemuDriverLock(driver); - n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames); + if (virAccessManagerCheckConnect(driver->accessManager, + VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)) + n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames); qemuDriverUnlock(driver); return n; } static int qemudNumDefinedDomains(virConnectPtr conn) { struct qemud_driver *driver = conn->privateData; - int n; + int n = -1; qemuDriverLock(driver); - n = virDomainObjListNumOfDomains(&driver->domains, 0); + if (virAccessManagerCheckConnect(driver->accessManager, + VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)) + n = virDomainObjListNumOfDomains(&driver->domains, 0); qemuDriverUnlock(driver); return n; @@ -4832,6 +5075,11 @@ qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags) goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_START)) + goto cleanup; + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -4987,6 +5235,15 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { if (virSecurityManagerVerify(driver->securityManager, def) < 0) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0) goto cleanup; @@ -5057,6 +5314,11 @@ qemuDomainUndefineFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_DELETE)) + goto cleanup; + if (!vm->persistent) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cannot undefine transient domain")); @@ -5708,6 +5970,17 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -5879,6 +6152,11 @@ static int qemudDomainGetAutostart(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + *autostart = vm->autostart; ret = 0; @@ -5906,6 +6184,15 @@ static int qemudDomainSetAutostart(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (!vm->persistent) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cannot set autostart for transient domain")); @@ -5996,8 +6283,22 @@ static char *qemuGetSchedulerType(virDomainPtr dom, struct qemud_driver *driver = dom->conn->privateData; char *ret = NULL; int rc; + virDomainObjPtr vm = NULL; qemuDriverLock(driver); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + + if (vm == NULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("No such domain %s"), dom->uuid); + goto cleanup; + } + + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cgroup CPU controller is not mounted")); @@ -6019,6 +6320,8 @@ static char *qemuGetSchedulerType(virDomainPtr dom, virReportOOMError(); cleanup: + if (vm) + virDomainObjUnlock(vm); qemuDriverUnlock(driver); return ret; } @@ -6183,6 +6486,16 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -6337,6 +6650,11 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if ((*nparams) == 0) { /* Current number of blkio parameters supported by cgroups */ *nparams = QEMU_NB_BLKIO_PARAM; @@ -6525,6 +6843,16 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -6632,6 +6960,11 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -6794,6 +7127,16 @@ qemuDomainSetNumaParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -6957,6 +7300,11 @@ qemuDomainGetNumaParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7178,6 +7526,16 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &vmdef) < 0) goto cleanup; @@ -7392,6 +7750,11 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -7524,6 +7887,11 @@ qemuDomainBlockResize(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + priv = vm->privateData; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) @@ -7594,6 +7962,11 @@ qemuDomainBlockStats(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -7679,6 +8052,11 @@ qemuDomainBlockStatsFlags(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -7848,6 +8226,11 @@ qemudDomainInterfaceStats (virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -7929,6 +8312,16 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -8092,6 +8485,11 @@ qemuDomainGetInterfaceParameters(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (virDomainLiveConfigHelperMethod(driver->caps, vm, &flags, &persistentDef) < 0) goto cleanup; @@ -8206,6 +8604,11 @@ qemudDomainMemoryStats (virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) goto cleanup; @@ -8267,6 +8670,11 @@ qemudDomainBlockPeek (virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ_BLOCK)) + goto cleanup; + if (!path || path[0] == '\0') { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("NULL or empty path")); @@ -8335,6 +8743,11 @@ qemudDomainMemoryPeek (virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ_MEM)) + goto cleanup; + if (flags != VIR_MEMORY_VIRTUAL && flags != VIR_MEMORY_PHYSICAL) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL")); @@ -8432,6 +8845,11 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!path || path[0] == '\0') { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("NULL or empty path")); @@ -8795,6 +9213,11 @@ qemudDomainMigratePerform (virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + if (flags & VIR_MIGRATE_PEER2PEER) { dconnuri = uri; uri = NULL; @@ -8841,6 +9264,11 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + /* Do not use cookies in v2 protocol, since the cookie * length was not sufficiently large, causing failures * migrating between old & new libvirtd @@ -8885,6 +9313,11 @@ qemuDomainMigrateBegin3(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto cleanup; @@ -9072,6 +9505,11 @@ qemuDomainMigratePerform3(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin, dconnuri, uri, cookiein, cookieinlen, cookieout, cookieoutlen, @@ -9109,6 +9547,11 @@ qemuDomainMigrateFinish3(virConnectPtr dconn, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + dom = qemuMigrationFinish(driver, dconn, vm, cookiein, cookieinlen, cookieout, cookieoutlen, @@ -9143,6 +9586,11 @@ qemuDomainMigrateConfirm3(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT)) goto cleanup; @@ -9384,6 +9832,11 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + priv = vm->privateData; if (virDomainObjIsActive(vm)) { @@ -9434,6 +9887,11 @@ static int qemuDomainAbortJob(virDomainPtr dom) { goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_ABORT) < 0) goto cleanup; @@ -9496,6 +9954,11 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, return -1; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) goto cleanup; @@ -9552,6 +10015,11 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, return -1; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + priv = vm->privateData; if (virDomainObjIsActive(vm)) { if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) @@ -9609,6 +10077,11 @@ qemuDomainMigrateGetMaxSpeed(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + priv = vm->privateData; *bandwidth = priv->migMaxBandwidth; ret = 0; @@ -10318,6 +10791,11 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SNAPSHOT)) + goto cleanup; + if (qemuProcessAutoDestroyActive(driver, vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is marked for auto destroy")); @@ -10567,6 +11045,11 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + n = virDomainSnapshotObjListGetNames(&vm->snapshots, names, nameslen, flags); @@ -10598,6 +11081,11 @@ static int qemuDomainSnapshotNum(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + /* All qemu snapshots have libvirt metadata, so * VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our * answer. */ @@ -10636,6 +11124,11 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -10676,6 +11169,11 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -10718,6 +11216,11 @@ static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -10753,6 +11256,11 @@ static int qemuDomainHasCurrentSnapshot(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + ret = (vm->current_snapshot != NULL); cleanup: @@ -10783,6 +11291,11 @@ qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -10826,6 +11339,11 @@ static virDomainSnapshotPtr qemuDomainSnapshotCurrent(virDomainPtr domain, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if (!vm->current_snapshot) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s", _("the domain does not have a current snapshot")); @@ -10861,6 +11379,11 @@ static char *qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -10931,6 +11454,11 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SNAPSHOT)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -11297,6 +11825,11 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SNAPSHOT)) + goto cleanup; + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name); if (!snap) { qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, @@ -11414,6 +11947,11 @@ static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -11473,6 +12011,11 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, &pidfile, &monConfig, &monJSON))) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_START)) + goto cleanup; + if (!monConfig) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("No monitor connection for pid %u"), pid_value); @@ -11567,6 +12110,11 @@ qemuDomainOpenConsole(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_OPEN_CONSOLE)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -11686,6 +12234,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } + + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -11862,6 +12416,11 @@ qemuDomainOpenGraphics(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_OPEN_GRAPHICS)) + goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); @@ -11957,6 +12516,16 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_WRITE)) + goto cleanup; + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_SAVE)) + goto cleanup; + device = qemuDiskPathToAlias(vm, disk, &idx); if (!device) { goto cleanup; @@ -12106,6 +12675,11 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, goto cleanup; } + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_READ)) + goto cleanup; + if ((*nparams) == 0) { /* Current number of parameters supported by QEMU Block I/O Throttling */ *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3a420be..3fab80d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1219,6 +1219,11 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; + if (!virAccessManagerCheckDomain(driver->accessManager, + vm->def, + VIR_ACCESS_PERM_DOMAIN_MIGRATE)) + goto cleanup; + if (!qemuMigrationIsAllowed(driver, NULL, def)) goto cleanup; -- 1.7.10 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list