Loading mysql-test/r/information_schema.result +42 −3 Original line number Diff line number Diff line show variables where variable_name like "skip_show_database"; Variable_name Value skip_show_database OFF grant all privileges on test.* to mysqltest_1@localhost; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; select * from information_schema.SCHEMATA where schema_name > 'm'; CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH NULL mysql latin1 NULL Loading Loading @@ -229,6 +230,44 @@ sel2 sel2 select count(*) from information_schema.ROUTINES; count(*) 2 select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION show create function sub1; ERROR 42000: FUNCTION sub1 does not exist select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 grant all privileges on test.* to mysqltest_1@localhost; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 create function sub2(i int) returns int return i+1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 sub2 return i+1 show create procedure sel2; Procedure sql_mode Create Procedure sel2 show create function sub1; Function sql_mode Create Function sub1 show create function sub2; Function sql_mode Create Function sub2 CREATE FUNCTION `test`.`sub2`(i int) RETURNS int return i+1 drop function sub2; show create procedure sel2; Procedure sql_mode Create Procedure sel2 CREATE PROCEDURE `test`.`sel2`() begin select * from t1; select * from t2; end create view v0 (c) as select schema_name from information_schema.schemata; select * from v0; c Loading Loading @@ -311,8 +350,8 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN 'mysqltest_1'@'localhost' NULL test t1 a INSERT NO 'mysqltest_1'@'localhost' NULL test t1 a UPDATE NO 'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; Loading mysql-test/t/information_schema.test +30 −7 Original line number Diff line number Diff line Loading @@ -3,7 +3,8 @@ # show databases show variables where variable_name like "skip_show_database"; grant all privileges on test.* to mysqltest_1@localhost; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; select * from information_schema.SCHEMATA where schema_name > 'm'; select schema_name from information_schema.schemata; Loading Loading @@ -104,6 +105,30 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8); select count(*) from information_schema.ROUTINES; connect (user1,localhost,mysqltest_1,,); connect (user3,localhost,mysqltest_2,,); connection user1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; --error 1305 show create function sub1; connection user3; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; connection default; grant all privileges on test.* to mysqltest_1@localhost; connect (user2,localhost,mysqltest_1,,); connection user2; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; create function sub2(i int) returns int return i+1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; show create procedure sel2; show create function sub1; show create function sub2; connection default; disconnect user1; drop function sub2; show create procedure sel2; # # Test for views # Loading Loading @@ -138,8 +163,8 @@ select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_ select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; Loading @@ -160,13 +185,11 @@ TABLE_SCHEMA= "test"; select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; connect (user1,localhost,mysqltest_1,,); connection user1; connection user2; select table_name from information_schema.TABLES where table_schema like "test%"; select table_name,column_name from information_schema.COLUMNS where table_schema like "test%"; select ROUTINE_NAME from information_schema.ROUTINES; disconnect user1; disconnect user2; connection default; delete from mysql.user where user='mysqltest_1'; drop table t1; Loading sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -453,6 +453,7 @@ bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name, bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, char *db, char *name); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool mysql_multi_update_prepare(THD *thd); Loading sql/sp_head.cc +33 −2 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,27 @@ sp_head::restore_thd_mem_root(THD *thd) } bool check_show_routine_acceess(THD *thd, sp_head *sp, bool *full_access) { TABLE_LIST tables; bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; tables.table_name= tables.alias= (char*) "proc"; *full_access= !check_table_access(thd, SELECT_ACL, &tables, 1); if (!(*full_access)) *full_access= (!strcmp(sp->m_definer_user.str, thd->priv_user) && !strcmp(sp->m_definer_host.str, thd->priv_host)); if (!(*full_access)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS return check_some_routine_access(thd, (char * )sp->m_db.str, (char * ) sp->m_name.str); #endif } return 0; } int sp_head::show_create_procedure(THD *thd) { Loading @@ -1016,12 +1037,16 @@ sp_head::show_create_procedure(THD *thd) sys_var *sql_mode_var; byte *sql_mode_str; ulong sql_mode_len; bool full_access; DBUG_ENTER("sp_head::show_create_procedure"); DBUG_PRINT("info", ("procedure %s", m_name.str)); LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); if (check_show_routine_acceess(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; thd->variables.sql_mode= m_sql_mode; sql_mode_var= find_sys_var("SQL_MODE", 8); Loading @@ -1047,6 +1072,7 @@ sp_head::show_create_procedure(THD *thd) protocol->store(m_name.str, m_name.length, system_charset_info); if (sql_mode_var) protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); if (full_access) protocol->store(m_defstr.str, m_defstr.length, system_charset_info); res= protocol->write(); send_eof(thd); Loading Loading @@ -1085,11 +1111,15 @@ sp_head::show_create_function(THD *thd) sys_var *sql_mode_var; byte *sql_mode_str; ulong sql_mode_len; bool full_access; DBUG_ENTER("sp_head::show_create_function"); DBUG_PRINT("info", ("procedure %s", m_name.str)); LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); if (check_show_routine_acceess(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; thd->variables.sql_mode= m_sql_mode; sql_mode_var= find_sys_var("SQL_MODE", 8); Loading @@ -1114,6 +1144,7 @@ sp_head::show_create_function(THD *thd) protocol->store(m_name.str, m_name.length, system_charset_info); if (sql_mode_var) protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); if (full_access) protocol->store(m_defstr.str, m_defstr.length, system_charset_info); res= protocol->write(); send_eof(thd); Loading sql/sql_acl.cc +31 −0 Original line number Diff line number Diff line Loading @@ -3583,6 +3583,37 @@ bool check_grant_procedure(THD *thd, ulong want_access, } /* Check if routine has any of the procedure level grants SYNPOSIS bool check_routine_level_acl() thd Thread handler db Database name name Routine name RETURN 1 error 0 Ok */ bool check_routine_level_acl(THD *thd, char *db, char *name) { bool no_routine_acl= 1; if (grant_option) { GRANT_NAME *grant_proc; rw_rdlock(&LOCK_grant); if ((grant_proc= proc_hash_search(thd->priv_host, thd->ip, db, thd->priv_user, name, 0))) no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); rw_unlock(&LOCK_grant); } return no_routine_acl; } /***************************************************************************** Functions to retrieve the grant for a table/column (for SHOW functions) *****************************************************************************/ Loading Loading
mysql-test/r/information_schema.result +42 −3 Original line number Diff line number Diff line show variables where variable_name like "skip_show_database"; Variable_name Value skip_show_database OFF grant all privileges on test.* to mysqltest_1@localhost; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; select * from information_schema.SCHEMATA where schema_name > 'm'; CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH NULL mysql latin1 NULL Loading Loading @@ -229,6 +230,44 @@ sel2 sel2 select count(*) from information_schema.ROUTINES; count(*) 2 select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION show create function sub1; ERROR 42000: FUNCTION sub1 does not exist select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 grant all privileges on test.* to mysqltest_1@localhost; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 create function sub2(i int) returns int return i+1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; ROUTINE_NAME ROUTINE_DEFINITION sel2 sub1 sub2 return i+1 show create procedure sel2; Procedure sql_mode Create Procedure sel2 show create function sub1; Function sql_mode Create Function sub1 show create function sub2; Function sql_mode Create Function sub2 CREATE FUNCTION `test`.`sub2`(i int) RETURNS int return i+1 drop function sub2; show create procedure sel2; Procedure sql_mode Create Procedure sel2 CREATE PROCEDURE `test`.`sel2`() begin select * from t1; select * from t2; end create view v0 (c) as select schema_name from information_schema.schemata; select * from v0; c Loading Loading @@ -311,8 +350,8 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN 'mysqltest_1'@'localhost' NULL test t1 a INSERT NO 'mysqltest_1'@'localhost' NULL test t1 a UPDATE NO 'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; Loading
mysql-test/t/information_schema.test +30 −7 Original line number Diff line number Diff line Loading @@ -3,7 +3,8 @@ # show databases show variables where variable_name like "skip_show_database"; grant all privileges on test.* to mysqltest_1@localhost; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; select * from information_schema.SCHEMATA where schema_name > 'm'; select schema_name from information_schema.schemata; Loading Loading @@ -104,6 +105,30 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8); select count(*) from information_schema.ROUTINES; connect (user1,localhost,mysqltest_1,,); connect (user3,localhost,mysqltest_2,,); connection user1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; --error 1305 show create function sub1; connection user3; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; connection default; grant all privileges on test.* to mysqltest_1@localhost; connect (user2,localhost,mysqltest_1,,); connection user2; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; create function sub2(i int) returns int return i+1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; show create procedure sel2; show create function sub1; show create function sub2; connection default; disconnect user1; drop function sub2; show create procedure sel2; # # Test for views # Loading Loading @@ -138,8 +163,8 @@ select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_ select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; Loading @@ -160,13 +185,11 @@ TABLE_SCHEMA= "test"; select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; connect (user1,localhost,mysqltest_1,,); connection user1; connection user2; select table_name from information_schema.TABLES where table_schema like "test%"; select table_name,column_name from information_schema.COLUMNS where table_schema like "test%"; select ROUTINE_NAME from information_schema.ROUTINES; disconnect user1; disconnect user2; connection default; delete from mysql.user where user='mysqltest_1'; drop table t1; Loading
sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -453,6 +453,7 @@ bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name, bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, char *db, char *name); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool mysql_multi_update_prepare(THD *thd); Loading
sql/sp_head.cc +33 −2 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,27 @@ sp_head::restore_thd_mem_root(THD *thd) } bool check_show_routine_acceess(THD *thd, sp_head *sp, bool *full_access) { TABLE_LIST tables; bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; tables.table_name= tables.alias= (char*) "proc"; *full_access= !check_table_access(thd, SELECT_ACL, &tables, 1); if (!(*full_access)) *full_access= (!strcmp(sp->m_definer_user.str, thd->priv_user) && !strcmp(sp->m_definer_host.str, thd->priv_host)); if (!(*full_access)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS return check_some_routine_access(thd, (char * )sp->m_db.str, (char * ) sp->m_name.str); #endif } return 0; } int sp_head::show_create_procedure(THD *thd) { Loading @@ -1016,12 +1037,16 @@ sp_head::show_create_procedure(THD *thd) sys_var *sql_mode_var; byte *sql_mode_str; ulong sql_mode_len; bool full_access; DBUG_ENTER("sp_head::show_create_procedure"); DBUG_PRINT("info", ("procedure %s", m_name.str)); LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); if (check_show_routine_acceess(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; thd->variables.sql_mode= m_sql_mode; sql_mode_var= find_sys_var("SQL_MODE", 8); Loading @@ -1047,6 +1072,7 @@ sp_head::show_create_procedure(THD *thd) protocol->store(m_name.str, m_name.length, system_charset_info); if (sql_mode_var) protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); if (full_access) protocol->store(m_defstr.str, m_defstr.length, system_charset_info); res= protocol->write(); send_eof(thd); Loading Loading @@ -1085,11 +1111,15 @@ sp_head::show_create_function(THD *thd) sys_var *sql_mode_var; byte *sql_mode_str; ulong sql_mode_len; bool full_access; DBUG_ENTER("sp_head::show_create_function"); DBUG_PRINT("info", ("procedure %s", m_name.str)); LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); if (check_show_routine_acceess(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; thd->variables.sql_mode= m_sql_mode; sql_mode_var= find_sys_var("SQL_MODE", 8); Loading @@ -1114,6 +1144,7 @@ sp_head::show_create_function(THD *thd) protocol->store(m_name.str, m_name.length, system_charset_info); if (sql_mode_var) protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); if (full_access) protocol->store(m_defstr.str, m_defstr.length, system_charset_info); res= protocol->write(); send_eof(thd); Loading
sql/sql_acl.cc +31 −0 Original line number Diff line number Diff line Loading @@ -3583,6 +3583,37 @@ bool check_grant_procedure(THD *thd, ulong want_access, } /* Check if routine has any of the procedure level grants SYNPOSIS bool check_routine_level_acl() thd Thread handler db Database name name Routine name RETURN 1 error 0 Ok */ bool check_routine_level_acl(THD *thd, char *db, char *name) { bool no_routine_acl= 1; if (grant_option) { GRANT_NAME *grant_proc; rw_rdlock(&LOCK_grant); if ((grant_proc= proc_hash_search(thd->priv_host, thd->ip, db, thd->priv_user, name, 0))) no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); rw_unlock(&LOCK_grant); } return no_routine_acl; } /***************************************************************************** Functions to retrieve the grant for a table/column (for SHOW functions) *****************************************************************************/ Loading