security_manager.c 25.0 KB
Newer Older
1 2 3
/*
 * security_manager.c: Internal security manager API
 *
4
 * Copyright (C) 2010-2014 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */
#include <config.h>

#include "security_driver.h"
#include "security_stack.h"
#include "security_dac.h"
27
#include "virerror.h"
28
#include "viralloc.h"
29
#include "virobject.h"
30
#include "virlog.h"
31 32 33

#define VIR_FROM_THIS VIR_FROM_SECURITY

34
VIR_LOG_INIT("security.security_manager");
35 36

struct _virSecurityManager {
37 38
    virObjectLockable parent;

39
    virSecurityDriverPtr drv;
40
    unsigned int flags;
41
    const char *virtDriver;
42
    void *privateData;
43 44
};

45 46
static virClassPtr virSecurityManagerClass;

47 48 49 50 51 52 53 54 55 56 57

static
void virSecurityManagerDispose(void *obj)
{
    virSecurityManagerPtr mgr = obj;

    if (mgr->drv->close)
        mgr->drv->close(mgr);
    VIR_FREE(mgr->privateData);
}

58

59 60
static int
virSecurityManagerOnceInit(void)
61 62 63 64 65 66 67 68 69 70 71 72
{
    if (!(virSecurityManagerClass = virClassNew(virClassForObjectLockable(),
                                                "virSecurityManagerClass",
                                                sizeof(virSecurityManager),
                                                virSecurityManagerDispose)))
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(virSecurityManager);

73 74 75 76

static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr drv,
                            const char *virtDriver,
77
                            unsigned int flags)
78 79
{
    virSecurityManagerPtr mgr;
80 81 82 83
    char *privateData;

    if (virSecurityManagerInitialize() < 0)
        return NULL;
84

85 86 87 88
    VIR_DEBUG("drv=%p (%s) virtDriver=%s flags=%x",
              drv, drv->name, virtDriver, flags);

    virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK, NULL);
89

90
    if (VIR_ALLOC_N(privateData, drv->privateDataLen) < 0)
91 92
        return NULL;

93 94 95 96 97
    if (!(mgr = virObjectLockableNew(virSecurityManagerClass))) {
        VIR_FREE(privateData);
        return NULL;
    }

98
    mgr->drv = drv;
99
    mgr->flags = flags;
100
    mgr->virtDriver = virtDriver;
101
    mgr->privateData = privateData;
102 103

    if (drv->open(mgr) < 0) {
104
        virObjectUnref(mgr);
105 106 107 108 109 110
        return NULL;
    }

    return mgr;
}

111 112 113

virSecurityManagerPtr
virSecurityManagerNewStack(virSecurityManagerPtr primary)
114 115 116
{
    virSecurityManagerPtr mgr =
        virSecurityManagerNewDriver(&virSecurityDriverStack,
117
                                    virSecurityManagerGetDriver(primary),
118
                                    primary->flags);
119 120 121 122

    if (!mgr)
        return NULL;

123
    virSecurityStackAddNested(mgr, primary);
124 125 126 127

    return mgr;
}

128 129 130 131

int
virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
                                 virSecurityManagerPtr nested)
132 133 134 135 136 137
{
    if (!STREQ("stack", stack->drv->name))
        return -1;
    return virSecurityStackAddNested(stack, nested);
}

138 139 140 141 142

virSecurityManagerPtr
virSecurityManagerNewDAC(const char *virtDriver,
                         uid_t user,
                         gid_t group,
143
                         unsigned int flags,
144
                         virSecurityManagerDACChownCallback chownCallback)
145
{
146 147 148 149 150 151 152 153
    virSecurityManagerPtr mgr;

    virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK |
                  VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP, NULL);

    mgr = virSecurityManagerNewDriver(&virSecurityDriverDAC,
                                      virtDriver,
                                      flags & VIR_SECURITY_MANAGER_NEW_MASK);
154 155 156 157

    if (!mgr)
        return NULL;

158 159 160 161
    if (virSecurityDACSetUserAndGroup(mgr, user, group) < 0) {
        virSecurityManagerDispose(mgr);
        return NULL;
    }
162

163
    virSecurityDACSetDynamicOwnership(mgr, flags & VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP);
164
    virSecurityDACSetChownCallback(mgr, chownCallback);
165 166 167 168

    return mgr;
}

169 170 171 172

virSecurityManagerPtr
virSecurityManagerNew(const char *name,
                      const char *virtDriver,
173
                      unsigned int flags)
174
{
175
    virSecurityDriverPtr drv = virSecurityDriverLookup(name, virtDriver);
176 177 178
    if (!drv)
        return NULL;

179 180
    /* driver "none" needs some special handling of *Confined bools */
    if (STREQ(drv->name, "none")) {
181
        if (flags & VIR_SECURITY_MANAGER_REQUIRE_CONFINED) {
182 183
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Security driver \"none\" cannot create confined guests"));
184 185 186
            return NULL;
        }

187
        if (flags & VIR_SECURITY_MANAGER_DEFAULT_CONFINED) {
188 189 190 191 192 193 194
            if (name != NULL) {
                VIR_WARN("Configured security driver \"none\" disables default"
                         " policy to create confined guests");
            } else {
                VIR_DEBUG("Auto-probed security driver is \"none\";"
                          " confined guests will not be created");
            }
195
            flags &= ~VIR_SECURITY_MANAGER_DEFAULT_CONFINED;
196 197 198
        }
    }

199
    return virSecurityManagerNewDriver(drv,
200
                                       virtDriver,
201
                                       flags);
202 203
}

204 205 206

/*
 * Must be called before fork()'ing to ensure mutex state
207 208 209 210
 * is sane for the child to use. A negative return means the
 * child must not be forked; a successful return must be
 * followed by a call to virSecurityManagerPostFork() in both
 * parent and child.
211
 */
212 213
int
virSecurityManagerPreFork(virSecurityManagerPtr mgr)
214
{
215 216
    int ret = 0;

217
    virObjectLock(mgr);
218 219 220 221 222 223 224
    if (mgr->drv->preFork) {
        ret = mgr->drv->preFork(mgr);
        if (ret < 0)
            virObjectUnlock(mgr);
    }

    return ret;
225 226 227 228 229 230 231
}


/*
 * Must be called after fork()'ing in both parent and child
 * to ensure mutex state is sane for the child to use
 */
232 233
void
virSecurityManagerPostFork(virSecurityManagerPtr mgr)
234 235 236 237
{
    virObjectUnlock(mgr);
}

238 239
void *
virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
240
{
241
    return mgr->privateData;
242 243 244
}


245 246 247 248 249 250
const char *
virSecurityManagerGetDriver(virSecurityManagerPtr mgr)
{
    return mgr->virtDriver;
}

251

252 253 254
const char *
virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
{
255 256 257 258 259 260 261
    if (mgr->drv->getDOI) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getDOI(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
262

263
    virReportUnsupportedError();
264 265 266
    return NULL;
}

267

268 269 270
const char *
virSecurityManagerGetModel(virSecurityManagerPtr mgr)
{
271 272 273 274 275 276 277
    if (mgr->drv->getModel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getModel(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
278

279
    virReportUnsupportedError();
280 281 282
    return NULL;
}

283

284 285
/* return NULL if a base label is not present */
const char *
286 287
virSecurityManagerGetBaseLabel(virSecurityManagerPtr mgr,
                               int virtType)
288 289 290 291 292 293 294 295 296 297 298 299
{
    if (mgr->drv->getBaseLabel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getBaseLabel(mgr, virtType);
        virObjectUnlock(mgr);
        return ret;
    }

    return NULL;
}

300 301 302

bool
virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
303
{
304
    return mgr->flags & VIR_SECURITY_MANAGER_ALLOW_DISK_PROBE;
305 306
}

307 308 309

bool
virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr)
310
{
311
    return mgr->flags & VIR_SECURITY_MANAGER_DEFAULT_CONFINED;
312 313
}

314 315 316

bool
virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
317
{
318
    return mgr->flags & VIR_SECURITY_MANAGER_REQUIRE_CONFINED;
319 320
}

321

322 323 324
bool
virSecurityManagerGetPrivileged(virSecurityManagerPtr mgr)
{
325
    return mgr->flags & VIR_SECURITY_MANAGER_PRIVILEGED;
326 327 328
}


329 330 331 332 333 334 335 336 337 338 339
/**
 * virSecurityManagerRestoreDiskLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @disk: disk definition to operate on
 *
 * Removes security label from the source image of the disk. Note that this
 * function doesn't restore labels on backing chain elements of @disk.
 *
 * Returns: 0 on success, -1 on error.
 */
340 341 342 343
int
virSecurityManagerRestoreDiskLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm,
                                   virDomainDiskDefPtr disk)
344
{
345
    if (mgr->drv->domainRestoreSecurityDiskLabel) {
346 347
        int ret;
        virObjectLock(mgr);
348
        ret = mgr->drv->domainRestoreSecurityDiskLabel(mgr, vm, disk);
349 350 351
        virObjectUnlock(mgr);
        return ret;
    }
352

353
    virReportUnsupportedError();
354 355 356
    return -1;
}

357

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
/**
 * virSecurityManagerRestoreImageLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @src: disk source definition to operate on
 *
 * Removes security label from a single storage image.
 *
 * Returns: 0 on success, -1 on error.
 */
int
virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm,
                                   virStorageSourcePtr src)
{
    if (mgr->drv->domainRestoreSecurityImageLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, src);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}


386 387 388
int
virSecurityManagerSetDaemonSocketLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr vm)
389
{
390 391 392 393 394 395 396
    if (mgr->drv->domainSetSecurityDaemonSocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityDaemonSocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
397

398
    virReportUnsupportedError();
399 400 401
    return -1;
}

402 403 404 405

int
virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
                                 virDomainDefPtr vm)
406
{
407 408 409 410 411 412 413
    if (mgr->drv->domainSetSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
414

415
    virReportUnsupportedError();
416 417 418
    return -1;
}

419 420 421 422

int
virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm)
423
{
424 425 426 427 428 429 430
    if (mgr->drv->domainClearSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
431

432
    virReportUnsupportedError();
433 434 435
    return -1;
}

436

437 438 439 440 441 442 443 444 445 446 447
/**
 * virSecurityManagerSetDiskLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @disk: disk definition to operate on
 *
 * Labels the disk image and all images in the backing chain with the configured
 * security label.
 *
 * Returns: 0 on success, -1 on error.
 */
448 449 450 451
int
virSecurityManagerSetDiskLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm,
                               virDomainDiskDefPtr disk)
452
{
453
    if (mgr->drv->domainSetSecurityDiskLabel) {
454 455
        int ret;
        virObjectLock(mgr);
456
        ret = mgr->drv->domainSetSecurityDiskLabel(mgr, vm, disk);
457 458 459
        virObjectUnlock(mgr);
        return ret;
    }
460

461
    virReportUnsupportedError();
462 463 464
    return -1;
}

465

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
/**
 * virSecurityManagerSetImageLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @src: disk source definition to operate on
 *
 * Labels a single storage image with the configured security label.
 *
 * Returns: 0 on success, -1 on error.
 */
int
virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
                                virDomainDefPtr vm,
                                virStorageSourcePtr src)
{
    if (mgr->drv->domainSetSecurityImageLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityImageLabel(mgr, vm, src);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}


494 495 496 497 498
int
virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
                                      virDomainDefPtr vm,
                                      virDomainHostdevDefPtr dev,
                                      const char *vroot)
499
{
500 501 502 503 504 505 506
    if (mgr->drv->domainRestoreSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
507

508
    virReportUnsupportedError();
509 510 511
    return -1;
}

512 513 514 515 516 517

int
virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  virDomainHostdevDefPtr dev,
                                  const char *vroot)
518
{
519 520 521 522 523 524 525
    if (mgr->drv->domainSetSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
526

527
    virReportUnsupportedError();
528 529 530
    return -1;
}

531 532 533 534 535

int
virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
                                     virDomainDefPtr vm,
                                     const char *savefile)
536
{
537 538 539 540 541 542 543
    if (mgr->drv->domainSetSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
544

545
    virReportUnsupportedError();
546 547 548
    return -1;
}

549 550 551 552
int
virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
                                         virDomainDefPtr vm,
                                         const char *savefile)
553
{
554 555 556 557 558 559 560
    if (mgr->drv->domainRestoreSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
561

562
    virReportUnsupportedError();
563 564 565
    return -1;
}

566 567 568 569

int
virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
                           virDomainDefPtr vm)
570
{
571
    int ret = -1;
572
    size_t i;
573 574
    virSecurityManagerPtr* sec_managers = NULL;
    virSecurityLabelDefPtr seclabel;
575
    bool generated = false;
576

577
    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
578
        return ret;
579

580
    virObjectLock(mgr);
581

582
    for (i = 0; sec_managers[i]; i++) {
583 584 585
        generated = false;
        seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name);
        if (!seclabel) {
586
            if (!(seclabel = virSecurityLabelDefNew(sec_managers[i]->drv->name)))
587 588
                goto cleanup;
            generated = seclabel->implicit = true;
589
        }
590

591
        if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
592
            if (virSecurityManagerGetDefaultConfined(sec_managers[i])) {
593
                seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
594
            } else {
595
                seclabel->type = VIR_DOMAIN_SECLABEL_NONE;
596
                seclabel->relabel = false;
597
            }
598 599
        }

600
        if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) {
601
            if (virSecurityManagerGetRequireConfined(sec_managers[i])) {
602 603 604 605 606 607
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Unconfined guests are not allowed on this host"));
                goto cleanup;
            } else if (vm->nseclabels && generated) {
                VIR_DEBUG("Skipping auto generated seclabel of type none");
                virSecurityLabelDefFree(seclabel);
608
                seclabel = NULL;
609 610
                continue;
            }
611 612 613
        }

        if (!sec_managers[i]->drv->domainGenSecurityLabel) {
614
            virReportUnsupportedError();
615 616
            virSecurityLabelDefFree(seclabel);
            seclabel = NULL;
617
        } else {
618 619
            /* The seclabel must be added to @vm prior calling domainGenSecurityLabel
             * which may require seclabel to be presented already */
620
            if (generated &&
621
                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0)
622 623 624 625 626 627
                goto cleanup;

            if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) {
                if (VIR_DELETE_ELEMENT(vm->seclabels,
                                       vm->nseclabels -1, vm->nseclabels) < 0)
                    vm->nseclabels--;
628
                goto cleanup;
629
            }
630 631

            seclabel = NULL;
632 633 634
        }
    }

635 636
    ret = 0;

637
 cleanup:
638
    virObjectUnlock(mgr);
639 640
    if (generated)
        virSecurityLabelDefFree(seclabel);
641
    VIR_FREE(sec_managers);
642
    return ret;
643 644
}

645 646 647 648 649

int
virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm,
                               pid_t pid)
650
{
651 652 653 654 655 656 657
    if (mgr->drv->domainReserveSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReserveSecurityLabel(mgr, vm, pid);
        virObjectUnlock(mgr);
        return ret;
    }
658

659
    virReportUnsupportedError();
660 661 662
    return -1;
}

663 664 665 666

int
virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm)
667
{
668 669 670 671 672 673 674
    if (mgr->drv->domainReleaseSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReleaseSecurityLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
675

676
    virReportUnsupportedError();
677 678 679
    return -1;
}

680

681 682 683
static int virSecurityManagerCheckModel(virSecurityManagerPtr mgr,
                                        char *secmodel)
{
684
    int ret = -1;
685 686 687 688 689 690
    size_t i;
    virSecurityManagerPtr *sec_managers = NULL;

    if (STREQ_NULLABLE(secmodel, "none"))
        return 0;

691 692 693
    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
        return -1;

694
    for (i = 0; sec_managers[i]; i++) {
695 696 697 698
        if (STREQ_NULLABLE(secmodel, sec_managers[i]->drv->name)) {
            ret = 0;
            goto cleanup;
        }
699 700 701 702 703
    }

    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                   _("Unable to find security driver for model %s"),
                   secmodel);
704 705 706
 cleanup:
    VIR_FREE(sec_managers);
    return ret;
707 708 709
}


710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
static int
virSecurityManagerCheckDomainLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr def)
{
    size_t i;

    for (i = 0; i < def->nseclabels; i++) {
        if (virSecurityManagerCheckModel(mgr, def->seclabels[i]->model) < 0)
            return -1;
    }

    return 0;
}


725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
static int
virSecurityManagerCheckDiskLabel(virSecurityManagerPtr mgr,
                                 virDomainDiskDefPtr disk)
{
    size_t i;

    for (i = 0; i < disk->src->nseclabels; i++) {
        if (virSecurityManagerCheckModel(mgr, disk->src->seclabels[i]->model) < 0)
            return -1;
    }

    return 0;
}


static int
virSecurityManagerCheckChardevLabel(virSecurityManagerPtr mgr,
                                    virDomainChrDefPtr dev)
{
    size_t i;

    for (i = 0; i < dev->nseclabels; i++) {
        if (virSecurityManagerCheckModel(mgr, dev->seclabels[i]->model) < 0)
            return -1;
    }

    return 0;
}


static int
virSecurityManagerCheckChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                       virDomainChrDefPtr dev,
                                       void *opaque)
{
    virSecurityManagerPtr mgr = opaque;
    return virSecurityManagerCheckChardevLabel(mgr, dev);
}


int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
                                    virDomainDefPtr vm)
{
    size_t i;

770 771 772
    if (virSecurityManagerCheckDomainLabel(mgr, vm) < 0)
        return -1;

773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
    for (i = 0; i < vm->ndisks; i++) {
        if (virSecurityManagerCheckDiskLabel(mgr, vm->disks[i]) < 0)
            return -1;
    }

    if (virDomainChrDefForeach(vm,
                               true,
                               virSecurityManagerCheckChardevCallback,
                               mgr) < 0)
        return -1;

    return 0;
}


788 789 790 791
int
virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
                              virDomainDefPtr vm,
                              const char *stdin_path)
792
{
793 794 795 796 797 798 799
    if (mgr->drv->domainSetSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
        virObjectUnlock(mgr);
        return ret;
    }
800

801
    virReportUnsupportedError();
802 803 804
    return -1;
}

805 806 807 808 809

int
virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  bool migrated)
810
{
811 812 813 814 815 816 817
    if (mgr->drv->domainRestoreSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
        virObjectUnlock(mgr);
        return ret;
    }
818

819
    virReportUnsupportedError();
820 821 822
    return -1;
}

823 824 825 826 827
int
virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  pid_t pid,
                                  virSecurityLabelPtr sec)
828
{
829 830 831 832 833 834 835
    if (mgr->drv->domainGetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityProcessLabel(mgr, vm, pid, sec);
        virObjectUnlock(mgr);
        return ret;
    }
836

837
    virReportUnsupportedError();
838 839 840
    return -1;
}

841 842 843 844

int
virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm)
845
{
846 847 848 849 850 851 852
    if (mgr->drv->domainSetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
853

854
    virReportUnsupportedError();
855 856 857
    return -1;
}

858 859 860 861 862

int
virSecurityManagerSetChildProcessLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr vm,
                                       virCommandPtr cmd)
863 864 865 866
{
    if (mgr->drv->domainSetSecurityChildProcessLabel)
       return mgr->drv->domainSetSecurityChildProcessLabel(mgr, vm, cmd);

867
    virReportUnsupportedError();
868 869 870
    return -1;
}

871 872 873 874

int
virSecurityManagerVerify(virSecurityManagerPtr mgr,
                         virDomainDefPtr def)
875
{
876 877 878 879 880
    virSecurityLabelDefPtr secdef;

    if (mgr == NULL || mgr->drv == NULL)
        return 0;

881 882 883 884
    /* NULL model == dynamic labelling, with whatever driver
     * is active, so we can short circuit verify check to
     * avoid drivers de-referencing NULLs by accident
     */
885 886
    secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
    if (secdef == NULL || secdef->model == NULL)
887 888
        return 0;

889 890 891 892 893 894 895
    if (mgr->drv->domainSecurityVerify) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSecurityVerify(mgr, def);
        virObjectUnlock(mgr);
        return ret;
    }
896

897
    virReportUnsupportedError();
898 899
    return -1;
}
900

901 902 903 904 905

int
virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  int fd)
906
{
907 908 909 910 911 912 913
    if (mgr->drv->domainSetSecurityImageFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityImageFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
914

915
    virReportUnsupportedError();
916 917
    return -1;
}
918

919 920 921 922 923

int
virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
                                virDomainDefPtr vm,
                                int fd)
924
{
925 926 927 928 929 930 931
    if (mgr->drv->domainSetSecurityTapFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityTapFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
932

933
    virReportUnsupportedError();
934 935 936
    return -1;
}

937 938 939 940

char *
virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm)
941
{
942 943 944 945 946 947 948
    if (mgr->drv->domainGetSecurityMountOptions) {
        char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityMountOptions(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
949

950
    virReportUnsupportedError();
951 952
    return NULL;
}
953

954

955 956 957 958 959
virSecurityManagerPtr*
virSecurityManagerGetNested(virSecurityManagerPtr mgr)
{
    virSecurityManagerPtr* list = NULL;

960
    if (STREQ("stack", mgr->drv->name))
961 962
        return virSecurityStackGetNested(mgr);

963
    if (VIR_ALLOC_N(list, 2) < 0)
964 965 966 967 968 969
        return NULL;

    list[0] = mgr;
    list[1] = NULL;
    return list;
}
970

971 972 973 974 975

int
virSecurityManagerSetHugepages(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm,
                               const char *path)
976
{
977 978 979 980 981 982 983
    if (mgr->drv->domainSetSecurityHugepages) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityHugepages(mgr, vm, path);
        virObjectUnlock(mgr);
        return ret;
    }
984 985 986

    return 0;
}
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003


int
virSecurityManagerDomainSetDirLabel(virSecurityManagerPtr mgr,
                                    virDomainDefPtr vm,
                                    const char *path)
{
    if (mgr->drv->domainSetDirLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetDirLabel(mgr, vm, path);
        virObjectUnlock(mgr);
        return ret;
    }

    return 0;
}