diff options
author | Vicențiu Ciorbaru <cvicentiu@gmail.com> | 2022-11-24 19:50:14 +0200 |
---|---|---|
committer | Vicențiu Ciorbaru <cvicentiu@gmail.com> | 2022-11-30 22:33:20 +0200 |
commit | b527bfe82310dba39894feff61a1cd7d76a8cc4c (patch) | |
tree | 982683407f481b716eebab0c51be7adbced8ed3a | |
parent | 6c973be2e9f6068507d42ccb644ff0a92e164d08 (diff) | |
download | mariadb-git-b527bfe82310dba39894feff61a1cd7d76a8cc4c.tar.gz |
MDEV-30023 Revoking Privilege on the Column Yields the Errorbb-10.3-vicentiu
The change from MDEV-29465 exposed a flaw in replace_column_table
where again we were not properly updating the column-level bits.
replace_table_table was changed in MDEV-29465 to properly update
grant_table->init_cols, however replace_column_table still only
modified grant_column->rights when the GRANT_COLUMN already existed.
This lead to a missmatch between GRANT_COLUMN::init_rights and
GRANT_COLUMN::rights, *if* the GRANT_COLUMN already existed.
As an example:
GRANT SELECT (col1) ...
Here:
For col1
GRANT_COLUMN::init_rights and GRANT_COLUMN::rights are set to 1 (SELECT) in
replace_column_table.
GRANT INSERT (col1) ...
Here, without this patch GRANT_COLUMN::init_rights is still 1 and
GRANT_COLUMN::rights is 3 (SELECT_PRIV | INSERT_PRIV)
Finally, if before this patch, one does:
REVOKE SELECT (col1) ...
replace_table_table will see that init_rights loses bit 1 thus it
considers there are no more rights granted on that particular table.
This prompts the whole GRANT_TABLE to be removed via the first revoke,
when the GRANT_COLUMN corresponding to it should still have init_rights == 2.
By also updating replace_column_table to keep init_rights in sync
properly, the issue is resolved.
Reviewed by <serg@mariadb.com>
-rw-r--r-- | mysql-test/main/grant5.result | 24 | ||||
-rw-r--r-- | mysql-test/main/grant5.test | 19 | ||||
-rw-r--r-- | sql/sql_acl.cc | 7 |
3 files changed, 48 insertions, 2 deletions
diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index 908a05aadf1..dc8ee527378 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -296,4 +296,28 @@ drop database db; drop user foo@localhost; drop user bar@localhost; drop user buz@localhost; +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.test_getcolpriv(col1 INT, col2 INT); +GRANT SELECT (col1,col2) ON db.test_getcolpriv TO foo; +GRANT INSERT (col1) ON db.test_getcolpriv TO foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +GRANT SELECT (col2, col1), INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +REVOKE SELECT (col1,col2) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +GRANT INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +REVOKE INSERT (col1) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +FLUSH PRIVILEGES; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +DROP USER foo; +DROP DATABASE db; # End of 10.3 tests diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index 35df5a6ec03..cff63d2a9f9 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -259,4 +259,23 @@ drop user foo@localhost; drop user bar@localhost; drop user buz@localhost; +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.test_getcolpriv(col1 INT, col2 INT); + +GRANT SELECT (col1,col2) ON db.test_getcolpriv TO foo; +GRANT INSERT (col1) ON db.test_getcolpriv TO foo; + +SHOW GRANTS FOR foo; +REVOKE SELECT (col1,col2) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +REVOKE INSERT (col1) ON db.test_getcolpriv FROM foo; + +SHOW GRANTS FOR foo; +FLUSH PRIVILEGES; +SHOW GRANTS FOR foo; + +DROP USER foo; +DROP DATABASE db; + --echo # End of 10.3 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 059a6ed4127..b48a4d2fc8d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5148,8 +5148,11 @@ static int replace_column_table(GRANT_TABLE *g_t, error= 0; grant_column= column_hash_search(g_t, column->column.ptr(), column->column.length()); - if (grant_column) // Should always be true - grant_column->rights= privileges; // Update hash + if (grant_column) // Should always be true + { + grant_column->rights= privileges; // Update hash + grant_column->init_rights= privileges; + } } else // new grant { |