support DEFINER=role and DEFINER=current_role
This commit is contained in:
parent
b054700619
commit
b2f16628cf
@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
C_MODE_START
|
C_MODE_START
|
||||||
|
|
||||||
void parse_user(const char *user_id_str, size_t user_id_len,
|
int parse_user(const char *user_id_str, size_t user_id_len,
|
||||||
char *user_name_str, size_t *user_name_len,
|
char *user_name_str, size_t *user_name_len,
|
||||||
char *host_name_str, size_t *host_name_len);
|
char *host_name_str, size_t *host_name_len);
|
||||||
|
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
|
||||||
|
625
mysql-test/r/acl_roles_definer.result
Normal file
625
mysql-test/r/acl_roles_definer.result
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
create database mysqltest1;
|
||||||
|
use mysqltest1;
|
||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
insert t1 values (1,10,100),(2,20,200);
|
||||||
|
create role role1;
|
||||||
|
grant select (a) on mysqltest1.t1 to role1;
|
||||||
|
grant event,execute,trigger on mysqltest1.* to role1;
|
||||||
|
grant role1 to current_user;
|
||||||
|
create role role2;
|
||||||
|
grant insert,select on mysqltest1.t1 to role2;
|
||||||
|
grant event,execute,trigger on mysqltest1.* to role2;
|
||||||
|
grant create view on mysqltest1.* to foo@localhost;
|
||||||
|
create role role4;
|
||||||
|
grant select on mysqltest1.t1 to role4;
|
||||||
|
grant role4 to foo@localhost;
|
||||||
|
create definer=current_role view test.v1 as select a+b,c from t1;
|
||||||
|
ERROR 0L000: Invalid definer
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role view test.v1 as select a+b,c from t1;
|
||||||
|
show create view test.v1;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`role1` SQL SECURITY DEFINER VIEW `test`.`v1` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
set role none;
|
||||||
|
create definer=role2 view test.v2 as select a+b,c from t1;
|
||||||
|
show create view test.v2;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`role2` SQL SECURITY DEFINER VIEW `test`.`v2` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
create definer=role3 view test.v3 as select a+b,c from t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show create view test.v3;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`role3`@`%` SQL SECURITY DEFINER VIEW `test`.`v3` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show grants;
|
||||||
|
Grants for foo@localhost
|
||||||
|
GRANT role4 TO 'foo'@'localhost'
|
||||||
|
GRANT USAGE ON *.* TO 'foo'@'localhost'
|
||||||
|
GRANT CREATE VIEW ON `mysqltest1`.* TO 'foo'@'localhost'
|
||||||
|
select * from test.v1;
|
||||||
|
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||||
|
select * from test.v2;
|
||||||
|
a+b c
|
||||||
|
11 100
|
||||||
|
22 200
|
||||||
|
select * from test.v3;
|
||||||
|
ERROR 28000: Access denied for user 'foo'@'localhost' (using password: NO)
|
||||||
|
create definer=role4 view test.v4 as select a+b,c from t1;
|
||||||
|
ERROR 42000: ANY command denied to user 'foo'@'localhost' for table 't1'
|
||||||
|
select * from t1;
|
||||||
|
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
|
||||||
|
set role role4;
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
create view test.v4 as select a+b,c from t1;
|
||||||
|
create definer=role4 view test.v5 as select a+b,c from t1;
|
||||||
|
select * from test.v4;
|
||||||
|
ERROR HY000: View 'test.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||||
|
select * from test.v5;
|
||||||
|
a+b c
|
||||||
|
11 100
|
||||||
|
22 200
|
||||||
|
set role none;
|
||||||
|
select * from test.v4;
|
||||||
|
ERROR HY000: View 'test.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||||
|
select * from test.v5;
|
||||||
|
a+b c
|
||||||
|
11 100
|
||||||
|
22 200
|
||||||
|
drop role role4;
|
||||||
|
show create view test.v5;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4` SQL SECURITY DEFINER VIEW `test`.`v5` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role4'@'') does not exist
|
||||||
|
select * from test.v5;
|
||||||
|
ERROR HY000: The user specified as a definer ('role4'@'') does not exist
|
||||||
|
grant select on mysqltest1.t1 to role4;
|
||||||
|
show create view test.v5;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4` SQL SECURITY DEFINER VIEW `test`.`v5` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role4'@'') does not exist
|
||||||
|
select * from test.v5;
|
||||||
|
ERROR HY000: The user specified as a definer ('role4'@'') does not exist
|
||||||
|
show create view test.v5;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4`@`%` SQL SECURITY DEFINER VIEW `test`.`v5` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||||
|
select * from test.v5;
|
||||||
|
a+b c
|
||||||
|
11 100
|
||||||
|
22 200
|
||||||
|
drop user role4;
|
||||||
|
create table t2 select * from t1;
|
||||||
|
create definer=current_role trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
ERROR 0L000: Invalid definer
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
show create trigger tr1;
|
||||||
|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
|
||||||
|
tr1 CREATE DEFINER=`role1` trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
set role none;
|
||||||
|
insert t2 values (11,22,33);
|
||||||
|
ERROR 42000: INSERT command denied to user 'role1'@'' for table 't1'
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
select * from t2;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
create definer=role2 trigger tr2 before delete on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
show create trigger tr2;
|
||||||
|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
|
||||||
|
tr2 CREATE DEFINER=`role2` trigger tr2 before delete on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
delete from t2 where a=1;
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
111 222 333
|
||||||
|
select * from t2;
|
||||||
|
a b c
|
||||||
|
2 20 200
|
||||||
|
delete from t1 where a=111;
|
||||||
|
create definer=role3 trigger tr3 before update on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show create trigger tr3;
|
||||||
|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
|
||||||
|
tr3 CREATE DEFINER=`role3`@`%` trigger tr3 before update on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
update t2 set b=2 where a=2;
|
||||||
|
ERROR HY000: The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
select * from t2;
|
||||||
|
a b c
|
||||||
|
2 20 200
|
||||||
|
flush tables;
|
||||||
|
show create trigger tr2;
|
||||||
|
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
|
||||||
|
tr2 CREATE DEFINER=`role2`@`` trigger tr2 before delete on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
delete from t2 where a=2;
|
||||||
|
ERROR HY000: The user specified as a definer ('role2'@'%') does not exist
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
select * from t2;
|
||||||
|
a b c
|
||||||
|
2 20 200
|
||||||
|
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
|
||||||
|
ERROR 0L000: Invalid definer
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
|
||||||
|
show create procedure pr1;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pr1 CREATE DEFINER=`role1` PROCEDURE `pr1`()
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
set role none;
|
||||||
|
call pr1();
|
||||||
|
ERROR 42000: INSERT command denied to user 'role1'@'' for table 't1'
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
create definer=role2 procedure pr2() insert t1 values (111, 222, 333);
|
||||||
|
show create procedure pr2;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pr2 CREATE DEFINER=`role2` PROCEDURE `pr2`()
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
call pr2();
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
111 222 333
|
||||||
|
delete from t1 where a=111;
|
||||||
|
create definer=role3 procedure pr3() insert t1 values (111, 222, 333);
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show create procedure pr3;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pr3 CREATE DEFINER=`role3`@`%` PROCEDURE `pr3`()
|
||||||
|
insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
call pr3();
|
||||||
|
ERROR HY000: The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
update mysql.proc set definer='role2@' where definer='role2';
|
||||||
|
call pr2();
|
||||||
|
ERROR HY000: The user specified as a definer ('role2'@'%') does not exist
|
||||||
|
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
|
||||||
|
ERROR 0L000: Invalid definer
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
|
||||||
|
show create function fn1;
|
||||||
|
Function sql_mode Create Function character_set_client collation_connection Database Collation
|
||||||
|
fn1 CREATE DEFINER=`role1` FUNCTION `fn1`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
set role none;
|
||||||
|
select fn1();
|
||||||
|
ERROR 42000: SELECT command denied to user 'role1'@'' for column 'b' in table 't1'
|
||||||
|
select * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
2 20 200
|
||||||
|
create definer=role2 function fn2() returns int return (select sum(a+b) from t1);
|
||||||
|
show create function fn2;
|
||||||
|
Function sql_mode Create Function character_set_client collation_connection Database Collation
|
||||||
|
fn2 CREATE DEFINER=`role2` FUNCTION `fn2`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
select fn2();
|
||||||
|
fn2()
|
||||||
|
33
|
||||||
|
create definer=role3 function fn3() returns int return (select sum(a+b) from t1);
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show create function fn3;
|
||||||
|
Function sql_mode Create Function character_set_client collation_connection Database Collation
|
||||||
|
fn3 CREATE DEFINER=`role3`@`%` FUNCTION `fn3`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
select fn3();
|
||||||
|
ERROR HY000: The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
set global event_scheduler=on;
|
||||||
|
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 1, 0);
|
||||||
|
ERROR 0L000: Invalid definer
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 2, 0);
|
||||||
|
show create event e1;
|
||||||
|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
|
||||||
|
e1 SYSTEM CREATE DEFINER=`role1` EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 2, 0) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
set role none;
|
||||||
|
create definer=role3 event e3 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 3, 0);
|
||||||
|
Warnings:
|
||||||
|
Note 1449 The user specified as a definer ('role3'@'%') does not exist
|
||||||
|
show create event e3;
|
||||||
|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
|
||||||
|
e3 SYSTEM CREATE DEFINER=`role3`@`%` EVENT `e3` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 3, 0) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
create definer=role2 event e2 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 4, 0);
|
||||||
|
show create event e2;
|
||||||
|
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
|
||||||
|
e2 SYSTEM CREATE DEFINER=`role2` EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 4, 0) latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
set global event_scheduler=off;
|
||||||
|
select distinct * from t1;
|
||||||
|
a b c
|
||||||
|
1 10 100
|
||||||
|
111 4 0
|
||||||
|
2 20 200
|
||||||
|
delete from t1 where a=111;
|
||||||
|
|
||||||
|
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||||
|
|
||||||
|
USE `test`;
|
||||||
|
SET @saved_cs_client = @@character_set_client;
|
||||||
|
SET character_set_client = utf8;
|
||||||
|
/*!50001 CREATE TABLE `v1` (
|
||||||
|
`a+b` tinyint NOT NULL,
|
||||||
|
`c` tinyint NOT NULL
|
||||||
|
) ENGINE=MyISAM */;
|
||||||
|
SET character_set_client = @saved_cs_client;
|
||||||
|
SET @saved_cs_client = @@character_set_client;
|
||||||
|
SET character_set_client = utf8;
|
||||||
|
/*!50001 CREATE TABLE `v2` (
|
||||||
|
`a+b` tinyint NOT NULL,
|
||||||
|
`c` tinyint NOT NULL
|
||||||
|
) ENGINE=MyISAM */;
|
||||||
|
SET character_set_client = @saved_cs_client;
|
||||||
|
SET @saved_cs_client = @@character_set_client;
|
||||||
|
SET character_set_client = utf8;
|
||||||
|
/*!50001 CREATE TABLE `v3` (
|
||||||
|
`a+b` tinyint NOT NULL,
|
||||||
|
`c` tinyint NOT NULL
|
||||||
|
) ENGINE=MyISAM */;
|
||||||
|
SET character_set_client = @saved_cs_client;
|
||||||
|
SET @saved_cs_client = @@character_set_client;
|
||||||
|
SET character_set_client = utf8;
|
||||||
|
/*!50001 CREATE TABLE `v4` (
|
||||||
|
`a+b` tinyint NOT NULL,
|
||||||
|
`c` tinyint NOT NULL
|
||||||
|
) ENGINE=MyISAM */;
|
||||||
|
SET character_set_client = @saved_cs_client;
|
||||||
|
SET @saved_cs_client = @@character_set_client;
|
||||||
|
SET character_set_client = utf8;
|
||||||
|
/*!50001 CREATE TABLE `v5` (
|
||||||
|
`a+b` tinyint NOT NULL,
|
||||||
|
`c` tinyint NOT NULL
|
||||||
|
) ENGINE=MyISAM */;
|
||||||
|
SET character_set_client = @saved_cs_client;
|
||||||
|
|
||||||
|
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||||
|
|
||||||
|
USE `mysqltest1`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL,
|
||||||
|
`c` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
INSERT INTO `t1` VALUES (1,10,100),(2,20,200);
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `t2` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL,
|
||||||
|
`c` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
INSERT INTO `t2` VALUES (2,20,200);
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 CREATE*/ /*!50017 DEFINER=`role1`*/ /*!50003 trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) */;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 CREATE*/ /*!50017 DEFINER=`role3`@`%`*/ /*!50003 trigger tr3 before update on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) */;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 CREATE*/ /*!50017 DEFINER=`role2`@``*/ /*!50003 trigger tr2 before delete on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333) */;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;;
|
||||||
|
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
|
||||||
|
/*!50003 SET time_zone = 'SYSTEM' */ ;;
|
||||||
|
/*!50106 CREATE*/ /*!50117 DEFINER=`role1`*/ /*!50106 EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 2, 0) */ ;;
|
||||||
|
/*!50003 SET time_zone = @saved_time_zone */ ;;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;;
|
||||||
|
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
|
||||||
|
/*!50003 SET time_zone = 'SYSTEM' */ ;;
|
||||||
|
/*!50106 CREATE*/ /*!50117 DEFINER=`role2`*/ /*!50106 EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 4, 0) */ ;;
|
||||||
|
/*!50003 SET time_zone = @saved_time_zone */ ;;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;;
|
||||||
|
DELIMITER ;;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;;
|
||||||
|
/*!50003 SET @saved_time_zone = @@time_zone */ ;;
|
||||||
|
/*!50003 SET time_zone = 'SYSTEM' */ ;;
|
||||||
|
/*!50106 CREATE*/ /*!50117 DEFINER=`role3`@`%`*/ /*!50106 EVENT `e3` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 3, 0) */ ;;
|
||||||
|
/*!50003 SET time_zone = @saved_time_zone */ ;;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role1` FUNCTION `fn1`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role2` FUNCTION `fn2`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role3`@`%` FUNCTION `fn3`() RETURNS int(11)
|
||||||
|
return (select sum(a+b) from t1) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role1` PROCEDURE `pr1`()
|
||||||
|
insert t1 values (111, 222, 333) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role2`@`%` PROCEDURE `pr2`()
|
||||||
|
insert t1 values (111, 222, 333) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||||
|
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||||
|
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||||
|
/*!50003 SET character_set_client = latin1 */ ;
|
||||||
|
/*!50003 SET character_set_results = latin1 */ ;
|
||||||
|
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
|
||||||
|
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||||
|
/*!50003 SET sql_mode = '' */ ;
|
||||||
|
DELIMITER ;;
|
||||||
|
CREATE DEFINER=`role3`@`%` PROCEDURE `pr3`()
|
||||||
|
insert t1 values (111, 222, 333) ;;
|
||||||
|
DELIMITER ;
|
||||||
|
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||||
|
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||||
|
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||||
|
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||||
|
|
||||||
|
USE `test`;
|
||||||
|
/*!50001 DROP TABLE IF EXISTS `v1`*/;
|
||||||
|
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||||
|
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||||
|
/*!50001 SET character_set_client = latin1 */;
|
||||||
|
/*!50001 SET character_set_results = latin1 */;
|
||||||
|
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||||
|
/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`role1` SQL SECURITY DEFINER VIEW `v1` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */;
|
||||||
|
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||||
|
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||||
|
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||||
|
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||||
|
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||||
|
/*!50001 SET character_set_client = latin1 */;
|
||||||
|
/*!50001 SET character_set_results = latin1 */;
|
||||||
|
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||||
|
/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`role2` SQL SECURITY DEFINER VIEW `v2` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */;
|
||||||
|
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||||
|
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||||
|
/*!50001 DROP TABLE IF EXISTS `v3`*/;
|
||||||
|
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||||
|
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||||
|
/*!50001 SET character_set_client = latin1 */;
|
||||||
|
/*!50001 SET character_set_results = latin1 */;
|
||||||
|
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||||
|
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||||
|
/*!50013 DEFINER=`role3`@`%` SQL SECURITY DEFINER */
|
||||||
|
/*!50001 VIEW `v3` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */;
|
||||||
|
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||||
|
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||||
|
/*!50001 DROP TABLE IF EXISTS `v4`*/;
|
||||||
|
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||||
|
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||||
|
/*!50001 SET character_set_client = latin1 */;
|
||||||
|
/*!50001 SET character_set_results = latin1 */;
|
||||||
|
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||||
|
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||||
|
/*!50013 DEFINER=`foo`@`localhost` SQL SECURITY DEFINER */
|
||||||
|
/*!50001 VIEW `v4` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */;
|
||||||
|
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||||
|
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||||
|
/*!50001 DROP TABLE IF EXISTS `v5`*/;
|
||||||
|
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||||
|
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||||
|
/*!50001 SET character_set_client = latin1 */;
|
||||||
|
/*!50001 SET character_set_results = latin1 */;
|
||||||
|
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||||
|
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||||
|
/*!50013 DEFINER=`role4`@`%` SQL SECURITY DEFINER */
|
||||||
|
/*!50001 VIEW `v5` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */;
|
||||||
|
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||||
|
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||||
|
|
||||||
|
USE `mysqltest1`;
|
||||||
|
drop trigger tr1;
|
||||||
|
drop trigger tr2;
|
||||||
|
drop trigger tr3;
|
||||||
|
drop procedure pr1;
|
||||||
|
drop procedure pr2;
|
||||||
|
drop procedure pr3;
|
||||||
|
drop function fn1;
|
||||||
|
drop function fn2;
|
||||||
|
drop function fn3;
|
||||||
|
drop event e1;
|
||||||
|
drop event e2;
|
||||||
|
drop event e3;
|
||||||
|
drop view test.v1, test.v2, test.v3, test.v4, test.v5;
|
||||||
|
drop table t1, t2;
|
||||||
|
drop role role1, role2;
|
||||||
|
drop user foo@localhost;
|
||||||
|
drop database mysqltest1;
|
||||||
|
use test;
|
||||||
|
create user utest;
|
||||||
|
prepare stmt1 from 'grant select on *.* to utest';
|
||||||
|
execute stmt1;
|
||||||
|
show grants for utest;
|
||||||
|
Grants for utest@%
|
||||||
|
GRANT SELECT ON *.* TO 'utest'@'%'
|
||||||
|
drop user utest;
|
||||||
|
create role utest;
|
||||||
|
execute stmt1;
|
||||||
|
show grants for utest;
|
||||||
|
Grants for utest
|
||||||
|
GRANT SELECT ON *.* TO 'utest'
|
||||||
|
drop role utest;
|
@ -1,11 +1,9 @@
|
|||||||
create user 'test_user'@'localhost';
|
create user test_user@localhost;
|
||||||
create user 'test_role1'@'';
|
create role test_role1;
|
||||||
update mysql.user set is_role='Y' where user='test_role1';
|
|
||||||
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('localhost',
|
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('localhost',
|
||||||
'test_user',
|
'test_user',
|
||||||
'test_role1');
|
'test_role1');
|
||||||
create user 'test_role2'@'';
|
create role test_role2;
|
||||||
update mysql.user set is_role='Y' where user='test_role2';
|
|
||||||
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('',
|
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('',
|
||||||
'test_role1',
|
'test_role1',
|
||||||
'test_role2');
|
'test_role2');
|
||||||
@ -25,26 +23,6 @@ select * from roles_mapping;
|
|||||||
HostFk UserFk RoleFk
|
HostFk UserFk RoleFk
|
||||||
test_role1 test_role2
|
test_role1 test_role2
|
||||||
newhost test_user_rm test_role1
|
newhost test_user_rm test_role1
|
||||||
rename user 'test_role2'@'' to 'test_role2_rm'@'';
|
|
||||||
select user, host from user where user like 'test%';
|
|
||||||
user host
|
|
||||||
test_role1
|
|
||||||
test_role2_rm
|
|
||||||
test_user_rm newhost
|
|
||||||
select * from roles_mapping;
|
|
||||||
HostFk UserFk RoleFk
|
|
||||||
test_role1 test_role2_rm
|
|
||||||
newhost test_user_rm test_role1
|
|
||||||
rename user 'test_role1'@'' to 'test_role1_rm'@'';
|
|
||||||
select user, host from user where user like 'test%';
|
|
||||||
user host
|
|
||||||
test_role1_rm
|
|
||||||
test_role2_rm
|
|
||||||
test_user_rm newhost
|
|
||||||
select * from roles_mapping;
|
|
||||||
HostFk UserFk RoleFk
|
|
||||||
test_role1_rm test_role2_rm
|
|
||||||
newhost test_user_rm test_role1_rm
|
|
||||||
delete from mysql.roles_mapping;
|
delete from mysql.roles_mapping;
|
||||||
delete from mysql.user where user like 'test%';
|
delete from mysql.user where user like 'test%';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
49
mysql-test/r/acl_roles_rpl_definer.result
Normal file
49
mysql-test/r/acl_roles_rpl_definer.result
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
create role role1;
|
||||||
|
grant execute on test.* to role1;
|
||||||
|
grant role1 to current_user;
|
||||||
|
set role role1;
|
||||||
|
create definer=current_user procedure pcu() select current_user;
|
||||||
|
create definer=root@localhost procedure pu() select "root@localhost";
|
||||||
|
create definer=current_role procedure pcr() select current_role;
|
||||||
|
create definer=role1 procedure pr() select "role1";
|
||||||
|
show create procedure pcu;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pcu CREATE DEFINER=`root`@`localhost` PROCEDURE `pcu`()
|
||||||
|
select current_user latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pu;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pu CREATE DEFINER=`root`@`localhost` PROCEDURE `pu`()
|
||||||
|
select "root@localhost" latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pcr;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pcr CREATE DEFINER=`role1` PROCEDURE `pcr`()
|
||||||
|
select current_role latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pr;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pr CREATE DEFINER=`role1` PROCEDURE `pr`()
|
||||||
|
select "role1" latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
[connection slave]
|
||||||
|
show create procedure pcu;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pcu CREATE DEFINER=`root`@`localhost` PROCEDURE `pcu`()
|
||||||
|
select current_user latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pu;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pu CREATE DEFINER=`root`@`localhost` PROCEDURE `pu`()
|
||||||
|
select "root@localhost" latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pcr;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pcr CREATE DEFINER=`role1` PROCEDURE `pcr`()
|
||||||
|
select current_role latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
show create procedure pr;
|
||||||
|
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
|
||||||
|
pr CREATE DEFINER=`role1` PROCEDURE `pr`()
|
||||||
|
select "role1" latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
drop procedure pcu;
|
||||||
|
drop procedure pu;
|
||||||
|
drop procedure pcr;
|
||||||
|
drop procedure pr;
|
||||||
|
drop role role1;
|
||||||
|
include/rpl_end.inc
|
@ -27,8 +27,7 @@ Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv D
|
|||||||
% test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 Y
|
% test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 Y
|
||||||
select * from mysql.user where user like 'test_role2';
|
select * from mysql.user where user like 'test_role2';
|
||||||
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string is_role
|
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string is_role
|
||||||
test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 Y
|
% test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 Y
|
||||||
% test_role2 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 Y
|
|
||||||
flush privileges;
|
flush privileges;
|
||||||
select * from mysql.roles_mapping;
|
select * from mysql.roles_mapping;
|
||||||
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
|
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
|
||||||
|
@ -162,7 +162,7 @@ SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_n
|
|||||||
trigger_name definer
|
trigger_name definer
|
||||||
trg1
|
trg1
|
||||||
trg2 @
|
trg2 @
|
||||||
trg3 @abc@def@@
|
trg3 @abc@def@@%
|
||||||
trg4 @hostname
|
trg4 @hostname
|
||||||
trg5 @abcdef@@@hostname
|
trg5 @abcdef@@@hostname
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
|
|||||||
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
|
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
|
||||||
def mysqltest_db1 trg1 INSERT def mysqltest_db1 t1 0 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW NULL latin1 latin1_swedish_ci latin1_swedish_ci
|
def mysqltest_db1 trg1 INSERT def mysqltest_db1 t1 0 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW NULL latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
def mysqltest_db1 trg2 INSERT def mysqltest_db1 t1 0 NULL SET @a = 2 ROW AFTER NULL NULL OLD NEW NULL @ latin1 latin1_swedish_ci latin1_swedish_ci
|
def mysqltest_db1 trg2 INSERT def mysqltest_db1 t1 0 NULL SET @a = 2 ROW AFTER NULL NULL OLD NEW NULL @ latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
def mysqltest_db1 trg3 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 3 ROW BEFORE NULL NULL OLD NEW NULL @abc@def@@ latin1 latin1_swedish_ci latin1_swedish_ci
|
def mysqltest_db1 trg3 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 3 ROW BEFORE NULL NULL OLD NEW NULL @abc@def@@% latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
def mysqltest_db1 trg4 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 4 ROW AFTER NULL NULL OLD NEW NULL @hostname latin1 latin1_swedish_ci latin1_swedish_ci
|
def mysqltest_db1 trg4 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 4 ROW AFTER NULL NULL OLD NEW NULL @hostname latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
def mysqltest_db1 trg5 DELETE def mysqltest_db1 t1 0 NULL SET @a = 5 ROW BEFORE NULL NULL OLD NEW NULL @abcdef@@@hostname latin1 latin1_swedish_ci latin1_swedish_ci
|
def mysqltest_db1 trg5 DELETE def mysqltest_db1 t1 0 NULL SET @a = 5 ROW BEFORE NULL NULL OLD NEW NULL @abcdef@@@hostname latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
|
|
||||||
|
330
mysql-test/t/acl_roles_definer.test
Normal file
330
mysql-test/t/acl_roles_definer.test
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
# create view
|
||||||
|
# create trigger
|
||||||
|
# create procedure
|
||||||
|
# create event
|
||||||
|
# mysqldump dumping the definer
|
||||||
|
|
||||||
|
let MYSQLD_DATADIR=`select @@datadir`;
|
||||||
|
|
||||||
|
create database mysqltest1;
|
||||||
|
use mysqltest1;
|
||||||
|
|
||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
insert t1 values (1,10,100),(2,20,200);
|
||||||
|
|
||||||
|
# non-priv role granted
|
||||||
|
create role role1;
|
||||||
|
grant select (a) on mysqltest1.t1 to role1;
|
||||||
|
grant event,execute,trigger on mysqltest1.* to role1;
|
||||||
|
|
||||||
|
grant role1 to current_user;
|
||||||
|
|
||||||
|
# priv role
|
||||||
|
create role role2;
|
||||||
|
grant insert,select on mysqltest1.t1 to role2;
|
||||||
|
grant event,execute,trigger on mysqltest1.* to role2;
|
||||||
|
|
||||||
|
# create a non-priv user and a priv role granted to him
|
||||||
|
grant create view on mysqltest1.* to foo@localhost;
|
||||||
|
create role role4;
|
||||||
|
grant select on mysqltest1.t1 to role4;
|
||||||
|
grant role4 to foo@localhost;
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# views
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# no curent role = error
|
||||||
|
--error ER_MALFORMED_DEFINER
|
||||||
|
create definer=current_role view test.v1 as select a+b,c from t1;
|
||||||
|
|
||||||
|
# definer=current_role, but it has doesn't have enough privileges
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role view test.v1 as select a+b,c from t1;
|
||||||
|
show create view test.v1;
|
||||||
|
set role none;
|
||||||
|
|
||||||
|
# definer=role_name, privileges ok
|
||||||
|
create definer=role2 view test.v2 as select a+b,c from t1;
|
||||||
|
show create view test.v2;
|
||||||
|
|
||||||
|
# definer=non_existent_role
|
||||||
|
create definer=role3 view test.v3 as select a+b,c from t1;
|
||||||
|
show create view test.v3;
|
||||||
|
|
||||||
|
connect (c1, localhost, foo,,mysqltest1);
|
||||||
|
connection c1;
|
||||||
|
show grants;
|
||||||
|
|
||||||
|
# role1 doesn't have enough privileges for v1 to work
|
||||||
|
--error ER_VIEW_INVALID
|
||||||
|
select * from test.v1;
|
||||||
|
|
||||||
|
# role2 is ok, v2 is ok
|
||||||
|
select * from test.v2;
|
||||||
|
|
||||||
|
# role3 is treated as a user name role3@%, doesn't exist, v3 fails
|
||||||
|
--error ER_ACCESS_DENIED_ERROR
|
||||||
|
select * from test.v3;
|
||||||
|
|
||||||
|
# fails, no SUPER - cannot specify a definer arbitrarily
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
create definer=role4 view test.v4 as select a+b,c from t1;
|
||||||
|
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
select * from t1;
|
||||||
|
set role role4;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
# can select from t1, but the view won't work, by default definer=current_user
|
||||||
|
create view test.v4 as select a+b,c from t1;
|
||||||
|
|
||||||
|
# now role4 is the current_role, can be specified as a definer
|
||||||
|
create definer=role4 view test.v5 as select a+b,c from t1;
|
||||||
|
|
||||||
|
--error ER_VIEW_INVALID
|
||||||
|
select * from test.v4;
|
||||||
|
select * from test.v5;
|
||||||
|
set role none;
|
||||||
|
--error ER_VIEW_INVALID
|
||||||
|
select * from test.v4;
|
||||||
|
select * from test.v5;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
drop role role4;
|
||||||
|
|
||||||
|
show create view test.v5;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
select * from test.v5;
|
||||||
|
|
||||||
|
grant select on mysqltest1.t1 to role4;
|
||||||
|
show create view test.v5;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
select * from test.v5;
|
||||||
|
|
||||||
|
# pretend it's an old view from before 10.0.5
|
||||||
|
perl;
|
||||||
|
local $/;
|
||||||
|
my $f= "$ENV{MYSQLD_DATADIR}/test/v5.frm";
|
||||||
|
open(F, '<', $f) or die "open(<$f): $!";
|
||||||
|
$_=<F>;
|
||||||
|
s/create-version=2/create-version=1/;
|
||||||
|
open(F, '>', $f) or die "open(>$f): $!";
|
||||||
|
syswrite F, $_ or die "syswrite($f): $!"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
show create view test.v5;
|
||||||
|
select * from test.v5;
|
||||||
|
drop user role4;
|
||||||
|
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# trigger
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
create table t2 select * from t1;
|
||||||
|
|
||||||
|
# no curent role = error
|
||||||
|
--error ER_MALFORMED_DEFINER
|
||||||
|
create definer=current_role trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
|
||||||
|
# definer=current_role, but it has doesn't have enough privileges
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role trigger tr1 before insert on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
show create trigger tr1;
|
||||||
|
set role none;
|
||||||
|
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
insert t2 values (11,22,33);
|
||||||
|
select * from t1;
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
# definer=role_name, privileges ok
|
||||||
|
create definer=role2 trigger tr2 before delete on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
show create trigger tr2;
|
||||||
|
delete from t2 where a=1;
|
||||||
|
select * from t1;
|
||||||
|
select * from t2;
|
||||||
|
delete from t1 where a=111;
|
||||||
|
|
||||||
|
# definer=non_existent_role
|
||||||
|
create definer=role3 trigger tr3 before update on t2 for each row
|
||||||
|
insert t1 values (111, 222, 333);
|
||||||
|
show create trigger tr3;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
update t2 set b=2 where a=2;
|
||||||
|
select * from t1;
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
flush tables;
|
||||||
|
|
||||||
|
# change triggers to use pre-10.0.5 definer with an empty hostname
|
||||||
|
perl;
|
||||||
|
local $/;
|
||||||
|
my $f= "$ENV{MYSQLD_DATADIR}/mysqltest1/t2.TRG";
|
||||||
|
open(F, '<', $f) or die "open(<$f): $!";
|
||||||
|
$_=<F>;
|
||||||
|
s/'role2'/'role2\@'/;
|
||||||
|
s/`role2`/$&\@``/;
|
||||||
|
open(F, '>', $f) or die "open(>$f): $!";
|
||||||
|
syswrite F, $_ or die "syswrite($f): $!"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
show create trigger tr2;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
delete from t2 where a=2;
|
||||||
|
select * from t1;
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# stored procedures
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# no curent role = error
|
||||||
|
--error ER_MALFORMED_DEFINER
|
||||||
|
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
|
||||||
|
|
||||||
|
# definer=current_role, but it has doesn't have enough privileges
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
|
||||||
|
show create procedure pr1;
|
||||||
|
set role none;
|
||||||
|
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
call pr1();
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
# definer=role_name, privileges ok
|
||||||
|
create definer=role2 procedure pr2() insert t1 values (111, 222, 333);
|
||||||
|
show create procedure pr2;
|
||||||
|
call pr2();
|
||||||
|
select * from t1;
|
||||||
|
delete from t1 where a=111;
|
||||||
|
|
||||||
|
# definer=non_existent_role
|
||||||
|
create definer=role3 procedure pr3() insert t1 values (111, 222, 333);
|
||||||
|
show create procedure pr3;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
call pr3();
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
# change a procedure to use pre-10.0.5 definer with an empty hostname
|
||||||
|
update mysql.proc set definer='role2@' where definer='role2';
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
call pr2();
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# stored functions
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# no curent role = error
|
||||||
|
--error ER_MALFORMED_DEFINER
|
||||||
|
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
|
||||||
|
|
||||||
|
# definer=current_role, but it has doesn't have enough privileges
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
|
||||||
|
show create function fn1;
|
||||||
|
set role none;
|
||||||
|
|
||||||
|
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||||
|
select fn1();
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
# definer=role_name, privileges ok
|
||||||
|
create definer=role2 function fn2() returns int return (select sum(a+b) from t1);
|
||||||
|
show create function fn2;
|
||||||
|
select fn2();
|
||||||
|
|
||||||
|
# definer=non_existent_role
|
||||||
|
create definer=role3 function fn3() returns int return (select sum(a+b) from t1);
|
||||||
|
show create function fn3;
|
||||||
|
--error ER_NO_SUCH_USER
|
||||||
|
select fn3();
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# events
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
set global event_scheduler=on;
|
||||||
|
|
||||||
|
# no curent role = error
|
||||||
|
--error ER_MALFORMED_DEFINER
|
||||||
|
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 1, 0);
|
||||||
|
|
||||||
|
# definer=current_role, but it has doesn't have enough privileges
|
||||||
|
set role role1;
|
||||||
|
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 2, 0);
|
||||||
|
show create event e1;
|
||||||
|
set role none;
|
||||||
|
|
||||||
|
# definer=non_existent_role
|
||||||
|
create definer=role3 event e3 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 3, 0);
|
||||||
|
show create event e3;
|
||||||
|
|
||||||
|
# definer=role_name, privileges ok
|
||||||
|
create definer=role2 event e2 on schedule every 1 second starts '2000-01-01' do
|
||||||
|
insert t1 values (111, 4, 0);
|
||||||
|
show create event e2;
|
||||||
|
|
||||||
|
let $wait_condition=select count(*) >= 4 from t1;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
set global event_scheduler=off;
|
||||||
|
|
||||||
|
--sorted_result
|
||||||
|
select distinct * from t1;
|
||||||
|
delete from t1 where a=111;
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# mysqldump
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# note that LOCK TABLES won't work because v3 has invalid definer
|
||||||
|
|
||||||
|
--exec $MYSQL_DUMP --compact --events --routines --skip-lock-tables --databases test mysqltest1
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# cleanup
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
drop trigger tr1;
|
||||||
|
drop trigger tr2;
|
||||||
|
drop trigger tr3;
|
||||||
|
drop procedure pr1;
|
||||||
|
drop procedure pr2;
|
||||||
|
drop procedure pr3;
|
||||||
|
drop function fn1;
|
||||||
|
drop function fn2;
|
||||||
|
drop function fn3;
|
||||||
|
drop event e1;
|
||||||
|
drop event e2;
|
||||||
|
drop event e3;
|
||||||
|
drop view test.v1, test.v2, test.v3, test.v4, test.v5;
|
||||||
|
drop table t1, t2;
|
||||||
|
drop role role1, role2;
|
||||||
|
drop user foo@localhost;
|
||||||
|
drop database mysqltest1;
|
||||||
|
use test;
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# reexecution
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
create user utest;
|
||||||
|
prepare stmt1 from 'grant select on *.* to utest';
|
||||||
|
execute stmt1;
|
||||||
|
show grants for utest;
|
||||||
|
drop user utest;
|
||||||
|
create role utest;
|
||||||
|
execute stmt1;
|
||||||
|
show grants for utest;
|
||||||
|
drop role utest;
|
||||||
|
|
@ -1,15 +1,11 @@
|
|||||||
|
|
||||||
#create a user with no privileges
|
#create a user with no privileges
|
||||||
create user 'test_user'@'localhost';
|
create user test_user@localhost;
|
||||||
create user 'test_role1'@'';
|
create role test_role1;
|
||||||
#manualy create role
|
|
||||||
update mysql.user set is_role='Y' where user='test_role1';
|
|
||||||
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('localhost',
|
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('localhost',
|
||||||
'test_user',
|
'test_user',
|
||||||
'test_role1');
|
'test_role1');
|
||||||
create user 'test_role2'@'';
|
create role test_role2;
|
||||||
#manualy create role
|
|
||||||
update mysql.user set is_role='Y' where user='test_role2';
|
|
||||||
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('',
|
insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('',
|
||||||
'test_role1',
|
'test_role1',
|
||||||
'test_role2');
|
'test_role2');
|
||||||
@ -26,19 +22,21 @@ select user, host from user where user like 'test%';
|
|||||||
--sorted_result
|
--sorted_result
|
||||||
select * from roles_mapping;
|
select * from roles_mapping;
|
||||||
|
|
||||||
rename user 'test_role2'@'' to 'test_role2_rm'@'';
|
######### role rename does not work yet
|
||||||
--sorted_result
|
#rename user 'test_role2'@'' to 'test_role2_rm'@'';
|
||||||
select user, host from user where user like 'test%';
|
#--sorted_result
|
||||||
--sorted_result
|
#select user, host from user where user like 'test%';
|
||||||
select * from roles_mapping;
|
#--sorted_result
|
||||||
|
#select * from roles_mapping;
|
||||||
#role rename
|
#
|
||||||
rename user 'test_role1'@'' to 'test_role1_rm'@'';
|
##role rename
|
||||||
--sorted_result
|
#rename user 'test_role1'@'' to 'test_role1_rm'@'';
|
||||||
select user, host from user where user like 'test%';
|
#--sorted_result
|
||||||
--sorted_result
|
#select user, host from user where user like 'test%';
|
||||||
select * from roles_mapping;
|
#--sorted_result
|
||||||
|
#select * from roles_mapping;
|
||||||
|
|
||||||
delete from mysql.roles_mapping;
|
delete from mysql.roles_mapping;
|
||||||
delete from mysql.user where user like 'test%';
|
delete from mysql.user where user like 'test%';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
|
|
||||||
|
40
mysql-test/t/acl_roles_rpl_definer.test
Normal file
40
mysql-test/t/acl_roles_rpl_definer.test
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#
|
||||||
|
# replication of the DEFINER=current_role
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
create role role1;
|
||||||
|
grant execute on test.* to role1;
|
||||||
|
grant role1 to current_user;
|
||||||
|
set role role1;
|
||||||
|
|
||||||
|
create definer=current_user procedure pcu() select current_user;
|
||||||
|
create definer=root@localhost procedure pu() select "root@localhost";
|
||||||
|
create definer=current_role procedure pcr() select current_role;
|
||||||
|
create definer=role1 procedure pr() select "role1";
|
||||||
|
|
||||||
|
show create procedure pcu;
|
||||||
|
show create procedure pu;
|
||||||
|
show create procedure pcr;
|
||||||
|
show create procedure pr;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection slave;
|
||||||
|
echo [connection slave];
|
||||||
|
|
||||||
|
show create procedure pcu;
|
||||||
|
show create procedure pu;
|
||||||
|
show create procedure pcr;
|
||||||
|
show create procedure pr;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
drop procedure pcu;
|
||||||
|
drop procedure pu;
|
||||||
|
drop procedure pcr;
|
||||||
|
drop procedure pr;
|
||||||
|
drop role role1;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
||||||
|
|
@ -30,34 +30,40 @@
|
|||||||
host_name_str [OUT] Buffer to store host name part.
|
host_name_str [OUT] Buffer to store host name part.
|
||||||
Must be not less than HOSTNAME_LENGTH + 1.
|
Must be not less than HOSTNAME_LENGTH + 1.
|
||||||
host_name_len [OUT] A place to store length of the host name part.
|
host_name_len [OUT] A place to store length of the host name part.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 - if only a user was set, no '@' was found
|
||||||
|
1 - if both user and host were set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void parse_user(const char *user_id_str, size_t user_id_len,
|
int parse_user(const char *user_id_str, size_t user_id_len,
|
||||||
char *user_name_str, size_t *user_name_len,
|
char *user_name_str, size_t *user_name_len,
|
||||||
char *host_name_str, size_t *host_name_len)
|
char *host_name_str, size_t *host_name_len)
|
||||||
{
|
{
|
||||||
char *p= strrchr(user_id_str, '@');
|
char *p= strrchr(user_id_str, '@');
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
*user_name_len= 0;
|
*user_name_len= user_id_len;
|
||||||
*host_name_len= 0;
|
*host_name_len= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*user_name_len= (uint) (p - user_id_str);
|
*user_name_len= (uint) (p - user_id_str);
|
||||||
*host_name_len= (uint) (user_id_len - *user_name_len - 1);
|
*host_name_len= (uint) (user_id_len - *user_name_len - 1);
|
||||||
|
|
||||||
if (*user_name_len > USERNAME_LENGTH)
|
|
||||||
*user_name_len= USERNAME_LENGTH;
|
|
||||||
|
|
||||||
if (*host_name_len > HOSTNAME_LENGTH)
|
|
||||||
*host_name_len= HOSTNAME_LENGTH;
|
|
||||||
|
|
||||||
memcpy(user_name_str, user_id_str, *user_name_len);
|
|
||||||
memcpy(host_name_str, p + 1, *host_name_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*user_name_len > USERNAME_LENGTH)
|
||||||
|
*user_name_len= USERNAME_LENGTH;
|
||||||
|
|
||||||
|
if (*host_name_len > HOSTNAME_LENGTH)
|
||||||
|
*host_name_len= HOSTNAME_LENGTH;
|
||||||
|
|
||||||
|
memcpy(user_name_str, user_id_str, *user_name_len);
|
||||||
|
memcpy(host_name_str, p + 1, *host_name_len);
|
||||||
|
|
||||||
user_name_str[*user_name_len]= 0;
|
user_name_str[*user_name_len]= 0;
|
||||||
host_name_str[*host_name_len]= 0;
|
host_name_str[*host_name_len]= 0;
|
||||||
|
|
||||||
|
return p != NULL;
|
||||||
}
|
}
|
||||||
|
@ -2853,17 +2853,22 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||||||
user= thd->get_invoker_user();
|
user= thd->get_invoker_user();
|
||||||
host= thd->get_invoker_host();
|
host= thd->get_invoker_host();
|
||||||
}
|
}
|
||||||
else if (thd->security_ctx->priv_user)
|
else
|
||||||
{
|
{
|
||||||
Security_context *ctx= thd->security_ctx;
|
Security_context *ctx= thd->security_ctx;
|
||||||
|
|
||||||
user.length= strlen(ctx->priv_user);
|
if (thd->need_binlog_invoker() == THD::INVOKER_USER)
|
||||||
user.str= ctx->priv_user;
|
|
||||||
if (ctx->priv_host[0] != '\0')
|
|
||||||
{
|
{
|
||||||
|
user.str= ctx->priv_user;
|
||||||
host.str= ctx->priv_host;
|
host.str= ctx->priv_host;
|
||||||
host.length= strlen(ctx->priv_host);
|
host.length= strlen(host.str);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.str= ctx->priv_role;
|
||||||
|
host= null_lex_str; // XXX FIXME or empty_lex_str ?
|
||||||
|
}
|
||||||
|
user.length= strlen(user.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.length > 0)
|
if (user.length > 0)
|
||||||
|
@ -5489,9 +5489,8 @@ ER_PS_NO_RECURSION
|
|||||||
ER_SP_CANT_SET_AUTOCOMMIT
|
ER_SP_CANT_SET_AUTOCOMMIT
|
||||||
eng "Not allowed to set autocommit from a stored function or trigger"
|
eng "Not allowed to set autocommit from a stored function or trigger"
|
||||||
ger "Es ist nicht erlaubt, innerhalb einer gespeicherten Funktion oder eines Triggers AUTOCOMMIT zu setzen"
|
ger "Es ist nicht erlaubt, innerhalb einer gespeicherten Funktion oder eines Triggers AUTOCOMMIT zu setzen"
|
||||||
ER_MALFORMED_DEFINER
|
ER_MALFORMED_DEFINER 0L000
|
||||||
eng "Definer is not fully qualified"
|
eng "Invalid definer"
|
||||||
ger "Definierer des View ist nicht vollständig spezifiziert"
|
|
||||||
ER_VIEW_FRM_NO_USER
|
ER_VIEW_FRM_NO_USER
|
||||||
eng "View '%-.192s'.'%-.192s' has no definer information (old table format). Current user is used as definer. Please recreate the view!"
|
eng "View '%-.192s'.'%-.192s' has no definer information (old table format). Current user is used as definer. Please recreate the view!"
|
||||||
ger "View '%-.192s'.'%-.192s' hat keine Definierer-Information (altes Tabellenformat). Der aktuelle Benutzer wird als Definierer verwendet. Bitte erstellen Sie den View neu"
|
ger "View '%-.192s'.'%-.192s' hat keine Definierer-Information (altes Tabellenformat). Der aktuelle Benutzer wird als Definierer verwendet. Bitte erstellen Sie den View neu"
|
||||||
|
19
sql/sp.cc
19
sql/sp.cc
@ -662,9 +662,14 @@ db_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
|
|||||||
close_system_tables(thd, &open_tables_state_backup);
|
close_system_tables(thd, &open_tables_state_backup);
|
||||||
table= 0;
|
table= 0;
|
||||||
|
|
||||||
parse_user(definer, strlen(definer),
|
if (parse_user(definer, strlen(definer),
|
||||||
definer_user_name.str, &definer_user_name.length,
|
definer_user_name.str, &definer_user_name.length,
|
||||||
definer_host_name.str, &definer_host_name.length);
|
definer_host_name.str, &definer_host_name.length) &&
|
||||||
|
definer_user_name.length && !definer_host_name.length)
|
||||||
|
{
|
||||||
|
// 'user@' -> 'user@%'
|
||||||
|
definer_host_name= host_not_specified;
|
||||||
|
}
|
||||||
|
|
||||||
ret= db_load_routine(thd, type, name, sphp,
|
ret= db_load_routine(thd, type, name, sphp,
|
||||||
sql_mode, params, returns, body, chistics,
|
sql_mode, params, returns, body, chistics,
|
||||||
@ -975,7 +980,8 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
char definer[USER_HOST_BUFF_SIZE];
|
char definer_buf[USER_HOST_BUFF_SIZE];
|
||||||
|
LEX_STRING definer;
|
||||||
ulonglong saved_mode= thd->variables.sql_mode;
|
ulonglong saved_mode= thd->variables.sql_mode;
|
||||||
MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
|
MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
|
||||||
MDL_key::FUNCTION : MDL_key::PROCEDURE;
|
MDL_key::FUNCTION : MDL_key::PROCEDURE;
|
||||||
@ -1012,8 +1018,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
|
|||||||
restore_record(table, s->default_values); // Get default values for fields
|
restore_record(table, s->default_values); // Get default values for fields
|
||||||
|
|
||||||
/* NOTE: all needed privilege checks have been already done. */
|
/* NOTE: all needed privilege checks have been already done. */
|
||||||
strxnmov(definer, sizeof(definer)-1, thd->lex->definer->user.str, "@",
|
thd->lex->definer->set_lex_string(&definer, definer_buf);
|
||||||
thd->lex->definer->host.str, NullS);
|
|
||||||
|
|
||||||
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
|
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
|
||||||
{
|
{
|
||||||
@ -1088,7 +1093,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
|
|||||||
|
|
||||||
store_failed= store_failed ||
|
store_failed= store_failed ||
|
||||||
table->field[MYSQL_PROC_FIELD_DEFINER]->
|
table->field[MYSQL_PROC_FIELD_DEFINER]->
|
||||||
store(definer, (uint)strlen(definer), system_charset_info);
|
store(definer.str, definer.length, system_charset_info);
|
||||||
|
|
||||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
|
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
|
||||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
||||||
|
@ -2549,8 +2549,13 @@ sp_head::set_definer(const char *definer, uint definerlen)
|
|||||||
char host_name_holder[HOSTNAME_LENGTH + 1];
|
char host_name_holder[HOSTNAME_LENGTH + 1];
|
||||||
LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH };
|
LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH };
|
||||||
|
|
||||||
parse_user(definer, definerlen, user_name.str, &user_name.length,
|
if (parse_user(definer, definerlen, user_name.str, &user_name.length,
|
||||||
host_name.str, &host_name.length);
|
host_name.str, &host_name.length) &&
|
||||||
|
user_name.length && !host_name.length)
|
||||||
|
{
|
||||||
|
// 'user@' -> 'user@%'
|
||||||
|
host_name= host_not_specified;
|
||||||
|
}
|
||||||
|
|
||||||
set_definer(&user_name, &host_name);
|
set_definer(&user_name, &host_name);
|
||||||
}
|
}
|
||||||
|
503
sql/sql_acl.cc
503
sql/sql_acl.cc
@ -314,27 +314,19 @@ public:
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
static void update_hostname(acl_host_and_ip *host, const char *hostname);
|
static void update_hostname(acl_host_and_ip *host, const char *hostname);
|
||||||
static ulong get_sort(uint count,...);
|
static ulong get_sort(uint count,...);
|
||||||
static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
|
static bool compare_hostname(const acl_host_and_ip *, const char *, const char *);
|
||||||
const char *ip);
|
static bool show_proxy_grants (THD *, const char *, const char *,
|
||||||
static bool show_proxy_grants (THD *thd,
|
char *, size_t);
|
||||||
const char *username, const char *hostname,
|
static bool show_role_grants(THD *, const char *, const char *,
|
||||||
char *buff, size_t buffsize);
|
ACL_USER_BASE *, char *, size_t);
|
||||||
static bool show_role_grants(THD *thd, const char *username, const char *hostname,
|
static bool show_global_privileges(THD *, ACL_USER_BASE *,
|
||||||
ACL_USER_BASE *acl_entry,
|
bool, char *, size_t);
|
||||||
char *buff, size_t buffsize);
|
static bool show_database_privileges(THD *, const char *, const char *,
|
||||||
static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
|
char *, size_t);
|
||||||
bool handle_as_role,
|
static bool show_table_and_column_privileges(THD *, const char *, const char *,
|
||||||
char *buff, size_t buffsize);
|
char *, size_t);
|
||||||
static bool show_database_privileges(THD *thd,
|
static int show_routine_grants(THD *, const char *, const char *, HASH *,
|
||||||
const char *username,
|
const char *, int, char *, int);
|
||||||
const char *hostname,
|
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, size_t buffsize);
|
|
||||||
static bool show_table_and_column_privileges(THD *thd,
|
|
||||||
const char *username,
|
|
||||||
const char *hostname,
|
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, size_t buffsize);
|
|
||||||
|
|
||||||
class ACL_PROXY_USER :public ACL_ACCESS
|
class ACL_PROXY_USER :public ACL_ACCESS
|
||||||
{
|
{
|
||||||
@ -1757,57 +1749,86 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
|
|||||||
sctx->db_access= 0;
|
sctx->db_access= 0;
|
||||||
*sctx->priv_user= *sctx->priv_host= *sctx->priv_role= 0;
|
*sctx->priv_user= *sctx->priv_host= *sctx->priv_role= 0;
|
||||||
|
|
||||||
/*
|
if (host[0]) // User, not Role
|
||||||
Find acl entry in user database.
|
|
||||||
This is specially tailored to suit the check we do for CALL of
|
|
||||||
a stored procedure; user is set to what is actually a
|
|
||||||
priv_user, which can be ''.
|
|
||||||
*/
|
|
||||||
for (i=0 ; i < acl_users.elements ; i++)
|
|
||||||
{
|
{
|
||||||
ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
|
/*
|
||||||
if ((!acl_user_tmp->user.str && !user[0]) ||
|
Find acl entry in user database.
|
||||||
(acl_user_tmp->user.str && strcmp(user, acl_user_tmp->user.str) == 0))
|
This is specially tailored to suit the check we do for CALL of
|
||||||
|
a stored procedure; user is set to what is actually a
|
||||||
|
priv_user, which can be ''.
|
||||||
|
*/
|
||||||
|
for (i=0 ; i < acl_users.elements ; i++)
|
||||||
{
|
{
|
||||||
if (compare_hostname(&acl_user_tmp->host, host, ip))
|
ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
|
||||||
|
if ((!acl_user_tmp->user.str && !user[0]) ||
|
||||||
|
(acl_user_tmp->user.str && strcmp(user, acl_user_tmp->user.str) == 0))
|
||||||
{
|
{
|
||||||
acl_user= acl_user_tmp;
|
if (compare_hostname(&acl_user_tmp->host, host, ip))
|
||||||
res= 0;
|
{
|
||||||
break;
|
acl_user= acl_user_tmp;
|
||||||
|
res= 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (acl_user)
|
||||||
|
{
|
||||||
|
for (i=0 ; i < acl_dbs.elements ; i++)
|
||||||
|
{
|
||||||
|
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*);
|
||||||
|
if (!acl_db->user ||
|
||||||
|
(user && user[0] && !strcmp(user, acl_db->user)))
|
||||||
|
{
|
||||||
|
if (compare_hostname(&acl_db->host, host, ip))
|
||||||
|
{
|
||||||
|
if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
|
||||||
|
{
|
||||||
|
sctx->db_access= acl_db->access;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sctx->master_access= acl_user->access;
|
||||||
|
|
||||||
|
if (acl_user->user.str)
|
||||||
|
strmake_buf(sctx->priv_user, user);
|
||||||
|
|
||||||
|
if (acl_user->host.hostname)
|
||||||
|
strmake_buf(sctx->priv_host, acl_user->host.hostname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Role, not User
|
||||||
|
{
|
||||||
|
ACL_ROLE *acl_role= find_acl_role(user);
|
||||||
|
if (acl_role)
|
||||||
|
{
|
||||||
|
res= 0;
|
||||||
|
for (i=0 ; i < acl_dbs.elements ; i++)
|
||||||
|
{
|
||||||
|
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*);
|
||||||
|
if (!acl_db->user ||
|
||||||
|
(user && user[0] && !strcmp(user, acl_db->user)))
|
||||||
|
{
|
||||||
|
if (compare_hostname(&acl_db->host, "", ""))
|
||||||
|
{
|
||||||
|
if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
|
||||||
|
{
|
||||||
|
sctx->db_access= acl_db->access;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sctx->master_access= acl_role->access;
|
||||||
|
|
||||||
|
if (acl_role->user.str)
|
||||||
|
strmake_buf(sctx->priv_user, user);
|
||||||
|
sctx->priv_host[0]= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acl_user)
|
|
||||||
{
|
|
||||||
for (i=0 ; i < acl_dbs.elements ; i++)
|
|
||||||
{
|
|
||||||
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*);
|
|
||||||
if (!acl_db->user ||
|
|
||||||
(user && user[0] && !strcmp(user, acl_db->user)))
|
|
||||||
{
|
|
||||||
if (compare_hostname(&acl_db->host, host, ip))
|
|
||||||
{
|
|
||||||
if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
|
|
||||||
{
|
|
||||||
sctx->db_access= acl_db->access;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sctx->master_access= acl_user->access;
|
|
||||||
|
|
||||||
if (acl_user->user.str)
|
|
||||||
strmake_buf(sctx->priv_user, user);
|
|
||||||
else
|
|
||||||
*sctx->priv_user= 0;
|
|
||||||
|
|
||||||
if (acl_user->host.hostname)
|
|
||||||
strmake_buf(sctx->priv_host, acl_user->host.hostname);
|
|
||||||
else
|
|
||||||
*sctx->priv_host= 0;
|
|
||||||
}
|
|
||||||
mysql_mutex_unlock(&acl_cache->lock);
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
@ -3039,7 +3060,12 @@ bool is_acl_user(const char *host, const char *user)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
mysql_mutex_lock(&acl_cache->lock);
|
mysql_mutex_lock(&acl_cache->lock);
|
||||||
res= find_user_no_anon(host, user, TRUE) != NULL;
|
|
||||||
|
if (*host) // User
|
||||||
|
res= find_user_no_anon(host, user, TRUE) != NULL;
|
||||||
|
else // Role
|
||||||
|
res= find_acl_role(user) != NULL;
|
||||||
|
|
||||||
mysql_mutex_unlock(&acl_cache->lock);
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -3345,13 +3371,13 @@ static bool test_if_create_new_users(THD *thd)
|
|||||||
|
|
||||||
static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
|
static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
|
||||||
ulong rights, bool revoke_grant,
|
ulong rights, bool revoke_grant,
|
||||||
bool can_create_user, bool no_auto_create,
|
bool can_create_user, bool no_auto_create)
|
||||||
bool handle_as_role)
|
|
||||||
{
|
{
|
||||||
int error = -1;
|
int error = -1;
|
||||||
bool old_row_exists=0;
|
bool old_row_exists=0;
|
||||||
char what= (revoke_grant) ? 'N' : 'Y';
|
char what= (revoke_grant) ? 'N' : 'Y';
|
||||||
uchar user_key[MAX_KEY_LENGTH];
|
uchar user_key[MAX_KEY_LENGTH];
|
||||||
|
bool handle_as_role= combo.is_role();
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
DBUG_ENTER("replace_user_table");
|
DBUG_ENTER("replace_user_table");
|
||||||
|
|
||||||
@ -4832,26 +4858,6 @@ table_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
A user name specified without a host can be either a
|
|
||||||
username@% (where '@%' is added automatically by the parser)
|
|
||||||
or a role name. Treat it as a role, if such a role exists.
|
|
||||||
*/
|
|
||||||
static ACL_ROLE *find_and_mark_as_role(LEX_USER *user)
|
|
||||||
{
|
|
||||||
if (user->host.str == host_not_specified.str)
|
|
||||||
{
|
|
||||||
ACL_ROLE *role= find_acl_role(user->user.str);
|
|
||||||
if (role)
|
|
||||||
{
|
|
||||||
user->host= empty_lex_str;
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Store table level and column level grants in the privilege tables
|
Store table level and column level grants in the privilege tables
|
||||||
|
|
||||||
@ -5018,21 +5024,16 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
GRANT_TABLE *grant_table;
|
GRANT_TABLE *grant_table;
|
||||||
if (!(Str= get_current_user(thd, tmp_Str)))
|
if (!(Str= get_current_user(thd, tmp_Str, false)))
|
||||||
{
|
{
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_as_role= FALSE;
|
|
||||||
if (find_and_mark_as_role(Str))
|
|
||||||
handle_as_role= TRUE;
|
|
||||||
|
|
||||||
/* Create user if needed */
|
/* Create user if needed */
|
||||||
error=replace_user_table(thd, tables[0].table, *Str,
|
error=replace_user_table(thd, tables[0].table, *Str,
|
||||||
0, revoke_grant, create_new_users,
|
0, revoke_grant, create_new_users,
|
||||||
test(thd->variables.sql_mode &
|
test(thd->variables.sql_mode &
|
||||||
MODE_NO_AUTO_CREATE_USER), handle_as_role);
|
MODE_NO_AUTO_CREATE_USER));
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
result= TRUE; // Remember error
|
result= TRUE; // Remember error
|
||||||
@ -5227,21 +5228,16 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
GRANT_NAME *grant_name;
|
GRANT_NAME *grant_name;
|
||||||
if (!(Str= get_current_user(thd, tmp_Str)))
|
if (!(Str= get_current_user(thd, tmp_Str, false)))
|
||||||
{
|
{
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_as_role= FALSE;
|
|
||||||
if (find_and_mark_as_role(Str))
|
|
||||||
handle_as_role=TRUE;
|
|
||||||
|
|
||||||
/* Create user if needed */
|
/* Create user if needed */
|
||||||
error=replace_user_table(thd, tables[0].table, *Str,
|
error=replace_user_table(thd, tables[0].table, *Str,
|
||||||
0, revoke_grant, create_new_users,
|
0, revoke_grant, create_new_users,
|
||||||
test(thd->variables.sql_mode &
|
test(thd->variables.sql_mode &
|
||||||
MODE_NO_AUTO_CREATE_USER), handle_as_role);
|
MODE_NO_AUTO_CREATE_USER));
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
result= TRUE; // Remember error
|
result= TRUE; // Remember error
|
||||||
@ -5297,15 +5293,14 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
|
|||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_user(String *str, const char *u, const char *h,
|
static void append_user(String *str, const char *u, const char *h)
|
||||||
bool handle_as_role)
|
|
||||||
{
|
{
|
||||||
if (str->length())
|
if (str->length())
|
||||||
str->append(',');
|
str->append(',');
|
||||||
str->append('\'');
|
str->append('\'');
|
||||||
str->append(u);
|
str->append(u);
|
||||||
/* hostname part is not relevant for roles, it is always empty */
|
/* hostname part is not relevant for roles, it is always empty */
|
||||||
if (!handle_as_role)
|
if (*h)
|
||||||
{
|
{
|
||||||
str->append(STRING_WITH_LEN("'@'"));
|
str->append(STRING_WITH_LEN("'@'"));
|
||||||
str->append(h);
|
str->append(h);
|
||||||
@ -5381,13 +5376,13 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
/* current_role is NONE */
|
/* current_role is NONE */
|
||||||
if (!thd->security_ctx->priv_role[0])
|
if (!thd->security_ctx->priv_role[0])
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, "NONE", "", TRUE);
|
append_user(&wrong_users, "NONE", "");
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
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)))
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, thd->security_ctx->priv_role, "", TRUE);
|
append_user(&wrong_users, thd->security_ctx->priv_role, "");
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5395,18 +5390,26 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
/* can not grant current_role to current_role */
|
/* can not grant current_role to current_role */
|
||||||
if (granted_role->user.str == current_role.str)
|
if (granted_role->user.str == current_role.str)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, thd->security_ctx->priv_role, "", TRUE);
|
append_user(&wrong_users, thd->security_ctx->priv_role, "");
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
username= thd->security_ctx->priv_role;
|
username= thd->security_ctx->priv_role;
|
||||||
hostname= (char *)"";
|
hostname= const_cast<char*>("");
|
||||||
|
}
|
||||||
|
else if (user->user.str == current_user.str)
|
||||||
|
{
|
||||||
|
role_as_user= NULL;
|
||||||
|
username= thd->security_ctx->priv_user;
|
||||||
|
hostname= thd->security_ctx->priv_host;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
role_as_user= find_and_mark_as_role(user);
|
if ((role_as_user= find_acl_role(user->user.str)))
|
||||||
|
hostname= const_cast<char*>("");
|
||||||
|
else
|
||||||
|
hostname= user->host.str ? user->host.str : host_not_specified.str;
|
||||||
username= user->user.str;
|
username= user->user.str;
|
||||||
hostname= user->host.str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ROLE_GRANT_PAIR *mapping, *hash_entry;
|
ROLE_GRANT_PAIR *mapping, *hash_entry;
|
||||||
@ -5421,7 +5424,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
/* role or user does not exist*/
|
/* role or user does not exist*/
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, username, hostname, role_as_user != NULL);
|
append_user(&wrong_users, username, hostname);
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5434,7 +5437,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
traverse_role_graph(role, NULL, NULL, NULL, role_explore_detect_cycle,
|
traverse_role_graph(role, NULL, NULL, NULL, role_explore_detect_cycle,
|
||||||
NULL) == 2)
|
NULL) == 2)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, username, hostname, TRUE);
|
append_user(&wrong_users, username, "");
|
||||||
result= 1;
|
result= 1;
|
||||||
/* need to rollback the mapping added previously */
|
/* need to rollback the mapping added previously */
|
||||||
remove_role_user_mapping(mapping);
|
remove_role_user_mapping(mapping);
|
||||||
@ -5450,7 +5453,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
/* grant was already removed or never existed */
|
/* grant was already removed or never existed */
|
||||||
if (!hash_entry)
|
if (!hash_entry)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, username, hostname, role_as_user != NULL);
|
append_user(&wrong_users, username, hostname);
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5458,7 +5461,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
int res= remove_role_user_mapping(mapping);
|
int res= remove_role_user_mapping(mapping);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, username, hostname, role_as_user != NULL);
|
append_user(&wrong_users, username, hostname);
|
||||||
result= 1;
|
result= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5467,7 +5470,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||||||
/* write into the roles_mapping table */
|
/* write into the roles_mapping table */
|
||||||
if (replace_roles_mapping_table(tables.table, mapping, revoke))
|
if (replace_roles_mapping_table(tables.table, mapping, revoke))
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, username, hostname, TRUE);
|
append_user(&wrong_users, username, "");
|
||||||
result= 1;
|
result= 1;
|
||||||
if (!revoke)
|
if (!revoke)
|
||||||
{
|
{
|
||||||
@ -5599,10 +5602,17 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
mysql_mutex_lock(&acl_cache->lock);
|
mysql_mutex_lock(&acl_cache->lock);
|
||||||
grant_version++;
|
grant_version++;
|
||||||
|
|
||||||
|
if (proxied_user)
|
||||||
|
{
|
||||||
|
if (!(proxied_user= get_current_user(thd, proxied_user, false)))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
DBUG_ASSERT(proxied_user->host.length); // not a Role
|
||||||
|
}
|
||||||
|
|
||||||
int result=0;
|
int result=0;
|
||||||
while ((tmp_Str = str_list++))
|
while ((tmp_Str = str_list++))
|
||||||
{
|
{
|
||||||
if (!(Str= get_current_user(thd, tmp_Str)))
|
if (!(Str= get_current_user(thd, tmp_Str, false)))
|
||||||
{
|
{
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
@ -5615,14 +5625,10 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
if (tmp_Str->user.str == current_user.str && tmp_Str->password.str)
|
if (tmp_Str->user.str == current_user.str && tmp_Str->password.str)
|
||||||
Str->password= tmp_Str->password;
|
Str->password= tmp_Str->password;
|
||||||
|
|
||||||
bool handle_as_role= FALSE;
|
|
||||||
if (find_and_mark_as_role(Str))
|
|
||||||
handle_as_role= TRUE;
|
|
||||||
|
|
||||||
if (replace_user_table(thd, tables[0].table, *Str,
|
if (replace_user_table(thd, tables[0].table, *Str,
|
||||||
(!db ? rights : 0), revoke_grant, create_new_users,
|
(!db ? rights : 0), revoke_grant, create_new_users,
|
||||||
test(thd->variables.sql_mode &
|
test(thd->variables.sql_mode &
|
||||||
MODE_NO_AUTO_CREATE_USER), handle_as_role))
|
MODE_NO_AUTO_CREATE_USER)))
|
||||||
result= -1;
|
result= -1;
|
||||||
else if (db)
|
else if (db)
|
||||||
{
|
{
|
||||||
@ -6870,14 +6876,6 @@ static uint command_lengths[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int show_routine_grants(THD *thd,
|
|
||||||
const char *username,
|
|
||||||
const char *hostname,
|
|
||||||
HASH *hash,
|
|
||||||
const char *type, int typelen,
|
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, int buffsize);
|
|
||||||
|
|
||||||
bool print_grants_for_role(THD *thd, ACL_ROLE * role,
|
bool print_grants_for_role(THD *thd, ACL_ROLE * role,
|
||||||
char *buff, size_t buffsize)
|
char *buff, size_t buffsize)
|
||||||
{
|
{
|
||||||
@ -6887,18 +6885,18 @@ bool print_grants_for_role(THD *thd, ACL_ROLE * role,
|
|||||||
if (show_global_privileges(thd, role, TRUE, buff, buffsize))
|
if (show_global_privileges(thd, role, TRUE, buff, buffsize))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (show_database_privileges(thd, role->user.str, "", TRUE, buff, buffsize))
|
if (show_database_privileges(thd, role->user.str, "", buff, buffsize))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (show_table_and_column_privileges(thd, role->user.str, "", TRUE, buff, buffsize))
|
if (show_table_and_column_privileges(thd, role->user.str, "", buff, buffsize))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (show_routine_grants(thd, role->user.str, "", &proc_priv_hash,
|
if (show_routine_grants(thd, role->user.str, "", &proc_priv_hash,
|
||||||
STRING_WITH_LEN("PROCEDURE"), TRUE, buff, buffsize))
|
STRING_WITH_LEN("PROCEDURE"), buff, buffsize))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (show_routine_grants(thd, role->user.str, "", &func_priv_hash,
|
if (show_routine_grants(thd, role->user.str, "", &func_priv_hash,
|
||||||
STRING_WITH_LEN("FUNCTION"), TRUE, buff, buffsize))
|
STRING_WITH_LEN("FUNCTION"), buff, buffsize))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -6951,7 +6949,8 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (find_and_mark_as_role(lex_user))
|
lex_user= get_current_user(thd, lex_user, false);
|
||||||
|
if (lex_user->is_role())
|
||||||
{
|
{
|
||||||
rolename= lex_user->user.str;
|
rolename= lex_user->user.str;
|
||||||
}
|
}
|
||||||
@ -7010,28 +7009,28 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Add database access */
|
/* Add database access */
|
||||||
if (show_database_privileges(thd, username, hostname, FALSE, buff, sizeof(buff)))
|
if (show_database_privileges(thd, username, hostname, buff, sizeof(buff)))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add table & column access */
|
/* Add table & column access */
|
||||||
if (show_table_and_column_privileges(thd, username, hostname, FALSE, buff, sizeof(buff)))
|
if (show_table_and_column_privileges(thd, username, hostname, buff, sizeof(buff)))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_routine_grants(thd, username, hostname, &proc_priv_hash,
|
if (show_routine_grants(thd, username, hostname, &proc_priv_hash,
|
||||||
STRING_WITH_LEN("PROCEDURE"), FALSE, buff, sizeof(buff)))
|
STRING_WITH_LEN("PROCEDURE"), buff, sizeof(buff)))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_routine_grants(thd, username, hostname, &func_priv_hash,
|
if (show_routine_grants(thd, username, hostname, &func_priv_hash,
|
||||||
STRING_WITH_LEN("FUNCTION"), FALSE, buff, sizeof(buff)))
|
STRING_WITH_LEN("FUNCTION"), buff, sizeof(buff)))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto end;
|
goto end;
|
||||||
@ -7267,7 +7266,6 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
|
|||||||
static bool show_database_privileges(THD *thd,
|
static bool show_database_privileges(THD *thd,
|
||||||
const char *username,
|
const char *username,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, size_t buffsize)
|
char *buff, size_t buffsize)
|
||||||
{
|
{
|
||||||
ACL_DB *acl_db;
|
ACL_DB *acl_db;
|
||||||
@ -7295,12 +7293,14 @@ static bool show_database_privileges(THD *thd,
|
|||||||
if (!strcmp(username, user) &&
|
if (!strcmp(username, user) &&
|
||||||
!my_strcasecmp(system_charset_info, hostname, host))
|
!my_strcasecmp(system_charset_info, hostname, host))
|
||||||
{
|
{
|
||||||
/* do not print inherited access bits, the role bits present in the
|
/*
|
||||||
table are what matters */
|
do not print inherited access bits for roles,
|
||||||
if (handle_as_role)
|
the role bits present in the table are what matters
|
||||||
want_access=acl_db->initial_access;
|
*/
|
||||||
else
|
if (*hostname) // User
|
||||||
want_access=acl_db->access;
|
want_access=acl_db->access;
|
||||||
|
else // Role
|
||||||
|
want_access=acl_db->initial_access;
|
||||||
if (want_access)
|
if (want_access)
|
||||||
{
|
{
|
||||||
String db(buff,sizeof(buff),system_charset_info);
|
String db(buff,sizeof(buff),system_charset_info);
|
||||||
@ -7331,7 +7331,7 @@ static bool show_database_privileges(THD *thd,
|
|||||||
db.append (STRING_WITH_LEN(".* TO '"));
|
db.append (STRING_WITH_LEN(".* TO '"));
|
||||||
db.append(username, strlen(username),
|
db.append(username, strlen(username),
|
||||||
system_charset_info);
|
system_charset_info);
|
||||||
if (!handle_as_role)
|
if (*hostname)
|
||||||
{
|
{
|
||||||
db.append (STRING_WITH_LEN("'@'"));
|
db.append (STRING_WITH_LEN("'@'"));
|
||||||
// host and lex_user->host are equal except for case
|
// host and lex_user->host are equal except for case
|
||||||
@ -7356,7 +7356,6 @@ static bool show_database_privileges(THD *thd,
|
|||||||
static bool show_table_and_column_privileges(THD *thd,
|
static bool show_table_and_column_privileges(THD *thd,
|
||||||
const char *username,
|
const char *username,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, size_t buffsize)
|
char *buff, size_t buffsize)
|
||||||
{
|
{
|
||||||
uint counter, index;
|
uint counter, index;
|
||||||
@ -7385,16 +7384,16 @@ static bool show_table_and_column_privileges(THD *thd,
|
|||||||
{
|
{
|
||||||
ulong table_access;
|
ulong table_access;
|
||||||
ulong cols_access;
|
ulong cols_access;
|
||||||
if (handle_as_role)
|
if (*hostname) // User
|
||||||
{
|
|
||||||
table_access= grant_table->init_privs;
|
|
||||||
cols_access= grant_table->init_cols;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
table_access= grant_table->privs;
|
table_access= grant_table->privs;
|
||||||
cols_access= grant_table->cols;
|
cols_access= grant_table->cols;
|
||||||
}
|
}
|
||||||
|
else // Role
|
||||||
|
{
|
||||||
|
table_access= grant_table->init_privs;
|
||||||
|
cols_access= grant_table->init_cols;
|
||||||
|
}
|
||||||
|
|
||||||
if ((table_access | cols_access) != 0)
|
if ((table_access | cols_access) != 0)
|
||||||
{
|
{
|
||||||
@ -7435,8 +7434,8 @@ static bool show_table_and_column_privileges(THD *thd,
|
|||||||
{
|
{
|
||||||
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
||||||
my_hash_element(hash_columns,col_index);
|
my_hash_element(hash_columns,col_index);
|
||||||
if ((!handle_as_role && (grant_column->rights & j)) ||
|
if (j & (*hostname ? grant_column->rights // User
|
||||||
(handle_as_role && (grant_column->init_rights & j)))
|
: grant_column->init_rights)) // Role
|
||||||
{
|
{
|
||||||
if (!found_col)
|
if (!found_col)
|
||||||
{
|
{
|
||||||
@ -7475,7 +7474,7 @@ static bool show_table_and_column_privileges(THD *thd,
|
|||||||
global.append(STRING_WITH_LEN(" TO '"));
|
global.append(STRING_WITH_LEN(" TO '"));
|
||||||
global.append(username, strlen(username),
|
global.append(username, strlen(username),
|
||||||
system_charset_info);
|
system_charset_info);
|
||||||
if (!handle_as_role)
|
if (*hostname)
|
||||||
{
|
{
|
||||||
global.append(STRING_WITH_LEN("'@'"));
|
global.append(STRING_WITH_LEN("'@'"));
|
||||||
// host and lex_user->host are equal except for case
|
// host and lex_user->host are equal except for case
|
||||||
@ -7499,9 +7498,7 @@ static bool show_table_and_column_privileges(THD *thd,
|
|||||||
|
|
||||||
static int show_routine_grants(THD* thd,
|
static int show_routine_grants(THD* thd,
|
||||||
const char *username, const char *hostname,
|
const char *username, const char *hostname,
|
||||||
HASH *hash,
|
HASH *hash, const char *type, int typelen,
|
||||||
const char *type, int typelen,
|
|
||||||
bool handle_as_role,
|
|
||||||
char *buff, int buffsize)
|
char *buff, int buffsize)
|
||||||
{
|
{
|
||||||
uint counter, index;
|
uint counter, index;
|
||||||
@ -7529,10 +7526,10 @@ static int show_routine_grants(THD* thd,
|
|||||||
!my_strcasecmp(system_charset_info, hostname, host))
|
!my_strcasecmp(system_charset_info, hostname, host))
|
||||||
{
|
{
|
||||||
ulong proc_access;
|
ulong proc_access;
|
||||||
if (handle_as_role)
|
if (*hostname) // User
|
||||||
proc_access= grant_proc->init_privs;
|
|
||||||
else
|
|
||||||
proc_access= grant_proc->privs;
|
proc_access= grant_proc->privs;
|
||||||
|
else // Role
|
||||||
|
proc_access= grant_proc->init_privs;
|
||||||
|
|
||||||
if (proc_access != 0)
|
if (proc_access != 0)
|
||||||
{
|
{
|
||||||
@ -7572,7 +7569,7 @@ static int show_routine_grants(THD* thd,
|
|||||||
global.append(STRING_WITH_LEN(" TO '"));
|
global.append(STRING_WITH_LEN(" TO '"));
|
||||||
global.append(username, strlen(username),
|
global.append(username, strlen(username),
|
||||||
system_charset_info);
|
system_charset_info);
|
||||||
if (!handle_as_role)
|
if (*hostname)
|
||||||
{
|
{
|
||||||
global.append(STRING_WITH_LEN("'@'"));
|
global.append(STRING_WITH_LEN("'@'"));
|
||||||
// host and lex_user->host are equal except for case
|
// host and lex_user->host are equal except for case
|
||||||
@ -8232,9 +8229,15 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
|
|||||||
table->key_info->key_part[1].store_length);
|
table->key_info->key_part[1].store_length);
|
||||||
key_copy(user_key, table->record[0], table->key_info, key_prefix_length);
|
key_copy(user_key, table->record[0], table->key_info, key_prefix_length);
|
||||||
|
|
||||||
if ((error= table->file->ha_index_read_idx_map(table->record[0], 0,
|
error= table->file->ha_index_read_idx_map(table->record[0], 0,
|
||||||
user_key, (key_part_map)3,
|
user_key, (key_part_map)3,
|
||||||
HA_READ_KEY_EXACT)))
|
HA_READ_KEY_EXACT);
|
||||||
|
if (!error && !*host_str)
|
||||||
|
{ // verify that we got a role or a user, as needed
|
||||||
|
if (check_is_role(table) != user_from->is_role())
|
||||||
|
error= HA_ERR_KEY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
||||||
{
|
{
|
||||||
@ -8371,7 +8374,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/* same. no roles in PROXY_USERS_ACL */
|
/* same. no roles in PROXY_USERS_ACL */
|
||||||
if (struct_no == PROXY_USERS_ACL && !user_from->host.length)
|
if (struct_no == PROXY_USERS_ACL && user_from->is_role())
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
if (struct_no == ROLE_ACL) //no need to scan the structures in this case
|
if (struct_no == ROLE_ACL) //no need to scan the structures in this case
|
||||||
@ -8678,8 +8681,12 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||||||
{
|
{
|
||||||
int result= 0;
|
int result= 0;
|
||||||
int found;
|
int found;
|
||||||
|
bool handle_as_role= user_from->is_role();
|
||||||
DBUG_ENTER("handle_grant_data");
|
DBUG_ENTER("handle_grant_data");
|
||||||
|
|
||||||
|
if (user_to)
|
||||||
|
DBUG_ASSERT(handle_as_role == user_to->is_role());
|
||||||
|
|
||||||
/* Handle user table. */
|
/* Handle user table. */
|
||||||
if ((found= handle_grant_table(tables, 0, drop, user_from, user_to)) < 0)
|
if ((found= handle_grant_table(tables, 0, drop, user_from, user_to)) < 0)
|
||||||
{
|
{
|
||||||
@ -8688,20 +8695,32 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Handle user array. */
|
if (handle_as_role)
|
||||||
if ((handle_grant_struct(USER_ACL, drop, user_from, user_to)) || found)
|
|
||||||
{
|
{
|
||||||
result= 1; /* At least one record/element found. */
|
if ((handle_grant_struct(ROLE_ACL, drop, user_from, user_to)) || found)
|
||||||
/* If search is requested, we do not need to search further. */
|
{
|
||||||
if (! drop && ! user_to)
|
result= 1; /* At least one record/element found. */
|
||||||
goto end;
|
/* If search is requested, we do not need to search further. */
|
||||||
|
if (! drop && ! user_to)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (find_user_no_anon(user_from->host.str, user_from->user.str, TRUE))
|
||||||
|
goto end; // looking for a role, found a user
|
||||||
}
|
}
|
||||||
if ((handle_grant_struct(ROLE_ACL, drop, user_from, user_to)) || found)
|
else
|
||||||
{
|
{
|
||||||
result= 1; /* At least one record/element found. */
|
/* Handle user array. */
|
||||||
/* If search is requested, we do not need to search further. */
|
if ((handle_grant_struct(USER_ACL, drop, user_from, user_to)) || found)
|
||||||
if (! drop && ! user_to)
|
{
|
||||||
goto end;
|
result= 1; /* At least one record/element found. */
|
||||||
|
/* If search is requested, we do not need to search further. */
|
||||||
|
if (! drop && ! user_to)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (find_acl_role(user_from->user.str))
|
||||||
|
goto end; // looking for a user, found a role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8821,14 +8840,14 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_user(String *str, LEX_USER *user, bool handle_as_role)
|
static void append_user(String *str, LEX_USER *user)
|
||||||
{
|
{
|
||||||
if (str->length())
|
if (str->length())
|
||||||
str->append(',');
|
str->append(',');
|
||||||
str->append('\'');
|
str->append('\'');
|
||||||
str->append(user->user.str);
|
str->append(user->user.str);
|
||||||
/* hostname part is not relevant for roles, it is always empty */
|
/* hostname part is not relevant for roles, it is always empty */
|
||||||
if (!handle_as_role)
|
if (!user->is_role())
|
||||||
{
|
{
|
||||||
str->append(STRING_WITH_LEN("'@'"));
|
str->append(STRING_WITH_LEN("'@'"));
|
||||||
str->append(user->host.str);
|
str->append(user->host.str);
|
||||||
@ -8854,7 +8873,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
String wrong_users;
|
String wrong_users;
|
||||||
LEX_USER *user_name, *tmp_user_name;
|
LEX_USER *user_name;
|
||||||
List_iterator <LEX_USER> user_list(list);
|
List_iterator <LEX_USER> user_list(list);
|
||||||
TABLE_LIST tables[GRANT_TABLES];
|
TABLE_LIST tables[GRANT_TABLES];
|
||||||
bool some_users_created= FALSE;
|
bool some_users_created= FALSE;
|
||||||
@ -8868,30 +8887,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
|
|||||||
mysql_rwlock_wrlock(&LOCK_grant);
|
mysql_rwlock_wrlock(&LOCK_grant);
|
||||||
mysql_mutex_lock(&acl_cache->lock);
|
mysql_mutex_lock(&acl_cache->lock);
|
||||||
|
|
||||||
while ((tmp_user_name= user_list++))
|
while ((user_name= user_list++))
|
||||||
{
|
{
|
||||||
if (handle_as_role)
|
|
||||||
{
|
|
||||||
user_name= tmp_user_name;
|
|
||||||
user_name->host.str= (char *)"";
|
|
||||||
user_name->host.length= 0;
|
|
||||||
/* role already exists */
|
|
||||||
if (find_acl_role(user_name->user.str))
|
|
||||||
{
|
|
||||||
append_user(&wrong_users, user_name, TRUE);
|
|
||||||
result = TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(user_name= get_current_user(thd, tmp_user_name)))
|
|
||||||
{
|
|
||||||
result= TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user_name->host.str)
|
if (!user_name->host.str)
|
||||||
user_name->host= host_not_specified;
|
user_name->host= host_not_specified;
|
||||||
|
|
||||||
@ -8901,17 +8898,16 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
|
|||||||
*/
|
*/
|
||||||
if (handle_grant_data(tables, 0, user_name, NULL))
|
if (handle_grant_data(tables, 0, user_name, NULL))
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, user_name, handle_as_role);
|
append_user(&wrong_users, user_name);
|
||||||
|
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
some_users_created= TRUE;
|
some_users_created= TRUE;
|
||||||
if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0,
|
if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0))
|
||||||
handle_as_role))
|
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, user_name, handle_as_role);
|
append_user(&wrong_users, user_name);
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8966,31 +8962,17 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
|
|||||||
|
|
||||||
while ((tmp_user_name= user_list++))
|
while ((tmp_user_name= user_list++))
|
||||||
{
|
{
|
||||||
if (handle_as_role)
|
user_name= get_current_user(thd, tmp_user_name, false);
|
||||||
|
if (!user_name || handle_as_role != user_name->is_role())
|
||||||
{
|
{
|
||||||
|
append_user(&wrong_users, tmp_user_name);
|
||||||
user_name= tmp_user_name;
|
result= TRUE;
|
||||||
user_name->host.str= (char *)"";
|
continue;
|
||||||
user_name->host.length= 0;
|
|
||||||
if (!find_acl_role(user_name->user.str))
|
|
||||||
{
|
|
||||||
append_user(&wrong_users, user_name, TRUE);
|
|
||||||
result= TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(user_name= get_current_user(thd, tmp_user_name)))
|
|
||||||
{
|
|
||||||
result= TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
|
if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
|
||||||
{
|
{
|
||||||
append_user(&wrong_users, user_name, handle_as_role);
|
append_user(&wrong_users, user_name);
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -9058,18 +9040,21 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
|||||||
|
|
||||||
while ((tmp_user_from= user_list++))
|
while ((tmp_user_from= user_list++))
|
||||||
{
|
{
|
||||||
if (!(user_from= get_current_user(thd, tmp_user_from)))
|
|
||||||
{
|
|
||||||
result= TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tmp_user_to= user_list++;
|
tmp_user_to= user_list++;
|
||||||
if (!(user_to= get_current_user(thd, tmp_user_to)))
|
if (!(user_from= get_current_user(thd, tmp_user_from, false)) ||
|
||||||
|
user_from->is_role())
|
||||||
{
|
{
|
||||||
|
append_user(&wrong_users, user_from);
|
||||||
|
result= TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(user_to= get_current_user(thd, tmp_user_to, false)) ||
|
||||||
|
user_to->is_role())
|
||||||
|
{
|
||||||
|
append_user(&wrong_users, user_to);
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Search all in-memory structures and grant tables
|
Search all in-memory structures and grant tables
|
||||||
@ -9079,7 +9064,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
|||||||
handle_grant_data(tables, 0, user_from, user_to) <= 0)
|
handle_grant_data(tables, 0, user_from, user_to) <= 0)
|
||||||
{
|
{
|
||||||
/* NOTE TODO renaming roles is not yet implemented */
|
/* NOTE TODO renaming roles is not yet implemented */
|
||||||
append_user(&wrong_users, user_from, FALSE);
|
append_user(&wrong_users, user_from);
|
||||||
result= TRUE;
|
result= TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -9139,7 +9124,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
|||||||
List_iterator <LEX_USER> user_list(list);
|
List_iterator <LEX_USER> user_list(list);
|
||||||
while ((tmp_lex_user= user_list++))
|
while ((tmp_lex_user= user_list++))
|
||||||
{
|
{
|
||||||
if (!(lex_user= get_current_user(thd, tmp_lex_user)))
|
if (!(lex_user= get_current_user(thd, tmp_lex_user, false)))
|
||||||
{
|
{
|
||||||
result= -1;
|
result= -1;
|
||||||
continue;
|
continue;
|
||||||
@ -9150,8 +9135,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace_user_table(thd, tables[0].table,
|
if (replace_user_table(thd, tables[0].table, *lex_user, ~(ulong)0, 1, 0, 0))
|
||||||
*lex_user, ~(ulong)0, 1, 0, 0, 0))
|
|
||||||
{
|
{
|
||||||
result= -1;
|
result= -1;
|
||||||
continue;
|
continue;
|
||||||
@ -10257,6 +10241,47 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retuns information about user or current user.
|
||||||
|
|
||||||
|
@param[in] thd thread handler
|
||||||
|
@param[in] user user
|
||||||
|
|
||||||
|
@return
|
||||||
|
- On success, return a valid pointer to initialized
|
||||||
|
LEX_USER, which contains user information.
|
||||||
|
- On error, return 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock)
|
||||||
|
{
|
||||||
|
if (user->user.str == current_user.str) // current_user
|
||||||
|
return create_default_definer(thd, false);
|
||||||
|
|
||||||
|
if (user->user.str == current_role.str) // current_role
|
||||||
|
return create_default_definer(thd, true);
|
||||||
|
|
||||||
|
if (user->host.str == NULL) // Possibly a role
|
||||||
|
{
|
||||||
|
// to be reexecution friendly we have to make a copy
|
||||||
|
LEX_USER *dup= (LEX_USER*) thd->memdup(user, sizeof(*user));
|
||||||
|
if (!dup)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (lock)
|
||||||
|
mysql_mutex_lock(&acl_cache->lock);
|
||||||
|
if (find_acl_role(dup->user.str))
|
||||||
|
dup->host= empty_lex_str;
|
||||||
|
else
|
||||||
|
dup->host= host_not_specified;
|
||||||
|
if (lock)
|
||||||
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
struct ACL_internal_schema_registry_entry
|
struct ACL_internal_schema_registry_entry
|
||||||
{
|
{
|
||||||
const LEX_STRING *m_name;
|
const LEX_STRING *m_name;
|
||||||
|
@ -938,7 +938,7 @@ THD::THD()
|
|||||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||||
|
|
||||||
m_internal_handler= NULL;
|
m_internal_handler= NULL;
|
||||||
m_binlog_invoker= FALSE;
|
m_binlog_invoker= INVOKER_NONE;
|
||||||
arena_for_cached_items= 0;
|
arena_for_cached_items= 0;
|
||||||
memset(&invoker_user, 0, sizeof(invoker_user));
|
memset(&invoker_user, 0, sizeof(invoker_user));
|
||||||
memset(&invoker_host, 0, sizeof(invoker_host));
|
memset(&invoker_host, 0, sizeof(invoker_host));
|
||||||
@ -1890,7 +1890,7 @@ void THD::cleanup_after_query()
|
|||||||
where= THD::DEFAULT_WHERE;
|
where= THD::DEFAULT_WHERE;
|
||||||
/* reset table map for multi-table update */
|
/* reset table map for multi-table update */
|
||||||
table_map_for_update= 0;
|
table_map_for_update= 0;
|
||||||
m_binlog_invoker= FALSE;
|
m_binlog_invoker= INVOKER_NONE;
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (rli_slave)
|
if (rli_slave)
|
||||||
@ -4341,9 +4341,9 @@ void THD::leave_locked_tables_mode()
|
|||||||
locked_tables_mode= LTM_NONE;
|
locked_tables_mode= LTM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void THD::get_definer(LEX_USER *definer)
|
void THD::get_definer(LEX_USER *definer, bool role)
|
||||||
{
|
{
|
||||||
binlog_invoker();
|
binlog_invoker(role);
|
||||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||||
if (slave_thread && has_invoker())
|
if (slave_thread && has_invoker())
|
||||||
{
|
{
|
||||||
@ -4355,7 +4355,7 @@ void THD::get_definer(LEX_USER *definer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
get_default_definer(this, definer);
|
get_default_definer(this, definer, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3153,9 +3153,11 @@ public:
|
|||||||
}
|
}
|
||||||
void leave_locked_tables_mode();
|
void leave_locked_tables_mode();
|
||||||
int decide_logging_format(TABLE_LIST *tables);
|
int decide_logging_format(TABLE_LIST *tables);
|
||||||
void binlog_invoker() { m_binlog_invoker= TRUE; }
|
|
||||||
bool need_binlog_invoker() { return m_binlog_invoker; }
|
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
||||||
void get_definer(LEX_USER *definer);
|
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
||||||
|
enum need_invoker need_binlog_invoker() { return m_binlog_invoker; }
|
||||||
|
void get_definer(LEX_USER *definer, bool role);
|
||||||
void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
|
void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
|
||||||
{
|
{
|
||||||
invoker_user= *user;
|
invoker_user= *user;
|
||||||
@ -3230,14 +3232,15 @@ private:
|
|||||||
Diagnostics_area main_da;
|
Diagnostics_area main_da;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
It will be set TURE if CURRENT_USER() is called in account management
|
It will be set if CURRENT_USER() or CURRENT_ROLE() is called in account
|
||||||
statements or default definer is set in CREATE/ALTER SP, SF, Event,
|
management statements or default definer is set in CREATE/ALTER SP, SF,
|
||||||
TRIGGER or VIEW statements.
|
Event, TRIGGER or VIEW statements.
|
||||||
|
|
||||||
Current user will be binlogged into Query_log_event if m_binlog_invoker
|
Current user or role will be binlogged into Query_log_event if
|
||||||
is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
|
m_binlog_invoker is not NONE; It will be stored into invoker_host and
|
||||||
|
invoker_user by SQL thread.
|
||||||
*/
|
*/
|
||||||
bool m_binlog_invoker;
|
enum need_invoker m_binlog_invoker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
It points to the invoker in the Query_log_event.
|
It points to the invoker in the Query_log_event.
|
||||||
|
@ -1840,7 +1840,7 @@ bool sp_process_definer(THD *thd)
|
|||||||
Query_arena original_arena;
|
Query_arena original_arena;
|
||||||
Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
|
Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
|
||||||
|
|
||||||
lex->definer= create_default_definer(thd);
|
lex->definer= create_default_definer(thd, false);
|
||||||
|
|
||||||
if (ps_arena)
|
if (ps_arena)
|
||||||
thd->restore_active_arena(ps_arena, &original_arena);
|
thd->restore_active_arena(ps_arena, &original_arena);
|
||||||
@ -1854,20 +1854,24 @@ bool sp_process_definer(THD *thd)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LEX_USER *d= lex->definer= get_current_user(thd, lex->definer);
|
||||||
|
if (!d)
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the specified definer differs from the current user, we
|
If the specified definer differs from the current user or role, we
|
||||||
should check that the current user has SUPER privilege (in order
|
should check that the current user has SUPER privilege (in order
|
||||||
to create a stored routine under another user one must have
|
to create a stored routine under another user one must have
|
||||||
SUPER privilege).
|
SUPER privilege).
|
||||||
*/
|
*/
|
||||||
if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
|
bool curuser= !strcmp(d->user.str, thd->security_ctx->priv_user);
|
||||||
my_strcasecmp(system_charset_info, lex->definer->host.str,
|
bool currole= !curuser && !strcmp(d->user.str, thd->security_ctx->priv_role);
|
||||||
thd->security_ctx->priv_host)) &&
|
bool curuserhost= curuser && d->host.str &&
|
||||||
check_global_access(thd, SUPER_ACL, true))
|
!my_strcasecmp(system_charset_info, d->host.str,
|
||||||
{
|
thd->security_ctx->priv_host);
|
||||||
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
|
if (!curuserhost && !currole &&
|
||||||
|
check_global_access(thd, SUPER_ACL, false))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the specified definer exists. Emit a warning if not. */
|
/* Check that the specified definer exists. Emit a warning if not. */
|
||||||
@ -3783,7 +3787,7 @@ end_with_restore_list:
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Replicate current user as grantor */
|
/* Replicate current user as grantor */
|
||||||
thd->binlog_invoker();
|
thd->binlog_invoker(false);
|
||||||
|
|
||||||
if (thd->security_ctx->user) // If not replication
|
if (thd->security_ctx->user) // If not replication
|
||||||
{
|
{
|
||||||
@ -7686,16 +7690,23 @@ Item *negate_expression(THD *thd, Item *expr)
|
|||||||
@param[out] definer definer
|
@param[out] definer definer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void get_default_definer(THD *thd, LEX_USER *definer)
|
void get_default_definer(THD *thd, LEX_USER *definer, bool role)
|
||||||
{
|
{
|
||||||
const Security_context *sctx= thd->security_ctx;
|
const Security_context *sctx= thd->security_ctx;
|
||||||
|
|
||||||
definer->user.str= (char *) sctx->priv_user;
|
if (role)
|
||||||
|
{
|
||||||
|
definer->user.str= const_cast<char*>(sctx->priv_role);
|
||||||
|
definer->host= empty_lex_str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
definer->user.str= const_cast<char*>(sctx->priv_user);
|
||||||
|
definer->host.str= const_cast<char*>(sctx->priv_host);
|
||||||
|
definer->host.length= strlen(definer->host.str);
|
||||||
|
}
|
||||||
definer->user.length= strlen(definer->user.str);
|
definer->user.length= strlen(definer->user.str);
|
||||||
|
|
||||||
definer->host.str= (char *) sctx->priv_host;
|
|
||||||
definer->host.length= strlen(definer->host.str);
|
|
||||||
|
|
||||||
definer->password= null_lex_str;
|
definer->password= null_lex_str;
|
||||||
definer->plugin= empty_lex_str;
|
definer->plugin= empty_lex_str;
|
||||||
definer->auth= empty_lex_str;
|
definer->auth= empty_lex_str;
|
||||||
@ -7713,16 +7724,22 @@ void get_default_definer(THD *thd, LEX_USER *definer)
|
|||||||
- On error, return 0.
|
- On error, return 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LEX_USER *create_default_definer(THD *thd)
|
LEX_USER *create_default_definer(THD *thd, bool role)
|
||||||
{
|
{
|
||||||
LEX_USER *definer;
|
LEX_USER *definer;
|
||||||
|
|
||||||
if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
|
if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
thd->get_definer(definer);
|
thd->get_definer(definer, role);
|
||||||
|
|
||||||
return definer;
|
if (role && definer->user.length == 0)
|
||||||
|
{
|
||||||
|
my_error(ER_MALFORMED_DEFINER, MYF(0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return definer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7757,27 +7774,6 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retuns information about user or current user.
|
|
||||||
|
|
||||||
@param[in] thd thread handler
|
|
||||||
@param[in] user user
|
|
||||||
|
|
||||||
@return
|
|
||||||
- On success, return a valid pointer to initialized
|
|
||||||
LEX_USER, which contains user information.
|
|
||||||
- On error, return 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
|
|
||||||
{
|
|
||||||
if (user->user.str == current_user.str) // current_user
|
|
||||||
return create_default_definer(thd);
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check that byte length of a string does not exceed some limit.
|
Check that byte length of a string does not exceed some limit.
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ Comp_creator *comp_ne_creator(bool invert);
|
|||||||
|
|
||||||
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||||
enum enum_schema_tables schema_table_idx);
|
enum enum_schema_tables schema_table_idx);
|
||||||
void get_default_definer(THD *thd, LEX_USER *definer);
|
void get_default_definer(THD *thd, LEX_USER *definer, bool role);
|
||||||
LEX_USER *create_default_definer(THD *thd);
|
LEX_USER *create_default_definer(THD *thd, bool role);
|
||||||
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
|
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
|
||||||
LEX_USER *get_current_user(THD *thd, LEX_USER *user);
|
LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock=true);
|
||||||
bool sp_process_definer(THD *thd);
|
bool sp_process_definer(THD *thd);
|
||||||
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
|
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
|
||||||
uint max_byte_length);
|
uint max_byte_length);
|
||||||
|
@ -2064,8 +2064,11 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
|
|||||||
{
|
{
|
||||||
buffer->append(STRING_WITH_LEN("DEFINER="));
|
buffer->append(STRING_WITH_LEN("DEFINER="));
|
||||||
append_identifier(thd, buffer, definer_user->str, definer_user->length);
|
append_identifier(thd, buffer, definer_user->str, definer_user->length);
|
||||||
buffer->append('@');
|
if (definer_host->str[0])
|
||||||
append_identifier(thd, buffer, definer_host->str, definer_host->length);
|
{
|
||||||
|
buffer->append('@');
|
||||||
|
append_identifier(thd, buffer, definer_host->str, definer_host->length);
|
||||||
|
}
|
||||||
buffer->append(' ');
|
buffer->append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,9 +763,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
|||||||
definer_user= lex->definer->user;
|
definer_user= lex->definer->user;
|
||||||
definer_host= lex->definer->host;
|
definer_host= lex->definer->host;
|
||||||
|
|
||||||
trg_definer->str= trg_definer_holder;
|
lex->definer->set_lex_string(trg_definer, trg_definer_holder);
|
||||||
trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@",
|
|
||||||
definer_host.str, NullS) - trg_definer->str;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -822,7 +822,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
view->file_version= 1;
|
view->file_version= 2;
|
||||||
view->calc_md5(md5);
|
view->calc_md5(md5);
|
||||||
if (!(view->md5.str= (char*) thd->memdup(md5, 32)))
|
if (!(view->md5.str= (char*) thd->memdup(md5, 32)))
|
||||||
{
|
{
|
||||||
@ -1113,8 +1113,16 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
|
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
|
||||||
table->db, table->table_name);
|
table->db, table->table_name);
|
||||||
get_default_definer(thd, &table->definer);
|
get_default_definer(thd, &table->definer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
since 10.0.5 definer.host can never be "" for a User, but it's
|
||||||
|
always "" for a Role. Before 10.0.5 it could be "" for a User,
|
||||||
|
but roles didn't exist. file_version helps.
|
||||||
|
*/
|
||||||
|
if (!table->definer.host.str[0] && table->file_version < 2)
|
||||||
|
table->definer.host= host_not_specified; // User, not Role
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize view definition context by character set names loaded from
|
Initialize view definition context by character set names loaded from
|
||||||
|
@ -13173,7 +13173,7 @@ user:
|
|||||||
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$$->user = $1;
|
$$->user = $1;
|
||||||
$$->host= host_not_specified;
|
$$->host= null_lex_str; // User or Role, see get_current_user()
|
||||||
$$->password= null_lex_str;
|
$$->password= null_lex_str;
|
||||||
$$->plugin= empty_lex_str;
|
$$->plugin= empty_lex_str;
|
||||||
$$->auth= empty_lex_str;
|
$$->auth= empty_lex_str;
|
||||||
@ -14351,7 +14351,7 @@ grant_role:
|
|||||||
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$$->user = $1;
|
$$->user = $1;
|
||||||
$$->host= host_not_specified;
|
$$->host= empty_lex_str;
|
||||||
$$->password= null_lex_str;
|
$$->password= null_lex_str;
|
||||||
$$->plugin= empty_lex_str;
|
$$->plugin= empty_lex_str;
|
||||||
$$->auth= empty_lex_str;
|
$$->auth= empty_lex_str;
|
||||||
@ -15044,9 +15044,9 @@ no_definer:
|
|||||||
;
|
;
|
||||||
|
|
||||||
definer:
|
definer:
|
||||||
DEFINER_SYM EQ user
|
DEFINER_SYM EQ user_or_role
|
||||||
{
|
{
|
||||||
thd->lex->definer= get_current_user(thd, $3);
|
thd->lex->definer= $3;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -190,6 +190,14 @@ typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
|
|||||||
|
|
||||||
typedef struct st_lex_user {
|
typedef struct st_lex_user {
|
||||||
LEX_STRING user, host, password, plugin, auth;
|
LEX_STRING user, host, password, plugin, auth;
|
||||||
|
bool is_role() { return user.str[0] && !host.str[0]; }
|
||||||
|
void set_lex_string(LEX_STRING *l, char *buf)
|
||||||
|
{
|
||||||
|
if (is_role())
|
||||||
|
*l= user;
|
||||||
|
else
|
||||||
|
l->length= strxmov(l->str= buf, user.str, "@", host.str, NullS) - buf;
|
||||||
|
}
|
||||||
} LEX_USER;
|
} LEX_USER;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user