diff options
41 files changed, 781 insertions, 546 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 1d5133794d2..8b25515405c 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -704,7 +704,7 @@ void *create_embedded_thd(int client_flag) thd->db= null_clex_str; #ifndef NO_EMBEDDED_ACCESS_CHECKS thd->security_ctx->db_access= DB_ACLS; - thd->security_ctx->master_access= ~NO_ACCESS; + thd->security_ctx->master_access= ALL_KNOWN_ACL; #endif thd->cur_data= 0; thd->first_data= 0; diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 171440c41ad..36db4e44cc0 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -106,7 +106,7 @@ static int prepare_for_fill(TABLE_LIST *tables) thd->db= null_clex_str; thd->security_ctx->host_or_ip= ""; thd->security_ctx->db_access= DB_ACLS; - thd->security_ctx->master_access= ~NO_ACCESS; + thd->security_ctx->master_access= ALL_KNOWN_ACL; bzero((char*) &thd->net, sizeof(thd->net)); lex_start(thd); mysql_init_select(thd->lex); diff --git a/plugin/userstat/index_stats.cc b/plugin/userstat/index_stats.cc index 8605e56fbc8..3ad5ef2e1ad 100644 --- a/plugin/userstat/index_stats.cc +++ b/plugin/userstat/index_stats.cc @@ -29,7 +29,7 @@ static int index_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) tmp_table.db.length= strlen(index_stats->index); tmp_table.table_name.str= index_stats->index + tmp_table.db.length + 1; tmp_table.table_name.length= strlen(tmp_table.table_name.str); - tmp_table.grant.privilege= 0; + tmp_table.grant.privilege= NO_ACL; if (check_access(thd, SELECT_ACL, tmp_table.db.str, &tmp_table.grant.privilege, NULL, 0, 1) || check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) diff --git a/plugin/userstat/table_stats.cc b/plugin/userstat/table_stats.cc index c733d77c26b..6551711475f 100644 --- a/plugin/userstat/table_stats.cc +++ b/plugin/userstat/table_stats.cc @@ -34,7 +34,7 @@ static int table_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) tmp_table.db.length= schema_length; tmp_table.table_name.str= end_of_schema+1; tmp_table.table_name.length= table_name_length; - tmp_table.grant.privilege= 0; + tmp_table.grant.privilege= NO_ACL; if (check_access(thd, SELECT_ACL, tmp_table.db.str, &tmp_table.grant.privilege, NULL, 0, 1) || check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index d9ed0b633e4..5ea8300b7e4 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1480,8 +1480,6 @@ end: ret= 1; else { - ulong saved_master_access; - thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length()); /* @@ -1493,7 +1491,7 @@ end: Temporarily reset it to read-write. */ - saved_master_access= thd->security_ctx->master_access; + privilege_t saved_master_access(thd->security_ctx->master_access); thd->security_ctx->master_access |= SUPER_ACL; bool save_tx_read_only= thd->tx_read_only; thd->tx_read_only= false; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 8d90e8aed70..9a8869e2fb3 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -177,8 +177,8 @@ pre_init_event_thread(THD* thd) set_current_thd(thd); thd->client_capabilities= 0; - thd->security_ctx->master_access= 0; - thd->security_ctx->db_access= 0; + thd->security_ctx->master_access= NO_ACL; + thd->security_ctx->db_access= NO_ACL; thd->security_ctx->host_or_ip= (char*)my_localhost; my_net_init(&thd->net, NULL, thd, MYF(MY_THREAD_SPECIFIC)); thd->security_ctx->set_user((char*)"event_scheduler"); diff --git a/sql/events.cc b/sql/events.cc index 38a9bbf3e9e..68e013adfae 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1145,7 +1145,6 @@ Events::load_events_from_db(THD *thd) READ_RECORD read_record_info; bool ret= TRUE; uint count= 0; - ulong saved_master_access; DBUG_ENTER("Events::load_events_from_db"); DBUG_PRINT("enter", ("thd: %p", thd)); @@ -1158,7 +1157,7 @@ Events::load_events_from_db(THD *thd) Temporarily reset it to read-write. */ - saved_master_access= thd->security_ctx->master_access; + privilege_t saved_master_access(thd->security_ctx->master_access); thd->security_ctx->master_access |= SUPER_ACL; bool save_tx_read_only= thd->tx_read_only; thd->tx_read_only= false; diff --git a/sql/grant.cc b/sql/grant.cc index d4bbaa7b1f3..1ba197bc1d9 100644 --- a/sql/grant.cc +++ b/sql/grant.cc @@ -20,7 +20,7 @@ bool Grant_privilege::add_column_privilege(THD *thd, const Lex_ident_sys &name, - uint which_grant) + privilege_t which_grant) { String *new_str= new (thd->mem_root) String((const char*) name.str, name.length, @@ -51,7 +51,7 @@ bool Grant_privilege::add_column_privilege(THD *thd, bool Grant_privilege::add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list, - uint privilege) + privilege_t privilege) { Lex_ident_sys *col; List_iterator<Lex_ident_sys> it(list); @@ -64,7 +64,7 @@ bool Grant_privilege::add_column_list_privilege(THD *thd, } -uint Grant_object_name::all_privileges_by_type() const +privilege_t Grant_object_name::all_privileges_by_type() const { switch (m_type) { case STAR: return DB_ACLS & ~GRANT_ACL; @@ -72,14 +72,14 @@ uint Grant_object_name::all_privileges_by_type() const case STAR_STAR: return GLOBAL_ACLS & ~GRANT_ACL; case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL; } - return 0; + return NO_ACL; } bool Grant_privilege::set_object_name(THD *thd, const Grant_object_name &ident, SELECT_LEX *sel, - uint with_grant_option) + privilege_t with_grant_option) { DBUG_ASSERT(!m_all_privileges || !m_columns.elements); diff --git a/sql/grant.h b/sql/grant.h index 18b39ea0719..5fbec4469d4 100644 --- a/sql/grant.h +++ b/sql/grant.h @@ -18,6 +18,7 @@ #define SQL_GRANT_INCLUDED #include "lex_string.h" +#include "privilege.h" class LEX_COLUMN; class Lex_ident_sys; @@ -50,7 +51,7 @@ public: m_table_ident(NULL), m_type(type) { } - uint all_privileges_by_type() const; + privilege_t all_privileges_by_type() const; }; @@ -65,30 +66,32 @@ class Grant_privilege protected: List<LEX_COLUMN> m_columns; Lex_cstring m_db; - uint m_object_privilege; - uint m_column_privilege_total; + privilege_t m_object_privilege; + privilege_t m_column_privilege_total; bool m_all_privileges; public: Grant_privilege() - :m_object_privilege(0), m_column_privilege_total(0), m_all_privileges(false) + :m_object_privilege(NO_ACL), + m_column_privilege_total(NO_ACL), + m_all_privileges(false) { } - Grant_privilege(uint privilege, bool all_privileges) + Grant_privilege(privilege_t privilege, bool all_privileges) :m_object_privilege(privilege), - m_column_privilege_total(0), + m_column_privilege_total(NO_ACL), m_all_privileges(all_privileges) { } - void add_object_privilege(uint privilege) + void add_object_privilege(privilege_t privilege) { m_object_privilege|= privilege; } bool add_column_privilege(THD *thd, const Lex_ident_sys &col, - uint privilege); + privilege_t privilege); bool add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list, - uint privilege); + privilege_t privilege); bool set_object_name(THD *thd, const Grant_object_name &ident, SELECT_LEX *sel, - uint with_grant_option); + privilege_t with_grant_option); const List<LEX_COLUMN> & columns() const { return m_columns; } }; diff --git a/sql/item.cc b/sql/item.cc index d837e8b5719..6b585325439 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2892,7 +2892,7 @@ Item_field::Item_field(THD *thd, Field *f) :Item_ident(thd, 0, null_clex_str, Lex_cstring_strlen(*f->table_name), f->field_name), item_equal(0), - have_privileges(0), any_privileges(0) + have_privileges(NO_ACL), any_privileges(0) { set_field(f); /* @@ -2917,7 +2917,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, :Item_ident(thd, context_arg, f->table->s->db, Lex_cstring_strlen(*f->table_name), f->field_name), item_equal(0), - have_privileges(0), any_privileges(0) + have_privileges(NO_ACL), any_privileges(0) { /* We always need to provide Item_field with a fully qualified field @@ -2961,7 +2961,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, const LEX_CSTRING &field_name_arg) :Item_ident(thd, context_arg, db_arg, table_name_arg, field_name_arg), field(0), item_equal(0), - have_privileges(0), any_privileges(0) + have_privileges(NO_ACL), any_privileges(0) { SELECT_LEX *select= thd->lex->current_select; collation.set(DERIVATION_IMPLICIT); diff --git a/sql/item.h b/sql/item.h index 2ba7ba6874d..6a9d401b101 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3290,7 +3290,7 @@ public: if any_privileges set to TRUE then here real effective privileges will be stored */ - uint have_privileges; + privilege_t have_privileges; /* field need any privileges (for VIEW creation) */ bool any_privileges; Item_field(THD *thd, Name_resolution_context *context_arg, @@ -6381,7 +6381,7 @@ public: Item_trigger_field(THD *thd, Name_resolution_context *context_arg, row_version_type row_ver_arg, const LEX_CSTRING &field_name_arg, - ulong priv, const bool ro) + privilege_t priv, const bool ro) :Item_field(thd, context_arg, field_name_arg), row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv), want_privilege(priv), table_grants(NULL), read_only (ro) @@ -6423,8 +6423,8 @@ private: want_privilege and cleanup() is responsible for restoring of original want_privilege once parameter's value is updated). */ - ulong original_privilege; - ulong want_privilege; + privilege_t original_privilege; + privilege_t want_privilege; GRANT_INFO *table_grants; /* Trigger field is read-only unless it belongs to the NEW row in a diff --git a/sql/lock.cc b/sql/lock.cc index 94e0d2733c7..6f86c0a38f6 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -114,7 +114,7 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) DBUG_ENTER("lock_tables_check"); system_count= 0; - is_superuser= thd->security_ctx->master_access & SUPER_ACL; + is_superuser= (thd->security_ctx->master_access & SUPER_ACL) != NO_ACL; log_table_write_query= (is_log_table_write_query(thd->lex->sql_command) || ((flags & MYSQL_LOCK_LOG_TABLE) != 0)); diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc index d95f0795542..7ff11e65a30 100644 --- a/sql/opt_trace.cc +++ b/sql/opt_trace.cc @@ -263,7 +263,7 @@ void opt_trace_disable_if_no_tables_access(THD *thd, TABLE_LIST *tbl) bool rc = check_table_access(thd, SELECT_ACL, t, false, 1, true) || // (1) - ((t->grant.privilege & SELECT_ACL) == 0); // (2) + ((t->grant.privilege & SELECT_ACL) == NO_ACL); // (2) if (t->is_view()) { /* diff --git a/sql/privilege.h b/sql/privilege.h new file mode 100644 index 00000000000..6f12546796e --- /dev/null +++ b/sql/privilege.h @@ -0,0 +1,333 @@ +#ifndef PRIVILEGE_H_INCLUDED +#define PRIVILEGE_H_INCLUDED + +/* 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 St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#include "my_global.h" // ulonglong + + +/* + A strict enum to store privilege bits. + + We should eventually make if even stricter using "enum class privilege_t" and: + - Replace all code pieces like `if (priv)` to `if (priv != NO_ACL)` + - Remove "delete" comparison operators below +*/ +enum privilege_t: unsigned long long +{ + NO_ACL = (0), + SELECT_ACL = (1UL << 0), + INSERT_ACL = (1UL << 1), + UPDATE_ACL = (1UL << 2), + DELETE_ACL = (1UL << 3), + CREATE_ACL = (1UL << 4), + DROP_ACL = (1UL << 5), + RELOAD_ACL = (1UL << 6), + SHUTDOWN_ACL = (1UL << 7), + PROCESS_ACL = (1UL << 8), + FILE_ACL = (1UL << 9), + GRANT_ACL = (1UL << 10), + REFERENCES_ACL = (1UL << 11), + INDEX_ACL = (1UL << 12), + ALTER_ACL = (1UL << 13), + SHOW_DB_ACL = (1UL << 14), + SUPER_ACL = (1UL << 15), + CREATE_TMP_ACL = (1UL << 16), + LOCK_TABLES_ACL = (1UL << 17), + EXECUTE_ACL = (1UL << 18), + REPL_SLAVE_ACL = (1UL << 19), + REPL_CLIENT_ACL = (1UL << 20), + CREATE_VIEW_ACL = (1UL << 21), + SHOW_VIEW_ACL = (1UL << 22), + CREATE_PROC_ACL = (1UL << 23), + ALTER_PROC_ACL = (1UL << 24), + CREATE_USER_ACL = (1UL << 25), + EVENT_ACL = (1UL << 26), + TRIGGER_ACL = (1UL << 27), + CREATE_TABLESPACE_ACL = (1UL << 28), + DELETE_HISTORY_ACL = (1UL << 29), + /* + don't forget to update + 1. static struct show_privileges_st sys_privileges[] + 2. static const char *command_array[] and static uint command_lengths[] + 3. mysql_system_tables.sql and mysql_system_tables_fix.sql + 4. acl_init() or whatever - to define behaviour for old privilege tables + 5. sql_yacc.yy - for GRANT/REVOKE to work + 6. ALL_KNOWN_ACL + */ + ALL_KNOWN_ACL = (1UL << 30) - 1 // A combination of all defined bits +}; + + +// Unary operators +static inline constexpr ulonglong operator~(privilege_t access) +{ + return ~static_cast<ulonglong>(access); +} + +/* + Comparison operators. + Delete automatic conversion between to/from integer types as much as possible. + This forces to use `(priv == NO_ACL)` instead of `(priv == 0)`. + + Note: these operators will be gone when we change privilege_t to + "enum class privilege_t". See comments above. +*/ +static inline bool operator==(privilege_t, ulonglong)= delete; +static inline bool operator==(privilege_t, ulong)= delete; +static inline bool operator==(privilege_t, uint)= delete; +static inline bool operator==(privilege_t, uchar)= delete; +static inline bool operator==(privilege_t, longlong)= delete; +static inline bool operator==(privilege_t, long)= delete; +static inline bool operator==(privilege_t, int)= delete; +static inline bool operator==(privilege_t, char)= delete; +static inline bool operator==(privilege_t, bool)= delete; + +static inline bool operator==(ulonglong, privilege_t)= delete; +static inline bool operator==(ulong, privilege_t)= delete; +static inline bool operator==(uint, privilege_t)= delete; +static inline bool operator==(uchar, privilege_t)= delete; +static inline bool operator==(longlong, privilege_t)= delete; +static inline bool operator==(long, privilege_t)= delete; +static inline bool operator==(int, privilege_t)= delete; +static inline bool operator==(char, privilege_t)= delete; +static inline bool operator==(bool, privilege_t)= delete; + +static inline bool operator!=(privilege_t, ulonglong)= delete; +static inline bool operator!=(privilege_t, ulong)= delete; +static inline bool operator!=(privilege_t, uint)= delete; +static inline bool operator!=(privilege_t, uchar)= delete; +static inline bool operator!=(privilege_t, longlong)= delete; +static inline bool operator!=(privilege_t, long)= delete; +static inline bool operator!=(privilege_t, int)= delete; +static inline bool operator!=(privilege_t, char)= delete; +static inline bool operator!=(privilege_t, bool)= delete; + +static inline bool operator!=(ulonglong, privilege_t)= delete; +static inline bool operator!=(ulong, privilege_t)= delete; +static inline bool operator!=(uint, privilege_t)= delete; +static inline bool operator!=(uchar, privilege_t)= delete; +static inline bool operator!=(longlong, privilege_t)= delete; +static inline bool operator!=(long, privilege_t)= delete; +static inline bool operator!=(int, privilege_t)= delete; +static inline bool operator!=(char, privilege_t)= delete; +static inline bool operator!=(bool, privilege_t)= delete; + + +// Dyadic bitwise operators +static inline constexpr privilege_t operator&(privilege_t a, privilege_t b) +{ + return static_cast<privilege_t>(static_cast<ulonglong>(a) & + static_cast<ulonglong>(b)); +} + +static inline constexpr privilege_t operator&(ulonglong a, privilege_t b) +{ + return static_cast<privilege_t>(a & static_cast<ulonglong>(b)); +} + +static inline constexpr privilege_t operator&(privilege_t a, ulonglong b) +{ + return static_cast<privilege_t>(static_cast<ulonglong>(a) & b); +} + +static inline constexpr privilege_t operator|(privilege_t a, privilege_t b) +{ + return static_cast<privilege_t>(static_cast<ulonglong>(a) | + static_cast<ulonglong>(b)); +} + + +// Dyadyc bitwise assignment operators +static inline privilege_t& operator&=(privilege_t &a, privilege_t b) +{ + return a= a & b; +} + +static inline privilege_t& operator&=(privilege_t &a, ulonglong b) +{ + return a= a & b; +} + +static inline privilege_t& operator|=(privilege_t &a, privilege_t b) +{ + return a= a | b; +} + + + +constexpr privilege_t COL_DML_ACLS= + SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL; + +constexpr privilege_t VIEW_ACLS= + CREATE_VIEW_ACL | SHOW_VIEW_ACL; + +constexpr privilege_t STD_TABLE_DDL_ACLS= + CREATE_ACL | DROP_ACL | ALTER_ACL; + +constexpr privilege_t ALL_TABLE_DDL_ACLS= + STD_TABLE_DDL_ACLS | INDEX_ACL; + +constexpr privilege_t COL_ACLS= + SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL; + +constexpr privilege_t PROC_DDL_ACLS= + CREATE_PROC_ACL | ALTER_PROC_ACL; + +constexpr privilege_t SHOW_PROC_ACLS= + PROC_DDL_ACLS | EXECUTE_ACL; + +constexpr privilege_t TABLE_ACLS= + COL_DML_ACLS | ALL_TABLE_DDL_ACLS | VIEW_ACLS | + GRANT_ACL | REFERENCES_ACL | + TRIGGER_ACL | DELETE_HISTORY_ACL; + +constexpr privilege_t DB_ACLS= + TABLE_ACLS | PROC_DDL_ACLS | EXECUTE_ACL | + CREATE_TMP_ACL | LOCK_TABLES_ACL | EVENT_ACL; + +constexpr privilege_t PROC_ACLS= + ALTER_PROC_ACL | EXECUTE_ACL | GRANT_ACL; + +constexpr privilege_t GLOBAL_ACLS= + DB_ACLS | SHOW_DB_ACL | + CREATE_USER_ACL | CREATE_TABLESPACE_ACL | + SUPER_ACL | RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | + REPL_SLAVE_ACL | REPL_CLIENT_ACL; + +constexpr privilege_t DEFAULT_CREATE_PROC_ACLS= + ALTER_PROC_ACL | EXECUTE_ACL; + +constexpr privilege_t SHOW_CREATE_TABLE_ACLS= + COL_DML_ACLS | ALL_TABLE_DDL_ACLS | + TRIGGER_ACL | REFERENCES_ACL | GRANT_ACL | VIEW_ACLS; + +/** + Table-level privileges which are automatically "granted" to everyone on + existing temporary tables (CREATE_ACL is necessary for ALTER ... RENAME). +*/ +constexpr privilege_t TMP_TABLE_ACLS= + COL_DML_ACLS | ALL_TABLE_DDL_ACLS; + +/* + 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 +*/ + +/* Privileges that need to be reallocated (in continous chunks) */ +constexpr privilege_t DB_CHUNK0 (COL_DML_ACLS | CREATE_ACL | DROP_ACL); +constexpr privilege_t DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL); +constexpr privilege_t DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL); +constexpr privilege_t DB_CHUNK3 (VIEW_ACLS | PROC_DDL_ACLS); +constexpr privilege_t DB_CHUNK4 (EXECUTE_ACL); +constexpr privilege_t DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL); +constexpr privilege_t DB_CHUNK6 (DELETE_HISTORY_ACL); + + +static inline privilege_t fix_rights_for_db(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + (((A) & DB_CHUNK0) | + ((A << 4) & DB_CHUNK1) | + ((A << 6) & DB_CHUNK2) | + ((A << 9) & DB_CHUNK3) | + ((A << 2) & DB_CHUNK4) | + ((A << 9) & DB_CHUNK5) | + ((A << 10) & DB_CHUNK6)); +} + +static inline privilege_t get_rights_for_db(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + ((A & DB_CHUNK0) | + ((A & DB_CHUNK1) >> 4) | + ((A & DB_CHUNK2) >> 6) | + ((A & DB_CHUNK3) >> 9) | + ((A & DB_CHUNK4) >> 2) | + ((A & DB_CHUNK5) >> 9) | + ((A & DB_CHUNK6) >> 10)); +} + + +#define TBL_CHUNK0 DB_CHUNK0 +#define TBL_CHUNK1 DB_CHUNK1 +#define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL) +#define TBL_CHUNK3 TRIGGER_ACL +#define TBL_CHUNK4 (DELETE_HISTORY_ACL) + + +static inline privilege_t fix_rights_for_table(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + ((A & TBL_CHUNK0) | + ((A << 4) & TBL_CHUNK1) | + ((A << 11) & TBL_CHUNK2) | + ((A << 15) & TBL_CHUNK3) | + ((A << 16) & TBL_CHUNK4)); +} + + +static inline privilege_t get_rights_for_table(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + ((A & TBL_CHUNK0) | + ((A & TBL_CHUNK1) >> 4) | + ((A & TBL_CHUNK2) >> 11) | + ((A & TBL_CHUNK3) >> 15) | + ((A & TBL_CHUNK4) >> 16)); +} + + +static inline privilege_t fix_rights_for_column(privilege_t A) +{ + const ulonglong mask(SELECT_ACL | INSERT_ACL | UPDATE_ACL); + return (A & mask) | static_cast<privilege_t>((A & ~mask) << 8); +} + + +static inline privilege_t get_rights_for_column(privilege_t A) +{ + const ulonglong mask(SELECT_ACL | INSERT_ACL | UPDATE_ACL); + return static_cast<privilege_t>((static_cast<ulonglong>(A) & mask) | + (static_cast<ulonglong>(A) >> 8)); +} + + +static inline privilege_t fix_rights_for_procedure(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + (((A << 18) & EXECUTE_ACL) | + ((A << 23) & ALTER_PROC_ACL) | + ((A << 8) & GRANT_ACL)); +} + + +static inline privilege_t get_rights_for_procedure(privilege_t access) +{ + ulonglong A(access); + return static_cast<privilege_t> + (((A & EXECUTE_ACL) >> 18) | + ((A & ALTER_PROC_ACL) >> 23) | + ((A & GRANT_ACL) >> 8)); +} + + +#endif /* PRIVILEGE_H_INCLUDED */ diff --git a/sql/set_var.h b/sql/set_var.h index c3147c1e3ca..c4a29968818 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -349,9 +349,9 @@ public: class set_var_role: public set_var_base { LEX_CSTRING role; - ulonglong access; + privilege_t access; public: - set_var_role(LEX_CSTRING role_arg) : role(role_arg) {} + set_var_role(LEX_CSTRING role_arg) : role(role_arg), access(NO_ACL) {} int check(THD *thd); int update(THD *thd); }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index cd5a836e8b5..c15465f105e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2852,7 +2852,7 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) *full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE, 1, TRUE) && - (tables.grant.privilege & SELECT_ACL) != 0) || + (tables.grant.privilege & SELECT_ACL) != NO_ACL) || /* Check if user owns the routine. */ (!strcmp(sp->m_definer.user.str, thd->security_ctx->priv_user) && diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7bdee80d596..ead50fe7df5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -126,9 +126,9 @@ static bool compare_hostname(const acl_host_and_ip *, const char *, const char * class ACL_ACCESS { public: ulonglong sort; - ulong access; + privilege_t access; ACL_ACCESS() - :sort(0), access(0) + :sort(0), access(NO_ACL) { } }; @@ -193,7 +193,7 @@ public: ACL_USER() { } ACL_USER(THD *thd, const LEX_USER &combo, const Account_options &options, - const ulong privileges); + const privilege_t privileges); ACL_USER *copy(MEM_ROOT *root) { @@ -259,7 +259,7 @@ public: the ACL_USER::access field needs to be reset first. The field initial_role_access holds initial grants, as granted directly to the role */ - ulong initial_role_access; + privilege_t initial_role_access; /* In subgraph traversal, when we need to traverse only a part of the graph (e.g. all direct and indirect grantees of a role X), the counter holds the @@ -270,16 +270,17 @@ public: DYNAMIC_ARRAY parent_grantee; // array of backlinks to elements granted ACL_ROLE(ACL_USER * user, MEM_ROOT *mem); - ACL_ROLE(const char * rolename, ulong privileges, MEM_ROOT *mem); + ACL_ROLE(const char * rolename, privilege_t privileges, MEM_ROOT *mem); }; class ACL_DB :public ACL_ACCESS { public: + ACL_DB() :initial_access(NO_ACL) { } acl_host_and_ip host; const char *user,*db; - ulong initial_access; /* access bits present in the table */ + privilege_t initial_access; /* access bits present in the table */ const char *get_username() { return user; } }; @@ -520,7 +521,7 @@ public: class acl_entry :public hash_filo_element { public: - ulong access; + privilege_t access; uint16 length; char key[1]; // Key will be stored here }; @@ -662,7 +663,7 @@ static HASH package_spec_priv_hash, package_body_priv_hash; static DYNAMIC_ARRAY acl_wild_hosts; static Hash_filo<acl_entry> *acl_cache; static uint grant_version=0; /* Version of priv tables. incremented by acl_load */ -static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); +static privilege_t get_access(TABLE *form, uint fieldnr, uint *next_field=0); static int acl_compare(const ACL_ACCESS *a, const ACL_ACCESS *b); static int acl_user_compare(const ACL_USER *a, const ACL_USER *b); static void rebuild_acl_users(); @@ -800,15 +801,15 @@ class Grant_table_base /* Return the underlying TABLE handle. */ TABLE* table() const { return m_table; } - ulong get_access() const + privilege_t get_access() const { - ulong access_bits= 0, bit= 1; + ulonglong access_bits= 0, bit= 1; for (uint i = start_priv_columns; i < end_priv_columns; i++, bit<<=1) { if (get_YN_as_bool(m_table->field[i])) access_bits|= bit; } - return access_bits; + return ALL_KNOWN_ACL & access_bits; } protected: @@ -862,8 +863,8 @@ class User_table: public Grant_table_base virtual LEX_CSTRING& name() const = 0; virtual int get_auth(THD *, MEM_ROOT *, ACL_USER *u) const= 0; virtual bool set_auth(const ACL_USER &u) const = 0; - virtual ulong get_access() const = 0; - virtual void set_access(ulong rights, bool revoke) const = 0; + virtual privilege_t get_access() const = 0; + virtual void set_access(const privilege_t rights, bool revoke) const = 0; char *get_host(MEM_ROOT *root) const { return ::get_field(root, m_table->field[0]); } @@ -981,9 +982,9 @@ class User_table_tabular: public User_table return 0; } - ulong get_access() const + privilege_t get_access() const { - ulong access= Grant_table_base::get_access(); + privilege_t access(Grant_table_base::get_access()); if ((num_fields() <= 13) && (access & CREATE_ACL)) access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL; @@ -1022,9 +1023,9 @@ class User_table_tabular: public User_table return access & GLOBAL_ACLS; } - void set_access(ulong rights, bool revoke) const + void set_access(const privilege_t rights, bool revoke) const { - ulong priv= SELECT_ACL; + ulonglong priv(SELECT_ACL); for (uint i= start_priv_columns; i < end_priv_columns; i++, priv <<= 1) { if (priv & rights) @@ -1469,23 +1470,23 @@ class User_table_json: public User_table set_str_value("authentication_string", u.auth[i].auth_string.str, u.auth[i].auth_string.length); } - ulong get_access() const + privilege_t get_access() const { /* when new privileges will be added, we'll start storing GLOBAL_ACLS (or, for example, my_count_bits(GLOBAL_ACLS)) in the json too, and it'll allow us to do privilege upgrades */ - return get_int_value("access") & GLOBAL_ACLS; + return get_access_value("access") & GLOBAL_ACLS; } - void set_access(ulong rights, bool revoke) const + void set_access(const privilege_t rights, bool revoke) const { - ulong access= get_access(); + privilege_t access= get_access(); if (revoke) access&= ~rights; else access|= rights; - set_int_value("access", access & GLOBAL_ACLS); + set_int_value("access", (longlong) (access & GLOBAL_ACLS)); } const char *unsafe_str(const char *s) const { return s[0] ? s : NULL; } @@ -1606,6 +1607,10 @@ class User_table_json: public User_table const char *value_end= value_start + value_len; return my_strtoll10(value_start, (char**)&value_end, &err); } + privilege_t get_access_value(const char *key) const + { + return privilege_t(ALL_KNOWN_ACL & (ulonglong) get_int_value(key)); + } double get_double_value(const char *key) const { int err; @@ -1969,17 +1974,20 @@ enum enum_acl_lists ROLES_MAPPINGS_HASH }; -ACL_ROLE::ACL_ROLE(ACL_USER *user, MEM_ROOT *root) : counter(0) +ACL_ROLE::ACL_ROLE(ACL_USER *user, MEM_ROOT *root) + : + /* set initial role access the same as the table row privileges */ + initial_role_access(user->access), + counter(0) { access= user->access; - /* set initial role access the same as the table row privileges */ - initial_role_access= user->access; this->user= user->user; bzero(&parent_grantee, sizeof(parent_grantee)); flags= IS_ROLE; } -ACL_ROLE::ACL_ROLE(const char * rolename, ulong privileges, MEM_ROOT *root) : +ACL_ROLE::ACL_ROLE(const char * rolename, privilege_t privileges, + MEM_ROOT *root) : initial_role_access(privileges), counter(0) { this->access= initial_role_access; @@ -2740,9 +2748,9 @@ end: privilege mask */ -static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) +static privilege_t get_access(TABLE *form, uint fieldnr, uint *next_field) { - ulong access_bits=0,bit; + ulonglong access_bits=0,bit; char buff[2]; String res(buff,sizeof(buff),&my_charset_latin1); Field **pos; @@ -2757,7 +2765,7 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) } if (next_field) *next_field=fieldnr; - return access_bits; + return ALL_KNOWN_ACL & access_bits; } @@ -2961,7 +2969,7 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host, mysql_mutex_lock(&acl_cache->lock); - sctx->db_access= 0; + sctx->db_access= NO_ACL; if (host[0]) // User, not Role { @@ -3001,7 +3009,7 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host, } static int check_user_can_set_role(const char *user, const char *host, - const char *ip, const char *rolename, ulonglong *access) + const char *ip, const char *rolename, privilege_t *access) { ACL_ROLE *role; ACL_USER_BASE *acl_user_base; @@ -3069,7 +3077,7 @@ end: } -int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access) +int acl_check_setrole(THD *thd, const char *rolename, privilege_t *access) { /* Yes! priv_user@host. Don't ask why - that's what check_access() does. */ return check_user_can_set_role(thd->security_ctx->priv_user, @@ -3077,11 +3085,11 @@ int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access) } -int acl_setrole(THD *thd, const char *rolename, ulonglong access) +int acl_setrole(THD *thd, const char *rolename, privilege_t access) { /* merge the privileges */ Security_context *sctx= thd->security_ctx; - sctx->master_access= static_cast<ulong>(access); + sctx->master_access= access; if (thd->db.str) sctx->db_access= acl_get(sctx->host, sctx->ip, sctx->user, thd->db.str, FALSE); @@ -3107,7 +3115,7 @@ static uchar* check_get_key(ACL_USER *buff, size_t *length, } -static void acl_update_role(const char *rolename, ulong privileges) +static void acl_update_role(const char *rolename, const privilege_t privileges) { ACL_ROLE *role= find_acl_role(rolename); if (role) @@ -3117,7 +3125,7 @@ static void acl_update_role(const char *rolename, ulong privileges) ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo, const Account_options &options, - const ulong privileges) + const privilege_t privileges) { user= safe_lexcstrdup_root(&acl_memroot, combo.user); update_hostname(&host, safe_strdup_root(&acl_memroot, combo.host.str)); @@ -3132,7 +3140,7 @@ ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo, static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth, const LEX_USER &combo, const Account_options &options, - const ulong privileges) + const privilege_t privileges) { if (nauth) { @@ -3204,7 +3212,7 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth, } -static void acl_insert_role(const char *rolename, ulong privileges) +static void acl_insert_role(const char *rolename, privilege_t privileges) { ACL_ROLE *entry; @@ -3219,7 +3227,7 @@ static void acl_insert_role(const char *rolename, ulong privileges) static bool acl_update_db(const char *user, const char *host, const char *db, - ulong privileges) + privilege_t privileges) { mysql_mutex_assert_owner(&acl_cache->lock); @@ -3271,7 +3279,7 @@ static bool acl_update_db(const char *user, const char *host, const char *db, */ static void acl_insert_db(const char *user, const char *host, const char *db, - ulong privileges) + const privilege_t privileges) { ACL_DB acl_db; mysql_mutex_assert_owner(&acl_cache->lock); @@ -3292,10 +3300,10 @@ static void acl_insert_db(const char *user, const char *host, const char *db, acl_cache is not used if db_is_pattern is set. */ -ulong acl_get(const char *host, const char *ip, - const char *user, const char *db, my_bool db_is_pattern) +privilege_t acl_get(const char *host, const char *ip, + const char *user, const char *db, my_bool db_is_pattern) { - ulong host_access= ~(ulong)0, db_access= 0; + privilege_t host_access(ALL_KNOWN_ACL), db_access(NO_ACL); uint i; size_t key_length; char key[ACL_KEY_LENGTH],*tmp_db,*end; @@ -3306,7 +3314,7 @@ ulong acl_get(const char *host, const char *ip, end= strnmov(tmp_db, db, key + sizeof(key) - tmp_db); if (end >= key + sizeof(key)) // db name was truncated - DBUG_RETURN(0); // no privileges for an invalid db name + DBUG_RETURN(NO_ACL); // no privileges for an invalid db name if (lower_case_table_names) { @@ -3320,7 +3328,7 @@ ulong acl_get(const char *host, const char *ip, { db_access=entry->access; mysql_mutex_unlock(&acl_cache->lock); - DBUG_PRINT("exit", ("access: 0x%lx", db_access)); + DBUG_PRINT("exit", ("access: 0x%llx", (longlong) db_access)); DBUG_RETURN(db_access); } @@ -3343,7 +3351,7 @@ ulong acl_get(const char *host, const char *ip, /* No host specified for user. Get hostdata from host table */ - host_access=0; // Host must be found + host_access= NO_ACL; // Host must be found for (i=0 ; i < acl_hosts.elements ; i++) { ACL_HOST *acl_host=dynamic_element(&acl_hosts,i,ACL_HOST*); @@ -3368,7 +3376,7 @@ exit: acl_cache->add(entry); } mysql_mutex_unlock(&acl_cache->lock); - DBUG_PRINT("exit", ("access: 0x%lx", db_access & host_access)); + DBUG_PRINT("exit", ("access: 0x%llx", (longlong) (db_access & host_access))); DBUG_RETURN(db_access & host_access); } @@ -4281,7 +4289,7 @@ static bool test_if_create_new_users(THD *thd) if (!create_new_users) { TABLE_LIST tl; - ulong db_access; + privilege_t db_access(NO_ACL); tl.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_TABLE_NAME[USER_TABLE], NULL, TL_WRITE); create_new_users= 1; @@ -4306,7 +4314,7 @@ static bool test_if_create_new_users(THD *thd) static USER_AUTH auth_no_password; static int replace_user_table(THD *thd, const User_table &user_table, - LEX_USER * const combo, ulong rights, + LEX_USER * const combo, privilege_t rights, const bool revoke_grant, const bool can_create_user, const bool no_auto_create) { @@ -4561,10 +4569,11 @@ end: static int replace_db_table(TABLE *table, const char *db, const LEX_USER &combo, - ulong rights, const bool revoke_grant) + privilege_t rights, const bool revoke_grant) { uint i; - ulong priv,store_rights; + ulonglong priv; + privilege_t store_rights(NO_ACL); bool old_row_exists=0; int error; char what= revoke_grant ? 'N' : 'Y'; @@ -4970,17 +4979,17 @@ class GRANT_COLUMN :public Sql_alloc { public: char *column; - ulong rights; - ulong init_rights; + privilege_t rights; + privilege_t init_rights; uint key_length; - GRANT_COLUMN(String &c, ulong y) :rights (y), init_rights(y) + GRANT_COLUMN(String &c, privilege_t y) :rights (y), init_rights(y) { column= (char*) memdup_root(&grant_memroot,c.ptr(), key_length=c.length()); } /* this constructor assumes thas source->column is allocated in grant_memroot */ GRANT_COLUMN(GRANT_COLUMN *source) : column(source->column), - rights (source->rights), init_rights(0), key_length(source->key_length) { } + rights (source->rights), init_rights(NO_ACL), key_length(source->key_length) { } }; @@ -4996,33 +5005,39 @@ class GRANT_NAME :public Sql_alloc public: acl_host_and_ip host; char *db, *user, *tname, *hash_key; - ulong privs; - ulong init_privs; /* privileges found in physical table */ + privilege_t privs; + privilege_t init_privs; /* privileges found in physical table */ ulonglong sort; size_t key_length; GRANT_NAME(const char *h, const char *d,const char *u, - const char *t, ulong p, bool is_routine); + const char *t, privilege_t p, bool is_routine); GRANT_NAME (TABLE *form, bool is_routine); virtual ~GRANT_NAME() {}; - virtual bool ok() { return privs != 0; } + virtual bool ok() { return privs != NO_ACL; } void set_user_details(const char *h, const char *d, const char *u, const char *t, bool is_routine); }; +static privilege_t get_access_value_from_val_int(Field *field) +{ + return privilege_t(ALL_KNOWN_ACL & (ulonglong) field->val_int()); +} + + class GRANT_TABLE :public GRANT_NAME { public: - ulong cols; - ulong init_cols; /* privileges found in physical table */ + privilege_t cols; + privilege_t init_cols; /* privileges found in physical table */ HASH hash_columns; GRANT_TABLE(const char *h, const char *d,const char *u, - const char *t, ulong p, ulong c); + const char *t, privilege_t p, privilege_t c); GRANT_TABLE (TABLE *form, TABLE *col_privs); ~GRANT_TABLE(); - bool ok() { return privs != 0 || cols != 0; } + bool ok() { return privs != NO_ACL || cols != NO_ACL; } void init_hash() { my_hash_init2(&hash_columns, 4, system_charset_info, 0, 0, 0, @@ -5057,15 +5072,15 @@ void GRANT_NAME::set_user_details(const char *h, const char *d, } GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u, - const char *t, ulong p, bool is_routine) + const char *t, privilege_t p, bool is_routine) :db(0), tname(0), privs(p), init_privs(p) { set_user_details(h, d, u, t, is_routine); } GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, - const char *t, ulong p, ulong c) - :GRANT_NAME(h,d,u,t,p, FALSE), cols(c) + const char *t, privilege_t p, privilege_t c) + :GRANT_NAME(h,d,u,t,p, FALSE), cols(c), init_cols(NO_ACL) { init_hash(); } @@ -5075,6 +5090,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, to 0 */ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine) + :privs(NO_ACL), init_privs(NO_ACL) { user= safe_str(get_field(&grant_memroot,form->field[2])); @@ -5090,7 +5106,6 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine) if (!db || !tname) { /* Wrong table row; Ignore it */ - privs= 0; return; /* purecov: inspected */ } sort= get_magic_sort("hdu", host.hostname, db, user); @@ -5105,14 +5120,14 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine) key_length= (strlen(db) + strlen(user) + strlen(tname) + 3); hash_key= (char*) alloc_root(&grant_memroot, key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - privs = (ulong) form->field[6]->val_int(); + privs = get_access_value_from_val_int(form->field[6]); privs = fix_rights_for_table(privs); init_privs= privs; } GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) - :GRANT_NAME(form, FALSE) + :GRANT_NAME(form, FALSE), cols(NO_ACL), init_cols(NO_ACL) { uchar key[MAX_KEY_LENGTH]; @@ -5120,10 +5135,10 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) { /* Wrong table row; Ignore it */ my_hash_clear(&hash_columns); /* allow for destruction */ - cols= 0; + cols= NO_ACL; return; } - cols= (ulong) form->field[7]->val_int(); + cols= get_access_value_from_val_int(form->field[7]); cols= fix_rights_for_column(cols); /* Initial columns privileges are the same as column privileges on creation. @@ -5155,8 +5170,8 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) if (col_privs->file->ha_index_init(0, 1)) { - cols= 0; - init_cols= 0; + cols= NO_ACL; + init_cols= NO_ACL; return; } @@ -5164,8 +5179,8 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) (key_part_map)15, HA_READ_KEY_EXACT)) { - cols= 0; /* purecov: deadcode */ - init_cols= 0; + cols= NO_ACL; /* purecov: deadcode */ + init_cols= NO_ACL; col_privs->file->ha_index_end(); return; } @@ -5175,18 +5190,18 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) GRANT_COLUMN *mem_check; /* As column name is a string, we don't have to supply a buffer */ res=col_privs->field[4]->val_str(&column_name); - ulong priv= (ulong) col_privs->field[6]->val_int(); + privilege_t priv= get_access_value_from_val_int(col_privs->field[6]); if (!(mem_check = new GRANT_COLUMN(*res, fix_rights_for_column(priv)))) { /* Don't use this entry */ - privs= cols= init_privs= init_cols=0; /* purecov: deadcode */ + privs= cols= init_privs= init_cols= NO_ACL; /* purecov: deadcode */ return; /* purecov: deadcode */ } if (my_hash_insert(&hash_columns, (uchar *) mem_check)) { /* Invalidate this entry */ - privs= cols= init_privs= init_cols=0; + privs= cols= init_privs= init_cols= NO_ACL; return; } } while (!col_privs->file->ha_index_next(col_privs->record[0]) && @@ -5301,7 +5316,7 @@ static int replace_column_table(GRANT_TABLE *g_t, TABLE *table, const LEX_USER &combo, List <LEX_COLUMN> &columns, const char *db, const char *table_name, - ulong rights, bool revoke_grant) + privilege_t rights, bool revoke_grant) { int result=0; uchar key[MAX_KEY_LENGTH]; @@ -5339,7 +5354,7 @@ static int replace_column_table(GRANT_TABLE *g_t, while ((column= iter++)) { - ulong privileges= column->rights; + privilege_t privileges= column->rights; bool old_row_exists=0; uchar user_key[MAX_KEY_LENGTH]; @@ -5371,7 +5386,7 @@ static int replace_column_table(GRANT_TABLE *g_t, } else { - ulong tmp= (ulong) table->field[6]->val_int(); + privilege_t tmp= get_access_value_from_val_int(table->field[6]); tmp=fix_rights_for_column(tmp); if (revoke_grant) @@ -5441,7 +5456,7 @@ static int replace_column_table(GRANT_TABLE *g_t, /* Scan through all rows with the same host,db,user and table */ do { - ulong privileges = (ulong) table->field[6]->val_int(); + privilege_t privileges = get_access_value_from_val_int(table->field[6]); privileges=fix_rights_for_column(privileges); store_record(table,record[1]); @@ -5454,7 +5469,7 @@ static int replace_column_table(GRANT_TABLE *g_t, privileges&= ~rights; table->field[6]->store((longlong) - get_rights_for_column(privileges), TRUE); + get_rights_for_column(privileges), TRUE); table->field[4]->val_str(&column_name); grant_column = column_hash_search(g_t, column_name.ptr(), @@ -5518,13 +5533,13 @@ static inline void get_grantor(THD *thd, char *grantor) static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, TABLE *table, const LEX_USER &combo, const char *db, const char *table_name, - ulong rights, ulong col_rights, + privilege_t rights, privilege_t col_rights, bool revoke_grant) { char grantor[USER_HOST_BUFF_SIZE]; int old_row_exists = 1; int error=0; - ulong store_table_rights, store_col_rights; + privilege_t store_table_rights(NO_ACL), store_col_rights(NO_ACL); uchar user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); @@ -5580,10 +5595,9 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, store_col_rights= get_rights_for_column(col_rights); if (old_row_exists) { - ulong j,k; store_record(table,record[1]); - j = (ulong) table->field[6]->val_int(); - k = (ulong) table->field[7]->val_int(); + privilege_t j= get_access_value_from_val_int(table->field[6]); + privilege_t k= get_access_value_from_val_int(table->field[7]); if (revoke_grant) { @@ -5651,12 +5665,11 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, TABLE *table, const LEX_USER &combo, const char *db, const char *routine_name, const Sp_handler *sph, - ulong rights, bool revoke_grant) + privilege_t rights, bool revoke_grant) { char grantor[USER_HOST_BUFF_SIZE]; int old_row_exists= 1; int error=0; - ulong store_proc_rights; HASH *hash= sph->get_priv_hash(); DBUG_ENTER("replace_routine_table"); @@ -5714,12 +5727,11 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, restore_record(table,record[1]); // Get saved record } - store_proc_rights= get_rights_for_procedure(rights); + privilege_t store_proc_rights= get_rights_for_procedure(rights); if (old_row_exists) { - ulong j; store_record(table,record[1]); - j= (ulong) table->field[6]->val_int(); + privilege_t j= get_access_value_from_val_int(table->field[6]); if (revoke_grant) { @@ -6122,7 +6134,7 @@ typedef Hash_set<ACL_ROLE> role_hash_t; static bool merge_role_global_privileges(ACL_ROLE *grantee) { - ulong old= grantee->access; + privilege_t old= grantee->access; grantee->access= grantee->initial_role_access; DBUG_EXECUTE_IF("role_merge_stats", role_global_merges++;); @@ -6153,7 +6165,7 @@ static int db_name_sort(const int *db1, const int *db2) 2 - ACL_DB was added 4 - ACL_DB was deleted */ -static int update_role_db(int merged, int first, ulong access, +static int update_role_db(int merged, int first, privilege_t access, const char *role) { if (first < 0) @@ -6178,12 +6190,12 @@ static int update_role_db(int merged, int first, ulong access, acl_db.host.ip= acl_db.host.ip_mask= 0; acl_db.db= acl_dbs.at(first).db; acl_db.access= access; - acl_db.initial_access= 0; + acl_db.initial_access= NO_ACL; acl_db.sort= get_magic_sort("hdu", "", acl_db.db, role); acl_dbs.push(acl_db); return 2; } - else if (access == 0) + else if (access == NO_ACL) { /* there is ACL_DB but the role has no db privileges granted @@ -6245,14 +6257,15 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname, is not necessarily the first and may be not present at all. */ int first= -1, merged= -1; - ulong access= 0, update_flags= 0; + privilege_t access(NO_ACL); + ulong update_flags= 0; for (int *p= dbs.front(); p <= dbs.back(); p++) { if (first<0 || (!dbname && strcmp(acl_dbs.at(p[0]).db, acl_dbs.at(p[-1]).db))) { // new db name series update_flags|= update_role_db(merged, first, access, grantee->user.str); merged= -1; - access= 0; + access= NO_ACL; first= *p; } if (strcmp(acl_dbs.at(*p).user, grantee->user.str) == 0) @@ -6310,7 +6323,7 @@ static int update_role_columns(GRANT_TABLE *merged, GRANT_TABLE **cur, GRANT_TABLE **last) { - ulong rights __attribute__((unused))= 0; + privilege_t rights __attribute__((unused)) (NO_ACL); int changed= 0; if (!merged->cols) { @@ -6380,7 +6393,8 @@ static int update_role_columns(GRANT_TABLE *merged, */ static int update_role_table_columns(GRANT_TABLE *merged, GRANT_TABLE **first, GRANT_TABLE **last, - ulong privs, ulong cols, const char *role) + privilege_t privs, privilege_t cols, + const char *role) { if (!first) return 0; @@ -6396,12 +6410,12 @@ static int update_role_table_columns(GRANT_TABLE *merged, DBUG_ASSERT(privs | cols); merged= new (&grant_memroot) GRANT_TABLE("", first[0]->db, role, first[0]->tname, privs, cols); - merged->init_privs= merged->init_cols= 0; + merged->init_privs= merged->init_cols= NO_ACL; update_role_columns(merged, first, last); my_hash_insert(&column_priv_hash,(uchar*) merged); return 2; } - else if ((privs | cols) == 0) + else if ((privs | cols) == NO_ACL) { /* there is GRANT_TABLE object but the role has no table or column @@ -6456,7 +6470,8 @@ static bool merge_role_table_and_column_privileges(ACL_ROLE *grantee, grants.sort(table_name_sort); GRANT_TABLE **first= NULL, *merged= NULL, **cur; - ulong privs= 0, cols= 0, update_flags= 0; + privilege_t privs(NO_ACL), cols(NO_ACL); + ulong update_flags= 0; for (cur= grants.front(); cur <= grants.back(); cur++) { if (!first || @@ -6466,7 +6481,7 @@ static bool merge_role_table_and_column_privileges(ACL_ROLE *grantee, update_flags|= update_role_table_columns(merged, first, cur, privs, cols, grantee->user.str); merged= NULL; - privs= cols= 0; + privs= cols= NO_ACL; first= cur; } if (strcmp(cur[0]->user, grantee->user.str) == 0) @@ -6509,7 +6524,7 @@ static int routine_name_sort(GRANT_NAME * const *r1, GRANT_NAME * const *r2) 4 - GRANT_NAME was deleted */ static int update_role_routines(GRANT_NAME *merged, GRANT_NAME **first, - ulong privs, const char *role, HASH *hash) + privilege_t privs, const char *role, HASH *hash) { if (!first) return 0; @@ -6525,11 +6540,11 @@ static int update_role_routines(GRANT_NAME *merged, GRANT_NAME **first, DBUG_ASSERT(privs); merged= new (&grant_memroot) GRANT_NAME("", first[0]->db, role, first[0]->tname, privs, true); - merged->init_privs= 0; // all privs are inherited + merged->init_privs= NO_ACL; // all privs are inherited my_hash_insert(hash, (uchar *)merged); return 2; } - else if (privs == 0) + else if (privs == NO_ACL) { /* there is GRANT_NAME but the role has no privileges granted @@ -6580,7 +6595,7 @@ static bool merge_role_routine_grant_privileges(ACL_ROLE *grantee, grants.sort(routine_name_sort); GRANT_NAME **first= NULL, *merged= NULL; - ulong privs= 0 ; + privilege_t privs(NO_ACL); for (GRANT_NAME **cur= grants.front(); cur <= grants.back(); cur++) { if (!first || @@ -6590,7 +6605,7 @@ static bool merge_role_routine_grant_privileges(ACL_ROLE *grantee, update_flags|= update_role_routines(merged, first, privs, grantee->user.str, hash); merged= NULL; - privs= 0; + privs= NO_ACL; first= cur; } if (strcmp(cur[0]->user, grantee->user.str) == 0) @@ -6714,10 +6729,10 @@ static bool copy_and_check_auth(LEX_USER *to, LEX_USER *from, THD *thd) int mysql_table_grant(THD *thd, TABLE_LIST *table_list, List <LEX_USER> &user_list, - List <LEX_COLUMN> &columns, ulong rights, + List <LEX_COLUMN> &columns, privilege_t rights, bool revoke_grant) { - ulong column_priv= 0; + privilege_t column_priv(NO_ACL); int result; List_iterator <LEX_USER> str_list (user_list); LEX_USER *Str, *tmp_Str; @@ -6837,7 +6852,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* Create user if needed */ error= copy_and_check_auth(Str, tmp_Str, thd) || replace_user_table(thd, tables.user_table(), Str, - 0, revoke_grant, create_new_users, + NO_ACL, revoke_grant, create_new_users, MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER)); if (unlikely(error)) @@ -6890,7 +6905,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, grant_column->rights&= ~(column->rights | rights); } /* scan trough all columns to get new column grant */ - column_priv= 0; + column_priv= NO_ACL; for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++) { grant_column= (GRANT_COLUMN*) @@ -6967,7 +6982,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, const Sp_handler *sph, - List <LEX_USER> &user_list, ulong rights, + List <LEX_USER> &user_list, privilege_t rights, bool revoke_grant, bool write_to_binlog) { List_iterator <LEX_USER> str_list (user_list); @@ -7017,7 +7032,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, /* Create user if needed */ if (copy_and_check_auth(Str, tmp_Str, thd) || replace_user_table(thd, tables.user_table(), Str, - 0, revoke_grant, create_new_users, + NO_ACL, revoke_grant, create_new_users, MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER))) { @@ -7288,7 +7303,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke) user_combo.user = username; if (copy_and_check_auth(&user_combo, &user_combo, thd) || - replace_user_table(thd, tables.user_table(), &user_combo, 0, + replace_user_table(thd, tables.user_table(), &user_combo, NO_ACL, false, create_new_user, no_auto_create_user)) { @@ -7401,7 +7416,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke) bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, - ulong rights, bool revoke_grant, bool is_proxy) + privilege_t rights, bool revoke_grant, bool is_proxy) { List_iterator <LEX_USER> str_list (list); LEX_USER *Str, *tmp_Str, *proxied_user= NULL; @@ -7460,13 +7475,14 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, if (copy_and_check_auth(Str, tmp_Str, thd) || replace_user_table(thd, tables.user_table(), Str, - (!db ? rights : 0), revoke_grant, create_new_users, + (!db ? rights : NO_ACL), + revoke_grant, create_new_users, MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER))) result= true; else if (db) { - ulong db_rights= rights & DB_ACLS; + privilege_t db_rights(rights & DB_ACLS); if (db_rights == rights) { if (replace_db_table(tables.db_table().table(), db, *Str, db_rights, @@ -7840,14 +7856,14 @@ bool grant_reload(THD *thd) */ -bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, +bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, bool any_combination_will_do, uint number, bool no_errors) { TABLE_LIST *tl; TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); Security_context *sctx= thd->security_ctx; uint i; - ulong original_want_access= want_access; + privilege_t original_want_access(want_access); bool locked= 0; GRANT_TABLE *grant_table; GRANT_TABLE *grant_table_role= NULL; @@ -7881,7 +7897,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, TABLE_LIST *const t_ref= tl->correspondent_table ? tl->correspondent_table : tl; sctx= t_ref->security_ctx ? t_ref->security_ctx : thd->security_ctx; - ulong orig_want_access= original_want_access; + privilege_t orig_want_access(original_want_access); /* If sequence is used as part of NEXT VALUE, PREVIOUS VALUE or SELECT, @@ -7952,7 +7968,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, clause, or an INFORMATION_SCHEMA table, drop the request for a privilege. */ - t_ref->grant.want_privilege= 0; + t_ref->grant.want_privilege= NO_ACL; } continue; } @@ -7966,7 +7982,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, if user has CREATE_TMP_ACL. */ t_ref->grant.privilege|= TMP_TABLE_ACLS; - t_ref->grant.want_privilege= 0; + t_ref->grant.want_privilege= NO_ACL; continue; } @@ -8003,15 +8019,15 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, t_ref->grant.grant_table_user= grant_table; // Remember for column test t_ref->grant.grant_table_role= grant_table_role; t_ref->grant.version= grant_version; - t_ref->grant.privilege|= grant_table ? grant_table->privs : 0; - t_ref->grant.privilege|= grant_table_role ? grant_table_role->privs : 0; + t_ref->grant.privilege|= grant_table ? grant_table->privs : NO_ACL; + t_ref->grant.privilege|= grant_table_role ? grant_table_role->privs : NO_ACL; t_ref->grant.want_privilege= ((want_access & COL_ACLS) & ~t_ref->grant.privilege); if (!(~t_ref->grant.privilege & want_access)) continue; - if ((want_access&= ~((grant_table ? grant_table->cols : 0) | - (grant_table_role ? grant_table_role->cols : 0) | + if ((want_access&= ~((grant_table ? grant_table->cols : NO_ACL) | + (grant_table_role ? grant_table_role->cols : NO_ACL) | t_ref->grant.privilege))) { goto err; // impossible @@ -8065,9 +8081,10 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, GRANT_TABLE *grant_table; GRANT_TABLE *grant_table_role; GRANT_COLUMN *grant_column; - ulong want_access= grant->want_privilege & ~grant->privilege; + privilege_t want_access(grant->want_privilege & ~grant->privilege); DBUG_ENTER("check_grant_column"); - DBUG_PRINT("enter", ("table: %s want_access: %lu", table_name, want_access)); + DBUG_PRINT("enter", ("table: %s want_access: %llx", + table_name, (longlong) want_access)); if (!want_access) DBUG_RETURN(0); // Already checked @@ -8172,7 +8189,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, if (table_ref->view || table_ref->field_translation) { /* View or derived information schema table. */ - ulong view_privs; + privilege_t view_privs(NO_ACL); grant= &(table_ref->grant); db_name= table_ref->view_db.str; table_name= table_ref->view_name.str; @@ -8223,11 +8240,11 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, For each table it will retrieve the grant information and will use it to check the required access privileges for the fields requested from it. */ -bool check_grant_all_columns(THD *thd, ulong want_access_arg, +bool check_grant_all_columns(THD *thd, privilege_t want_access_arg, Field_iterator_table_ref *fields) { Security_context *sctx= thd->security_ctx; - ulong UNINIT_VAR(want_access); + privilege_t want_access(NO_ACL); const char *table_name= NULL; const char* db_name; GRANT_INFO *grant; @@ -8279,7 +8296,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, if (want_access) { - ulong have_access= 0; + privilege_t have_access(NO_ACL); if (grant_table) { GRANT_COLUMN *grant_column= @@ -8446,7 +8463,7 @@ bool check_grant_db(THD *thd, const char *db) 1 Error: User did not have the requested privielges ****************************************************************************/ -bool check_grant_routine(THD *thd, ulong want_access, +bool check_grant_routine(THD *thd, privilege_t want_access, TABLE_LIST *procs, const Sp_handler *sph, bool no_errors) { @@ -8549,9 +8566,8 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, Functions to retrieve the grant for a table/column (for SHOW functions) *****************************************************************************/ -ulong get_table_grant(THD *thd, TABLE_LIST *table) +privilege_t get_table_grant(THD *thd, TABLE_LIST *table) { - ulong privilege; Security_context *sctx= thd->security_ctx; const char *db = table->db.str ? table->db.str : thd->db.str; GRANT_TABLE *grant_table; @@ -8575,7 +8591,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table) table->grant.privilege|= grant_table->privs; if (grant_table_role) table->grant.privilege|= grant_table_role->privs; - privilege= table->grant.privilege; + privilege_t privilege(table->grant.privilege); mysql_rwlock_unlock(&LOCK_grant); return privilege; } @@ -8599,14 +8615,14 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table) The access priviliges for the field db_name.table_name.field_name */ -ulong get_column_grant(THD *thd, GRANT_INFO *grant, - const char *db_name, const char *table_name, - const char *field_name) +privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, + const char *db_name, const char *table_name, + const char *field_name) { GRANT_TABLE *grant_table; GRANT_TABLE *grant_table_role; GRANT_COLUMN *grant_column; - ulong priv= 0; + privilege_t priv(NO_ACL); mysql_rwlock_rdlock(&LOCK_grant); /* reload table if someone has modified any grants */ @@ -9182,7 +9198,7 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, char *buff, size_t buffsize) { uint counter; - ulong want_access; + privilege_t want_access(NO_ACL); Protocol *protocol= thd->protocol; String global(buff,sizeof(buff),system_charset_info); @@ -9200,7 +9216,8 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, else { bool found=0; - ulong j,test_access= want_access & ~GRANT_ACL; + ulonglong j; + privilege_t test_access(want_access & ~GRANT_ACL); for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1) { if (test_access & j) @@ -9233,7 +9250,7 @@ static bool show_database_privileges(THD *thd, const char *username, const char *hostname, char *buff, size_t buffsize) { - ulong want_access; + privilege_t want_access(NO_ACL); Protocol *protocol= thd->protocol; for (uint i=0 ; i < acl_dbs.elements() ; i++) @@ -9275,7 +9292,8 @@ static bool show_database_privileges(THD *thd, const char *username, else { int found=0, cnt; - ulong j,test_access= want_access & ~GRANT_ACL; + ulonglong j; + privilege_t test_access(want_access & ~GRANT_ACL); for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) { if (test_access & j) @@ -9340,8 +9358,8 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, if (!strcmp(username,user) && !my_strcasecmp(system_charset_info, hostname, host)) { - ulong table_access; - ulong cols_access; + privilege_t table_access(NO_ACL); + privilege_t cols_access(NO_ACL); if (*hostname) // User { table_access= grant_table->privs; @@ -9353,10 +9371,10 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, cols_access= grant_table->init_cols; } - if ((table_access | cols_access) != 0) + if ((table_access | cols_access) != NO_ACL) { String global(buff, sizeof(buff), system_charset_info); - ulong test_access= (table_access | cols_access) & ~GRANT_ACL; + privilege_t test_access= (table_access | cols_access) & ~GRANT_ACL; global.length(0); global.append(STRING_WITH_LEN("GRANT ")); @@ -9369,7 +9387,7 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, { /* Add specific column access */ int found= 0; - ulong j; + ulonglong j; for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1) { @@ -9482,16 +9500,16 @@ static int show_routine_grants(THD* thd, if (!strcmp(username, user) && !my_strcasecmp(system_charset_info, hostname, host)) { - ulong proc_access; + privilege_t proc_access(NO_ACL); if (*hostname) // User proc_access= grant_proc->privs; else // Role proc_access= grant_proc->init_privs; - if (proc_access != 0) + if (proc_access != NO_ACL) { String global(buff, buffsize, system_charset_info); - ulong test_access= proc_access & ~GRANT_ACL; + privilege_t test_access(proc_access & ~GRANT_ACL); global.length(0); global.append(STRING_WITH_LEN("GRANT ")); @@ -9502,7 +9520,7 @@ static int show_routine_grants(THD* thd, { /* Add specific procedure access */ int found= 0; - ulong j; + ulonglong j; for (counter= 0, j= SELECT_ACL; j <= PROC_ACLS; counter++, j<<= 1) { @@ -9554,13 +9572,13 @@ static int show_routine_grants(THD* thd, Make a clear-text version of the requested privilege. */ -void get_privilege_desc(char *to, uint max_length, ulong access) +void get_privilege_desc(char *to, uint max_length, privilege_t access_arg) { uint pos; char *start=to; DBUG_ASSERT(max_length >= 30); // For end ', ' removal - if (access) + if (ulonglong access= access_arg) { max_length--; // Reserve place for end-zero for (pos=0 ; access ; pos++, access>>=1) @@ -10598,7 +10616,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role) } } - if (replace_user_table(thd, tables.user_table(), user_name, 0, 0, 1, 0)) + if (replace_user_table(thd, tables.user_table(), user_name, + NO_ACL, 0, 1, 0)) { append_user(thd, &wrong_users, user_name); result= TRUE; @@ -10900,8 +10919,9 @@ int mysql_alter_user(THD* thd, List<LEX_USER> &users_list) while ((tmp_lex_user= users_list_iterator++)) { LEX_USER* lex_user= get_current_user(thd, tmp_lex_user, false); - if (!lex_user || replace_user_table(thd, tables.user_table(), lex_user, 0, - false, false, true)) + if (!lex_user || + replace_user_table(thd, tables.user_table(), lex_user, NO_ACL, + false, false, true)) { thd->clear_error(); append_user(thd, &wrong_users, tmp_lex_user); @@ -10963,7 +10983,7 @@ mysql_revoke_sp_privs(THD *thd, Grant_tables *tables, const Sp_handler *sph, tables->procs_priv_table().table(), *lex_user, grant_proc->db, grant_proc->tname, - sph, ~(ulong)0, 1) == 0) + sph, ALL_KNOWN_ACL, 1) == 0) { revoked= 1; continue; @@ -11029,7 +11049,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) } if (replace_user_table(thd, tables.user_table(), lex_user, - ~(ulong)0, 1, 0, 0)) + ALL_KNOWN_ACL, 1, 0, 0)) { result= -1; continue; @@ -11058,7 +11078,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) /* TODO(cvicentiu) refactor replace_db_table to use Db_table instead of TABLE directly. */ if (!replace_db_table(tables.db_table().table(), acl_db->db, *lex_user, - ~(ulong)0, 1)) + ALL_KNOWN_ACL, 1)) { /* Don't increment counter as replace_db_table deleted the @@ -11092,7 +11112,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) if (replace_table_table(thd, grant_table, tables.tables_priv_table().table(), *lex_user, grant_table->db, - grant_table->tname, ~(ulong)0, 0, 1)) + grant_table->tname, ALL_KNOWN_ACL, NO_ACL, 1)) { result= -1; } @@ -11109,7 +11129,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) if (!replace_column_table(grant_table, tables.columns_priv_table().table(), *lex_user, columns, grant_table->db, - grant_table->tname, ~(ulong)0, 1)) + grant_table->tname, ALL_KNOWN_ACL, 1)) { revoked= 1; continue; @@ -11318,7 +11338,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, if (replace_routine_table(thd, grant_proc, tables.procs_priv_table().table(), lex_user, grant_proc->db, grant_proc->tname, - sph, ~(ulong)0, 1) == 0) + sph, ALL_KNOWN_ACL, 1) == 0) { revoked= 1; continue; @@ -11652,7 +11672,7 @@ static int show_database_grants(THD *thd, SHOW_VAR *var, char *buff, #else static bool set_user_salt_if_needed(ACL_USER *, int, plugin_ref) { return 0; } -bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool) +bool check_grant(THD *, privilege_t, TABLE_LIST *, bool, uint, bool) { return 0; } #endif /*NO_EMBEDDED_ACCESS_CHECKS */ @@ -11741,7 +11761,7 @@ 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 + DBUG_ASSERT((m_grant_option & ~GRANT_ACL) == NO_ACL); // only WITH GRANT OPTION grant_stage0(thd); @@ -11767,7 +11787,7 @@ wsrep_error_label: 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; + privilege_t 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)) @@ -11802,7 +11822,7 @@ bool Sql_cmd_grant_sp::execute(THD *thd) 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 + privilege_t grants= m_all_privileges ? (PROC_ACLS & ~GRANT_ACL) | (m_object_privilege & GRANT_ACL) : m_object_privilege; @@ -12068,7 +12088,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int error= 0; uint counter; ACL_USER *acl_user; - ulong want_access; char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", @@ -12090,7 +12109,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) !thd->security_ctx->is_priv_user(user, host)) continue; - want_access= acl_user->access; + privilege_t want_access(acl_user->access); if (!(want_access & GRANT_ACL)) is_grantable= "NO"; @@ -12107,7 +12126,8 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) else { uint priv_id; - ulong j,test_access= want_access & ~GRANT_ACL; + ulonglong j; + privilege_t test_access(want_access & ~GRANT_ACL); for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1) { if (test_access & j) @@ -12139,7 +12159,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int error= 0; uint counter; ACL_DB *acl_db; - ulong want_access; char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", @@ -12162,7 +12181,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) !thd->security_ctx->is_priv_user(user, host)) continue; - want_access=acl_db->access; + privilege_t want_access(acl_db->access); if (want_access) { if (!(want_access & GRANT_ACL)) @@ -12182,7 +12201,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) else { int cnt; - ulong j,test_access= want_access & ~GRANT_ACL; + ulonglong j; + privilege_t test_access(want_access & ~GRANT_ACL); for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) if (test_access & j) { @@ -12232,10 +12252,10 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) !thd->security_ctx->is_priv_user(user, host)) continue; - ulong table_access= grant_table->privs; + privilege_t table_access(grant_table->privs); if (table_access) { - ulong test_access= table_access & ~GRANT_ACL; + privilege_t test_access(table_access & ~GRANT_ACL); /* We should skip 'usage' privilege on table if we have any privileges on column(s) of this table @@ -12258,7 +12278,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } else { - ulong j; + ulonglong j; int cnt; for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) { @@ -12312,19 +12332,19 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) !thd->security_ctx->is_priv_user(user, host)) continue; - ulong table_access= grant_table->cols; - if (table_access != 0) + privilege_t table_access(grant_table->cols); + if (table_access != NO_ACL) { if (!(grant_table->privs & GRANT_ACL)) is_grantable= "NO"; - ulong test_access= table_access & ~GRANT_ACL; + privilege_t test_access(table_access & ~GRANT_ACL); strxmov(buff, "'", user, "'@'", host, "'", NullS); if (!test_access) continue; else { - ulong j; + ulonglong j; int cnt; for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) { @@ -12388,8 +12408,8 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, if (!initialized) { DBUG_PRINT("info", ("skip grants")); - grant->privilege= ~NO_ACCESS; // everything is allowed - DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); + grant->privilege= ALL_KNOWN_ACL; // everything is allowed + DBUG_PRINT("info", ("privilege 0x%llx", (longlong) grant->privilege)); DBUG_VOID_RETURN; } @@ -12433,7 +12453,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, } mysql_rwlock_unlock(&LOCK_grant); - DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); + DBUG_PRINT("info", ("privilege 0x%llx", (longlong) grant->privilege)); DBUG_VOID_RETURN; } @@ -14131,11 +14151,11 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) DBUG_PRINT("info", ("Capabilities: %llu packet_length: %ld Host: '%s' " "Login user: '%s' Priv_user: '%s' Using password: %s " - "Access: %lu db: '%s'", + "Access: %llx db: '%s'", thd->client_capabilities, thd->max_client_packet_length, sctx->host_or_ip, sctx->user, sctx->priv_user, thd->password ? "yes": "no", - sctx->master_access, mpvio.db.str)); + (longlong) sctx->master_access, mpvio.db.str)); if (command == COM_CONNECT && !(thd->main_security_ctx.master_access & SUPER_ACL)) @@ -14152,14 +14172,14 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) set to 0 here because we don't have an active database yet (and we may not have an active database to set. */ - sctx->db_access=0; + sctx->db_access= NO_ACL; #ifndef NO_EMBEDDED_ACCESS_CHECKS /* In case the user has a default role set, attempt to set that role */ if (initialized && acl_user->default_rolename.length) { - ulonglong access= 0; + privilege_t access(NO_ACL); int result; result= acl_check_setrole(thd, acl_user->default_rolename.str, &access); if (!result) diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 4147981bb98..000228945f4 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -22,144 +22,6 @@ #include "grant.h" #include "sql_cmd.h" /* Sql_cmd */ -#define SELECT_ACL (1UL << 0) -#define INSERT_ACL (1UL << 1) -#define UPDATE_ACL (1UL << 2) -#define DELETE_ACL (1UL << 3) -#define CREATE_ACL (1UL << 4) -#define DROP_ACL (1UL << 5) -#define RELOAD_ACL (1UL << 6) -#define SHUTDOWN_ACL (1UL << 7) -#define PROCESS_ACL (1UL << 8) -#define FILE_ACL (1UL << 9) -#define GRANT_ACL (1UL << 10) -#define REFERENCES_ACL (1UL << 11) -#define INDEX_ACL (1UL << 12) -#define ALTER_ACL (1UL << 13) -#define SHOW_DB_ACL (1UL << 14) -#define SUPER_ACL (1UL << 15) -#define CREATE_TMP_ACL (1UL << 16) -#define LOCK_TABLES_ACL (1UL << 17) -#define EXECUTE_ACL (1UL << 18) -#define REPL_SLAVE_ACL (1UL << 19) -#define REPL_CLIENT_ACL (1UL << 20) -#define CREATE_VIEW_ACL (1UL << 21) -#define SHOW_VIEW_ACL (1UL << 22) -#define CREATE_PROC_ACL (1UL << 23) -#define ALTER_PROC_ACL (1UL << 24) -#define CREATE_USER_ACL (1UL << 25) -#define EVENT_ACL (1UL << 26) -#define TRIGGER_ACL (1UL << 27) -#define CREATE_TABLESPACE_ACL (1UL << 28) -#define DELETE_HISTORY_ACL (1UL << 29) -/* - don't forget to update - 1. static struct show_privileges_st sys_privileges[] - 2. static const char *command_array[] and static uint command_lengths[] - 3. mysql_system_tables.sql and mysql_system_tables_fix.sql - 4. acl_init() or whatever - to define behaviour for old privilege tables - 5. sql_yacc.yy - for GRANT/REVOKE to work -*/ -#define NO_ACCESS (1UL << 30) -#define DB_ACLS \ -(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \ - LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ - CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL | \ - DELETE_HISTORY_ACL) - -#define TABLE_ACLS \ -(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \ - SHOW_VIEW_ACL | TRIGGER_ACL | DELETE_HISTORY_ACL) - -#define COL_ACLS \ -(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL) - -#define PROC_ACLS \ -(ALTER_PROC_ACL | EXECUTE_ACL | GRANT_ACL) - -#define SHOW_PROC_ACLS \ -(ALTER_PROC_ACL | EXECUTE_ACL | CREATE_PROC_ACL) - -#define GLOBAL_ACLS \ -(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \ - REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \ - CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \ - EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \ - ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL | \ - CREATE_TABLESPACE_ACL | DELETE_HISTORY_ACL) - -#define DEFAULT_CREATE_PROC_ACLS \ -(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) - -/** - Table-level privileges which are automatically "granted" to everyone on - existing temporary tables (CREATE_ACL is necessary for ALTER ... RENAME). -*/ -#define TMP_TABLE_ACLS \ -(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - INDEX_ACL | ALTER_ACL) - -/* - 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 -*/ - -/* Privileges that needs to be reallocated (in continous chunks) */ -#define DB_CHUNK0 (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \ - CREATE_ACL | DROP_ACL) -#define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL) -#define DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL) -#define DB_CHUNK3 (CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ - CREATE_PROC_ACL | ALTER_PROC_ACL ) -#define DB_CHUNK4 (EXECUTE_ACL) -#define DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL) -#define DB_CHUNK6 (DELETE_HISTORY_ACL) - -#define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \ - (((A) << 4) & DB_CHUNK1) | \ - (((A) << 6) & DB_CHUNK2) | \ - (((A) << 9) & DB_CHUNK3) | \ - (((A) << 2) & DB_CHUNK4) | \ - (((A) << 9) & DB_CHUNK5) | \ - (((A) << 10) & DB_CHUNK6)) -#define get_rights_for_db(A) (((A) & DB_CHUNK0) | \ - (((A) & DB_CHUNK1) >> 4) | \ - (((A) & DB_CHUNK2) >> 6) | \ - (((A) & DB_CHUNK3) >> 9) | \ - (((A) & DB_CHUNK4) >> 2) | \ - (((A) & DB_CHUNK5) >> 9) | \ - (((A) & DB_CHUNK6) >> 10)) -#define TBL_CHUNK0 DB_CHUNK0 -#define TBL_CHUNK1 DB_CHUNK1 -#define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL) -#define TBL_CHUNK3 TRIGGER_ACL -#define TBL_CHUNK4 (DELETE_HISTORY_ACL) -#define fix_rights_for_table(A) (((A) & TBL_CHUNK0) | \ - (((A) << 4) & TBL_CHUNK1) | \ - (((A) << 11) & TBL_CHUNK2) | \ - (((A) << 15) & TBL_CHUNK3) | \ - (((A) << 16) & TBL_CHUNK4)) -#define get_rights_for_table(A) (((A) & TBL_CHUNK0) | \ - (((A) & TBL_CHUNK1) >> 4) | \ - (((A) & TBL_CHUNK2) >> 11) | \ - (((A) & TBL_CHUNK3) >> 15) | \ - (((A) & TBL_CHUNK4) >> 16)) -#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8)) -#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8)) -#define fix_rights_for_procedure(A) ((((A) << 18) & EXECUTE_ACL) | \ - (((A) << 23) & ALTER_PROC_ACL) | \ - (((A) << 8) & GRANT_ACL)) -#define get_rights_for_procedure(A) ((((A) & EXECUTE_ACL) >> 18) | \ - (((A) & ALTER_PROC_ACL) >> 23) | \ - (((A) & GRANT_ACL) >> 8)) enum mysql_db_table_field { @@ -214,8 +76,8 @@ bool hostname_requires_resolving(const char *hostname); bool acl_init(bool dont_read_acl_tables); bool acl_reload(THD *thd); void acl_free(bool end=0); -ulong acl_get(const char *host, const char *ip, - const char *user, const char *db, my_bool db_is_pattern); +privilege_t acl_get(const char *host, const char *ip, + const char *user, const char *db, my_bool db_is_pattern); bool acl_authenticate(THD *thd, uint com_change_user_pkt_len); bool acl_getroot(Security_context *sctx, const char *user, const char *host, const char *ip, const char *db); @@ -225,37 +87,38 @@ bool change_password(THD *thd, LEX_USER *user); bool mysql_grant_role(THD *thd, List<LEX_USER> &user_list, bool revoke); bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, - ulong rights, bool revoke, bool is_proxy); + privilege_t rights, bool revoke, bool is_proxy); int 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, privilege_t rights, bool revoke); bool mysql_routine_grant(THD *thd, TABLE_LIST *table, const Sp_handler *sph, - List <LEX_USER> &user_list, ulong rights, + List <LEX_USER> &user_list, privilege_t rights, bool revoke, bool write_to_binlog); bool grant_init(); void grant_free(void); bool grant_reload(THD *thd); -bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, +bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, bool any_combination_will_do, uint number, bool no_errors); bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, size_t length, Security_context *sctx); bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, const char *name, size_t length, Field *fld); -bool check_grant_all_columns(THD *thd, ulong want_access, +bool check_grant_all_columns(THD *thd, privilege_t want_access, Field_iterator_table_ref *fields); -bool check_grant_routine(THD *thd, ulong want_access, +bool check_grant_routine(THD *thd, privilege_t want_access, TABLE_LIST *procs, const Sp_handler *sph, bool no_error); bool check_grant_db(THD *thd,const char *db); -bool check_global_access(THD *thd, ulong want_access, bool no_errors= false); -bool check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, +bool check_global_access(THD *thd, const privilege_t want_access, bool no_errors= false); +bool check_access(THD *thd, privilege_t want_access, + const char *db, privilege_t *save_priv, GRANT_INTERNAL_INFO *grant_internal_info, bool dont_check_global_grants, bool no_errors); -ulong get_table_grant(THD *thd, TABLE_LIST *table); -ulong get_column_grant(THD *thd, GRANT_INFO *grant, - const char *db_name, const char *table_name, - const char *field_name); +privilege_t get_table_grant(THD *thd, TABLE_LIST *table); +privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, + const char *db_name, const char *table_name, + const char *field_name); bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username, const char **hostname, const char **rolename); void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, @@ -264,7 +127,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *user); bool mysql_show_create_user(THD *thd, LEX_USER *user); int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond); -void get_privilege_desc(char *to, uint max_length, ulong access); +void get_privilege_desc(char *to, uint max_length, privilege_t access); void get_mqh(const char *user, const char *host, USER_CONN *uc); bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role); bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role); @@ -345,8 +208,8 @@ public: privilege. Requested privileges that are granted, if any, are saved in save_priv. */ - virtual ACL_internal_access_result check(ulong want_access, - ulong *save_priv) const= 0; + virtual ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const= 0; }; /** @@ -382,8 +245,8 @@ public: privilege. Requested privileges that are granted, if any, are saved in save_priv. */ - virtual ACL_internal_access_result check(ulong want_access, - ulong *save_priv) const= 0; + virtual ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const= 0; /** Search for per table ACL access rules by table name. @@ -417,8 +280,8 @@ get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info, bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user, bool with_grant); -int acl_setrole(THD *thd, const char *rolename, ulonglong access); -int acl_check_setrole(THD *thd, const char *rolename, ulonglong *access); +int acl_setrole(THD *thd, const char *rolename, privilege_t access); +int acl_check_setrole(THD *thd, const char *rolename, privilege_t *access); int acl_check_set_default_role(THD *thd, const char *host, const char *user); int acl_set_default_role(THD *thd, const char *host, const char *user, const char *rolename); @@ -459,12 +322,12 @@ public: class Sql_cmd_grant_proxy: public Sql_cmd_grant { - uint m_grant_option; + privilege_t 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_proxy(enum_sql_command command, privilege_t grant_option) :Sql_cmd_grant(command), m_grant_option(grant_option) { } bool execute(THD *thd); diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index bc4c903d05d..f3dd46b5139 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -395,8 +395,8 @@ bool Sql_cmd_alter_table::execute(THD *thd) HA_CREATE_INFO create_info(lex->create_info); Alter_info alter_info(lex->alter_info, thd->mem_root); create_info.alter_info= &alter_info; - ulong priv=0; - ulong priv_needed= ALTER_ACL; + privilege_t priv(NO_ACL); + privilege_t priv_needed(ALTER_ACL); bool result; DBUG_ENTER("Sql_cmd_alter_table::execute"); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 60e2b9957a4..c88aef09c96 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -261,7 +261,7 @@ static my_bool list_open_tables_callback(TDC_element *element, arg->table_list.db.length= db_length; arg->table_list.table_name.str= table_name; arg->table_list.table_name.length= strlen(table_name); - arg->table_list.grant.privilege= 0; + arg->table_list.grant.privilege= NO_ACL; if (check_table_access(arg->thd, SELECT_ACL, &arg->table_list, TRUE, 1, TRUE)) return FALSE; @@ -7878,8 +7878,8 @@ bool setup_tables_and_check_access(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, bool select_insert, - ulong want_access_first, - ulong want_access, + privilege_t want_access_first, + privilege_t want_access, bool full_table_list) { DBUG_ENTER("setup_tables_and_check_access"); @@ -7890,7 +7890,7 @@ bool setup_tables_and_check_access(THD *thd, List_iterator<TABLE_LIST> ti(leaves); TABLE_LIST *table_list; - ulong access= want_access_first; + privilege_t access= want_access_first; while ((table_list= ti++)) { if (table_list->belong_to_view && !table_list->view && diff --git a/sql/sql_base.h b/sql/sql_base.h index 6b641a90212..572dd487d4a 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -218,8 +218,8 @@ bool setup_tables_and_check_access(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, bool select_insert, - ulong want_access_first, - ulong want_access, + privilege_t want_access_first, + privilege_t want_access, bool full_table_list); bool wait_while_table_is_used(THD *thd, TABLE *table, enum ha_extra_function function); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a0d2924009f..2ffb61a98f2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -35,7 +35,7 @@ #include "sql_base.h" // close_thread_tables #include "sql_time.h" // date_time_format_copy #include "tztime.h" // MYSQL_TIME <-> my_time_t -#include "sql_acl.h" // NO_ACCESS, +#include "sql_acl.h" // NO_ACL, // acl_getroot_no_password #include "sql_base.h" #include "sql_handler.h" // mysql_ha_cleanup @@ -644,6 +644,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) m_digest(NULL), m_statement_psi(NULL), m_idle_psi(NULL), + col_access(NO_ACL), thread_id(id), thread_dbug_id(id), os_thread_id(0), @@ -766,7 +767,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) count_cuted_fields= CHECK_FIELD_IGNORE; killed= NOT_KILLED; killed_err= 0; - col_access=0; is_slave_error= thread_specific_used= FALSE; my_hash_clear(&handler_tables_hash); my_hash_clear(&ull_hash); @@ -4292,10 +4292,10 @@ void Security_context::init() host= user= ip= external_user= 0; host_or_ip= "connecting host"; priv_user[0]= priv_host[0]= proxy_user[0]= priv_role[0]= '\0'; - master_access= 0; + master_access= NO_ACL; password_expired= false; #ifndef NO_EMBEDDED_ACCESS_CHECKS - db_access= NO_ACCESS; + db_access= NO_ACL; #endif } @@ -4330,7 +4330,7 @@ void Security_context::skip_grants() { /* privileges for the user are unknown everything is allowed */ host_or_ip= (char *)""; - master_access= ~NO_ACCESS; + master_access= ALL_KNOWN_ACL; *priv_user= *priv_host= '\0'; password_expired= false; } @@ -4343,10 +4343,11 @@ bool Security_context::set_user(char *user_arg) return user == 0; } -bool Security_context::check_access(ulong want_access, bool match_any) +bool Security_context::check_access(const privilege_t want_access, + bool match_any) { DBUG_ENTER("Security_context::check_access"); - DBUG_RETURN((match_any ? (master_access & want_access) + DBUG_RETURN((match_any ? (master_access & want_access) != NO_ACL : ((master_access & want_access) == want_access))); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 0891cd214f8..dcf72bdbacf 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -440,8 +440,8 @@ class LEX_COLUMN : public Sql_alloc { public: String column; - uint rights; - LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} + privilege_t rights; + LEX_COLUMN (const String& x,const privilege_t & y ): column (x),rights (y) {} }; class MY_LOCALE; @@ -1303,7 +1303,10 @@ struct st_savepoint { class Security_context { public: - Security_context() {} /* Remove gcc warning */ + Security_context() + :master_access(NO_ACL), + db_access(NO_ACL) + {} /* Remove gcc warning */ /* host - host of the client user - user of the client, set to NULL until the user has been read from @@ -1323,8 +1326,8 @@ public: char *external_user; /* points to host if host is available, otherwise points to ip */ const char *host_or_ip; - ulong master_access; /* Global privileges from mysql.user */ - ulong db_access; /* Privileges for current db */ + privilege_t master_access; /* Global privileges from mysql.user */ + privilege_t db_access; /* Privileges for current db */ bool password_expired; @@ -1357,7 +1360,7 @@ public: * privileges. @return True if the security context fulfills the access requirements. */ - bool check_access(ulong want_access, bool match_any = false); + bool check_access(const privilege_t want_access, bool match_any = false); bool is_priv_user(const char *user, const char *host); }; @@ -2993,7 +2996,7 @@ public: update auto-updatable fields (like auto_increment and timestamp). */ query_id_t query_id; - ulong col_access; + privilege_t col_access; /* Statement id is thread-wide. This counter is used to generate ids */ ulong statement_id_counter; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 0add71b7b11..e2a3c482ae4 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -35,7 +35,7 @@ #include "sql_db.h" // mysql_change_db #include "hostname.h" // inc_host_errors, ip_to_hostname, // reset_host_errors -#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL +#include "privilege.h" // acl_getroot, SUPER_ACL #include "sql_callback.h" #ifdef WITH_WSREP diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 38dba2c11fd..ae7f26370fa 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -61,7 +61,7 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error); static void mysql_change_db_impl(THD *thd, LEX_CSTRING *new_db_name, - ulong new_db_access, + privilege_t new_db_access, CHARSET_INFO *new_db_charset); static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silent); @@ -1088,7 +1088,7 @@ exit: */ if (unlikely(thd->db.str && cmp_db_names(&thd->db, db) && !error)) { - mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); thd->session_tracker.current_schema.mark_as_changed(thd); } my_dirend(dirp); @@ -1352,7 +1352,7 @@ err: static void mysql_change_db_impl(THD *thd, LEX_CSTRING *new_db_name, - ulong new_db_access, + privilege_t new_db_access, CHARSET_INFO *new_db_charset) { /* 1. Change current database in THD. */ @@ -1501,7 +1501,7 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, LEX_CSTRING new_db_file_name; Security_context *sctx= thd->security_ctx; - ulong db_access= sctx->db_access; + privilege_t db_access(sctx->db_access); CHARSET_INFO *db_default_cl; DBUG_ENTER("mysql_change_db"); @@ -1518,7 +1518,7 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, new_db_name->length == 0. */ - mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); goto done; } @@ -1570,7 +1570,7 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, my_free(const_cast<char*>(new_db_file_name.str)); if (force_switch) - mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); DBUG_RETURN(ER_WRONG_DB_NAME); } @@ -1622,7 +1622,7 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, /* Change db to NULL. */ - mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); /* The operation succeed. */ goto done; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index cbd2e953d7b..ea60d0cebd0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11241,7 +11241,7 @@ bool LEX::add_column_foreign_key(const LEX_CSTRING *name, bool LEX::stmt_grant_table(THD *thd, Grant_privilege *grant, const Lex_grant_object_name &ident, - uint grant_option) + privilege_t grant_option) { sql_command= SQLCOM_GRANT; return @@ -11256,7 +11256,7 @@ bool LEX::stmt_revoke_table(THD *thd, { sql_command= SQLCOM_REVOKE; return - grant->set_object_name(thd, ident, current_select, 0) || + grant->set_object_name(thd, ident, current_select, NO_ACL) || !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_table(sql_command, *grant)); } @@ -11265,7 +11265,7 @@ bool LEX::stmt_grant_sp(THD *thd, Grant_privilege *grant, const Lex_grant_object_name &ident, const Sp_handler &sph, - uint grant_option) + privilege_t grant_option) { sql_command= SQLCOM_GRANT; return @@ -11283,14 +11283,14 @@ bool LEX::stmt_revoke_sp(THD *thd, { sql_command= SQLCOM_REVOKE; return - grant->set_object_name(thd, ident, current_select, 0) || + grant->set_object_name(thd, ident, current_select, NO_ACL) || 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) +bool LEX::stmt_grant_proxy(THD *thd, LEX_USER *user, privilege_t grant_option) { users_list.push_front(user); sql_command= SQLCOM_GRANT; @@ -11303,5 +11303,6 @@ 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)); + return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_proxy(sql_command, + NO_ACL)); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ad1bd6adfa2..2d08aa6c79b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -187,14 +187,14 @@ public: struct Lex_column_list_privilege_st { List<Lex_ident_sys> *m_columns; - uint m_privilege; + privilege_t 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) + Lex_column_list_privilege(List<Lex_ident_sys> *columns, privilege_t privilege) { m_columns= columns; m_privilege= privilege; @@ -3126,7 +3126,7 @@ class Lex_grant_privilege: public Grant_privilege, public Sql_alloc { public: Lex_grant_privilege() {} - Lex_grant_privilege(uint grant, bool all_privileges= false) + Lex_grant_privilege(privilege_t grant, bool all_privileges= false) :Grant_privilege(grant, all_privileges) { } }; @@ -4417,7 +4417,7 @@ public: bool stmt_grant_table(THD *thd, Grant_privilege *grant, const Lex_grant_object_name &ident, - uint grant_option); + privilege_t grant_option); bool stmt_revoke_table(THD *thd, Grant_privilege *grant, @@ -4427,14 +4427,14 @@ public: Grant_privilege *grant, const Lex_grant_object_name &ident, const Sp_handler &sph, - uint grant_option); + privilege_t 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_grant_proxy(THD *thd, LEX_USER *user, privilege_t 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 ab8af4e9b96..141dfd9be65 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -998,7 +998,7 @@ int bootstrap(MYSQL_FILE *file) thd->bootstrap=1; my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0)); thd->max_client_packet_length= thd->net.max_packet; - thd->security_ctx->master_access= ~(ulong)0; + thd->security_ctx->master_access= ALL_KNOWN_ACL; #ifndef EMBEDDED_LIBRARY mysql_thread_set_psi_id(thd->thread_id); @@ -1404,8 +1404,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) LEX *lex= thd->lex; /* Super user is allowed to do changes */ - if (((ulong)(thd->security_ctx->master_access & SUPER_ACL) == - (ulong)SUPER_ACL)) + if ((thd->security_ctx->master_access & SUPER_ACL) == SUPER_ACL) DBUG_RETURN(FALSE); /* Check if command doesn't update anything */ @@ -1445,7 +1444,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables) { int opt_readonly_saved = opt_readonly; - ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL); + privilege_t flag_saved= thd->security_ctx->master_access & SUPER_ACL; opt_readonly = 0; thd->security_ctx->master_access &= ~SUPER_ACL; @@ -3170,7 +3169,8 @@ wsrep_error_label: from other cases: bad database error, no access error. This can be done by testing thd->is_error(). */ -static bool prepare_db_action(THD *thd, ulong want_access, LEX_CSTRING *dbname) +static bool prepare_db_action(THD *thd, privilege_t want_access, + LEX_CSTRING *dbname) { if (check_db_name((LEX_STRING*)dbname)) { @@ -3890,8 +3890,8 @@ mysql_execute_command(THD *thd) lex->exchange != NULL implies SELECT .. INTO OUTFILE and this requires FILE_ACL access. */ - ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : - SELECT_ACL; + privilege_t privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : + SELECT_ACL; if (all_tables) res= check_table_access(thd, @@ -4928,9 +4928,9 @@ mysql_execute_command(THD *thd) case SQLCOM_LOAD: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - uint privilege= (lex->duplicates == DUP_REPLACE ? - INSERT_ACL | DELETE_ACL : INSERT_ACL) | - (lex->local_file ? 0 : FILE_ACL); + privilege_t privilege= (lex->duplicates == DUP_REPLACE ? + INSERT_ACL | DELETE_ACL : INSERT_ACL) | + (lex->local_file ? NO_ACL : FILE_ACL); if (lex->local_file) { @@ -6521,7 +6521,8 @@ wsrep_error_label: */ bool -check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, +check_access(THD *thd, privilege_t want_access, + const char *db, privilege_t *save_priv, GRANT_INTERNAL_INFO *grant_internal_info, bool dont_check_global_grants, bool no_errors) { @@ -6531,7 +6532,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, return false; #else Security_context *sctx= thd->security_ctx; - ulong db_access; + privilege_t db_access(NO_ACL); /* GRANT command: @@ -6543,17 +6544,19 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, set db_is_pattern according to 'dont_check_global_grants' value. */ bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants); - ulong dummy; + privilege_t dummy(NO_ACL); DBUG_ENTER("check_access"); - DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu", - db ? db : "", want_access, sctx->master_access)); + DBUG_PRINT("enter",("db: %s want_access: %llx master_access: %llx", + db ? db : "", + (longlong) want_access, + (longlong) sctx->master_access)); if (save_priv) - *save_priv=0; + *save_priv= NO_ACL; else { save_priv= &dummy; - dummy= 0; + dummy= NO_ACL; } /* check access may be called twice in a row. Don't change to same stage */ @@ -6671,8 +6674,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, } else db_access= sctx->db_access; - DBUG_PRINT("info",("db_access: %lu want_access: %lu", - db_access, want_access)); + DBUG_PRINT("info",("db_access: %llx want_access: %llx", + (longlong) db_access, (longlong) want_access)); /* Save the union of User-table and the intersection between Db-table and @@ -6740,7 +6743,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, 1 access denied, error is sent to client */ -bool check_single_table_access(THD *thd, ulong privilege, +bool check_single_table_access(THD *thd, privilege_t privilege, TABLE_LIST *all_tables, bool no_errors) { Switch_to_definer_security_ctx backup_sctx(thd, all_tables); @@ -6781,7 +6784,8 @@ bool check_single_table_access(THD *thd, ulong privilege, 1 access denied, error is sent to client */ -bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) +bool check_one_table_access(THD *thd, privilege_t privilege, + TABLE_LIST *all_tables) { if (check_single_table_access (thd,privilege,all_tables, FALSE)) return 1; @@ -6933,7 +6937,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) */ bool -check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, +check_table_access(THD *thd, privilege_t requirements, TABLE_LIST *tables, bool any_combination_of_privileges_will_do, uint number, bool no_errors) { @@ -6952,7 +6956,7 @@ check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, tables->correspondent_table : tables; Switch_to_definer_security_ctx backup_ctx(thd, table_ref); - ulong want_access= requirements; + privilege_t want_access(requirements); /* Register access for view underlying table. @@ -6995,7 +6999,7 @@ check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, bool -check_routine_access(THD *thd, ulong want_access, const LEX_CSTRING *db, +check_routine_access(THD *thd, privilege_t want_access, const LEX_CSTRING *db, const LEX_CSTRING *name, const Sp_handler *sph, bool no_errors) { @@ -7017,7 +7021,7 @@ check_routine_access(THD *thd, ulong want_access, const LEX_CSTRING *db, as long as this code path is not abused to create routines. The assert enforce that. */ - DBUG_ASSERT((want_access & CREATE_PROC_ACL) == 0); + DBUG_ASSERT((want_access & CREATE_PROC_ACL) == NO_ACL); if ((thd->security_ctx->master_access & want_access) == want_access) tables->grant.privilege= want_access; else if (check_access(thd, want_access, db->str, @@ -7046,7 +7050,7 @@ check_routine_access(THD *thd, ulong want_access, const LEX_CSTRING *db, bool check_some_routine_access(THD *thd, const char *db, const char *name, const Sp_handler *sph) { - ulong save_priv; + privilege_t save_priv(NO_ACL); /* The following test is just a shortcut for check_access() (to avoid calculating db_access) @@ -7077,16 +7081,15 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name, 1 error */ -bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) +bool check_some_access(THD *thd, privilege_t want_access, TABLE_LIST *table) { - ulong access; DBUG_ENTER("check_some_access"); - /* This loop will work as long as we have less than 32 privileges */ - for (access= 1; access < want_access ; access<<= 1) + for (ulonglong bit= 1; bit < (ulonglong) want_access ; bit<<= 1) { - if (access & want_access) + if (bit & want_access) { + privilege_t access= ALL_KNOWN_ACL & bit; if (!check_access(thd, access, table->db.str, &table->grant.privilege, &table->grant.m_internal, @@ -7120,7 +7123,7 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) 1 Access denied. In this case an error is sent to the client */ -bool check_global_access(THD *thd, ulong want_access, bool no_errors) +bool check_global_access(THD *thd, privilege_t want_access, bool no_errors) { #ifndef NO_EMBEDDED_ACCESS_CHECKS char command[128]; @@ -7172,8 +7175,7 @@ bool check_fk_parent_table_access(THD *thd, LEX_CSTRING db_name; LEX_CSTRING table_name= { fk_key->ref_table.str, fk_key->ref_table.length }; - const ulong privileges= (SELECT_ACL | INSERT_ACL | UPDATE_ACL | - DELETE_ACL | REFERENCES_ACL); + const privilege_t privileges(COL_DML_ACLS | REFERENCES_ACL); // Check if tablename is valid or not. DBUG_ASSERT(table_name.str != NULL); @@ -9365,7 +9367,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE))) DBUG_RETURN(TRUE); - table->grant.orig_want_privilege= 0; + table->grant.orig_want_privilege= NO_ACL; table->table_in_first_from_clause= 1; } /* @@ -9626,9 +9628,9 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables) Check that we have modify privileges for the first table and select privileges for the rest */ - ulong privilege= (INSERT_ACL | - (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | - (lex->value_list.elements ? UPDATE_ACL : 0)); + privilege_t privilege= (INSERT_ACL | + (lex->duplicates == DUP_REPLACE ? DELETE_ACL : NO_ACL) | + (lex->value_list.elements ? UPDATE_ACL : NO_ACL)); if (check_one_table_access(thd, privilege, tables)) DBUG_RETURN(TRUE); @@ -9688,7 +9690,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, { LEX *lex= thd->lex; SELECT_LEX *select_lex= lex->first_select_lex(); - ulong want_priv; + privilege_t want_priv(NO_ACL); bool error= TRUE; // Error message is given DBUG_ENTER("create_table_precheck"); @@ -9697,8 +9699,8 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, CREATE TABLE ... SELECT, also require INSERT. */ - want_priv= lex->tmp_table() ? CREATE_TMP_ACL : - (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : 0)); + want_priv= lex->tmp_table() ? CREATE_TMP_ACL : + (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : NO_ACL)); /* CREATE OR REPLACE on not temporary tables require DROP_ACL */ if (lex->create_info.or_replace() && !lex->tmp_table()) diff --git a/sql/sql_parse.h b/sql/sql_parse.h index a90628781cc..6b0ee75b57b 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -143,32 +143,32 @@ inline bool check_identifier_name(LEX_CSTRING *str) } #ifndef NO_EMBEDDED_ACCESS_CHECKS -bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); -bool check_single_table_access(THD *thd, ulong privilege, - TABLE_LIST *tables, bool no_errors); -bool check_routine_access(THD *thd,ulong want_access, +bool check_one_table_access(THD *thd, privilege_t privilege, TABLE_LIST *tables); +bool check_single_table_access(THD *thd, privilege_t privilege, + TABLE_LIST *tables, bool no_errors); +bool check_routine_access(THD *thd, privilege_t want_access, const LEX_CSTRING *db, const LEX_CSTRING *name, const Sp_handler *sph, bool no_errors); -bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); +bool check_some_access(THD *thd, privilege_t want_access, TABLE_LIST *table); bool check_some_routine_access(THD *thd, const char *db, const char *name, const Sp_handler *sph); -bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, +bool check_table_access(THD *thd, privilege_t requirements,TABLE_LIST *tables, bool any_combination_of_privileges_will_do, uint number, bool no_errors); #else -inline bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables) +inline bool check_one_table_access(THD *thd, privilege_t privilege, TABLE_LIST *tables) { return false; } -inline bool check_single_table_access(THD *thd, ulong privilege, - TABLE_LIST *tables, bool no_errors) +inline bool check_single_table_access(THD *thd, privilege_t privilege, + TABLE_LIST *tables, bool no_errors) { return false; } -inline bool check_routine_access(THD *thd,ulong want_access, +inline bool check_routine_access(THD *thd, privilege_t want_access, const LEX_CSTRING *db, const LEX_CSTRING *name, const Sp_handler *sph, bool no_errors) { return false; } -inline bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) +inline bool check_some_access(THD *thd, privilege_t want_access, TABLE_LIST *table) { table->grant.privilege= want_access; return false; @@ -178,7 +178,7 @@ inline bool check_some_routine_access(THD *thd, const char *db, const Sp_handler *sph) { return false; } inline bool -check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, +check_table_access(THD *thd, privilege_t requirements,TABLE_LIST *tables, bool any_combination_of_privileges_will_do, uint number, bool no_errors) diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index edd2116833c..92ac1b2ce4c 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -63,7 +63,7 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd) */ IF_DBUG(HA_CREATE_INFO create_info(lex->create_info);,) Alter_info alter_info(lex->alter_info, thd->mem_root); - ulong priv_needed= ALTER_ACL | DROP_ACL | INSERT_ACL | CREATE_ACL; + privilege_t priv_needed(ALTER_ACL | DROP_ACL | INSERT_ACL | CREATE_ACL); DBUG_ENTER("Sql_cmd_alter_table_exchange_partition::execute"); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 29f629280b7..dcf445f3cfb 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1359,7 +1359,7 @@ static int mysql_test_update(Prepared_statement *stmt, TABLE_LIST *update_source_table; SELECT_LEX *select= stmt->lex->first_select_lex(); #ifndef NO_EMBEDDED_ACCESS_CHECKS - uint want_privilege; + privilege_t want_privilege(NO_ACL); #endif DBUG_ENTER("mysql_test_update"); @@ -1516,7 +1516,7 @@ static int mysql_test_select(Prepared_statement *stmt, lex->first_select_lex()->context.resolve_in_select_list= TRUE; - ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; + privilege_t privilege(lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL); if (tables) { if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eaa4b5a33bb..94a28e74eff 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1146,10 +1146,10 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, access is granted. We need to check if table_list->grant.privilege contains any table-specific privilege. */ - DBUG_PRINT("debug", ("table_list->grant.privilege: %lx", - table_list->grant.privilege)); + DBUG_PRINT("debug", ("table_list->grant.privilege: %llx", + (longlong) (table_list->grant.privilege))); if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, table_list) || - (table_list->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0) + (table_list->grant.privilege & SHOW_CREATE_TABLE_ACLS) == NO_ACL) { my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "SHOW", thd->security_ctx->priv_user, @@ -1347,7 +1347,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname, String buffer(buff, sizeof(buff), system_charset_info); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; - uint db_access; + privilege_t db_access(NO_ACL); #endif Schema_specification_st create; Protocol *protocol=thd->protocol; @@ -5265,7 +5265,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) || (sctx->priv_role[0] ? - acl_get("", "", sctx->priv_role, db_name->str, false) : 0) || + acl_get("", "", sctx->priv_role, db_name->str, false) : NO_ACL) || !check_grant_db(thd, db_name->str)) #endif { @@ -5861,7 +5861,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, restore_record(table, s->default_values); #ifndef NO_EMBEDDED_ACCESS_CHECKS - uint col_access; + ulonglong col_access; check_access(thd,SELECT_ACL, db_name->str, &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); col_access= get_column_grant(thd, &tables->grant, @@ -6641,12 +6641,11 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, else { TABLE_LIST table_list; - uint view_access; table_list.reset(); table_list.db= tables->db; table_list.table_name= tables->table_name; table_list.grant.privilege= thd->col_access; - view_access= get_table_grant(thd, &table_list); + privilege_t view_access(get_table_grant(thd, &table_list)); if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) == (SHOW_VIEW_ACL|SELECT_ACL)) tables->allowed_show= TRUE; @@ -9866,15 +9865,15 @@ public: ~IS_internal_schema_access() {} - ACL_internal_access_result check(ulong want_access, - ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; const ACL_internal_table_access *lookup(const char *name) const; }; ACL_internal_access_result -IS_internal_schema_access::check(ulong want_access, - ulong *save_priv) const +IS_internal_schema_access::check(privilege_t want_access, + privilege_t *save_priv) const { want_access &= ~SELECT_ACL; @@ -9882,7 +9881,7 @@ IS_internal_schema_access::check(ulong want_access, We don't allow any simple privileges but SELECT_ACL on the information_schema database. */ - if (unlikely(want_access & DB_ACLS)) + if (unlikely((want_access & DB_ACLS) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; /* Always grant SELECT for the information schema. */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 55dece1ec5c..6d6958ba50b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -373,7 +373,7 @@ int mysql_update(THD *thd, bool need_sort= TRUE; bool reverse= FALSE; #ifndef NO_EMBEDDED_ACCESS_CHECKS - uint want_privilege; + privilege_t want_privilege(NO_ACL); #endif uint table_count= 0; ha_rows updated, found; @@ -1874,8 +1874,8 @@ int mysql_multi_update_prepare(THD *thd) (SELECT_ACL & ~tlist->grant.privilege); table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); } - DBUG_PRINT("info", ("table: %s want_privilege: %u", tl->alias.str, - (uint) table->grant.want_privilege)); + DBUG_PRINT("info", ("table: %s want_privilege: %llx", tl->alias.str, + (longlong) table->grant.want_privilege)); } /* Set exclude_from_table_unique_test value back to FALSE. It is needed for diff --git a/sql/sql_view.cc b/sql/sql_view.cc index ecf4ba2f22d..12dfb8bc59d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -592,7 +592,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, This will hold the intersection of the priviliges on all columns in the view. */ - uint final_priv= VIEW_ANY_ACL; + privilege_t final_priv(VIEW_ANY_ACL); for (sl= select_lex; sl; sl= sl->next_select()) { @@ -602,8 +602,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, while ((item= it++)) { Item_field *fld= item->field_for_view_update(); - uint priv= (get_column_grant(thd, &view->grant, view->db.str, - view->table_name.str, item->name.str) & + privilege_t priv(get_column_grant(thd, &view->grant, view->db.str, + view->table_name.str, + item->name.str) & VIEW_ANY_ACL); if (!fld) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 53551567b51..f24da3ed412 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -191,7 +191,6 @@ 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; @@ -314,6 +313,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)() enum vers_kind_t vers_range_unit; enum Column_definition::enum_column_versioning vers_column_versioning; enum plsql_cursor_attr_t plsql_cursor_attr; + privilege_t privilege; } %{ @@ -16846,7 +16846,7 @@ object_privilege: | UPDATE_SYM { $$= UPDATE_ACL; } | REFERENCES { $$= REFERENCES_ACL; } | DELETE_SYM { $$= DELETE_ACL;} - | USAGE { $$= 0; } + | USAGE { $$= NO_ACL; } | INDEX_SYM { $$= INDEX_ACL;} | ALTER { $$= ALTER_ACL;} | CREATE { $$= CREATE_ACL;} @@ -17105,12 +17105,12 @@ opt_resource_options: opt_grant_options: - /* empty */ { $$= 0; } + /* empty */ { $$= NO_ACL; } | WITH grant_option_list { $$= $2; } ; opt_grant_option: - /* empty */ { $$= 0; } + /* empty */ { $$= NO_ACL; } | WITH GRANT OPTION { $$= GRANT_ACL; } ; @@ -17121,7 +17121,7 @@ grant_option_list: grant_option: GRANT OPTION { $$= GRANT_ACL;} - | resource_option { $$= 0; } + | resource_option { $$= NO_ACL; } ; begin_stmt_mariadb: diff --git a/sql/table.cc b/sql/table.cc index be2b8781399..c270b00a8b5 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6153,7 +6153,7 @@ TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution() want_access Acess which we require */ -void TABLE_LIST::register_want_access(ulong want_access) +void TABLE_LIST::register_want_access(privilege_t want_access) { /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ want_access&= ~SHOW_VIEW_ACL; @@ -6322,7 +6322,7 @@ bool TABLE_LIST::prepare_security(THD *thd) thd->security_ctx= save_security_ctx; #else while ((tbl= tb++)) - tbl->grant.privilege= ~NO_ACCESS; + tbl->grant.privilege= ALL_KNOWN_ACL; #endif DBUG_RETURN(FALSE); } diff --git a/sql/table.h b/sql/table.h index acaa8bcdafe..6ce92ee048e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -33,6 +33,7 @@ #include "parse_file.h" #include "sql_i_s.h" #include "sql_type.h" /* vers_kind_t */ +#include "privilege.h" /* privilege_t */ /* Structs that defines the TABLE */ @@ -309,19 +310,25 @@ typedef struct st_grant_info The set is implemented as a bitmap, with the bits defined in sql_acl.h. */ - ulong privilege; + privilege_t privilege; /** @brief the set of privileges that the current user needs to fulfil in order to carry out the requested operation. */ - ulong want_privilege; + privilege_t want_privilege; /** Stores the requested access acl of top level tables list. Is used to check access rights to the underlying tables of a view. */ - ulong orig_want_privilege; + privilege_t orig_want_privilege; /** The grant state for internal tables. */ GRANT_INTERNAL_INFO m_internal; + + st_grant_info() + :privilege(NO_ACL), + want_privilege(NO_ACL), + orig_want_privilege(NO_ACL) + { } } GRANT_INFO; enum tmp_table_type @@ -2507,7 +2514,7 @@ struct TABLE_LIST return FALSE; } - void register_want_access(ulong want_access); + void register_want_access(privilege_t want_access); bool prepare_security(THD *thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *find_view_security_context(THD *thd); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 52ee3219ee5..a3c5e91eb24 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2801,7 +2801,7 @@ void* start_wsrep_THD(void *arg) /* from bootstrap()... */ thd->bootstrap=1; thd->max_client_packet_length= thd->net.max_packet; - thd->security_ctx->master_access= ~(ulong)0; + thd->security_ctx->master_access= ALL_KNOWN_ACL; /* from handle_one_connection... */ pthread_detach_this_thread(); diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index 49ea78a3872..59fa68db6c0 100644 --- a/sql/wsrep_utils.cc +++ b/sql/wsrep_utils.cc @@ -426,7 +426,7 @@ thd::thd (my_bool won) : init(), ptr(new THD(0)) wsrep_store_threadvars(ptr); ptr->variables.option_bits&= ~OPTION_BIN_LOG; // disable binlog ptr->variables.wsrep_on= won; - ptr->security_ctx->master_access= ~(ulong)0; + ptr->security_ctx->master_access= ALL_KNOWN_ACL; lex_start(ptr); } } diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 8bf3a79fe5b..9a18879bc62 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -451,22 +451,22 @@ public: ~PFS_internal_schema_access() {} - ACL_internal_access_result check(ulong want_access, - ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; const ACL_internal_table_access *lookup(const char *name) const; }; ACL_internal_access_result -PFS_internal_schema_access::check(ulong want_access, - ulong *save_priv) const +PFS_internal_schema_access::check(privilege_t want_access, + privilege_t *save_priv) const { - const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL + const privilege_t always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL ; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; /* @@ -511,13 +511,13 @@ void initialize_performance_schema_acl(bool bootstrap) PFS_readonly_acl pfs_readonly_acl; ACL_internal_access_result -PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const +PFS_readonly_acl::check(privilege_t want_access, privilege_t *save_priv) const { - const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL + const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; return ACL_INTERNAL_ACCESS_CHECK_GRANT; @@ -526,13 +526,13 @@ PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const PFS_truncatable_acl pfs_truncatable_acl; ACL_internal_access_result -PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const +PFS_truncatable_acl::check(privilege_t want_access, privilege_t *save_priv) const { - const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL + const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; return ACL_INTERNAL_ACCESS_CHECK_GRANT; @@ -541,13 +541,13 @@ PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const PFS_updatable_acl pfs_updatable_acl; ACL_internal_access_result -PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const +PFS_updatable_acl::check(privilege_t want_access, privilege_t *save_priv) const { - const ulong always_forbidden= INSERT_ACL | DELETE_ACL + const privilege_t always_forbidden= INSERT_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; return ACL_INTERNAL_ACCESS_CHECK_GRANT; @@ -556,12 +556,12 @@ PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const PFS_editable_acl pfs_editable_acl; ACL_internal_access_result -PFS_editable_acl::check(ulong want_access, ulong *save_priv) const +PFS_editable_acl::check(privilege_t want_access, privilege_t *save_priv) const { - const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL + const privilege_t always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; return ACL_INTERNAL_ACCESS_CHECK_GRANT; @@ -570,13 +570,13 @@ PFS_editable_acl::check(ulong want_access, ulong *save_priv) const PFS_unknown_acl pfs_unknown_acl; ACL_internal_access_result -PFS_unknown_acl::check(ulong want_access, ulong *save_priv) const +PFS_unknown_acl::check(privilege_t want_access, privilege_t *save_priv) const { - const ulong always_forbidden= CREATE_ACL + const privilege_t always_forbidden= CREATE_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | TRIGGER_ACL; - if (unlikely(want_access & always_forbidden)) + if (unlikely((want_access & always_forbidden) != NO_ACL)) return ACL_INTERNAL_ACCESS_DENIED; /* diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h index 03a2b6a9d28..a1a01df6e15 100644 --- a/storage/perfschema/pfs_engine_table.h +++ b/storage/perfschema/pfs_engine_table.h @@ -266,7 +266,8 @@ public: ~PFS_readonly_acl() {} - virtual ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; + virtual ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; }; /** Singleton instance of PFS_readonly_acl. */ @@ -285,7 +286,8 @@ public: ~PFS_truncatable_acl() {} - ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; }; /** Singleton instance of PFS_truncatable_acl. */ @@ -304,7 +306,8 @@ public: ~PFS_updatable_acl() {} - ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; }; /** Singleton instance of PFS_updatable_acl. */ @@ -323,7 +326,8 @@ public: ~PFS_editable_acl() {} - ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; }; /** Singleton instance of PFS_editable_acl. */ @@ -341,7 +345,8 @@ public: ~PFS_unknown_acl() {} - ACL_internal_access_result check(ulong want_access, ulong *save_priv) const; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv) const; }; /** Singleton instance of PFS_unknown_acl. */ |