Ejemplo n.º 1
0
char *virSystemdMakeMachineName(const char *name,
                                const char *drivername,
                                bool privileged)
{
    char *machinename = NULL;
    char *username = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (privileged) {
        virBufferAsprintf(&buf, "%s-", drivername);
    } else {
        if (!(username = virGetUserName(geteuid())))
            goto cleanup;

        virBufferAsprintf(&buf, "%s-%s-", username, drivername);
    }

    virSystemdEscapeName(&buf, name, false);

    machinename = virBufferContentAndReset(&buf);
 cleanup:
    VIR_FREE(username);

    return machinename;
}
Ejemplo n.º 2
0
/**
 * virIdentityGetSystem:
 *
 * Returns an identity that represents the system itself.
 * This is the identity that the process is running as
 *
 * Returns a reference to the system identity, or NULL
 */
virIdentityPtr virIdentityGetSystem(void)
{
    char *username = NULL;
    char *groupname = NULL;
    char *seccontext = NULL;
    virIdentityPtr ret = NULL;
#if WITH_SELINUX
    security_context_t con;
#endif

    if (!(username = virGetUserName(getuid())))
        goto cleanup;
    if (!(groupname = virGetGroupName(getgid())))
        goto cleanup;

#if WITH_SELINUX
    if (getcon(&con) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to lookup SELinux process context"));
        goto cleanup;
    }
    if (VIR_STRDUP(seccontext, con) < 0) {
        freecon(con);
        goto cleanup;
    }
    freecon(con);
#endif

    if (!(ret = virIdentityNew()))
        goto cleanup;

    if (username &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_USER_NAME,
                           username) < 0)
        goto error;
    if (groupname &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_GROUP_NAME,
                           groupname) < 0)
        goto error;
    if (seccontext &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_SELINUX_CONTEXT,
                           seccontext) < 0)
        goto error;

cleanup:
    VIR_FREE(username);
    VIR_FREE(groupname);
    VIR_FREE(seccontext);
    return ret;

error:
    virObjectUnref(ret);
    ret = NULL;
    goto cleanup;
}
Ejemplo n.º 3
0
/**
 * virIdentityGetSystem:
 *
 * Returns an identity that represents the system itself.
 * This is the identity that the process is running as
 *
 * Returns a reference to the system identity, or NULL
 */
virIdentityPtr virIdentityGetSystem(void)
{
    VIR_AUTOFREE(char *) username = NULL;
    VIR_AUTOFREE(char *) groupname = NULL;
    unsigned long long startTime;
    virIdentityPtr ret = NULL;
#if WITH_SELINUX
    security_context_t con;
#endif

    if (!(ret = virIdentityNew()))
        goto error;

    if (virIdentitySetUNIXProcessID(ret, getpid()) < 0)
        goto error;

    if (virProcessGetStartTime(getpid(), &startTime) < 0)
        goto error;
    if (startTime != 0 &&
        virIdentitySetUNIXProcessTime(ret, startTime) < 0)
        goto error;

    if (!(username = virGetUserName(geteuid())))
        return ret;
    if (virIdentitySetUNIXUserName(ret, username) < 0)
        goto error;
    if (virIdentitySetUNIXUserID(ret, getuid()) < 0)
        goto error;

    if (!(groupname = virGetGroupName(getegid())))
        return ret;
    if (virIdentitySetUNIXGroupName(ret, groupname) < 0)
        goto error;
    if (virIdentitySetUNIXGroupID(ret, getgid()) < 0)
        goto error;

#if WITH_SELINUX
    if (is_selinux_enabled() > 0) {
        if (getcon(&con) < 0) {
            virReportSystemError(errno, "%s",
                                 _("Unable to lookup SELinux process context"));
            return ret;
        }
        if (virIdentitySetSELinuxContext(ret, con) < 0) {
            freecon(con);
            goto error;
        }
        freecon(con);
    }
#endif

    return ret;

 error:
    virObjectUnref(ret);
    return NULL;
}
Ejemplo n.º 4
0
char *virSystemdMakeMachineName(const char *name,
                                const char *drivername,
                                bool privileged)
{
    char *machinename = NULL;
    char *username = NULL;
    if (privileged) {
        if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
            goto cleanup;
    } else {
        if (!(username = virGetUserName(geteuid())))
            goto cleanup;
        if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
            goto cleanup;
    }

 cleanup:
    VIR_FREE(username);

    return machinename;
}
Ejemplo n.º 5
0
static int virCgroupAppRoot(int privileged,
                            virCgroupPtr *group,
                            int create)
{
    virCgroupPtr rootgrp = NULL;
    int rc;

    rc = virCgroupNew("/", &rootgrp);
    if (rc != 0)
        return rc;

    if (privileged) {
        rc = virCgroupNew("/libvirt", group);
    } else {
        char *rootname;
        char *username;
        username = virGetUserName(getuid());
        if (!username) {
            rc = -ENOMEM;
            goto cleanup;
        }
        rc = virAsprintf(&rootname, "/libvirt-%s", username);
        VIR_FREE(username);
        if (rc < 0) {
            rc = -ENOMEM;
            goto cleanup;
        }

        rc = virCgroupNew(rootname, group);
        VIR_FREE(rootname);
    }
    if (rc != 0)
        goto cleanup;

    rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE);

cleanup:
    virCgroupFree(&rootgrp);
    return rc;
}
Ejemplo n.º 6
0
static int
virStorageBackendVzPoolStart(virStoragePoolObjPtr pool)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    VIR_AUTOFREE(char *) grp_name = NULL;
    VIR_AUTOFREE(char *) usr_name = NULL;
    VIR_AUTOFREE(char *) mode = NULL;
    VIR_AUTOPTR(virCommand) cmd = NULL;

    /* Check the permissions */
    if (def->target.perms.mode == (mode_t)-1)
        def->target.perms.mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE;
    if (def->target.perms.uid == (uid_t)-1)
        def->target.perms.uid = geteuid();
    if (def->target.perms.gid == (gid_t)-1)
        def->target.perms.gid = getegid();

    /* Convert ids to names because vstorage uses names */

    if (!(grp_name = virGetGroupName(def->target.perms.gid)))
        return -1;

    if (!(usr_name = virGetUserName(def->target.perms.uid)))
        return -1;

    if (virAsprintf(&mode, "%o", def->target.perms.mode) < 0)
        return -1;

    cmd = virCommandNewArgList(VSTORAGE_MOUNT,
                               "-c", def->source.name,
                               def->target.path,
                               "-m", mode,
                               "-g", grp_name, "-u", usr_name,
                               NULL);

    return virCommandRun(cmd, NULL);
}
Ejemplo n.º 7
0
static virIdentityPtr
virNetServerClientCreateIdentity(virNetServerClientPtr client)
{
    char *username = NULL;
    char *groupname = NULL;
    char *seccontext = NULL;
    virIdentityPtr ret = NULL;

    if (!(ret = virIdentityNew()))
        goto error;

    if (client->sock && virNetSocketIsLocal(client->sock)) {
        gid_t gid;
        uid_t uid;
        pid_t pid;
        unsigned long long timestamp;
        if (virNetSocketGetUNIXIdentity(client->sock,
                                        &uid, &gid, &pid,
                                        &timestamp) < 0)
            goto error;

        if (!(username = virGetUserName(uid)))
            goto error;
        if (virIdentitySetUNIXUserName(ret, username) < 0)
            goto error;
        if (virIdentitySetUNIXUserID(ret, uid) < 0)
            goto error;

        if (!(groupname = virGetGroupName(gid)))
            goto error;
        if (virIdentitySetUNIXGroupName(ret, groupname) < 0)
            goto error;
        if (virIdentitySetUNIXGroupID(ret, gid) < 0)
            goto error;

        if (virIdentitySetUNIXProcessID(ret, pid) < 0)
            goto error;
        if (virIdentitySetUNIXProcessTime(ret, timestamp) < 0)
            goto error;
    }

#if WITH_SASL
    if (client->sasl) {
        const char *identity = virNetSASLSessionGetIdentity(client->sasl);
        if (virIdentitySetSASLUserName(ret, identity) < 0)
            goto error;
    }
#endif

#if WITH_GNUTLS
    if (client->tls) {
        const char *identity = virNetTLSSessionGetX509DName(client->tls);
        if (virIdentitySetX509DName(ret, identity) < 0)
            goto error;
    }
#endif

    if (client->sock &&
        virNetSocketGetSELinuxContext(client->sock, &seccontext) < 0)
        goto error;
    if (seccontext &&
        virIdentitySetSELinuxContext(ret, seccontext) < 0)
        goto error;

 cleanup:
    VIR_FREE(username);
    VIR_FREE(groupname);
    VIR_FREE(seccontext);
    return ret;

 error:
    virObjectUnref(ret);
    ret = NULL;
    goto cleanup;
}
Ejemplo n.º 8
0
static virIdentityPtr
virNetServerClientCreateIdentity(virNetServerClientPtr client)
{
    char *processid = NULL;
    char *processtime = NULL;
    char *username = NULL;
    char *userid = NULL;
    char *groupname = NULL;
    char *groupid = NULL;
#if WITH_SASL
    char *saslname = NULL;
#endif
#if WITH_GNUTLS
    char *x509dname = NULL;
#endif
    char *seccontext = NULL;
    virIdentityPtr ret = NULL;

    if (client->sock && virNetSocketIsLocal(client->sock)) {
        gid_t gid;
        uid_t uid;
        pid_t pid;
        unsigned long long timestamp;
        if (virNetSocketGetUNIXIdentity(client->sock,
                                        &uid, &gid, &pid,
                                        &timestamp) < 0)
            goto cleanup;

        if (!(username = virGetUserName(uid)))
            goto cleanup;
        if (virAsprintf(&userid, "%d", (int)uid) < 0)
            goto cleanup;
        if (!(groupname = virGetGroupName(gid)))
            goto cleanup;
        if (virAsprintf(&groupid, "%d", (int)gid) < 0)
            goto cleanup;
        if (virAsprintf(&processid, "%llu",
                        (unsigned long long)pid) < 0)
            goto cleanup;
        if (virAsprintf(&processtime, "%llu",
                        timestamp) < 0)
            goto cleanup;
    }

#if WITH_SASL
    if (client->sasl) {
        const char *identity = virNetSASLSessionGetIdentity(client->sasl);
        if (VIR_STRDUP(saslname, identity) < 0)
            goto cleanup;
    }
#endif

#if WITH_GNUTLS
    if (client->tls) {
        const char *identity = virNetTLSSessionGetX509DName(client->tls);
        if (VIR_STRDUP(x509dname, identity) < 0)
            goto cleanup;
    }
#endif

    if (client->sock &&
        virNetSocketGetSELinuxContext(client->sock, &seccontext) < 0)
        goto cleanup;

    if (!(ret = virIdentityNew()))
        goto cleanup;

    if (username &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_USER_NAME,
                           username) < 0)
        goto error;
    if (userid &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_USER_ID,
                           userid) < 0)
        goto error;
    if (groupname &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_GROUP_NAME,
                           groupname) < 0)
        goto error;
    if (groupid &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_GROUP_ID,
                           groupid) < 0)
        goto error;
    if (processid &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_PROCESS_ID,
                           processid) < 0)
        goto error;
    if (processtime &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_UNIX_PROCESS_TIME,
                           processtime) < 0)
        goto error;
#if WITH_SASL
    if (saslname &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_SASL_USER_NAME,
                           saslname) < 0)
        goto error;
#endif
#if WITH_GNUTLS
    if (x509dname &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_X509_DISTINGUISHED_NAME,
                           x509dname) < 0)
        goto error;
#endif
    if (seccontext &&
        virIdentitySetAttr(ret,
                           VIR_IDENTITY_ATTR_SELINUX_CONTEXT,
                           seccontext) < 0)
        goto error;

cleanup:
    VIR_FREE(username);
    VIR_FREE(userid);
    VIR_FREE(groupname);
    VIR_FREE(groupid);
    VIR_FREE(processid);
    VIR_FREE(processtime);
    VIR_FREE(seccontext);
#if WITH_SASL
    VIR_FREE(saslname);
#endif
#if WITH_GNUTLS
    VIR_FREE(x509dname);
#endif
    return ret;

error:
    virObjectUnref(ret);
    ret = NULL;
    goto cleanup;
}
Ejemplo n.º 9
0
int
main(int argc, char **argv)
{
    virConfPtr conf = NULL;
    const char *login_shell_path = conf_file;
    pid_t cpid = -1;
    int ret = EXIT_CANCELED;
    int status;
    uid_t uid = getuid();
    gid_t gid = getgid();
    char *name = NULL;
    char **shargv = NULL;
    virSecurityModelPtr secmodel = NULL;
    virSecurityLabelPtr seclabel = NULL;
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;
    char *homedir = NULL;
    int arg;
    int longindex = -1;
    int ngroups;
    gid_t *groups = NULL;
    ssize_t nfdlist = 0;
    int *fdlist = NULL;
    int openmax;
    size_t i;

    struct option opt[] = {
        {"help", no_argument, NULL, 'h'},
        {"version", optional_argument, NULL, 'V'},
        {NULL, 0, NULL, 0}
    };
    if (virInitialize() < 0) {
        fprintf(stderr, _("Failed to initialize libvirt error handling"));
        return EXIT_CANCELED;
    }

    setenv("PATH", "/bin:/usr/bin", 1);

    virSetErrorFunc(NULL, NULL);
    virSetErrorLogPriorityFunc(NULL);

    progname = argv[0];
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
        /* failure to setup locale is not fatal */
    }
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
        perror("bindtextdomain");
        return ret;
    }
    if (!textdomain(PACKAGE)) {
        perror("textdomain");
        return ret;
    }

    while ((arg = getopt_long(argc, argv, "hV", opt, &longindex)) != -1) {
        switch (arg) {
        case 'h':
            usage();
            exit(EXIT_SUCCESS);

        case 'V':
            show_version();
            exit(EXIT_SUCCESS);

        case '?':
        default:
            usage();
            exit(EXIT_CANCELED);
        }
    }

    if (argc > optind) {
        virReportSystemError(EINVAL, _("%s takes no options"), progname);
        goto cleanup;
    }

    if (uid == 0) {
        virReportSystemError(EPERM, _("%s must be run by non root users"),
                             progname);
        goto cleanup;
    }

    name = virGetUserName(uid);
    if (!name)
        goto cleanup;

    homedir = virGetUserDirectoryByUID(uid);
    if (!homedir)
        goto cleanup;

    if (!(conf = virConfReadFile(login_shell_path, 0)))
        goto cleanup;

    if ((ngroups = virGetGroupList(uid, gid, &groups)) < 0)
        goto cleanup;

    if (virLoginShellAllowedUser(conf, name, groups) < 0)
        goto cleanup;

    if (!(shargv = virLoginShellGetShellArgv(conf)))
        goto cleanup;

    conn = virConnectOpen("lxc:///");
    if (!conn)
        goto cleanup;

    dom = virDomainLookupByName(conn, name);
    if (!dom)
        goto cleanup;

    if (!virDomainIsActive(dom) && virDomainCreate(dom)) {
        virErrorPtr last_error;
        last_error = virGetLastError();
        if (last_error->code != VIR_ERR_OPERATION_INVALID) {
            virReportSystemError(last_error->code,
                                 _("Can't create %s container: %s"),
                                 name, last_error->message);
            goto cleanup;
        }
    }

    openmax = sysconf(_SC_OPEN_MAX);
    if (openmax < 0) {
        virReportSystemError(errno,  "%s",
                             _("sysconf(_SC_OPEN_MAX) failed"));
        goto cleanup;
    }

    if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0)
        goto cleanup;
    if (VIR_ALLOC(secmodel) < 0)
        goto cleanup;
    if (VIR_ALLOC(seclabel) < 0)
        goto cleanup;
    if (virNodeGetSecurityModel(conn, secmodel) < 0)
        goto cleanup;
    if (virDomainGetSecurityLabel(dom, seclabel) < 0)
        goto cleanup;
    if (virSetUIDGID(0, 0, NULL, 0) < 0)
        goto cleanup;
    if (virDomainLxcEnterSecurityLabel(secmodel, seclabel, NULL, 0) < 0)
        goto cleanup;
    if (nfdlist > 0 &&
        virDomainLxcEnterNamespace(dom, nfdlist, fdlist, NULL, NULL, 0) < 0)
        goto cleanup;
    if (virSetUIDGID(uid, gid, groups, ngroups) < 0)
        goto cleanup;
    if (chdir(homedir) < 0) {
        virReportSystemError(errno, _("Unable to chdir(%s)"), homedir);
        goto cleanup;
    }

    /* A fork is required to create new process in correct pid namespace.  */
    if ((cpid = virFork()) < 0)
        goto cleanup;

    if (cpid == 0) {
        int tmpfd;

        for (i = 3; i < openmax; i++) {
            tmpfd = i;
            VIR_MASS_CLOSE(tmpfd);
        }
        if (execv(shargv[0], (char *const*) shargv) < 0) {
            virReportSystemError(errno, _("Unable to exec shell %s"),
                                 shargv[0]);
            virDispatchError(NULL);
            return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
        }
    }

    /* At this point, the parent is now waiting for the child to exit,
     * but as that may take a long time, we release resources now.  */
 cleanup:
    if (nfdlist > 0)
        for (i = 0; i < nfdlist; i++)
            VIR_FORCE_CLOSE(fdlist[i]);
    VIR_FREE(fdlist);
    virConfFree(conf);
    if (dom)
        virDomainFree(dom);
    if (conn)
        virConnectClose(conn);
    virStringFreeList(shargv);
    VIR_FREE(name);
    VIR_FREE(homedir);
    VIR_FREE(seclabel);
    VIR_FREE(secmodel);
    VIR_FREE(groups);

    if (virProcessWait(cpid, &status, true) == 0)
        virProcessExitWithStatus(status);

    if (virGetLastError())
        virDispatchError(NULL);
    return ret;
}