Commit 480506e1 authored by unknown's avatar unknown

Bug#10246 - Parser: bad syntax for GRANT EXECUTE

  Rename some functions
  more fine-grained sp privileges
  make grant/revoke sp grammar less ambigious


mysql-test/r/sp-security.result:
  change test for new syntax
mysql-test/r/system_mysql_db.result:
  change test for new syntax
mysql-test/t/sp-security.test:
  change test for new syntax
scripts/mysql_create_system_tables.sh:
  now store routine_type for procs_priv
scripts/mysql_fix_privilege_tables.sql:
  now store routine_type for procs_priv
sql/item_func.cc:
  rename of function
sql/mysql_priv.h:
  rename of function
sql/sp_head.cc:
  extra arg for check_some_routine_access
sql/sql_acl.cc:
  rename of function. now handle func/proc acls seperately
sql/sql_acl.h:
  rename of function
sql/sql_parse.cc:
  rename of function
  grants for procs handled distinctly from funcs
sql/sql_show.cc:
  check_some_routine_access extra arg
sql/sql_base.cc:
  fix for build
sql/sql_yacc.yy:
  fix for build
parent b51bd4ef
...@@ -23,10 +23,10 @@ root@localhost 1 ...@@ -23,10 +23,10 @@ root@localhost 1
select db(); select db();
db() db()
db1_secret db1_secret
grant execute on db1_secret.stamp to user1@'%'; grant execute on procedure db1_secret.stamp to user1@'%';
grant execute on db1_secret.db to user1@'%'; grant execute on function db1_secret.db to user1@'%';
grant execute on db1_secret.stamp to ''@'%'; grant execute on procedure db1_secret.stamp to ''@'%';
grant execute on db1_secret.db to ''@'%'; grant execute on function db1_secret.db to ''@'%';
call db1_secret.stamp(2); call db1_secret.stamp(2);
select db1_secret.db(); select db1_secret.db();
db1_secret.db() db1_secret.db()
...@@ -105,8 +105,8 @@ select * from t2; ...@@ -105,8 +105,8 @@ select * from t2;
s1 s1
0 0
2 2
grant usage on db2.q to user2@localhost with grant option; grant usage on procedure db2.q to user2@localhost with grant option;
grant execute on db2.q to user1@localhost; grant execute on procedure db2.q to user1@localhost;
use db2; use db2;
call q(); call q();
select * from t2; select * from t2;
...@@ -117,9 +117,9 @@ s1 ...@@ -117,9 +117,9 @@ s1
alter procedure p modifies sql data; alter procedure p modifies sql data;
drop procedure p; drop procedure p;
alter procedure q modifies sql data; alter procedure q modifies sql data;
ERROR 42000: alter procedure command denied to user 'user1'@'localhost' for routine 'db2.q' ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db2.q'
drop procedure q; drop procedure q;
ERROR 42000: alter procedure command denied to user 'user1'@'localhost' for routine 'db2.q' ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db2.q'
use db2; use db2;
alter procedure q modifies sql data; alter procedure q modifies sql data;
drop procedure q; drop procedure q;
...@@ -141,52 +141,52 @@ create database sptest; ...@@ -141,52 +141,52 @@ create database sptest;
create table t1 ( u varchar(64), i int ); create table t1 ( u varchar(64), i int );
create procedure sptest.p1(i int) insert into test.t1 values (user(), i); create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
grant insert on t1 to usera@localhost; grant insert on t1 to usera@localhost;
grant execute on sptest.p1 to usera@localhost; grant execute on procedure sptest.p1 to usera@localhost;
show grants for usera@localhost; show grants for usera@localhost;
Grants for usera@localhost Grants for usera@localhost
GRANT USAGE ON *.* TO 'usera'@'localhost' GRANT USAGE ON *.* TO 'usera'@'localhost'
GRANT INSERT ON `test`.`t1` TO 'usera'@'localhost' GRANT INSERT ON `test`.`t1` TO 'usera'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'usera'@'localhost' GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'usera'@'localhost'
grant execute on sptest.p1 to userc@localhost with grant option; grant execute on procedure sptest.p1 to userc@localhost with grant option;
show grants for userc@localhost; show grants for userc@localhost;
Grants for userc@localhost Grants for userc@localhost
GRANT USAGE ON *.* TO 'userc'@'localhost' GRANT USAGE ON *.* TO 'userc'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION
call sptest.p1(1); call sptest.p1(1);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: grant command denied to user 'usera'@'localhost' for routine 'sptest.p1' ERROR 42000: grant command denied to user 'usera'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'usera'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'usera'@'localhost' for routine 'sptest.p1'
call sptest.p1(2); call sptest.p1(2);
ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1'
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: execute command denied to user 'userb'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userb'@'localhost' for routine 'sptest.p1'
call sptest.p1(3); call sptest.p1(3);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userc'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userc'@'localhost' for routine 'sptest.p1'
call sptest.p1(4); call sptest.p1(4);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
ERROR 42000: grant command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: grant command denied to user 'userb'@'localhost' for routine 'sptest.p1'
drop procedure sptest.p1; drop procedure sptest.p1;
ERROR 42000: alter procedure command denied to user 'userb'@'localhost' for routine 'sptest.p1' ERROR 42000: alter routine command denied to user 'userb'@'localhost' for routine 'sptest.p1'
select * from t1; select * from t1;
u i u i
usera@localhost 1 usera@localhost 1
userc@localhost 3 userc@localhost 3
userb@localhost 4 userb@localhost 4
grant all privileges on sptest.p1 to userc@localhost; grant all privileges on procedure sptest.p1 to userc@localhost;
show grants for userc@localhost; show grants for userc@localhost;
Grants for userc@localhost Grants for userc@localhost
GRANT USAGE ON *.* TO 'userc'@'localhost' GRANT USAGE ON *.* TO 'userc'@'localhost'
GRANT EXECUTE, ALTER ROUTINE ON `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `sptest`.`p1` TO 'userc'@'localhost' WITH GRANT OPTION
show grants for userb@localhost; show grants for userb@localhost;
Grants for userb@localhost Grants for userb@localhost
GRANT USAGE ON *.* TO 'userb'@'localhost' GRANT USAGE ON *.* TO 'userb'@'localhost'
GRANT EXECUTE ON `sptest`.`p1` TO 'userb'@'localhost' GRANT EXECUTE ON PROCEDURE `sptest`.`p1` TO 'userb'@'localhost'
revoke all privileges on sptest.p1 from userb@localhost; revoke all privileges on procedure sptest.p1 from userb@localhost;
show grants for userb@localhost; show grants for userb@localhost;
Grants for userb@localhost Grants for userb@localhost
GRANT USAGE ON *.* TO 'userb'@'localhost' GRANT USAGE ON *.* TO 'userb'@'localhost'
......
...@@ -152,10 +152,11 @@ procs_priv CREATE TABLE `procs_priv` ( ...@@ -152,10 +152,11 @@ procs_priv CREATE TABLE `procs_priv` (
`Db` char(64) collate utf8_bin NOT NULL default '', `Db` char(64) collate utf8_bin NOT NULL default '',
`User` char(16) collate utf8_bin NOT NULL default '', `User` char(16) collate utf8_bin NOT NULL default '',
`Routine_name` char(64) collate utf8_bin NOT NULL default '', `Routine_name` char(64) collate utf8_bin NOT NULL default '',
`Routine_type` enum('FUNCTION','PROCEDURE') collate utf8_bin NOT NULL default 'FUNCTION',
`Grantor` char(77) collate utf8_bin NOT NULL default '', `Grantor` char(77) collate utf8_bin NOT NULL default '',
`Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '', `Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '',
PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`), `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`,`Routine_type`),
KEY `Grantor` (`Grantor`) KEY `Grantor` (`Grantor`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges'
show create table proc; show create table proc;
......
...@@ -43,10 +43,10 @@ call stamp(1); ...@@ -43,10 +43,10 @@ call stamp(1);
select * from t1; select * from t1;
select db(); select db();
grant execute on db1_secret.stamp to user1@'%'; grant execute on procedure db1_secret.stamp to user1@'%';
grant execute on db1_secret.db to user1@'%'; grant execute on function db1_secret.db to user1@'%';
grant execute on db1_secret.stamp to ''@'%'; grant execute on procedure db1_secret.stamp to ''@'%';
grant execute on db1_secret.db to ''@'%'; grant execute on function db1_secret.db to ''@'%';
connect (con2user1,localhost,user1,,); connect (con2user1,localhost,user1,,);
connect (con3anon,localhost,anon,,); connect (con3anon,localhost,anon,,);
...@@ -183,10 +183,10 @@ call q(); ...@@ -183,10 +183,10 @@ call q();
select * from t2; select * from t2;
connection con1root; connection con1root;
grant usage on db2.q to user2@localhost with grant option; grant usage on procedure db2.q to user2@localhost with grant option;
connection con4user2; connection con4user2;
grant execute on db2.q to user1@localhost; grant execute on procedure db2.q to user1@localhost;
connection con2user1; connection con2user1;
use db2; use db2;
...@@ -245,9 +245,9 @@ create database sptest; ...@@ -245,9 +245,9 @@ create database sptest;
create table t1 ( u varchar(64), i int ); create table t1 ( u varchar(64), i int );
create procedure sptest.p1(i int) insert into test.t1 values (user(), i); create procedure sptest.p1(i int) insert into test.t1 values (user(), i);
grant insert on t1 to usera@localhost; grant insert on t1 to usera@localhost;
grant execute on sptest.p1 to usera@localhost; grant execute on procedure sptest.p1 to usera@localhost;
show grants for usera@localhost; show grants for usera@localhost;
grant execute on sptest.p1 to userc@localhost with grant option; grant execute on procedure sptest.p1 to userc@localhost with grant option;
show grants for userc@localhost; show grants for userc@localhost;
connect (con2usera,localhost,usera,,); connect (con2usera,localhost,usera,,);
...@@ -257,7 +257,7 @@ connect (con4userc,localhost,userc,,); ...@@ -257,7 +257,7 @@ connect (con4userc,localhost,userc,,);
connection con2usera; connection con2usera;
call sptest.p1(1); call sptest.p1(1);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
...@@ -265,32 +265,32 @@ connection con3userb; ...@@ -265,32 +265,32 @@ connection con3userb;
--error 1370 --error 1370
call sptest.p1(2); call sptest.p1(2);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con4userc; connection con4userc;
call sptest.p1(3); call sptest.p1(3);
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con3userb; connection con3userb;
call sptest.p1(4); call sptest.p1(4);
--error 1370 --error 1370
grant execute on sptest.p1 to userb@localhost; grant execute on procedure sptest.p1 to userb@localhost;
--error 1370 --error 1370
drop procedure sptest.p1; drop procedure sptest.p1;
connection con1root; connection con1root;
select * from t1; select * from t1;
grant all privileges on sptest.p1 to userc@localhost; grant all privileges on procedure sptest.p1 to userc@localhost;
show grants for userc@localhost; show grants for userc@localhost;
show grants for userb@localhost; show grants for userb@localhost;
connection con4userc; connection con4userc;
revoke all privileges on sptest.p1 from userb@localhost; revoke all privileges on procedure sptest.p1 from userb@localhost;
connection con1root; connection con1root;
show grants for userb@localhost; show grants for userb@localhost;
......
...@@ -255,10 +255,11 @@ then ...@@ -255,10 +255,11 @@ then
c_pp="$c_pp Db char(64) binary DEFAULT '' NOT NULL," c_pp="$c_pp Db char(64) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp User char(16) binary DEFAULT '' NOT NULL," c_pp="$c_pp User char(16) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp Routine_name char(64) binary DEFAULT '' NOT NULL," c_pp="$c_pp Routine_name char(64) binary DEFAULT '' NOT NULL,"
c_pp="$c_pp Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,"
c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL," c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL,"
c_pp="$c_pp Timestamp timestamp(14),"
c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,"
c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name)," c_pp="$c_pp Timestamp timestamp(14),"
c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),"
c_pp="$c_pp KEY Grantor (Grantor)" c_pp="$c_pp KEY Grantor (Grantor)"
c_pp="$c_pp ) engine=MyISAM" c_pp="$c_pp ) engine=MyISAM"
c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin" c_pp="$c_pp CHARACTER SET utf8 COLLATE utf8_bin"
......
...@@ -67,6 +67,10 @@ ALTER TABLE tables_priv ...@@ -67,6 +67,10 @@ ALTER TABLE tables_priv
ALTER TABLE procs_priv ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE procs_priv ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
ALTER TABLE procs_priv ALTER TABLE procs_priv
modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL; modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL;
ALTER TABLE procs_priv
add Routine_type enum('FUNCTION','PROCEDURE') COLLATE utf8_general_ci NOT NULL AFTER Routine_name;
ALTER TABLE procs_priv
modify Timestamp timestamp(14) AFTER Proc_priv;
CREATE TABLE IF NOT EXISTS columns_priv ( CREATE TABLE IF NOT EXISTS columns_priv (
Host char(60) DEFAULT '' NOT NULL, Host char(60) DEFAULT '' NOT NULL,
...@@ -316,10 +320,11 @@ Host char(60) binary DEFAULT '' NOT NULL, ...@@ -316,10 +320,11 @@ Host char(60) binary DEFAULT '' NOT NULL,
Db char(64) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL,
User char(16) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL,
Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL,
Routine_type enum('FUNCTION','PROCEDURE') NOT NULL,
Grantor char(77) DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL,
Timestamp timestamp(14),
Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,
PRIMARY KEY (Host,Db,User,Routine_name), Timestamp timestamp(14),
PRIMARY KEY (Host,Db,User,Routine_name,Routine_type),
KEY Grantor (Grantor) KEY Grantor (Grantor)
) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; ) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
......
...@@ -4771,13 +4771,13 @@ Item_func_sp::execute(Item **itp) ...@@ -4771,13 +4771,13 @@ Item_func_sp::execute(Item **itp)
#endif #endif
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_procedure_access(thd, EXECUTE_ACL, if (check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0)) m_sp->m_db.str, m_sp->m_name.str, 0, 0))
DBUG_RETURN(-1); DBUG_RETURN(-1);
sp_change_security_context(thd, m_sp, &save_ctx); sp_change_security_context(thd, m_sp, &save_ctx);
if (save_ctx.changed && if (save_ctx.changed &&
check_procedure_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0)) m_sp->m_db.str, m_sp->m_name.str, 0, 0))
{ {
sp_restore_security_context(thd, m_sp, &save_ctx); sp_restore_security_context(thd, m_sp, &save_ctx);
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS; thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
......
...@@ -473,12 +473,12 @@ void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0, ...@@ -473,12 +473,12 @@ void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0,
TABLE *stopper= 0); TABLE *stopper= 0);
bool check_one_table_access(THD *thd, ulong privilege, bool check_one_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables); TABLE_LIST *tables);
bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name, bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
bool no_errors); bool is_proc, bool no_errors);
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
bool check_merge_table_access(THD *thd, char *db, bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list); TABLE_LIST *table_list);
bool check_some_routine_access(THD *thd, const char *db, const char *name); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
bool mysql_multi_update_prepare(THD *thd); bool mysql_multi_update_prepare(THD *thd);
......
...@@ -1111,7 +1111,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) ...@@ -1111,7 +1111,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
(!strcmp(sp->m_definer_user.str, thd->priv_user) && (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
!strcmp(sp->m_definer_host.str, thd->priv_host))); !strcmp(sp->m_definer_host.str, thd->priv_host)));
if (!*full_access) if (!*full_access)
return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str); return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
sp->m_type == TYPE_ENUM_PROCEDURE);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -185,7 +185,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, ...@@ -185,7 +185,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list, bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
List <LEX_COLUMN> &column_list, ulong rights, List <LEX_COLUMN> &column_list, ulong rights,
bool revoke); bool revoke);
bool mysql_procedure_grant(THD *thd, TABLE_LIST *table, bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
List <LEX_USER> &user_list, ulong rights, List <LEX_USER> &user_list, ulong rights,
bool revoke, bool no_error); bool revoke, bool no_error);
ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx); ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx);
...@@ -200,8 +200,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant, ...@@ -200,8 +200,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant,
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
const char* db_name, const char *table_name, const char* db_name, const char *table_name,
Field_iterator *fields); Field_iterator *fields);
bool check_grant_procedure(THD *thd, ulong want_access, bool check_grant_routine(THD *thd, ulong want_access,
TABLE_LIST *procs, bool no_error); TABLE_LIST *procs, bool is_proc, bool no_error);
bool check_grant_db(THD *thd,const char *db); bool check_grant_db(THD *thd,const char *db);
ulong get_table_grant(THD *thd, TABLE_LIST *table); ulong get_table_grant(THD *thd, TABLE_LIST *table);
ulong get_column_grant(THD *thd, GRANT_INFO *grant, ulong get_column_grant(THD *thd, GRANT_INFO *grant,
...@@ -216,9 +216,12 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list); ...@@ -216,9 +216,12 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list);
bool mysql_revoke_all(THD *thd, List <LEX_USER> &list); bool mysql_revoke_all(THD *thd, List <LEX_USER> &list);
void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table); const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name); bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name); bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name); bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name,
bool is_proc);
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E,F) 0 #define check_grant(A,B,C,D,E,F) 0
......
...@@ -3307,7 +3307,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, ...@@ -3307,7 +3307,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
0) 0)
{ {
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
table->real_name); table->s->table_name);
map->set_all(); map->set_all();
return 1; return 1;
} }
......
...@@ -3669,17 +3669,20 @@ mysql_execute_command(THD *thd) ...@@ -3669,17 +3669,20 @@ mysql_execute_command(THD *thd)
} }
if (first_table) if (first_table)
{ {
if (!lex->columns.elements && if (lex->type == TYPE_ENUM_PROCEDURE ||
sp_exists_routine(thd, all_tables, 1, 1)) lex->type == TYPE_ENUM_FUNCTION)
{ {
uint grants= lex->all_privileges uint grants= lex->all_privileges
? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL) ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
: lex->grant; : lex->grant;
if (grant_option && if (grant_option &&
check_grant_procedure(thd, grants | GRANT_ACL, all_tables, 0)) check_grant_routine(thd, grants | GRANT_ACL, all_tables,
lex->type == TYPE_ENUM_PROCEDURE, 0))
goto error; goto error;
res= mysql_procedure_grant(thd, all_tables, lex->users_list, res= mysql_routine_grant(thd, all_tables,
grants, lex->sql_command == SQLCOM_REVOKE,0); lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
lex->sql_command == SQLCOM_REVOKE, 0);
} }
else else
{ {
...@@ -3701,7 +3704,7 @@ mysql_execute_command(THD *thd) ...@@ -3701,7 +3704,7 @@ mysql_execute_command(THD *thd)
} }
else else
{ {
if (lex->columns.elements) if (lex->columns.elements || lex->type)
{ {
my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
MYF(0)); MYF(0));
...@@ -3983,11 +3986,13 @@ mysql_execute_command(THD *thd) ...@@ -3983,11 +3986,13 @@ mysql_execute_command(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* only add privileges if really neccessary */ /* only add privileges if really neccessary */
if (sp_automatic_privileges && if (sp_automatic_privileges &&
check_procedure_access(thd, DEFAULT_CREATE_PROC_ACLS, check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
db, name, 1)) db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
{ {
close_thread_tables(thd); close_thread_tables(thd);
if (sp_grant_privileges(thd, db, name)) if (sp_grant_privileges(thd, db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_GRANT_FAIL, ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL)); ER(ER_PROC_AUTO_GRANT_FAIL));
...@@ -4072,8 +4077,8 @@ mysql_execute_command(THD *thd) ...@@ -4072,8 +4077,8 @@ mysql_execute_command(THD *thd)
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_procedure_access(thd, EXECUTE_ACL, if (check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, 0)) sp->m_db.str, sp->m_name.str, TRUE, 0))
{ {
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
...@@ -4082,8 +4087,8 @@ mysql_execute_command(THD *thd) ...@@ -4082,8 +4087,8 @@ mysql_execute_command(THD *thd)
} }
sp_change_security_context(thd, sp, &save_ctx); sp_change_security_context(thd, sp, &save_ctx);
if (save_ctx.changed && if (save_ctx.changed &&
check_procedure_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, 0)) sp->m_db.str, sp->m_name.str, TRUE, 0))
{ {
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
...@@ -4185,8 +4190,9 @@ mysql_execute_command(THD *thd) ...@@ -4185,8 +4190,9 @@ mysql_execute_command(THD *thd)
} }
else else
{ {
if (check_procedure_access(thd, ALTER_PROC_ACL, sp->m_db.str, if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
sp->m_name.str, 0)) sp->m_name.str,
lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
goto error; goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (!trust_routine_creators && mysql_bin_log.is_open() && if (!trust_routine_creators && mysql_bin_log.is_open() &&
...@@ -4244,11 +4250,13 @@ mysql_execute_command(THD *thd) ...@@ -4244,11 +4250,13 @@ mysql_execute_command(THD *thd)
{ {
db= thd->strdup(sp->m_db.str); db= thd->strdup(sp->m_db.str);
name= thd->strdup(sp->m_name.str); name= thd->strdup(sp->m_name.str);
if (check_procedure_access(thd, ALTER_PROC_ACL, db, name, 0)) if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
goto error; goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (sp_automatic_privileges && if (sp_automatic_privileges &&
sp_revoke_privileges(thd, db, name)) sp_revoke_privileges(thd, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE))
{ {
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_REVOKE_FAIL, ER_PROC_AUTO_REVOKE_FAIL,
...@@ -4832,8 +4840,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, ...@@ -4832,8 +4840,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
bool bool
check_procedure_access(THD *thd, ulong want_access,char *db, char *name, check_routine_access(THD *thd, ulong want_access,char *db, char *name,
bool no_errors) bool is_proc, bool no_errors)
{ {
TABLE_LIST tables[1]; TABLE_LIST tables[1];
...@@ -4849,7 +4857,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name, ...@@ -4849,7 +4857,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (grant_option) if (grant_option)
return check_grant_procedure(thd, want_access, tables, no_errors); return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
#endif #endif
return FALSE; return FALSE;
...@@ -4870,7 +4878,8 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name, ...@@ -4870,7 +4878,8 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
1 error 1 error
*/ */
bool check_some_routine_access(THD *thd, const char *db, const char *name) bool check_some_routine_access(THD *thd, const char *db, const char *name,
bool is_proc)
{ {
ulong save_priv; ulong save_priv;
if (thd->master_access & SHOW_PROC_ACLS) if (thd->master_access & SHOW_PROC_ACLS)
...@@ -4878,7 +4887,7 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name) ...@@ -4878,7 +4887,7 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name)
if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) || if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) ||
(save_priv & SHOW_PROC_ACLS)) (save_priv & SHOW_PROC_ACLS))
return FALSE; return FALSE;
return check_routine_level_acl(thd, db, name); return check_routine_level_acl(thd, db, name, is_proc);
} }
......
...@@ -2625,7 +2625,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, ...@@ -2625,7 +2625,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
definer= get_field(thd->mem_root, proc_table->field[11]); definer= get_field(thd->mem_root, proc_table->field[11]);
if (!full_access) if (!full_access)
full_access= !strcmp(sp_user, definer); full_access= !strcmp(sp_user, definer);
if (!full_access && check_some_routine_access(thd, sp_db, sp_name)) if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
return 0; return 0;
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
......
...@@ -804,7 +804,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -804,7 +804,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_delete_options opt_delete_option varchar nchar nvarchar opt_delete_options opt_delete_option varchar nchar nvarchar
opt_outer table_list table_name opt_option opt_place opt_outer table_list table_name opt_option opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges opt_table grant_list grant_option opt_column_list grant_privileges grant_ident grant_list grant_option
object_privilege object_privilege_list user_list rename_list object_privilege object_privilege_list user_list rename_list
clear_privileges flush_options flush_option clear_privileges flush_options flush_option
equal optional_braces opt_key_definition key_usage_list2 equal optional_braces opt_key_definition key_usage_list2
...@@ -3994,6 +3994,7 @@ select_options: ...@@ -3994,6 +3994,7 @@ select_options:
YYABORT; YYABORT;
} }
} }
;
select_option_list: select_option_list:
select_option_list select_option select_option_list select_option
...@@ -7906,9 +7907,36 @@ revoke: ...@@ -7906,9 +7907,36 @@ revoke:
; ;
revoke_command: revoke_command:
grant_privileges ON opt_table FROM grant_list grant_privileges ON opt_table grant_ident FROM grant_list
{ {
Lex->sql_command = SQLCOM_REVOKE; LEX *lex= Lex;
lex->sql_command= SQLCOM_REVOKE;
lex->type= 0;
}
|
grant_privileges ON FUNCTION_SYM grant_ident FROM grant_list
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_REVOKE;
lex->type= TYPE_ENUM_FUNCTION;
}
|
grant_privileges ON PROCEDURE grant_ident FROM grant_list
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_REVOKE;
lex->type= TYPE_ENUM_PROCEDURE;
} }
| |
ALL opt_privileges ',' GRANT OPTION FROM grant_list ALL opt_privileges ',' GRANT OPTION FROM grant_list
...@@ -7918,11 +7946,50 @@ revoke_command: ...@@ -7918,11 +7946,50 @@ revoke_command:
; ;
grant: grant:
GRANT clear_privileges grant_privileges ON opt_table TO_SYM grant_list GRANT clear_privileges grant_command
{}
;
grant_command:
grant_privileges ON opt_table grant_ident TO_SYM grant_list
require_clause grant_options require_clause grant_options
{ Lex->sql_command= SQLCOM_GRANT; } {
LEX *lex= Lex;
lex->sql_command= SQLCOM_GRANT;
lex->type= 0;
}
|
grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
require_clause grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_GRANT;
lex->type= TYPE_ENUM_FUNCTION;
}
|
grant_privileges ON PROCEDURE grant_ident TO_SYM grant_list
require_clause grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
lex->sql_command= SQLCOM_GRANT;
lex->type= TYPE_ENUM_PROCEDURE;
}
; ;
opt_table:
/* Empty */
| TABLE_SYM ;
grant_privileges: grant_privileges:
object_privilege_list { } object_privilege_list { }
| ALL opt_privileges | ALL opt_privileges
...@@ -8015,7 +8082,7 @@ require_list_element: ...@@ -8015,7 +8082,7 @@ require_list_element:
} }
; ;
opt_table: grant_ident:
'*' '*'
{ {
LEX *lex= Lex; LEX *lex= Lex;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment