Commit 72025253 authored by Alexander Nozdrin's avatar Alexander Nozdrin

Backporting patches for Bug#38347 (ALTER ROUTINE privilege

allows SHOW CREATE TABLE) from 6.0. Original revisions:
------------------------------------------------------------
revno: 2617.31.8
committer: Alexander Nozdrin <alik@sun.com>
branch nick: 6.0-rt-bug38347
timestamp: Thu 2009-03-26 09:08:24 +0300
message:
  Patch for Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
  
  If a user has any of the following privileges for a table (or the database
  if the table), he should be able to issue SHOW CREATE TABLE for the table:
    - CREATE
    - DROP
    - ALTER
    - DELETE
    - INDEX
    - INSERT
    - SELECT
    - UPDATE
    - TRIGGER
    - REFERENCES
    - GRANT OPTION
    - CREATE VIEW
    - SHOW VIEW
  
  Any other privilege (even SUPER) should not allow SHOW CREATE TABLE.
------------------------------------------------------------
revno: 2617.31.11
committer: Alexander Nozdrin <alik@sun.com>
branch nick: 6.0-rt
timestamp: Fri 2009-03-27 21:36:34 +0300
message:
  Additional patch for Bug#38347 (ALTER ROUTINE privilege
  allows SHOW CREATE TABLE).
  
  The problem was that information_schema.test,
  information_schema_parameters.test and information_schema_routines.test
  failed with the first patch. That happened due to limitation in check_access():
  it allows only SELECT_ACL privilege for INFORMATION_SCHEMA tables.
  
  The patch is to request only SELECT_ACL privilege for INFORMATION_SCHEMA tables.
------------------------------------------------------------
parent 481066db
--echo
SHOW GRANTS FOR mysqltest_u1@localhost;
--echo
--echo # connection: con1 (mysqltest_u1@mysqltest_db1)
--connect (con1,localhost,mysqltest_u1,,mysqltest_db1)
--connection con1
--echo
SHOW CREATE TABLE t1;
--echo
--echo # connection: default
--connection default
--disconnect con1
--echo
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost;
SHOW GRANTS FOR mysqltest_u1@localhost;
This diff is collapsed.
...@@ -1556,3 +1556,326 @@ disconnect conn1; ...@@ -1556,3 +1556,326 @@ disconnect conn1;
# Wait till we reached the initial number of concurrent sessions # Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
--echo #########################################################################
--echo #
--echo # Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
--echo #
--echo #########################################################################
--echo
--echo # --
--echo # -- Prepare the environment.
--echo # --
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
--disable_warnings
DROP DATABASE IF EXISTS mysqltest_db1;
--enable_warnings
CREATE DATABASE mysqltest_db1;
CREATE TABLE mysqltest_db1.t1(a INT);
--echo
--echo # --
--echo # -- Check that global privileges don't allow SHOW CREATE TABLE.
--echo # --
GRANT EVENT ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT CREATE TEMPORARY TABLES ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT LOCK TABLES ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT ALTER ROUTINE ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT CREATE ROUTINE ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT EXECUTE ON mysqltest_db1.* TO mysqltest_u1@localhost;
GRANT FILE ON *.* TO mysqltest_u1@localhost;
GRANT CREATE USER ON *.* TO mysqltest_u1@localhost;
GRANT PROCESS ON *.* TO mysqltest_u1@localhost;
GRANT RELOAD ON *.* TO mysqltest_u1@localhost;
GRANT REPLICATION CLIENT ON *.* TO mysqltest_u1@localhost;
GRANT REPLICATION SLAVE ON *.* TO mysqltest_u1@localhost;
GRANT SHOW DATABASES ON *.* TO mysqltest_u1@localhost;
GRANT SHUTDOWN ON *.* TO mysqltest_u1@localhost;
GRANT USAGE ON *.* TO mysqltest_u1@localhost;
--echo
SHOW GRANTS FOR mysqltest_u1@localhost;
--echo
--echo # connection: con1 (mysqltest_u1@mysqltest_db1)
--connect (con1,localhost,mysqltest_u1,,mysqltest_db1)
--connection con1
--echo
--error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE t1;
--echo
--echo # connection: default
--connection default
--disconnect con1
--echo
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost;
SHOW GRANTS FOR mysqltest_u1@localhost;
--echo
--echo # --
--echo # -- Check that global SELECT allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT SELECT ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global INSERT allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT INSERT ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global UPDATE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT UPDATE ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global DELETE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT DELETE ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global CREATE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT CREATE ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global DROP allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT DROP ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global ALTER allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT ALTER ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global INDEX allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT INDEX ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global REFERENCES allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT REFERENCES ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global GRANT OPTION allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT GRANT OPTION ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global CREATE VIEW allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT CREATE VIEW ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that global SHOW VIEW allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT SHOW VIEW ON mysqltest_db1.* TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level SELECT allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level INSERT allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT INSERT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level UPDATE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level DELETE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT DELETE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level CREATE allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT CREATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level DROP allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT DROP ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level ALTER allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT ALTER ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level INDEX allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT INDEX ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level REFERENCES allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT REFERENCES ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level GRANT OPTION allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT GRANT OPTION ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level CREATE VIEW allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT CREATE VIEW ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Check that table-level SHOW VIEW allows SHOW CREATE TABLE.
--echo # --
--echo
GRANT SHOW VIEW ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
--source include/bug38347.inc
--echo
--echo # --
--echo # -- Cleanup.
--echo # --
--echo
DROP DATABASE mysqltest_db1;
DROP USER mysqltest_u1@localhost;
--echo
--echo # End of Bug#38347.
--echo
...@@ -85,6 +85,11 @@ ...@@ -85,6 +85,11 @@
#define DEFAULT_CREATE_PROC_ACLS \ #define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL) (ALTER_PROC_ACL | EXECUTE_ACL)
#define SHOW_CREATE_TABLE_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \
CREATE_ACL | DROP_ACL | ALTER_ACL | INDEX_ACL | \
TRIGGER_ACL | REFERENCES_ACL | GRANT_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL)
/* /*
Defines to change the above bits to how things are stored in tables Defines to change the above bits to how things are stored in tables
This is needed as the 'host' and 'db' table is missing a few privileges This is needed as the 'host' and 'db' table is missing a few privileges
......
...@@ -2990,18 +2990,41 @@ end_with_restore_list: ...@@ -2990,18 +2990,41 @@ end_with_restore_list:
else else
{ {
ulong save_priv; ulong save_priv;
if (check_access(thd, SELECT_ACL, first_table->db,
/*
If it is an INFORMATION_SCHEMA table, SELECT_ACL privilege is the
only privilege allowed. For any other privilege check_access()
reports an error. That's how internal implementation protects
INFORMATION_SCHEMA from updates.
For ordinary tables any privilege from the SHOW_CREATE_TABLE_ACLS
set is sufficient.
*/
ulong check_privs= test(first_table->schema_table) ?
SELECT_ACL : SHOW_CREATE_TABLE_ACLS;
if (check_access(thd, check_privs, first_table->db,
&save_priv, FALSE, FALSE, &save_priv, FALSE, FALSE,
test(first_table->schema_table))) test(first_table->schema_table)))
goto error; goto error;
/* /*
save_priv contains any privileges actually granted by check_access. save_priv contains any privileges actually granted by check_access
If there are no global privileges (save_priv == 0) and no table level (i.e. save_priv contains global (user- and database-level)
privileges, access is denied. privileges).
The fact that check_access() returned FALSE does not mean that
access is granted. We need to check if save_priv contains any
table-specific privilege. If not, we need to check table-level
privileges.
If there are no global privileges and no table-level privileges,
access is denied.
*/ */
if (!save_priv &&
!has_any_table_level_privileges(thd, TABLE_ACLS, if (!(save_priv & (SHOW_CREATE_TABLE_ACLS)) &&
first_table)) !has_any_table_level_privileges(thd, SHOW_CREATE_TABLE_ACLS, first_table))
{ {
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"SHOW", thd->security_ctx->priv_user, "SHOW", thd->security_ctx->priv_user,
...@@ -3010,9 +3033,7 @@ end_with_restore_list: ...@@ -3010,9 +3033,7 @@ end_with_restore_list:
} }
} }
/* /* Access is granted. Execute the command. */
Access is granted. Execute command.
*/
res= mysqld_show_create(thd, first_table); res= mysqld_show_create(thd, first_table);
break; break;
} }
......
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