qemuSecurityInit(struct qemud_driver *driver)
{
char **names;
- char *primary;
- virSecurityManagerPtr mgr, nested, stack = NULL;
-
- if (driver->securityDriverNames == NULL)
- primary = NULL;
- else
+ char *primary = NULL;
+ virSecurityManagerPtr mgr = NULL;
+ virSecurityManagerPtr nested = NULL;
+ virSecurityManagerPtr stack = NULL;
+ bool hasDAC = false;
+
+ /* set the name of the primary security driver */
+ if (driver->securityDriverNames)
primary = driver->securityDriverNames[0];
- /* Create primary driver */
- mgr = virSecurityManagerNew(primary,
- QEMU_DRIVER_NAME,
- driver->allowDiskFormatProbing,
- driver->securityDefaultConfined,
- driver->securityRequireConfined);
+ /* add primary security driver */
+ if ((primary == NULL && driver->privileged) ||
+ STREQ_NULLABLE(primary, "dac")) {
+ if (!driver->privileged) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("DAC security driver usable only when "
+ "running privileged (as root)"));
+ goto error;
+ }
+
+ mgr = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+ driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined,
+ driver->dynamicOwnership);
+ hasDAC = true;
+ } else {
+ mgr = virSecurityManagerNew(primary,
+ QEMU_DRIVER_NAME,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined);
+ }
+
if (!mgr)
goto error;
- /* If a DAC driver is required or additional drivers are provived, a stack
- * driver should be create to group them all */
- if (driver->privileged ||
+ /* We need a stack to group the security drivers if:
+ * - additional drivers are provived in configuration
+ * - the primary driver isn't DAC and we are running privileged
+ */
+ if ((driver->privileged && !hasDAC) ||
(driver->securityDriverNames && driver->securityDriverNames[1])) {
- stack = virSecurityManagerNewStack(mgr);
- if (!stack)
+ if (!(stack = virSecurityManagerNewStack(mgr)))
goto error;
mgr = stack;
}
- /* Loop through additional driver names and add a secudary driver to each
- * one */
+ /* Loop through additional driver names and add them as nested */
if (driver->securityDriverNames) {
names = driver->securityDriverNames + 1;
while (names && *names) {
if (STREQ("dac", *names)) {
/* A DAC driver has specific parameters */
+ if (!driver->privileged) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("DAC security driver usable only when "
+ "running privileged (as root)"));
+ goto error;
+ }
+
nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
driver->user,
driver->group,
driver->securityDefaultConfined,
driver->securityRequireConfined,
driver->dynamicOwnership);
+ hasDAC = true;
} else {
nested = virSecurityManagerNew(*names,
QEMU_DRIVER_NAME,
driver->securityDefaultConfined,
driver->securityRequireConfined);
}
- if (nested == NULL)
+
+ if (!nested)
goto error;
+
if (virSecurityManagerStackAddNested(stack, nested))
goto error;
+
+ nested = NULL;
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;
- }
+ if (driver->privileged && !hasDAC) {
+ if (!(nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+ driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined,
+ driver->dynamicOwnership)))
+ goto error;
+
+ if (virSecurityManagerStackAddNested(stack, nested))
+ goto error;
+
+ nested = NULL;
}
driver->securityManager = mgr;
error:
VIR_ERROR(_("Failed to initialize security drivers"));
virSecurityManagerFree(mgr);
+ virSecurityManagerFree(nested);
return -1;
}