Support for multiple default security drivers in QEMU config

This patch updates the key "security_driver" in QEMU config to suport
both a sigle default driver or a list of default drivers. This ensures
that it will remain compatible with older versions of the config file.

Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
This commit is contained in:
Marcelo Cerri 2012-08-15 19:10:38 -03:00 committed by Michal Privoznik
parent a994ef2d1a
commit 6d6bff3a46
4 changed files with 119 additions and 28 deletions

View File

@ -144,7 +144,11 @@
# on the host, then the security driver will automatically disable
# itself. If you wish to disable QEMU SELinux security driver while
# leaving SELinux enabled for the host in general, then set this
# to 'none' instead.
# to 'none' instead. It's also possible to use more than one security
# driver at the same time, for this use a list of names separated by
# comma and delimited by square brackets. For example:
#
# security_driver = [ "selinux", "dac" ]
#
#security_driver = "selinux"

View File

@ -193,13 +193,45 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
p = virConfGetValue (conf, "security_driver");
CHECK_TYPE ("security_driver", VIR_CONF_STRING);
if (p && p->str) {
if (!(driver->securityDriverName = strdup(p->str))) {
if (p && p->type == VIR_CONF_LIST) {
size_t len;
virConfValuePtr pp;
/* Calc lenght and check items */
for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
if (pp->type != VIR_CONF_STRING) {
VIR_ERROR(_("security_driver be a list of strings"));
virConfFree(conf);
return -1;
}
}
if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0) {
virReportOOMError();
virConfFree(conf);
return -1;
}
for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
driver->securityDriverNames[i] = strdup(pp->str);
if (driver->securityDriverNames == NULL) {
virReportOOMError();
virConfFree(conf);
return -1;
}
}
driver->securityDriverNames[len] = NULL;
} else {
CHECK_TYPE ("security_driver", VIR_CONF_STRING);
if (p && p->str) {
if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
!(driver->securityDriverNames[0] = strdup(p->str))) {
virReportOOMError();
virConfFree(conf);
return -1;
}
driver->securityDriverNames[1] = NULL;
}
}
p = virConfGetValue (conf, "security_default_confined");

View File

@ -116,7 +116,7 @@ struct qemud_driver {
virDomainEventStatePtr domainEventState;
char *securityDriverName;
char **securityDriverNames;
bool securityDefaultConfined;
bool securityRequireConfined;
virSecurityManagerPtr securityManager;

View File

@ -248,36 +248,91 @@ qemuAutostartDomains(struct qemud_driver *driver)
static int
qemuSecurityInit(struct qemud_driver *driver)
{
virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
QEMU_DRIVER_NAME,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined);
char **names;
char *primary;
virSecurityManagerPtr mgr, nested, stack = NULL;
if (driver->securityDriverNames == NULL)
primary = NULL;
else
primary = driver->securityDriverNames[0];
/* Create primary driver */
mgr = virSecurityManagerNew(primary,
QEMU_DRIVER_NAME,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined);
if (!mgr)
goto error;
if (driver->privileged) {
virSecurityManagerPtr dac = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user,
driver->group,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
if (!dac)
/* If a DAC driver is required or additional drivers are provived, a stack
* driver should be create to group them all */
if (driver->privileged ||
(driver->securityDriverNames && driver->securityDriverNames[1])) {
stack = virSecurityManagerNewStack(mgr);
if (!stack)
goto error;
if (!(driver->securityManager = virSecurityManagerNewStack(mgr)) ||
!(virSecurityManagerStackAddNested(mgr, dac))) {
virSecurityManagerFree(dac);
goto error;
}
} else {
driver->securityManager = mgr;
mgr = stack;
}
/* Loop through additional driver names and add a secudary driver to each
* one */
if (driver->securityDriverNames) {
names = driver->securityDriverNames + 1;
while (names && *names) {
if (STREQ("dac", *names)) {
/* A DAC driver has specific parameters */
nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user,
driver->group,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
} else {
nested = virSecurityManagerNew(*names,
QEMU_DRIVER_NAME,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined);
}
if (nested == NULL)
goto error;
if (virSecurityManagerStackAddNested(stack, nested))
goto error;
names++;
}
}
if (driver->privileged) {
/* When a DAC driver is required, check if there is already one in the
* additional drivers */
names = driver->securityDriverNames;
while (names && *names) {
if (STREQ("dac", *names)) {
break;
}
names++;
}
/* If there is no DAC driver, create a new one and add it to the stack
* manager */
if (names == NULL || *names == NULL) {
nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user,
driver->group,
driver->allowDiskFormatProbing,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
if (nested == NULL)
goto error;
if (virSecurityManagerStackAddNested(stack, nested))
goto error;
}
}
driver->securityManager = mgr;
return 0;
error: