/* * Copyright (C) 2008 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Authors: * James Morris * */ #include #include #include "virterror_internal.h" #include "security.h" #ifdef WITH_SECDRIVER_SELINUX #include "security_selinux.h" #endif static virSecurityDriverPtr security_drivers[] = { #ifdef WITH_SECDRIVER_SELINUX &virSELinuxSecurityDriver, #endif NULL }; int virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def) { unsigned int i; const virSecurityLabelDefPtr secdef = &def->seclabel; if (!secdef->model || STREQ(secdef->model, "none")) return 0; for (i = 0; security_drivers[i] != NULL ; i++) { if (STREQ(security_drivers[i]->name, secdef->model)) { return security_drivers[i]->domainSecurityVerify(conn, def); } } virSecurityReportError(conn, VIR_ERR_XML_ERROR, _("invalid security model '%s'"), secdef->model); return -1; } int virSecurityDriverStartup(virSecurityDriverPtr *drv, const char *name) { unsigned int i; if (name && STREQ(name, "none")) return -2; for (i = 0; security_drivers[i] != NULL ; i++) { virSecurityDriverPtr tmp = security_drivers[i]; if (name && STRNEQ(tmp->name, name)) continue; switch (tmp->probe()) { case SECURITY_DRIVER_ENABLE: virSecurityDriverInit(tmp); if (tmp->open(NULL, tmp) == -1) { return -1; } else { *drv = tmp; return 0; } break; case SECURITY_DRIVER_DISABLE: break; default: return -1; } } return -2; } void virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...) { va_list args; char errorMessage[1024]; if (fmt) { va_start(args, fmt); vsnprintf(errorMessage, sizeof(errorMessage) - 1, fmt, args); va_end(args); } else errorMessage[0] = '\0'; virRaiseError(conn, NULL, NULL, VIR_FROM_SECURITY, code, VIR_ERR_ERROR, NULL, NULL, NULL, -1, -1, "%s", errorMessage); } /* * Helpers */ void virSecurityDriverInit(virSecurityDriverPtr drv) { memset(&drv->_private, 0, sizeof drv->_private); } int virSecurityDriverSetDOI(virConnectPtr conn, virSecurityDriverPtr drv, const char *doi) { if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) { virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: DOI \'%s\' is " "longer than the maximum allowed length of %d"), __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1); return -1; } strcpy(drv->_private.doi, doi); return 0; } const char * virSecurityDriverGetDOI(virSecurityDriverPtr drv) { return drv->_private.doi; } const char * virSecurityDriverGetModel(virSecurityDriverPtr drv) { return drv->name; }