The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for
'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
---
po/POTFILES.in | 2 +-
src/Makefile.am | 12 +-
src/libvirt.c | 4 +
src/libvirt_private.syms | 34 ++-
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 167 ++++------
src/qemu/qemu_hotplug.c | 84 ++---
src/qemu/qemu_security_dac.c | 576 ------------------------------
src/qemu/qemu_security_dac.h | 22 --
src/qemu/qemu_security_stacked.c | 418 ----------------------
src/qemu/qemu_security_stacked.h | 22 --
src/security/security_apparmor.c | 152 ++++++---
src/security/security_apparmor.h | 2 +
src/security/security_dac.c | 713 ++++++++++++++++++++++++++++++++++++++
src/security/security_dac.h | 36 ++
src/security/security_driver.c | 125 ++-----
src/security/security_driver.h | 95 +++---
src/security/security_manager.c | 317 +++++++++++++++++
src/security/security_manager.h | 95 +++++
src/security/security_nop.c | 185 ++++++++++
src/security/security_nop.h | 27 ++
src/security/security_selinux.c | 145 +++++---
src/security/security_selinux.h | 2 +-
src/security/security_stack.c | 401 +++++++++++++++++++++
src/security/security_stack.h | 33 ++
25 files changed, 2207 insertions(+), 1468 deletions(-)
delete mode 100644 src/qemu/qemu_security_dac.c
delete mode 100644 src/qemu/qemu_security_dac.h
delete mode 100644 src/qemu/qemu_security_stacked.c
delete mode 100644 src/qemu/qemu_security_stacked.h
create mode 100644 src/security/security_dac.c
create mode 100644 src/security/security_dac.h
create mode 100644 src/security/security_manager.c
create mode 100644 src/security/security_manager.h
create mode 100644 src/security/security_nop.c
create mode 100644 src/security/security_nop.h
create mode 100644 src/security/security_stack.c
create mode 100644 src/security/security_stack.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3d7bc8b..3521ba6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -61,10 +61,10 @@ src/qemu/qemu_hotplug.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c
-src/qemu/qemu_security_dac.c
src/remote/remote_driver.c
src/secret/secret_driver.c
src/security/security_apparmor.c
+src/security/security_dac.c
src/security/security_driver.c
src/security/security_selinux.c
src/security/virt-aa-helper.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c13724a..f8b8434 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -288,11 +288,7 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_monitor_json.h \
qemu/qemu_driver.c qemu/qemu_driver.h \
qemu/qemu_bridge_filter.c \
- qemu/qemu_bridge_filter.h \
- qemu/qemu_security_stacked.h \
- qemu/qemu_security_stacked.c \
- qemu/qemu_security_dac.h \
- qemu/qemu_security_dac.c
+ qemu/qemu_bridge_filter.h
XENAPI_DRIVER_SOURCES = \
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
@@ -390,7 +386,11 @@ NWFILTER_DRIVER_SOURCES = \
# Security framework and drivers for various models
SECURITY_DRIVER_SOURCES = \
- security/security_driver.h security/security_driver.c
+ security/security_driver.h security/security_driver.c \
+ security/security_nop.h security/security_nop.c \
+ security/security_stack.h security/security_stack.c \
+ security/security_dac.h security/security_dac.c \
+ security/security_manager.h security/security_manager.c
SECURITY_DRIVER_SELINUX_SOURCES = \
security/security_selinux.h security/security_selinux.c
diff --git a/src/libvirt.c b/src/libvirt.c
index 89b37c5..a4789bc 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5642,6 +5642,8 @@ virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr
seclabel)
{
virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
virDispatchError(NULL);
@@ -5684,6 +5686,8 @@ error:
int
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
{
+ DEBUG("conn=%p secmodel=%p", conn, secmodel);
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
virDispatchError(NULL);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 19e581c..e9b8cb7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -701,13 +701,33 @@ virSecretDefParseFile;
virSecretDefParseString;
-# security.h
-virSecurityDriverGetDOI;
-virSecurityDriverGetModel;
-virSecurityDriverInit;
-virSecurityDriverSetDOI;
-virSecurityDriverStartup;
-virSecurityDriverVerify;
+# security_driver.h
+virSecurityDriverLookup;
+
+
+# security_manager.h
+virSecurityManagerClearSocketLabel;
+virSecurityManagerFree;
+virSecurityManagerGenLabel;
+virSecurityManagerGetDOI;
+virSecurityManagerGetModel;
+virSecurityManagerGetProcessLabel;
+virSecurityManagerNew;
+virSecurityManagerNewStack;
+virSecurityManagerNewDAC;
+virSecurityManagerReleaseLabel;
+virSecurityManagerReserveLabel;
+virSecurityManagerRestoreImageLabel;
+virSecurityManagerRestoreAllLabel;
+virSecurityManagerRestoreHostdevLabel;
+virSecurityManagerRestoreSavedStateLabel;
+virSecurityManagerSetAllLabel;
+virSecurityManagerSetImageLabel;
+virSecurityManagerSetHostdevLabel;
+virSecurityManagerSetProcessLabel;
+virSecurityManagerSetSavedStateLabel;
+virSecurityManagerSetSocketLabel;
+virSecurityManagerVerify;
# storage_conf.h
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 83ddedd..5a5748b 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -35,7 +35,7 @@
# include "domain_conf.h"
# include "domain_event.h"
# include "threads.h"
-# include "security/security_driver.h"
+# include "security/security_manager.h"
# include "cgroup.h"
# include "pci.h"
# include "cpu_conf.h"
@@ -114,9 +114,7 @@ struct qemud_driver {
int domainEventDispatching;
char *securityDriverName;
- virSecurityDriverPtr securityDriver;
- virSecurityDriverPtr securityPrimaryDriver;
- virSecurityDriverPtr securitySecondaryDriver;
+ virSecurityManagerPtr securityManager;
char *saveImageFormat;
char *dumpImageFormat;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..24e9162 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -73,8 +73,6 @@
#include "pci.h"
#include "hostusb.h"
#include "processinfo.h"
-#include "qemu_security_stacked.h"
-#include "qemu_security_dac.h"
#include "libvirt_internal.h"
#include "xml.h"
#include "cpu/cpu.h"
@@ -861,10 +859,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecuritySocketLabel &&
- driver->securityDriver->domainSetSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerSetSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to set security context for monitor for %s"),
vm->def->name);
goto error;
@@ -882,10 +877,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
if (priv->mon == NULL)
virDomainObjUnref(vm);
- if (driver->securityDriver &&
- driver->securityDriver->domainClearSecuritySocketLabel &&
- driver->securityDriver->domainClearSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerClearSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
vm->def->name);
goto error;
@@ -954,10 +946,7 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED,
void *opaq
goto error;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainReserveSecurityLabel &&
-
driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver,
- obj) < 0)
+ if (virSecurityManagerReserveLabel(driver->securityManager, obj) < 0)
goto error;
if (qemudVMFiltersInstantiate(conn, obj->def))
@@ -995,35 +984,34 @@ qemuReconnectDomains(virConnectPtr conn, struct qemud_driver
*driver)
static int
-qemudSecurityInit(struct qemud_driver *qemud_drv)
+qemuSecurityInit(struct qemud_driver *driver)
{
- int ret;
- virSecurityDriverPtr security_drv;
-
- qemuSecurityStackedSetDriver(qemud_drv);
- qemuSecurityDACSetDriver(qemud_drv);
+ virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
+
driver->allowDiskFormatProbing);
+ if (!mgr)
+ goto error;
- ret = virSecurityDriverStartup(&security_drv,
- qemud_drv->securityDriverName,
- qemud_drv->allowDiskFormatProbing);
- if (ret == -1) {
- VIR_ERROR0(_("Failed to start security driver"));
- return -1;
- }
+ if (driver->privileged) {
+ virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
+ driver->group,
+
driver->allowDiskFormatProbing,
+
driver->dynamicOwnership);
+ if (!dac)
+ goto error;
- /* No primary security driver wanted to be enabled: just setup
- * the DAC driver on its own */
- if (ret == -2) {
- qemud_drv->securityDriver = &qemuDACSecurityDriver;
- VIR_INFO0(_("No security driver available"));
+ if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
+ dac)))
+ goto error;
} else {
- qemud_drv->securityPrimaryDriver = security_drv;
- qemud_drv->securitySecondaryDriver = &qemuDACSecurityDriver;
- qemud_drv->securityDriver = &qemuStackedSecurityDriver;
- VIR_INFO("Initialized security driver %s", security_drv->name);
+ driver->securityManager = mgr;
}
return 0;
+
+error:
+ VIR_ERROR0("Failed to initialize security drivers");
+ virSecurityManagerFree(mgr);
+ return -1;
}
@@ -1057,21 +1045,20 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
}
/* Security driver data */
- if (driver->securityPrimaryDriver) {
- const char *doi, *model;
-
- doi = virSecurityDriverGetDOI(driver->securityPrimaryDriver);
- model = virSecurityDriverGetModel(driver->securityPrimaryDriver);
+ const char *doi, *model;
+ doi = virSecurityManagerGetDOI(driver->securityManager);
+ model = virSecurityManagerGetModel(driver->securityManager);
+ if (STRNEQ(model, "none")) {
if (!(caps->host.secModel.model = strdup(model)))
goto no_memory;
if (!(caps->host.secModel.doi = strdup(doi)))
goto no_memory;
-
- VIR_DEBUG("Initialized caps for security driver \"%s\" with
"
- "DOI \"%s\"", model, doi);
}
+ VIR_DEBUG("Initialized caps for security driver \"%s\" with "
+ "DOI \"%s\"", model, doi);
+
return caps;
no_memory:
@@ -1336,7 +1323,7 @@ qemudStartup(int privileged) {
}
VIR_FREE(driverConf);
- if (qemudSecurityInit(qemu_driver) < 0)
+ if (qemuSecurityInit(qemu_driver) < 0)
goto error;
if ((qemu_driver->caps = qemuCreateCapabilities(NULL,
@@ -1555,10 +1542,11 @@ qemudShutdown(void) {
VIR_FREE(qemu_driver->spicePassword);
VIR_FREE(qemu_driver->hugetlbfs_mount);
VIR_FREE(qemu_driver->hugepage_path);
- VIR_FREE(qemu_driver->securityDriverName);
VIR_FREE(qemu_driver->saveImageFormat);
VIR_FREE(qemu_driver->dumpImageFormat);
+ virSecurityManagerFree(qemu_driver->securityManager);
+
ebtablesContextFree(qemu_driver->ebtables);
if (qemu_driver->cgroupDeviceACL) {
@@ -2573,9 +2561,7 @@ static int qemudSecurityHook(void *data) {
if (qemudInitCpuAffinity(h->vm) < 0)
return -1;
- if (h->driver->securityDriver &&
- h->driver->securityDriver->domainSetSecurityProcessLabel &&
-
h->driver->securityDriver->domainSetSecurityProcessLabel(h->driver->securityDriver,
h->vm) < 0)
+ if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm)
< 0)
return -1;
return 0;
@@ -2660,22 +2646,16 @@ static int qemudStartVMDaemon(virConnectPtr conn,
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
DEBUG0("Generating domain security label (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainGenSecurityLabel) {
- ret =
driver->securityDriver->domainGenSecurityLabel(driver->securityDriver,
- vm);
- qemuDomainSecurityLabelAudit(vm, ret >= 0);
- if (ret < 0)
- goto cleanup;
+ if (virSecurityManagerGenLabel(driver->securityManager, vm) < 0) {
+ qemuDomainSecurityLabelAudit(vm, false);
+ goto cleanup;
}
+ qemuDomainSecurityLabelAudit(vm, true);
DEBUG0("Generating setting domain security labels (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityAllLabel &&
-
driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver,
- vm, stdin_path) < 0) {
+ if (virSecurityManagerSetAllLabel(driver->securityManager,
+ vm, stdin_path) < 0)
goto cleanup;
- }
/* Ensure no historical cgroup for this VM is lying around bogus
* settings */
@@ -3057,14 +3037,9 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver,
}
/* Reset Security Labels */
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityAllLabel)
-
driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver,
- vm, migrated);
- if (driver->securityDriver &&
- driver->securityDriver->domainReleaseSecurityLabel)
-
driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver,
- vm);
+ virSecurityManagerRestoreAllLabel(driver->securityManager,
+ vm, migrated);
+ virSecurityManagerReleaseLabel(driver->securityManager, vm);
/* Clear out dynamically assigned labels */
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
@@ -3568,7 +3543,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char
*xml,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
@@ -4471,10 +4446,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver,
virDomainPtr dom,
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
-
driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto endjob;
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
@@ -4507,10 +4480,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver,
virDomainPtr dom,
goto endjob;
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
-
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
if (cgroup != NULL) {
@@ -4552,10 +4523,8 @@ endjob:
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
-
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
}
@@ -4779,10 +4748,8 @@ static int doCoreDump(struct qemud_driver *driver,
goto cleanup;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
-
driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -4814,10 +4781,8 @@ static int doCoreDump(struct qemud_driver *driver,
if (ret < 0)
goto cleanup;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
-
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
cleanup:
@@ -5434,10 +5399,8 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom,
virSecurityLabelPtr sec
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
*/
if (virDomainObjIsActive(vm)) {
- if (driver->securityDriver &&
- driver->securityDriver->domainGetSecurityProcessLabel &&
-
driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver,
- vm, seclabel) < 0)
{
+ if (virSecurityManagerGetProcessLabel(driver->securityManager,
+ vm, seclabel) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to get security
label"));
goto cleanup;
@@ -5461,10 +5424,12 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn,
int ret = 0;
qemuDriverLock(driver);
- if (!driver->securityPrimaryDriver) {
- memset(secmodel, 0, sizeof (*secmodel));
+ memset(secmodel, 0, sizeof(*secmodel));
+
+ /* NULL indicates no driver, which we treat as
+ * success, but simply return no data in *secmodel */
+ if (driver->caps->host.secModel.model == NULL)
goto cleanup;
- }
p = driver->caps->host.secModel.model;
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
@@ -5840,10 +5805,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
ret = 0;
out:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
-
driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
return ret;
@@ -6372,7 +6335,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char
*xml) {
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 827bcaf..1dc036c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -83,10 +83,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
-
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
@@ -115,10 +113,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
if (ret < 0)
goto error;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, origdisk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, origdisk) < 0)
VIR_WARN("Unable to restore security label on ejected image %s",
origdisk->src);
VIR_FREE(origdisk->src);
@@ -134,10 +130,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
error:
VIR_FREE(driveAlias);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on new media %s",
disk->src);
return -1;
}
@@ -162,10 +156,8 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
-
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
@@ -232,10 +224,8 @@ error:
qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
VIR_WARN("Unable to release PCI address on %s", disk->src);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -375,10 +365,8 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
-
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
/* We should have an address already, so make sure */
@@ -464,10 +452,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -492,10 +478,8 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver
*driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
-
driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!disk->src) {
@@ -551,10 +535,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -979,10 +961,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityHostdevLabel &&
-
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
return -1;
switch (hostdev->source.subsys.type) {
@@ -1008,10 +988,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
return 0;
error:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
-
driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
return -1;
@@ -1183,10 +1161,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk)
< 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s",
dev->data.disk->src);
if (cgroup != NULL) {
@@ -1263,10 +1239,8 @@ int qemuDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
-
driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk)
< 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s",
dev->data.disk->src);
if (cgroup != NULL) {
@@ -1699,10 +1673,8 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
-
driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm,
dev->data.hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, dev->data.hostdev) < 0)
VIR_WARN0("Failed to restore host device labelling");
return ret;
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
deleted file mode 100644
index 6b6170a..0000000
--- a/src/qemu/qemu_security_dac.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_dac.h"
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-static struct qemud_driver *driver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityDACSetOwnership(const char *path, int uid, int gid)
-{
- VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'",
path, uid, gid);
-
- if (chown(path, uid, gid) < 0) {
- struct stat sb;
- int chown_errno = errno;
-
- if (stat(path, &sb) >= 0) {
- if (sb.st_uid == uid &&
- sb.st_gid == gid) {
- /* It's alright, there's nothing to change anyway. */
- return 0;
- }
- }
-
- if (chown_errno == EOPNOTSUPP) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not
supported by filesystem",
- uid, gid, path);
- } else if (chown_errno == EPERM) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not
permitted",
- uid, gid, path);
- } else if (chown_errno == EROFS) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not
possible on readonly filesystem",
- uid, gid, path);
- } else {
- virReportSystemError(chown_errno,
- _("unable to set user and group to '%d:%d'
on '%s'"),
- uid, gid, path);
- return -1;
- }
- }
- return 0;
-}
-
-static int
-qemuSecurityDACRestoreSecurityFileLabel(const char *path)
-{
- struct stat buf;
- int rc = -1;
- char *newpath = NULL;
-
- VIR_INFO("Restoring DAC user and group on '%s'", path);
-
- if (virFileResolveLink(path, &newpath) < 0) {
- virReportSystemError(errno,
- _("cannot resolve symlink %s"), path);
- goto err;
- }
-
- if (stat(newpath, &buf) != 0)
- goto err;
-
- /* XXX record previous ownership */
- rc = qemuSecurityDACSetOwnership(newpath, 0, 0);
-
-err:
- VIR_FREE(newpath);
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
- const char *path,
- size_t depth ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk)
-
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return virDomainDiskDefForeachPath(disk,
- driver->allowDiskFormatProbing,
- false,
- qemuSecurityDACSetSecurityFileLabel,
- NULL);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk,
- int migrated)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- /* Don't restore labels on readoly/shared disks, because
- * other VMs may still be accessing these
- * Alternatively we could iterate over all running
- * domains and try to figure out if it is in use, but
- * this would not work for clustered filesystems, since
- * we can't see running VMs using the file on other nodes
- * Safest bet is thus to skip the restore step.
- */
- if (disk->readonly || disk->shared)
- return 0;
-
- if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
- return 0;
-
- /* If we have a shared FS & doing migrated, we must not
- * change ownership, because that kills access on the
- * destination host which is sub-optimal for the guest
- * VM's I/O attempts :-)
- */
- if (migrated) {
- int rc = virStorageFileIsSharedFS(disk->src);
- if (rc < 0)
- return -1;
- if (rc == 1) {
- VIR_DEBUG("Skipping image label restore on %s because FS is
shared",
- disk->src);
- return 0;
- }
- }
-
- return qemuSecurityDACRestoreSecurityFileLabel(disk->src);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0);
-}
-
-
-static int
-qemuSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACSetSecurityUSBLabel, vm);
- usbFreeDevice(usb);
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACSetSecurityPCILabel, vm);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACRestoreSecurityUSBLabel, NULL);
- usbFreeDevice(usb);
-
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACRestoreSecurityPCILabel, NULL);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACSetChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACSetOwnership(dev->data.file.path, driver->user,
driver->group);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
- (virAsprintf(&out, "%s.out", dev->data.file.path) < 0))
{
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACSetOwnership(in, driver->user, driver->group) < 0)
||
- (qemuSecurityDACSetOwnership(out, driver->user, driver->group) <
0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-static int
-qemuSecurityDACRestoreChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0)
||
- (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACRestoreSecurityFileLabel(out) < 0) ||
- (qemuSecurityDACRestoreSecurityFileLabel(in) < 0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACRestoreChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- int migrated)
-{
- int i;
- int rc = 0;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- VIR_DEBUG("Restoring security label on %s migrated=%d",
- vm->def->name, migrated);
-
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACRestoreSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) <
0)
- rc = -1;
- }
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (qemuSecurityDACRestoreSecurityImageLabelInt(drv,
- vm,
- vm->def->disks[i],
- migrated) < 0)
- rc = -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- false,
- qemuSecurityDACRestoreChardevCallback,
- vm) < 0)
- rc = -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
- rc = -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACSetChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- const char *stdin_path ATTRIBUTE_UNUSED)
-{
- int i;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- /* XXX fixme - we need to recursively label the entriy tree :-( */
- if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
- continue;
- if (qemuSecurityDACSetSecurityImageLabel(drv,
- vm,
- vm->def->disks[i]) < 0)
- return -1;
- }
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACSetSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) < 0)
- return -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- true,
- qemuSecurityDACSetChardevCallback,
- vm) < 0)
- return -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACSetOwnership(vm->def->os.kernel,
- driver->user,
- driver->group) < 0)
- return -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACSetOwnership(vm->def->os.initrd,
- driver->user,
- driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-static int
-qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged)
- return 0;
-
- return qemuSecurityDACSetOwnership(savefile, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return qemuSecurityDACRestoreSecurityFileLabel(savefile);
-}
-
-
-static int
-qemuSecurityDACSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED)
-{
- DEBUG("Dropping privileges of VM to %d:%d", driver->user,
driver->group);
-
- if (!driver->privileged)
- return 0;
-
- if (virSetUIDGID(driver->user, driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-
-virSecurityDriver qemuDACSecurityDriver = {
- .name = "qemuDAC",
-
- .domainSetSecurityProcessLabel = qemuSecurityDACSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityDACSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityDACRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityDACSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityDACRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityDACSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityDACRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityDACSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityDACRestoreSavedStateLabel,
-};
diff --git a/src/qemu/qemu_security_dac.h b/src/qemu/qemu_security_dac.h
deleted file mode 100644
index a742f7a..0000000
--- a/src/qemu/qemu_security_dac.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_DAC
-# define __QEMU_SECURITY_DAC
-
-extern virSecurityDriver qemuDACSecurityDriver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/qemu/qemu_security_stacked.c b/src/qemu/qemu_security_stacked.c
deleted file mode 100644
index 432d095..0000000
--- a/src/qemu/qemu_security_stacked.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_stacked.h"
-
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-
-static struct qemud_driver *driver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityStackedVerify(virDomainDefPtr def)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSecurityVerify &&
- driver->securitySecondaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSecurityVerify &&
- driver->securityPrimaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainGenSecurityLabel &&
-
driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGenSecurityLabel &&
-
driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReleaseSecurityLabel &&
-
driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReleaseSecurityLabel &&
-
driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReserveSecurityLabel &&
-
driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReserveSecurityLabel &&
-
driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityImageLabel &&
-
driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityImageLabel &&
-
driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel
&&
-
driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) <
0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel &&
-
driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel &&
-
driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel &&
-
driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel
&&
-
driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) <
0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel
&&
-
driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) <
0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *stdin_path)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityAllLabel &&
-
driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver,
- vm, stdin_path) <
0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityAllLabel &&
-
driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver,
- vm, stdin_path) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int migrated)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
-
driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver,
- vm, migrated) <
0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
-
driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver,
- vm, migrated) <
0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSavedStateLabel &&
-
driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSavedStateLabel &&
-
driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSavedStateLabel &&
-
driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) <
0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSavedStateLabel &&
-
driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) <
0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityProcessLabel &&
-
driver->securitySecondaryDriver->domainSetSecurityProcessLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityProcessLabel &&
-
driver->securityPrimaryDriver->domainSetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-static int
-qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virSecurityLabelPtr seclabel)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGetSecurityProcessLabel &&
-
driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm,
- seclabel) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecuritySocketLabel &&
-
driver->securityPrimaryDriver->domainSetSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecuritySocketLabel &&
-
driver->securitySecondaryDriver->domainSetSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedClearSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainClearSecuritySocketLabel &&
-
driver->securitySecondaryDriver->domainClearSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainClearSecuritySocketLabel &&
-
driver->securityPrimaryDriver->domainClearSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-virSecurityDriver qemuStackedSecurityDriver = {
- .name = "qemuStacked",
- .domainSecurityVerify = qemuSecurityStackedVerify,
-
- .domainGenSecurityLabel = qemuSecurityStackedGenLabel,
- .domainReleaseSecurityLabel = qemuSecurityStackedReleaseLabel,
- .domainReserveSecurityLabel = qemuSecurityStackedReserveLabel,
-
- .domainGetSecurityProcessLabel = qemuSecurityStackedGetProcessLabel,
- .domainSetSecurityProcessLabel = qemuSecurityStackedSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityStackedSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityStackedRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityStackedSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityStackedRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityStackedSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityStackedRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityStackedSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityStackedRestoreSavedStateLabel,
-
- .domainClearSecuritySocketLabel = qemuSecurityStackedClearSocketLabel,
- .domainSetSecuritySocketLabel = qemuSecurityStackedSetSocketLabel,
-};
diff --git a/src/qemu/qemu_security_stacked.h b/src/qemu/qemu_security_stacked.h
deleted file mode 100644
index 07f76d5..0000000
--- a/src/qemu/qemu_security_stacked.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_STACKED
-# define __QEMU_SECURITY_STACKED
-
-extern virSecurityDriver qemuStackedSecurityDriver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 468d0a3..d82ba73 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -1,4 +1,3 @@
-
/*
* AppArmor security driver for libvirt
* Copyright (C) 2009-2010 Canonical Ltd.
@@ -28,7 +27,6 @@
#include "internal.h"
-#include "security_driver.h"
#include "security_apparmor.h"
#include "util.h"
#include "memory.h"
@@ -47,7 +45,7 @@
/* Data structure to pass to *FileIterate so we have everything we need */
struct SDPDOP {
- virSecurityDriverPtr drv;
+ virSecurityManagerPtr mgr;
virDomainObjPtr vm;
};
@@ -158,7 +156,7 @@ profile_status_file(const char *str)
* load (add) a profile. Will create one if necessary
*/
static int
-load_profile(virSecurityDriverPtr drv,
+load_profile(virSecurityManagerPtr mgr,
const char *profile,
virDomainObjPtr vm,
const char *fn,
@@ -169,7 +167,7 @@ load_profile(virSecurityDriverPtr drv,
char *xml = NULL;
int pipefd[2];
pid_t child;
- const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+ const char *probe = virSecurityManagerGetAllowDiskFormatProbing(mgr)
? "1" : "0";
if (pipe(pipefd) < -1) {
@@ -300,7 +298,7 @@ cleanup:
* NULL.
*/
static int
-reload_profile(virSecurityDriverPtr drv,
+reload_profile(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *fn,
bool append)
@@ -317,7 +315,7 @@ reload_profile(virSecurityDriverPtr drv,
/* Update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, fn, append) < 0) {
+ if (load_profile(mgr, secdef->imagelabel, vm, fn, append) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
"\'%s\'"),
@@ -340,7 +338,7 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -358,7 +356,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -371,7 +369,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
/* Called on libvirtd startup to see if AppArmor is available */
static int
-AppArmorSecurityDriverProbe(void)
+AppArmorSecurityManagerProbe(void)
{
char *template = NULL;
int rc = SECURITY_DRIVER_DISABLE;
@@ -403,21 +401,37 @@ AppArmorSecurityDriverProbe(void)
* currently not used.
*/
static int
-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+AppArmorSecurityManagerOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorSecurityManagerClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
- virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return 0;
}
+static const char *
+AppArmorSecurityManagerGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_NAME;
+}
+
+static const char *
+AppArmorSecurityManagerGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_VOID_DOI;
+}
+
+
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
* use a profile based on the UUID, otherwise create one based on a template.
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
* called on shutdown.
*/
static int
-AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -472,7 +486,7 @@ AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, const char *stdin_path)
{
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
@@ -480,7 +494,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
/* if the profile is not already loaded, then load one */
if (profile_loaded(vm->def->seclabel.label) < 0) {
- if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path,
+ if (load_profile(mgr, vm->def->seclabel.label, vm, stdin_path,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate AppArmor profile "
@@ -496,7 +510,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
* running.
*/
static int
-AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -530,7 +544,7 @@ AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
* more details. Currently called via qemudShutdownVMDaemon.
*/
static int
-AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -544,7 +558,7 @@ AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
static int
-AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -565,7 +579,7 @@ AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
*/
static int
-AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
+AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int rc = -1;
@@ -574,12 +588,12 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv,
virDomainObjPtr vm)
if ((profile_name = get_profile_name(vm)) == NULL)
return rc;
- if (STRNEQ(drv->name, secdef->model)) {
+ if (STRNEQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"\'%s\' model configured for domain, but
"
"hypervisor driver is \'%s\'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (use_apparmor() > 0)
goto clean;
}
@@ -597,19 +611,33 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv,
virDomainObjPtr vm)
return rc;
}
+static int
+AppArmorSetSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorClearSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
/* Called when hotplugging */
static int
-AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
/* Called when hotplugging */
static int
-AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -635,7 +663,7 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
/* update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, disk->src,
+ if (load_profile(mgr, secdef->imagelabel, vm, disk->src,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -654,7 +682,8 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
}
static int
-AppArmorSecurityVerify(virDomainDefPtr def)
+AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
@@ -670,7 +699,7 @@ AppArmorSecurityVerify(virDomainDefPtr def)
}
static int
-AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm ATTRIBUTE_UNUSED)
{
/* NOOP. Nothing to reserve with AppArmor */
@@ -678,7 +707,7 @@ AppArmorReserveSecurityLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -698,7 +727,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
if (VIR_ALLOC(ptr) < 0)
return -1;
- ptr->drv = drv;
+ ptr->mgr = mgr;
ptr->vm = vm;
switch (dev->source.subsys.type) {
@@ -740,7 +769,7 @@ done:
static int
-AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
@@ -749,42 +778,57 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
static int
-AppArmorSetSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorSetSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile)
{
- return reload_profile(drv, vm, savefile, true);
+ return reload_profile(mgr, vm, savefile, true);
}
static int
-AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
virSecurityDriver virAppArmorSecurityDriver = {
- .name = SECURITY_APPARMOR_NAME,
- .probe = AppArmorSecurityDriverProbe,
- .open = AppArmorSecurityDriverOpen,
- .domainSecurityVerify = AppArmorSecurityVerify,
- .domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
- .domainGenSecurityLabel = AppArmorGenSecurityLabel,
- .domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
- .domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
- .domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
+ 0,
+ SECURITY_APPARMOR_NAME,
+ AppArmorSecurityManagerProbe,
+ AppArmorSecurityManagerOpen,
+ AppArmorSecurityManagerClose,
+
+ AppArmorSecurityManagerGetModel,
+ AppArmorSecurityManagerGetDOI,
+
+ AppArmorSecurityVerify,
+
+ AppArmorSetSecurityImageLabel,
+ AppArmorRestoreSecurityImageLabel,
+
+ AppArmorSetSecuritySocketLabel,
+ AppArmorClearSecuritySocketLabel,
+
+ AppArmorGenSecurityLabel,
+ AppArmorReserveSecurityLabel,
+ AppArmorReleaseSecurityLabel,
+
+ AppArmorGetSecurityProcessLabel,
+ AppArmorSetSecurityProcessLabel,
+
+ AppArmorSetSecurityAllLabel,
+ AppArmorRestoreSecurityAllLabel,
+
+ AppArmorSetSecurityHostdevLabel,
+ AppArmorRestoreSecurityHostdevLabel,
+
+ AppArmorSetSavedStateLabel,
+ AppArmorRestoreSavedStateLabel,
};
diff --git a/src/security/security_apparmor.h b/src/security/security_apparmor.h
index eb7e140..ffd8288 100644
--- a/src/security/security_apparmor.h
+++ b/src/security/security_apparmor.h
@@ -14,6 +14,8 @@
#ifndef __VIR_SECURITY_APPARMOR_H__
# define __VIR_SECURITY_APPARMOR_H__
+# include "security_driver.h"
+
extern virSecurityDriver virAppArmorSecurityDriver;
# define AA_PREFIX "libvirt-"
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
new file mode 100644
index 0000000..de5d011
--- /dev/null
+++ b/src/security/security_dac.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * POSIX DAC security driver
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "pci.h"
+#include "hostusb.h"
+#include "storage_file.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityDACData virSecurityDACData;
+typedef virSecurityDACData *virSecurityDACDataPtr;
+
+struct _virSecurityDACData {
+ uid_t user;
+ gid_t group;
+ bool dynamicOwnership;
+};
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->user = user;
+}
+
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->group = group;
+}
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamicOwnership)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->dynamicOwnership = dynamicOwnership;
+}
+
+static virSecurityDriverStatus
+virSecurityDACProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "dac";
+}
+
+static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int
+virSecurityDACSetOwnership(const char *path, int uid, int gid)
+{
+ VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'",
path, uid, gid);
+
+ if (chown(path, uid, gid) < 0) {
+ struct stat sb;
+ int chown_errno = errno;
+
+ if (stat(path, &sb) >= 0) {
+ if (sb.st_uid == uid &&
+ sb.st_gid == gid) {
+ /* It's alright, there's nothing to change anyway. */
+ return 0;
+ }
+ }
+
+ if (chown_errno == EOPNOTSUPP) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not
supported by filesystem",
+ uid, gid, path);
+ } else if (chown_errno == EPERM) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not
permitted",
+ uid, gid, path);
+ } else if (chown_errno == EROFS) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not
possible on readonly filesystem",
+ uid, gid, path);
+ } else {
+ virReportSystemError(chown_errno,
+ _("unable to set user and group to '%d:%d'
on '%s'"),
+ uid, gid, path);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+virSecurityDACRestoreSecurityFileLabel(const char *path)
+{
+ struct stat buf;
+ int rc = -1;
+ char *newpath = NULL;
+
+ VIR_INFO("Restoring DAC user and group on '%s'", path);
+
+ if (virFileResolveLink(path, &newpath) < 0) {
+ virReportSystemError(errno,
+ _("cannot resolve symlink %s"), path);
+ goto err;
+ }
+
+ if (stat(newpath, &buf) != 0)
+ goto err;
+
+ /* XXX record previous ownership */
+ rc = virSecurityDACSetOwnership(newpath, 0, 0);
+
+err:
+ VIR_FREE(newpath);
+ return rc;
+}
+
+
+static int
+virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(path, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virDomainDiskDefForeachPath(disk,
+ virSecurityManagerGetAllowDiskFormatProbing(mgr),
+ false,
+ virSecurityDACSetSecurityFileLabel,
+ mgr);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ /* Don't restore labels on readoly/shared disks, because
+ * other VMs may still be accessing these
+ * Alternatively we could iterate over all running
+ * domains and try to figure out if it is in use, but
+ * this would not work for clustered filesystems, since
+ * we can't see running VMs using the file on other nodes
+ * Safest bet is thus to skip the restore step.
+ */
+ if (disk->readonly || disk->shared)
+ return 0;
+
+ if (!disk->src)
+ return 0;
+
+ /* If we have a shared FS & doing migrated, we must not
+ * change ownership, because that kills access on the
+ * destination host which is sub-optimal for the guest
+ * VM's I/O attempts :-)
+ */
+ if (migrated) {
+ int rc = virStorageFileIsSharedFS(disk->src);
+ if (rc < 0)
+ return -1;
+ if (rc == 1) {
+ VIR_DEBUG("Skipping image label restore on %s because FS is
shared",
+ disk->src);
+ return 0;
+ }
+ }
+
+ return virSecurityDACRestoreSecurityFileLabel(disk->src);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ return virSecurityDACRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
+}
+
+
+static int
+virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
+ virDomainChrDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user,
priv->group);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
+ (virAsprintf(&out, "%s.out", dev->data.file.path) < 0))
{
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
+ (virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+static int
+virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev)
+{
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0)
||
+ (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
+ (virSecurityDACRestoreSecurityFileLabel(in) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACRestoreChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+ int rc = 0;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+
+ VIR_DEBUG("Restoring security label on %s migrated=%d",
+ vm->def->name, migrated);
+
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) <
0)
+ rc = -1;
+ }
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
+ vm,
+ vm->def->disks[i],
+ migrated) < 0)
+ rc = -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ false,
+ virSecurityDACRestoreChardevCallback,
+ vm) < 0)
+ rc = -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
+ rc = -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACSetChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ /* XXX fixme - we need to recursively label the entire tree :-( */
+ if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
+ continue;
+ if (virSecurityDACSetSecurityImageLabel(mgr,
+ vm,
+ vm->def->disks[i]) < 0)
+ return -1;
+ }
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACSetSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) < 0)
+ return -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ true,
+ virSecurityDACSetChardevCallback,
+ vm) < 0)
+ return -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACSetOwnership(vm->def->os.kernel,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACSetOwnership(vm->def->os.initrd,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virSecurityDACRestoreSecurityFileLabel(savefile);
+}
+
+
+static int
+virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ DEBUG("Dropping privileges of VM to %d:%d", priv->user,
priv->group);
+
+ if (virSetUIDGID(priv->user, priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static int
+virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+virSecurityDriver virSecurityDriverDAC = {
+ sizeof(virSecurityDACData),
+ "virDAC",
+
+ virSecurityDACProbe,
+ virSecurityDACOpen,
+ virSecurityDACClose,
+
+ virSecurityDACGetModel,
+ virSecurityDACGetDOI,
+
+ virSecurityDACVerify,
+
+ virSecurityDACSetSecurityImageLabel,
+ virSecurityDACRestoreSecurityImageLabel,
+
+ virSecurityDACSetSocketLabel,
+ virSecurityDACClearSocketLabel,
+
+ virSecurityDACGenLabel,
+ virSecurityDACReserveLabel,
+ virSecurityDACReleaseLabel,
+
+ virSecurityDACGetProcessLabel,
+ virSecurityDACSetProcessLabel,
+
+ virSecurityDACSetSecurityAllLabel,
+ virSecurityDACRestoreSecurityAllLabel,
+
+ virSecurityDACSetSecurityHostdevLabel,
+ virSecurityDACRestoreSecurityHostdevLabel,
+
+ virSecurityDACSetSavedStateLabel,
+ virSecurityDACRestoreSavedStateLabel,
+};
diff --git a/src/security/security_dac.h b/src/security/security_dac.h
new file mode 100644
index 0000000..ccd9d1c
--- /dev/null
+++ b/src/security/security_dac.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * POSIX DAC security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_DAC
+# define __VIR_SECURITY_DAC
+
+extern virSecurityDriver virSecurityDriverDAC;
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user);
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group);
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamic);
+
+#endif /* __VIR_SECURITY_DAC */
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index 9e32fa4..4df73d7 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -14,6 +14,7 @@
#include <string.h>
#include "virterror_internal.h"
+#include "logging.h"
#include "security_driver.h"
#ifdef WITH_SECDRIVER_SELINUX
@@ -24,116 +25,56 @@
# include "security_apparmor.h"
#endif
+#include "security_nop.h"
+
static virSecurityDriverPtr security_drivers[] = {
#ifdef WITH_SECDRIVER_SELINUX
- &virSELinuxSecurityDriver,
+ &virSecurityDriverSELinux,
#endif
#ifdef WITH_SECDRIVER_APPARMOR
&virAppArmorSecurityDriver,
#endif
- NULL
+ &virSecurityDriverNop, /* Must always be last, since it will always probe */
};
-int
-virSecurityDriverVerify(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(def);
- }
- }
- virSecurityReportError(VIR_ERR_XML_ERROR,
- _("invalid security model '%s'"),
secdef->model);
- return -1;
-}
-
-int
-virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing)
+virSecurityDriverPtr virSecurityDriverLookup(const char *name)
{
- unsigned int i;
+ virSecurityDriverPtr drv = NULL;
+ int i;
- if (name && STREQ(name, "none"))
- return -2;
+ VIR_DEBUG("name=%s", NULLSTR(name));
- for (i = 0; security_drivers[i] != NULL ; i++) {
+ for (i = 0; i < ARRAY_CARDINALITY(security_drivers) && !drv ; 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(tmp, allowDiskFormatProbing) == -1) {
- return -1;
- } else {
- *drv = tmp;
- return 0;
+ if (name) {
+ if (STREQ(tmp->name, name)) {
+ drv = tmp;
+ break;
+ }
+ } else {
+ switch (tmp->probe()) {
+ case SECURITY_DRIVER_ENABLE:
+ VIR_DEBUG("Probed name=%s", tmp->name);
+ drv = tmp;
+ break;
+
+ case SECURITY_DRIVER_DISABLE:
+ VIR_DEBUG("Not enabled name=%s", tmp->name);
+ break;
+
+ default:
+ return NULL;
}
- break;
-
- case SECURITY_DRIVER_DISABLE:
- break;
-
- default:
- return -1;
}
}
- return -2;
-}
-
-/*
- * Helpers
- */
-void
-virSecurityDriverInit(virSecurityDriverPtr drv)
-{
- memset(&drv->_private, 0, sizeof drv->_private);
-}
-int
-virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi)
-{
- if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
+ if (!drv) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
- _("%s: DOI \'%s\' is "
- "longer than the maximum allowed length of
%d"),
- __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
- return -1;
+ _("Security driver %s not found"),
+ NULLSTR(name));
+ return NULL;
}
- strcpy(drv->_private.doi, doi);
- return 0;
-}
-
-const char *
-virSecurityDriverGetDOI(virSecurityDriverPtr drv)
-{
- return drv->_private.doi;
-}
-const char *
-virSecurityDriverGetModel(virSecurityDriverPtr drv)
-{
- return drv->name;
-}
-
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
-{
- drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
-}
-
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
-{
- return drv->_private.allowDiskFormatProbing;
+ return drv;
}
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index d768f32..e5a8d41 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -16,6 +16,8 @@
# include "internal.h"
# include "domain_conf.h"
+# include "security_manager.h"
+
/*
* Return values for security driver probing: the driver will determine
* whether it should be enabled or disabled.
@@ -29,104 +31,91 @@ typedef enum {
typedef struct _virSecurityDriver virSecurityDriver;
typedef virSecurityDriver *virSecurityDriverPtr;
-typedef struct _virSecurityDriverState virSecurityDriverState;
-typedef virSecurityDriverState *virSecurityDriverStatePtr;
-
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDriverOpen) (virSecurityManagerPtr mgr);
+typedef int (*virSecurityDriverClose) (virSecurityManagerPtr mgr);
+
+typedef const char *(*virSecurityDriverGetModel) (virSecurityManagerPtr mgr);
+typedef const char *(*virSecurityDriverGetDOI) (virSecurityManagerPtr mgr);
+
+typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSocketLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainClearSocketLabel)(virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGenLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReserveLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec,
const char *stdin_path);
-typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
int migrated);
-typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virSecurityLabelPtr sec);
-typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSecurityVerify) (virDomainDefPtr def);
+typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
struct _virSecurityDriver {
+ size_t privateDataLen;
const char *name;
virSecurityDriverProbe probe;
virSecurityDriverOpen open;
+ virSecurityDriverClose close;
+
+ virSecurityDriverGetModel getModel;
+ virSecurityDriverGetDOI getDOI;
+
virSecurityDomainSecurityVerify domainSecurityVerify;
+
+ virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
+
virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
- virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
+
virSecurityDomainGenLabel domainGenSecurityLabel;
virSecurityDomainReserveLabel domainReserveSecurityLabel;
virSecurityDomainReleaseLabel domainReleaseSecurityLabel;
+
virSecurityDomainGetProcessLabel domainGetSecurityProcessLabel;
virSecurityDomainSetProcessLabel domainSetSecurityProcessLabel;
+
virSecurityDomainSetAllLabel domainSetSecurityAllLabel;
virSecurityDomainRestoreAllLabel domainRestoreSecurityAllLabel;
- virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
+ virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
-
- /*
- * This is internally managed driver state and should only be accessed
- * via helpers below.
- */
- struct {
- char doi[VIR_SECURITY_DOI_BUFLEN];
- bool allowDiskFormatProbing;
- } _private;
};
-/* Global methods */
-int virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing);
-
-int
-virSecurityDriverVerify(virDomainDefPtr def);
-
-# define virSecurityReportError(code, ...) \
- virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/* Helpers */
-void virSecurityDriverInit(virSecurityDriverPtr drv);
-int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi);
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
-const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
+virSecurityDriverPtr virSecurityDriverLookup(const char *name);
#endif /* __VIR_SECURITY_H__ */
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
new file mode 100644
index 0000000..66cffb5
--- /dev/null
+++ b/src/security/security_manager.c
@@ -0,0 +1,317 @@
+/*
+ * security_manager.c: Internal security manager API
+ *
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+
+#include "security_driver.h"
+#include "security_stack.h"
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "memory.h"
+#include "logging.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+
+struct _virSecurityManager {
+ virSecurityDriverPtr drv;
+ bool allowDiskFormatProbing;
+};
+
+static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
+{
+ virSecurityManagerPtr mgr;
+
+ if (VIR_ALLOC_VAR(mgr, char, drv->privateDataLen) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ mgr->drv = drv;
+ mgr->allowDiskFormatProbing = allowDiskFormatProbing;
+
+ if (drv->open(mgr) < 0) {
+ virSecurityManagerFree(mgr);
+ return NULL;
+ }
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverStack,
+
virSecurityManagerGetAllowDiskFormatProbing(primary));
+
+ if (!mgr)
+ return NULL;
+
+ virSecurityStackSetPrimary(mgr, primary);
+ virSecurityStackSetSecondary(mgr, secondary);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverDAC,
+ allowDiskFormatProbing);
+
+ if (!mgr)
+ return NULL;
+
+ virSecurityDACSetUser(mgr, user);
+ virSecurityDACSetGroup(mgr, group);
+ virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing)
+{
+ virSecurityDriverPtr drv = virSecurityDriverLookup(name);
+ if (!drv)
+ return NULL;
+
+ return virSecurityManagerNewDriver(drv, allowDiskFormatProbing);
+}
+
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
+{
+ return ((char*)mgr) + sizeof(mgr);
+}
+
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr)
+{
+ if (!mgr)
+ return;
+
+ if (mgr->drv->close)
+ mgr->drv->close(mgr);
+
+ VIR_FREE(mgr);
+}
+
+const char *
+virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getDOI)
+ return mgr->drv->getDOI(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+const char *
+virSecurityManagerGetModel(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getModel)
+ return mgr->drv->getModel(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
+{
+ return mgr->allowDiskFormatProbing;
+}
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainRestoreSecurityImageLabel)
+ return mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecuritySocketLabel)
+ return mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainClearSecuritySocketLabel)
+ return mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainSetSecurityImageLabel)
+ return mgr->drv->domainSetSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainRestoreSecurityHostdevLabel)
+ return mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainSetSecurityHostdevLabel)
+ return mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainSetSavedStateLabel)
+ return mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainRestoreSavedStateLabel)
+ return mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainGenSecurityLabel)
+ return mgr->drv->domainGenSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReserveSecurityLabel)
+ return mgr->drv->domainReserveSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReleaseSecurityLabel)
+ return mgr->drv->domainReleaseSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ if (mgr->drv->domainSetSecurityAllLabel)
+ return mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ if (mgr->drv->domainRestoreSecurityAllLabel)
+ return mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec)
+{
+ if (mgr->drv->domainGetSecurityProcessLabel)
+ return mgr->drv->domainGetSecurityProcessLabel(mgr, vm, sec);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecurityProcessLabel)
+ return mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ if (mgr->drv->domainSecurityVerify)
+ return mgr->drv->domainSecurityVerify(mgr, def);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
new file mode 100644
index 0000000..189b6b4
--- /dev/null
+++ b/src/security/security_manager.h
@@ -0,0 +1,95 @@
+/*
+ * security_manager.h: Internal security manager API
+ *
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef VIR_SECURITY_MANAGER_H__
+# define VIR_SECURITY_MANAGER_H__
+
+# define virSecurityReportError(code, ...) \
+ virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+typedef struct _virSecurityManager virSecurityManager;
+typedef virSecurityManager *virSecurityManagerPtr;
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing);
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary);
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership);
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr);
+
+const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr);
+const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec,
+ const char *stdin_path);
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated);
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec);
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
+#endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
new file mode 100644
index 0000000..6d7cb47
--- /dev/null
+++ b/src/security/security_nop.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "security_nop.h"
+
+static virSecurityDriverStatus virSecurityDriverProbeNop(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int virSecurityDriverOpenNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDriverCloseNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char * virSecurityDriverGetModelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED)
+{
+ return "none";
+}
+
+static const char * virSecurityDriverGetDOINop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int virSecurityDomainRestoreImageLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk
ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSocketLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainClearSocketLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreHostdevLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev
ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetHostdevLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev
ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSavedStateLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainRestoreSavedStateLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm
ATTRIBUTE_UNUSED,
+ const char *savefile
ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainGenLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReserveLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ int migrated ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainGetProcessLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetProcessLabelNop(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainVerifyNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+virSecurityDriver virSecurityDriverNop = {
+ 0,
+ "none",
+ virSecurityDriverProbeNop,
+ virSecurityDriverOpenNop,
+ virSecurityDriverCloseNop,
+
+ virSecurityDriverGetModelNop,
+ virSecurityDriverGetDOINop,
+
+ virSecurityDomainVerifyNop,
+
+ virSecurityDomainSetImageLabelNop,
+ virSecurityDomainRestoreImageLabelNop,
+
+ virSecurityDomainSetSocketLabelNop,
+ virSecurityDomainClearSocketLabelNop,
+
+ virSecurityDomainGenLabelNop,
+ virSecurityDomainReserveLabelNop,
+ virSecurityDomainReleaseLabelNop,
+
+ virSecurityDomainGetProcessLabelNop,
+ virSecurityDomainSetProcessLabelNop,
+
+ virSecurityDomainSetAllLabelNop,
+ virSecurityDomainRestoreAllLabelNop,
+
+ virSecurityDomainSetHostdevLabelNop,
+ virSecurityDomainRestoreHostdevLabelNop,
+
+ virSecurityDomainSetSavedStateLabelNop,
+ virSecurityDomainRestoreSavedStateLabelNop,
+};
diff --git a/src/security/security_nop.h b/src/security/security_nop.h
new file mode 100644
index 0000000..589a75d
--- /dev/null
+++ b/src/security/security_nop.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __VIR_SECURITY_NOP_H__
+# define __VIR_SECURITY_NOP_H__
+
+# include "security_driver.h"
+
+extern virSecurityDriver virSecurityDriverNop;
+
+#endif /* __VIR_SECURITY_NOP_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 47da677..d06afde 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -160,7 +160,7 @@ SELinuxInitialize(void)
}
static int
-SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -225,7 +225,7 @@ done:
}
static int
-SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
security_context_t pctx;
@@ -270,20 +270,34 @@ SELinuxSecurityDriverProbe(void)
}
static int
-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+SELinuxSecurityDriverOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SELinuxInitialize();
+}
+
+static int
+SELinuxSecurityDriverClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char *SELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_SELINUX_NAME;
+}
+
+static const char *SELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
- virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
- return SELinuxInitialize();
+ return SECURITY_SELINUX_VOID_DOI;
}
static int
-SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -415,7 +429,7 @@ err:
}
static int
-SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
int migrated)
@@ -460,11 +474,11 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
- return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0);
+ return SELinuxRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
}
@@ -498,13 +512,13 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
}
static int
-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
+ bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
@@ -538,7 +552,7 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -607,7 +621,7 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -756,7 +770,7 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def
ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -770,13 +784,13 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
return 0;
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxRestoreSecurityHostdevLabel(drv,
+ if (SELinuxRestoreSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
rc = -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (SELinuxRestoreSecurityImageLabelInt(drv,
+ if (SELinuxRestoreSecurityImageLabelInt(mgr,
vm,
vm->def->disks[i],
migrated) < 0)
@@ -801,7 +815,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
}
static int
-SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -825,7 +839,7 @@ SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
static int
-SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -839,7 +853,7 @@ SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -853,9 +867,19 @@ SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv
ATTRIBUTE_UNUSED,
static int
-SELinuxSecurityVerify(virDomainDefPtr def)
+SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label driver mismatch: "
+ "'%s' model configured for domain, but
"
+ "hypervisor driver is '%s'."),
+ secdef->model, virSecurityManagerGetModel(mgr));
+ return -1;
+ }
+
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
if (security_check_context(secdef->label) != 0) {
virSecurityReportError(VIR_ERR_XML_ERROR,
@@ -867,7 +891,7 @@ SELinuxSecurityVerify(virDomainDefPtr def)
}
static int
-SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -876,12 +900,12 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but
"
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -898,7 +922,7 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
}
static int
-SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -911,12 +935,12 @@ SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but
"
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
goto done;
}
@@ -969,7 +993,7 @@ done:
}
static int
-SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -978,12 +1002,12 @@ SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but
"
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -1011,7 +1035,7 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def
ATTRIBUTE_UNUSED,
static int
-SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *stdin_path)
{
@@ -1028,12 +1052,12 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
vm->def->disks[i]->src, vm->def->disks[i]->dst);
continue;
}
- if (SELinuxSetSecurityImageLabel(drv,
+ if (SELinuxSetSecurityImageLabel(mgr,
vm, vm->def->disks[i]) < 0)
return -1;
}
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxSetSecurityHostdevLabel(drv,
+ if (SELinuxSetSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
return -1;
@@ -1063,24 +1087,37 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
return 0;
}
-virSecurityDriver virSELinuxSecurityDriver = {
- .name = SECURITY_SELINUX_NAME,
- .probe = SELinuxSecurityDriverProbe,
- .open = SELinuxSecurityDriverOpen,
- .domainSecurityVerify = SELinuxSecurityVerify,
- .domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
- .domainSetSecuritySocketLabel = SELinuxSetSecuritySocketLabel,
- .domainClearSecuritySocketLabel = SELinuxClearSecuritySocketLabel,
- .domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
- .domainGenSecurityLabel = SELinuxGenSecurityLabel,
- .domainReserveSecurityLabel = SELinuxReserveSecurityLabel,
- .domainReleaseSecurityLabel = SELinuxReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = SELinuxGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = SELinuxSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = SELinuxRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = SELinuxSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
- .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
+virSecurityDriver virSecurityDriverSELinux = {
+ 0,
+ SECURITY_SELINUX_NAME,
+ SELinuxSecurityDriverProbe,
+ SELinuxSecurityDriverOpen,
+ SELinuxSecurityDriverClose,
+
+ SELinuxSecurityGetModel,
+ SELinuxSecurityGetDOI,
+
+ SELinuxSecurityVerify,
+
+ SELinuxSetSecurityImageLabel,
+ SELinuxRestoreSecurityImageLabel,
+
+ SELinuxSetSecuritySocketLabel,
+ SELinuxClearSecuritySocketLabel,
+
+ SELinuxGenSecurityLabel,
+ SELinuxReserveSecurityLabel,
+ SELinuxReleaseSecurityLabel,
+
+ SELinuxGetSecurityProcessLabel,
+ SELinuxSetSecurityProcessLabel,
+
+ SELinuxSetSecurityAllLabel,
+ SELinuxRestoreSecurityAllLabel,
+
+ SELinuxSetSecurityHostdevLabel,
+ SELinuxRestoreSecurityHostdevLabel,
+
+ SELinuxSetSavedStateLabel,
+ SELinuxRestoreSavedStateLabel,
};
diff --git a/src/security/security_selinux.h b/src/security/security_selinux.h
index 056ba75..aa67421 100644
--- a/src/security/security_selinux.h
+++ b/src/security/security_selinux.h
@@ -13,6 +13,6 @@
#ifndef __VIR_SECURITY_SELINUX_H__
# define __VIR_SECURITY_SELINUX_H__
-extern virSecurityDriver virSELinuxSecurityDriver;
+extern virSecurityDriver virSecurityDriverSELinux;
#endif /* __VIR_SECURITY_SELINUX_H__ */
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
new file mode 100644
index 0000000..e8bb058
--- /dev/null
+++ b/src/security/security_stack.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Stacked security driver
+ */
+
+#include <config.h>
+
+#include "security_stack.h"
+
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityStackData virSecurityStackData;
+typedef virSecurityStackData *virSecurityStackDataPtr;
+
+struct _virSecurityStackData {
+ virSecurityManagerPtr primary;
+ virSecurityManagerPtr secondary;
+};
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->primary = primary;
+}
+
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->secondary = secondary;
+}
+
+static virSecurityDriverStatus
+virSecurityStackProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityStackOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityStackClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char *
+virSecurityStackGetModel(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetModel(priv->primary);
+}
+
+static const char *
+virSecurityStackGetDOI(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetDOI(priv->primary);
+}
+
+static int
+virSecurityStackVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerVerify(priv->primary, def) < 0)
+ rc = -1;
+
+ if (virSecurityManagerVerify(priv->secondary, def) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+#if 0
+ /* We don't allow secondary drivers to generate labels.
+ * This may have to change in the future, but requires
+ * changes elsewhere in domain_conf.c and capabilities.c
+ * XML formats first, to allow recording of multiple
+ * labels
+ */
+ if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ /* XXX See note in GenLabel */
+ if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReserveLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ /* XXX See note in GenLabel */
+ if (virSecurityManagerReserveLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
+ rc = -1;
+ if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) <
0)
+ rc = -1;
+ if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+static int
+virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr seclabel)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+#if 0
+ if (virSecurityManagerGetProcessLabel(priv->secondary, vm, seclabel) < 0)
+ rc = -1;
+#endif
+ if (virSecurityManagerGetProcessLabel(priv->primary, vm, seclabel) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+virSecurityDriver virSecurityDriverStack = {
+ sizeof(virSecurityStackData),
+ "stack",
+ virSecurityStackProbe,
+ virSecurityStackOpen,
+ virSecurityStackClose,
+
+ virSecurityStackGetModel,
+ virSecurityStackGetDOI,
+
+ virSecurityStackVerify,
+
+ virSecurityStackSetSecurityImageLabel,
+ virSecurityStackRestoreSecurityImageLabel,
+
+ virSecurityStackSetSocketLabel,
+ virSecurityStackClearSocketLabel,
+
+ virSecurityStackGenLabel,
+ virSecurityStackReserveLabel,
+ virSecurityStackReleaseLabel,
+
+ virSecurityStackGetProcessLabel,
+ virSecurityStackSetProcessLabel,
+
+ virSecurityStackSetSecurityAllLabel,
+ virSecurityStackRestoreSecurityAllLabel,
+
+ virSecurityStackSetSecurityHostdevLabel,
+ virSecurityStackRestoreSecurityHostdevLabel,
+
+ virSecurityStackSetSavedStateLabel,
+ virSecurityStackRestoreSavedStateLabel,
+};
diff --git a/src/security/security_stack.h b/src/security/security_stack.h
new file mode 100644
index 0000000..bc83ff3
--- /dev/null
+++ b/src/security/security_stack.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Stacked security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_STACK
+# define __VIR_SECURITY_STACK
+
+extern virSecurityDriver virSecurityDriverStack;
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary);
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary);
+
+#endif /* __VIR_SECURITY_DAC */
--
1.7.3.4