From 8822b30f1e258a5f0efc124043f42970e600c5d4 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Tue, 10 Oct 2017 23:39:48 +0300 Subject: [PATCH] MW-416 Replicating DDL after ACL check, 5.6 version Re-implemented the fix for MW-416 according to 5.7 version --- mysql-test/suite/galera/r/MW-416.result | 114 ++++++++++++++++++++ mysql-test/suite/galera/t/MW-416.test | 132 ++++++++++++++++++++++++ sql/events.cc | 15 +++ sql/sql_class.h | 1 + sql/sql_parse.cc | 7 -- sql/sql_plugin.cc | 19 +++- sql/sql_trigger.cc | 5 + sql/sql_view.cc | 5 + 8 files changed, 287 insertions(+), 11 deletions(-) create mode 100644 mysql-test/suite/galera/r/MW-416.result create mode 100644 mysql-test/suite/galera/t/MW-416.test diff --git a/mysql-test/suite/galera/r/MW-416.result b/mysql-test/suite/galera/r/MW-416.result new file mode 100644 index 00000000000..05399b213a8 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-416.result @@ -0,0 +1,114 @@ +CREATE USER 'userMW416'@'localhost'; +GRANT SELECT, INSERT, UPDATE ON test.* TO 'userMW416'@'localhost'; +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; +Variable_name Value +wsrep_replicated 2 +ALTER DATABASE db CHARACTER SET = utf8; +ERROR 42000: Access denied for user 'userMW416'@'localhost' to database 'db' +ALTER EVENT ev1 RENAME TO ev2; +ERROR 42000: Access denied for user 'userMW416'@'localhost' to database 'test' +ALTER FUNCTION fun1 COMMENT 'foo'; +ERROR 42000: alter routine command denied to user 'userMW416'@'localhost' for routine 'test.fun1' +ALTER LOGFILE GROUP lfg ADD UNDOFILE 'file' ENGINE=InnoDB; +Got one of the listed errors +ALTER PROCEDURE proc1 COMMENT 'foo'; +Got one of the listed errors +ALTER SERVER srv OPTIONS (USER 'sally'); +Got one of the listed errors +ALTER TABLE tbl DROP COLUMN col; +Got one of the listed errors +ALTER TABLESPACE tblspc DROP DATAFILE 'file' ENGINE=innodb; +Got one of the listed errors +ALTER VIEW vw AS SELECT 1; +Got one of the listed errors +CREATE DATABASE db; +Got one of the listed errors +CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP DO SELECT 1; +Got one of the listed errors +CREATE FUNCTION fun1() RETURNS int RETURN(1); +Got one of the listed errors +CREATE FUNCTION fun1 RETURNS STRING SONAME 'funlib.so'; +Got one of the listed errors +CREATE PROCEDURE proc1() BEGIN END; +Got one of the listed errors +CREATE INDEX idx ON tbl(id); +Got one of the listed errors +CREATE LOGFILE GROUP lfg ADD UNDOFILE 'undofile' ENGINE innodb; +Got one of the listed errors +CREATE SERVER srv FOREIGN DATA WRAPPER 'fdw' OPTIONS (USER 'user'); +Got one of the listed errors +CREATE TABLE t (i int); +Got one of the listed errors +CREATE TABLESPACE tblspc ADD DATAFILE 'file' ENGINE=innodb; +Got one of the listed errors +CREATE TRIGGER trg BEFORE UPDATE ON t FOR EACH ROW BEGIN END; +Got one of the listed errors +CREATE VIEW vw AS SELECT 1; +Got one of the listed errors +DROP DATABASE db; +Got one of the listed errors +DROP EVENT ev; +Got one of the listed errors +DROP FUNCTION fun1; +Got one of the listed errors +DROP INDEX idx ON t0; +Got one of the listed errors +DROP LOGFILE GROUP lfg; +Got one of the listed errors +DROP PROCEDURE proc1; +Got one of the listed errors +DROP SERVEr srv; +Got one of the listed errors +DROP TABLE t0; +Got one of the listed errors +DROP TABLESPACE tblspc; +Got one of the listed errors +DROP TRIGGER trg; +Got one of the listed errors +DROP VIEW vw; +Got one of the listed errors +RENAME TABLE t0 TO t1; +Got one of the listed errors +TRUNCATE TABLE t0; +Got one of the listed errors +ALTER USER myuser PASSWORD EXPIRE; +Got one of the listed errors +CREATE USER myuser IDENTIFIED BY 'pass'; +Got one of the listed errors +DROP USER myuser; +Got one of the listed errors +GRANT ALL ON *.* TO 'myuser'; +Got one of the listed errors +RENAME USER myuser TO mariauser; +Got one of the listed errors +REVOKE SELECT ON test FROM myuser; +Got one of the listed errors +REVOKE ALL, GRANT OPTION FROM myuser; +Got one of the listed errors +REVOKE PROXY ON myuser FROM myuser; +Got one of the listed errors +ANALYZE TABLE db.tbl; +Got one of the listed errors +CHECK TABLE db.tbl; +Got one of the listed errors +CHECKSUM TABLE db.tbl; +Got one of the listed errors +OPTIMIZE TABLE db.tbl; +Got one of the listed errors +REPAIR TABLE db.tbl; +Got one of the listed errors +INSTALL PLUGIN plg SONAME 'plg.so'; +Got one of the listed errors +UNINSTALL PLUGIN plg; +Got one of the listed errors +DROP USER 'userMW416'@'localhost'; +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +test +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; +Variable_name Value +wsrep_replicated 3 diff --git a/mysql-test/suite/galera/t/MW-416.test b/mysql-test/suite/galera/t/MW-416.test new file mode 100644 index 00000000000..ebc15438adc --- /dev/null +++ b/mysql-test/suite/galera/t/MW-416.test @@ -0,0 +1,132 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE USER 'userMW416'@'localhost'; +GRANT SELECT, INSERT, UPDATE ON test.* TO 'userMW416'@'localhost'; + +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; + +--connect userMW416, localhost, userMW416,, test, $NODE_MYPORT_1 +--connection userMW416 + +# DDL + +--error 1044 +ALTER DATABASE db CHARACTER SET = utf8; +--error 1044 +ALTER EVENT ev1 RENAME TO ev2; +--error 1370 +ALTER FUNCTION fun1 COMMENT 'foo'; +#--error 1044,1227 +#ALTER INSTANCE ROTATE INNODB MASTER KEY; +--error 1044,1227 +ALTER LOGFILE GROUP lfg ADD UNDOFILE 'file' ENGINE=InnoDB; +--error 1044,1227,1370 +ALTER PROCEDURE proc1 COMMENT 'foo'; +--error 1044,1227,1370 +ALTER SERVER srv OPTIONS (USER 'sally'); +--error 1044,1142,1227,1370 +ALTER TABLE tbl DROP COLUMN col; +--error 1044,1227,1370 +ALTER TABLESPACE tblspc DROP DATAFILE 'file' ENGINE=innodb; +--error 1044,1142,1227,1370 +ALTER VIEW vw AS SELECT 1; + +--error 1044,1227,1370 +CREATE DATABASE db; +--error 1044,1227,1370 +CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP DO SELECT 1; +--error 1044,1227,1370 +CREATE FUNCTION fun1() RETURNS int RETURN(1); +--error 1044,1227,1370 +CREATE FUNCTION fun1 RETURNS STRING SONAME 'funlib.so'; +--error 1044,1227,1370 +CREATE PROCEDURE proc1() BEGIN END; +--error 1044,1142,1227,1370 +CREATE INDEX idx ON tbl(id); +--error 1044,1142,1227,1370 +CREATE LOGFILE GROUP lfg ADD UNDOFILE 'undofile' ENGINE innodb; +--error 1044,1142,1227,1370 +CREATE SERVER srv FOREIGN DATA WRAPPER 'fdw' OPTIONS (USER 'user'); +--error 1044,1142,1227,1370 +CREATE TABLE t (i int); +--error 1044,1142,1227,1370 +CREATE TABLESPACE tblspc ADD DATAFILE 'file' ENGINE=innodb; +--error 1044,1142,1227,1370 +CREATE TRIGGER trg BEFORE UPDATE ON t FOR EACH ROW BEGIN END; +--error 1044,1142,1227,1370 +CREATE VIEW vw AS SELECT 1; + + + +--error 1044,1142,1227,1370 +DROP DATABASE db; +--error 1044,1142,1227,1370 +DROP EVENT ev; +--error 1044,1142,1227,1370 +DROP FUNCTION fun1; +--error 1044,1142,1227,1370 +DROP INDEX idx ON t0; +--error 1044,1142,1227,1370 +DROP LOGFILE GROUP lfg; +--error 1044,1142,1227,1370 +DROP PROCEDURE proc1; +--error 1044,1142,1227,1370 +DROP SERVEr srv; +--error 1044,1142,1227,1370 +DROP TABLE t0; +--error 1044,1142,1227,1370 +DROP TABLESPACE tblspc; +--error 1044,1142,1227,1360,1370 +DROP TRIGGER trg; +--error 1044,1142,1227,1370 +DROP VIEW vw; + +--error 1044,1142,1227,1370 +RENAME TABLE t0 TO t1; + +--error 1044,1142,1227,1370 +TRUNCATE TABLE t0; + +# DCL + +# account management +--error 1044,1142,1227,1370 +ALTER USER myuser PASSWORD EXPIRE; +--error 1044,1142,1227,1370 +CREATE USER myuser IDENTIFIED BY 'pass'; +--error 1044,1142,1227,1370 +DROP USER myuser; +--error 1044,1045,1142,1227,1370 +GRANT ALL ON *.* TO 'myuser'; +--error 1044,1142,1227,1370 +RENAME USER myuser TO mariauser; +--error 1044,1142,1227,1370 +REVOKE SELECT ON test FROM myuser; +--error 1044,1142,1227,1370,1698 +REVOKE ALL, GRANT OPTION FROM myuser; +--error 1044,1142,1227,1370,1698 +REVOKE PROXY ON myuser FROM myuser; + +# table maintenance +--error 1044,1142,1227,1370 +ANALYZE TABLE db.tbl; +--error 1044,1142,1227,1370 +CHECK TABLE db.tbl; +--error 1044,1142,1227,1370 +CHECKSUM TABLE db.tbl; +--error 1044,1142,1227,1370 +OPTIMIZE TABLE db.tbl; +--error 1044,1142,1227,1370 +REPAIR TABLE db.tbl; + +# plugin and user defined functions +--error 1044,1142,1227,1370 +INSTALL PLUGIN plg SONAME 'plg.so'; +--error 1044,1142,1227,1370 +UNINSTALL PLUGIN plg; + +--connection node_1 +DROP USER 'userMW416'@'localhost'; +SHOW DATABASES; +SHOW GLOBAL STATUS LIKE 'wsrep_replicated'; diff --git a/sql/events.cc b/sql/events.cc index 7aa7dae4d7f..a6379ec5a46 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -327,6 +327,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); if (check_db_dir_existence(parse_data->dbname.str)) { @@ -406,6 +407,10 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } @@ -446,6 +451,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); if (new_dbname) /* It's a rename */ { @@ -521,6 +527,10 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } @@ -560,6 +570,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) if (check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* Turn off row binlogging of this statement and use statement-based so @@ -585,6 +596,10 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) if (save_binlog_row_based) thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } diff --git a/sql/sql_class.h b/sql/sql_class.h index 8cfb3ced4b6..70bf6f7783d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2383,6 +2383,7 @@ public: enum wsrep_query_state wsrep_query_state; enum wsrep_conflict_state wsrep_conflict_state; mysql_mutex_t LOCK_wsrep_thd; + mysql_cond_t COND_wsrep_thd; // changed from wsrep_seqno_t to wsrep_trx_meta_t in wsrep API rev 75 // wsrep_seqno_t wsrep_trx_seqno; wsrep_trx_meta_t wsrep_trx_meta; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d102c6162d0..553a6e7539d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3825,7 +3825,6 @@ end_with_restore_list: if (res) break; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) switch (lex->sql_command) { case SQLCOM_CREATE_EVENT: { @@ -3861,7 +3860,6 @@ end_with_restore_list: lex->spname->m_name); break; case SQLCOM_DROP_EVENT: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res= Events::drop_event(thd, lex->spname->m_db, lex->spname->m_name, lex->drop_if_exists))) @@ -4773,7 +4771,6 @@ create_sp_error: Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands as specified through the thd->lex->create_view_mode flag. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); break; } @@ -4789,7 +4786,6 @@ create_sp_error: case SQLCOM_CREATE_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 1); break; @@ -4797,7 +4793,6 @@ create_sp_error: case SQLCOM_DROP_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 0); break; } @@ -4860,13 +4855,11 @@ create_sp_error: my_ok(thd); break; case SQLCOM_INSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_install_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); break; case SQLCOM_UNINSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index d4f497743b7..7e5c7c9c852 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2079,6 +2079,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, bool error; int argc=orig_argc; char **argv=orig_argv; + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = + { MYSQL_AUDIT_GENERAL_CLASSMASK }; DBUG_ENTER("mysql_install_plugin"); if (opt_noacl) @@ -2090,6 +2092,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE); if (check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* need to open before acquiring LOCK_plugin or it will deadlock */ if (! (table = open_ltable(thd, &tables, TL_WRITE, @@ -2123,8 +2126,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, See also mysql_uninstall_plugin() and initialize_audit_plugin() */ - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = - { MYSQL_AUDIT_GENERAL_CLASSMASK }; + mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); @@ -2155,6 +2157,10 @@ err: if (argv) free_defaults(argv); DBUG_RETURN(error); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } @@ -2221,6 +2227,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, TABLE_LIST tables; LEX_STRING dl= *dl_arg; bool error= false; + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = + { MYSQL_AUDIT_GENERAL_CLASSMASK }; DBUG_ENTER("mysql_uninstall_plugin"); if (opt_noacl) @@ -2233,6 +2241,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, if (check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* need to open before acquiring LOCK_plugin or it will deadlock */ if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) @@ -2259,8 +2268,6 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, See also mysql_install_plugin() and initialize_audit_plugin() */ - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = - { MYSQL_AUDIT_GENERAL_CLASSMASK }; mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); @@ -2290,6 +2297,10 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, mysql_mutex_unlock(&LOCK_plugin); DBUG_RETURN(error); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c562ee9762c..70ed6f0e600 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -501,6 +501,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (err_status) goto end; } + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); /* We should have only one table in table list. */ DBUG_ASSERT(tables->next_global == 0); @@ -605,6 +606,10 @@ end: my_ok(thd); DBUG_RETURN(result); +#ifdef WITH_WSREP + error: + DBUG_RETURN(TRUE); +#endif /* WITH_WSREP */ } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5bd82fdd842..f6948a76f6a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -429,6 +429,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if ((res= create_view_precheck(thd, tables, view, mode))) goto err; + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); lex->link_first_table_back(view, link_to_local); view->open_type= OT_BASE_ONLY; @@ -721,6 +722,10 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, lex->link_first_table_back(view, link_to_local); DBUG_RETURN(0); +#ifdef WITH_WSREP + error: + res= TRUE; +#endif /* WITH_WSREP */ err: thd_proc_info(thd, "end"); lex->link_first_table_back(view, link_to_local);