diff options
author | Alexander Barkov <bar@mariadb.com> | 2020-02-05 12:43:17 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2020-02-08 21:35:35 +0400 |
commit | 77c6382312535991d26c85e7eb5492f9b3a59e92 (patch) | |
tree | efcbf3c238aa8b67165031b5c7d9266c0082e7b4 | |
parent | 06b0623adb71f2b7918f69ab68660ec45736ebb5 (diff) | |
download | mariadb-git-77c6382312535991d26c85e7eb5492f9b3a59e92.tar.gz |
MDEV-21689 Add Sql_cmd for GRANT/REVOKE statements
Rewriting GRANT/REVOKE grammar to use more bison stack and use Sql_cmd_ style
1. Removing a few members from LEX:
- uint grant, grant_to_col, which_columns
- List<LEX_COLUMN> columns
- bool all_privileges
2. Adding classes Grand_object_name, Lex_grant_object_name
3. Adding classes Grand_privilege, Lex_grand_privilege
4. Adding struct Lex_column_list_privilege_st, class Lex_column_list_privilege
5. Rewriting the GRANT/REVOKE grammar to use new classes and pass them through
bison stack (rather than directly access LEX members)
6. Adding classes Sql_cmd_grant* and Sql_cmd_revoke*,
changing GRANT/REVOKE to use LEX::m_sql_cmd.
7. Adding the "sp_handler" grammar rule and removing some duplicate grammar
for GRANT/REVOKE for different kinds of SP objects.
8. Adding a new rule comma_separated_ident_list, reusing it in:
- with_column_list
- colum_list_privilege
-rw-r--r-- | libmysqld/CMakeLists.txt | 3 | ||||
-rw-r--r-- | sql/CMakeLists.txt | 1 | ||||
-rw-r--r-- | sql/grant.cc | 108 | ||||
-rw-r--r-- | sql/grant.h | 96 | ||||
-rw-r--r-- | sql/lex_string.h | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 221 | ||||
-rw-r--r-- | sql/sql_acl.h | 76 | ||||
-rw-r--r-- | sql/sql_cte.cc | 4 | ||||
-rw-r--r-- | sql/sql_cte.h | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 74 | ||||
-rw-r--r-- | sql/sql_lex.h | 70 | ||||
-rw-r--r-- | sql/sql_parse.cc | 109 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 360 |
13 files changed, 813 insertions, 317 deletions
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index d03abc5c378..f9eba7d7713 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -47,7 +47,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/password.c ../sql/discover.cc ../sql/derror.cc ../sql/field.cc ../sql/field_conv.cc ../sql/field_comp.cc ../sql/filesort_utils.cc ../sql/sql_digest.cc - ../sql/filesort.cc ../sql/gstream.cc ../sql/slave.cc + ../sql/filesort.cc ../sql/grant.cc + ../sql/gstream.cc ../sql/slave.cc ../sql/signal_handler.cc ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 23c66576b19..da046d0ec3a 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -129,6 +129,7 @@ SET (SQL_SOURCE sql_reload.cc # added in MariaDB: + grant.cc sql_explain.cc sql_analyze_stmt.cc sql_join_cache.cc diff --git a/sql/grant.cc b/sql/grant.cc new file mode 100644 index 00000000000..d4bbaa7b1f3 --- /dev/null +++ b/sql/grant.cc @@ -0,0 +1,108 @@ +/* + Copyright (c) 2009, 2020, MariaDB Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#include "mariadb.h" +#include "sql_acl.h" + + +bool Grant_privilege::add_column_privilege(THD *thd, + const Lex_ident_sys &name, + uint which_grant) +{ + String *new_str= new (thd->mem_root) String((const char*) name.str, + name.length, + system_charset_info); + if (unlikely(new_str == NULL)) + return true; + List_iterator <LEX_COLUMN> iter(m_columns); + class LEX_COLUMN *point; + while ((point=iter++)) + { + if (!my_strcasecmp(system_charset_info, + point->column.c_ptr(), new_str->c_ptr())) + break; + } + m_column_privilege_total|= which_grant; + if (point) + { + point->rights |= which_grant; + return false; + } + + LEX_COLUMN *col= new (thd->mem_root) LEX_COLUMN(*new_str, which_grant); + if (unlikely(col == NULL)) + return true; + return m_columns.push_back(col, thd->mem_root); +} + + +bool Grant_privilege::add_column_list_privilege(THD *thd, + List<Lex_ident_sys> &list, + uint privilege) +{ + Lex_ident_sys *col; + List_iterator<Lex_ident_sys> it(list); + while ((col= it++)) + { + if (add_column_privilege(thd, *col, privilege)) + return true; + } + return false; +} + + +uint Grant_object_name::all_privileges_by_type() const +{ + switch (m_type) { + case STAR: return DB_ACLS & ~GRANT_ACL; + case IDENT_STAR: return DB_ACLS & ~GRANT_ACL; + case STAR_STAR: return GLOBAL_ACLS & ~GRANT_ACL; + case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL; + } + return 0; +} + + +bool Grant_privilege::set_object_name(THD *thd, + const Grant_object_name &ident, + SELECT_LEX *sel, + uint with_grant_option) +{ + DBUG_ASSERT(!m_all_privileges || !m_columns.elements); + + m_db= ident.m_db; + if (m_all_privileges) + m_object_privilege= ident.all_privileges_by_type(); + m_object_privilege|= with_grant_option; + switch (ident.m_type) + { + case Lex_grant_object_name::STAR: + case Lex_grant_object_name::IDENT_STAR: + case Lex_grant_object_name::STAR_STAR: + if (!m_all_privileges && m_columns.elements) + { + // e.g. GRANT SELECT (a) ON db.* + my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + return true; + } + return false; + case Lex_grant_object_name::TABLE_IDENT: + m_db= ident.m_table_ident->db; + return !sel->add_table_to_list(thd, ident.m_table_ident, + NULL, TL_OPTION_UPDATING); + } + return false; // Make gcc happy +} diff --git a/sql/grant.h b/sql/grant.h new file mode 100644 index 00000000000..18b39ea0719 --- /dev/null +++ b/sql/grant.h @@ -0,0 +1,96 @@ +/* + Copyright (c) 2020, MariaDB Corporation. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + +#ifndef SQL_GRANT_INCLUDED +#define SQL_GRANT_INCLUDED + +#include "lex_string.h" + +class LEX_COLUMN; +class Lex_ident_sys; +class Table_ident; + +/* + Represents the object name in this standard SQL grammar: + GRANT <object privileges> ON <object name> +*/ +class Grant_object_name +{ +public: + enum Type + { + STAR, // ON * + IDENT_STAR, // ON db.* + STAR_STAR, // ON *.* + TABLE_IDENT // ON db.name + }; + Lex_cstring m_db; + Table_ident *m_table_ident; + Type m_type; +public: + Grant_object_name(Table_ident *table_ident) + :m_table_ident(table_ident), + m_type(TABLE_IDENT) + { } + Grant_object_name(const LEX_CSTRING &db, Type type) + :m_db(db), + m_table_ident(NULL), + m_type(type) + { } + uint all_privileges_by_type() const; +}; + + + +/* + Represents standard SQL statements described by: + - <grant privilege statement> + - <revoke privilege statement> +*/ +class Grant_privilege +{ +protected: + List<LEX_COLUMN> m_columns; + Lex_cstring m_db; + uint m_object_privilege; + uint m_column_privilege_total; + bool m_all_privileges; +public: + Grant_privilege() + :m_object_privilege(0), m_column_privilege_total(0), m_all_privileges(false) + { } + Grant_privilege(uint privilege, bool all_privileges) + :m_object_privilege(privilege), + m_column_privilege_total(0), + m_all_privileges(all_privileges) + { } + void add_object_privilege(uint privilege) + { + m_object_privilege|= privilege; + } + bool add_column_privilege(THD *thd, const Lex_ident_sys &col, + uint privilege); + bool add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list, + uint privilege); + bool set_object_name(THD *thd, + const Grant_object_name &ident, + SELECT_LEX *sel, + uint with_grant_option); + const List<LEX_COLUMN> & columns() const { return m_columns; } +}; + + +#endif // SQL_GRANT_INCLUDED diff --git a/sql/lex_string.h b/sql/lex_string.h index a62609c6b60..008e5f75812 100644 --- a/sql/lex_string.h +++ b/sql/lex_string.h @@ -30,6 +30,10 @@ class Lex_cstring : public LEX_CSTRING str= NULL; length= 0; } + Lex_cstring(const LEX_CSTRING &str) + { + LEX_CSTRING::operator=(str); + } Lex_cstring(const char *_str, size_t _len) { str= _str; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 67263386706..7bdee80d596 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -11656,6 +11656,227 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool) { return 0; } #endif /*NO_EMBEDDED_ACCESS_CHECKS */ + +#ifdef NO_EMBEDDED_ACCESS_CHECKS + +bool Sql_cmd_grant_proxy::execute(THD *thd) +{ + my_ok(thd); + return false; +} + +bool Sql_cmd_grant_table::execute(THD *thd) +{ + my_ok(thd); + return false; +} + + +bool Sql_cmd_grant_sp::execute(THD *thd) +{ + my_ok(thd); + return false; +} + +#else // not NO_EMBEDDED_ACCESS_CHECKS + + +void Sql_cmd_grant::warn_hostname_requires_resolving(THD *thd, + List<LEX_USER> &users) +{ + LEX_USER *user; + List_iterator <LEX_USER> it(users); + while ((user= it++)) + { + if (specialflag & SPECIAL_NO_RESOLVE && + hostname_requires_resolving(user->host.str)) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WARN_HOSTNAME_WONT_WORK, + ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK)); + } +} + + +void Sql_cmd_grant::grant_stage0(THD *thd) +{ + thd->binlog_invoker(false); // Replicate current user as grantor + if (thd->security_ctx->user) // If not replication + warn_hostname_requires_resolving(thd, thd->lex->users_list); +} + + +bool Sql_cmd_grant::user_list_reset_mqh(THD *thd, List<LEX_USER> &users) +{ + List_iterator <LEX_USER> it(users); + LEX_USER *user, *tmp_user; + while ((tmp_user= it++)) + { + if (!(user= get_current_user(thd, tmp_user))) + return true; + reset_mqh(user, 0); + } + return false; +} + + +bool Sql_cmd_grant_proxy::check_access_proxy(THD *thd, List<LEX_USER> &users) +{ + LEX_USER *user; + List_iterator <LEX_USER> it(users); + if ((user= it++)) + { + // GRANT/REVOKE PROXY has the target user as a first entry in the list + if (!(user= get_current_user(thd, user)) || !user->host.str) + return true; + if (acl_check_proxy_grant_access(thd, user->host.str, user->user.str, + m_grant_option & GRANT_ACL)) + return true; + } + return false; +} + + +bool Sql_cmd_grant_proxy::execute(THD *thd) +{ + LEX *lex= thd->lex; + + DBUG_ASSERT(lex->first_select_lex()->table_list.first == NULL); + DBUG_ASSERT((m_grant_option & ~GRANT_ACL) == 0); // only WITH GRANT OPTION + + grant_stage0(thd); + + if (thd->security_ctx->user /* If not replication */ && + check_access_proxy(thd, lex->users_list)) + return true; + + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + /* Conditionally writes to binlog */ + if (mysql_grant(thd, NULL/*db*/, lex->users_list, m_grant_option, + is_revoke(), true/*proxy*/)) + return true; + + return !is_revoke() && user_list_reset_mqh(thd, lex->users_list); + +#ifdef WITH_WSREP +wsrep_error_label: + return true; +#endif // WITH_WSREP +} + + +bool Sql_cmd_grant_object::grant_stage0_exact_object(THD *thd, + TABLE_LIST *table) +{ + uint priv= m_object_privilege | m_column_privilege_total | GRANT_ACL; + if (check_access(thd, priv, table->db.str, + &table->grant.privilege, &table->grant.m_internal, + 0, 0)) + return true; + grant_stage0(thd); + return false; +} + + +bool Sql_cmd_grant_table::execute_exact_table(THD *thd, TABLE_LIST *table) +{ + LEX *lex= thd->lex; + if (grant_stage0_exact_object(thd, table) || + check_grant(thd, m_object_privilege | m_column_privilege_total | GRANT_ACL, + lex->query_tables, FALSE, UINT_MAX, FALSE)) + return true; + /* Conditionally writes to binlog */ + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + return mysql_table_grant(thd, lex->query_tables, lex->users_list, + m_columns, m_object_privilege, + is_revoke()); +#ifdef WITH_WSREP +wsrep_error_label: + return true; +#endif // WITH_WSREP +} + + +bool Sql_cmd_grant_sp::execute(THD *thd) +{ + DBUG_ASSERT(!m_columns.elements); + DBUG_ASSERT(!m_column_privilege_total); + LEX *lex= thd->lex; + TABLE_LIST *table= lex->first_select_lex()->table_list.first; + uint grants= m_all_privileges + ? (PROC_ACLS & ~GRANT_ACL) | (m_object_privilege & GRANT_ACL) + : m_object_privilege; + + if (!table) // e.g: GRANT EXECUTE ON PROCEDURE *.* + { + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); + return true; + } + + if (grant_stage0_exact_object(thd, table) || + check_grant_routine(thd, grants|GRANT_ACL, lex->query_tables, &m_sph, 0)) + return true; + + /* Conditionally writes to binlog */ + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + if (mysql_routine_grant(thd, lex->query_tables, &m_sph, + lex->users_list, grants, + is_revoke(), true)) + return true; + my_ok(thd); + return false; +#ifdef WITH_WSREP +wsrep_error_label: + return true; +#endif // WITH_WSREP +} + + +bool Sql_cmd_grant_table::execute_table_mask(THD *thd) +{ + LEX *lex= thd->lex; + DBUG_ASSERT(lex->first_select_lex()->table_list.first == NULL); + + if (check_access(thd, m_object_privilege | m_column_privilege_total | GRANT_ACL, + m_db.str, NULL, NULL, 1, 0)) + return true; + + grant_stage0(thd); + + if (m_columns.elements) // e.g. GRANT SELECT (a) ON *.* + { + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); + return true; + } + + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); + /* Conditionally writes to binlog */ + if (mysql_grant(thd, m_db.str, lex->users_list, m_object_privilege, + is_revoke(), false/*not proxy*/)) + return true; + + return !is_revoke() && user_list_reset_mqh(thd, lex->users_list); + +#ifdef WITH_WSREP +wsrep_error_label: + return true; +#endif // WITH_WSREP +} + + +bool Sql_cmd_grant_table::execute(THD *thd) +{ + TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first; + return table ? execute_exact_table(thd, table) : + execute_table_mask(thd); +} + + +#endif // NO_EMBEDDED_ACCESS_CHECKS + + + SHOW_VAR acl_statistics[] = { #ifndef NO_EMBEDDED_ACCESS_CHECKS {"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC}, diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 7989367ec44..4147981bb98 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -19,6 +19,8 @@ #include "violite.h" /* SSL_type */ #include "sql_class.h" /* LEX_COLUMN */ +#include "grant.h" +#include "sql_cmd.h" /* Sql_cmd */ #define SELECT_ACL (1UL << 0) #define INSERT_ACL (1UL << 1) @@ -435,4 +437,78 @@ bool check_role_is_granted(const char *username, extern ulong role_global_merges, role_db_merges, role_table_merges, role_column_merges, role_routine_merges; #endif + + +class Sql_cmd_grant: public Sql_cmd +{ +protected: + enum_sql_command m_command; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + void warn_hostname_requires_resolving(THD *thd, List<LEX_USER> &list); + bool user_list_reset_mqh(THD *thd, List<LEX_USER> &list); + void grant_stage0(THD *thd); +#endif +public: + Sql_cmd_grant(enum_sql_command command) + :m_command(command) + { } + bool is_revoke() const { return m_command == SQLCOM_REVOKE; } + enum_sql_command sql_command_code() const { return m_command; } +}; + + +class Sql_cmd_grant_proxy: public Sql_cmd_grant +{ + uint m_grant_option; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool check_access_proxy(THD *thd, List<LEX_USER> &list); +#endif +public: + Sql_cmd_grant_proxy(enum_sql_command command, uint grant_option) + :Sql_cmd_grant(command), m_grant_option(grant_option) + { } + bool execute(THD *thd); +}; + + +class Sql_cmd_grant_object: public Sql_cmd_grant, public Grant_privilege +{ +protected: +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool grant_stage0_exact_object(THD *thd, TABLE_LIST *table); +#endif +public: + Sql_cmd_grant_object(enum_sql_command command, const Grant_privilege &grant) + :Sql_cmd_grant(command), Grant_privilege(grant) + { } +}; + + +class Sql_cmd_grant_table: public Sql_cmd_grant_object +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + bool execute_table_mask(THD *thd); + bool execute_exact_table(THD *thd, TABLE_LIST *table); +#endif +public: + Sql_cmd_grant_table(enum_sql_command command, const Grant_privilege &grant) + :Sql_cmd_grant_object(command, grant) + { } + bool execute(THD *thd); +}; + + + +class Sql_cmd_grant_sp: public Sql_cmd_grant_object +{ + const Sp_handler &m_sph; +public: + Sql_cmd_grant_sp(enum_sql_command command, const Grant_privilege &grant, + const Sp_handler &sph) + :Sql_cmd_grant_object(command, grant), + m_sph(sph) + { } + bool execute(THD *thd); +}; + #endif /* SQL_ACL_INCLUDED */ diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 5b3d3108da5..c7a0f9186e2 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -956,7 +956,7 @@ With_element::rename_columns_of_derived_unit(THD *thd, if (column_list.elements) // The column list is optional { List_iterator_fast<Item> it(select->item_list); - List_iterator_fast<LEX_CSTRING> nm(column_list); + List_iterator_fast<Lex_ident_sys> nm(column_list); Item *item; LEX_CSTRING *name; @@ -1442,7 +1442,7 @@ void With_element::print(String *str, enum_query_type query_type) str->append(query_name); if (column_list.elements) { - List_iterator_fast<LEX_CSTRING> li(column_list); + List_iterator_fast<Lex_ident_sys> li(column_list); str->append('('); for (LEX_CSTRING *col_name= li++; ; ) { diff --git a/sql/sql_cte.h b/sql/sql_cte.h index 80d56644d7e..92aca5090f3 100644 --- a/sql/sql_cte.h +++ b/sql/sql_cte.h @@ -111,7 +111,7 @@ public: inherited from the query that specified the table. Otherwise the list is always empty. */ - List <LEX_CSTRING> column_list; + List <Lex_ident_sys> column_list; /* The query that specifies the table introduced by this with element */ st_select_lex_unit *spec; /* @@ -163,7 +163,7 @@ public: SQL_I_List<TABLE_LIST> derived_with_rec_ref; With_element(LEX_CSTRING *name, - List <LEX_CSTRING> list, + List <Lex_ident_sys> list, st_select_lex_unit *unit) : next(NULL), base_dep_map(0), derived_dep_map(0), sq_dep_map(0), work_dep_map(0), mutually_recursive(0), diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 65fbd5a0ede..cbd2e953d7b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9009,16 +9009,13 @@ bool LEX::create_package_finalize(THD *thd, } -bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg, - stored_procedure_type type_arg) +bool LEX::add_grant_command(THD *thd, const List<LEX_COLUMN> &columns) { if (columns.elements) { thd->parse_error(); return true; } - sql_command= sql_command_arg, - type= type_arg; return false; } @@ -11239,3 +11236,72 @@ bool LEX::add_column_foreign_key(const LEX_CSTRING *name, return false; } + + +bool LEX::stmt_grant_table(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + uint grant_option) +{ + sql_command= SQLCOM_GRANT; + return + grant->set_object_name(thd, ident, current_select, grant_option) || + !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_table(sql_command, *grant)); +} + + +bool LEX::stmt_revoke_table(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident) +{ + sql_command= SQLCOM_REVOKE; + return + grant->set_object_name(thd, ident, current_select, 0) || + !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_table(sql_command, *grant)); +} + + +bool LEX::stmt_grant_sp(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + const Sp_handler &sph, + uint grant_option) +{ + sql_command= SQLCOM_GRANT; + return + grant->set_object_name(thd, ident, current_select, grant_option) || + add_grant_command(thd, grant->columns()) || + !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command, + *grant, sph)); +} + + +bool LEX::stmt_revoke_sp(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + const Sp_handler &sph) +{ + sql_command= SQLCOM_REVOKE; + return + grant->set_object_name(thd, ident, current_select, 0) || + add_grant_command(thd, grant->columns()) || + !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command, + *grant, sph)); +} + + +bool LEX::stmt_grant_proxy(THD *thd, LEX_USER *user, uint grant_option) +{ + users_list.push_front(user); + sql_command= SQLCOM_GRANT; + return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_proxy(sql_command, + grant_option)); +} + + +bool LEX::stmt_revoke_proxy(THD *thd, LEX_USER *user) +{ + users_list.push_front(user); + sql_command= SQLCOM_REVOKE; + return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_proxy(sql_command, 0)); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 308bebd9fa1..ad1bd6adfa2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -25,6 +25,7 @@ #include "sql_trigger.h" #include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */ #include "mem_root_array.h" +#include "grant.h" #include "sql_cmd.h" #include "sql_alter.h" // Alter_info #include "sql_window.h" @@ -183,6 +184,24 @@ public: }; +struct Lex_column_list_privilege_st +{ + List<Lex_ident_sys> *m_columns; + uint m_privilege; +}; + + +class Lex_column_list_privilege: public Lex_column_list_privilege_st +{ +public: + Lex_column_list_privilege(List<Lex_ident_sys> *columns, uint privilege) + { + m_columns= columns; + m_privilege= privilege; + } +}; + + /** ORDER BY ... LIMIT parameters; */ @@ -3091,6 +3110,28 @@ public: }; +class Lex_grant_object_name: public Grant_object_name, public Sql_alloc +{ +public: + Lex_grant_object_name(Table_ident *table_ident) + :Grant_object_name(table_ident) + { } + Lex_grant_object_name(const LEX_CSTRING &db, Type type) + :Grant_object_name(db, type) + { } +}; + + +class Lex_grant_privilege: public Grant_privilege, public Sql_alloc +{ +public: + Lex_grant_privilege() {} + Lex_grant_privilege(uint grant, bool all_privileges= false) + :Grant_privilege(grant, all_privileges) + { } +}; + + struct LEX: public Query_tables_list { SELECT_LEX_UNIT unit; /* most upper unit */ @@ -3187,7 +3228,6 @@ public: Table_type table_type; /* Used for SHOW CREATE */ List<Key_part_spec> ref_list; List<LEX_USER> users_list; - List<LEX_COLUMN> columns; List<Item> *insert_list,field_list,value_list,update_list; List<List_item> many_values; List<set_var_base> var_list; @@ -3309,7 +3349,6 @@ public: uint profile_query_id; uint profile_options; - uint grant, grant_tot_col, which_columns; enum backup_stages backup_stage; enum Foreign_key::fk_match_opt fk_match_option; enum_fk_option fk_update_opt; @@ -3362,7 +3401,6 @@ public: sp_head *sphead; sp_name *spname; bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling - bool all_privileges; sp_pcontext *spcont; @@ -4374,8 +4412,30 @@ public: bool add_create_view(THD *thd, DDL_options_st ddl, uint16 algorithm, enum_view_suid suid, Table_ident *table_ident); - bool add_grant_command(THD *thd, enum_sql_command sql_command_arg, - stored_procedure_type type_arg); + bool add_grant_command(THD *thd, const List<LEX_COLUMN> &columns); + + bool stmt_grant_table(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + uint grant_option); + + bool stmt_revoke_table(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident); + + bool stmt_grant_sp(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + const Sp_handler &sph, + uint grant_option); + + bool stmt_revoke_sp(THD *thd, + Grant_privilege *grant, + const Lex_grant_object_name &ident, + const Sp_handler &sph); + + bool stmt_grant_proxy(THD *thd, LEX_USER *user, uint grant_option); + bool stmt_revoke_proxy(THD *thd, LEX_USER *user); Vers_parse_info &vers_get_info() { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a586dd9107c..ab8af4e9b96 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5261,113 +5261,6 @@ mysql_execute_command(THD *thd) my_ok(thd); break; } - case SQLCOM_REVOKE: - case SQLCOM_GRANT: - { - if (lex->type != TYPE_ENUM_PROXY && - check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, - first_table ? first_table->db.str : select_lex->db.str, - first_table ? &first_table->grant.privilege : NULL, - first_table ? &first_table->grant.m_internal : NULL, - first_table ? 0 : 1, 0)) - goto error; - - /* Replicate current user as grantor */ - thd->binlog_invoker(false); - - if (thd->security_ctx->user) // If not replication - { - LEX_USER *user; - bool first_user= TRUE; - - List_iterator <LEX_USER> user_list(lex->users_list); - while ((user= user_list++)) - { - if (specialflag & SPECIAL_NO_RESOLVE && - hostname_requires_resolving(user->host.str)) - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WARN_HOSTNAME_WONT_WORK, - ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK)); - - /* - GRANT/REVOKE PROXY has the target user as a first entry in the list. - */ - if (lex->type == TYPE_ENUM_PROXY && first_user) - { - if (!(user= get_current_user(thd, user)) || !user->host.str) - goto error; - - first_user= FALSE; - if (acl_check_proxy_grant_access (thd, user->host.str, user->user.str, - lex->grant & GRANT_ACL)) - goto error; - } - } - } - if (first_table) - { - const Sp_handler *sph= Sp_handler::handler((stored_procedure_type) - lex->type); - if (sph) - { - uint grants= lex->all_privileges - ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL) - : lex->grant; - if (check_grant_routine(thd, grants | GRANT_ACL, all_tables, sph, 0)) - goto error; - /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); - res= mysql_routine_grant(thd, all_tables, sph, - lex->users_list, grants, - lex->sql_command == SQLCOM_REVOKE, TRUE); - if (!res) - my_ok(thd); - } - else - { - if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL), - all_tables, FALSE, UINT_MAX, FALSE)) - goto error; - /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); - res= mysql_table_grant(thd, all_tables, lex->users_list, - lex->columns, lex->grant, - lex->sql_command == SQLCOM_REVOKE); - } - } - else - { - if (lex->columns.elements || (lex->type && lex->type != TYPE_ENUM_PROXY)) - { - my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE), - MYF(0)); - goto error; - } - else - { - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); - /* Conditionally writes to binlog */ - res= mysql_grant(thd, select_lex->db.str, lex->users_list, lex->grant, - lex->sql_command == SQLCOM_REVOKE, - lex->type == TYPE_ENUM_PROXY); - } - if (!res) - { - if (lex->sql_command == SQLCOM_GRANT) - { - List_iterator <LEX_USER> str_list(lex->users_list); - LEX_USER *user, *tmp_user; - while ((tmp_user=str_list++)) - { - if (!(user= get_current_user(thd, tmp_user))) - goto error; - reset_mqh(user, 0); - } - } - } - } - break; - } case SQLCOM_REVOKE_ROLE: case SQLCOM_GRANT_ROLE: { @@ -5955,6 +5848,8 @@ mysql_execute_command(THD *thd) case SQLCOM_RESIGNAL: case SQLCOM_GET_DIAGNOSTICS: case SQLCOM_CALL: + case SQLCOM_REVOKE: + case SQLCOM_GRANT: DBUG_ASSERT(lex->m_sql_cmd != NULL); res= lex->m_sql_cmd->execute(thd); DBUG_PRINT("result", ("res: %d killed: %d is_error: %d", diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 332ef6c8aca..53551567b51 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -191,12 +191,14 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)() ulonglong ulonglong_number; longlong longlong_number; uint sp_instr_addr; + uint privilege; /* structs */ LEX_CSTRING lex_str; Lex_ident_cli_st kwd; Lex_ident_cli_st ident_cli; Lex_ident_sys_st ident_sys; + Lex_column_list_privilege_st column_list_privilege; Lex_string_with_metadata_st lex_string_with_metadata; Lex_spblock_st spblock; Lex_spblock_handlers_st spblock_handlers; @@ -224,10 +226,12 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)() Lex_order_limit_lock *order_limit_lock; /* pointers */ + Lex_ident_sys *ident_sys_ptr; Create_field *create_field; Spvar_definition *spvar_definition; Row_definition_list *spvar_definition_list; const Type_handler *type_handler; + const class Sp_handler *sp_handler; CHARSET_INFO *charset; Condition_information_item *cond_info_item; DYNCALL_CREATE_DEF *dyncol_def; @@ -250,7 +254,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)() List<sp_assignment_lex> *sp_assignment_lex_list; List<Statement_information_item> *stmt_info_list; List<String> *string_list; - List<LEX_CSTRING> *lex_str_list; + List<Lex_ident_sys> *ident_sys_list; Statement_information_item *stmt_info_item; String *string; TABLE_LIST *table_list; @@ -259,6 +263,8 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)() char *simple_string; const char *const_simple_string; chooser_compare_func_creator boolfunc2creator; + class Lex_grant_privilege *lex_grant; + class Lex_grant_object_name *lex_grant_ident; class my_var *myvar; class sp_condition_value *spcondvalue; class sp_head *sphead; @@ -1294,6 +1300,9 @@ End SQL_MODE_ORACLE_SPECIFIC */ ident_cli ident_cli_set_usual_case +%type <ident_sys_ptr> + ident_sys_alloc + %type <kwd> keyword_data_type keyword_cast_type @@ -1336,6 +1345,8 @@ End SQL_MODE_ORACLE_SPECIFIC */ %type <type_handler> int_type real_type +%type <sp_handler> sp_handler + %type <Lex_field_type> type_with_opt_collate field_type field_type_numeric field_type_string @@ -1346,6 +1357,9 @@ End SQL_MODE_ORACLE_SPECIFIC */ %type <Lex_dyncol_type> opt_dyncol_type dyncol_type numeric_dyncol_type temporal_dyncol_type string_dyncol_type +%type <column_list_privilege> + column_list_privilege + %type <create_field> field_spec column_def %type <num> @@ -1383,6 +1397,21 @@ End SQL_MODE_ORACLE_SPECIFIC */ %type <m_fk_option> delete_option +%type <privilege> + column_privilege + object_privilege + opt_grant_options + opt_grant_option + grant_option_list + grant_option + +%type <lex_grant> + object_privilege_list + grant_privileges + +%type <lex_grant_ident> + grant_ident + %type <ulong_num> ulong_num real_ulong_num merge_insert_types ws_nweights @@ -1602,9 +1631,8 @@ End SQL_MODE_ORACLE_SPECIFIC */ attribute attribute_list compressed_deprecated_data_type_attribute compressed_deprecated_column_attribute - column_list column_list_id - opt_column_list grant_privileges grant_ident grant_list grant_option - object_privilege object_privilege_list user_list user_and_role_list + grant_list + user_list user_and_role_list rename_list table_or_tables clear_privileges flush_options flush_option opt_flush_lock flush_lock flush_options_list @@ -1717,7 +1745,10 @@ End SQL_MODE_ORACLE_SPECIFIC */ %type <lex_str_ptr> query_name -%type <lex_str_list> opt_with_column_list with_column_list +%type <ident_sys_list> + comma_separated_ident_list + opt_with_column_list + with_column_list %type <vers_range_unit> opt_history_unit %type <vers_history_point> history_point @@ -2810,9 +2841,6 @@ clear_privileges: { LEX *lex=Lex; lex->users_list.empty(); - lex->columns.empty(); - lex->grant= lex->grant_tot_col= 0; - lex->all_privileges= 0; lex->first_select_lex()->db= null_clex_str; lex->account_options.reset(); } @@ -2823,6 +2851,15 @@ opt_aggregate: | AGGREGATE_SYM { $$= GROUP_AGGREGATE; } ; + +sp_handler: + FUNCTION_SYM { $$= &sp_handler_function; } + | PROCEDURE_SYM { $$= &sp_handler_procedure; } + | PACKAGE_ORACLE_SYM { $$= &sp_handler_package_spec; } + | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM { $$= &sp_handler_package_body; } + ; + + sp_name: ident '.' ident { @@ -14717,7 +14754,7 @@ with_list_element: opt_with_column_list: /* empty */ { - if (($$= new (thd->mem_root) List<LEX_CSTRING>) == NULL) + if (($$= new (thd->mem_root) List<Lex_ident_sys>) == NULL) MYSQL_YYABORT; } | '(' with_column_list ')' @@ -14725,22 +14762,30 @@ opt_with_column_list: ; with_column_list: - ident + comma_separated_ident_list + ; + +ident_sys_alloc: + ident_cli { + void *buf= thd->alloc(sizeof(Lex_ident_sys)); + if (!buf) + MYSQL_YYABORT; + $$= new (buf) Lex_ident_sys(thd, &$1); + } + ; - $$= new (thd->mem_root) List<LEX_CSTRING>; - if (unlikely($$ == NULL) || - unlikely($$->push_back((LEX_CSTRING*) - thd->memdup(&$1, sizeof(LEX_CSTRING)), - thd->mem_root))) +comma_separated_ident_list: + ident_sys_alloc + { + $$= new (thd->mem_root) List<Lex_ident_sys>; + if (unlikely($$ == NULL || $$->push_back($1))) MYSQL_YYABORT; } - | with_column_list ',' ident + | comma_separated_ident_list ',' ident_sys_alloc { - $1->push_back((LEX_CSTRING*) - thd->memdup(&$3, sizeof(LEX_CSTRING)), - thd->mem_root); - $$= $1; + if (($$= $1)->push_back($3)) + MYSQL_YYABORT; } ; @@ -16615,34 +16660,12 @@ revoke: revoke_command: grant_privileges ON opt_table grant_ident FROM user_and_role_list { - LEX *lex= Lex; - lex->sql_command= SQLCOM_REVOKE; - lex->type= 0; - } - | grant_privileges ON FUNCTION_SYM grant_ident FROM user_and_role_list - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_FUNCTION))) - MYSQL_YYABORT; - } - | grant_privileges ON PROCEDURE_SYM grant_ident FROM user_and_role_list - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_PROCEDURE))) + if (Lex->stmt_revoke_table(thd, $1, *$4)) MYSQL_YYABORT; } - | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident - FROM user_and_role_list + | grant_privileges ON sp_handler grant_ident FROM user_and_role_list { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_PACKAGE))) - MYSQL_YYABORT; - } - | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident - FROM user_and_role_list - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_PACKAGE_BODY))) + if (Lex->stmt_revoke_sp(thd, $1, *$4, *$3)) MYSQL_YYABORT; } | ALL opt_privileges ',' GRANT OPTION FROM user_and_role_list @@ -16651,10 +16674,8 @@ revoke_command: } | PROXY_SYM ON user FROM user_list { - LEX *lex= Lex; - lex->users_list.push_front ($3); - lex->sql_command= SQLCOM_REVOKE; - lex->type= TYPE_ENUM_PROXY; + if (Lex->stmt_revoke_proxy(thd, $3)) + MYSQL_YYABORT; } | admin_option_for_role FROM user_and_role_list { @@ -16680,44 +16701,19 @@ grant_command: grant_privileges ON opt_table grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - LEX *lex= Lex; - lex->sql_command= SQLCOM_GRANT; - lex->type= 0; - } - | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list - opt_require_clause opt_grant_options - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_FUNCTION))) - MYSQL_YYABORT; - } - | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list - opt_require_clause opt_grant_options - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_PROCEDURE))) - MYSQL_YYABORT; - } - | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident TO_SYM grant_list - opt_require_clause opt_grant_options - { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_PACKAGE))) + if (Lex->stmt_grant_table(thd, $1, *$4, $8)) MYSQL_YYABORT; } - | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident TO_SYM grant_list + | grant_privileges ON sp_handler grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_PACKAGE_BODY))) + if (Lex->stmt_grant_sp(thd, $1, *$4, *$3, $8)) MYSQL_YYABORT; } | PROXY_SYM ON user TO_SYM grant_list opt_grant_option { - LEX *lex= Lex; - lex->users_list.push_front ($3); - lex->sql_command= SQLCOM_GRANT; - lex->type= TYPE_ENUM_PROXY; + if (Lex->stmt_grant_proxy(thd, $3, $6)) + MYSQL_YYABORT; } | grant_role TO_SYM grant_list opt_with_admin_option { @@ -16792,11 +16788,11 @@ opt_table: ; grant_privileges: - object_privilege_list {} + object_privilege_list | ALL opt_privileges { - Lex->all_privileges= 1; - Lex->grant= GLOBAL_ACLS; + if (!($$= new (thd->mem_root) Lex_grant_privilege(GLOBAL_ACLS, true))) + MYSQL_YYABORT; } ; @@ -16807,49 +16803,75 @@ opt_privileges: object_privilege_list: object_privilege + { + if (!($$= new (thd->mem_root) Lex_grant_privilege($1))) + MYSQL_YYABORT; + } + | column_list_privilege + { + if (!($$= new (thd->mem_root) Lex_grant_privilege()) || + $$->add_column_list_privilege(thd, $1.m_columns[0], + $1.m_privilege)) + MYSQL_YYABORT; + } | object_privilege_list ',' object_privilege + { + ($$= $1)->add_object_privilege($3); + } + | object_privilege_list ',' column_list_privilege + { + if (($$= $1)->add_column_list_privilege(thd, $3.m_columns[0], + $3.m_privilege)) + MYSQL_YYABORT; + } + ; + +column_list_privilege: + column_privilege '(' comma_separated_ident_list ')' + { + $$= Lex_column_list_privilege($3, $1); + } + ; + +column_privilege: + SELECT_SYM { $$= SELECT_ACL; } + | INSERT { $$= INSERT_ACL; } + | UPDATE_SYM { $$= UPDATE_ACL; } + | REFERENCES { $$= REFERENCES_ACL; } ; object_privilege: - SELECT_SYM - { Lex->which_columns = SELECT_ACL;} - opt_column_list {} - | INSERT - { Lex->which_columns = INSERT_ACL;} - opt_column_list {} - | UPDATE_SYM - { Lex->which_columns = UPDATE_ACL; } - opt_column_list {} - | REFERENCES - { Lex->which_columns = REFERENCES_ACL;} - opt_column_list {} - | DELETE_SYM { Lex->grant |= DELETE_ACL;} - | USAGE {} - | INDEX_SYM { Lex->grant |= INDEX_ACL;} - | ALTER { Lex->grant |= ALTER_ACL;} - | CREATE { Lex->grant |= CREATE_ACL;} - | DROP { Lex->grant |= DROP_ACL;} - | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;} - | RELOAD { Lex->grant |= RELOAD_ACL;} - | SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;} - | PROCESS { Lex->grant |= PROCESS_ACL;} - | FILE_SYM { Lex->grant |= FILE_ACL;} - | GRANT OPTION { Lex->grant |= GRANT_ACL;} - | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;} - | SUPER_SYM { Lex->grant |= SUPER_ACL;} - | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;} - | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; } - | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL; } - | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL; } - | CREATE VIEW_SYM { Lex->grant |= CREATE_VIEW_ACL; } - | SHOW VIEW_SYM { Lex->grant |= SHOW_VIEW_ACL; } - | CREATE ROUTINE_SYM { Lex->grant |= CREATE_PROC_ACL; } - | ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; } - | CREATE USER_SYM { Lex->grant |= CREATE_USER_ACL; } - | EVENT_SYM { Lex->grant |= EVENT_ACL;} - | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; } - | CREATE TABLESPACE { Lex->grant |= CREATE_TABLESPACE_ACL; } - | DELETE_SYM HISTORY_SYM { Lex->grant |= DELETE_HISTORY_ACL; } + SELECT_SYM { $$= SELECT_ACL; } + | INSERT { $$= INSERT_ACL; } + | UPDATE_SYM { $$= UPDATE_ACL; } + | REFERENCES { $$= REFERENCES_ACL; } + | DELETE_SYM { $$= DELETE_ACL;} + | USAGE { $$= 0; } + | INDEX_SYM { $$= INDEX_ACL;} + | ALTER { $$= ALTER_ACL;} + | CREATE { $$= CREATE_ACL;} + | DROP { $$= DROP_ACL;} + | EXECUTE_SYM { $$= EXECUTE_ACL;} + | RELOAD { $$= RELOAD_ACL;} + | SHUTDOWN { $$= SHUTDOWN_ACL;} + | PROCESS { $$= PROCESS_ACL;} + | FILE_SYM { $$= FILE_ACL;} + | GRANT OPTION { $$= GRANT_ACL;} + | SHOW DATABASES { $$= SHOW_DB_ACL;} + | SUPER_SYM { $$= SUPER_ACL;} + | CREATE TEMPORARY TABLES { $$= CREATE_TMP_ACL;} + | LOCK_SYM TABLES { $$= LOCK_TABLES_ACL; } + | REPLICATION SLAVE { $$= REPL_SLAVE_ACL; } + | REPLICATION CLIENT_SYM { $$= REPL_CLIENT_ACL; } + | CREATE VIEW_SYM { $$= CREATE_VIEW_ACL; } + | SHOW VIEW_SYM { $$= SHOW_VIEW_ACL; } + | CREATE ROUTINE_SYM { $$= CREATE_PROC_ACL; } + | ALTER ROUTINE_SYM { $$= ALTER_PROC_ACL; } + | CREATE USER_SYM { $$= CREATE_USER_ACL; } + | EVENT_SYM { $$= EVENT_ACL;} + | TRIGGER_SYM { $$= TRIGGER_ACL; } + | CREATE TABLESPACE { $$= CREATE_TABLESPACE_ACL; } + | DELETE_SYM HISTORY_SYM { $$= DELETE_HISTORY_ACL; } ; opt_and: @@ -16889,41 +16911,30 @@ require_list_element: grant_ident: '*' { - LEX *lex= Lex; - if (unlikely(lex->copy_db_to(&lex->current_select->db))) + LEX_CSTRING db; + if (unlikely(Lex->copy_db_to(&db))) + MYSQL_YYABORT; + if (!($$= new (thd->mem_root) Lex_grant_object_name(db, + Lex_grant_object_name::STAR))) MYSQL_YYABORT; - if (lex->grant == GLOBAL_ACLS) - lex->grant = DB_ACLS & ~GRANT_ACL; - else if (unlikely(lex->columns.elements)) - my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | ident '.' '*' { - LEX *lex= Lex; - lex->current_select->db= $1; - if (lex->grant == GLOBAL_ACLS) - lex->grant = DB_ACLS & ~GRANT_ACL; - else if (unlikely(lex->columns.elements)) - my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); + if (!($$= new (thd->mem_root) Lex_grant_object_name($1, + Lex_grant_object_name::IDENT_STAR))) + MYSQL_YYABORT; } | '*' '.' '*' { - LEX *lex= Lex; - lex->current_select->db= null_clex_str; - if (lex->grant == GLOBAL_ACLS) - lex->grant= GLOBAL_ACLS & ~GRANT_ACL; - else if (unlikely(lex->columns.elements)) - my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); + if (!($$= new (thd->mem_root) Lex_grant_object_name( + null_clex_str, + Lex_grant_object_name::STAR_STAR))) + MYSQL_YYABORT; } | table_ident { - LEX *lex=Lex; - if (unlikely(!lex->current_select-> - add_table_to_list(thd, $1,NULL, - TL_OPTION_UPDATING))) + if (!($$= new (thd->mem_root) Lex_grant_object_name($1))) MYSQL_YYABORT; - if (lex->grant == GLOBAL_ACLS) - lex->grant = TABLE_ACLS & ~GRANT_ACL; } ; @@ -17034,49 +17045,6 @@ opt_auth_str: } ; -opt_column_list: - /* empty */ - { - LEX *lex=Lex; - lex->grant |= lex->which_columns; - } - | '(' column_list ')' { } - ; - -column_list: - column_list ',' column_list_id - | column_list_id - ; - -column_list_id: - ident - { - String *new_str= new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info); - if (unlikely(new_str == NULL)) - MYSQL_YYABORT; - List_iterator <LEX_COLUMN> iter(Lex->columns); - class LEX_COLUMN *point; - LEX *lex=Lex; - while ((point=iter++)) - { - if (!my_strcasecmp(system_charset_info, - point->column.c_ptr(), new_str->c_ptr())) - break; - } - lex->grant_tot_col|= lex->which_columns; - if (point) - point->rights |= lex->which_columns; - else - { - LEX_COLUMN *col= (new (thd->mem_root) - LEX_COLUMN(*new_str,lex->which_columns)); - if (unlikely(col == NULL)) - MYSQL_YYABORT; - lex->columns.push_back(col, thd->mem_root); - } - } - ; - opt_require_clause: /* empty */ | REQUIRE_SYM require_list @@ -17137,23 +17105,23 @@ opt_resource_options: opt_grant_options: - /* empty */ {} - | WITH grant_option_list {} + /* empty */ { $$= 0; } + | WITH grant_option_list { $$= $2; } ; opt_grant_option: - /* empty */ {} - | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} + /* empty */ { $$= 0; } + | WITH GRANT OPTION { $$= GRANT_ACL; } ; grant_option_list: - grant_option_list grant_option {} - | grant_option {} + grant_option_list grant_option { $$= $1 | $2; } + | grant_option ; grant_option: - GRANT OPTION { Lex->grant |= GRANT_ACL;} - | resource_option {} + GRANT OPTION { $$= GRANT_ACL;} + | resource_option { $$= 0; } ; begin_stmt_mariadb: |