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:
committed by
Sergei Golubchik
parent
594bed9b42
commit
b0325bd6d6
138
mysql-test/main/public_basic.result
Normal file
138
mysql-test/main/public_basic.result
Normal 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;
|
130
mysql-test/main/public_basic.test
Normal file
130
mysql-test/main/public_basic.test
Normal 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;
|
346
mysql-test/main/public_privileges.result
Normal file
346
mysql-test/main/public_privileges.result
Normal 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;
|
411
mysql-test/main/public_privileges.test
Normal file
411
mysql-test/main/public_privileges.test
Normal 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;
|
@ -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='';
|
||||
|
@ -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='';
|
||||
|
414
sql/sql_acl.cc
414
sql/sql_acl.cc
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 &&
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user