예제 #1
0
static const char *
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);

    return virSecurityManagerGetDOI(priv->primary);
}
예제 #2
0
void
virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
                                  bool dynamicOwnership)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->dynamicOwnership = dynamicOwnership;
}
예제 #3
0
static int
virSecurityStackClose(virSecurityManagerPtr mgr)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);

    virSecurityManagerFree(priv->primary);
    virSecurityManagerFree(priv->secondary);

    return 0;
}
예제 #4
0
static int
virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
                                 virDomainObjPtr vm)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
        rc = -1;
    if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
        rc = -1;

    return rc;
}
예제 #5
0
static int
SELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
{
    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);

    if (!data)
        return 0;

    VIR_FREE(data->domain_context);
    VIR_FREE(data->file_context);
    VIR_FREE(data->content_context);

    return 0;
}
예제 #6
0
static int
virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
                                       virDomainObjPtr vm,
                                       const char *savefile)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) < 0)
        rc = -1;
    if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
        rc = -1;

    return rc;
}
예제 #7
0
static int
virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                        virDomainObjPtr vm,
                                        int migrated)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
        rc = -1;
    if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
        rc = -1;

    return rc;
}
예제 #8
0
static int
virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                    virDomainObjPtr vm,
                                    const char *stdin_path)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
        rc = -1;
    if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
        rc = -1;

    return rc;
}
예제 #9
0
static int
virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
                                            virDomainObjPtr vm,
                                            virDomainHostdevDefPtr dev)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
        rc = -1;
    if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
        rc = -1;

    return rc;
}
예제 #10
0
static int
virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
                                          virDomainObjPtr vm,
                                          virDomainDiskDefPtr disk)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
        rc = -1;
    if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
        rc = -1;

    return rc;
}
예제 #11
0
static int
virSecurityStackVerify(virSecurityManagerPtr mgr,
                       virDomainDefPtr def)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerVerify(priv->primary, def) < 0)
        rc = -1;

    if (virSecurityManagerVerify(priv->secondary, def) < 0)
        rc = -1;

    return rc;
}
예제 #12
0
static int
virSecurityStackSetFDLabel(virSecurityManagerPtr mgr,
                           virDomainObjPtr vm,
                           int fd)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerSetFDLabel(priv->secondary, vm, fd) < 0)
        rc = -1;
    if (virSecurityManagerSetFDLabel(priv->primary, vm, fd) < 0)
        rc = -1;

    return rc;
}
예제 #13
0
/* returns -1 on error, 0 on success */
int
virSecurityDACSetUserAndGroup(virSecurityManagerPtr mgr,
                              uid_t user,
                              gid_t group)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->user = user;
    priv->group = group;

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

    return 0;
}
예제 #14
0
static int
virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
                             virDomainObjPtr vm)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerReserveLabel(priv->primary, vm) < 0)
        rc = -1;
#if 0
    /* XXX See note in GenLabel */
    if (virSecurityManagerReserveLabel(priv->secondary, vm) < 0)
        rc = -1;
#endif

    return rc;
}
예제 #15
0
static int
virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
                                virDomainObjPtr vm,
                                virSecurityLabelPtr seclabel)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

#if 0
    if (virSecurityManagerGetProcessLabel(priv->secondary, vm, seclabel) < 0)
        rc = -1;
#endif
    if (virSecurityManagerGetProcessLabel(priv->primary, vm, seclabel) < 0)
        rc = -1;

    return rc;
}
예제 #16
0
static int
SELinuxQEMUInitialize(virSecurityManagerPtr mgr)
{
    char *ptr;
    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);

    if (virFileReadAll(selinux_virtual_domain_context_path(), MAX_CONTEXT, &(data->domain_context)) < 0) {
        virReportSystemError(errno,
                             _("cannot read SELinux virtual domain context file '%s'"),
                             selinux_virtual_domain_context_path());
        goto error;
    }

    ptr = strchrnul(data->domain_context, '\n');
    if (ptr)
        *ptr = '\0';

    if (virFileReadAll(selinux_virtual_image_context_path(), 2*MAX_CONTEXT, &(data->file_context)) < 0) {
        virReportSystemError(errno,
                             _("cannot read SELinux virtual image context file %s"),
                             selinux_virtual_image_context_path());
        goto error;
    }

    ptr = strchrnul(data->file_context, '\n');
    if (ptr && *ptr == '\n') {
        *ptr = '\0';
        data->content_context = strdup(ptr+1);
        if (!data->content_context) {
            virReportOOMError();
            goto error;
        }
        ptr = strchrnul(data->content_context, '\n');
        if (ptr && *ptr == '\n')
            *ptr = '\0';
    }

    return 0;

error:
    VIR_FREE(data->domain_context);
    VIR_FREE(data->file_context);
    VIR_FREE(data->content_context);
    return -1;
}
예제 #17
0
static int
SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
                            const char *path,
                            size_t depth,
                            void *opaque)
{
    virSecuritySELinuxCallbackDataPtr cbdata = opaque;
    const virSecurityLabelDefPtr secdef = cbdata->secdef;
    int ret;
    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager);

    if (disk->seclabel && disk->seclabel->norelabel)
        return 0;

    if (disk->seclabel && !disk->seclabel->norelabel &&
        disk->seclabel->label) {
        ret = SELinuxSetFilecon(path, disk->seclabel->label);
    } else if (depth == 0) {

        if (disk->shared) {
            ret = SELinuxSetFileconOptional(path, data->file_context);
        } else if (disk->readonly) {
            ret = SELinuxSetFileconOptional(path, data->content_context);
        } else if (secdef->imagelabel) {
            ret = SELinuxSetFileconOptional(path, secdef->imagelabel);
        } else {
            ret = 0;
        }
    } else {
        ret = SELinuxSetFileconOptional(path, data->content_context);
    }
    if (ret == 1 && !disk->seclabel) {
        /* If we failed to set a label, but virt_use_nfs let us
         * proceed anyway, then we don't need to relabel later.  */
        if (VIR_ALLOC(disk->seclabel) < 0) {
            virReportOOMError();
            return -1;
        }
        disk->seclabel->norelabel = true;
        ret = 0;
    }
    return ret;
}
예제 #18
0
int
virSecurityStackAddNested(virSecurityManagerPtr mgr,
                          virSecurityManagerPtr nested)
{
    virSecurityStackItemPtr item = NULL;
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    virSecurityStackItemPtr tmp;

    tmp = priv->itemsHead;
    while (tmp && tmp->next)
        tmp = tmp->next;

    if (VIR_ALLOC(item) < 0)
        return -1;
    item->securityManager = nested;
    if (tmp)
        tmp->next = item;
    else
        priv->itemsHead = item;

    return 0;
}
예제 #19
0
static int
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
                         virDomainObjPtr vm)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    int rc = 0;

    if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
        rc = -1;

#if 0
    /* We don't allow secondary drivers to generate labels.
     * This may have to change in the future, but requires
     * changes elsewhere in domain_conf.c and capabilities.c
     * XML formats first, to allow recording of multiple
     * labels
     */
    if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
        rc = -1;
#endif

    return rc;
}
예제 #20
0
void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
                            gid_t group)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->group = group;
}
예제 #21
0
void virSecurityDACSetUser(virSecurityManagerPtr mgr,
                           uid_t user)
{
    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->user = user;
}
예제 #22
0
static int
SELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
                        virDomainDefPtr def)
{
    int rc = -1;
    char *mcs = NULL;
    char *scontext = NULL;
    int c1 = 0;
    int c2 = 0;
    context_t ctx = NULL;
    const char *range;
    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);

    VIR_DEBUG("SELinuxGenSecurityLabel %s", virSecurityManagerGetDriver(mgr));
    if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
        !def->seclabel.baselabel &&
        def->seclabel.model) {
        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("security model already defined for VM"));
        return rc;
    }

    if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
        def->seclabel.label) {
        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("security label already defined for VM"));
        return rc;
    }

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

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

    VIR_DEBUG("SELinuxGenSecurityLabel %d", def->seclabel.type);

    switch (def->seclabel.type) {
    case VIR_DOMAIN_SECLABEL_STATIC:
        if (!(ctx = context_new(def->seclabel.label)) ) {
            virReportSystemError(errno,
                                 _("unable to allocate socket security context '%s'"),
                                 def->seclabel.label);
            return rc;
        }

        range = context_range_get(ctx);
        if (!range ||
            !(mcs = strdup(range))) {
            virReportOOMError();
            goto cleanup;
        }
        break;

    case VIR_DOMAIN_SECLABEL_DYNAMIC:
        do {
            c1 = virRandomBits(10);
            c2 = virRandomBits(10);

            if ( c1 == c2 ) {
                if (virAsprintf(&mcs, "s0:c%d", c1) < 0) {
                    virReportOOMError();
                    goto cleanup;
                }
            } else {
                if (c1 > c2) {
                    c1 ^= c2;
                    c2 ^= c1;
                    c1 ^= c2;
                }
                if (virAsprintf(&mcs, "s0:c%d,c%d", c1, c2) < 0) {
                    virReportOOMError();
                    goto cleanup;
                }
            }
        } while (mcsAdd(mcs) == -1);

        def->seclabel.label =
            SELinuxGenNewContext(def->seclabel.baselabel ?
                                 def->seclabel.baselabel :
                                 data->domain_context, mcs);
        if (! def->seclabel.label)  {
            virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("cannot generate selinux context for %s"), mcs);
            goto cleanup;
        }
        break;

    case VIR_DOMAIN_SECLABEL_NONE:
        /* no op */
        break;

    default:
        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unexpected security label type '%s'"),
                               virDomainSeclabelTypeToString(def->seclabel.type));
        goto cleanup;
    }

    if (!def->seclabel.norelabel) {
        def->seclabel.imagelabel = SELinuxGenNewContext(data->file_context, mcs);
        if (!def->seclabel.imagelabel)  {
            virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("cannot generate selinux context for %s"), mcs);
            goto cleanup;
        }
    }

    if (!def->seclabel.model &&
        !(def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) {
        virReportOOMError();
        goto cleanup;
    }

    rc = 0;

cleanup:
    if (rc != 0) {
        if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC)
            VIR_FREE(def->seclabel.label);
        VIR_FREE(def->seclabel.imagelabel);
        if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
            !def->seclabel.baselabel)
            VIR_FREE(def->seclabel.model);
    }

    if (ctx)
        context_free(ctx);
    VIR_FREE(scontext);
    VIR_FREE(mcs);

    VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
              NULLSTR(def->seclabel.model),
              NULLSTR(def->seclabel.label),
              NULLSTR(def->seclabel.imagelabel),
              NULLSTR(def->seclabel.baselabel));

    return rc;
}
예제 #23
0
static int
SELinuxLXCInitialize(virSecurityManagerPtr mgr)
{
    virConfValuePtr scon = NULL;
    virConfValuePtr tcon = NULL;
    virConfValuePtr dcon = NULL;
    virConfPtr selinux_conf;
    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);

    selinux_conf = virConfReadFile(selinux_lxc_contexts_path(), 0);
    if (!selinux_conf) {
        virReportSystemError(errno,
                             _("cannot open SELinux lxc contexts file '%s'"),
                             selinux_lxc_contexts_path());
        return -1;
    }

    scon = virConfGetValue(selinux_conf, "process");
    if (! scon || scon->type != VIR_CONF_STRING || (! scon->str)) {
        virReportSystemError(errno,
                             _("cannot read 'process' value from selinux lxc contexts file '%s'"),
                             selinux_lxc_contexts_path());
        goto error;
    }

    tcon = virConfGetValue(selinux_conf, "file");
    if (! tcon || tcon->type != VIR_CONF_STRING || (! tcon->str)) {
        virReportSystemError(errno,
                             _("cannot read 'file' value from selinux lxc contexts file '%s'"),
                             selinux_lxc_contexts_path());
        goto error;
    }

    dcon = virConfGetValue(selinux_conf, "content");
    if (! dcon || dcon->type != VIR_CONF_STRING || (! dcon->str)) {
        virReportSystemError(errno,
                             _("cannot read 'file' value from selinux lxc contexts file '%s'"),
                             selinux_lxc_contexts_path());
        goto error;
    }

    data->domain_context = strdup(scon->str);
    data->file_context = strdup(tcon->str);
    data->content_context = strdup(dcon->str);
    if (!data->domain_context ||
        !data->file_context ||
        !data->content_context) {
        virReportSystemError(errno,
                             _("cannot allocate memory for LXC SELinux contexts '%s'"),
                             selinux_lxc_contexts_path());
        goto error;
    }
    virConfFree(selinux_conf);
    return 0;

error:
    virConfFree(selinux_conf);
    VIR_FREE(data->domain_context);
    VIR_FREE(data->file_context);
    VIR_FREE(data->content_context);
    return -1;
}
예제 #24
0
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
                                virSecurityManagerPtr primary)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->primary = primary;
}
예제 #25
0
virSecurityManagerPtr
virSecurityStackGetPrimary(virSecurityManagerPtr mgr)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    return priv->itemsHead->securityManager;
}
예제 #26
0
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
                                  virSecurityManagerPtr secondary)
{
    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
    priv->secondary = secondary;
}