mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
456 lines
11 KiB
Text
456 lines
11 KiB
Text
# create view
|
|
# create trigger
|
|
# create procedure
|
|
# create event
|
|
# mysqldump dumping the definer
|
|
|
|
source include/not_embedded.inc;
|
|
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
|
|
create user foo@localhost;
|
|
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;
|
|
|
|
create user role4;
|
|
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
|
|
|
|
flush tables;
|
|
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;
|
|
|
|
--echo #
|
|
--echo # MDEV-13676: Field "create Procedure" is NULL, even if the the user
|
|
--echo # has role which is the definer. (SHOW CREATE PROCEDURE)
|
|
--echo #
|
|
|
|
create database rtest;
|
|
create role r1;
|
|
create role r2;
|
|
create role r3;
|
|
grant all privileges on rtest.* to r1;
|
|
|
|
create user user1;
|
|
grant r1 to user1;
|
|
grant r1 to r2;
|
|
grant r2 to user1;
|
|
grant r3 to user1;
|
|
|
|
connect (user1, localhost,user1,,,,,);
|
|
set role r2;
|
|
use rtest;
|
|
|
|
DELIMITER //;
|
|
CREATE DEFINER=current_role() PROCEDURE user1_proc() SQL SECURITY INVOKER
|
|
BEGIN
|
|
SELECT NOW(), VERSION();
|
|
END;//
|
|
DELIMITER ;//
|
|
|
|
set role r2;
|
|
show create procedure user1_proc;
|
|
|
|
--echo #
|
|
--echo # Currently one can not use as definer any role except CURRENT_ROLE
|
|
--echo #
|
|
DELIMITER //;
|
|
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
|
|
CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
|
|
BEGIN
|
|
SELECT NOW(), VERSION();
|
|
END;//
|
|
DELIMITER ;//
|
|
|
|
set role r1;
|
|
DELIMITER //;
|
|
CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
|
|
BEGIN
|
|
SELECT NOW(), VERSION();
|
|
END;//
|
|
DELIMITER ;//
|
|
|
|
show create procedure user1_proc2;
|
|
--echo #
|
|
--echo # Test to see if the user can still see the procedure code if the
|
|
--echo # role that owns it is granted to him indirectly.
|
|
--echo #
|
|
set role r2;
|
|
show create procedure user1_proc2;
|
|
|
|
--echo #
|
|
--echo # One should not be able to see the procedure code if the role that owns
|
|
--echo # the procedure is not set by the user or is not in the subgraph of the
|
|
--echo # currently active role.
|
|
--echo #
|
|
set role r3;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
show create procedure user1_proc2;
|
|
|
|
connection default;
|
|
|
|
use rtest;
|
|
|
|
--echo #
|
|
--echo # Try a few edge cases, with usernames identical to role name;
|
|
--echo #
|
|
|
|
create user user_like_role;
|
|
create user foo;
|
|
create role user_like_role;
|
|
grant select on rtest.* to user_like_role;
|
|
grant select on rtest.* to foo;
|
|
grant select on rtest.* to user_like_role@'%';
|
|
|
|
grant user_like_role to foo;
|
|
|
|
--echo #
|
|
--echo # Here we have a procedure that is owned by user_like_role USER
|
|
--echo # We don't want user_like_role ROLE to have access to its code.
|
|
--echo #
|
|
DELIMITER //;
|
|
CREATE DEFINER=`user_like_role`@`%` PROCEDURE sensitive_proc() SQL SECURITY INVOKER
|
|
BEGIN
|
|
SELECT NOW(), VERSION();
|
|
END;//
|
|
DELIMITER ;//
|
|
|
|
connect (user_like_role, localhost, user_like_role,,,,,);
|
|
use rtest;
|
|
show create procedure sensitive_proc;
|
|
|
|
connect (foo, localhost, foo,,,,,);
|
|
set role user_like_role;
|
|
use rtest;
|
|
|
|
--echo #
|
|
--echo # Foo has the set rolename identical to the procedure's definer's username.
|
|
--echo # Foo should not have access to this procedure.
|
|
--echo #
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
show create procedure sensitive_proc;
|
|
|
|
connection default;
|
|
drop role r1;
|
|
drop role r2;
|
|
drop role r3;
|
|
drop role user_like_role;
|
|
drop user user1;
|
|
drop user foo;
|
|
drop user user_like_role;
|
|
drop procedure user1_proc;
|
|
drop procedure user1_proc2;
|
|
drop procedure sensitive_proc;
|
|
drop database rtest;
|