Commit b527bfe8 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

MDEV-30023 Revoking Privilege on the Column Yields the Error

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>
parent 6c973be2
...@@ -296,4 +296,28 @@ drop database db; ...@@ -296,4 +296,28 @@ drop database db;
drop user foo@localhost; drop user foo@localhost;
drop user bar@localhost; drop user bar@localhost;
drop user buz@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 # End of 10.3 tests
...@@ -259,4 +259,23 @@ drop user foo@localhost; ...@@ -259,4 +259,23 @@ drop user foo@localhost;
drop user bar@localhost; drop user bar@localhost;
drop user buz@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 --echo # End of 10.3 tests
...@@ -5148,8 +5148,11 @@ static int replace_column_table(GRANT_TABLE *g_t, ...@@ -5148,8 +5148,11 @@ static int replace_column_table(GRANT_TABLE *g_t,
error= 0; error= 0;
grant_column= column_hash_search(g_t, column->column.ptr(), grant_column= column_hash_search(g_t, column->column.ptr(),
column->column.length()); column->column.length());
if (grant_column) // Should always be true if (grant_column) // Should always be true
grant_column->rights= privileges; // Update hash {
grant_column->rights= privileges; // Update hash
grant_column->init_rights= privileges;
}
} }
else // new grant else // new grant
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment