security_dac.c 39.7 KB
Newer Older
1
/*
2
 * Copyright (C) 2010-2014 Red Hat, Inc.
3 4 5 6 7 8 9 10 11 12 13 14
 *
 * 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
15
 * License along with this library.  If not, see
O
Osier Yang 已提交
16
 * <http://www.gnu.org/licenses/>.
17 18 19 20 21 22 23 24 25 26
 *
 * POSIX DAC security driver
 */

#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "security_dac.h"
27
#include "virerror.h"
28
#include "virfile.h"
29
#include "viralloc.h"
30
#include "virlog.h"
31
#include "virpci.h"
32
#include "virusb.h"
33
#include "virscsi.h"
34
#include "virstoragefile.h"
35
#include "virstring.h"
M
Martin Kletzander 已提交
36
#include "virutil.h"
37 38

#define VIR_FROM_THIS VIR_FROM_SECURITY
39 40 41

VIR_LOG_INIT("security.security_dac");

42
#define SECURITY_DAC_NAME "dac"
43 44 45 46 47 48 49

typedef struct _virSecurityDACData virSecurityDACData;
typedef virSecurityDACData *virSecurityDACDataPtr;

struct _virSecurityDACData {
    uid_t user;
    gid_t group;
50 51
    gid_t *groups;
    int ngroups;
52
    bool dynamicOwnership;
53
    char *baselabel;
54
    virSecurityManagerDACChownCallback chownCallback;
55 56
};

57 58 59 60 61 62 63 64
typedef struct _virSecurityDACCallbackData virSecurityDACCallbackData;
typedef virSecurityDACCallbackData *virSecurityDACCallbackDataPtr;

struct _virSecurityDACCallbackData {
    virSecurityManagerPtr manager;
    virSecurityLabelDefPtr secdef;
};

65 66 67 68 69
/* returns -1 on error, 0 on success */
int
virSecurityDACSetUserAndGroup(virSecurityManagerPtr mgr,
                              uid_t user,
                              gid_t group)
70 71 72 73
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->user = user;
    priv->group = group;
74

75
    if (virAsprintf(&priv->baselabel, "+%u:+%u",
76 77 78 79 80
                    (unsigned int) user,
                    (unsigned int) group) < 0)
        return -1;

    return 0;
81 82
}

O
Osier Yang 已提交
83 84 85
void
virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
                                  bool dynamicOwnership)
86 87 88 89 90
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->dynamicOwnership = dynamicOwnership;
}

91 92 93 94 95 96 97 98
void
virSecurityDACSetChownCallback(virSecurityManagerPtr mgr,
                               virSecurityManagerDACChownCallback chownCallback)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->chownCallback = chownCallback;
}

99
/* returns 1 if label isn't found, 0 on success, -1 on error */
O
Osier Yang 已提交
100
static int
101
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
102 103
virSecurityDACParseIds(virSecurityLabelDefPtr seclabel,
                       uid_t *uidPtr, gid_t *gidPtr)
104
{
105
    if (!seclabel || !seclabel->label)
106
        return 1;
107

108
    if (virParseOwnershipIds(seclabel->label, uidPtr, gidPtr) < 0)
109 110 111 112 113
        return -1;

    return 0;
}

O
Osier Yang 已提交
114
static int
115
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
116 117
virSecurityDACGetIds(virSecurityLabelDefPtr seclabel,
                     virSecurityDACDataPtr priv,
118 119
                     uid_t *uidPtr, gid_t *gidPtr,
                     gid_t **groups, int *ngroups)
120
{
121 122
    int ret;

123 124 125 126 127
    if (groups)
        *groups = priv ? priv->groups : NULL;
    if (ngroups)
        *ngroups = priv ? priv->ngroups : 0;

128
    if ((ret = virSecurityDACParseIds(seclabel, uidPtr, gidPtr)) <= 0)
129 130 131
        return ret;

    if (!priv) {
132 133
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("DAC seclabel couldn't be determined"));
134 135 136
        return -1;
    }

137 138
    *uidPtr = priv->user;
    *gidPtr = priv->group;
139 140

    return 0;
141 142
}

143 144

/* returns 1 if label isn't found, 0 on success, -1 on error */
O
Osier Yang 已提交
145
static int
146
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
147
virSecurityDACParseImageIds(virSecurityLabelDefPtr seclabel,
O
Osier Yang 已提交
148
                            uid_t *uidPtr, gid_t *gidPtr)
149
{
150
    if (!seclabel || !seclabel->imagelabel)
151
        return 1;
152

153
    if (virParseOwnershipIds(seclabel->imagelabel, uidPtr, gidPtr) < 0)
154 155 156 157 158
        return -1;

    return 0;
}

O
Osier Yang 已提交
159
static int
160
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
161 162
virSecurityDACGetImageIds(virSecurityLabelDefPtr seclabel,
                          virSecurityDACDataPtr priv,
O
Osier Yang 已提交
163
                          uid_t *uidPtr, gid_t *gidPtr)
164
{
165 166
    int ret;

167
    if ((ret = virSecurityDACParseImageIds(seclabel, uidPtr, gidPtr)) <= 0)
168 169 170
        return ret;

    if (!priv) {
171 172
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("DAC imagelabel couldn't be determined"));
173
        return -1;
174
    }
175

176 177
    *uidPtr = priv->user;
    *gidPtr = priv->group;
178 179

    return 0;
180 181 182
}


183
static virSecurityDriverStatus
184
virSecurityDACProbe(const char *virtDriver ATTRIBUTE_UNUSED)
185 186 187 188 189 190 191 192 193 194 195
{
    return SECURITY_DRIVER_ENABLE;
}

static int
virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
    return 0;
}

static int
196
virSecurityDACClose(virSecurityManagerPtr mgr)
197
{
198 199
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    VIR_FREE(priv->groups);
200
    VIR_FREE(priv->baselabel);
201 202 203 204
    return 0;
}


O
Osier Yang 已提交
205 206
static const char *
virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
207
{
208
    return SECURITY_DAC_NAME;
209 210
}

O
Osier Yang 已提交
211 212
static const char *
virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
213 214 215 216
{
    return "0";
}

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
static int
virSecurityDACPreFork(virSecurityManagerPtr mgr)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int ngroups;

    VIR_FREE(priv->groups);
    priv->ngroups = 0;
    if ((ngroups = virGetGroupList(priv->user, priv->group,
                                   &priv->groups)) < 0)
        return -1;
    priv->ngroups = ngroups;
    return 0;
}

232
static int
233 234 235 236 237
virSecurityDACSetOwnershipInternal(virSecurityDACDataPtr priv,
                                   virStorageSourcePtr src,
                                   const char *path,
                                   uid_t uid,
                                   gid_t gid)
238
{
239 240 241
    int rc;
    int chown_errno;

242
    VIR_INFO("Setting DAC user and group on '%s' to '%ld:%ld'",
243 244 245 246 247 248 249 250 251 252
             NULLSTR(src ? src->path : path), (long) uid, (long) gid);

    if (priv && src && priv->chownCallback) {
        rc = priv->chownCallback(src, uid, gid);
        /* here path is used only for error messages */
        path = NULLSTR(src->path);

        /* on -2 returned an error was already reported */
        if (rc == -2)
            return -1;
253

254 255 256
        /* on -1 only errno was set */
        chown_errno = errno;
    } else {
257 258
        struct stat sb;

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
        if (!path) {
            if (!src || !src->path)
                return 0;

            if (!virStorageSourceIsLocalStorage(src))
                return 0;

            path = src->path;
        }

        rc = chown(path, uid, gid);
        chown_errno = errno;

        if (rc < 0 &&
            stat(path, &sb) >= 0) {
274 275 276 277 278 279
            if (sb.st_uid == uid &&
                sb.st_gid == gid) {
                /* It's alright, there's nothing to change anyway. */
                return 0;
            }
        }
280
    }
281

282
    if (rc < 0) {
283
        if (chown_errno == EOPNOTSUPP || chown_errno == EINVAL) {
284 285 286
            VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not "
                     "supported by filesystem",
                     (long) uid, (long) gid, path);
287
        } else if (chown_errno == EPERM) {
288 289 290
            VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not "
                     "permitted",
                     (long) uid, (long) gid, path);
291
        } else if (chown_errno == EROFS) {
292 293 294
            VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not "
                     "possible on readonly filesystem",
                     (long) uid, (long) gid, path);
295 296
        } else {
            virReportSystemError(chown_errno,
297 298 299
                                 _("unable to set user and group to '%ld:%ld' "
                                   "on '%s'"),
                                 (long) uid, (long) gid, path);
300 301 302 303 304 305
            return -1;
        }
    }
    return 0;
}

306

307
static int
308 309 310 311 312 313 314 315 316 317
virSecurityDACSetOwnership(const char *path, uid_t uid, gid_t gid)
{
    return virSecurityDACSetOwnershipInternal(NULL, NULL, path, uid, gid);
}


static int
virSecurityDACRestoreSecurityFileLabelInternal(virSecurityDACDataPtr priv,
                                               virStorageSourcePtr src,
                                               const char *path)
318
{
319 320
    VIR_INFO("Restoring DAC user and group on '%s'",
             NULLSTR(src ? src->path : path));
321 322

    /* XXX record previous ownership */
323 324 325 326 327 328 329 330
    return virSecurityDACSetOwnershipInternal(priv, src, path, 0, 0);
}


static int
virSecurityDACRestoreSecurityFileLabel(const char *path)
{
    return virSecurityDACRestoreSecurityFileLabelInternal(NULL, NULL, path);
331 332 333 334
}


static int
335 336 337
virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
                                    virDomainDefPtr def,
                                    virStorageSourcePtr src)
338
{
339
    virSecurityLabelDefPtr secdef;
340
    virSecurityDeviceLabelDefPtr disk_seclabel;
341
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
342 343 344
    uid_t user;
    gid_t group;

345 346 347 348
    if (!priv->dynamicOwnership)
        return 0;

    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
349
    if (secdef && !secdef->relabel)
350
        return 0;
351

352 353
    disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
                                                        SECURITY_DAC_NAME);
354
    if (disk_seclabel && !disk_seclabel->relabel)
355 356 357 358 359 360 361 362 363
        return 0;

    if (disk_seclabel && disk_seclabel->label) {
        if (virParseOwnershipIds(disk_seclabel->label, &user, &group) < 0)
            return -1;
    } else {
        if (virSecurityDACGetImageIds(secdef, priv, &user, &group))
            return -1;
    }
364

365
    return virSecurityDACSetOwnershipInternal(priv, src, NULL, user, group);
366 367 368 369
}


static int
370 371 372
virSecurityDACSetSecurityDiskLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr def,
                                   virDomainDiskDefPtr disk)
373 374

{
375
    virStorageSourcePtr next;
376

377 378 379 380
    for (next = disk->src; next; next = next->backingStore) {
        if (virSecurityDACSetSecurityImageLabel(mgr, def, next) < 0)
            return -1;
    }
381

382
    return 0;
383 384 385 386 387
}


static int
virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
388
                                           virDomainDefPtr def,
389
                                           virStorageSourcePtr src,
390
                                           bool migrated)
391 392
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
393 394
    virSecurityLabelDefPtr secdef;
    virSecurityDeviceLabelDefPtr disk_seclabel;
395 396 397 398

    if (!priv->dynamicOwnership)
        return 0;

399 400 401 402 403 404 405
    /* 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 (src->readonly || src->shared)
        return 0;
406

407
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
408
    if (secdef && !secdef->relabel)
409 410
        return 0;

411
    disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
412
                                                        SECURITY_DAC_NAME);
413
    if (disk_seclabel && !disk_seclabel->relabel)
414 415
        return 0;

416 417 418
    /* If we have a shared FS and are doing migration, 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 :-) */
419
    if (migrated) {
420 421 422 423 424 425 426 427 428 429
        int rc = 1;

        if (virStorageSourceIsLocalStorage(src)) {
            if (!src->path)
                return 0;

            if ((rc = virFileIsSharedFS(src->path)) < 0)
                return -1;
        }

430 431
        if (rc == 1) {
            VIR_DEBUG("Skipping image label restore on %s because FS is shared",
432
                      src->path);
433 434 435 436
            return 0;
        }
    }

437
    return virSecurityDACRestoreSecurityFileLabelInternal(priv, src, NULL);
438 439 440 441 442 443 444 445 446
}


static int
virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
                                        virDomainDefPtr def,
                                        virStorageSourcePtr src)
{
    return virSecurityDACRestoreSecurityImageLabelInt(mgr, def, src, false);
447 448 449 450
}


static int
451 452 453
virSecurityDACRestoreSecurityDiskLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
                                       virDomainDiskDefPtr disk)
454
{
455
    return virSecurityDACRestoreSecurityImageLabelInt(mgr, def, disk->src, false);
456 457 458 459
}


static int
460 461
virSecurityDACSetSecurityHostdevLabelHelper(const char *file,
                                            void *opaque)
462
{
463 464 465
    virSecurityDACCallbackDataPtr cbdata = opaque;
    virSecurityManagerPtr mgr = cbdata->manager;
    virSecurityLabelDefPtr secdef = cbdata->secdef;
466
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
467 468
    uid_t user;
    gid_t group;
469

470
    if (virSecurityDACGetIds(secdef, priv, &user, &group, NULL, NULL))
471 472 473
        return -1;

    return virSecurityDACSetOwnership(file, user, group);
474 475 476
}


477 478 479 480 481 482 483 484 485
static int
virSecurityDACSetSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED,
                                  const char *file,
                                  void *opaque)
{
    return virSecurityDACSetSecurityHostdevLabelHelper(file, opaque);
}


486
static int
487
virSecurityDACSetSecurityUSBLabel(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
488 489 490
                                  const char *file,
                                  void *opaque)
{
491 492
    return virSecurityDACSetSecurityHostdevLabelHelper(file, opaque);
}
493

494

495 496 497 498 499 500
static int
virSecurityDACSetSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
                                   const char *file,
                                   void *opaque)
{
    return virSecurityDACSetSecurityHostdevLabelHelper(file, opaque);
501 502 503 504 505
}


static int
virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
506
                                      virDomainDefPtr def,
507 508
                                      virDomainHostdevDefPtr dev,
                                      const char *vroot)
509 510
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
511
    virSecurityDACCallbackData cbdata;
512
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
513
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
514
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
515 516 517 518 519 520 521 522
    int ret = -1;

    if (!priv->dynamicOwnership)
        return 0;

    if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
        return 0;

523 524 525
    cbdata.manager = mgr;
    cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

526
    if (cbdata.secdef && !cbdata.secdef->relabel)
527 528
        return 0;

529
    switch ((virDomainHostdevSubsysType) dev->source.subsys.type) {
530
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
531
        virUSBDevicePtr usb;
532

533 534 535
        if (dev->missing)
            return 0;

536
        if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
537 538
            goto done;

539 540 541
        ret = virUSBDeviceFileIterate(usb,
                                      virSecurityDACSetSecurityUSBLabel,
                                      &cbdata);
542
        virUSBDeviceFree(usb);
543 544 545 546
        break;
    }

    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
547
        virPCIDevicePtr pci =
548 549
            virPCIDeviceNew(pcisrc->addr.domain, pcisrc->addr.bus,
                            pcisrc->addr.slot, pcisrc->addr.function);
550 551 552 553

        if (!pci)
            goto done;

554
        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
555
            char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
556

557 558
            if (!vfioGroupDev) {
                virPCIDeviceFree(pci);
559
                goto done;
560
            }
561
            ret = virSecurityDACSetSecurityPCILabel(pci, vfioGroupDev, &cbdata);
562 563
            VIR_FREE(vfioGroupDev);
        } else {
564 565 566
            ret = virPCIDeviceFileIterate(pci,
                                          virSecurityDACSetSecurityPCILabel,
                                          &cbdata);
567 568
        }

569
        virPCIDeviceFree(pci);
570 571 572
        break;
    }

573
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
574
        virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
575
        virSCSIDevicePtr scsi =
576
            virSCSIDeviceNew(NULL,
577 578
                             scsihostsrc->adapter, scsihostsrc->bus,
                             scsihostsrc->target, scsihostsrc->unit,
579
                             dev->readonly, dev->shareable);
580 581 582 583

        if (!scsi)
            goto done;

584 585 586
        ret = virSCSIDeviceFileIterate(scsi,
                                       virSecurityDACSetSecuritySCSILabel,
                                       &cbdata);
587 588 589 590 591
        virSCSIDeviceFree(scsi);

        break;
    }

592
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
593 594 595 596
        ret = 0;
        break;
    }

597
 done:
598 599 600 601 602
    return ret;
}


static int
603
virSecurityDACRestoreSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED,
604 605 606 607 608 609 610 611
                                      const char *file,
                                      void *opaque ATTRIBUTE_UNUSED)
{
    return virSecurityDACRestoreSecurityFileLabel(file);
}


static int
612 613 614
virSecurityDACRestoreSecurityUSBLabel(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
                                      const char *file,
                                      void *opaque ATTRIBUTE_UNUSED)
615 616 617 618 619
{
    return virSecurityDACRestoreSecurityFileLabel(file);
}


620 621 622 623 624 625 626 627 628
static int
virSecurityDACRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
                                       const char *file,
                                       void *opaque ATTRIBUTE_UNUSED)
{
    return virSecurityDACRestoreSecurityFileLabel(file);
}


629 630
static int
virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
631
                                          virDomainDefPtr def,
632 633
                                          virDomainHostdevDefPtr dev,
                                          const char *vroot)
634 635 636

{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
637
    virSecurityLabelDefPtr secdef;
638
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
639
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
640
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
641 642
    int ret = -1;

643 644
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

645
    if (!priv->dynamicOwnership || (secdef && !secdef->relabel))
646 647 648 649 650
        return 0;

    if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
        return 0;

651
    switch ((virDomainHostdevSubsysType) dev->source.subsys.type) {
652
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
653
        virUSBDevicePtr usb;
654 655 656

        if (dev->missing)
            return 0;
657

658
        if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
659 660
            goto done;

661 662
        ret = virUSBDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
        virUSBDeviceFree(usb);
663 664 665 666 667

        break;
    }

    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
668
        virPCIDevicePtr pci =
669 670
            virPCIDeviceNew(pcisrc->addr.domain, pcisrc->addr.bus,
                            pcisrc->addr.slot, pcisrc->addr.function);
671 672 673 674

        if (!pci)
            goto done;

675
        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
676
            char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
677

678 679
            if (!vfioGroupDev) {
                virPCIDeviceFree(pci);
680
                goto done;
681
            }
682 683 684 685 686
            ret = virSecurityDACRestoreSecurityPCILabel(pci, vfioGroupDev, mgr);
            VIR_FREE(vfioGroupDev);
        } else {
            ret = virPCIDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
        }
687
        virPCIDeviceFree(pci);
688 689 690
        break;
    }

691
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
692
        virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
693
        virSCSIDevicePtr scsi =
694
            virSCSIDeviceNew(NULL,
695 696
                             scsihostsrc->adapter, scsihostsrc->bus,
                             scsihostsrc->target, scsihostsrc->unit,
697
                             dev->readonly, dev->shareable);
698 699 700 701 702 703 704 705 706 707

        if (!scsi)
            goto done;

        ret = virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSecuritySCSILabel, mgr);
        virSCSIDeviceFree(scsi);

        break;
    }

708
    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
709 710 711 712
        ret = 0;
        break;
    }

713
 done:
714 715 716 717 718 719
    return ret;
}


static int
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
720
                              virDomainDefPtr def,
721 722
                              virDomainChrDefPtr dev,
                              virDomainChrSourceDefPtr dev_source)
723 724 725

{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
726
    virSecurityLabelDefPtr seclabel;
727
    virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
728 729
    char *in = NULL, *out = NULL;
    int ret = -1;
730 731 732
    uid_t user;
    gid_t group;

733 734
    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

735 736 737 738
    if (dev)
        chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
                                                          SECURITY_DAC_NAME);

739
    if (chr_seclabel && !chr_seclabel->relabel)
740 741 742 743 744 745 746 747 748
        return 0;

    if (chr_seclabel && chr_seclabel->label) {
        if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
            return -1;
    } else {
        if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0)
            return -1;
    }
749

750
    switch ((virDomainChrType) dev_source->type) {
751 752
    case VIR_DOMAIN_CHR_TYPE_DEV:
    case VIR_DOMAIN_CHR_TYPE_FILE:
753 754
        ret = virSecurityDACSetOwnership(dev_source->data.file.path,
                                         user, group);
755 756 757
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
758 759
        if ((virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0) ||
            (virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0))
760 761
            goto done;
        if (virFileExists(in) && virFileExists(out)) {
762 763
            if ((virSecurityDACSetOwnership(in, user, group) < 0) ||
                (virSecurityDACSetOwnership(out, user, group) < 0)) {
764
                goto done;
765
            }
766
        } else if (virSecurityDACSetOwnership(dev_source->data.file.path,
767
                                              user, group) < 0) {
768
            goto done;
769 770 771 772
        }
        ret = 0;
        break;

773 774 775 776 777 778 779 780 781 782 783
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
    case VIR_DOMAIN_CHR_TYPE_NULL:
    case VIR_DOMAIN_CHR_TYPE_VC:
    case VIR_DOMAIN_CHR_TYPE_PTY:
    case VIR_DOMAIN_CHR_TYPE_STDIO:
    case VIR_DOMAIN_CHR_TYPE_UDP:
    case VIR_DOMAIN_CHR_TYPE_TCP:
    case VIR_DOMAIN_CHR_TYPE_UNIX:
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
    case VIR_DOMAIN_CHR_TYPE_NMDM:
    case VIR_DOMAIN_CHR_TYPE_LAST:
784 785 786 787
        ret = 0;
        break;
    }

788
 done:
789 790 791 792 793 794 795
    VIR_FREE(in);
    VIR_FREE(out);
    return ret;
}

static int
virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
796
                                  virDomainDefPtr def ATTRIBUTE_UNUSED,
797 798
                                  virDomainChrDefPtr dev,
                                  virDomainChrSourceDefPtr dev_source)
799
{
800
    virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
801 802 803
    char *in = NULL, *out = NULL;
    int ret = -1;

804 805 806 807
    if (dev)
        chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
                                                          SECURITY_DAC_NAME);

808
    if (chr_seclabel && !chr_seclabel->relabel)
809 810
        return 0;

811
    switch ((virDomainChrType) dev_source->type) {
812 813
    case VIR_DOMAIN_CHR_TYPE_DEV:
    case VIR_DOMAIN_CHR_TYPE_FILE:
814
        ret = virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path);
815 816 817
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
818 819
        if ((virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0) ||
            (virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0))
820
            goto done;
821 822 823
        if (virFileExists(in) && virFileExists(out)) {
            if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
                (virSecurityDACRestoreSecurityFileLabel(in) < 0)) {
J
Jim Fehlig 已提交
824
                goto done;
825
            }
826
        } else if (virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path) < 0) {
827 828
            goto done;
        }
829 830 831
        ret = 0;
        break;

832 833 834 835 836 837 838 839 840 841 842
    case VIR_DOMAIN_CHR_TYPE_NULL:
    case VIR_DOMAIN_CHR_TYPE_VC:
    case VIR_DOMAIN_CHR_TYPE_PTY:
    case VIR_DOMAIN_CHR_TYPE_STDIO:
    case VIR_DOMAIN_CHR_TYPE_UDP:
    case VIR_DOMAIN_CHR_TYPE_TCP:
    case VIR_DOMAIN_CHR_TYPE_UNIX:
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
    case VIR_DOMAIN_CHR_TYPE_NMDM:
    case VIR_DOMAIN_CHR_TYPE_LAST:
843 844 845 846
        ret = 0;
        break;
    }

847
 done:
848 849 850 851 852 853 854
    VIR_FREE(in);
    VIR_FREE(out);
    return ret;
}


static int
855
virSecurityDACRestoreChardevCallback(virDomainDefPtr def,
856 857 858 859 860
                                     virDomainChrDefPtr dev,
                                     void *opaque)
{
    virSecurityManagerPtr mgr = opaque;

861
    return virSecurityDACRestoreChardevLabel(mgr, def, dev, &dev->source);
862 863 864
}


865 866 867 868 869 870 871 872 873
static int
virSecurityDACSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
                                      virDomainDefPtr def,
                                      virDomainTPMDefPtr tpm)
{
    int ret = 0;

    switch (tpm->type) {
    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
874
        ret = virSecurityDACSetChardevLabel(mgr, def, NULL,
875 876 877 878 879 880 881 882 883 884 885
                                            &tpm->data.passthrough.source);
        break;
    case VIR_DOMAIN_TPM_TYPE_LAST:
        break;
    }

    return ret;
}


static int
O
Osier Yang 已提交
886
virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr,
887
                                          virDomainDefPtr def,
O
Osier Yang 已提交
888
                                          virDomainTPMDefPtr tpm)
889 890 891 892 893
{
    int ret = 0;

    switch (tpm->type) {
    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
894
        ret = virSecurityDACRestoreChardevLabel(mgr, def, NULL,
895 896 897 898 899 900 901 902 903 904
                                          &tpm->data.passthrough.source);
        break;
    case VIR_DOMAIN_TPM_TYPE_LAST:
        break;
    }

    return ret;
}


905 906
static int
virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
907
                                      virDomainDefPtr def,
908
                                      bool migrated)
909 910
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
911
    virSecurityLabelDefPtr secdef;
912
    size_t i;
913 914
    int rc = 0;

915
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
916

917
    if (!priv->dynamicOwnership || (secdef && !secdef->relabel))
918
        return 0;
919 920

    VIR_DEBUG("Restoring security label on %s migrated=%d",
921
              def->name, migrated);
922

923
    for (i = 0; i < def->nhostdevs; i++) {
924
        if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
925
                                                      def,
926 927
                                                      def->hostdevs[i],
                                                      NULL) < 0)
928 929
            rc = -1;
    }
930
    for (i = 0; i < def->ndisks; i++) {
931
        if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
932
                                                       def,
933
                                                       def->disks[i]->src,
934 935 936 937
                                                       migrated) < 0)
            rc = -1;
    }

938
    if (virDomainChrDefForeach(def,
939 940
                               false,
                               virSecurityDACRestoreChardevCallback,
941
                               mgr) < 0)
942 943
        rc = -1;

944 945
    if (def->tpm) {
        if (virSecurityDACRestoreSecurityTPMFileLabel(mgr,
946
                                                      def,
947 948 949 950
                                                      def->tpm) < 0)
            rc = -1;
    }

951 952
    if (def->os.kernel &&
        virSecurityDACRestoreSecurityFileLabel(def->os.kernel) < 0)
953 954
        rc = -1;

955 956
    if (def->os.initrd &&
        virSecurityDACRestoreSecurityFileLabel(def->os.initrd) < 0)
957 958
        rc = -1;

O
Olivia Yin 已提交
959 960 961 962
    if (def->os.dtb &&
        virSecurityDACRestoreSecurityFileLabel(def->os.dtb) < 0)
        rc = -1;

963 964 965 966 967
    return rc;
}


static int
968
virSecurityDACSetChardevCallback(virDomainDefPtr def,
969 970 971 972 973
                                 virDomainChrDefPtr dev,
                                 void *opaque)
{
    virSecurityManagerPtr mgr = opaque;

974
    return virSecurityDACSetChardevLabel(mgr, def, dev, &dev->source);
975 976 977 978 979
}


static int
virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
980
                                  virDomainDefPtr def,
981 982 983
                                  const char *stdin_path ATTRIBUTE_UNUSED)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
984
    virSecurityLabelDefPtr secdef;
985
    size_t i;
986 987
    uid_t user;
    gid_t group;
988

989 990
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

991
    if (!priv->dynamicOwnership || (secdef && !secdef->relabel))
992 993
        return 0;

994
    for (i = 0; i < def->ndisks; i++) {
995
        /* XXX fixme - we need to recursively label the entire tree :-( */
E
Eric Blake 已提交
996
        if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
997
            continue;
998 999 1000
        if (virSecurityDACSetSecurityDiskLabel(mgr,
                                               def,
                                               def->disks[i]) < 0)
1001 1002
            return -1;
    }
1003
    for (i = 0; i < def->nhostdevs; i++) {
1004
        if (virSecurityDACSetSecurityHostdevLabel(mgr,
1005
                                                  def,
1006 1007
                                                  def->hostdevs[i],
                                                  NULL) < 0)
1008 1009 1010
            return -1;
    }

1011
    if (virDomainChrDefForeach(def,
1012 1013
                               true,
                               virSecurityDACSetChardevCallback,
1014
                               mgr) < 0)
1015 1016
        return -1;

1017 1018 1019 1020 1021 1022 1023
    if (def->tpm) {
        if (virSecurityDACSetSecurityTPMFileLabel(mgr,
                                                  def,
                                                  def->tpm) < 0)
            return -1;
    }

1024
    if (virSecurityDACGetImageIds(secdef, priv, &user, &group))
1025 1026
        return -1;

1027
    if (def->os.kernel &&
1028
        virSecurityDACSetOwnership(def->os.kernel, user, group) < 0)
1029 1030
        return -1;

1031
    if (def->os.initrd &&
1032
        virSecurityDACSetOwnership(def->os.initrd, user, group) < 0)
1033 1034
        return -1;

O
Olivia Yin 已提交
1035 1036 1037 1038
    if (def->os.dtb &&
        virSecurityDACSetOwnership(def->os.dtb, user, group) < 0)
        return -1;

1039 1040 1041 1042 1043 1044
    return 0;
}


static int
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
1045
                                 virDomainDefPtr def,
1046 1047
                                 const char *savefile)
{
1048 1049
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityLabelDefPtr secdef;
1050 1051
    uid_t user;
    gid_t group;
1052

1053 1054 1055
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

    if (virSecurityDACGetImageIds(secdef, priv, &user, &group) < 0)
1056 1057 1058
        return -1;

    return virSecurityDACSetOwnership(savefile, user, group);
1059 1060 1061 1062 1063
}


static int
virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
1064
                                     virDomainDefPtr def ATTRIBUTE_UNUSED,
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
                                     const char *savefile)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);

    if (!priv->dynamicOwnership)
        return 0;

    return virSecurityDACRestoreSecurityFileLabel(savefile);
}


static int
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
1078
                              virDomainDefPtr def)
1079
{
1080 1081
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityLabelDefPtr secdef;
1082 1083
    uid_t user;
    gid_t group;
1084 1085
    gid_t *groups;
    int ngroups;
1086

1087 1088 1089
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

    if (virSecurityDACGetIds(secdef, priv, &user, &group, &groups, &ngroups) < 0)
1090
        return -1;
1091

1092 1093
    VIR_DEBUG("Dropping privileges of DEF to %u:%u, %d supplemental groups",
              (unsigned int) user, (unsigned int) group, ngroups);
1094

1095
    if (virSetUIDGID(user, group, groups, ngroups) < 0)
1096 1097 1098
        return -1;

    return 0;
1099 1100 1101
}


1102 1103
static int
virSecurityDACSetChildProcessLabel(virSecurityManagerPtr mgr,
1104
                                   virDomainDefPtr def,
1105 1106
                                   virCommandPtr cmd)
{
1107 1108
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityLabelDefPtr secdef;
1109 1110 1111
    uid_t user;
    gid_t group;

1112 1113 1114
    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

    if (virSecurityDACGetIds(secdef, priv, &user, &group, NULL, NULL))
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
        return -1;

    VIR_DEBUG("Setting child to drop privileges of DEF to %u:%u",
              (unsigned int) user, (unsigned int) group);

    virCommandSetUID(cmd, user);
    virCommandSetGID(cmd, group);
    return 0;
}


1126 1127 1128 1129 1130 1131 1132 1133
static int
virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                     virDomainDefPtr def ATTRIBUTE_UNUSED)
{
    return 0;
}

static int
1134 1135
virSecurityDACGenLabel(virSecurityManagerPtr mgr,
                       virDomainDefPtr def)
1136
{
1137 1138 1139 1140 1141
    int rc = -1;
    virSecurityLabelDefPtr seclabel;
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);

    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
1142
    if (seclabel == NULL)
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
        return rc;

    if (seclabel->imagelabel) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("security image label already "
                         "defined for VM"));
        return rc;
    }

    if (seclabel->model
        && STRNEQ(seclabel->model, SECURITY_DAC_NAME)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("security label model %s is not supported "
                         "with selinux"),
                       seclabel->model);
            return rc;
    }

1161
    switch ((virDomainSeclabelType) seclabel->type) {
1162 1163 1164 1165 1166 1167 1168 1169 1170
    case VIR_DOMAIN_SECLABEL_STATIC:
        if (seclabel->label == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("missing label for static security "
                             "driver in domain %s"), def->name);
            return rc;
        }
        break;
    case VIR_DOMAIN_SECLABEL_DYNAMIC:
1171
        if (virAsprintf(&seclabel->label, "+%u:+%u",
1172
                        (unsigned int) priv->user,
1173
                        (unsigned int) priv->group) < 0)
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
            return rc;
        if (seclabel->label == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot generate dac user and group id "
                             "for domain %s"), def->name);
            return rc;
        }
        break;
    case VIR_DOMAIN_SECLABEL_NONE:
        /* no op */
1184
        return 0;
1185 1186
    case VIR_DOMAIN_SECLABEL_DEFAULT:
    case VIR_DOMAIN_SECLABEL_LAST:
1187 1188 1189 1190 1191 1192
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected security label type '%s'"),
                       virDomainSeclabelTypeToString(seclabel->type));
        return rc;
    }

1193
    if (seclabel->relabel && !seclabel->imagelabel &&
1194 1195 1196
        VIR_STRDUP(seclabel->imagelabel, seclabel->label) < 0) {
        VIR_FREE(seclabel->label);
        return rc;
1197 1198
    }

1199 1200 1201 1202 1203
    return 0;
}

static int
virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1204
                           virDomainDefPtr def ATTRIBUTE_UNUSED)
1205 1206 1207 1208 1209 1210
{
    return 0;
}

static int
virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1211 1212
                           virDomainDefPtr def ATTRIBUTE_UNUSED,
                           pid_t pid ATTRIBUTE_UNUSED)
1213 1214 1215 1216 1217 1218
{
    return 0;
}

static int
virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1219
                              virDomainDefPtr def,
1220
                              pid_t pid ATTRIBUTE_UNUSED,
1221
                              virSecurityLabelPtr seclabel)
1222
{
1223 1224 1225 1226 1227 1228 1229
    virSecurityLabelDefPtr secdef =
        virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);

    if (!secdef || !seclabel)
        return -1;

    if (secdef->label)
1230 1231
        ignore_value(virStrcpy(seclabel->label, secdef->label,
                               VIR_SECURITY_LABEL_BUFLEN));
1232

1233 1234 1235 1236
    return 0;
}

static int
1237
virSecurityDACSetDaemonSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1238
                                   virDomainDefPtr vm ATTRIBUTE_UNUSED)
1239 1240 1241 1242 1243
{
    return 0;
}


1244 1245
static int
virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1246
                             virDomainDefPtr def ATTRIBUTE_UNUSED)
1247 1248 1249 1250 1251
{
    return 0;
}


1252 1253
static int
virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1254
                               virDomainDefPtr def ATTRIBUTE_UNUSED)
1255 1256 1257 1258
{
    return 0;
}

1259
static int
1260
virSecurityDACSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
1261
                              virDomainDefPtr def ATTRIBUTE_UNUSED,
1262
                              int fd ATTRIBUTE_UNUSED)
1263 1264 1265 1266
{
    return 0;
}

1267 1268 1269 1270 1271 1272 1273 1274
static int
virSecurityDACSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                            virDomainDefPtr def ATTRIBUTE_UNUSED,
                            int fd ATTRIBUTE_UNUSED)
{
    return 0;
}

O
Osier Yang 已提交
1275 1276 1277 1278
static char *
virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                              virDomainDefPtr vm ATTRIBUTE_UNUSED)
{
1279 1280 1281
    return NULL;
}

1282 1283 1284 1285 1286 1287 1288 1289
static const char *
virSecurityDACGetBaseLabel(virSecurityManagerPtr mgr,
                           int virt ATTRIBUTE_UNUSED)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    return priv->baselabel;
}

1290
virSecurityDriver virSecurityDriverDAC = {
1291
    .privateDataLen                     = sizeof(virSecurityDACData),
1292
    .name                               = SECURITY_DAC_NAME,
1293 1294 1295
    .probe                              = virSecurityDACProbe,
    .open                               = virSecurityDACOpen,
    .close                              = virSecurityDACClose,
1296

1297 1298
    .getModel                           = virSecurityDACGetModel,
    .getDOI                             = virSecurityDACGetDOI,
1299

1300 1301
    .preFork                            = virSecurityDACPreFork,

1302
    .domainSecurityVerify               = virSecurityDACVerify,
1303

1304
    .domainSetSecurityDiskLabel         = virSecurityDACSetSecurityDiskLabel,
1305
    .domainRestoreSecurityDiskLabel     = virSecurityDACRestoreSecurityDiskLabel,
1306

1307
    .domainSetSecurityImageLabel        = virSecurityDACSetSecurityImageLabel,
1308 1309
    .domainRestoreSecurityImageLabel    = virSecurityDACRestoreSecurityImageLabel,

1310 1311 1312
    .domainSetSecurityDaemonSocketLabel = virSecurityDACSetDaemonSocketLabel,
    .domainSetSecuritySocketLabel       = virSecurityDACSetSocketLabel,
    .domainClearSecuritySocketLabel     = virSecurityDACClearSocketLabel,
1313

1314 1315 1316
    .domainGenSecurityLabel             = virSecurityDACGenLabel,
    .domainReserveSecurityLabel         = virSecurityDACReserveLabel,
    .domainReleaseSecurityLabel         = virSecurityDACReleaseLabel,
1317

1318 1319
    .domainGetSecurityProcessLabel      = virSecurityDACGetProcessLabel,
    .domainSetSecurityProcessLabel      = virSecurityDACSetProcessLabel,
1320
    .domainSetSecurityChildProcessLabel = virSecurityDACSetChildProcessLabel,
1321

1322 1323
    .domainSetSecurityAllLabel          = virSecurityDACSetSecurityAllLabel,
    .domainRestoreSecurityAllLabel      = virSecurityDACRestoreSecurityAllLabel,
1324

1325 1326
    .domainSetSecurityHostdevLabel      = virSecurityDACSetSecurityHostdevLabel,
    .domainRestoreSecurityHostdevLabel  = virSecurityDACRestoreSecurityHostdevLabel,
1327

1328 1329
    .domainSetSavedStateLabel           = virSecurityDACSetSavedStateLabel,
    .domainRestoreSavedStateLabel       = virSecurityDACRestoreSavedStateLabel,
1330

1331
    .domainSetSecurityImageFDLabel      = virSecurityDACSetImageFDLabel,
1332
    .domainSetSecurityTapFDLabel        = virSecurityDACSetTapFDLabel,
1333

1334
    .domainGetSecurityMountOptions      = virSecurityDACGetMountOptions,
1335 1336

    .getBaseLabel                       = virSecurityDACGetBaseLabel,
1337
};