security_manager.c 31.3 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
    if (!VIR_CLASS_NEW(virSecurityManager, virClassForObjectLockable()))
63 64 65 66 67 68 69
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(virSecurityManager);

70 71 72 73

static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr drv,
                            const char *virtDriver,
74
                            unsigned int flags)
75
{
76 77
    virSecurityManagerPtr mgr = NULL;
    char *privateData = NULL;
78 79 80

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

82
    VIR_DEBUG("drv=%p (%s) virtDriver=%s flags=0x%x",
83 84 85
              drv, drv->name, virtDriver, flags);

    virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK, NULL);
86

87
    if (VIR_ALLOC_N(privateData, drv->privateDataLen) < 0)
88 89
        return NULL;

90 91
    if (!(mgr = virObjectLockableNew(virSecurityManagerClass)))
        goto error;
92

93
    mgr->drv = drv;
94
    mgr->flags = flags;
95
    mgr->virtDriver = virtDriver;
96
    VIR_STEAL_PTR(mgr->privateData, privateData);
97

98 99
    if (drv->open(mgr) < 0)
        goto error;
100 101

    return mgr;
102 103 104 105
 error:
    VIR_FREE(privateData);
    virObjectUnref(mgr);
    return NULL;
106 107
}

108 109 110

virSecurityManagerPtr
virSecurityManagerNewStack(virSecurityManagerPtr primary)
111 112 113
{
    virSecurityManagerPtr mgr =
        virSecurityManagerNewDriver(&virSecurityDriverStack,
114
                                    virSecurityManagerGetDriver(primary),
115
                                    primary->flags);
116 117 118 119

    if (!mgr)
        return NULL;

120 121
    if (virSecurityStackAddNested(mgr, primary) < 0)
        goto error;
122 123

    return mgr;
124 125 126
 error:
    virObjectUnref(mgr);
    return NULL;
127 128
}

129 130 131 132

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

139 140 141 142 143

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

    virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK |
150 151
                  VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP |
                  VIR_SECURITY_MANAGER_MOUNT_NAMESPACE, NULL);
152 153 154 155

    mgr = virSecurityManagerNewDriver(&virSecurityDriverDAC,
                                      virtDriver,
                                      flags & VIR_SECURITY_MANAGER_NEW_MASK);
156 157 158 159

    if (!mgr)
        return NULL;

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

165
    virSecurityDACSetDynamicOwnership(mgr, flags & VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP);
166
    virSecurityDACSetMountNamespace(mgr, flags & VIR_SECURITY_MANAGER_MOUNT_NAMESPACE);
167
    virSecurityDACSetChownCallback(mgr, chownCallback);
168 169 170 171

    return mgr;
}

172 173 174 175

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

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

190
        if (flags & VIR_SECURITY_MANAGER_DEFAULT_CONFINED) {
191 192 193 194 195 196 197
            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");
            }
198
            flags &= ~VIR_SECURITY_MANAGER_DEFAULT_CONFINED;
199 200 201
        }
    }

202
    return virSecurityManagerNewDriver(drv,
203
                                       virtDriver,
204
                                       flags);
205 206
}

207 208 209

/*
 * Must be called before fork()'ing to ensure mutex state
210 211 212 213
 * 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.
214
 */
215 216
int
virSecurityManagerPreFork(virSecurityManagerPtr mgr)
217
{
218 219
    int ret = 0;

220
    virObjectLock(mgr);
221 222 223 224 225 226 227
    if (mgr->drv->preFork) {
        ret = mgr->drv->preFork(mgr);
        if (ret < 0)
            virObjectUnlock(mgr);
    }

    return ret;
228 229 230 231 232 233 234
}


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

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

/**
 * virSecurityManagerTransactionStart:
 * @mgr: security manager
 *
 * Starts a new transaction. In transaction nothing is changed security
 * label until virSecurityManagerTransactionCommit() is called.
 *
 * Returns 0 on success,
 *        -1 otherwise.
 */
int
virSecurityManagerTransactionStart(virSecurityManagerPtr mgr)
{
    int ret = 0;

    virObjectLock(mgr);
    if (mgr->drv->transactionStart)
        ret = mgr->drv->transactionStart(mgr);
    virObjectUnlock(mgr);
    return ret;
}


/**
 * virSecurityManagerTransactionCommit:
 * @mgr: security manager
 * @pid: domain's PID
 *
270 271 272 273 274 275 276 277 278
 * If @pid is not -1 then enter the @pid namespace (usually @pid refers
 * to a domain) and perform all the operations on the transaction list.
 * If @pid is -1 then the transaction is performed in the namespace of
 * the caller.
 *
 * Note that the transaction is also freed, therefore new one has to be
 * started after successful return from this function. Also it is
 * considered as error if there's no transaction set and this function
 * is called.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
 *
 * Returns: 0 on success,
 *         -1 otherwise.
 */
int
virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr,
                                    pid_t pid)
{
    int ret = 0;

    virObjectLock(mgr);
    if (mgr->drv->transactionCommit)
        ret = mgr->drv->transactionCommit(mgr, pid);
    virObjectUnlock(mgr);
    return ret;
}


/**
 * virSecurityManagerTransactionAbort:
 * @mgr: security manager
 *
 * Cancels and frees any out standing transaction.
 */
void
virSecurityManagerTransactionAbort(virSecurityManagerPtr mgr)
{
    virObjectLock(mgr);
    if (mgr->drv->transactionAbort)
        mgr->drv->transactionAbort(mgr);
    virObjectUnlock(mgr);
}


313 314
void *
virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
315
{
316
    return mgr->privateData;
317 318 319
}


320 321 322 323 324 325
const char *
virSecurityManagerGetDriver(virSecurityManagerPtr mgr)
{
    return mgr->virtDriver;
}

326

327 328 329
const char *
virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
{
330 331 332 333 334 335 336
    if (mgr->drv->getDOI) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getDOI(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
337

338
    virReportUnsupportedError();
339 340 341
    return NULL;
}

342

343 344 345
const char *
virSecurityManagerGetModel(virSecurityManagerPtr mgr)
{
346 347 348 349 350 351 352
    if (mgr->drv->getModel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getModel(mgr);
        virObjectUnlock(mgr);
        return ret;
    }
353

354
    virReportUnsupportedError();
355 356 357
    return NULL;
}

358

359 360
/* return NULL if a base label is not present */
const char *
361 362
virSecurityManagerGetBaseLabel(virSecurityManagerPtr mgr,
                               int virtType)
363 364 365 366 367 368 369 370 371 372 373 374
{
    if (mgr->drv->getBaseLabel) {
        const char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->getBaseLabel(mgr, virtType);
        virObjectUnlock(mgr);
        return ret;
    }

    return NULL;
}

375 376 377

bool
virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr)
378
{
379
    return mgr->flags & VIR_SECURITY_MANAGER_DEFAULT_CONFINED;
380 381
}

382 383 384

bool
virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
385
{
386
    return mgr->flags & VIR_SECURITY_MANAGER_REQUIRE_CONFINED;
387 388
}

389

390 391 392
bool
virSecurityManagerGetPrivileged(virSecurityManagerPtr mgr)
{
393
    return mgr->flags & VIR_SECURITY_MANAGER_PRIVILEGED;
394 395 396
}


397 398 399 400 401 402 403 404 405 406 407
/**
 * 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.
 */
408 409 410 411
int
virSecurityManagerRestoreDiskLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm,
                                   virDomainDiskDefPtr disk)
412
{
413
    if (mgr->drv->domainRestoreSecurityDiskLabel) {
414 415
        int ret;
        virObjectLock(mgr);
416
        ret = mgr->drv->domainRestoreSecurityDiskLabel(mgr, vm, disk);
417 418 419
        virObjectUnlock(mgr);
        return ret;
    }
420

421
    virReportUnsupportedError();
422 423 424
    return -1;
}

425

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
/**
 * 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;
}


454 455 456
int
virSecurityManagerSetDaemonSocketLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr vm)
457
{
458 459 460 461 462 463 464
    if (mgr->drv->domainSetSecurityDaemonSocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityDaemonSocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
465

466
    virReportUnsupportedError();
467 468 469
    return -1;
}

470 471 472 473

int
virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
                                 virDomainDefPtr vm)
474
{
475 476 477 478 479 480 481
    if (mgr->drv->domainSetSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
482

483
    virReportUnsupportedError();
484 485 486
    return -1;
}

487 488 489 490

int
virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm)
491
{
492 493 494 495 496 497 498
    if (mgr->drv->domainClearSecuritySocketLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
499

500
    virReportUnsupportedError();
501 502 503
    return -1;
}

504

505 506 507 508 509 510 511 512 513 514 515
/**
 * 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.
 */
516 517 518 519
int
virSecurityManagerSetDiskLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm,
                               virDomainDiskDefPtr disk)
520
{
521
    if (mgr->drv->domainSetSecurityDiskLabel) {
522 523
        int ret;
        virObjectLock(mgr);
524
        ret = mgr->drv->domainSetSecurityDiskLabel(mgr, vm, disk);
525 526 527
        virObjectUnlock(mgr);
        return ret;
    }
528

529
    virReportUnsupportedError();
530 531 532
    return -1;
}

533

534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
/**
 * 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;
}


562 563 564 565 566
int
virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
                                      virDomainDefPtr vm,
                                      virDomainHostdevDefPtr dev,
                                      const char *vroot)
567
{
568 569 570 571 572 573 574
    if (mgr->drv->domainRestoreSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
575

576
    virReportUnsupportedError();
577 578 579
    return -1;
}

580 581 582 583 584 585

int
virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  virDomainHostdevDefPtr dev,
                                  const char *vroot)
586
{
587 588 589 590 591 592 593
    if (mgr->drv->domainSetSecurityHostdevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev, vroot);
        virObjectUnlock(mgr);
        return ret;
    }
594

595
    virReportUnsupportedError();
596 597 598
    return -1;
}

599 600 601 602 603

int
virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
                                     virDomainDefPtr vm,
                                     const char *savefile)
604
{
605 606 607 608 609 610 611
    if (mgr->drv->domainSetSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
612

613
    virReportUnsupportedError();
614 615 616
    return -1;
}

617 618 619 620
int
virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
                                         virDomainDefPtr vm,
                                         const char *savefile)
621
{
622 623 624 625 626 627 628
    if (mgr->drv->domainRestoreSavedStateLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
        virObjectUnlock(mgr);
        return ret;
    }
629

630
    virReportUnsupportedError();
631 632 633
    return -1;
}

634 635 636 637

int
virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
                           virDomainDefPtr vm)
638
{
639
    int ret = -1;
640
    size_t i;
641 642
    virSecurityManagerPtr* sec_managers = NULL;
    virSecurityLabelDefPtr seclabel;
643
    bool generated = false;
644

645
    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
646
        return ret;
647

648
    virObjectLock(mgr);
649

650
    for (i = 0; sec_managers[i]; i++) {
651 652
        generated = false;
        seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name);
653 654 655 656 657
        if (seclabel == NULL) {
            /* Only generate seclabel if confinement is enabled */
            if (!virSecurityManagerGetDefaultConfined(sec_managers[i])) {
                VIR_DEBUG("Skipping auto generated seclabel");
                continue;
658
            } else {
659 660 661 662 663 664 665 666 667 668 669 670 671
                if (!(seclabel = virSecurityLabelDefNew(sec_managers[i]->drv->name)))
                    goto cleanup;
                generated = seclabel->implicit = true;
                seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
            }
        } else {
            if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
                if (virSecurityManagerGetDefaultConfined(sec_managers[i])) {
                    seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
                } else {
                    seclabel->type = VIR_DOMAIN_SECLABEL_NONE;
                    seclabel->relabel = false;
                }
672
            }
673

674 675 676 677 678 679
            if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) {
                if (virSecurityManagerGetRequireConfined(sec_managers[i])) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("Unconfined guests are not allowed on this host"));
                    goto cleanup;
                }
680
            }
681 682 683
        }

        if (!sec_managers[i]->drv->domainGenSecurityLabel) {
684
            virReportUnsupportedError();
685 686
            virSecurityLabelDefFree(seclabel);
            seclabel = NULL;
687
        } else {
688 689
            /* The seclabel must be added to @vm prior calling domainGenSecurityLabel
             * which may require seclabel to be presented already */
690
            if (generated &&
691
                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0)
692 693 694 695 696 697
                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--;
698
                goto cleanup;
699
            }
700 701

            seclabel = NULL;
702 703 704
        }
    }

705 706
    ret = 0;

707
 cleanup:
708
    virObjectUnlock(mgr);
709 710
    if (generated)
        virSecurityLabelDefFree(seclabel);
711
    VIR_FREE(sec_managers);
712
    return ret;
713 714
}

715 716 717 718 719

int
virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm,
                               pid_t pid)
720
{
721 722 723 724 725 726 727
    if (mgr->drv->domainReserveSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReserveSecurityLabel(mgr, vm, pid);
        virObjectUnlock(mgr);
        return ret;
    }
728

729
    virReportUnsupportedError();
730 731 732
    return -1;
}

733 734 735 736

int
virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm)
737
{
738 739 740 741 742 743 744
    if (mgr->drv->domainReleaseSecurityLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainReleaseSecurityLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
745

746
    virReportUnsupportedError();
747 748 749
    return -1;
}

750

751 752 753
static int virSecurityManagerCheckModel(virSecurityManagerPtr mgr,
                                        char *secmodel)
{
754
    int ret = -1;
755 756 757 758 759 760
    size_t i;
    virSecurityManagerPtr *sec_managers = NULL;

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

761 762 763
    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
        return -1;

764
    for (i = 0; sec_managers[i]; i++) {
765 766 767 768
        if (STREQ_NULLABLE(secmodel, sec_managers[i]->drv->name)) {
            ret = 0;
            goto cleanup;
        }
769 770 771 772 773
    }

    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                   _("Unable to find security driver for model %s"),
                   secmodel);
774 775 776
 cleanup:
    VIR_FREE(sec_managers);
    return ret;
777 778 779
}


780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
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;
}


795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
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;

816 817
    for (i = 0; i < dev->source->nseclabels; i++) {
        if (virSecurityManagerCheckModel(mgr, dev->source->seclabels[i]->model) < 0)
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
            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;

840 841 842
    if (virSecurityManagerCheckDomainLabel(mgr, vm) < 0)
        return -1;

843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
    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;
}


858 859 860
int
virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
                              virDomainDefPtr vm,
861 862
                              const char *stdin_path,
                              bool chardevStdioLogd)
863
{
864 865 866
    if (mgr->drv->domainSetSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
867 868
        ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path,
                                                  chardevStdioLogd);
869 870 871
        virObjectUnlock(mgr);
        return ret;
    }
872

873
    virReportUnsupportedError();
874 875 876
    return -1;
}

877 878 879 880

int
virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
881 882
                                  bool migrated,
                                  bool chardevStdioLogd)
883
{
884 885 886
    if (mgr->drv->domainRestoreSecurityAllLabel) {
        int ret;
        virObjectLock(mgr);
887 888
        ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated,
                                                      chardevStdioLogd);
889 890 891
        virObjectUnlock(mgr);
        return ret;
    }
892

893
    virReportUnsupportedError();
894 895 896
    return -1;
}

897 898 899 900 901
int
virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  pid_t pid,
                                  virSecurityLabelPtr sec)
902
{
903 904 905 906 907 908 909
    if (mgr->drv->domainGetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityProcessLabel(mgr, vm, pid, sec);
        virObjectUnlock(mgr);
        return ret;
    }
910

911
    virReportUnsupportedError();
912 913 914
    return -1;
}

915 916 917 918

int
virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm)
919
{
920 921 922 923 924 925 926
    if (mgr->drv->domainSetSecurityProcessLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
927

928
    virReportUnsupportedError();
929 930 931
    return -1;
}

932 933 934 935 936

int
virSecurityManagerSetChildProcessLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr vm,
                                       virCommandPtr cmd)
937 938 939 940
{
    if (mgr->drv->domainSetSecurityChildProcessLabel)
       return mgr->drv->domainSetSecurityChildProcessLabel(mgr, vm, cmd);

941
    virReportUnsupportedError();
942 943 944
    return -1;
}

945 946 947 948

int
virSecurityManagerVerify(virSecurityManagerPtr mgr,
                         virDomainDefPtr def)
949
{
950 951 952 953 954
    virSecurityLabelDefPtr secdef;

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

955 956 957 958
    /* NULL model == dynamic labelling, with whatever driver
     * is active, so we can short circuit verify check to
     * avoid drivers de-referencing NULLs by accident
     */
959 960
    secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
    if (secdef == NULL || secdef->model == NULL)
961 962
        return 0;

963 964 965 966 967 968 969
    if (mgr->drv->domainSecurityVerify) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSecurityVerify(mgr, def);
        virObjectUnlock(mgr);
        return ret;
    }
970

971
    virReportUnsupportedError();
972 973
    return -1;
}
974

975 976 977 978 979

int
virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm,
                                  int fd)
980
{
981 982 983 984 985 986 987
    if (mgr->drv->domainSetSecurityImageFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityImageFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
988

989
    virReportUnsupportedError();
990 991
    return -1;
}
992

993 994 995 996 997

int
virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
                                virDomainDefPtr vm,
                                int fd)
998
{
999 1000 1001 1002 1003 1004 1005
    if (mgr->drv->domainSetSecurityTapFDLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityTapFDLabel(mgr, vm, fd);
        virObjectUnlock(mgr);
        return ret;
    }
1006

1007
    virReportUnsupportedError();
1008 1009 1010
    return -1;
}

1011 1012 1013 1014

char *
virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
                                  virDomainDefPtr vm)
1015
{
1016 1017 1018 1019 1020 1021 1022
    if (mgr->drv->domainGetSecurityMountOptions) {
        char *ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainGetSecurityMountOptions(mgr, vm);
        virObjectUnlock(mgr);
        return ret;
    }
1023

1024
    virReportUnsupportedError();
1025 1026
    return NULL;
}
1027

1028

1029 1030 1031 1032 1033
virSecurityManagerPtr*
virSecurityManagerGetNested(virSecurityManagerPtr mgr)
{
    virSecurityManagerPtr* list = NULL;

1034
    if (STREQ("stack", mgr->drv->name))
1035 1036
        return virSecurityStackGetNested(mgr);

1037
    if (VIR_ALLOC_N(list, 2) < 0)
1038 1039 1040 1041 1042 1043
        return NULL;

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

1045

1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
/**
 * virSecurityManagerDomainSetPathLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @path: path to label
 * @allowSubtree: whether to allow just @path or its subtree too
 *
 * This function relabels given @path so that @vm can access it.
 * If @allowSubtree is set to true the manager will grant access
 * to @path and its subdirectories at any level (currently
 * implemented only by AppArmor).
 *
 * Returns: 0 on success, -1 on error.
 */
1060
int
1061 1062
virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr,
                                     virDomainDefPtr vm,
1063 1064
                                     const char *path,
                                     bool allowSubtree)
1065
{
1066
    if (mgr->drv->domainSetPathLabel) {
1067 1068
        int ret;
        virObjectLock(mgr);
1069
        ret = mgr->drv->domainSetPathLabel(mgr, vm, path, allowSubtree);
1070 1071 1072 1073 1074 1075
        virObjectUnlock(mgr);
        return ret;
    }

    return 0;
}
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131


/**
 * virSecurityManagerSetMemoryLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @mem: memory module to operate on
 *
 * Labels the host part of a memory module.
 *
 * Returns: 0 on success, -1 on error.
 */
int
virSecurityManagerSetMemoryLabel(virSecurityManagerPtr mgr,
                                     virDomainDefPtr vm,
                                     virDomainMemoryDefPtr mem)
{
    if (mgr->drv->domainSetSecurityMemoryLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityMemoryLabel(mgr, vm, mem);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}


/**
 * virSecurityManagerRestoreMemoryLabel:
 * @mgr: security manager object
 * @vm: domain definition object
 * @mem: memory module to operate on
 *
 * Removes security label from the host part of a memory module.
 *
 * Returns: 0 on success, -1 on error.
 */
int
virSecurityManagerRestoreMemoryLabel(virSecurityManagerPtr mgr,
                                        virDomainDefPtr vm,
                                        virDomainMemoryDefPtr mem)
{
    if (mgr->drv->domainRestoreSecurityMemoryLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityMemoryLabel(mgr, vm, mem);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167


int
virSecurityManagerSetInputLabel(virSecurityManagerPtr mgr,
                                virDomainDefPtr vm,
                                virDomainInputDefPtr input)
{
    if (mgr->drv->domainSetSecurityInputLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityInputLabel(mgr, vm, input);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}


int
virSecurityManagerRestoreInputLabel(virSecurityManagerPtr mgr,
                                    virDomainDefPtr vm,
                                    virDomainInputDefPtr input)
{
    if (mgr->drv->domainRestoreSecurityInputLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityInputLabel(mgr, vm, input);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207


int
virSecurityManagerSetChardevLabel(virSecurityManagerPtr mgr,
                                  virDomainDefPtr def,
                                  virDomainChrSourceDefPtr dev_source,
                                  bool chardevStdioLogd)
{
    if (mgr->drv->domainSetSecurityChardevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityChardevLabel(mgr, def, dev_source,
                                                      chardevStdioLogd);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}


int
virSecurityManagerRestoreChardevLabel(virSecurityManagerPtr mgr,
                                      virDomainDefPtr def,
                                      virDomainChrSourceDefPtr dev_source,
                                      bool chardevStdioLogd)
{
    if (mgr->drv->domainRestoreSecurityChardevLabel) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityChardevLabel(mgr, def, dev_source,
                                                          chardevStdioLogd);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243


int
virSecurityManagerSetTPMLabels(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm)
{
    int ret;

    if (mgr->drv->domainSetSecurityTPMLabels) {
        virObjectLock(mgr);
        ret = mgr->drv->domainSetSecurityTPMLabels(mgr, vm);
        virObjectUnlock(mgr);

        return ret;
    }

    return 0;
}


int
virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr,
                                   virDomainDefPtr vm)
{
    int ret;

    if (mgr->drv->domainRestoreSecurityTPMLabels) {
        virObjectLock(mgr);
        ret = mgr->drv->domainRestoreSecurityTPMLabels(mgr, vm);
        virObjectUnlock(mgr);

        return ret;
    }

    return 0;
}