1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-5215 Granted to PUBLIC

This commit is contained in:
Oleksandr Byelkin
2021-12-13 16:15:21 +01:00
committed by Sergei Golubchik
parent 594bed9b42
commit b0325bd6d6
14 changed files with 1326 additions and 205 deletions

View File

@ -0,0 +1,138 @@
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
# it is not PUBLIC but an user
# (this should work as it allowed for roles for example)
create user PUBLIC;
create user PUBLIC@localhost;
GRANT SELECT on test.* to PUBLIC@localhost;
drop user PUBLIC@localhost;
drop user PUBLIC;
# preinstalled PUBLIC
GRANT SELECT on test.* to PUBLIC;
GRANT SELECT on mysql.db to PUBLIC;
select * from mysql.global_priv where user="PUBLIC" ;
Host User Priv
PUBLIC {"access":0,"version_id":VERSION,"is_role":true}
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT SELECT ON `test`.* TO `PUBLIC`
GRANT SELECT ON `mysql`.`db` TO `PUBLIC`
GRANT UPDATE on test.* to PUBLIC;
GRANT UPDATE on mysql.db to PUBLIC;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT SELECT, UPDATE ON `test`.* TO `PUBLIC`
GRANT SELECT, UPDATE ON `mysql`.`db` TO `PUBLIC`
REVOKE SELECT on test.* from PUBLIC;
REVOKE SELECT on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT UPDATE ON `test`.* TO `PUBLIC`
GRANT UPDATE ON `mysql`.`db` TO `PUBLIC`
REVOKE UPDATE on test.* from PUBLIC;
REVOKE UPDATE on mysql.db from PUBLIC;
REVOKE UPDATE on test.* from PUBLIC;
ERROR 42000: There is no such grant defined for user 'PUBLIC' on host ''
REVOKE UPDATE on mysql.db from PUBLIC;
ERROR 42000: There is no such grant defined for user 'PUBLIC' on host '' on table 'db'
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
# automaticly added PUBLIC
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
select * from mysql.global_priv where user="PUBLIC" ;
Host User Priv
GRANT SELECT on test.* to PUBLIC;
GRANT SELECT on mysql.db to PUBLIC;
select * from mysql.global_priv where user="PUBLIC" ;
Host User Priv
PUBLIC {"access":0,"version_id":VERSION,"is_role":true}
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT SELECT ON `test`.* TO `PUBLIC`
GRANT SELECT ON `mysql`.`db` TO `PUBLIC`
GRANT UPDATE on test.* to PUBLIC;
GRANT UPDATE on mysql.db to PUBLIC;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT SELECT, UPDATE ON `test`.* TO `PUBLIC`
GRANT SELECT, UPDATE ON `mysql`.`db` TO `PUBLIC`
REVOKE SELECT on test.* from PUBLIC;
REVOKE SELECT on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT UPDATE ON `test`.* TO `PUBLIC`
GRANT UPDATE ON `mysql`.`db` TO `PUBLIC`
REVOKE UPDATE on test.* from PUBLIC;
REVOKE UPDATE on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
GRANT XXXXXX TO CURRENT_USER;
ERROR OP000: Invalid role specification `XXXXXX`
# following should fail with the same error as above
GRANT PUBLIC TO CURRENT_USER;
ERROR OP000: Invalid role specification `PUBLIC`
REVOKE XXXXXX FROM CURRENT_USER;
ERROR OP000: Invalid role specification `XXXXXX`
# following should fail with the same error as above
REVOKE PUBLIC FROM CURRENT_USER;
ERROR OP000: Invalid role specification `PUBLIC`
drop role XXXXXX;
ERROR HY000: Operation DROP ROLE failed for 'XXXXXX'
# following should fail with the same error as above
drop role PUBLIC;
ERROR HY000: Operation DROP ROLE failed for PUBLIC
SET ROLE XXXXXX;
ERROR OP000: Invalid role specification `XXXXXX`
# following should fail with the same error as above
SET ROLE PUBLIC;
ERROR OP000: Invalid role specification `PUBLIC`
SET DEFAULT ROLE XXXXXX;
ERROR OP000: Invalid role specification `XXXXXX`
# following should fail with the same error as above
SET DEFAULT ROLE PUBLIC;
ERROR OP000: Invalid role specification `PUBLIC`
#
# check prohibition of change security context to PUBLIC
#
# be sure that we have PUBLIC
GRANT SELECT on test.* to PUBLIC;
# try with a view
create table t1( a int);
create definer = PUBLIC view v1 as select * from t1;
Warnings:
Note 1449 The user specified as a definer ('PUBLIC'@'') does not exist
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`PUBLIC` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
Warnings:
Note 1449 The user specified as a definer ('PUBLIC'@'') does not exist
select * from v1;
ERROR HY000: The user specified as a definer ('PUBLIC'@'') does not exist
drop view v1;
drop table t1;
# try with a view
create definer='PUBLIC' PROCEDURE p1() SELECT 1;
Warnings:
Note 1449 The user specified as a definer ('PUBLIC'@'') does not exist
show create procedure p1;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`PUBLIC` PROCEDURE `p1`()
SELECT 1 latin1 latin1_swedish_ci latin1_swedish_ci
call p1();
ERROR HY000: The user specified as a definer ('PUBLIC'@'') does not exist
drop procedure p1;
# this test cleanup
REVOKE SELECT on test.* from PUBLIC;
#
# check autocreation of PUBLIC on GRAND role TO PUBLIC
#
# make sure that the privilege will be added automatically
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
create role roletest;
GRANT roletest TO PUBLIC;
drop role roletest;
# clean up
delete from mysql.global_priv where user="PUBLIC";
flush privileges;

View File

@ -0,0 +1,130 @@
SHOW GRANTS FOR PUBLIC;
--echo # it is not PUBLIC but an user
--echo # (this should work as it allowed for roles for example)
create user PUBLIC;
create user PUBLIC@localhost;
GRANT SELECT on test.* to PUBLIC@localhost;
drop user PUBLIC@localhost;
drop user PUBLIC;
--echo # preinstalled PUBLIC
GRANT SELECT on test.* to PUBLIC;
GRANT SELECT on mysql.db to PUBLIC;
--replace_regex /"version_id"\:[0-9]+/"version_id":VERSION/
select * from mysql.global_priv where user="PUBLIC" ;
SHOW GRANTS FOR PUBLIC;
GRANT UPDATE on test.* to PUBLIC;
GRANT UPDATE on mysql.db to PUBLIC;
SHOW GRANTS FOR PUBLIC;
REVOKE SELECT on test.* from PUBLIC;
REVOKE SELECT on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
REVOKE UPDATE on test.* from PUBLIC;
REVOKE UPDATE on mysql.db from PUBLIC;
--error ER_NONEXISTING_GRANT
REVOKE UPDATE on test.* from PUBLIC;
--error ER_NONEXISTING_TABLE_GRANT
REVOKE UPDATE on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
--echo # automaticly added PUBLIC
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
select * from mysql.global_priv where user="PUBLIC" ;
GRANT SELECT on test.* to PUBLIC;
GRANT SELECT on mysql.db to PUBLIC;
--replace_regex /"version_id"\:[0-9]+/"version_id":VERSION/
select * from mysql.global_priv where user="PUBLIC" ;
SHOW GRANTS FOR PUBLIC;
GRANT UPDATE on test.* to PUBLIC;
GRANT UPDATE on mysql.db to PUBLIC;
SHOW GRANTS FOR PUBLIC;
REVOKE SELECT on test.* from PUBLIC;
REVOKE SELECT on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
REVOKE UPDATE on test.* from PUBLIC;
REVOKE UPDATE on mysql.db from PUBLIC;
SHOW GRANTS FOR PUBLIC;
--error ER_INVALID_ROLE
GRANT XXXXXX TO CURRENT_USER;
--echo # following should fail with the same error as above
--error ER_INVALID_ROLE
GRANT PUBLIC TO CURRENT_USER;
--error ER_INVALID_ROLE
REVOKE XXXXXX FROM CURRENT_USER;
--echo # following should fail with the same error as above
--error ER_INVALID_ROLE
REVOKE PUBLIC FROM CURRENT_USER;
--error ER_CANNOT_USER
drop role XXXXXX;
--echo # following should fail with the same error as above
--error ER_CANNOT_USER
drop role PUBLIC;
--error ER_INVALID_ROLE
SET ROLE XXXXXX;
--echo # following should fail with the same error as above
--error ER_INVALID_ROLE
SET ROLE PUBLIC;
--error ER_INVALID_ROLE
SET DEFAULT ROLE XXXXXX;
--echo # following should fail with the same error as above
--error ER_INVALID_ROLE
SET DEFAULT ROLE PUBLIC;
--echo #
--echo # check prohibition of change security context to PUBLIC
--echo #
--echo # be sure that we have PUBLIC
GRANT SELECT on test.* to PUBLIC;
--echo # try with a view
create table t1( a int);
create definer = PUBLIC view v1 as select * from t1;
show create view v1;
--error ER_NO_SUCH_USER
select * from v1;
drop view v1;
drop table t1;
--echo # try with a view
create definer='PUBLIC' PROCEDURE p1() SELECT 1;
show create procedure p1;
--error ER_NO_SUCH_USER
call p1();
drop procedure p1;
--echo # this test cleanup
REVOKE SELECT on test.* from PUBLIC;
--echo #
--echo # check autocreation of PUBLIC on GRAND role TO PUBLIC
--echo #
--echo # make sure that the privilege will be added automatically
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
create role roletest;
GRANT roletest TO PUBLIC;
drop role roletest;
-- echo # clean up
delete from mysql.global_priv where user="PUBLIC";
flush privileges;

View File

@ -0,0 +1,346 @@
#
# Test DB/TABLE/COLUMN privileges in queries
#
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
insert into t1 values (1,2);
create database testdb2;
use testdb2;
create table t2 (a int, b int);
insert into t2 values (1,2);
create table t3 (a int, b int);
insert into t3 values (1,2);
connect testuser,localhost,testuser,,;
connection testuser;
select * from testdb1.t1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb1`.`t1`
select * from testdb2.t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb2`.`t2`
select b from testdb2.t3;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb2`.`t3`
select a from testdb2.t3;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb2`.`t3`
connection default;
GRANT SELECT ON testdb1.* to PUBLIC;
GRANT SELECT ON testdb2.t2 to PUBLIC;
GRANT SELECT (b) ON testdb2.t3 to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
select * from testdb1.t1;
a b
1 2
select * from testdb2.t2;
a b
1 2
select b from testdb2.t3;
b
2
select a from testdb2.t3;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'a' in table 't3'
connection default;
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,;
connection testuser;
select * from testdb1.t1;
a b
1 2
select * from testdb2.t2;
a b
1 2
select b from testdb2.t3;
b
2
select a from testdb2.t3;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'a' in table 't3'
connection default;
use test;
disconnect testuser;
REVOKE SELECT ON testdb1.* from PUBLIC;
REVOKE SELECT ON testdb2.t2 from PUBLIC;
REVOKE SELECT (b) ON testdb2.t3 from PUBLIC;
drop user testuser;
drop database testdb1;
drop database testdb2;
#
# test global process list privilege and EXECUTE db level
#
create user testuser;
create database testdb;
use testdb;
create procedure p1 () select 1;
connect testuser,localhost,testuser,,;
connection testuser;
SHOW PROCESSLIST;
Id User Host db Command Time State Info Progress
# testuser # NULL Query # # SHOW PROCESSLIST 0.000
call testdb.p1();
ERROR 42000: execute command denied to user 'testuser'@'%' for routine 'testdb.p1'
connection default;
GRANT PROCESS ON *.* to PUBLIC;
GRANT EXECUTE ON testdb.* to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
SHOW PROCESSLIST;
Id User Host db Command Time State Info Progress
# root # testdb Sleep # # NULL 0.000
# testuser # NULL Query # # SHOW PROCESSLIST 0.000
call testdb.p1();
1
1
connection default;
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,;
connection testuser;
SHOW PROCESSLIST;
Id User Host db Command Time State Info Progress
# root # testdb Sleep # # NULL 0.000
# testuser # NULL Query # # SHOW PROCESSLIST 0.000
call testdb.p1();
1
1
connection default;
SHOW PROCESSLIST;
Id User Host db Command Time State Info Progress
# root # testdb Query # # SHOW PROCESSLIST 0.000
# testuser # NULL Sleep # # NULL 0.000
connection default;
use test;
disconnect testuser;
REVOKE PROCESS ON *.* from PUBLIC;
REVOKE EXECUTE ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
#
# test DB privilege to allow USE statement
#
create user testuser;
create database testdb;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
ERROR 42000: Access denied for user 'testuser'@'%' to database 'testdb'
connection default;
GRANT LOCK TABLES ON testdb.* to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
connection default;
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
connection default;
use test;
disconnect testuser;
REVOKE LOCK TABLES ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
#
# test DB privilege to allow USE statement (as above)
# test current db privileges
#
create user testuser;
create database testdb;
use testdb;
create table t1 (a int);
insert into t1 values (1);
GRANT LOCK TABLES ON testdb.* to PUBLIC;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
update t1 set a=a+1;
ERROR 42000: UPDATE command denied to user 'testuser'@'localhost' for table `testdb`.`t1`
connection default;
GRANT UPDATE,SELECT ON testdb.* to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
update t1 set a=a+1;
connection default;
select * from testdb.t1;
a
2
use test;
disconnect testuser;
REVOKE LOCK TABLES ON testdb.* from PUBLIC;
REVOKE UPDATE,SELECT ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
#
# test DB privilege to allow USE statement (as above)
# test table/column privileges in current DB
#
create user testuser;
create database testdb;
use testdb;
create table t1 (a int);
insert into t1 values (1);
create table t2 (a int, b int);
insert into t2 values (1,2);
GRANT LOCK TABLES ON testdb.* to PUBLIC;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
delete from t1;
ERROR 42000: DELETE command denied to user 'testuser'@'localhost' for table `testdb`.`t1`
select b from t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb`.`t2`
select a from t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb`.`t2`
connection default;
GRANT DELETE ON testdb.t1 to PUBLIC;
GRANT SELECT (a) ON testdb.t2 to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
delete from t1;
select a from t2;
a
1
select b from t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't2'
connection default;
select * from testdb.t1;
a
insert into t1 values (1);
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,;
connection testuser;
use testdb;
delete from t1;
select a from t2;
a
1
select b from t2;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't2'
connection default;
select * from testdb.t1;
a
use test;
disconnect testuser;
REVOKE ALL PRIVILEGES, GRANT OPTION from `PUBLIC`;
SHOW GRANTS FOR PUBLIC;
Grants for PUBLIC
drop user testuser;
drop database testdb;
#
# test function privilege
#
create user testuser;
create database testdb;
use testdb;
create function f1() returns int return 2;
connect testuser,localhost,testuser,,;
connection testuser;
alter function testdb.f1 comment "A stupid function";
ERROR 42000: alter routine command denied to user 'testuser'@'%' for routine 'testdb.f1'
select testdb.f1();
ERROR 42000: execute command denied to user 'testuser'@'%' for routine 'testdb.f1'
connection default;
GRANT ALTER ROUTINE ON testdb.* to PUBLIC;
disconnect testuser;
connect testuser,localhost,testuser,,;
connection testuser;
alter function testdb.f1 comment "A stupid function";
select testdb.f1();
ERROR 42000: execute command denied to user 'testuser'@'%' for routine 'testdb.f1'
connection default;
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,;
connection testuser;
alter function testdb.f1 comment "A stupid function";
select testdb.f1();
ERROR 42000: execute command denied to user 'testuser'@'%' for routine 'testdb.f1'
connection default;
use test;
disconnect testuser;
REVOKE ALTER ROUTINE ON testdb.* from PUBLIC;
drop function testdb.f1;
drop user testuser;
drop database testdb;
#
# bug with automatically added PUBLIC role
#
# automaticly added PUBLIC
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
GRANT SELECT on test.* to PUBLIC;
REVOKE SELECT on test.* from PUBLIC;
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
insert into t1 values (1,2);
connect testuser,localhost,testuser,,;
connection testuser;
select * from testdb1.t1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb1`.`t1`
connection default;
disconnect testuser;
drop user testuser;
drop database testdb1;
#
# check assigning privileges via GRAND role TO PUBLIC
#
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
# check that user do not have rights
connect testuser,localhost,testuser,,*NO-ONE*;
connection testuser;
select * from testdb1.t1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb1`.`t1`
connection default;
disconnect testuser;
give rights to everyone via assigning the role to public
create role roletest;
GRANT SELECT ON testdb1.* TO roletest;
GRANT roletest TO PUBLIC;
connect testuser,localhost,testuser,,*NO-ONE*;
connection testuser;
select * from testdb1.t1;
a b
connection default;
disconnect testuser;
# check that the privilegas correctly read by acl_load
flush privileges;
connect testuser,localhost,testuser,,*NO-ONE*;
connection testuser;
select * from testdb1.t1;
a b
connection default;
disconnect testuser;
# drop role...
drop role roletest;
# ... and check that user do not have rights again
connect testuser,localhost,testuser,,*NO-ONE*;
connection testuser;
select * from testdb1.t1;
ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table `testdb1`.`t1`
connection default;
disconnect testuser;
drop user testuser;
drop database testdb1;
# clean up
delete from mysql.global_priv where user="PUBLIC";
flush privileges;

View File

@ -0,0 +1,411 @@
--echo #
--echo # Test DB/TABLE/COLUMN privileges in queries
--echo #
SHOW GRANTS FOR PUBLIC;
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
insert into t1 values (1,2);
create database testdb2;
use testdb2;
create table t2 (a int, b int);
insert into t2 values (1,2);
create table t3 (a int, b int);
insert into t3 values (1,2);
connect (testuser,localhost,testuser,,);
connection testuser;
--error ER_TABLEACCESS_DENIED_ERROR
select * from testdb1.t1;
--error ER_TABLEACCESS_DENIED_ERROR
select * from testdb2.t2;
--error ER_TABLEACCESS_DENIED_ERROR
select b from testdb2.t3;
--error ER_TABLEACCESS_DENIED_ERROR
select a from testdb2.t3;
connection default;
GRANT SELECT ON testdb1.* to PUBLIC;
GRANT SELECT ON testdb2.t2 to PUBLIC;
GRANT SELECT (b) ON testdb2.t3 to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
select * from testdb1.t1;
select * from testdb2.t2;
select b from testdb2.t3;
--error ER_COLUMNACCESS_DENIED_ERROR
select a from testdb2.t3;
connection default;
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,);
connection testuser;
select * from testdb1.t1;
select * from testdb2.t2;
select b from testdb2.t3;
--error ER_COLUMNACCESS_DENIED_ERROR
select a from testdb2.t3;
connection default;
use test;
disconnect testuser;
REVOKE SELECT ON testdb1.* from PUBLIC;
REVOKE SELECT ON testdb2.t2 from PUBLIC;
REVOKE SELECT (b) ON testdb2.t3 from PUBLIC;
drop user testuser;
drop database testdb1;
drop database testdb2;
--echo #
--echo # test global process list privilege and EXECUTE db level
--echo #
create user testuser;
create database testdb;
use testdb;
create procedure p1 () select 1;
connect (testuser,localhost,testuser,,);
connection testuser;
--replace_column 1 # 3 # 6 # 7 #
SHOW PROCESSLIST;
--error ER_PROCACCESS_DENIED_ERROR
call testdb.p1();
connection default;
GRANT PROCESS ON *.* to PUBLIC;
GRANT EXECUTE ON testdb.* to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
--replace_column 1 # 3 # 6 # 7 #
SHOW PROCESSLIST;
call testdb.p1();
connection default;
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,);
connection testuser;
--replace_column 1 # 3 # 6 # 7 #
SHOW PROCESSLIST;
call testdb.p1();
connection default;
--replace_column 1 # 3 # 6 # 7 #
SHOW PROCESSLIST;
connection default;
use test;
disconnect testuser;
REVOKE PROCESS ON *.* from PUBLIC;
REVOKE EXECUTE ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
--echo #
--echo # test DB privilege to allow USE statement
--echo #
create user testuser;
create database testdb;
connect (testuser,localhost,testuser,,);
connection testuser;
--error ER_DBACCESS_DENIED_ERROR
use testdb;
connection default;
GRANT LOCK TABLES ON testdb.* to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
connection default;
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
connection default;
use test;
disconnect testuser;
REVOKE LOCK TABLES ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
--echo #
--echo # test DB privilege to allow USE statement (as above)
--echo # test current db privileges
--echo #
create user testuser;
create database testdb;
use testdb;
create table t1 (a int);
insert into t1 values (1);
GRANT LOCK TABLES ON testdb.* to PUBLIC;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
--error ER_TABLEACCESS_DENIED_ERROR
update t1 set a=a+1;
connection default;
GRANT UPDATE,SELECT ON testdb.* to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
update t1 set a=a+1;
connection default;
select * from testdb.t1;
use test;
disconnect testuser;
REVOKE LOCK TABLES ON testdb.* from PUBLIC;
REVOKE UPDATE,SELECT ON testdb.* from PUBLIC;
drop user testuser;
drop database testdb;
--echo #
--echo # test DB privilege to allow USE statement (as above)
--echo # test table/column privileges in current DB
--echo #
create user testuser;
create database testdb;
use testdb;
create table t1 (a int);
insert into t1 values (1);
create table t2 (a int, b int);
insert into t2 values (1,2);
GRANT LOCK TABLES ON testdb.* to PUBLIC;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
--error ER_TABLEACCESS_DENIED_ERROR
delete from t1;
--error ER_TABLEACCESS_DENIED_ERROR
select b from t2;
--error ER_TABLEACCESS_DENIED_ERROR
select a from t2;
connection default;
GRANT DELETE ON testdb.t1 to PUBLIC;
GRANT SELECT (a) ON testdb.t2 to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
delete from t1;
select a from t2;
--error ER_COLUMNACCESS_DENIED_ERROR
select b from t2;
connection default;
select * from testdb.t1;
insert into t1 values (1);
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,);
connection testuser;
use testdb;
delete from t1;
select a from t2;
--error ER_COLUMNACCESS_DENIED_ERROR
select b from t2;
connection default;
select * from testdb.t1;
use test;
disconnect testuser;
REVOKE ALL PRIVILEGES, GRANT OPTION from `PUBLIC`;
SHOW GRANTS FOR PUBLIC;
drop user testuser;
drop database testdb;
--echo #
--echo # test function privilege
--echo #
create user testuser;
create database testdb;
use testdb;
create function f1() returns int return 2;
connect (testuser,localhost,testuser,,);
connection testuser;
--error ER_PROCACCESS_DENIED_ERROR
alter function testdb.f1 comment "A stupid function";
--error ER_PROCACCESS_DENIED_ERROR
select testdb.f1();
connection default;
GRANT ALTER ROUTINE ON testdb.* to PUBLIC;
disconnect testuser;
connect (testuser,localhost,testuser,,);
connection testuser;
alter function testdb.f1 comment "A stupid function";
--error ER_PROCACCESS_DENIED_ERROR
select testdb.f1();
connection default;
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,);
connection testuser;
alter function testdb.f1 comment "A stupid function";
--error ER_PROCACCESS_DENIED_ERROR
select testdb.f1();
connection default;
use test;
disconnect testuser;
REVOKE ALTER ROUTINE ON testdb.* from PUBLIC;
drop function testdb.f1;
drop user testuser;
drop database testdb;
--echo #
--echo # bug with automatically added PUBLIC role
--echo #
--echo # automaticly added PUBLIC
delete from mysql.global_priv where user="PUBLIC";
flush privileges;
GRANT SELECT on test.* to PUBLIC;
REVOKE SELECT on test.* from PUBLIC;
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
insert into t1 values (1,2);
connect (testuser,localhost,testuser,,);
connection testuser;
--error ER_TABLEACCESS_DENIED_ERROR
select * from testdb1.t1;
connection default;
disconnect testuser;
drop user testuser;
drop database testdb1;
--echo #
--echo # check assigning privileges via GRAND role TO PUBLIC
--echo #
create user testuser;
create database testdb1;
use testdb1;
create table t1 (a int, b int);
--echo # check that user do not have rights
connect (testuser,localhost,testuser,,*NO-ONE*);
connection testuser;
--error ER_TABLEACCESS_DENIED_ERROR
select * from testdb1.t1;
connection default;
disconnect testuser;
--echo give rights to everyone via assigning the role to public
create role roletest;
GRANT SELECT ON testdb1.* TO roletest;
GRANT roletest TO PUBLIC;
connect (testuser,localhost,testuser,,*NO-ONE*);
connection testuser;
select * from testdb1.t1;
connection default;
disconnect testuser;
--echo # check that the privilegas correctly read by acl_load
flush privileges;
connect (testuser,localhost,testuser,,*NO-ONE*);
connection testuser;
select * from testdb1.t1;
connection default;
disconnect testuser;
--echo # drop role...
drop role roletest;
--echo # ... and check that user do not have rights again
connect (testuser,localhost,testuser,,*NO-ONE*);
connection testuser;
--error ER_TABLEACCESS_DENIED_ERROR
select * from testdb1.t1;
connection default;
disconnect testuser;
drop user testuser;
drop database testdb1;
-- echo # clean up
delete from mysql.global_priv where user="PUBLIC";
flush privileges;

View File

@ -14,9 +14,6 @@ ERROR OP000: Invalid role specification `none`
grant public to role1;
ERROR OP000: Invalid role specification `public`
grant role1 to public;
ERROR OP000: Invalid role specification `public`
grant select on *.* to public;
ERROR OP000: Invalid role specification `public`
grant role1 to current_role;
ERROR OP000: Invalid role specification `NONE`
revoke none from role1;
@ -28,21 +25,15 @@ ERROR OP000: Invalid role specification `none`
revoke public from role1;
ERROR OP000: Invalid role specification `public`
revoke role1 from public;
ERROR OP000: Invalid role specification `public`
ERROR HY000: Cannot revoke role 'role1' from: 'public'@'%'
revoke select on *.* from public;
ERROR OP000: Invalid role specification `public`
show grants for none;
ERROR OP000: Invalid role specification `none`
show grants for public;
ERROR OP000: Invalid role specification `public`
create definer=none view test.v1 as select 1;
ERROR OP000: Invalid role specification `none`
create definer=public view test.v1 as select 1;
ERROR OP000: Invalid role specification `public`
drop role role1;
insert mysql.global_priv values ('', 'none', '{"is_role":true}'), ('', 'public', '{"is_role":true}');
insert mysql.global_priv values ('', 'none', '{"is_role":true}');
flush privileges;
Warnings:
Error 1959 Invalid role specification `none`
Error 1959 Invalid role specification `public`
delete from mysql.global_priv where host='';

View File

@ -17,10 +17,10 @@ grant role1 to none;
grant select on *.* to none;
--error ER_INVALID_ROLE
grant public to role1;
--error ER_INVALID_ROLE
grant role1 to public;
--error ER_INVALID_ROLE
grant select on *.* to public;
# PUBLIC is legal role
#--error ER_INVALID_ROLE
#grant select on *.* to public;
--error ER_INVALID_ROLE
grant role1 to current_role;
@ -33,23 +33,24 @@ revoke role1 from none;
revoke select on *.* from none;
--error ER_INVALID_ROLE
revoke public from role1;
--error ER_INVALID_ROLE
--error ER_CANNOT_REVOKE_ROLE
revoke role1 from public;
--error ER_INVALID_ROLE
revoke select on *.* from public;
--error ER_INVALID_ROLE
show grants for none;
--error ER_INVALID_ROLE
show grants for public;
# PUBLIC is legal role
#--error ER_INVALID_ROLE
#show grants for public;
--error ER_INVALID_ROLE
create definer=none view test.v1 as select 1;
--error ER_INVALID_ROLE
create definer=public view test.v1 as select 1;
# PUBLIC is legal role
#--error ER_INVALID_ROLE
#create definer=public view test.v1 as select 1;
drop role role1;
insert mysql.global_priv values ('', 'none', '{"is_role":true}'), ('', 'public', '{"is_role":true}');
insert mysql.global_priv values ('', 'none', '{"is_role":true}');
flush privileges;
delete from mysql.global_priv where host='';

View File

@ -103,7 +103,9 @@ LEX_CSTRING host_not_specified= { STRING_WITH_LEN("%") };
*/
LEX_CSTRING current_user= { STRING_WITH_LEN("*current_user") };
LEX_CSTRING current_role= { STRING_WITH_LEN("*current_role") };
LEX_CSTRING current_user_and_current_role= { STRING_WITH_LEN("*current_user_and_current_role") };
LEX_CSTRING current_user_and_current_role=
{ STRING_WITH_LEN("*current_user_and_current_role") };
LEX_CSTRING public_name= {STRING_WITH_LEN("PUBLIC") };
static plugin_ref old_password_plugin;
@ -317,6 +319,13 @@ static bool show_table_and_column_privileges(THD *, const char *, const char *,
static int show_routine_grants(THD *, const char *, const char *,
const Sp_handler *sph, char *, int);
static ACL_ROLE *acl_public= NULL;
inline privilege_t public_access()
{
return (acl_public ? acl_public->access : NO_ACL);
}
class Grant_tables;
class User_table;
class Proxies_priv_table;
@ -685,7 +694,7 @@ static void rebuild_check_host(void);
static void rebuild_role_grants(void);
static ACL_USER *find_user_exact(const char *host, const char *user);
static ACL_USER *find_user_wild(const char *host, const char *user, const char *ip= 0);
static ACL_ROLE *find_acl_role(const char *user);
static ACL_ROLE *find_acl_role(const char *user, bool allow_public);
static ROLE_GRANT_PAIR *find_role_grant_pair(const LEX_CSTRING *u, const LEX_CSTRING *h, const LEX_CSTRING *r);
static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host);
static bool update_user_table_password(THD *, const User_table&, const ACL_USER&);
@ -2196,14 +2205,32 @@ ACL_ROLE::ACL_ROLE(const char * rolename, privilege_t privileges,
flags= IS_ROLE;
}
static bool is_invalid_role_name(const char *str)
enum role_name_check_result
{
if (*str && strcasecmp(str, "PUBLIC") && strcasecmp(str, "NONE"))
return false;
ROLE_NAME_OK= 0,
ROLE_NAME_PUBLIC,
ROLE_NAME_INVALID
};
static role_name_check_result check_role_name(const char *str,
bool public_is_ok)
{
if (*str)
{
if (strcasecmp(str, public_name.str) == 0)
{
if (public_is_ok)
return ROLE_NAME_PUBLIC;
else
goto error;
}
if (strcasecmp(str, "NONE") != 0)
return ROLE_NAME_OK;
}
error:
my_error(ER_INVALID_ROLE, MYF(0), str);
return true;
return ROLE_NAME_INVALID;
}
@ -2632,7 +2659,8 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
if (is_role)
{
if (is_invalid_role_name(username))
role_name_check_result result= check_role_name(username, true);
if (result == ROLE_NAME_INVALID)
{
thd->clear_error(); // the warning is still issued
continue;
@ -2642,6 +2670,9 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
entry->role_grants = user.role_grants;
my_init_dynamic_array(key_memory_acl_mem, &entry->parent_grantee,
sizeof(ACL_USER_BASE *), 0, 8, MYF(0));
if (result == ROLE_NAME_PUBLIC)
acl_public= entry;
my_hash_insert(&acl_roles, (uchar *)entry);
continue;
@ -2697,7 +2728,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
char *db_name;
db.user=safe_str(get_field(&acl_memroot, db_table.user()));
const char *hostname= get_field(&acl_memroot, db_table.host());
if (!hostname && find_acl_role(db.user))
if (!hostname && find_acl_role(db.user, true))
hostname= "";
update_hostname(&db.host, hostname);
db.db= db_name= get_field(&acl_memroot, db_table.db());
@ -2827,6 +2858,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
void acl_free(bool end)
{
my_hash_free(&acl_roles);
acl_public= NULL;
free_root(&acl_memroot,MYF(0));
delete_dynamic(&acl_hosts);
delete_dynamic_with_callback(&acl_users, (FREE_FUNC) free_acl_user);
@ -2871,10 +2903,13 @@ bool acl_reload(THD *thd)
DYNAMIC_ARRAY old_acl_hosts, old_acl_users, old_acl_proxy_users;
Dynamic_array<ACL_DB> old_acl_dbs(PSI_INSTRUMENT_MEM, 0, 0);
HASH old_acl_roles, old_acl_roles_mappings;
ACL_ROLE *old_acl_public;
MEM_ROOT old_mem;
int result;
DBUG_ENTER("acl_reload");
acl_public= NULL;
Grant_tables tables;
/*
To avoid deadlocks we should obtain table locks before
@ -2901,6 +2936,7 @@ bool acl_reload(THD *thd)
old_acl_hosts= acl_hosts;
old_acl_users= acl_users;
old_acl_roles= acl_roles;
old_acl_public= acl_public;
old_acl_roles_mappings= acl_roles_mappings;
old_acl_proxy_users= acl_proxy_users;
old_acl_dbs= acl_dbs;
@ -2925,6 +2961,7 @@ bool acl_reload(THD *thd)
acl_hosts= old_acl_hosts;
acl_users= old_acl_users;
acl_roles= old_acl_roles;
acl_public= old_acl_public;
acl_roles_mappings= old_acl_roles_mappings;
acl_proxy_users= old_acl_proxy_users;
acl_dbs= old_acl_dbs;
@ -3209,7 +3246,7 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host,
}
else // Role, not User
{
ACL_ROLE *acl_role= find_acl_role(user);
ACL_ROLE *acl_role= find_acl_role(user, false);
if (acl_role)
{
res= 0;
@ -3222,6 +3259,14 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host,
}
}
if (acl_public)
{
if (ACL_DB *acl_db= acl_db_find(db, public_name.str, "", "", FALSE))
sctx->db_access|= acl_db->access;
sctx->master_access|= acl_public->access;
}
mysql_mutex_unlock(&acl_cache->lock);
DBUG_RETURN(res);
}
@ -3276,7 +3321,7 @@ static int check_user_can_set_role(THD *thd, const char *user,
goto end;
}
role= find_acl_role(rolename);
role= find_acl_role(rolename, false);
/* According to SQL standard, the same error message must be presented */
if (role == NULL)
@ -3381,20 +3426,22 @@ int acl_setrole(THD *thd, const char *rolename, privilege_t access)
/* merge the privileges */
Security_context *sctx= thd->security_ctx;
sctx->master_access= access;
if (thd->db.str)
sctx->db_access= acl_get(sctx->host, sctx->ip, sctx->user, thd->db.str, FALSE);
if (!strcasecmp(rolename, "NONE"))
{
thd->security_ctx->priv_role[0]= 0;
}
else
{
if (thd->db.str)
sctx->db_access|= acl_get("", "", rolename, thd->db.str, FALSE);
/* mark the current role */
strmake_buf(thd->security_ctx->priv_role, rolename);
}
if (thd->db.str)
sctx->db_access= acl_get_all3(sctx, thd->db.str, FALSE);
// PUBLIC magic
if (acl_public)
sctx->master_access|= acl_public->access;
return 0;
}
@ -3408,9 +3455,13 @@ static uchar* check_get_key(ACL_USER *buff, size_t *length,
static void acl_update_role(const char *rolename, const privilege_t privileges)
{
ACL_ROLE *role= find_acl_role(rolename);
ACL_ROLE *role= find_acl_role(rolename, true);
if (role)
{
role->initial_role_access= role->access= privileges;
if (strcasecmp(rolename, public_name.str) == 0)
acl_public= role;
}
}
@ -3532,6 +3583,8 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
static void acl_insert_role(const char *rolename, privilege_t privileges)
{
ACL_ROLE *entry;
DBUG_ENTER("acl_insert_role");
DBUG_PRINT("enter", ("Role: '%s'", rolename));
mysql_mutex_assert_owner(&acl_cache->lock);
entry= new (&acl_memroot) ACL_ROLE(rolename, privileges, &acl_memroot);
@ -3541,6 +3594,10 @@ static void acl_insert_role(const char *rolename, privilege_t privileges)
sizeof(ACL_ROLE *), 0, 8, MYF(0));
my_hash_insert(&acl_roles, (uchar *)entry);
if (strcasecmp(rolename, public_name.str) == 0)
acl_public= entry;
DBUG_VOID_RETURN;
}
@ -3659,7 +3716,9 @@ privilege_t acl_get(const char *host, const char *ip,
if (acl_db->host.hostname)
goto exit; // Fully specified. Take it
/* the host table is not used for roles */
if ((!host || !host[0]) && !acl_db->host.hostname && find_acl_role(user))
if ((!host || !host[0]) &&
!acl_db->host.hostname &&
find_acl_role(user, false))
goto exit;
}
@ -3699,6 +3758,23 @@ exit:
DBUG_RETURN(db_access & host_access);
}
/*
Check if there is access for the host/user, role, public on the database
*/
privilege_t acl_get_all3(Security_context *sctx, const char *db,
bool db_is_patern)
{
privilege_t access= acl_get(sctx->host, sctx->ip,
sctx->priv_user, db, db_is_patern);
if (sctx->priv_role[0])
access|= acl_get("", "", sctx->priv_role, db, db_is_patern);
if (acl_public)
access|= acl_get("", "", public_name.str, db, db_is_patern);
return access;
}
/*
Check if there are any possible matching entries for this host
@ -3820,7 +3896,7 @@ static bool add_role_user_mapping(const char *uname, const char *hname,
const char *rname)
{
ACL_USER_BASE *grantee= find_acl_user_base(uname, hname);
ACL_ROLE *role= find_acl_role(rname);
ACL_ROLE *role= find_acl_role(rname, false);
if (grantee == NULL || role == NULL)
return 1;
@ -4319,7 +4395,7 @@ bool is_acl_user(const char *host, const char *user)
if (*host) // User
res= find_user_exact(host, user) != NULL;
else // Role
res= find_acl_role(user) != NULL;
res= find_acl_role(user, false) != NULL;
mysql_mutex_unlock(&acl_cache->lock);
return res;
@ -4369,7 +4445,7 @@ static ACL_USER * find_user_wild(const char *host, const char *user, const char
/*
Find a role with the specified name
*/
static ACL_ROLE *find_acl_role(const char *role)
static ACL_ROLE *find_acl_role(const char *role, bool allow_public)
{
size_t length= strlen(role);
DBUG_ENTER("find_acl_role");
@ -4378,7 +4454,9 @@ static ACL_ROLE *find_acl_role(const char *role)
mysql_mutex_assert_owner(&acl_cache->lock);
if (!length)
if (!length || (!allow_public &&
length == public_name.length &&
strcasecmp(role, public_name.str) == 0))
DBUG_RETURN(NULL);
ACL_ROLE *r= (ACL_ROLE *)my_hash_search(&acl_roles, (uchar *)role,
@ -4392,7 +4470,7 @@ static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host)
if (*host)
return find_user_exact(host, user);
return find_acl_role(user);
return find_acl_role(user, true);
}
@ -4608,10 +4686,7 @@ static bool test_if_create_new_users(THD *thd)
NULL, TL_WRITE);
create_new_users= 1;
db_access=acl_get(sctx->host, sctx->ip,
sctx->priv_user, tl.db.str, 0);
if (sctx->priv_role[0])
db_access|= acl_get("", "", sctx->priv_role, tl.db.str, 0);
db_access= acl_get_all3(sctx, tl.db.str, FALSE);
if (!(db_access & INSERT_ACL))
{
if (check_grant(thd, INSERT_ACL, &tl, FALSE, UINT_MAX, TRUE))
@ -4903,7 +4978,7 @@ static int replace_db_table(TABLE *table, const char *db,
if (!find_user_wild(combo.host.str,combo.user.str))
{
/* The user could be a role, check if the user is registered as a role */
if (!combo.host.length && !find_acl_role(combo.user.str))
if (!combo.host.length && !find_acl_role(combo.user.str, true))
{
my_message(ER_PASSWORD_NO_MATCH, ER_THD(table->in_use,
ER_PASSWORD_NO_MATCH), MYF(0));
@ -5415,7 +5490,7 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine)
const char *hostname= get_field(&grant_memroot, form->field[0]);
mysql_mutex_lock(&acl_cache->lock);
if (!hostname && find_acl_role(user))
if (!hostname && find_acl_role(user, true))
hostname= "";
mysql_mutex_unlock(&acl_cache->lock);
update_hostname(&host, hostname);
@ -5874,6 +5949,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
privilege_t store_table_rights(NO_ACL), store_col_rights(NO_ACL);
uchar user_key[MAX_KEY_LENGTH];
DBUG_ENTER("replace_table_table");
DBUG_PRINT("enter", ("User: '%s' Host: '%s' Revoke:'%d'",
(combo.user.length ? combo.user.str : ""),
(combo.host.length ? combo.host.str : ""),
(int) revoke_grant));
get_grantor(thd, grantor);
/*
@ -5882,7 +5961,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
*/
if (!find_user_wild(combo.host.str,combo.user.str))
{
if (!combo.host.length && !find_acl_role(combo.user.str))
if (!combo.host.length && !find_acl_role(combo.user.str, true))
{
my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH),
MYF(0)); /* purecov: deadcode */
@ -7196,8 +7275,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
error= copy_and_check_auth(Str, tmp_Str, thd) ||
replace_user_table(thd, tables.user_table(), Str,
NO_ACL, revoke_grant, create_new_users,
MY_TEST(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER));
MY_TEST(tmp_Str->is_public ||
(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER)));
if (unlikely(error))
{
result= TRUE; // Remember error
@ -7293,7 +7373,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
}
if (Str->is_role())
propagate_role_grants(find_acl_role(Str->user.str),
propagate_role_grants(find_acl_role(Str->user.str, true),
PRIVS_TO_MERGE::TABLE_COLUMN, db_name, table_name);
}
@ -7420,7 +7500,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
continue;
}
if (Str->is_role())
propagate_role_grants(find_acl_role(Str->user.str),
propagate_role_grants(find_acl_role(Str->user.str, true),
sp_privs_to_merge(sph->type()),
db_name, table_name);
}
@ -7558,7 +7638,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
if (!(role= find_acl_role(rolename.str)))
if (!(role= find_acl_role(rolename.str, false)))
{
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
@ -7589,7 +7669,8 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
result= 1;
continue;
}
if (!(role_as_user= find_acl_role(thd->security_ctx->priv_role)))
if (!(role_as_user= find_acl_role(thd->security_ctx->priv_role,
true)))
{
LEX_CSTRING ls= { thd->security_ctx->priv_role,
strlen(thd->security_ctx->priv_role) };
@ -7622,11 +7703,11 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
if (user->host.str)
hostname= user->host;
else
if ((role_as_user= find_acl_role(user->user.str)))
if ((role_as_user= find_acl_role(user->user.str, false)))
hostname= empty_clex_str;
else
{
if (is_invalid_role_name(username.str))
if (check_role_name(username.str, true) == ROLE_NAME_INVALID)
{
append_user(thd, &wrong_users, &username, &empty_clex_str);
result= 1;
@ -7648,19 +7729,31 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
if (!grantee && !revoke)
{
LEX_USER user_combo = *user;
user_combo.host = hostname;
user_combo.user = username;
user_combo.is_public= (user->host.length == 0 &&
// it is also can be that
// hostname.length= 1 && hostname.str[0] == '%'
// if the PUBLIC was absent
username.length == public_name.length &&
(strcasecmp(username.str, public_name.str) == 0));
if (user_combo.is_public)
user_combo.host= hostname= empty_clex_str;
else
user_combo.host = hostname;
if (copy_and_check_auth(&user_combo, &user_combo, thd) ||
replace_user_table(thd, tables.user_table(), &user_combo, NO_ACL,
false, create_new_user,
no_auto_create_user))
(!user_combo.is_public && no_auto_create_user)))
{
append_user(thd, &wrong_users, &username, &hostname);
result= 1;
continue;
}
if (!user_combo.is_public)
grantee= find_user_exact(hostname.str, username.str);
else
grantee= role_as_user= acl_public;
/* either replace_user_table failed, or we've added the user */
DBUG_ASSERT(grantee);
@ -7826,8 +7919,9 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
replace_user_table(thd, tables.user_table(), Str,
(!db ? rights : NO_ACL),
revoke_grant, create_new_users,
MY_TEST(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER)))
MY_TEST(!Str->is_public &&
(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER))))
result= true;
else if (db)
{
@ -7851,7 +7945,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
result= true;
}
if (Str->is_role())
propagate_role_grants(find_acl_role(Str->user.str),
propagate_role_grants(find_acl_role(Str->user.str, true),
db ? PRIVS_TO_MERGE::DB : PRIVS_TO_MERGE::GLOBAL,
db);
}
@ -8218,8 +8312,6 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables,
uint i;
privilege_t original_want_access(want_access);
bool locked= 0;
GRANT_TABLE *grant_table;
GRANT_TABLE *grant_table_role= NULL;
DBUG_ENTER("check_grant");
DBUG_ASSERT(number > 0);
@ -8341,18 +8433,11 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables,
mysql_rwlock_rdlock(&LOCK_grant);
}
grant_table= table_hash_search(sctx->host, sctx->ip,
t_ref->get_db_name(),
sctx->priv_user,
t_ref->get_table_name(),
FALSE);
if (sctx->priv_role[0])
grant_table_role= table_hash_search("", NULL, t_ref->get_db_name(),
sctx->priv_role,
t_ref->get_table_name(),
TRUE);
t_ref->grant.read(sctx, t_ref->get_db_name(), t_ref->get_table_name());
if (!grant_table && !grant_table_role)
if (!t_ref->grant.grant_table_user &&
!t_ref->grant.grant_table_role &&
!t_ref->grant.grant_public)
{
want_access&= ~t_ref->grant.privilege;
goto err; // No grants
@ -8365,18 +8450,13 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables,
if (any_combination_will_do)
continue;
t_ref->grant.grant_table_user= grant_table; // Remember for column test
t_ref->grant.grant_table_role= grant_table_role;
t_ref->grant.version= grant_version;
t_ref->grant.privilege|= grant_table ? grant_table->privs : NO_ACL;
t_ref->grant.privilege|= grant_table_role ? grant_table_role->privs : NO_ACL;
t_ref->grant.privilege|= t_ref->grant.aggregate_privs();
t_ref->grant.want_privilege= ((want_access & COL_ACLS) & ~t_ref->grant.privilege);
if (!(~t_ref->grant.privilege & want_access))
continue;
if ((want_access&= ~((grant_table ? grant_table->cols : NO_ACL) |
(grant_table_role ? grant_table_role->cols : NO_ACL) |
if ((want_access&= ~(t_ref->grant.aggregate_cols() |
t_ref->grant.privilege)))
{
goto err; // impossible
@ -8420,6 +8500,49 @@ static void check_grant_column_int(GRANT_TABLE *grant_table, const char *name,
}
}
inline privilege_t GRANT_INFO::aggregate_privs()
{
return (grant_table_user ? grant_table_user->privs : NO_ACL) |
(grant_table_role ? grant_table_role->privs : NO_ACL) |
(grant_public ? grant_public->privs : NO_ACL);
}
inline privilege_t GRANT_INFO::aggregate_cols()
{
return (grant_table_user ? grant_table_user->cols : NO_ACL) |
(grant_table_role ? grant_table_role->cols : NO_ACL) |
(grant_public ? grant_public->cols : NO_ACL);
}
void GRANT_INFO::refresh(const Security_context *sctx,
const char *db, const char *table)
{
if (version != grant_version)
read(sctx, db, table);
}
void GRANT_INFO::read(const Security_context *sctx,
const char *db, const char *table)
{
#ifdef EMBEDDED_LIBRARY
grant_table_user= grant_table_role= grant_public= NULL;
#else
grant_table_user=
table_hash_search(sctx->host, sctx->ip, db,
sctx->priv_user,
table, FALSE); /* purecov: inspected */
grant_table_role=
sctx->priv_role[0] ? table_hash_search("", NULL, db,
sctx->priv_role,
table, TRUE) : NULL;
grant_public=
acl_public ? table_hash_search("", NULL, db,
public_name.str,
table, TRUE) : NULL;
#endif
version= grant_version; /* purecov: inspected */
}
/*
Check column rights in given security context
@ -8453,24 +8576,14 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
mysql_rwlock_rdlock(&LOCK_grant);
/* reload table if someone has modified any grants */
if (grant->version != grant_version)
{
grant->grant_table_user=
table_hash_search(sctx->host, sctx->ip, db_name,
sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->grant_table_role=
sctx->priv_role[0] ? table_hash_search("", NULL, db_name,
sctx->priv_role,
table_name, TRUE) : NULL;
grant->version= grant_version; /* purecov: inspected */
}
grant->refresh(sctx, db_name, table_name);
check_grant_column_int(grant->grant_table_user, name, (uint)length,
&want_access);
check_grant_column_int(grant->grant_table_role, name, (uint)length,
&want_access);
check_grant_column_int(grant->grant_public, name, (uint)length,
&want_access);
mysql_rwlock_unlock(&LOCK_grant);
if (!want_access)
@ -8586,6 +8699,7 @@ bool check_grant_all_columns(THD *thd, privilege_t want_access_arg,
GRANT_INFO *grant;
GRANT_TABLE *UNINIT_VAR(grant_table);
GRANT_TABLE *UNINIT_VAR(grant_table_role);
GRANT_TABLE *UNINIT_VAR(grant_public);
/*
Flag that gets set if privilege checking has to be performed on column
level.
@ -8611,22 +8725,12 @@ bool check_grant_all_columns(THD *thd, privilege_t want_access_arg,
if (want_access)
{
/* reload table if someone has modified any grants */
if (grant->version != grant_version)
{
grant->grant_table_user=
table_hash_search(sctx->host, sctx->ip, db_name,
sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->grant_table_role=
sctx->priv_role[0] ? table_hash_search("", NULL, db_name,
sctx->priv_role,
table_name, TRUE) : NULL;
grant->version= grant_version; /* purecov: inspected */
}
grant->refresh(sctx, db_name, table_name);
grant_table= grant->grant_table_user;
grant_table_role= grant->grant_table_role;
if (!grant_table && !grant_table_role)
grant_public= grant->grant_public;
if (!grant_table && !grant_table_role && !grant_public)
goto err;
}
}
@ -8649,6 +8753,15 @@ bool check_grant_all_columns(THD *thd, privilege_t want_access_arg,
if (grant_column)
have_access|= grant_column->rights;
}
if (grant_public)
{
GRANT_COLUMN *grant_column=
column_hash_search(grant_public, field_name->str,
field_name->length);
if (grant_column)
have_access|= grant_column->rights;
}
if (have_access)
using_column_privileges= TRUE;
@ -8828,6 +8941,13 @@ bool check_grant_routine(THD *thd, privilege_t want_access,
table->table_name.str, sph, 0)))
table->grant.privilege|= grant_proc->privs;
}
if (acl_public)
{
if ((grant_proc= routine_hash_search("", NULL, table->db.str,
public_name.str,
table->table_name.str, sph, 0)))
table->grant.privilege|= grant_proc->privs;
}
if (want_access & ~table->grant.privilege)
{
@ -8907,27 +9027,10 @@ privilege_t get_table_grant(THD *thd, TABLE_LIST *table)
{
Security_context *sctx= thd->security_ctx;
const char *db = table->db.str ? table->db.str : thd->db.str;
GRANT_TABLE *grant_table;
GRANT_TABLE *grant_table_role= NULL;
mysql_rwlock_rdlock(&LOCK_grant);
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
grant_table_role= NULL;
#else
grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
table->table_name.str, 0);
if (sctx->priv_role[0])
grant_table_role= table_hash_search("", "", db, sctx->priv_role,
table->table_name.str, 0);
#endif
table->grant.grant_table_user= grant_table; // Remember for column test
table->grant.grant_table_role= grant_table_role;
table->grant.version=grant_version;
if (grant_table)
table->grant.privilege|= grant_table->privs;
if (grant_table_role)
table->grant.privilege|= grant_table_role->privs;
table->grant.read(sctx, db, table->table_name.str);
table->grant.privilege|= table->grant.aggregate_privs();
privilege_t privilege(table->grant.privilege);
mysql_rwlock_unlock(&LOCK_grant);
return privilege;
@ -8958,29 +9061,19 @@ privilege_t get_column_grant(THD *thd, GRANT_INFO *grant,
{
GRANT_TABLE *grant_table;
GRANT_TABLE *grant_table_role;
GRANT_TABLE *grant_public;
GRANT_COLUMN *grant_column;
privilege_t priv(NO_ACL);
mysql_rwlock_rdlock(&LOCK_grant);
/* reload table if someone has modified any grants */
if (grant->version != grant_version)
{
Security_context *sctx= thd->security_ctx;
grant->grant_table_user=
table_hash_search(sctx->host, sctx->ip,
db_name, sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->grant_table_role=
sctx->priv_role[0] ? table_hash_search("", "", db_name,
sctx->priv_role,
table_name, TRUE) : NULL;
grant->version= grant_version; /* purecov: inspected */
}
grant->refresh(thd->security_ctx, db_name, table_name);
grant_table= grant->grant_table_user;
grant_table_role= grant->grant_table_role;
grant_public= grant->grant_public;
if (!grant_table && !grant_table_role)
if (!grant_table && !grant_table_role && !grant_public)
priv= grant->privilege;
else
{
@ -9004,6 +9097,16 @@ privilege_t get_column_grant(THD *thd, GRANT_INFO *grant,
priv|= (grant->privilege | grant_table_role->privs |
grant_column->rights);
}
if (grant_public)
{
grant_column= column_hash_search(grant_public, field_name,
(uint) strlen(field_name));
if (!grant_column)
priv|= (grant->privilege | grant_public->privs);
else
priv|= (grant->privilege | grant_public->privs |
grant_column->rights);
}
}
mysql_rwlock_unlock(&LOCK_grant);
return priv;
@ -9479,7 +9582,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
if (rolename)
{
acl_role= find_acl_role(rolename);
acl_role= find_acl_role(rolename, true);
if (acl_role)
{
/* get a list of all inherited roles */
@ -9618,6 +9721,13 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
want_access= ((ACL_ROLE *)acl_entry)->initial_role_access;
else
want_access= acl_entry->access;
// suppress "GRANT USAGE ON *.* TO `PUBLIC`"
if (!(want_access & ~GRANT_ACL) &&
acl_entry->user.length == public_name.length &&
strcasecmp(acl_entry->user.str, public_name.str) == 0)
return FALSE;
if (test_all_bits(want_access, (GLOBAL_ACLS & ~ GRANT_ACL)))
global.append(STRING_WITH_LEN("ALL PRIVILEGES"));
else if (!(want_access & ~GRANT_ACL))
@ -10354,7 +10464,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
if (struct_no == ROLE_ACL) //no need to scan the structures in this case
{
acl_role= find_acl_role(user_from->user.str);
acl_role= find_acl_role(user_from->user.str, true);
if (!acl_role)
DBUG_RETURN(0);
@ -10712,7 +10822,7 @@ static int handle_grant_data(THD *thd, Grant_tables& tables, bool drop,
if (search_only)
{
/* quickly search in-memory structures first */
if (handle_as_role && find_acl_role(user_from->user.str))
if (handle_as_role && find_acl_role(user_from->user.str, true))
DBUG_RETURN(1); // found
if (!handle_as_role && find_user_exact(user_from->host.str, user_from->user.str))
@ -10943,7 +11053,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
continue;
}
if (handle_as_role && is_invalid_role_name(user_name->user.str))
if (handle_as_role &&
(check_role_name(user_name->user.str, false) == ROLE_NAME_INVALID))
{
append_user(thd, &wrong_users, user_name);
result= TRUE;
@ -11011,7 +11122,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
{
ACL_USER_BASE *grantee= find_acl_user_base(thd->lex->definer->user.str,
thd->lex->definer->host.str);
ACL_ROLE *role= find_acl_role(user_name->user.str);
ACL_ROLE *role= find_acl_role(user_name->user.str, false);
/*
just like with routines, views, triggers, and events we allow
@ -11103,10 +11214,15 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
{
int rc;
user_name= get_current_user(thd, tmp_user_name, false);
if (!user_name)
if (!user_name || (handle_as_role &&
(strcasecmp(user_name->user.str,
public_name.str) == 0)))
{
thd->clear_error();
if (!user_name)
append_str(&wrong_users, STRING_WITH_LEN("CURRENT_ROLE"));
else
append_str(&wrong_users, public_name.str, public_name.length);
result= TRUE;
continue;
}
@ -11535,7 +11651,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (lex_user->is_role())
{
/* this can not fail due to get_current_user already having searched for it */
user_or_role= find_acl_role(lex_user->user.str);
user_or_role= find_acl_role(lex_user->user.str, true);
}
else
{
@ -12056,6 +12172,8 @@ static bool set_user_salt_if_needed(ACL_USER *, int, plugin_ref)
{ return 0; }
bool check_grant(THD *, privilege_t, TABLE_LIST *, bool, uint, bool)
{ return 0; }
inline privilege_t public_access()
{ return NO_ACL; }
#endif /*NO_EMBEDDED_ACCESS_CHECKS */
@ -12314,7 +12432,7 @@ bool check_role_is_granted(const char *username,
if (hostname)
root= find_user_exact(hostname, username);
else
root= find_acl_role(username);
root= find_acl_role(username, false);
LEX_CSTRING role_lex;
role_lex.str= rolename;
@ -12342,7 +12460,7 @@ int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond)
{
mysql_rwlock_rdlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
ACL_ROLE *acl_role= find_acl_role(thd->security_ctx->priv_role);
ACL_ROLE *acl_role= find_acl_role(thd->security_ctx->priv_role, false);
if (acl_role)
traverse_role_graph_down(acl_role, table, enabled_roles_insert, NULL);
mysql_mutex_unlock(&acl_cache->lock);
@ -12816,11 +12934,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
if (!thd->db.str || strcmp(db, thd->db.str))
{
/* db privileges */
grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0);
/* db privileges for role */
if (sctx->priv_role[0])
grant->privilege|= acl_get("", "", sctx->priv_role, db, 0);
grant->privilege|= acl_get_all3(sctx, db, FALSE);
}
else
{
@ -12829,18 +12943,8 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
/* table privileges */
mysql_rwlock_rdlock(&LOCK_grant);
if (grant->version != grant_version)
{
grant->grant_table_user=
table_hash_search(sctx->host, sctx->ip, db,
sctx->priv_user,
table, 0); /* purecov: inspected */
grant->grant_table_role=
sctx->priv_role[0] ? table_hash_search("", "", db,
sctx->priv_role,
table, TRUE) : NULL;
grant->version= grant_version; /* purecov: inspected */
}
grant->refresh(sctx, db, table);
if (grant->grant_table_user != 0)
{
grant->privilege|= grant->grant_table_user->privs;
@ -12849,6 +12953,10 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
{
grant->privilege|= grant->grant_table_role->privs;
}
if (grant->grant_public != 0)
{
grant->privilege|= grant->grant_public->privs;
}
mysql_rwlock_unlock(&LOCK_grant);
DBUG_PRINT("info", ("privilege 0x%llx", (longlong) grant->privilege));
@ -12904,12 +13012,16 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock)
return dup;
}
if (is_invalid_role_name(user->user.str))
role_name_check_result result= check_role_name(user->user.str,
user->host.length == 0);
if (result == ROLE_NAME_INVALID)
return 0;
if (result == ROLE_NAME_PUBLIC)
dup->is_public= true;
if (lock)
mysql_mutex_lock(&acl_cache->lock);
if (find_acl_role(dup->user.str))
if (find_acl_role(dup->user.str, false) || dup->is_public)
dup->host= empty_clex_str;
else
dup->host= host_not_specified;
@ -14518,7 +14630,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
}
#endif
sctx->master_access= acl_user->access;
sctx->master_access= (acl_user->access | public_access());
strmake_buf(sctx->priv_user, acl_user->user.str);
if (acl_user->host.hostname)

View File

@ -76,8 +76,8 @@ bool hostname_requires_resolving(const char *hostname);
bool acl_init(bool dont_read_acl_tables);
bool acl_reload(THD *thd);
void acl_free(bool end=0);
privilege_t acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
privilege_t acl_get_all3(Security_context *sctx, const char *db,
bool db_is_patern);
bool acl_authenticate(THD *thd, uint com_change_user_pkt_len);
bool acl_getroot(Security_context *sctx, const char *user, const char *host,
const char *ip, const char *db);

View File

@ -1778,16 +1778,13 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name,
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (test_all_bits(sctx->master_access, DB_ACLS))
{
db_access= DB_ACLS;
}
else
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user,
new_db_file_name.str, FALSE) | sctx->master_access;
if (sctx->priv_role[0])
{
/* include a possible currently set role for access */
db_access|= acl_get("", "", sctx->priv_role, new_db_file_name.str, FALSE);
}
db_access= acl_get_all3(sctx, new_db_file_name.str, FALSE);
db_access|= sctx->master_access;
}
if (!force_switch &&

View File

@ -6760,10 +6760,7 @@ check_access(THD *thd, privilege_t want_access,
{
if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
if (sctx->priv_role[0])
db_access|= acl_get("", "", sctx->priv_role, db, db_is_pattern);
db_access= acl_get_all3(sctx, db, db_is_pattern);
}
else
{
@ -6808,14 +6805,7 @@ check_access(THD *thd, privilege_t want_access,
}
if (db && (!thd->db.str || db_is_pattern || strcmp(db, thd->db.str)))
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
db_is_pattern);
if (sctx->priv_role[0])
{
db_access|= acl_get("", "", sctx->priv_role, db, db_is_pattern);
}
}
db_access= acl_get_all3(sctx, db, db_is_pattern);
else
db_access= sctx->db_access;
DBUG_PRINT("info",("db_access: %llx want_access: %llx",

View File

@ -1406,12 +1406,8 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
{
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname->str, 0) |
db_access= acl_get_all3(sctx, dbname->str, FALSE) |
sctx->master_access;
if (sctx->priv_role[0])
db_access|= acl_get("", "", sctx->priv_role, dbname->str, 0);
}
if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname->str))
{
@ -5302,7 +5298,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
&thd->col_access, NULL, 0, 1) ||
(!thd->col_access && check_grant_db(thd, db_name->str))) ||
sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
acl_get_all3(sctx, db_name->str, 0))
#endif
{
Dynamic_array<LEX_CSTRING*> table_names(PSI_INSTRUMENT_MEM);
@ -5502,9 +5498,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) ||
(sctx->priv_role[0] ?
acl_get("", "", sctx->priv_role, db_name->str, false) : NO_ACL) ||
acl_get_all3(sctx, db_name->str, false) ||
!check_grant_db(thd, db_name->str))
#endif
{

View File

@ -17156,6 +17156,7 @@ grant_role:
$$->user= $1;
$$->host= empty_clex_str;
$$->auth= NULL;
$$->is_public= false;
if (unlikely(check_string_char_length(&$$->user, ER_USERNAME,
username_char_length,

View File

@ -254,6 +254,7 @@ struct AUTHID
struct LEX_USER: public AUTHID
{
USER_AUTH *auth;
bool is_public;
bool has_auth()
{
return auth && (auth->plugin.length || auth->auth_str.length || auth->pwtext.length);

View File

@ -301,6 +301,7 @@ typedef struct st_grant_info
*/
GRANT_TABLE *grant_table_user;
GRANT_TABLE *grant_table_role;
GRANT_TABLE *grant_public;
/**
@brief Used for cache invalidation when caching privilege information.
@ -347,6 +348,14 @@ typedef struct st_grant_info
want_privilege(NO_ACL),
orig_want_privilege(NO_ACL)
{ }
void read(const Security_context *sctx, const char *db,
const char *table);
inline void refresh(const Security_context *sctx, const char *db,
const char *table);
inline privilege_t aggregate_privs();
inline privilege_t aggregate_cols();
} GRANT_INFO;
enum tmp_table_type