static gboolean register_mechanism (GnomeClockAppletMechanism *mechanism) { GError *error = NULL; mechanism->priv->pol_ctx = polkit_context_new (); polkit_context_set_io_watch_functions (mechanism->priv->pol_ctx, pk_io_add_watch, pk_io_remove_watch); if (!polkit_context_init (mechanism->priv->pol_ctx, NULL)) { g_critical ("cannot initialize libpolkit"); goto error; } error = NULL; mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (mechanism->priv->system_bus_connection == NULL) { if (error != NULL) { g_critical ("error getting system bus: %s", error->message); g_error_free (error); } goto error; } dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/", G_OBJECT (mechanism)); mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); reset_killtimer (); return TRUE; error: return FALSE; }
//! Check if sender is allowed to call method int policy_check(const char *sender, const char *action, PolKitResult *result) { /*! * * @sender Bus name of the sender * @result PK result * @return 0 on success, 1 on error */ DBusConnection *conn; DBusError err; PolKitContext *polkit_ctx; PolKitCaller *polkit_clr; PolKitAction *polkit_act; PolKitError *perr; int uid = -1; *result = (PolKitResult) POLKIT_RESULT_NO; dbus_error_init(&err); conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err); if (dbus_error_is_set(&err)) { log_error("Unable to open connection to query PolicyKit: %s\n", err.message); dbus_error_free(&err); return -1; } // If UID is 0, don't query PolicyKit uid = dbus_bus_get_unix_user(conn, sender, &err); if (dbus_error_is_set(&err)) { log_error("Unable to get caller UID: %s\n", err.message); dbus_error_free(&err); return -1; } if (uid == 0) { *result = (PolKitResult) POLKIT_RESULT_YES; return 0; } polkit_ctx = polkit_context_new(); if (!polkit_context_init(polkit_ctx, &perr)) { log_error("Unable to initialize PK context: %s\n", polkit_error_get_error_message(perr)); polkit_error_free(perr); return -1; } polkit_clr = polkit_caller_new_from_dbus_name(conn, sender, &err); if (dbus_error_is_set(&err)) { log_error("Unable to get caller info: %s\n", err.message); dbus_error_free(&err); return -1; } if (!polkit_action_validate_id(action)) { log_error("Unable to query PolicyKit, action is not valid: %s\n", action); return -1; } polkit_act = polkit_action_new(); polkit_action_set_action_id(polkit_act, action); *result = polkit_context_is_caller_authorized(polkit_ctx, polkit_act, polkit_clr, FALSE, &perr); return 0; }
int virPolkitCheckAuth(const char *actionid, pid_t pid, unsigned long long startTime ATTRIBUTE_UNUSED, uid_t uid, const char **details, bool allowInteraction ATTRIBUTE_UNUSED) { PolKitCaller *pkcaller = NULL; PolKitAction *pkaction = NULL; PolKitContext *pkcontext = NULL; PolKitError *pkerr = NULL; PolKitResult pkresult; DBusError err; DBusConnection *sysbus; int ret = -1; if (details) { virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Details not supported with polkit v0")); return -1; } if (!(sysbus = virDBusGetSystemBus())) goto cleanup; VIR_INFO("Checking PID %lld running as %d", (long long) pid, uid); dbus_error_init(&err); if (!(pkcaller = polkit_caller_new_from_pid(sysbus, pid, &err))) { VIR_DEBUG("Failed to lookup policy kit caller: %s", err.message); dbus_error_free(&err); goto cleanup; } if (!(pkaction = polkit_action_new())) { char ebuf[1024]; VIR_DEBUG("Failed to create polkit action %s", virStrerror(errno, ebuf, sizeof(ebuf))); goto cleanup; } polkit_action_set_action_id(pkaction, actionid); if (!(pkcontext = polkit_context_new()) || !polkit_context_init(pkcontext, &pkerr)) { char ebuf[1024]; VIR_DEBUG("Failed to create polkit context %s", (pkerr ? polkit_error_get_error_message(pkerr) : virStrerror(errno, ebuf, sizeof(ebuf)))); if (pkerr) polkit_error_free(pkerr); dbus_error_free(&err); goto cleanup; } # if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED pkresult = polkit_context_is_caller_authorized(pkcontext, pkaction, pkcaller, 0, &pkerr); if (pkerr && polkit_error_is_set(pkerr)) { VIR_DEBUG("Policy kit failed to check authorization %d %s", polkit_error_get_error_code(pkerr), polkit_error_get_error_message(pkerr)); goto cleanup; } # else pkresult = polkit_context_can_caller_do_action(pkcontext, pkaction, pkcaller); # endif if (pkresult != POLKIT_RESULT_YES) { VIR_DEBUG("Policy kit denied action %s from pid %lld, uid %d, result: %s", actionid, (long long) pid, uid, polkit_result_to_string_representation(pkresult)); ret = -2; goto cleanup; } VIR_DEBUG("Policy allowed action %s from pid %lld, uid %d", actionid, (long long)pid, (int)uid); ret = 0; cleanup: if (ret < 0) { virResetLastError(); virReportError(VIR_ERR_AUTH_FAILED, "%s", _("authentication failed")); } if (pkcontext) polkit_context_unref(pkcontext); if (pkcaller) polkit_caller_unref(pkcaller); if (pkaction) polkit_action_unref(pkaction); return ret; }