From: Terry Burton Date: Tue, 3 Aug 2021 21:16:46 +0000 (+0100) Subject: MySQL sqlippool SP: Run as invoker, not definer; close transaction on error (#4171) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e80f899894ec5f6c2cf669cb57ae5d1c4725168;p=thirdparty%2Ffreeradius-server.git MySQL sqlippool SP: Run as invoker, not definer; close transaction on error (#4171) In MariaDB/MySQL, stored procedures default to running in the context of the definer rather than the invoker. This is a problem in a streaming replication scenario since the definer is often the root user who has the "super" power to write to a read-only database (unless super-read-only is enabled, which is not available for MariaDB), thus breaking the replication timeline. Additionally, exiting an SP does not finalise any running transaction. If an exception is raised within the SP (e.g. due to the database being read-only) we must handle this and finalise the transaction, otherwise subsequent calls to "SET TRANSACTION ISOLATION LEVEL READ COMMITTED" will fail ad nauseam until the connection is finally closed. --- diff --git a/raddb/mods-config/sql/ippool/mysql/procedure.sql b/raddb/mods-config/sql/ippool/mysql/procedure.sql index 1db20854f24..1a05bf99129 100644 --- a/raddb/mods-config/sql/ippool/mysql/procedure.sql +++ b/raddb/mods-config/sql/ippool/mysql/procedure.sql @@ -38,9 +38,16 @@ CREATE PROCEDURE fr_ippool_allocate_previous_or_new_address ( IN v_lease_duration INT, IN v_requested_address VARCHAR(15) ) +SQL SECURITY INVOKER proc:BEGIN DECLARE r_address VARCHAR(15); + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + RESIGNAL; + END; + SET TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION;