domain_audit.c 19.5 KB
Newer Older
1
/*
2
 * domain_audit.c: Domain audit management
3
 *
4
 * Copyright (C) 2006-2012 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * 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
O
Osier Yang 已提交
18 19
 * License along with this library;  If not, see
 * <http://www.gnu.org/licenses/>.
20 21 22 23 24 25
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

26 27 28
#include <sys/stat.h>
#include <sys/types.h>

29
#include "domain_audit.h"
30
#include "viraudit.h"
31 32 33 34
#include "uuid.h"
#include "logging.h"
#include "memory.h"

35 36 37 38
/* Return nn:mm in hex for block and character devices, and NULL
 * for other file types, stat failure, or allocation failure.  */
#if defined major && defined minor
static char *
39
virDomainAuditGetRdev(const char *path)
40 41 42 43 44 45 46 47
{
    char *ret = NULL;
    struct stat sb;

    if (stat(path, &sb) == 0 &&
        (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode))) {
        int maj = major(sb.st_rdev);
        int min = minor(sb.st_rdev);
48
        ignore_value(virAsprintf(&ret, "%02X:%02X", maj, min));
49 50 51 52 53
    }
    return ret;
}
#else
static char *
54
virDomainAuditGetRdev(const char *path ATTRIBUTE_UNUSED)
55 56 57 58 59
{
    return NULL;
}
#endif

60
void
61
virDomainAuditDisk(virDomainObjPtr vm,
62
                   const char *oldDef, const char *newDef,
63
                   const char *reason, bool success)
64 65 66 67 68
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
    char *oldsrc = NULL;
    char *newsrc = NULL;
69
    const char *virt;
70 71 72

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
73
        VIR_WARN("OOM while encoding audit message");
74 75 76
        return;
    }

77 78 79 80 81
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

82
    if (!(oldsrc = virAuditEncode("old-disk", VIR_AUDIT_STR(oldDef)))) {
83
        VIR_WARN("OOM while encoding audit message");
84 85
        goto cleanup;
    }
86
    if (!(newsrc = virAuditEncode("new-disk", VIR_AUDIT_STR(newDef)))) {
87
        VIR_WARN("OOM while encoding audit message");
88 89 90 91
        goto cleanup;
    }

    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
92 93
              "virt=%s resrc=disk reason=%s %s uuid=%s %s %s",
              virt, reason, vmname, uuidstr,
94 95 96 97 98 99 100 101 102
              oldsrc, newsrc);

cleanup:
    VIR_FREE(vmname);
    VIR_FREE(oldsrc);
    VIR_FREE(newsrc);
}


D
Daniel P. Berrange 已提交
103 104 105 106 107 108 109 110 111
void
virDomainAuditFS(virDomainObjPtr vm,
                 virDomainFSDefPtr oldDef, virDomainFSDefPtr newDef,
                 const char *reason, bool success)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
    char *oldsrc = NULL;
    char *newsrc = NULL;
112
    const char *virt;
D
Daniel P. Berrange 已提交
113 114 115 116 117 118 119

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
        VIR_WARN("OOM while encoding audit message");
        return;
    }

120 121 122 123 124
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

D
Daniel P. Berrange 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137 138
    if (!(oldsrc = virAuditEncode("old-fs",
                                  oldDef && oldDef->src ?
                                  oldDef->src : "?"))) {
        VIR_WARN("OOM while encoding audit message");
        goto cleanup;
    }
    if (!(newsrc = virAuditEncode("new-fs",
                                  newDef && newDef->src ?
                                  newDef->src : "?"))) {
        VIR_WARN("OOM while encoding audit message");
        goto cleanup;
    }

    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
139 140
              "virt=%s resrc=fs reason=%s %s uuid=%s %s %s",
              virt, reason, vmname, uuidstr,
D
Daniel P. Berrange 已提交
141 142 143 144 145 146 147 148 149
              oldsrc, newsrc);

cleanup:
    VIR_FREE(vmname);
    VIR_FREE(oldsrc);
    VIR_FREE(newsrc);
}


150
void
151 152 153
virDomainAuditNet(virDomainObjPtr vm,
                  virDomainNetDefPtr oldDef, virDomainNetDefPtr newDef,
                  const char *reason, bool success)
154 155 156 157 158
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char newMacstr[VIR_MAC_STRING_BUFLEN];
    char oldMacstr[VIR_MAC_STRING_BUFLEN];
    char *vmname;
159
    const char *virt;
160 161 162

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (oldDef)
163
        virMacAddrFormat(&oldDef->mac, oldMacstr);
164
    if (newDef)
165
        virMacAddrFormat(&newDef->mac, newMacstr);
166
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
167
        VIR_WARN("OOM while encoding audit message");
168 169 170
        return;
    }

171 172 173 174 175
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

176
    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
177
              "virt=%s resrc=net reason=%s %s uuid=%s old-net=%s new-net=%s",
178
              virt, reason, vmname, uuidstr,
179 180 181 182 183 184
              oldDef ? oldMacstr : "?",
              newDef ? newMacstr : "?");

    VIR_FREE(vmname);
}

185
/**
186
 * virDomainAuditNetDevice:
187 188 189 190
 * @vm: domain opening a network-related device
 * @def: details of network device that fd will be tied to
 * @device: device being opened (such as /dev/vhost-net,
 * /dev/net/tun, /dev/tanN). Note that merely opening a device
191
 * does not mean that virDomain owns it; a followup virDomainAuditNet
192 193 194 195 196 197
 * shows whether the fd was passed on.
 * @success: true if the device was opened
 *
 * Log an audit message about an attempted network device open.
 */
void
198 199
virDomainAuditNetDevice(virDomainDefPtr vmDef, virDomainNetDefPtr netDef,
                        const char *device, bool success)
200 201 202 203
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char macstr[VIR_MAC_STRING_BUFLEN];
    char *vmname;
204
    char *dev_name;
205
    char *rdev;
206
    const char *virt;
207 208

    virUUIDFormat(vmDef->uuid, uuidstr);
209
    virMacAddrFormat(&netDef->mac, macstr);
210
    rdev = virDomainAuditGetRdev(device);
211 212

    if (!(vmname = virAuditEncode("vm", vmDef->name)) ||
213
        !(dev_name = virAuditEncode("path", device))) {
214
        VIR_WARN("OOM while encoding audit message");
215 216 217
        goto cleanup;
    }

218 219 220 221 222
    if (!(virt = virDomainVirtTypeToString(vmDef->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vmDef->virtType);
        virt = "?";
    }

223
    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
224
              "virt=%s resrc=net reason=open %s uuid=%s net=%s %s rdev=%s",
225
              virt, vmname, uuidstr, macstr, dev_name, VIR_AUDIT_STR(rdev));
226 227 228

cleanup:
    VIR_FREE(vmname);
229
    VIR_FREE(dev_name);
230 231
    VIR_FREE(rdev);
}
232

233
/**
234
 * virDomainAuditHostdev:
235 236
 * @vm: domain making a change in pass-through host device
 * @hostdev: device being attached or removed
237
 * @reason: one of "start", "attach", or "detach"
238 239 240 241 242
 * @success: true if the device passthrough operation succeeded
 *
 * Log an audit message about an attempted device passthrough change.
 */
void
243 244
virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
                      const char *reason, bool success)
245 246 247
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
248 249
    char *address = NULL;
    char *device = NULL;
250
    const char *virt;
251 252 253

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
254
        VIR_WARN("OOM while encoding audit message");
255 256 257
        return;
    }

258 259 260 261 262
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

263 264 265 266 267 268 269
    switch (hostdev->source.subsys.type) {
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
        if (virAsprintf(&address, "%.4x:%.2x:%.2x.%.1x",
                        hostdev->source.subsys.u.pci.domain,
                        hostdev->source.subsys.u.pci.bus,
                        hostdev->source.subsys.u.pci.slot,
                        hostdev->source.subsys.u.pci.function) < 0) {
270
            VIR_WARN("OOM while encoding audit message");
271 272 273 274 275 276 277
            goto cleanup;
        }
        break;
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
        if (virAsprintf(&address, "%.3d.%.3d",
                        hostdev->source.subsys.u.usb.bus,
                        hostdev->source.subsys.u.usb.device) < 0) {
278
            VIR_WARN("OOM while encoding audit message");
279 280 281 282 283 284 285 286 287 288
            goto cleanup;
        }
        break;
    default:
        VIR_WARN("Unexpected hostdev type while encoding audit message: %d",
                 hostdev->source.subsys.type);
        goto cleanup;
    }

    if (!(device = virAuditEncode("device", VIR_AUDIT_STR(address)))) {
289
        VIR_WARN("OOM while encoding audit message");
290 291 292 293
        goto cleanup;
    }

    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
294 295
              "virt=%s resrc=dev reason=%s %s uuid=%s bus=%s %s",
              virt, reason, vmname, uuidstr,
296 297 298 299 300 301 302 303 304 305
              virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type),
              device);

cleanup:
    VIR_FREE(vmname);
    VIR_FREE(device);
    VIR_FREE(address);
}


306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
/**
 * virDomainAuditRedirdev:
 * @vm: domain making a change in pass-through host device
 * @redirdev: device being attached or removed
 * @reason: one of "start", "attach", or "detach"
 * @success: true if the device passthrough operation succeeded
 *
 * Log an audit message about an attempted device passthrough change.
 */
void
virDomainAuditRedirdev(virDomainObjPtr vm, virDomainRedirdevDefPtr redirdev,
                      const char *reason, bool success)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
321 322
    char *address = NULL;
    char *device = NULL;
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
    const char *virt;

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
        VIR_WARN("OOM while encoding audit message");
        return;
    }

    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

    switch (redirdev->bus) {
    case VIR_DOMAIN_REDIRDEV_BUS_USB:
        if (virAsprintf(&address, "USB redirdev") < 0) {
            VIR_WARN("OOM while encoding audit message");
            goto cleanup;
        }
342
        break;
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
    default:
        VIR_WARN("Unexpected redirdev bus while encoding audit message: %d",
                 redirdev->bus);
        goto cleanup;
    }

    if (!(device = virAuditEncode("device", VIR_AUDIT_STR(address)))) {
        VIR_WARN("OOM while encoding audit message");
        goto cleanup;
    }

    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
              "virt=%s resrc=dev reason=%s %s uuid=%s bus=%s %s",
              virt, reason, vmname, uuidstr,
              virDomainRedirdevBusTypeToString(redirdev->bus),
              device);

cleanup:
    VIR_FREE(vmname);
    VIR_FREE(device);
    VIR_FREE(address);
}


367
/**
368
 * virDomainAuditCgroup:
369 370 371
 * @vm: domain making the cgroups ACL change
 * @cgroup: cgroup that manages the devices
 * @reason: either "allow" or "deny"
372 373
 * @extra: additional details, in the form "all",
 * "major category=xyz maj=nn", or "path path=xyz dev=nn:mm" (the
374 375
 * latter two are generated by virDomainAuditCgroupMajor and
 * virDomainAuditCgroupPath).
376 377 378 379
 * @success: true if the cgroup operation succeeded
 *
 * Log an audit message about an attempted cgroup device ACL change.
 */
380
void
381 382
virDomainAuditCgroup(virDomainObjPtr vm, virCgroupPtr cgroup,
                     const char *reason, const char *extra, bool success)
383 384 385
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
386 387
    char *controller = NULL;
    char *detail;
388
    const char *virt;
389 390 391

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
392
        VIR_WARN("OOM while encoding audit message");
393 394
        return;
    }
395

396 397 398 399 400
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

E
Eric Blake 已提交
401 402 403
    ignore_value(virCgroupPathOfController(cgroup,
                                           VIR_CGROUP_CONTROLLER_DEVICES,
                                           NULL, &controller));
404 405
    detail = virAuditEncode("cgroup", VIR_AUDIT_STR(controller));

406
    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
407 408
              "virt=%s resrc=cgroup reason=%s %s uuid=%s %s class=%s",
              virt, reason, vmname, uuidstr,
409
              detail ? detail : "cgroup=?", extra);
410 411

    VIR_FREE(vmname);
412 413
    VIR_FREE(controller);
    VIR_FREE(detail);
414 415 416
}

/**
417
 * virDomainAuditCgroupMajor:
418 419 420 421 422
 * @vm: domain making the cgroups ACL change
 * @cgroup: cgroup that manages the devices
 * @reason: either "allow" or "deny"
 * @maj: the major number of the device category
 * @name: a textual name for that device category, alphabetic only
423
 * @perms: string containing "r", "w", and/or "m" as appropriate
424 425 426 427 428
 * @success: true if the cgroup operation succeeded
 *
 * Log an audit message about an attempted cgroup device ACL change.
 */
void
429 430 431
virDomainAuditCgroupMajor(virDomainObjPtr vm, virCgroupPtr cgroup,
                          const char *reason, int maj, const char *name,
                          const char *perms, bool success)
432 433 434
{
    char *extra;

435 436
    if (virAsprintf(&extra, "major category=%s maj=%02X acl=%s",
                    name, maj, perms) < 0) {
437
        VIR_WARN("OOM while encoding audit message");
438 439 440
        return;
    }

441
    virDomainAuditCgroup(vm, cgroup, reason, extra, success);
442 443 444 445 446

    VIR_FREE(extra);
}

/**
447
 * virDomainAuditCgroupPath:
448 449 450 451
 * @vm: domain making the cgroups ACL change
 * @cgroup: cgroup that manages the devices
 * @reason: either "allow" or "deny"
 * @path: the device being adjusted
452
 * @perms: string containing "r", "w", and/or "m" as appropriate
453 454 455 456 457 458
 * @rc: > 0 if not a device, 0 if success, < 0 if failure
 *
 * Log an audit message about an attempted cgroup device ACL change to
 * a specific device.
 */
void
459 460 461
virDomainAuditCgroupPath(virDomainObjPtr vm, virCgroupPtr cgroup,
                         const char *reason, const char *path, const char *perms,
                         int rc)
462 463 464 465 466 467 468 469 470
{
    char *detail;
    char *rdev;
    char *extra;

    /* Nothing to audit for regular files.  */
    if (rc > 0)
        return;

471
    rdev = virDomainAuditGetRdev(path);
472 473

    if (!(detail = virAuditEncode("path", path)) ||
474 475
        virAsprintf(&extra, "path path=%s rdev=%s acl=%s",
                    path, VIR_AUDIT_STR(rdev), perms) < 0) {
476
        VIR_WARN("OOM while encoding audit message");
477 478 479
        goto cleanup;
    }

480
    virDomainAuditCgroup(vm, cgroup, reason, extra, rc == 0);
481 482

cleanup:
483
    VIR_FREE(extra);
484
    VIR_FREE(detail);
485
    VIR_FREE(rdev);
486 487
}

488
/**
489
 * virDomainAuditResource:
490 491 492 493 494 495 496 497 498 499
 * @vm: domain making an integer resource change
 * @resource: name of the resource: "mem" or "vcpu"
 * @oldval: the old value of the resource
 * @newval: the new value of the resource
 * @reason: either "start" or "update"
 * @success: true if the resource change succeeded
 *
 * Log an audit message about an attempted resource change.
 */
static void
500 501 502
virDomainAuditResource(virDomainObjPtr vm, const char *resource,
                       unsigned long long oldval, unsigned long long newval,
                       const char *reason, bool success)
503 504 505
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
506
    const char *virt;
507 508 509

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
510
        VIR_WARN("OOM while encoding audit message");
511 512 513
        return;
    }

514 515 516 517 518
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

519
    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
520 521
              "virt=%s resrc=%s reason=%s %s uuid=%s old-%s=%lld new-%s=%lld",
              virt, resource, reason, vmname, uuidstr,
522 523 524 525 526 527
              resource, oldval, resource, newval);

    VIR_FREE(vmname);
}

void
528 529 530
virDomainAuditMemory(virDomainObjPtr vm,
                     unsigned long long oldmem, unsigned long long newmem,
                     const char *reason, bool success)
531
{
532
    return virDomainAuditResource(vm, "mem", oldmem, newmem, reason, success);
533 534 535
}

void
536 537 538
virDomainAuditVcpu(virDomainObjPtr vm,
                   unsigned int oldvcpu, unsigned int newvcpu,
                   const char *reason, bool success)
539
{
540
    return virDomainAuditResource(vm, "vcpu", oldvcpu, newvcpu, reason, success);
541 542
}

543
static void
544 545
virDomainAuditLifecycle(virDomainObjPtr vm, const char *op,
                        const char *reason, bool success)
546 547 548
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
549
    const char *virt;
550 551 552 553

    virUUIDFormat(vm->def->uuid, uuidstr);

    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
554
        VIR_WARN("OOM while encoding audit message");
555 556 557
        return;
    }

558 559 560 561 562
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

563
    VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_CONTROL, success,
564 565
              "virt=%s op=%s reason=%s %s uuid=%s vm-pid=%lld",
              virt, op, reason, vmname, uuidstr, (long long)vm->pid);
566 567 568 569 570

    VIR_FREE(vmname);
}


571
void
572
virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
573 574 575 576 577 578
{
    int i;

    for (i = 0 ; i < vm->def->ndisks ; i++) {
        virDomainDiskDefPtr disk = vm->def->disks[i];
        if (disk->src) /* Skips CDROM without media initially inserted */
579
            virDomainAuditDisk(vm, NULL, disk->src, "start", true);
580 581
    }

D
Daniel P. Berrange 已提交
582 583 584 585 586
    for (i = 0 ; i < vm->def->nfss ; i++) {
        virDomainFSDefPtr fs = vm->def->fss[i];
        virDomainAuditFS(vm, NULL, fs, "start", true);
    }

587 588
    for (i = 0 ; i < vm->def->nnets ; i++) {
        virDomainNetDefPtr net = vm->def->nets[i];
589
        virDomainAuditNet(vm, NULL, net, "start", true);
590 591
    }

592 593
    for (i = 0 ; i < vm->def->nhostdevs ; i++) {
        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
594
        virDomainAuditHostdev(vm, hostdev, "start", true);
595 596
    }

597 598 599 600 601
    for (i = 0 ; i < vm->def->nredirdevs ; i++) {
        virDomainRedirdevDefPtr redirdev = vm->def->redirdevs[i];
        virDomainAuditRedirdev(vm, redirdev, "start", true);
    }

602 603
    virDomainAuditMemory(vm, 0, vm->def->mem.cur_balloon, "start", true);
    virDomainAuditVcpu(vm, 0, vm->def->vcpus, "start", true);
604

605
    virDomainAuditLifecycle(vm, "start", reason, success);
606 607 608
}


609
void
610
virDomainAuditStop(virDomainObjPtr vm, const char *reason)
611
{
612
    virDomainAuditLifecycle(vm, "stop", reason, true);
613 614
}

615
void
616
virDomainAuditSecurityLabel(virDomainObjPtr vm, bool success)
617 618 619
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    char *vmname;
620
    const char *virt;
621
    int i;
622 623 624

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
625
        VIR_WARN("OOM while encoding audit message");
626 627 628
        return;
    }

629 630 631 632 633
    if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
        VIR_WARN("Unexpected virt type %d while encoding audit message", vm->def->virtType);
        virt = "?";
    }

634 635 636 637 638 639 640 641
    for (i = 0; i < vm->def->nseclabels; i++) {
        VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_ID, success,
                  "virt=%s %s uuid=%s vm-ctx=%s img-ctx=%s model=%s",
                  virt, vmname, uuidstr,
                  VIR_AUDIT_STR(vm->def->seclabels[i]->label),
                  VIR_AUDIT_STR(vm->def->seclabels[i]->imagelabel),
                  VIR_AUDIT_STR(vm->def->seclabels[i]->model));
    }
642 643 644

    VIR_FREE(vmname);
}