MDEV-21702 Add a data type for privileges

This commit is contained in:
Alexander Barkov 2020-02-09 21:53:11 +04:00
parent f79f537f9f
commit 83e75b39b3
41 changed files with 781 additions and 546 deletions

View file

@ -704,7 +704,7 @@ void *create_embedded_thd(int client_flag)
thd->db= null_clex_str; thd->db= null_clex_str;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->security_ctx->db_access= DB_ACLS; thd->security_ctx->db_access= DB_ACLS;
thd->security_ctx->master_access= ~NO_ACCESS; thd->security_ctx->master_access= ALL_KNOWN_ACL;
#endif #endif
thd->cur_data= 0; thd->cur_data= 0;
thd->first_data= 0; thd->first_data= 0;

View file

@ -106,7 +106,7 @@ static int prepare_for_fill(TABLE_LIST *tables)
thd->db= null_clex_str; thd->db= null_clex_str;
thd->security_ctx->host_or_ip= ""; thd->security_ctx->host_or_ip= "";
thd->security_ctx->db_access= DB_ACLS; 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)); bzero((char*) &thd->net, sizeof(thd->net));
lex_start(thd); lex_start(thd);
mysql_init_select(thd->lex); mysql_init_select(thd->lex);

View file

@ -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.db.length= strlen(index_stats->index);
tmp_table.table_name.str= index_stats->index + tmp_table.db.length + 1; 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.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, if (check_access(thd, SELECT_ACL, tmp_table.db.str,
&tmp_table.grant.privilege, NULL, 0, 1) || &tmp_table.grant.privilege, NULL, 0, 1) ||
check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))

View file

@ -34,7 +34,7 @@ static int table_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond)
tmp_table.db.length= schema_length; tmp_table.db.length= schema_length;
tmp_table.table_name.str= end_of_schema+1; tmp_table.table_name.str= end_of_schema+1;
tmp_table.table_name.length= table_name_length; 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, if (check_access(thd, SELECT_ACL, tmp_table.db.str,
&tmp_table.grant.privilege, NULL, 0, 1) || &tmp_table.grant.privilege, NULL, 0, 1) ||
check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX,

View file

@ -1480,8 +1480,6 @@ end:
ret= 1; ret= 1;
else else
{ {
ulong saved_master_access;
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length()); thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
/* /*
@ -1493,7 +1491,7 @@ end:
Temporarily reset it to read-write. 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; thd->security_ctx->master_access |= SUPER_ACL;
bool save_tx_read_only= thd->tx_read_only; bool save_tx_read_only= thd->tx_read_only;
thd->tx_read_only= false; thd->tx_read_only= false;

View file

@ -177,8 +177,8 @@ pre_init_event_thread(THD* thd)
set_current_thd(thd); set_current_thd(thd);
thd->client_capabilities= 0; thd->client_capabilities= 0;
thd->security_ctx->master_access= 0; thd->security_ctx->master_access= NO_ACL;
thd->security_ctx->db_access= 0; thd->security_ctx->db_access= NO_ACL;
thd->security_ctx->host_or_ip= (char*)my_localhost; thd->security_ctx->host_or_ip= (char*)my_localhost;
my_net_init(&thd->net, NULL, thd, MYF(MY_THREAD_SPECIFIC)); my_net_init(&thd->net, NULL, thd, MYF(MY_THREAD_SPECIFIC));
thd->security_ctx->set_user((char*)"event_scheduler"); thd->security_ctx->set_user((char*)"event_scheduler");

View file

@ -1145,7 +1145,6 @@ Events::load_events_from_db(THD *thd)
READ_RECORD read_record_info; READ_RECORD read_record_info;
bool ret= TRUE; bool ret= TRUE;
uint count= 0; uint count= 0;
ulong saved_master_access;
DBUG_ENTER("Events::load_events_from_db"); DBUG_ENTER("Events::load_events_from_db");
DBUG_PRINT("enter", ("thd: %p", thd)); DBUG_PRINT("enter", ("thd: %p", thd));
@ -1158,7 +1157,7 @@ Events::load_events_from_db(THD *thd)
Temporarily reset it to read-write. 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; thd->security_ctx->master_access |= SUPER_ACL;
bool save_tx_read_only= thd->tx_read_only; bool save_tx_read_only= thd->tx_read_only;
thd->tx_read_only= false; thd->tx_read_only= false;

View file

@ -20,7 +20,7 @@
bool Grant_privilege::add_column_privilege(THD *thd, bool Grant_privilege::add_column_privilege(THD *thd,
const Lex_ident_sys &name, const Lex_ident_sys &name,
uint which_grant) privilege_t which_grant)
{ {
String *new_str= new (thd->mem_root) String((const char*) name.str, String *new_str= new (thd->mem_root) String((const char*) name.str,
name.length, name.length,
@ -51,7 +51,7 @@ bool Grant_privilege::add_column_privilege(THD *thd,
bool Grant_privilege::add_column_list_privilege(THD *thd, bool Grant_privilege::add_column_list_privilege(THD *thd,
List<Lex_ident_sys> &list, List<Lex_ident_sys> &list,
uint privilege) privilege_t privilege)
{ {
Lex_ident_sys *col; Lex_ident_sys *col;
List_iterator<Lex_ident_sys> it(list); 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) { switch (m_type) {
case STAR: return DB_ACLS & ~GRANT_ACL; 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 STAR_STAR: return GLOBAL_ACLS & ~GRANT_ACL;
case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL; case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL;
} }
return 0; return NO_ACL;
} }
bool Grant_privilege::set_object_name(THD *thd, bool Grant_privilege::set_object_name(THD *thd,
const Grant_object_name &ident, const Grant_object_name &ident,
SELECT_LEX *sel, SELECT_LEX *sel,
uint with_grant_option) privilege_t with_grant_option)
{ {
DBUG_ASSERT(!m_all_privileges || !m_columns.elements); DBUG_ASSERT(!m_all_privileges || !m_columns.elements);

View file

@ -18,6 +18,7 @@
#define SQL_GRANT_INCLUDED #define SQL_GRANT_INCLUDED
#include "lex_string.h" #include "lex_string.h"
#include "privilege.h"
class LEX_COLUMN; class LEX_COLUMN;
class Lex_ident_sys; class Lex_ident_sys;
@ -50,7 +51,7 @@ public:
m_table_ident(NULL), m_table_ident(NULL),
m_type(type) m_type(type)
{ } { }
uint all_privileges_by_type() const; privilege_t all_privileges_by_type() const;
}; };
@ -65,30 +66,32 @@ class Grant_privilege
protected: protected:
List<LEX_COLUMN> m_columns; List<LEX_COLUMN> m_columns;
Lex_cstring m_db; Lex_cstring m_db;
uint m_object_privilege; privilege_t m_object_privilege;
uint m_column_privilege_total; privilege_t m_column_privilege_total;
bool m_all_privileges; bool m_all_privileges;
public: public:
Grant_privilege() 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_object_privilege(privilege),
m_column_privilege_total(0), m_column_privilege_total(NO_ACL),
m_all_privileges(all_privileges) m_all_privileges(all_privileges)
{ } { }
void add_object_privilege(uint privilege) void add_object_privilege(privilege_t privilege)
{ {
m_object_privilege|= privilege; m_object_privilege|= privilege;
} }
bool add_column_privilege(THD *thd, const Lex_ident_sys &col, 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, bool add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list,
uint privilege); privilege_t privilege);
bool set_object_name(THD *thd, bool set_object_name(THD *thd,
const Grant_object_name &ident, const Grant_object_name &ident,
SELECT_LEX *sel, SELECT_LEX *sel,
uint with_grant_option); privilege_t with_grant_option);
const List<LEX_COLUMN> & columns() const { return m_columns; } const List<LEX_COLUMN> & columns() const { return m_columns; }
}; };

View file

@ -2892,7 +2892,7 @@ Item_field::Item_field(THD *thd, Field *f)
:Item_ident(thd, 0, null_clex_str, :Item_ident(thd, 0, null_clex_str,
Lex_cstring_strlen(*f->table_name), f->field_name), Lex_cstring_strlen(*f->table_name), f->field_name),
item_equal(0), item_equal(0),
have_privileges(0), any_privileges(0) have_privileges(NO_ACL), any_privileges(0)
{ {
set_field(f); 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, :Item_ident(thd, context_arg, f->table->s->db,
Lex_cstring_strlen(*f->table_name), f->field_name), Lex_cstring_strlen(*f->table_name), f->field_name),
item_equal(0), 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 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) const LEX_CSTRING &field_name_arg)
:Item_ident(thd, context_arg, db_arg, table_name_arg, field_name_arg), :Item_ident(thd, context_arg, db_arg, table_name_arg, field_name_arg),
field(0), item_equal(0), 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; SELECT_LEX *select= thd->lex->current_select;
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);

View file

@ -3290,7 +3290,7 @@ public:
if any_privileges set to TRUE then here real effective privileges will if any_privileges set to TRUE then here real effective privileges will
be stored be stored
*/ */
uint have_privileges; privilege_t have_privileges;
/* field need any privileges (for VIEW creation) */ /* field need any privileges (for VIEW creation) */
bool any_privileges; bool any_privileges;
Item_field(THD *thd, Name_resolution_context *context_arg, Item_field(THD *thd, Name_resolution_context *context_arg,
@ -6381,7 +6381,7 @@ public:
Item_trigger_field(THD *thd, Name_resolution_context *context_arg, Item_trigger_field(THD *thd, Name_resolution_context *context_arg,
row_version_type row_ver_arg, row_version_type row_ver_arg,
const LEX_CSTRING &field_name_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), :Item_field(thd, context_arg, field_name_arg),
row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv), row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
want_privilege(priv), table_grants(NULL), read_only (ro) want_privilege(priv), table_grants(NULL), read_only (ro)
@ -6423,8 +6423,8 @@ private:
want_privilege and cleanup() is responsible for restoring of want_privilege and cleanup() is responsible for restoring of
original want_privilege once parameter's value is updated). original want_privilege once parameter's value is updated).
*/ */
ulong original_privilege; privilege_t original_privilege;
ulong want_privilege; privilege_t want_privilege;
GRANT_INFO *table_grants; GRANT_INFO *table_grants;
/* /*
Trigger field is read-only unless it belongs to the NEW row in a Trigger field is read-only unless it belongs to the NEW row in a

View file

@ -114,7 +114,7 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
DBUG_ENTER("lock_tables_check"); DBUG_ENTER("lock_tables_check");
system_count= 0; 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) log_table_write_query= (is_log_table_write_query(thd->lex->sql_command)
|| ((flags & MYSQL_LOCK_LOG_TABLE) != 0)); || ((flags & MYSQL_LOCK_LOG_TABLE) != 0));

View file

@ -263,7 +263,7 @@ void opt_trace_disable_if_no_tables_access(THD *thd, TABLE_LIST *tbl)
bool rc = bool rc =
check_table_access(thd, SELECT_ACL, t, false, 1, true) || // (1) 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()) if (t->is_view())
{ {
/* /*

333
sql/privilege.h Normal file
View file

@ -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 */

View file

@ -349,9 +349,9 @@ public:
class set_var_role: public set_var_base class set_var_role: public set_var_base
{ {
LEX_CSTRING role; LEX_CSTRING role;
ulonglong access; privilege_t access;
public: 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 check(THD *thd);
int update(THD *thd); int update(THD *thd);
}; };

View file

@ -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, *full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE,
1, TRUE) && 1, TRUE) &&
(tables.grant.privilege & SELECT_ACL) != 0) || (tables.grant.privilege & SELECT_ACL) != NO_ACL) ||
/* Check if user owns the routine. */ /* Check if user owns the routine. */
(!strcmp(sp->m_definer.user.str, (!strcmp(sp->m_definer.user.str,
thd->security_ctx->priv_user) && thd->security_ctx->priv_user) &&

File diff suppressed because it is too large Load diff

View file

@ -22,144 +22,6 @@
#include "grant.h" #include "grant.h"
#include "sql_cmd.h" /* Sql_cmd */ #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 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_init(bool dont_read_acl_tables);
bool acl_reload(THD *thd); bool acl_reload(THD *thd);
void acl_free(bool end=0); void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip, privilege_t acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern); const char *user, const char *db, my_bool db_is_pattern);
bool acl_authenticate(THD *thd, uint com_change_user_pkt_len); bool acl_authenticate(THD *thd, uint com_change_user_pkt_len);
bool acl_getroot(Security_context *sctx, const char *user, const char *host, bool acl_getroot(Security_context *sctx, const char *user, const char *host,
const char *ip, const char *db); 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_role(THD *thd, List<LEX_USER> &user_list, bool revoke);
bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, 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, 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 revoke);
bool mysql_routine_grant(THD *thd, TABLE_LIST *table, const Sp_handler *sph, 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 revoke, bool write_to_binlog);
bool grant_init(); bool grant_init();
void grant_free(void); void grant_free(void);
bool grant_reload(THD *thd); 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 any_combination_will_do, uint number, bool no_errors);
bool check_grant_column (THD *thd, GRANT_INFO *grant, bool check_grant_column (THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name, const char *db_name, const char *table_name,
const char *name, size_t length, Security_context *sctx); const char *name, size_t length, Security_context *sctx);
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
const char *name, size_t length, Field *fld); 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); 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, TABLE_LIST *procs, const Sp_handler *sph,
bool no_error); bool no_error);
bool check_grant_db(THD *thd,const char *db); bool check_grant_db(THD *thd,const char *db);
bool check_global_access(THD *thd, ulong want_access, bool no_errors= false); bool check_global_access(THD *thd, const privilege_t want_access, bool no_errors= false);
bool check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool check_access(THD *thd, privilege_t want_access,
const char *db, privilege_t *save_priv,
GRANT_INTERNAL_INFO *grant_internal_info, GRANT_INTERNAL_INFO *grant_internal_info,
bool dont_check_global_grants, bool no_errors); bool dont_check_global_grants, bool no_errors);
ulong get_table_grant(THD *thd, TABLE_LIST *table); privilege_t get_table_grant(THD *thd, TABLE_LIST *table);
ulong get_column_grant(THD *thd, GRANT_INFO *grant, privilege_t get_column_grant(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name, const char *db_name, const char *table_name,
const char *field_name); const char *field_name);
bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username, bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username,
const char **hostname, const char **rolename); const char **hostname, const char **rolename);
void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, 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); 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_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond);
int fill_schema_applicable_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); 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_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); 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 privilege. Requested privileges that are granted, if any, are saved
in save_priv. in save_priv.
*/ */
virtual ACL_internal_access_result check(ulong want_access, virtual ACL_internal_access_result check(privilege_t want_access,
ulong *save_priv) const= 0; privilege_t *save_priv) const= 0;
}; };
/** /**
@ -382,8 +245,8 @@ public:
privilege. Requested privileges that are granted, if any, are saved privilege. Requested privileges that are granted, if any, are saved
in save_priv. in save_priv.
*/ */
virtual ACL_internal_access_result check(ulong want_access, virtual ACL_internal_access_result check(privilege_t want_access,
ulong *save_priv) const= 0; privilege_t *save_priv) const= 0;
/** /**
Search for per table ACL access rules by table name. 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 acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
bool with_grant); bool with_grant);
int acl_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, ulonglong *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_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, int acl_set_default_role(THD *thd, const char *host, const char *user,
const char *rolename); const char *rolename);
@ -459,12 +322,12 @@ public:
class Sql_cmd_grant_proxy: public Sql_cmd_grant class Sql_cmd_grant_proxy: public Sql_cmd_grant
{ {
uint m_grant_option; privilege_t m_grant_option;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
bool check_access_proxy(THD *thd, List<LEX_USER> &list); bool check_access_proxy(THD *thd, List<LEX_USER> &list);
#endif #endif
public: 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) :Sql_cmd_grant(command), m_grant_option(grant_option)
{ } { }
bool execute(THD *thd); bool execute(THD *thd);

View file

@ -395,8 +395,8 @@ bool Sql_cmd_alter_table::execute(THD *thd)
HA_CREATE_INFO create_info(lex->create_info); HA_CREATE_INFO create_info(lex->create_info);
Alter_info alter_info(lex->alter_info, thd->mem_root); Alter_info alter_info(lex->alter_info, thd->mem_root);
create_info.alter_info= &alter_info; create_info.alter_info= &alter_info;
ulong priv=0; privilege_t priv(NO_ACL);
ulong priv_needed= ALTER_ACL; privilege_t priv_needed(ALTER_ACL);
bool result; bool result;
DBUG_ENTER("Sql_cmd_alter_table::execute"); DBUG_ENTER("Sql_cmd_alter_table::execute");

View file

@ -261,7 +261,7 @@ static my_bool list_open_tables_callback(TDC_element *element,
arg->table_list.db.length= db_length; arg->table_list.db.length= db_length;
arg->table_list.table_name.str= table_name; arg->table_list.table_name.str= table_name;
arg->table_list.table_name.length= strlen(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)) if (check_table_access(arg->thd, SELECT_ACL, &arg->table_list, TRUE, 1, TRUE))
return FALSE; return FALSE;
@ -7878,8 +7878,8 @@ bool setup_tables_and_check_access(THD *thd,
TABLE_LIST *tables, TABLE_LIST *tables,
List<TABLE_LIST> &leaves, List<TABLE_LIST> &leaves,
bool select_insert, bool select_insert,
ulong want_access_first, privilege_t want_access_first,
ulong want_access, privilege_t want_access,
bool full_table_list) bool full_table_list)
{ {
DBUG_ENTER("setup_tables_and_check_access"); 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); List_iterator<TABLE_LIST> ti(leaves);
TABLE_LIST *table_list; TABLE_LIST *table_list;
ulong access= want_access_first; privilege_t access= want_access_first;
while ((table_list= ti++)) while ((table_list= ti++))
{ {
if (table_list->belong_to_view && !table_list->view && if (table_list->belong_to_view && !table_list->view &&

View file

@ -218,8 +218,8 @@ bool setup_tables_and_check_access(THD *thd,
TABLE_LIST *tables, TABLE_LIST *tables,
List<TABLE_LIST> &leaves, List<TABLE_LIST> &leaves,
bool select_insert, bool select_insert,
ulong want_access_first, privilege_t want_access_first,
ulong want_access, privilege_t want_access,
bool full_table_list); bool full_table_list);
bool wait_while_table_is_used(THD *thd, TABLE *table, bool wait_while_table_is_used(THD *thd, TABLE *table,
enum ha_extra_function function); enum ha_extra_function function);

View file

@ -35,7 +35,7 @@
#include "sql_base.h" // close_thread_tables #include "sql_base.h" // close_thread_tables
#include "sql_time.h" // date_time_format_copy #include "sql_time.h" // date_time_format_copy
#include "tztime.h" // MYSQL_TIME <-> my_time_t #include "tztime.h" // MYSQL_TIME <-> my_time_t
#include "sql_acl.h" // NO_ACCESS, #include "sql_acl.h" // NO_ACL,
// acl_getroot_no_password // acl_getroot_no_password
#include "sql_base.h" #include "sql_base.h"
#include "sql_handler.h" // mysql_ha_cleanup #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_digest(NULL),
m_statement_psi(NULL), m_statement_psi(NULL),
m_idle_psi(NULL), m_idle_psi(NULL),
col_access(NO_ACL),
thread_id(id), thread_id(id),
thread_dbug_id(id), thread_dbug_id(id),
os_thread_id(0), os_thread_id(0),
@ -766,7 +767,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
count_cuted_fields= CHECK_FIELD_IGNORE; count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED; killed= NOT_KILLED;
killed_err= 0; killed_err= 0;
col_access=0;
is_slave_error= thread_specific_used= FALSE; is_slave_error= thread_specific_used= FALSE;
my_hash_clear(&handler_tables_hash); my_hash_clear(&handler_tables_hash);
my_hash_clear(&ull_hash); my_hash_clear(&ull_hash);
@ -4292,10 +4292,10 @@ void Security_context::init()
host= user= ip= external_user= 0; host= user= ip= external_user= 0;
host_or_ip= "connecting host"; host_or_ip= "connecting host";
priv_user[0]= priv_host[0]= proxy_user[0]= priv_role[0]= '\0'; priv_user[0]= priv_host[0]= proxy_user[0]= priv_role[0]= '\0';
master_access= 0; master_access= NO_ACL;
password_expired= false; password_expired= false;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS; db_access= NO_ACL;
#endif #endif
} }
@ -4330,7 +4330,7 @@ void Security_context::skip_grants()
{ {
/* privileges for the user are unknown everything is allowed */ /* privileges for the user are unknown everything is allowed */
host_or_ip= (char *)""; host_or_ip= (char *)"";
master_access= ~NO_ACCESS; master_access= ALL_KNOWN_ACL;
*priv_user= *priv_host= '\0'; *priv_user= *priv_host= '\0';
password_expired= false; password_expired= false;
} }
@ -4343,10 +4343,11 @@ bool Security_context::set_user(char *user_arg)
return user == 0; 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_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))); : ((master_access & want_access) == want_access)));
} }

View file

@ -440,8 +440,8 @@ class LEX_COLUMN : public Sql_alloc
{ {
public: public:
String column; String column;
uint rights; privilege_t rights;
LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} LEX_COLUMN (const String& x,const privilege_t & y ): column (x),rights (y) {}
}; };
class MY_LOCALE; class MY_LOCALE;
@ -1303,7 +1303,10 @@ struct st_savepoint {
class Security_context { class Security_context {
public: public:
Security_context() {} /* Remove gcc warning */ Security_context()
:master_access(NO_ACL),
db_access(NO_ACL)
{} /* Remove gcc warning */
/* /*
host - host of the client host - host of the client
user - user of the client, set to NULL until the user has been read from user - user of the client, set to NULL until the user has been read from
@ -1323,8 +1326,8 @@ public:
char *external_user; char *external_user;
/* points to host if host is available, otherwise points to ip */ /* points to host if host is available, otherwise points to ip */
const char *host_or_ip; const char *host_or_ip;
ulong master_access; /* Global privileges from mysql.user */ privilege_t master_access; /* Global privileges from mysql.user */
ulong db_access; /* Privileges for current db */ privilege_t db_access; /* Privileges for current db */
bool password_expired; bool password_expired;
@ -1357,7 +1360,7 @@ public:
* privileges. * privileges.
@return True if the security context fulfills the access requirements. @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); bool is_priv_user(const char *user, const char *host);
}; };
@ -2993,7 +2996,7 @@ public:
update auto-updatable fields (like auto_increment and timestamp). update auto-updatable fields (like auto_increment and timestamp).
*/ */
query_id_t query_id; query_id_t query_id;
ulong col_access; privilege_t col_access;
/* Statement id is thread-wide. This counter is used to generate ids */ /* Statement id is thread-wide. This counter is used to generate ids */
ulong statement_id_counter; ulong statement_id_counter;

View file

@ -35,7 +35,7 @@
#include "sql_db.h" // mysql_change_db #include "sql_db.h" // mysql_change_db
#include "hostname.h" // inc_host_errors, ip_to_hostname, #include "hostname.h" // inc_host_errors, ip_to_hostname,
// reset_host_errors // reset_host_errors
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL #include "privilege.h" // acl_getroot, SUPER_ACL
#include "sql_callback.h" #include "sql_callback.h"
#ifdef WITH_WSREP #ifdef WITH_WSREP

View file

@ -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 my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
static void mysql_change_db_impl(THD *thd, static void mysql_change_db_impl(THD *thd,
LEX_CSTRING *new_db_name, LEX_CSTRING *new_db_name,
ulong new_db_access, privilege_t new_db_access,
CHARSET_INFO *new_db_charset); CHARSET_INFO *new_db_charset);
static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db,
bool if_exists, bool silent); bool if_exists, bool silent);
@ -1088,7 +1088,7 @@ exit:
*/ */
if (unlikely(thd->db.str && cmp_db_names(&thd->db, db) && !error)) 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); thd->session_tracker.current_schema.mark_as_changed(thd);
} }
my_dirend(dirp); my_dirend(dirp);
@ -1352,7 +1352,7 @@ err:
static void mysql_change_db_impl(THD *thd, static void mysql_change_db_impl(THD *thd,
LEX_CSTRING *new_db_name, LEX_CSTRING *new_db_name,
ulong new_db_access, privilege_t new_db_access,
CHARSET_INFO *new_db_charset) CHARSET_INFO *new_db_charset)
{ {
/* 1. Change current database in THD. */ /* 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; LEX_CSTRING new_db_file_name;
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
ulong db_access= sctx->db_access; privilege_t db_access(sctx->db_access);
CHARSET_INFO *db_default_cl; CHARSET_INFO *db_default_cl;
DBUG_ENTER("mysql_change_db"); 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. 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; 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)); my_free(const_cast<char*>(new_db_file_name.str));
if (force_switch) 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); 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. */ /* 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. */ /* The operation succeed. */
goto done; goto done;

View file

@ -11241,7 +11241,7 @@ bool LEX::add_column_foreign_key(const LEX_CSTRING *name,
bool LEX::stmt_grant_table(THD *thd, bool LEX::stmt_grant_table(THD *thd,
Grant_privilege *grant, Grant_privilege *grant,
const Lex_grant_object_name &ident, const Lex_grant_object_name &ident,
uint grant_option) privilege_t grant_option)
{ {
sql_command= SQLCOM_GRANT; sql_command= SQLCOM_GRANT;
return return
@ -11256,7 +11256,7 @@ bool LEX::stmt_revoke_table(THD *thd,
{ {
sql_command= SQLCOM_REVOKE; sql_command= SQLCOM_REVOKE;
return 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)); !(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, Grant_privilege *grant,
const Lex_grant_object_name &ident, const Lex_grant_object_name &ident,
const Sp_handler &sph, const Sp_handler &sph,
uint grant_option) privilege_t grant_option)
{ {
sql_command= SQLCOM_GRANT; sql_command= SQLCOM_GRANT;
return return
@ -11283,14 +11283,14 @@ bool LEX::stmt_revoke_sp(THD *thd,
{ {
sql_command= SQLCOM_REVOKE; sql_command= SQLCOM_REVOKE;
return 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()) || add_grant_command(thd, grant->columns()) ||
!(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command, !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command,
*grant, sph)); *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); users_list.push_front(user);
sql_command= SQLCOM_GRANT; sql_command= SQLCOM_GRANT;
@ -11303,5 +11303,6 @@ bool LEX::stmt_revoke_proxy(THD *thd, LEX_USER *user)
{ {
users_list.push_front(user); users_list.push_front(user);
sql_command= SQLCOM_REVOKE; 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));
} }

View file

@ -187,14 +187,14 @@ public:
struct Lex_column_list_privilege_st struct Lex_column_list_privilege_st
{ {
List<Lex_ident_sys> *m_columns; List<Lex_ident_sys> *m_columns;
uint m_privilege; privilege_t m_privilege;
}; };
class Lex_column_list_privilege: public Lex_column_list_privilege_st class Lex_column_list_privilege: public Lex_column_list_privilege_st
{ {
public: 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_columns= columns;
m_privilege= privilege; m_privilege= privilege;
@ -3126,7 +3126,7 @@ class Lex_grant_privilege: public Grant_privilege, public Sql_alloc
{ {
public: public:
Lex_grant_privilege() {} 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) :Grant_privilege(grant, all_privileges)
{ } { }
}; };
@ -4417,7 +4417,7 @@ public:
bool stmt_grant_table(THD *thd, bool stmt_grant_table(THD *thd,
Grant_privilege *grant, Grant_privilege *grant,
const Lex_grant_object_name &ident, const Lex_grant_object_name &ident,
uint grant_option); privilege_t grant_option);
bool stmt_revoke_table(THD *thd, bool stmt_revoke_table(THD *thd,
Grant_privilege *grant, Grant_privilege *grant,
@ -4427,14 +4427,14 @@ public:
Grant_privilege *grant, Grant_privilege *grant,
const Lex_grant_object_name &ident, const Lex_grant_object_name &ident,
const Sp_handler &sph, const Sp_handler &sph,
uint grant_option); privilege_t grant_option);
bool stmt_revoke_sp(THD *thd, bool stmt_revoke_sp(THD *thd,
Grant_privilege *grant, Grant_privilege *grant,
const Lex_grant_object_name &ident, const Lex_grant_object_name &ident,
const Sp_handler &sph); 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); bool stmt_revoke_proxy(THD *thd, LEX_USER *user);
Vers_parse_info &vers_get_info() Vers_parse_info &vers_get_info()

View file

@ -998,7 +998,7 @@ int bootstrap(MYSQL_FILE *file)
thd->bootstrap=1; thd->bootstrap=1;
my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0)); my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
thd->max_client_packet_length= thd->net.max_packet; 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 #ifndef EMBEDDED_LIBRARY
mysql_thread_set_psi_id(thd->thread_id); 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; LEX *lex= thd->lex;
/* Super user is allowed to do changes */ /* Super user is allowed to do changes */
if (((ulong)(thd->security_ctx->master_access & SUPER_ACL) == if ((thd->security_ctx->master_access & SUPER_ACL) == SUPER_ACL)
(ulong)SUPER_ACL))
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
/* Check if command doesn't update anything */ /* 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) static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables)
{ {
int opt_readonly_saved = opt_readonly; 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; opt_readonly = 0;
thd->security_ctx->master_access &= ~SUPER_ACL; thd->security_ctx->master_access &= ~SUPER_ACL;
@ -3170,7 +3169,8 @@ wsrep_error_label:
from other cases: bad database error, no access error. from other cases: bad database error, no access error.
This can be done by testing thd->is_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)) 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 lex->exchange != NULL implies SELECT .. INTO OUTFILE and this
requires FILE_ACL access. requires FILE_ACL access.
*/ */
ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : privilege_t privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
SELECT_ACL; SELECT_ACL;
if (all_tables) if (all_tables)
res= check_table_access(thd, res= check_table_access(thd,
@ -4928,9 +4928,9 @@ mysql_execute_command(THD *thd)
case SQLCOM_LOAD: case SQLCOM_LOAD:
{ {
DBUG_ASSERT(first_table == all_tables && first_table != 0); DBUG_ASSERT(first_table == all_tables && first_table != 0);
uint privilege= (lex->duplicates == DUP_REPLACE ? privilege_t privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL) | INSERT_ACL | DELETE_ACL : INSERT_ACL) |
(lex->local_file ? 0 : FILE_ACL); (lex->local_file ? NO_ACL : FILE_ACL);
if (lex->local_file) if (lex->local_file)
{ {
@ -6521,7 +6521,8 @@ wsrep_error_label:
*/ */
bool 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, GRANT_INTERNAL_INFO *grant_internal_info,
bool dont_check_global_grants, bool no_errors) 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; return false;
#else #else
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
ulong db_access; privilege_t db_access(NO_ACL);
/* /*
GRANT command: 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. set db_is_pattern according to 'dont_check_global_grants' value.
*/ */
bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants); bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants);
ulong dummy; privilege_t dummy(NO_ACL);
DBUG_ENTER("check_access"); DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu", DBUG_PRINT("enter",("db: %s want_access: %llx master_access: %llx",
db ? db : "", want_access, sctx->master_access)); db ? db : "",
(longlong) want_access,
(longlong) sctx->master_access));
if (save_priv) if (save_priv)
*save_priv=0; *save_priv= NO_ACL;
else else
{ {
save_priv= &dummy; save_priv= &dummy;
dummy= 0; dummy= NO_ACL;
} }
/* check access may be called twice in a row. Don't change to same stage */ /* 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 else
db_access= sctx->db_access; db_access= sctx->db_access;
DBUG_PRINT("info",("db_access: %lu want_access: %lu", DBUG_PRINT("info",("db_access: %llx want_access: %llx",
db_access, want_access)); (longlong) db_access, (longlong) want_access));
/* /*
Save the union of User-table and the intersection between Db-table and 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 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) TABLE_LIST *all_tables, bool no_errors)
{ {
Switch_to_definer_security_ctx backup_sctx(thd, all_tables); 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 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)) if (check_single_table_access (thd,privilege,all_tables, FALSE))
return 1; return 1;
@ -6933,7 +6937,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
*/ */
bool 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, bool any_combination_of_privileges_will_do,
uint number, bool no_errors) uint number, bool no_errors)
{ {
@ -6952,7 +6956,7 @@ check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
tables->correspondent_table : tables; tables->correspondent_table : tables;
Switch_to_definer_security_ctx backup_ctx(thd, table_ref); 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. Register access for view underlying table.
@ -6995,7 +6999,7 @@ check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
bool 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 LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors) 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. as long as this code path is not abused to create routines.
The assert enforce that. 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) if ((thd->security_ctx->master_access & want_access) == want_access)
tables->grant.privilege= want_access; tables->grant.privilege= want_access;
else if (check_access(thd, want_access, db->str, 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, bool check_some_routine_access(THD *thd, const char *db, const char *name,
const Sp_handler *sph) 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 The following test is just a shortcut for check_access() (to avoid
calculating db_access) calculating db_access)
@ -7077,16 +7081,15 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name,
1 error 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"); DBUG_ENTER("check_some_access");
/* This loop will work as long as we have less than 32 privileges */ for (ulonglong bit= 1; bit < (ulonglong) want_access ; bit<<= 1)
for (access= 1; access < want_access ; access<<= 1)
{ {
if (access & want_access) if (bit & want_access)
{ {
privilege_t access= ALL_KNOWN_ACL & bit;
if (!check_access(thd, access, table->db.str, if (!check_access(thd, access, table->db.str,
&table->grant.privilege, &table->grant.privilege,
&table->grant.m_internal, &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 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 #ifndef NO_EMBEDDED_ACCESS_CHECKS
char command[128]; char command[128];
@ -7172,8 +7175,7 @@ bool check_fk_parent_table_access(THD *thd,
LEX_CSTRING db_name; LEX_CSTRING db_name;
LEX_CSTRING table_name= { fk_key->ref_table.str, LEX_CSTRING table_name= { fk_key->ref_table.str,
fk_key->ref_table.length }; fk_key->ref_table.length };
const ulong privileges= (SELECT_ACL | INSERT_ACL | UPDATE_ACL | const privilege_t privileges(COL_DML_ACLS | REFERENCES_ACL);
DELETE_ACL | REFERENCES_ACL);
// Check if tablename is valid or not. // Check if tablename is valid or not.
DBUG_ASSERT(table_name.str != NULL); 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))) check_grant(thd, SELECT_ACL, table, FALSE, 1, FALSE)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
table->grant.orig_want_privilege= 0; table->grant.orig_want_privilege= NO_ACL;
table->table_in_first_from_clause= 1; 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 Check that we have modify privileges for the first table and
select privileges for the rest select privileges for the rest
*/ */
ulong privilege= (INSERT_ACL | privilege_t privilege= (INSERT_ACL |
(lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | (lex->duplicates == DUP_REPLACE ? DELETE_ACL : NO_ACL) |
(lex->value_list.elements ? UPDATE_ACL : 0)); (lex->value_list.elements ? UPDATE_ACL : NO_ACL));
if (check_one_table_access(thd, privilege, tables)) if (check_one_table_access(thd, privilege, tables))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -9688,7 +9690,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
SELECT_LEX *select_lex= lex->first_select_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 bool error= TRUE; // Error message is given
DBUG_ENTER("create_table_precheck"); DBUG_ENTER("create_table_precheck");
@ -9697,8 +9699,8 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
CREATE TABLE ... SELECT, also require INSERT. CREATE TABLE ... SELECT, also require INSERT.
*/ */
want_priv= lex->tmp_table() ? CREATE_TMP_ACL : want_priv= lex->tmp_table() ? CREATE_TMP_ACL :
(CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : 0)); (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : NO_ACL));
/* CREATE OR REPLACE on not temporary tables require DROP_ACL */ /* CREATE OR REPLACE on not temporary tables require DROP_ACL */
if (lex->create_info.or_replace() && !lex->tmp_table()) if (lex->create_info.or_replace() && !lex->tmp_table())

View file

@ -143,32 +143,32 @@ inline bool check_identifier_name(LEX_CSTRING *str)
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); bool check_one_table_access(THD *thd, privilege_t privilege, TABLE_LIST *tables);
bool check_single_table_access(THD *thd, ulong privilege, bool check_single_table_access(THD *thd, privilege_t privilege,
TABLE_LIST *tables, bool no_errors); TABLE_LIST *tables, bool no_errors);
bool check_routine_access(THD *thd,ulong want_access, bool check_routine_access(THD *thd, privilege_t want_access,
const LEX_CSTRING *db, const LEX_CSTRING *db,
const LEX_CSTRING *name, const LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors); 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, bool check_some_routine_access(THD *thd, const char *db, const char *name,
const Sp_handler *sph); 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, bool any_combination_of_privileges_will_do,
uint number, uint number,
bool no_errors); bool no_errors);
#else #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; } { return false; }
inline bool check_single_table_access(THD *thd, ulong privilege, inline bool check_single_table_access(THD *thd, privilege_t privilege,
TABLE_LIST *tables, bool no_errors) TABLE_LIST *tables, bool no_errors)
{ return false; } { 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 *db,
const LEX_CSTRING *name, const LEX_CSTRING *name,
const Sp_handler *sph, bool no_errors) const Sp_handler *sph, bool no_errors)
{ return false; } { 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; table->grant.privilege= want_access;
return false; return false;
@ -178,7 +178,7 @@ inline bool check_some_routine_access(THD *thd, const char *db,
const Sp_handler *sph) const Sp_handler *sph)
{ return false; } { return false; }
inline bool 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, bool any_combination_of_privileges_will_do,
uint number, uint number,
bool no_errors) bool no_errors)

View file

@ -63,7 +63,7 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
*/ */
IF_DBUG(HA_CREATE_INFO create_info(lex->create_info);,) IF_DBUG(HA_CREATE_INFO create_info(lex->create_info);,)
Alter_info alter_info(lex->alter_info, thd->mem_root); 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"); DBUG_ENTER("Sql_cmd_alter_table_exchange_partition::execute");

View file

@ -1359,7 +1359,7 @@ static int mysql_test_update(Prepared_statement *stmt,
TABLE_LIST *update_source_table; TABLE_LIST *update_source_table;
SELECT_LEX *select= stmt->lex->first_select_lex(); SELECT_LEX *select= stmt->lex->first_select_lex();
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege; privilege_t want_privilege(NO_ACL);
#endif #endif
DBUG_ENTER("mysql_test_update"); 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; 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 (tables)
{ {
if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE)) if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE))

View file

@ -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 access is granted. We need to check if table_list->grant.privilege
contains any table-specific privilege. contains any table-specific privilege.
*/ */
DBUG_PRINT("debug", ("table_list->grant.privilege: %lx", DBUG_PRINT("debug", ("table_list->grant.privilege: %llx",
table_list->grant.privilege)); (longlong) (table_list->grant.privilege)));
if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, table_list) || 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), my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"SHOW", thd->security_ctx->priv_user, "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); String buffer(buff, sizeof(buff), system_charset_info);
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
uint db_access; privilege_t db_access(NO_ACL);
#endif #endif
Schema_specification_st create; Schema_specification_st create;
Protocol *protocol=thd->protocol; 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) || if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) || acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) ||
(sctx->priv_role[0] ? (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)) !check_grant_db(thd, db_name->str))
#endif #endif
{ {
@ -5861,7 +5861,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
restore_record(table, s->default_values); restore_record(table, s->default_values);
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
uint col_access; ulonglong col_access;
check_access(thd,SELECT_ACL, db_name->str, check_access(thd,SELECT_ACL, db_name->str,
&tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table));
col_access= get_column_grant(thd, &tables->grant, col_access= get_column_grant(thd, &tables->grant,
@ -6641,12 +6641,11 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
else else
{ {
TABLE_LIST table_list; TABLE_LIST table_list;
uint view_access;
table_list.reset(); table_list.reset();
table_list.db= tables->db; table_list.db= tables->db;
table_list.table_name= tables->table_name; table_list.table_name= tables->table_name;
table_list.grant.privilege= thd->col_access; 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)) == if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
(SHOW_VIEW_ACL|SELECT_ACL)) (SHOW_VIEW_ACL|SELECT_ACL))
tables->allowed_show= TRUE; tables->allowed_show= TRUE;
@ -9866,15 +9865,15 @@ public:
~IS_internal_schema_access() ~IS_internal_schema_access()
{} {}
ACL_internal_access_result check(ulong want_access, ACL_internal_access_result check(privilege_t want_access,
ulong *save_priv) const; privilege_t *save_priv) const;
const ACL_internal_table_access *lookup(const char *name) const; const ACL_internal_table_access *lookup(const char *name) const;
}; };
ACL_internal_access_result ACL_internal_access_result
IS_internal_schema_access::check(ulong want_access, IS_internal_schema_access::check(privilege_t want_access,
ulong *save_priv) const privilege_t *save_priv) const
{ {
want_access &= ~SELECT_ACL; 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 We don't allow any simple privileges but SELECT_ACL on
the information_schema database. the information_schema database.
*/ */
if (unlikely(want_access & DB_ACLS)) if (unlikely((want_access & DB_ACLS) != NO_ACL))
return ACL_INTERNAL_ACCESS_DENIED; return ACL_INTERNAL_ACCESS_DENIED;
/* Always grant SELECT for the information schema. */ /* Always grant SELECT for the information schema. */

View file

@ -373,7 +373,7 @@ int mysql_update(THD *thd,
bool need_sort= TRUE; bool need_sort= TRUE;
bool reverse= FALSE; bool reverse= FALSE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege; privilege_t want_privilege(NO_ACL);
#endif #endif
uint table_count= 0; uint table_count= 0;
ha_rows updated, found; ha_rows updated, found;
@ -1874,8 +1874,8 @@ int mysql_multi_update_prepare(THD *thd)
(SELECT_ACL & ~tlist->grant.privilege); (SELECT_ACL & ~tlist->grant.privilege);
table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
} }
DBUG_PRINT("info", ("table: %s want_privilege: %u", tl->alias.str, DBUG_PRINT("info", ("table: %s want_privilege: %llx", tl->alias.str,
(uint) table->grant.want_privilege)); (longlong) table->grant.want_privilege));
} }
/* /*
Set exclude_from_table_unique_test value back to FALSE. It is needed for Set exclude_from_table_unique_test value back to FALSE. It is needed for

View file

@ -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 This will hold the intersection of the priviliges on all columns in the
view. view.
*/ */
uint final_priv= VIEW_ANY_ACL; privilege_t final_priv(VIEW_ANY_ACL);
for (sl= select_lex; sl; sl= sl->next_select()) 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++)) while ((item= it++))
{ {
Item_field *fld= item->field_for_view_update(); Item_field *fld= item->field_for_view_update();
uint priv= (get_column_grant(thd, &view->grant, view->db.str, privilege_t priv(get_column_grant(thd, &view->grant, view->db.str,
view->table_name.str, item->name.str) & view->table_name.str,
item->name.str) &
VIEW_ANY_ACL); VIEW_ANY_ACL);
if (!fld) if (!fld)

View file

@ -191,7 +191,6 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
ulonglong ulonglong_number; ulonglong ulonglong_number;
longlong longlong_number; longlong longlong_number;
uint sp_instr_addr; uint sp_instr_addr;
uint privilege;
/* structs */ /* structs */
LEX_CSTRING lex_str; LEX_CSTRING lex_str;
@ -314,6 +313,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
enum vers_kind_t vers_range_unit; enum vers_kind_t vers_range_unit;
enum Column_definition::enum_column_versioning vers_column_versioning; enum Column_definition::enum_column_versioning vers_column_versioning;
enum plsql_cursor_attr_t plsql_cursor_attr; enum plsql_cursor_attr_t plsql_cursor_attr;
privilege_t privilege;
} }
%{ %{
@ -16846,7 +16846,7 @@ object_privilege:
| UPDATE_SYM { $$= UPDATE_ACL; } | UPDATE_SYM { $$= UPDATE_ACL; }
| REFERENCES { $$= REFERENCES_ACL; } | REFERENCES { $$= REFERENCES_ACL; }
| DELETE_SYM { $$= DELETE_ACL;} | DELETE_SYM { $$= DELETE_ACL;}
| USAGE { $$= 0; } | USAGE { $$= NO_ACL; }
| INDEX_SYM { $$= INDEX_ACL;} | INDEX_SYM { $$= INDEX_ACL;}
| ALTER { $$= ALTER_ACL;} | ALTER { $$= ALTER_ACL;}
| CREATE { $$= CREATE_ACL;} | CREATE { $$= CREATE_ACL;}
@ -17105,12 +17105,12 @@ opt_resource_options:
opt_grant_options: opt_grant_options:
/* empty */ { $$= 0; } /* empty */ { $$= NO_ACL; }
| WITH grant_option_list { $$= $2; } | WITH grant_option_list { $$= $2; }
; ;
opt_grant_option: opt_grant_option:
/* empty */ { $$= 0; } /* empty */ { $$= NO_ACL; }
| WITH GRANT OPTION { $$= GRANT_ACL; } | WITH GRANT OPTION { $$= GRANT_ACL; }
; ;
@ -17121,7 +17121,7 @@ grant_option_list:
grant_option: grant_option:
GRANT OPTION { $$= GRANT_ACL;} GRANT OPTION { $$= GRANT_ACL;}
| resource_option { $$= 0; } | resource_option { $$= NO_ACL; }
; ;
begin_stmt_mariadb: begin_stmt_mariadb:

View file

@ -6153,7 +6153,7 @@ TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
want_access Acess which we require 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 */ /* Remove SHOW_VIEW_ACL, because it will be checked during making view */
want_access&= ~SHOW_VIEW_ACL; want_access&= ~SHOW_VIEW_ACL;
@ -6322,7 +6322,7 @@ bool TABLE_LIST::prepare_security(THD *thd)
thd->security_ctx= save_security_ctx; thd->security_ctx= save_security_ctx;
#else #else
while ((tbl= tb++)) while ((tbl= tb++))
tbl->grant.privilege= ~NO_ACCESS; tbl->grant.privilege= ALL_KNOWN_ACL;
#endif #endif
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }

View file

@ -33,6 +33,7 @@
#include "parse_file.h" #include "parse_file.h"
#include "sql_i_s.h" #include "sql_i_s.h"
#include "sql_type.h" /* vers_kind_t */ #include "sql_type.h" /* vers_kind_t */
#include "privilege.h" /* privilege_t */
/* Structs that defines the TABLE */ /* 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. 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 @brief the set of privileges that the current user needs to fulfil in
order to carry out the requested operation. 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 Stores the requested access acl of top level tables list. Is used to
check access rights to the underlying tables of a view. 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. */ /** The grant state for internal tables. */
GRANT_INTERNAL_INFO m_internal; GRANT_INTERNAL_INFO m_internal;
st_grant_info()
:privilege(NO_ACL),
want_privilege(NO_ACL),
orig_want_privilege(NO_ACL)
{ }
} GRANT_INFO; } GRANT_INFO;
enum tmp_table_type enum tmp_table_type
@ -2507,7 +2514,7 @@ struct TABLE_LIST
return FALSE; return FALSE;
} }
void register_want_access(ulong want_access); void register_want_access(privilege_t want_access);
bool prepare_security(THD *thd); bool prepare_security(THD *thd);
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *find_view_security_context(THD *thd); Security_context *find_view_security_context(THD *thd);

View file

@ -2801,7 +2801,7 @@ void* start_wsrep_THD(void *arg)
/* from bootstrap()... */ /* from bootstrap()... */
thd->bootstrap=1; thd->bootstrap=1;
thd->max_client_packet_length= thd->net.max_packet; 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... */ /* from handle_one_connection... */
pthread_detach_this_thread(); pthread_detach_this_thread();

View file

@ -426,7 +426,7 @@ thd::thd (my_bool won) : init(), ptr(new THD(0))
wsrep_store_threadvars(ptr); wsrep_store_threadvars(ptr);
ptr->variables.option_bits&= ~OPTION_BIN_LOG; // disable binlog ptr->variables.option_bits&= ~OPTION_BIN_LOG; // disable binlog
ptr->variables.wsrep_on= won; ptr->variables.wsrep_on= won;
ptr->security_ctx->master_access= ~(ulong)0; ptr->security_ctx->master_access= ALL_KNOWN_ACL;
lex_start(ptr); lex_start(ptr);
} }
} }

View file

@ -451,22 +451,22 @@ public:
~PFS_internal_schema_access() ~PFS_internal_schema_access()
{} {}
ACL_internal_access_result check(ulong want_access, ACL_internal_access_result check(privilege_t want_access,
ulong *save_priv) const; privilege_t *save_priv) const;
const ACL_internal_table_access *lookup(const char *name) const; const ACL_internal_table_access *lookup(const char *name) const;
}; };
ACL_internal_access_result ACL_internal_access_result
PFS_internal_schema_access::check(ulong want_access, PFS_internal_schema_access::check(privilege_t want_access,
ulong *save_priv) const 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 | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL
| CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL
| EVENT_ACL | TRIGGER_ACL ; | EVENT_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_DENIED;
/* /*
@ -511,13 +511,13 @@ void initialize_performance_schema_acl(bool bootstrap)
PFS_readonly_acl pfs_readonly_acl; PFS_readonly_acl pfs_readonly_acl;
ACL_internal_access_result 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_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
| CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_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_DENIED;
return ACL_INTERNAL_ACCESS_CHECK_GRANT; 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; PFS_truncatable_acl pfs_truncatable_acl;
ACL_internal_access_result 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_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
| CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_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_DENIED;
return ACL_INTERNAL_ACCESS_CHECK_GRANT; 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; PFS_updatable_acl pfs_updatable_acl;
ACL_internal_access_result 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_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
| CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_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_DENIED;
return ACL_INTERNAL_ACCESS_CHECK_GRANT; 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; PFS_editable_acl pfs_editable_acl;
ACL_internal_access_result 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; | 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_DENIED;
return ACL_INTERNAL_ACCESS_CHECK_GRANT; 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; PFS_unknown_acl pfs_unknown_acl;
ACL_internal_access_result 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 | REFERENCES_ACL | INDEX_ACL | ALTER_ACL
| CREATE_VIEW_ACL | TRIGGER_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; return ACL_INTERNAL_ACCESS_DENIED;
/* /*

View file

@ -266,7 +266,8 @@ public:
~PFS_readonly_acl() ~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. */ /** Singleton instance of PFS_readonly_acl. */
@ -285,7 +286,8 @@ public:
~PFS_truncatable_acl() ~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. */ /** Singleton instance of PFS_truncatable_acl. */
@ -304,7 +306,8 @@ public:
~PFS_updatable_acl() ~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. */ /** Singleton instance of PFS_updatable_acl. */
@ -323,7 +326,8 @@ public:
~PFS_editable_acl() ~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. */ /** Singleton instance of PFS_editable_acl. */
@ -341,7 +345,8 @@ public:
~PFS_unknown_acl() ~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. */ /** Singleton instance of PFS_unknown_acl. */