[libvirt] [PATCH 0/8] events: Add helpers for driver dispatching
by Cole Robinson
I noticed that there is quite a bit of code duplication among the
drivers that support domain events. This patch series is an attempt
to consolidate the shared logic.
Patch #1 is the bugfix for https://bugzilla.redhat.com/show_bug.cgi?id=624252
which started me down this path. It can be applied independently of the
refactoring if need be.
Thanks,
Cole
Cole Robinson (8):
remote: Don't lose track of events when callbacks are slow
event-test: Simplify debug on/off
domain_event: Add virDomainEventState structure
domain_event: Add common domain event queue/flush helpers
qemu: Use virDomainEventState helpers
lxc: Use virDomainEventState helpers
test: Use virDomainEventState helpers
remote: Use virDomainEventState helpers
examples/domain-events/events-python/event-test.py | 37 +++--
src/conf/domain_event.c | 163 +++++++++++++++++---
src/conf/domain_event.h | 64 ++++++--
src/libvirt_private.syms | 6 +
src/lxc/lxc_conf.h | 6 +-
src/lxc/lxc_driver.c | 76 +++------
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 80 +++-------
src/remote/remote_driver.c | 162 ++++++++------------
src/test/test_driver.c | 104 ++++---------
10 files changed, 363 insertions(+), 341 deletions(-)
--
1.7.3.3
13 years, 10 months
[libvirt] [PATCH] qemu: Allow serving VNC over a unix domain socket
by Cole Robinson
QEMU supports serving VNC over a unix domain socket rather than traditional
TCP host/port. This is specified with:
<graphics type='vnc' socket='/foo/bar/baz'/>
Currently not hooked up with the security driver, I'll wait for Dan's
big reorg. I also have a virtinst/virt-manager patch queued locally to
handle this change.
To be useful, we probably want a qemu.conf option to use sockets as the
default VNC method, so VMs without hardcoded listen addresses will
magically start up serving over a socket in /var/lib/libvirt/qemu. This
provides better security access control than VNC listening on 127.0.0.1, but
will cause issues with tools that rely on the lax security (virt-manager
in fedora runs as regular user by default, and wouldn't be able to access
a socket owned by 'qemu' or 'root').
---
docs/formatdomain.html.in | 6 ++-
docs/schemas/domain.rng | 5 ++
src/conf/domain_conf.c | 30 +++++++----
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 52 +++++++++++++-------
src/qemu/qemu_driver.c | 1 +
tests/qemuargv2xmltest.c | 1 +
.../qemuxml2argv-graphics-vnc-socket.args | 1 +
.../qemuxml2argv-graphics-vnc-socket.xml | 30 +++++++++++
tests/qemuxml2argvtest.c | 1 +
10 files changed, 98 insertions(+), 30 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e9fcea1..fbcff0b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1153,7 +1153,11 @@ qemu-kvm -net nic,model=? /dev/null
in clear text. The <code>keymap</code> attribute specifies the keymap
to use. It is possible to set a limit on the validity of the password
be giving an timestamp <code>passwdValidTo='2010-04-09T15:51:00'</code>
- assumed to be in UTC. NB, this may not be supported by all hypervisors.
+ assumed to be in UTC. NB, this may not be supported by all hypervisors.<br>
+ <br>
+ Rather than using listen/port, QEMU supports a <code>socket</code>
+ attribute for listening on a unix domain socket path.
+ <span class="since">Since 0.8.8</span>
</dd>
<dt><code>"spice"</code></dt>
<dd>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index a524e4b..554a39f 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1116,6 +1116,11 @@
</attribute>
</optional>
<optional>
+ <attribute name="socket">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ <optional>
<attribute name="passwd">
<text/>
</attribute>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c857a89..aec23aa 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -471,6 +471,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
switch (def->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
VIR_FREE(def->data.vnc.listenAddr);
+ VIR_FREE(def->data.vnc.socket);
VIR_FREE(def->data.vnc.keymap);
virDomainGraphicsAuthDefClear(&def->data.vnc.auth);
break;
@@ -3349,6 +3350,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
}
def->data.vnc.listenAddr = virXMLPropString(node, "listen");
+ def->data.vnc.socket = virXMLPropString(node, "socket");
def->data.vnc.keymap = virXMLPropString(node, "keymap");
if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0)
@@ -6844,19 +6846,25 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
switch (def->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
- if (def->data.vnc.port &&
- (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_XML_INACTIVE)))
- virBufferVSprintf(buf, " port='%d'",
- def->data.vnc.port);
- else if (def->data.vnc.autoport)
- virBufferAddLit(buf, " port='-1'");
+ if (def->data.vnc.socket) {
+ if (def->data.vnc.socket)
+ virBufferVSprintf(buf, " socket='%s'",
+ def->data.vnc.socket);
+ } else {
+ if (def->data.vnc.port &&
+ (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_XML_INACTIVE)))
+ virBufferVSprintf(buf, " port='%d'",
+ def->data.vnc.port);
+ else if (def->data.vnc.autoport)
+ virBufferAddLit(buf, " port='-1'");
- virBufferVSprintf(buf, " autoport='%s'",
- def->data.vnc.autoport ? "yes" : "no");
+ virBufferVSprintf(buf, " autoport='%s'",
+ def->data.vnc.autoport ? "yes" : "no");
- if (def->data.vnc.listenAddr)
- virBufferVSprintf(buf, " listen='%s'",
- def->data.vnc.listenAddr);
+ if (def->data.vnc.listenAddr)
+ virBufferVSprintf(buf, " listen='%s'",
+ def->data.vnc.listenAddr);
+ }
if (def->data.vnc.keymap)
virBufferEscapeString(buf, " keymap='%s'",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a459a22..684fc7d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -574,6 +574,7 @@ struct _virDomainGraphicsDef {
unsigned int autoport :1;
char *listenAddr;
char *keymap;
+ char *socket;
virDomainGraphicsAuthDef auth;
} vnc;
struct {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7dd8e03..c0fd00b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3511,7 +3511,11 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
- if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
+ if (def->graphics[0]->data.vnc.socket) {
+ virBufferVSprintf(&opt, "unix:%s",
+ def->graphics[0]->data.vnc.socket);
+
+ } else if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
if (def->graphics[0]->data.vnc.listenAddr)
virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1);
else if (driver->vncListen)
@@ -3520,6 +3524,12 @@ qemuBuildCommandLine(virConnectPtr conn,
virBufferVSprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900);
+ } else {
+ virBufferVSprintf(&opt, "%d",
+ def->graphics[0]->data.vnc.port - 5900);
+ }
+
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
if (def->graphics[0]->data.vnc.auth.passwd ||
driver->vncPassword)
virBufferAddLit(&opt, ",password");
@@ -3544,9 +3554,6 @@ qemuBuildCommandLine(virConnectPtr conn,
/* TODO: Support ACLs later */
}
- } else {
- virBufferVSprintf(&opt, "%d",
- def->graphics[0]->data.vnc.port - 5900);
}
virCommandAddArg(cmd, "-vnc");
@@ -5174,24 +5181,33 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
goto no_memory;
vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
- tmp = strchr(val, ':');
- if (tmp) {
- char *opts;
- if (virStrToLong_i(tmp+1, &opts, 10, &vnc->data.vnc.port) < 0) {
- VIR_FREE(vnc);
- qemuReportError(VIR_ERR_INTERNAL_ERROR, \
- _("cannot parse VNC port '%s'"), tmp+1);
- goto error;
- }
- vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
+ if (STRPREFIX(val, "unix:")) {
+ vnc->data.vnc.socket = strdup(val + 5);
+ if (!vnc->data.vnc.socket) {
VIR_FREE(vnc);
goto no_memory;
}
- vnc->data.vnc.port += 5900;
- vnc->data.vnc.autoport = 0;
} else {
- vnc->data.vnc.autoport = 1;
+ tmp = strchr(val, ':');
+ if (tmp) {
+ char *opts;
+ if (virStrToLong_i(tmp+1, &opts, 10,
+ &vnc->data.vnc.port) < 0) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse VNC port '%s'"), tmp+1);
+ goto error;
+ }
+ vnc->data.vnc.listenAddr = strndup(val, tmp-val);
+ if (!vnc->data.vnc.listenAddr) {
+ VIR_FREE(vnc);
+ goto no_memory;
+ }
+ vnc->data.vnc.port += 5900;
+ vnc->data.vnc.autoport = 0;
+ } else {
+ vnc->data.vnc.autoport = 1;
+ }
}
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..0f2e3b2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2684,6 +2684,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (vm->def->ngraphics == 1) {
if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+ !vm->def->graphics[0]->data.vnc.socket &&
vm->def->graphics[0]->data.vnc.autoport) {
int port = qemudNextFreePort(driver, QEMU_VNC_PORT_MIN);
if (port < 0) {
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 8338af3..7499ba0 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -178,6 +178,7 @@ mymain(int argc, char **argv)
DO_TEST("disk-drive-network-sheepdog");
DO_TEST("disk-usb");
DO_TEST("graphics-vnc");
+ DO_TEST("graphics-vnc-socket");
driver.vncSASL = 1;
driver.vncSASLdir = strdup("/root/.sasl2");
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
new file mode 100644
index 0000000..055c562
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc unix:/tmp/foo.socket
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
new file mode 100644
index 0000000..d6ad72b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' socket='/tmp/foo.socket'/>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 6760f67..8a1d5f7 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -316,6 +316,7 @@ mymain(int argc, char **argv)
DO_TEST("disk-scsi-device-auto", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG, false);
DO_TEST("graphics-vnc", 0, false);
+ DO_TEST("graphics-vnc-socket", 0, false);
driver.vncSASL = 1;
driver.vncSASLdir = strdup("/root/.sasl2");
--
1.7.3.3
13 years, 10 months
[libvirt] [PATCH] conf: Report error if invalid type specified for character device
by Osier Yang
If invalid type is specified, e.g.
<serial type='foo'>
<target port='0'/>
</serial>
We replace 'foo' with "null" type implicitly, without reporting an
error message to tell the user, and "start" or "edit" the domain
will be success.
It's not good to guess what the user wants, This patch is to fix
the problem.
* src/conf/domain_conf.c
---
src/conf/domain_conf.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c857a89..b4df38c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2821,10 +2821,14 @@ virDomainChrDefParseXML(virCapsPtr caps,
}
type = virXMLPropString(node, "type");
- if (type == NULL)
+ if (type == NULL) {
def->type = VIR_DOMAIN_CHR_TYPE_PTY;
- else if ((def->type = virDomainChrTypeFromString(type)) < 0)
- def->type = VIR_DOMAIN_CHR_TYPE_NULL;
+ } else if ((def->type = virDomainChrTypeFromString(type)) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("unknown type presented to host for character device: %s"),
+ type);
+ goto error;
+ }
nodeName = (const char *) node->name;
if ((def->deviceType = virDomainChrDeviceTypeFromString(nodeName)) < 0) {
--
1.7.3.2
13 years, 10 months
[libvirt] VirtualBox error message displayed on windows
by Justin Clift
Hi Matthias,
Just came across an interesting (non fatal) bug with the new VirtualBox code on
windows.
When starting virsh on a windows system that *doesn't* have VirtualBox installed,
virsh prints an error to the users terminal about missing VirtualBox registry keys,
then continues on with it's intended operation. (screenshot attached)
It's not a killer, but the error makes no sense in context when I'm (for example)
trying to connect to a remote qemu box. Heh.
Feel inclined to write a patch for it?
Regards and best wishes,
Justin Clift
13 years, 10 months
[libvirt] [PATCH] Basic support for VDE networking
by Renzo Davoli
I have seen several messages asking for VDE networking support.
There is an item also in your todo web page.
http://libvirt.org/todo.html
I have developed a patch to provide a basic support for VDE.
It defines and manages the syntax:
<domain ....>
<device>
<interface type='vde'>
...
<switch path='/tmp/vde.ctl'/>
</interface>
</device>
</domain>
the switch tag can be omitted: vde uses the default switch.
I have tested the qemu/kvm support.
user-mode linux support is included but not tested yet.
libvirt vde support for virtualbox has not been coded yet (virtualbox
itself supports vde).
The patch is against libvirt-0.8.7.
renzo
(designer/developer of VDE, university of bologna, wiki.virtualsquare.org)
(I have not subscribed the ML, please Cc: to me your reply messages)
Signed-off-by: Renzo Davoli <renzo(a)cs.unibo.it>
---
--- a/src/lxc/lxc_driver.c 2011-01-10 11:49:49.000000000 +0100
+++ b/src/lxc/lxc_driver.c 2011-01-10 11:50:03.000000000 +0100
@@ -1083,6 +1083,7 @@
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_LAST:
+ case VIR_DOMAIN_NET_TYPE_VDE:
break;
}
--- a/src/uml/uml_conf.c 2011-01-10 12:03:54.000000000 +0100
+++ b/src/uml/uml_conf.c 2011-01-10 13:26:08.000000000 +0100
@@ -269,6 +269,14 @@
virBufferVSprintf(&buf, "tuntap,%s", def->ifname);
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ /* ethNNN=vde,vde_switch,macaddr,port,group,mode,description */
+ if (def->data.vde.vdeswitch) {
+ virBufferVSprintf(&buf, "vde,%s", def->data.vde.vdeswitch);
+ } else
+ virBufferAddLit(&buf, "vde");
+ break;
+
case VIR_DOMAIN_NET_TYPE_INTERNAL:
umlReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("internal networking type not supported"));
--- a/src/conf/domain_conf.h 2011-01-10 11:41:07.000000000 +0100
+++ b/src/conf/domain_conf.h 2011-01-10 13:21:08.000000000 +0100
@@ -288,6 +288,7 @@
VIR_DOMAIN_NET_TYPE_BRIDGE,
VIR_DOMAIN_NET_TYPE_INTERNAL,
VIR_DOMAIN_NET_TYPE_DIRECT,
+ VIR_DOMAIN_NET_TYPE_VDE,
VIR_DOMAIN_NET_TYPE_LAST,
};
@@ -336,6 +337,9 @@
int mode;
virVirtualPortProfileParams virtPortProfile;
} direct;
+ struct {
+ char *vdeswitch;
+ } vde;
} data;
char *ifname;
virDomainDeviceInfo info;
--- a/src/conf/domain_conf.c 2011-01-10 11:42:04.000000000 +0100
+++ b/src/conf/domain_conf.c 2011-01-10 14:49:46.000000000 +0100
@@ -182,7 +182,8 @@
"network",
"bridge",
"internal",
- "direct")
+ "direct",
+ "vde")
VIR_ENUM_IMPL(virDomainChrChannelTarget,
VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST,
@@ -598,6 +599,10 @@
VIR_FREE(def->data.direct.linkdev);
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ VIR_FREE(def->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
@@ -2293,6 +2298,7 @@
char *internal = NULL;
char *devaddr = NULL;
char *mode = NULL;
+ char *vdeswitch = NULL;
virNWFilterHashTablePtr filterparams = NULL;
virVirtualPortProfileParams virtPort;
bool virtPortParsed = false;
@@ -2379,7 +2385,11 @@
xmlStrEqual(cur->name, BAD_CAST "state")) {
/* Legacy back-compat. Don't add any more attributes here */
devaddr = virXMLPropString(cur, "devaddr");
- }
+ } else if ((vdeswitch == NULL) &&
+ def->type == VIR_DOMAIN_NET_TYPE_VDE &&
+ xmlStrEqual(cur->name, BAD_CAST "switch")) {
+ vdeswitch = virXMLPropString(cur, "path");
+ }
}
cur = cur->next;
}
@@ -2529,6 +2539,11 @@
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ def->data.vde.vdeswitch = vdeswitch;
+ vdeswitch = NULL;
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
@@ -6263,6 +6278,12 @@
" ");
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ if (def->data.vde.vdeswitch)
+ virBufferEscapeString(buf, " <switch path='%s'/>\n",
+ def->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
--- a/src/qemu/qemu_command.c 2011-01-10 13:11:17.000000000 +0100
+++ b/src/qemu/qemu_command.c 2011-01-10 13:26:28.000000000 +0100
@@ -1602,12 +1602,21 @@
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
+ case VIR_DOMAIN_NET_TYPE_VDE:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
type_sep = ',';
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ virBufferAddLit(&buf, "vde");
+ if (net->data.vde.vdeswitch)
+ virBufferVSprintf(&buf, "%csock=%s",
+ type_sep,
+ net->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
default:
virBufferAddLit(&buf, "user");
13 years, 10 months
[libvirt] [PATCH] daemon: Fix core dumps if unix_sock_group is set
by Jiri Denemark
Setting unix_sock_group to something else than default "root" in
/etc/libvirt/libvirtd.conf prevents system libvirtd from dumping core on
crash. This is because we used setgid(unix_sock_group) before binding to
/var/run/libvirt/libvirt-sock* and setgid() back to original group.
However, if a process changes its effective or filesystem group ID, it
will be forbidden from leaving core dumps unless fs.suid_dumpable sysctl
is set to something else then 0 (and it is 0 by default).
Changing socket's group ownership after bind works better. And we can do
so without introducing a race condition since we loosen access rights by
changing the group from root to something else.
---
daemon/libvirtd.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 2df9337..b1539b1 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -542,7 +542,6 @@ static int qemudListenUnix(struct qemud_server *server,
char *path, int readonly, int auth) {
struct qemud_socket *sock;
mode_t oldmask;
- gid_t oldgrp;
char ebuf[1024];
if (VIR_ALLOC(sock) < 0) {
@@ -579,21 +578,21 @@ static int qemudListenUnix(struct qemud_server *server,
if (sock->addr.data.un.sun_path[0] == '@')
sock->addr.data.un.sun_path[0] = '\0';
- oldgrp = getgid();
oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask);
- if (server->privileged && setgid(unix_sock_gid)) {
- VIR_ERROR(_("Failed to set group ID to %d"), unix_sock_gid);
- goto cleanup;
- }
-
if (bind(sock->fd, &sock->addr.data.sa, sock->addr.len) < 0) {
VIR_ERROR(_("Failed to bind socket to '%s': %s"),
path, virStrerror(errno, ebuf, sizeof ebuf));
goto cleanup;
}
umask(oldmask);
- if (server->privileged && setgid(oldgrp)) {
- VIR_ERROR(_("Failed to restore group ID to %d"), oldgrp);
+
+ /* chown() doesn't work for abstract sockets but we use them only
+ * if libvirtd runs unprivileged
+ */
+ if (server->privileged && chown(path, -1, unix_sock_gid)) {
+ VIR_ERROR(_("Failed to change group ID of '%s' to %d: %s"),
+ path, unix_sock_gid,
+ virStrerror(errno, ebuf, sizeof ebuf));
goto cleanup;
}
--
1.7.4.rc1
13 years, 10 months
[libvirt] [PATCH v3] Refactor the security drivers to simplify usage
by Daniel P. Berrange
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
13 years, 10 months
[libvirt] Implementing VNC per VM access control lists
by Neil Wilson
Hi,
At the moment SASL VNC authentication in libvirt allows any of the
userids to access any of the VNC consoles on a particular libvirt host.
There is a section in the qemu_command code marked "TODO: Support ACLs
later" and we would really like the ability to have per VM user
authorization to the VNC console from within libvirt.
Essentially the people who are accessing the VNC consoles are not
administrators and have no access to the Host server - so these ACLs
need to be completely based on a separate list of userids to any access
mechanism for the libvirtd itself.
Given that the VNC restrictions are enforced within qemu from the
monitor system, I'm presuming the authorization list is going to have to
be passed in via XML and be capable of being updated throughout the life
of a VM session. Unless there's another way of doing it...
What's the feeling about how this feature should be provided within
libvirt?
If there is somebody out there who has a bit of time at the moment and
fancies having a go at implementing this - and, of course, there is
agreement on a specification here - then we'd look at sponsoring them to
add the feature into Libvirt. Please put your hand up!
Regards,
Neil Wilson
13 years, 10 months
[libvirt] virsh save command will throw an error when used with qemu
by oliver
Hey subscribers,
I have a problem with the actual libvirt/virsh release and qemu-kvm
0.13. if i want to save the actual status of my virtual machine i get
the following error:
lserver ~ # virsh save windows /virtual/windows_ram
error: Failed to save domain windows to /virtual/windows_ram
error: internal error unable to execute QEMU command 'migrate': An
undefined error has ocurred
First i asked in OFTC but there was said, that this could be an error
with the qemu console command.
The system details:
lserver ~ # uname -a
Linux lserver 2.6.36.2 #2 SMP PREEMPT Wed Dec 29 02:58:41 Local time
zone must be set-- x86_64 Intel(R) Core(TM) i5 CPU K 655 @ 3.20GHz
GenuineIntel GNU/Linux
lserver ~ # virsh --version
0.8.7
lserver ~ # qemu-kvm --version
QEMU emulator version 0.13.0 (qemu-kvm-0.13.0), Copyright (c)
2003-2008 Fabrice Bellard
root 28673 7.7 81.5 3184544 3092128 ? Sl Jan09 72:19
/usr/bin/qemu-system-x86_64 --enable-kvm -S -M pc-0.13 -enable-kvm -m
3000 -smp 2,sockets=2,cores=1,threads=1 -name windows -uuid
30c59551-5571-a177-9036-1d5d51cb76b2 -nodefconfig -nodefaults -chardev
socket,id=monitor,path=/var/lib/libvirt/qemu/windows.monitor,server,nowait
-mon chardev=monitor,mode=control -rtc base=localtime -boot c -drive
file=/virtual/server2003.img,if=none,id=drive-ide0-0-0,format=raw
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0
-netdev tap,fd=39,id=hostnet0 -device
e1000,netdev=hostnet0,id=net0,mac=52:54:00:12:34:70,bus=pci.0,addr=0x3
-chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -device
usb-tablet,id=input0 -vnc 127.0.0.1:0 -k de -vga std -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
It was for me not possible to get further debug info from libvirt.
Best regards,
Oliver Lott
13 years, 10 months
[libvirt] Fwd: libvirtd and listen_addr
by Daniel Huhardeaux
Hello,
got no reaction on this, I try again :-)
-------- Message original --------
Sujet: libvirtd and listen_addr
Date : Sat, 01 Jan 2011 11:33:55 +0100
De : Daniel Huhardeaux <tech(a)tootai.net>
Pour : libvir-list(a)redhat.com
Hi,
at first, best wishes to all for this new year.
We have a request: would it be possible to start libvirtd listen_addr
*after* the VM network is up?
We have VPN through different libvirt+kvm servers and want to virsh
connect to the private VM network address of each server instead of his
VPN IP. The problem is that libvirt doesn't start with unknown IP
address. If network would be already up, libvirt could listen on this
address.
Regards
libvirtd (libvirt) 0.8.3 - Debian stable + backports
--
Daniel
13 years, 10 months