static int virSecurityManagerCheckModel(virSecurityManagerPtr mgr, char *secmodel) { int ret = -1; size_t i; virSecurityManagerPtr *sec_managers = NULL; if (STREQ_NULLABLE(secmodel, "none")) return 0; if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) return -1; for (i = 0; sec_managers[i]; i++) { if (STREQ_NULLABLE(secmodel, sec_managers[i]->drv->name)) { ret = 0; goto cleanup; } } virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unable to find security driver for model %s"), secmodel); cleanup: VIR_FREE(sec_managers); return ret; }
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) { int rc = 0; size_t i; virSecurityManagerPtr* sec_managers = NULL; virSecurityLabelDefPtr seclabel; if (mgr == NULL || mgr->drv == NULL) return -1; if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) return -1; virObjectLock(mgr); for (i = 0; sec_managers[i]; i++) { seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name); if (seclabel == NULL) { rc = -1; goto cleanup; } if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) { if (sec_managers[i]->defaultConfined) { seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC; } else { seclabel->type = VIR_DOMAIN_SECLABEL_NONE; seclabel->norelabel = true; } } if ((seclabel->type == VIR_DOMAIN_SECLABEL_NONE) && sec_managers[i]->requireConfined) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Unconfined guests are not allowed on this host")); rc = -1; goto cleanup; } if (!sec_managers[i]->drv->domainGenSecurityLabel) { virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__); } else { rc += sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm); if (rc) goto cleanup; } } cleanup: virObjectUnlock(mgr); VIR_FREE(sec_managers); return rc; }
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) { int ret = -1; size_t i, j; virSecurityManagerPtr* sec_managers = NULL; virSecurityLabelDefPtr seclabel; bool generated = false; if (mgr == NULL || mgr->drv == NULL) return ret; if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) return ret; virObjectLock(mgr); for (i = 0; i < vm->nseclabels; i++) { if (!vm->seclabels[i]->model) continue; for (j = 0; sec_managers[j]; j++) if (STREQ(vm->seclabels[i]->model, sec_managers[j]->drv->name)) break; if (!sec_managers[j]) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unable to find security driver for label %s"), vm->seclabels[i]->model); goto cleanup; } } for (i = 0; sec_managers[i]; i++) { generated = false; seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name); if (!seclabel) { if (!(seclabel = virSecurityLabelDefNew(sec_managers[i]->drv->name))) goto cleanup; generated = seclabel->implicit = true; } if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) { if (sec_managers[i]->defaultConfined) { seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC; } else { seclabel->type = VIR_DOMAIN_SECLABEL_NONE; seclabel->norelabel = true; } } if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) { if (sec_managers[i]->requireConfined) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Unconfined guests are not allowed on this host")); goto cleanup; } else if (vm->nseclabels && generated) { VIR_DEBUG("Skipping auto generated seclabel of type none"); virSecurityLabelDefFree(seclabel); seclabel = NULL; continue; } } if (!sec_managers[i]->drv->domainGenSecurityLabel) { virReportUnsupportedError(); virSecurityLabelDefFree(seclabel); seclabel = NULL; } else { /* The seclabel must be added to @vm prior calling domainGenSecurityLabel * which may require seclabel to be presented already */ if (generated && VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0) goto cleanup; if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) { if (VIR_DELETE_ELEMENT(vm->seclabels, vm->nseclabels -1, vm->nseclabels) < 0) vm->nseclabels--; goto cleanup; } seclabel = NULL; } } ret = 0; cleanup: virObjectUnlock(mgr); if (generated) virSecurityLabelDefFree(seclabel); VIR_FREE(sec_managers); return ret; }
virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) { size_t i, j; virCapsPtr caps; virSecurityManagerPtr *sec_managers = NULL; /* Security driver data */ const char *doi, *model, *lbl, *type; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); const int virtTypes[] = {VIR_DOMAIN_VIRT_KVM, VIR_DOMAIN_VIRT_QEMU,}; /* Basic host arch / guest machine capabilities */ if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) goto error; if (virGetHostUUID(caps->host.host_uuid)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get the host uuid")); goto error; } /* access sec drivers and create a sec model for each one */ if (!(sec_managers = virSecurityManagerGetNested(driver->securityManager))) goto error; /* calculate length */ for (i = 0; sec_managers[i]; i++) ; caps->host.nsecModels = i; if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0) goto error; for (i = 0; sec_managers[i]; i++) { virCapsHostSecModelPtr sm = &caps->host.secModels[i]; doi = virSecurityManagerGetDOI(sec_managers[i]); model = virSecurityManagerGetModel(sec_managers[i]); if (VIR_STRDUP(sm->model, model) < 0 || VIR_STRDUP(sm->doi, doi) < 0) goto error; for (j = 0; j < ARRAY_CARDINALITY(virtTypes); j++) { lbl = virSecurityManagerGetBaseLabel(sec_managers[i], virtTypes[j]); type = virDomainVirtTypeToString(virtTypes[j]); if (lbl && virCapabilitiesHostSecModelAddBaseLabel(sm, type, lbl) < 0) goto error; } VIR_DEBUG("Initialized caps for security driver \"%s\" with " "DOI \"%s\"", model, doi); } VIR_FREE(sec_managers); virObjectUnref(cfg); return caps; error: VIR_FREE(sec_managers); virObjectUnref(caps); virObjectUnref(cfg); return NULL; }