Ejemplo n.º 1
0
static int
virSystemdPMSupportTarget(const char *methodName, bool *result)
{
    int ret;
    DBusConnection *conn;
    DBusMessage *message = NULL;
    char *response;

    ret = virDBusIsServiceEnabled("org.freedesktop.login1");
    if (ret < 0)
        return ret;

    if ((ret = virDBusIsServiceRegistered("org.freedesktop.login1")) < 0)
        return ret;

    if (!(conn = virDBusGetSystemBus()))
        return -1;

    ret = -1;

    if (virDBusCallMethod(conn,
                          &message,
                          NULL,
                          "org.freedesktop.login1",
                          "/org/freedesktop/login1",
                          "org.freedesktop.login1.Manager",
                          methodName,
                          NULL) < 0)
        return ret;

    if ((ret = virDBusMessageRead(message, "s", &response)) < 0)
        goto cleanup;

    *result = STREQ("yes", response) || STREQ("challenge", response);

    ret = 0;

 cleanup:
    virDBusMessageUnref(message);
    VIR_FREE(response);

    return ret;
}
Ejemplo n.º 2
0
VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
                       DBusMessage *,
                       DBusConnection *, connection,
                       DBusMessage *, message,
                       int, timeout_milliseconds,
                       DBusError *, error)
{
    DBusMessage *reply = NULL;
    const char *service = dbus_message_get_destination(message);
    const char *member = dbus_message_get_member(message);

    VIR_MOCK_REAL_INIT(dbus_connection_send_with_reply_and_block);

    if (STREQ(service, "org.freedesktop.PolicyKit1") &&
        STREQ(member, "CheckAuthorization")) {
        char *type;
        char *pidkey;
        unsigned int pidval;
        char *timekey;
        unsigned long long timeval;
        char *uidkey;
        int uidval;
        char *actionid;
        char **details;
        size_t detailslen;
        int allowInteraction;
        char *cancellationId;
        const char **retdetails = NULL;
        size_t retdetailslen = 0;
        const char *retdetailscancelled[] = {
            "polkit.dismissed", "true",
        };
        int is_authorized = 1;
        int is_challenge = 0;

        if (virDBusMessageRead(message,
                               "(sa{sv})sa&{ss}us",
                               &type,
                               3,
                               &pidkey, "u", &pidval,
                               &timekey, "t", &timeval,
                               &uidkey, "i", &uidval,
                               &actionid,
                               &detailslen,
                               &details,
                               &allowInteraction,
                               &cancellationId) < 0)
            goto error;

        if (STREQ(actionid, "org.libvirt.test.success")) {
            is_authorized = 1;
            is_challenge = 0;
        } else if (STREQ(actionid, "org.libvirt.test.challenge")) {
            is_authorized = 0;
            is_challenge = 1;
        } else if (STREQ(actionid, "org.libvirt.test.cancelled")) {
            is_authorized = 0;
            is_challenge = 0;
            retdetails = retdetailscancelled;
            retdetailslen = ARRAY_CARDINALITY(retdetailscancelled) / 2;
        } else if (STREQ(actionid, "org.libvirt.test.details")) {
            size_t i;
            is_authorized = 0;
            is_challenge = 0;
            for (i = 0; i < detailslen / 2; i++) {
                if (STREQ(details[i * 2],
                          "org.libvirt.test.person") &&
                    STREQ(details[(i * 2) + 1],
                          "Fred")) {
                    is_authorized = 1;
                    is_challenge = 0;
                }
            }
        } else {
            is_authorized = 0;
            is_challenge = 0;
        }

        VIR_FREE(type);
        VIR_FREE(pidkey);
        VIR_FREE(timekey);
        VIR_FREE(uidkey);
        VIR_FREE(actionid);
        VIR_FREE(cancellationId);
        virStringListFreeCount(details, detailslen);

        if (virDBusCreateReply(&reply,
                               "(bba&{ss})",
                               is_authorized,
                               is_challenge,
                               retdetailslen,
                               retdetails) < 0)
            goto error;
    } else {
        reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
    }

    return reply;

 error:
    virDBusMessageUnref(reply);
    return NULL;
}
Ejemplo n.º 3
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;
}