libvirt/src/security.c

140 lines
3.3 KiB
C

/*
* 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 <jmorris@namei.org>
*
*/
#include <config.h>
#include <string.h>
#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;
}