Ejemplo n.º 1
0
/**
 * virStringListCopy:
 * @dst: where to store the copy of @strings
 * @src: a NULL-terminated array of strings
 *
 * Makes a deep copy of the @src string list and stores it in @dst. Callers
 * are responsible for freeing @dst.
 *
 * Returns 0 on success, -1 on error.
 */
int
virStringListCopy(char ***dst,
                  const char **src)
{
    char **copy = NULL;
    size_t i;

    *dst = NULL;

    if (!src)
        return 0;

    if (VIR_ALLOC_N(copy, virStringListLength(src) + 1) < 0)
        goto error;

    for (i = 0; src[i]; i++) {
        if (VIR_STRDUP(copy[i], src[i]) < 0)
            goto error;
    }

    *dst = copy;
    return 0;

 error:
    virStringListFree(copy);
    return -1;
}
Ejemplo n.º 2
0
static int
virStorageBackendSheepdogRefreshAllVol(virConnectPtr conn ATTRIBUTE_UNUSED,
                                       virStoragePoolObjPtr pool)
{
    int ret = -1;
    char *output = NULL;
    char **lines = NULL;
    char **cells = NULL;
    size_t i;

    virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "list", "-r", NULL);
    virStorageBackendSheepdogAddHostArg(cmd, pool);
    virCommandSetOutputBuffer(cmd, &output);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    lines = virStringSplit(output, "\n", 0);
    if (lines == NULL)
        goto cleanup;

    for (i = 0; lines[i]; i++) {
        const char *line = lines[i];
        if (line == NULL)
            break;

        cells = virStringSplit(line, " ", 0);

        if (cells != NULL && virStringListLength(cells) > 2) {
            if (virStorageBackendSheepdogAddVolume(conn, pool, cells[1]) < 0)
                goto cleanup;
        }

        virStringFreeList(cells);
        cells = NULL;
    }

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    virStringFreeList(lines);
    virStringFreeList(cells);
    VIR_FREE(output);
    return ret;
}
Ejemplo n.º 3
0
static int
lxcNetworkParseDataIPs(const char *name,
                       virConfValuePtr value,
                       lxcNetworkParseData *parseData)
{
    int family = AF_INET;
    char **ipparts = NULL;
    virNetDevIPAddrPtr ip = NULL;

    if (VIR_ALLOC(ip) < 0)
        return -1;

    if (STREQ(name, "ipv6"))
        family = AF_INET6;

    ipparts = virStringSplit(value->str, "/", 2);
    if (virStringListLength((const char * const *)ipparts) != 2 ||
        virSocketAddrParse(&ip->address, ipparts[0], family) < 0 ||
        virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) {

        virReportError(VIR_ERR_INVALID_ARG,
                       _("Invalid CIDR address: '%s'"), value->str);

        virStringListFree(ipparts);
        VIR_FREE(ip);
        return -1;
    }

    virStringListFree(ipparts);

    if (VIR_APPEND_ELEMENT(parseData->ips, parseData->nips, ip) < 0) {
        VIR_FREE(ip);
        return -1;
    }

    return 0;
}
Ejemplo n.º 4
0
static int
lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data)
{
    lxcNetworkParseData *parseData = data;
    int status;

    if (STREQ(name, "lxc.network.type")) {
        /* Store the previous NIC */
        status = lxcAddNetworkDefinition(parseData);

        if (status < 0)
            return -1;
        else if (status > 0)
            parseData->networks++;
        else if (parseData->type != NULL && STREQ(parseData->type, "none"))
            parseData->privnet = false;

        /* Start a new network interface config */
        parseData->type = NULL;
        parseData->link = NULL;
        parseData->mac = NULL;
        parseData->flag = NULL;
        parseData->macvlanmode = NULL;
        parseData->vlanid = NULL;
        parseData->name = NULL;

        parseData->ips = NULL;
        parseData->nips = 0;

        /* Keep the new value */
        parseData->type = value->str;
    }
    else if (STREQ(name, "lxc.network.link"))
        parseData->link = value->str;
    else if (STREQ(name, "lxc.network.hwaddr"))
        parseData->mac = value->str;
    else if (STREQ(name, "lxc.network.flags"))
        parseData->flag = value->str;
    else if (STREQ(name, "lxc.network.macvlan.mode"))
        parseData->macvlanmode = value->str;
    else if (STREQ(name, "lxc.network.vlan.id"))
        parseData->vlanid = value->str;
    else if (STREQ(name, "lxc.network.name"))
        parseData->name = value->str;
    else if (STREQ(name, "lxc.network.ipv4") ||
             STREQ(name, "lxc.network.ipv6")) {
        int family = AF_INET;
        char **ipparts = NULL;
        virDomainNetIpDefPtr ip = NULL;

        if (VIR_ALLOC(ip) < 0)
            return -1;

        if (STREQ(name, "lxc.network.ipv6"))
            family = AF_INET6;

        ipparts = virStringSplit(value->str, "/", 2);
        if (virStringListLength((const char * const *)ipparts) != 2 ||
            virSocketAddrParse(&ip->address, ipparts[0], family) < 0 ||
            virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) {

            virReportError(VIR_ERR_INVALID_ARG,
                           _("Invalid CIDR address: '%s'"), value->str);

            virStringFreeList(ipparts);
            VIR_FREE(ip);
            return -1;
        }

        virStringFreeList(ipparts);

        if (VIR_APPEND_ELEMENT(parseData->ips, parseData->nips, ip) < 0) {
            VIR_FREE(ip);
            return -1;
        }
    } else if (STREQ(name, "lxc.network.ipv4.gateway")) {
        parseData->gateway_ipv4 = value->str;
    } else if (STREQ(name, "lxc.network.ipv6.gateway")) {
        parseData->gateway_ipv6 = value->str;
    } else if (STRPREFIX(name, "lxc.network")) {
        VIR_WARN("Unhandled network property: %s = %s",
                 name,
                 value->str);
    }

    return 0;
}
Ejemplo n.º 5
0
/*
 * virPolkitCheckAuth:
 * @actionid: permission to check
 * @pid: client process ID
 * @startTime: process start time, or 0
 * @uid: client process user ID
 * @details: NULL terminated (key, value) pair list
 * @allowInteraction: true if auth prompts are allowed
 *
 * Check if a client is authenticated with polkit
 *
 * Returns 0 on success, -1 on failure, -2 on auth denied
 */
int virPolkitCheckAuth(const char *actionid,
                       pid_t pid,
                       unsigned long long startTime,
                       uid_t uid,
                       const char **details,
                       bool allowInteraction)
{
    DBusConnection *sysbus;
    DBusMessage *reply = NULL;
    char **retdetails = NULL;
    size_t nretdetails = 0;
    bool is_authorized;
    bool is_challenge;
    bool is_dismissed = false;
    size_t i;
    int ret = -1;

    if (!(sysbus = virDBusGetSystemBus()))
        goto cleanup;

    VIR_INFO("Checking PID %lld running as %d",
             (long long) pid, uid);

    if (virDBusCallMethod(sysbus,
                          &reply,
                          NULL,
                          "org.freedesktop.PolicyKit1",
                          "/org/freedesktop/PolicyKit1/Authority",
                          "org.freedesktop.PolicyKit1.Authority",
                          "CheckAuthorization",
                          "(sa{sv})sa&{ss}us",
                          "unix-process",
                          3,
                          "pid", "u", (unsigned int)pid,
                          "start-time", "t", startTime,
                          "uid", "i", (int)uid,
                          actionid,
                          virStringListLength(details) / 2,
                          details,
                          allowInteraction,
                          "" /* cancellation ID */) < 0)
        goto cleanup;

    if (virDBusMessageRead(reply,
                           "(bba&{ss})",
                           &is_authorized,
                           &is_challenge,
                           &nretdetails,
                           &retdetails) < 0)
        goto cleanup;

    for (i = 0; i < (nretdetails / 2); i++) {
        if (STREQ(retdetails[(i * 2)], "polkit.dismissed") &&
            STREQ(retdetails[(i * 2) + 1], "true"))
            is_dismissed = true;
    }

    VIR_DEBUG("is auth %d  is challenge %d",
              is_authorized, is_challenge);

    if (is_authorized) {
        ret = 0;
    } else {
        ret = -2;
        if (is_dismissed)
            virReportError(VIR_ERR_AUTH_CANCELLED, "%s",
                           _("user cancelled authentication process"));
        else if (is_challenge)
            virReportError(VIR_ERR_AUTH_UNAVAILABLE,
                           _("no polkit agent available to authenticate "
                             "action '%s'"),
                           actionid);
        else
            virReportError(VIR_ERR_AUTH_FAILED, "%s",
                           _("access denied by policy"));
    }

 cleanup:
    virStringFreeListCount(retdetails, nretdetails);
    return ret;
}