[MXS-872] MaxScale doesn't understand roles Created: 2016-09-20  Updated: 2020-08-25  Resolved: 2018-06-19

Status: Closed
Project: MariaDB MaxScale
Component/s: Core
Affects Version/s: 2.0.1
Fix Version/s: 2.2.10

Type: Bug Priority: Major
Reporter: markus makela Assignee: markus makela
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Relates
relates to MXS-2544 PAMAuth doesn't check role permissions Closed
Sprint: MXS-SPRINT-60

 Description   

When a user is assigned a role which grants access to a specific database, MaxScale will refuse to grant access for that user.

Steps to reproduce

  1. Execute following SQL on master

    CREATE DATABASE my_db;
    CREATE ROLE dba;
    GRANT SELECT ON my_db.* TO dba;
    CREATE USER 'test'@'%' IDENTIFIED BY 'test';
    SET DEFAULT ROLE dba FOR 'test'@'%';
    

  2. Start MaxScale with any configuration that uses the master where the SQL was executed
  3. Connect to MaxScale as 'test'@'%' with the default database my_db

    mysql -u test -ptest -h $maxscale_host -P $maxscale_port -D my_db
    



 Comments   
Comment by markus makela [ 2016-12-13 ]

A workaround for this is to use the skip_authentication option for the MySQLAuth authenticator module.

Comment by markus makela [ 2017-10-23 ]

The following SQL would use the grants of the role instead of the actual user.

SELECT t.user, t.host, t.db, t.select_priv, t.password FROM 
(
    SELECT u.user, u.host, d.db, u.select_priv, u.password AS password 
    FROM mysql.user AS u LEFT JOIN mysql.db AS d 
    ON (u.user = d.user AND u.host = d.host) 
    UNION 
    SELECT u.user, u.host, t.db, u.select_priv, u.password AS password 
    FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t 
    ON (u.user = t.user AND u.host = t.host)
    WHERE u.is_role <> 'Y'
) AS t 
WHERE (t.user, t.host) NOT IN (SELECT user, host FROM mysql.roles_mapping)
UNION 
SELECT r.user, r.host, u.db, u.select_priv, t.password FROM 
(
    SELECT u.user, u.host, d.db, u.select_priv, u.password AS password
    FROM mysql.user AS u LEFT JOIN mysql.db AS d 
    ON (u.user = d.user AND u.host = d.host) 
    UNION 
    SELECT u.user, u.host, t.db, u.select_priv, u.password AS password
    FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t 
    ON (u.user = t.user AND u.host = t.host) 
) AS t 
JOIN mysql.roles_mapping AS r
ON (r.user = t.user AND r.host = t.host)
JOIN
(
    SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role
    FROM mysql.user AS u LEFT JOIN mysql.db AS d 
    ON (u.user = d.user AND u.host = d.host) 
    UNION 
    SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role 
    FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t 
    ON (u.user = t.user AND u.host = t.host) 
) AS u 
ON (u.user = r.role AND u.is_role = 'Y');

This will only work with MariaDB 10.0 and newer.

Generated at Thu Feb 08 04:02:33 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.