/* Parse config values of the form barrier:limit into barrier and limit */ static int openvzParseBarrierLimit(const char* value, unsigned long long *barrier, unsigned long long *limit) { char **tmp = NULL; size_t ntmp = 0; int ret = -1; if (!(tmp = virStringSplitCount(value, ":", 0, &ntmp))) goto error; if (ntmp != 2) goto error; if (barrier && virStrToLong_ull(tmp[0], NULL, 10, barrier) < 0) goto error; if (limit && virStrToLong_ull(tmp[1], NULL, 10, limit) < 0) goto error; ret = 0; error: virStringFreeListCount(tmp, ntmp); return ret; }
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); virStringFreeListCount(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; }
/* * 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; }