mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-02 11:21:12 +00:00
99be754ada
When sVirt is integrated with the LXC driver, it will be neccessary to invoke the security driver APIs using only a virDomainDefPtr since the lxc_container.c code has no virDomainObjPtr available. Aside from two functions which want obj->pid, every bit of the security driver code only touches obj->def. So we don't need to pass a virDomainObjPtr into the security drivers, a virDomainDefPtr is sufficient. Two functions also gain a 'pid_t pid' argument. * src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/qemu/qemu_process.c, src/security/security_apparmor.c, src/security/security_dac.c, src/security/security_driver.h, src/security/security_manager.c, src/security/security_manager.h, src/security/security_nop.c, src/security/security_selinux.c, src/security/security_stack.c: Change all security APIs to use a virDomainDefPtr instead of virDomainObjPtr
752 lines
21 KiB
C
752 lines
21 KiB
C
/*
|
|
* 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 || chown_errno == EINVAL) {
|
|
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,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
virDomainDiskDefPtr disk)
|
|
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
if (!priv->dynamicOwnership)
|
|
return 0;
|
|
|
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
|
return 0;
|
|
|
|
return virDomainDiskDefForeachPath(disk,
|
|
virSecurityManagerGetAllowDiskFormatProbing(mgr),
|
|
false,
|
|
virSecurityDACSetSecurityFileLabel,
|
|
mgr);
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
virDomainDiskDefPtr disk,
|
|
int migrated)
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
if (!priv->dynamicOwnership)
|
|
return 0;
|
|
|
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
|
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,
|
|
virDomainDefPtr def,
|
|
virDomainDiskDefPtr disk)
|
|
{
|
|
return virSecurityDACRestoreSecurityImageLabelInt(mgr, def, 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,
|
|
virDomainDefPtr def 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,
|
|
virDomainDefPtr def 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,
|
|
virDomainChrSourceDefPtr 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 (virFileExists(in) && virFileExists(out)) {
|
|
if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
|
|
(virSecurityDACSetOwnership(out, priv->user, priv->group) < 0)) {
|
|
goto done;
|
|
}
|
|
} else if (virSecurityDACSetOwnership(dev->data.file.path,
|
|
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,
|
|
virDomainChrSourceDefPtr 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 (virFileExists(in) && virFileExists(out)) {
|
|
if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
|
|
(virSecurityDACRestoreSecurityFileLabel(in) < 0)) {
|
|
goto done;
|
|
}
|
|
} else if (virSecurityDACRestoreSecurityFileLabel(dev->data.file.path) < 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->source);
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def,
|
|
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",
|
|
def->name, migrated);
|
|
|
|
for (i = 0 ; i < def->nhostdevs ; i++) {
|
|
if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
|
|
def,
|
|
def->hostdevs[i]) < 0)
|
|
rc = -1;
|
|
}
|
|
for (i = 0 ; i < def->ndisks ; i++) {
|
|
if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
|
|
def,
|
|
def->disks[i],
|
|
migrated) < 0)
|
|
rc = -1;
|
|
}
|
|
|
|
if (virDomainChrDefForeach(def,
|
|
false,
|
|
virSecurityDACRestoreChardevCallback,
|
|
mgr) < 0)
|
|
rc = -1;
|
|
|
|
if (def->os.kernel &&
|
|
virSecurityDACRestoreSecurityFileLabel(def->os.kernel) < 0)
|
|
rc = -1;
|
|
|
|
if (def->os.initrd &&
|
|
virSecurityDACRestoreSecurityFileLabel(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->source);
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def,
|
|
const char *stdin_path ATTRIBUTE_UNUSED)
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
int i;
|
|
|
|
if (!priv->dynamicOwnership)
|
|
return 0;
|
|
|
|
for (i = 0 ; i < def->ndisks ; i++) {
|
|
/* XXX fixme - we need to recursively label the entire tree :-( */
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
|
|
continue;
|
|
if (virSecurityDACSetSecurityImageLabel(mgr,
|
|
def,
|
|
def->disks[i]) < 0)
|
|
return -1;
|
|
}
|
|
for (i = 0 ; i < def->nhostdevs ; i++) {
|
|
if (virSecurityDACSetSecurityHostdevLabel(mgr,
|
|
def,
|
|
def->hostdevs[i]) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if (virDomainChrDefForeach(def,
|
|
true,
|
|
virSecurityDACSetChardevCallback,
|
|
mgr) < 0)
|
|
return -1;
|
|
|
|
if (def->os.kernel &&
|
|
virSecurityDACSetOwnership(def->os.kernel,
|
|
priv->user,
|
|
priv->group) < 0)
|
|
return -1;
|
|
|
|
if (def->os.initrd &&
|
|
virSecurityDACSetOwnership(def->os.initrd,
|
|
priv->user,
|
|
priv->group) < 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
const char *savefile)
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
const char *savefile)
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
if (!priv->dynamicOwnership)
|
|
return 0;
|
|
|
|
return virSecurityDACRestoreSecurityFileLabel(savefile);
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
|
{
|
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
VIR_DEBUG("Dropping privileges of DEF to %u:%u",
|
|
(unsigned int) priv->user, (unsigned int) 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,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
pid_t pid ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
pid_t pid ATTRIBUTE_UNUSED,
|
|
virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
virSecurityDACSetDaemonSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr vm ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
virSecurityDACSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
int fd ATTRIBUTE_UNUSED)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
virSecurityDriver virSecurityDriverDAC = {
|
|
sizeof(virSecurityDACData),
|
|
"virDAC",
|
|
|
|
virSecurityDACProbe,
|
|
virSecurityDACOpen,
|
|
virSecurityDACClose,
|
|
|
|
virSecurityDACGetModel,
|
|
virSecurityDACGetDOI,
|
|
|
|
virSecurityDACVerify,
|
|
|
|
virSecurityDACSetSecurityImageLabel,
|
|
virSecurityDACRestoreSecurityImageLabel,
|
|
|
|
virSecurityDACSetDaemonSocketLabel,
|
|
virSecurityDACSetSocketLabel,
|
|
virSecurityDACClearSocketLabel,
|
|
|
|
virSecurityDACGenLabel,
|
|
virSecurityDACReserveLabel,
|
|
virSecurityDACReleaseLabel,
|
|
|
|
virSecurityDACGetProcessLabel,
|
|
virSecurityDACSetProcessLabel,
|
|
|
|
virSecurityDACSetSecurityAllLabel,
|
|
virSecurityDACRestoreSecurityAllLabel,
|
|
|
|
virSecurityDACSetSecurityHostdevLabel,
|
|
virSecurityDACRestoreSecurityHostdevLabel,
|
|
|
|
virSecurityDACSetSavedStateLabel,
|
|
virSecurityDACRestoreSavedStateLabel,
|
|
|
|
virSecurityDACSetImageFDLabel,
|
|
};
|