]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
MySQL sqlippool SP: Run as invoker, not definer; close transaction on error (#4170)
authorTerry Burton <tez@terryburton.co.uk>
Tue, 3 Aug 2021 21:17:04 +0000 (22:17 +0100)
committerGitHub <noreply@github.com>
Tue, 3 Aug 2021 21:17:04 +0000 (17:17 -0400)
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.

raddb/mods-config/sql/ippool-dhcp/mysql/procedure-no-skip-locked.sql
raddb/mods-config/sql/ippool-dhcp/mysql/procedure.sql
raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql
raddb/mods-config/sql/ippool/mysql/procedure.sql

index 8d919c711aceea5da31759aaaa7b9c1f1d35ae59..bee37de4abd3c0bf4f24e02d97d5b377cb18d2b4 100644 (file)
@@ -50,6 +50,7 @@ CREATE PROCEDURE fr_allocate_previous_or_new_framedipaddress (
        IN v_lease_duration INT,
        IN v_requested_address VARCHAR(15)
 )
+SQL SECURITY INVOKER
 proc:BEGIN
        DECLARE r_address VARCHAR(15);
 
index d3f9dd5d2c45f09d94cf04a123af6b63ebb893ed..b5dfae087804e337f7eef2e28b619afc932f27f2 100644 (file)
@@ -38,9 +38,16 @@ CREATE PROCEDURE fr_dhcp_allocate_previous_or_new_framedipaddress (
        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;
index d2a53cae6fdf43b3b6aec1899fb52f572ac2ab5d..1c88446543096fd535290d9f98277a408744c18e 100644 (file)
@@ -54,6 +54,7 @@ CREATE PROCEDURE fr_allocate_previous_or_new_framedipaddress (
         IN v_pool_key VARCHAR(64),
         IN v_lease_duration INT
 )
+SQL SECURITY INVOKER
 proc:BEGIN
         DECLARE r_address VARCHAR(15);
 
index 2e88e93d3499288cf01ef5aee7af40fc01e6d5a2..121451fb6a1dca7724e8149a4b8c01677ba9f26a 100644 (file)
@@ -42,9 +42,16 @@ CREATE PROCEDURE fr_allocate_previous_or_new_framedipaddress (
         IN v_pool_key VARCHAR(64),
         IN v_lease_duration INT
 )
+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;