From 7a5a3e1fbd72e8bcc12b864577b1d8315dfafedc Mon Sep 17 00:00:00 2001 Message-Id: <7a5a3e1fbd72e8bcc12b864577b1d8315dfafedc.1288197060.git.jdenemar@redhat.com> From: Daniel P. Berrange <berrange@redhat.com> Date: Wed, 27 Oct 2010 15:15:26 +0100 Subject: [PATCH] Add auditing of start/stop events to the QEMU driver Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=587280 Add audit hooks to report all start and stop events on QEMU guest domains. * src/qemu/qemu_driver.c: Audit start/stop events (from 62622f841a156bd1cec31e73e6185ce9331299e9) --- src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4a69852..5ed3739 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -77,6 +77,7 @@ #include "domain_nwfilter.h" #include "hooks.h" #include "storage_file.h" +#include "virtaudit.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -157,6 +158,9 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver, virDomainObjPtr vm, int migrated); +static void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason, bool success); +static void qemuDomainStopAudit(virDomainObjPtr vm, const char *reason); + static int qemudDomainGetMaxVcpus(virDomainPtr dom); static int qemuDetectVcpuPIDs(struct qemud_driver *driver, @@ -746,6 +750,8 @@ qemuHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); qemudShutdownVMDaemon(driver, vm, 0); + qemuDomainStopAudit(vm, hasError ? "failed" : "shutdown"); + if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); else @@ -3390,6 +3396,36 @@ static int qemuDomainSnapshotSetActive(virDomainObjPtr vm, static int qemuDomainSnapshotSetInactive(virDomainObjPtr vm, char *snapshotDir); +static void qemuDomainLifecycleAudit(virDomainObjPtr vm, + const char *op, + const char *reason, + bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + + virUUIDFormat(vm->def->uuid, uuidstr); + if (!(vmname = virAuditEncode("vm", vm->def->name))) { + VIR_WARN0("OOM while encoding audit message"); + return; + } + + VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_CONTROL, success, + "op=%s reason=%s %s uuid=%s", op, reason, vmname, uuidstr); + + VIR_FREE(vmname); +} + +static void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason, bool success) +{ + qemuDomainLifecycleAudit(vm, "start", reason, success); +} + +static void qemuDomainStopAudit(virDomainObjPtr vm, const char *reason) +{ + qemuDomainLifecycleAudit(vm, "stop", reason, true); +} + static int qemudStartVMDaemon(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, @@ -4325,6 +4361,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (qemudStartVMDaemon(conn, driver, vm, NULL, (flags & VIR_DOMAIN_START_PAUSED) != 0, -1, NULL) < 0) { + qemuDomainStartAudit(vm, "booted", false); if (qemuDomainObjEndJob(vm) > 0) virDomainRemoveInactive(&driver->domains, vm); @@ -4335,6 +4372,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_BOOTED); + qemuDomainStartAudit(vm, "booted", true); dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) dom->id = vm->def->id; @@ -4562,6 +4600,8 @@ static int qemudDomainDestroy(virDomainPtr dom) { event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); + qemuDomainStopAudit(vm, "destroyed"); + if (!vm->persistent) { if (qemuDomainObjEndJob(vm) > 0) virDomainRemoveInactive(&driver->domains, @@ -5277,6 +5317,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, /* Shut it down */ qemudShutdownVMDaemon(driver, vm, 0); + qemuDomainStopAudit(vm, "saved"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); @@ -5597,6 +5638,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, endjob: if ((ret == 0) && (flags & VIR_DUMP_CRASH)) { qemudShutdownVMDaemon(driver, vm, 0); + qemuDomainStopAudit(vm, "crashed"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_CRASHED); @@ -6352,12 +6394,15 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, } } - if (ret < 0) + if (ret < 0) { + qemuDomainStartAudit(vm, "restored", false); goto out; + } event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_RESTORED); + qemuDomainStartAudit(vm, "restored", true); if (event) qemuDomainEventQueue(driver, event); @@ -6782,7 +6827,8 @@ static int qemudDomainObjStart(virConnectPtr conn, } ret = qemudStartVMDaemon(conn, driver, vm, NULL, start_paused, -1, NULL); - if (ret != -1) { + qemuDomainStartAudit(vm, "booted", ret >= 0); + if (ret >= 0) { virDomainEventPtr event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, @@ -10321,6 +10367,7 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn, -1, NULL); VIR_FREE(migrateFrom); if (internalret < 0) { + qemuDomainStartAudit(vm, "migrated", false); /* Note that we don't set an error here because qemudStartVMDaemon * should have already done that. */ @@ -10333,6 +10380,7 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn, qemust = qemuStreamMigOpen(st, unixfile); if (qemust == NULL) { + qemuDomainStartAudit(vm, "migrated", false); qemudShutdownVMDaemon(driver, vm, 0); if (!vm->persistent) { if (qemuDomainObjEndJob(vm) > 0) @@ -10348,6 +10396,7 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn, st->driver = &qemuStreamMigDrv; st->privateData = qemust; + qemuDomainStartAudit(vm, "migrated", true); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_MIGRATED); @@ -10563,6 +10612,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn, snprintf (migrateFrom, sizeof (migrateFrom), "tcp:0.0.0.0:%d", this_port); if (qemudStartVMDaemon (dconn, driver, vm, migrateFrom, true, -1, NULL) < 0) { + qemuDomainStartAudit(vm, "migrated", false); /* Note that we don't set an error here because qemudStartVMDaemon * should have already done that. */ @@ -10574,6 +10624,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn, goto endjob; } + qemuDomainStartAudit(vm, "migrated", true); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_MIGRATED); @@ -11131,6 +11182,7 @@ qemudDomainMigratePerform (virDomainPtr dom, /* Clean up the source domain. */ qemudShutdownVMDaemon(driver, vm, 1); + qemuDomainStopAudit(vm, "migrated"); resume = 0; event = virDomainEventNewFromObj(vm, @@ -11300,6 +11352,7 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn, } } else { qemudShutdownVMDaemon(driver, vm, 1); + qemuDomainStopAudit(vm, "failed"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_FAILED); @@ -12129,6 +12182,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, rc = qemudStartVMDaemon(snapshot->domain->conn, driver, vm, NULL, false, -1, NULL); + qemuDomainStartAudit(vm, "from-snapshot", rc >= 0); if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0) goto endjob; if (rc < 0) @@ -12168,6 +12222,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, if (virDomainObjIsActive(vm)) { qemudShutdownVMDaemon(driver, vm, 0); + qemuDomainStopAudit(vm, "from-snapshot"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT); -- 1.7.3.2