MySQL  8.0.19
Source Code Documentation
sql_user_table.cc File Reference
#include "sql/auth/sql_user_table.h"
#include "my_config.h"
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <memory>
#include <set>
#include <unordered_map>
#include <utility>
#include "lex_string.h"
#include "m_ctype.h"
#include "m_string.h"
#include "map_helpers.h"
#include "my_alloc.h"
#include "my_base.h"
#include "my_dbug.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "mysql/components/services/log_builtins.h"
#include "mysql/components/services/log_shared.h"
#include "mysql/psi/mysql_statement.h"
#include "mysql_com.h"
#include "mysql_time.h"
#include "mysqld_error.h"
#include "sql/auth/acl_change_notification.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/auth/auth_internal.h"
#include "sql/auth/sql_auth_cache.h"
#include "sql/auth/sql_authentication.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/binlog.h"
#include "sql/field.h"
#include "sql/handler.h"
#include "sql/item_func.h"
#include "sql/key.h"
#include "sql/log.h"
#include "sql/mdl.h"
#include "sql/mysqld.h"
#include "sql/rpl_filter.h"
#include "sql/rpl_rli.h"
#include "sql/sql_base.h"
#include "sql/sql_class.h"
#include "sql/sql_connect.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_lex.h"
#include "sql/sql_list.h"
#include "sql/sql_parse.h"
#include "sql/sql_rewrite.h"
#include "sql/sql_table.h"
#include "sql/sql_update.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/transaction.h"
#include "sql/tztime.h"
#include "sql_string.h"
#include "thr_lock.h"
#include "typelib.h"
#include "violite.h"

Functions

void commit_and_close_mysql_tables (THD *thd)
 A helper function to commit statement transaction and close ACL tables after reading some data from them as part of FLUSH PRIVILEGES statement or during server initialization. More...
 
ulong get_access (TABLE *form, uint fieldnr, uint *next_field)
 
void acl_notify_htons (THD *thd, enum_sql_command operation, const List< LEX_USER > *users, const List< LEX_CSTRING > *dynamic_privs)
 
static bool acl_end_trans_and_close_tables (THD *thd, bool rollback_transaction)
 Commit or rollback ACL statement (and transaction), close tables which it has opened and release metadata locks. More...
 
bool log_and_commit_acl_ddl (THD *thd, bool transactional_tables, std::set< LEX_USER * > *extra_users, Rewrite_params *rewrite_params, bool extra_error, bool write_to_binlog)
 
static void get_grantor (THD *thd, char *grantor)
 
void acl_print_ha_error (int handler_error)
 Take a handler error and generate the mysql error ER_ACL_OPERATION_FAILED containing original text of HA error. More...
 
int replace_db_table (THD *thd, TABLE *table, const char *db, const LEX_USER &combo, ulong rights, bool revoke_grant)
 change grants in the mysql.db table. More...
 
int replace_proxies_priv_table (THD *thd, TABLE *table, const LEX_USER *user, const LEX_USER *proxied_user, bool with_grant_arg, bool revoke_grant)
 Insert, update or remove a record in the mysql.proxies_priv table. More...
 
int replace_column_table (THD *thd, 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)
 Update record in the table mysql.columns_priv. More...
 
int replace_table_table (THD *thd, GRANT_TABLE *grant_table, std::unique_ptr< GRANT_TABLE, Destroy_only< GRANT_TABLE >> *deleted_grant_table, TABLE *table, const LEX_USER &combo, const char *db, const char *table_name, ulong rights, ulong col_rights, bool revoke_grant)
 Search and create/update a record for requested table privileges. More...
 
int replace_routine_table (THD *thd, GRANT_NAME *grant_name, TABLE *table, const LEX_USER &combo, const char *db, const char *routine_name, bool is_proc, ulong rights, bool revoke_grant)
 Search and create/update a record for the routine requested. More...
 
void grant_tables_setup_for_open (TABLE_LIST *tables, thr_lock_type lock_type, enum_mdl_type mdl_type)
 Prepare an array of all of the grant tables for opening. More...
 
int open_grant_tables (THD *thd, TABLE_LIST *tables, bool *transactional_tables)
 Open the grant tables. More...
 
static int modify_grant_table (TABLE *table, Field *host_field, Field *user_field, LEX_USER *user_to)
 Modify a privilege table. More...
 
int handle_grant_table (THD *thd, TABLE_LIST *tables, ACL_TABLES table_no, bool drop, LEX_USER *user_from, LEX_USER *user_to)
 Handle a privilege table. More...
 
bool check_engine_type_for_acl_table (TABLE_LIST *tables, bool report_error)
 Check that every ACL table has a supported storage engine (InnoDB). More...
 

Variables

static const TABLE_FIELD_TYPE mysql_db_table_fields [MYSQL_DB_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_user_table_fields [MYSQL_USER_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_proxies_priv_table_fields [MYSQL_PROXIES_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_procs_priv_table_fields [MYSQL_PROCS_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_columns_priv_table_fields [MYSQL_COLUMNS_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_tables_priv_table_fields [MYSQL_TABLES_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_role_edges_table_fields [MYSQL_ROLE_EDGES_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_default_roles_table_fields [MYSQL_DEFAULT_ROLES_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_password_history_table_fields [MYSQL_PASSWORD_HISTORY_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_dynamic_priv_table_fields [MYSQL_DYNAMIC_PRIV_FIELD_COUNT]
 
bool initialized
 

Function Documentation

◆ acl_end_trans_and_close_tables()

static bool acl_end_trans_and_close_tables ( THD thd,
bool  rollback_transaction 
)
static

Commit or rollback ACL statement (and transaction), close tables which it has opened and release metadata locks.

Note
In case of failure to commit transaction we try to restore correct state of in-memory structures by reloading privileges.
Return values
False- Success.
True- Error.

◆ acl_notify_htons()

void acl_notify_htons ( THD thd,
enum_sql_command  operation,
const List< LEX_USER > *  users,
const List< LEX_CSTRING > *  dynamic_privs 
)

◆ acl_print_ha_error()

void acl_print_ha_error ( int  handler_error)

Take a handler error and generate the mysql error ER_ACL_OPERATION_FAILED containing original text of HA error.

Parameters
handler_erroran error number resulted from storage engine

◆ check_engine_type_for_acl_table()

bool check_engine_type_for_acl_table ( TABLE_LIST tables,
bool  report_error 
)

Check that every ACL table has a supported storage engine (InnoDB).

Report error if table's engine type is not supported.

Parameters
tablesPointer to TABLES_LIST of ACL tables to check.
report_errorIf true report error to the client/diagnostic area, otherwise write a warning to the error log.
Returns
bool
Return values
falseOK
truesome of ACL tables has an unsupported engine type.

◆ commit_and_close_mysql_tables()

void commit_and_close_mysql_tables ( THD thd)

A helper function to commit statement transaction and close ACL tables after reading some data from them as part of FLUSH PRIVILEGES statement or during server initialization.

Note
We assume that we have only read from the tables so commit can't fail.
See also
close_mysql_tables().
Note
This function also rollbacks the transaction if rollback was requested (e.g. as result of deadlock).

◆ get_access()

ulong get_access ( TABLE form,
uint  fieldnr,
uint next_field 
)

◆ get_grantor()

static void get_grantor ( THD thd,
char *  grantor 
)
static

◆ grant_tables_setup_for_open()

void grant_tables_setup_for_open ( TABLE_LIST tables,
thr_lock_type  lock_type,
enum_mdl_type  mdl_type 
)

Prepare an array of all of the grant tables for opening.

Prepare references to all of the grant tables in the order of the ACL_TABLES enum.

Set the tables to be one after another.

Parameters
[in,out]tablesArray of ACL_TABLES::LAST_ENTRY table list elements which will be used for opening tables.
lock_typeLock type to use
mdl_typeMDL lock type to use

◆ handle_grant_table()

int handle_grant_table ( THD thd,
TABLE_LIST tables,
ACL_TABLES  table_no,
bool  drop,
LEX_USER user_from,
LEX_USER user_to 
)

Handle a privilege table.

Parameters
thdThe thead handler
tablesThe array with the four open tables.
table_noThe number of the table to handle (0..4).
dropIf user_from is to be dropped.
user_fromThe the user to be searched/dropped/renamed.
user_toThe new name for the user if to be renamed, NULL otherwise.

Scan through all records in a grant table and apply the requested operation. For the "user" table, a single index access is sufficient, since there is an unique index on (host, user). Delete from grant table if drop is true. Update in grant table if drop is false and user_to is not NULL. Search in grant table if drop is false and user_to is NULL.

Returns
Operation result
Return values
0OK, but no record matched.
<0 Error.
>0 At least one record matched.

◆ log_and_commit_acl_ddl()

bool log_and_commit_acl_ddl ( THD thd,
bool  transactional_tables,
std::set< LEX_USER * > *  extra_users,
Rewrite_params rewrite_params,
bool  extra_error,
bool  write_to_binlog 
)

◆ modify_grant_table()

static int modify_grant_table ( TABLE table,
Field host_field,
Field user_field,
LEX_USER user_to 
)
static

Modify a privilege table.

Parameters
tableThe table to modify.
host_fieldThe host name field.
user_fieldThe user name field.
user_toThe new name for the user if to be renamed, NULL otherwise.
Note
Update user/host in the current record if user_to is not NULL. Delete the current record if user_to is NULL.
Return values
0OK.
!=0 Error.

◆ open_grant_tables()

int open_grant_tables ( THD thd,
TABLE_LIST tables,
bool transactional_tables 
)

Open the grant tables.

Parameters
thdThe current thread.
[in,out]tablesArray of ACL_TABLES::LAST_ENTRY table list elements which will be used for opening tables.
[out]transactional_tablesSet to true if one of grant tables is transactional, false otherwise.
Return values
1Skip GRANT handling during replication.
0OK.
<0 Error.
Note
IX Backup Lock is implicitly acquired as side effect of calling this function.

◆ replace_column_table()

int replace_column_table ( THD thd,
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 
)

Update record in the table mysql.columns_priv.

Parameters
thdCurrent thread execution context.
g_tPointer to a cached table grant object
tablePointer to a TABLE object for open mysql.columns_priv table
comboPointer to a LEX_USER object containing info about a user being processed
columnsList of columns to give/revoke grant
dbDatabase name of table for which column priviliges are modified
table_nameName of table for which column priviliges are modified
rightsTable level grant
revoke_grantSet to true if this is a REVOKE command
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen
>0 Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.

◆ replace_db_table()

int replace_db_table ( THD thd,
TABLE table,
const char *  db,
const LEX_USER combo,
ulong  rights,
bool  revoke_grant 
)

change grants in the mysql.db table.

Parameters
thdCurrent thread execution context.
tablePointer to a TABLE object for opened mysql.db table.
dbDatabase name of table for which column priviliges are modified.
comboPointer to a LEX_USER object containing info about a user being processed.
rightsDatabase level grant.
revoke_grantSet to true if this is a REVOKE command.
Returns
Operation result
Return values
0OK.
1Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.
<0 Error.

◆ replace_proxies_priv_table()

int replace_proxies_priv_table ( THD thd,
TABLE table,
const LEX_USER user,
const LEX_USER proxied_user,
bool  with_grant_arg,
bool  revoke_grant 
)

Insert, update or remove a record in the mysql.proxies_priv table.

Parameters
thdThe current thread.
tablePointer to a TABLE object for opened mysql.proxies_priv table.
userInformation about user being handled.
proxied_userInformation about proxied user being handled.
with_grant_argTrue if a user is allowed to execute GRANT, else false.
revoke_grantSet to true if this is REVOKE command.
Returns
Operation result.
Return values
0OK.
1Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.
<0 Error.

◆ replace_routine_table()

int replace_routine_table ( THD thd,
GRANT_NAME grant_name,
TABLE table,
const LEX_USER combo,
const char *  db,
const char *  routine_name,
bool  is_proc,
ulong  rights,
bool  revoke_grant 
)

Search and create/update a record for the routine requested.

Parameters
thdThe current thread.
grant_nameCached info about stored routine.
tablePointer to a TABLE object for open mysql.procs_priv table.
comboUser information.
dbDatabase name for stored routine.
routine_nameName for stored routine.
is_procTrue for stored procedure, false for stored function.
rightsRights requested.
revoke_grantSet to true if a REVOKE command is executed.
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen
>0 Error in handling current routine entry but still can continue processing subsequent user specified in the ACL statement.

◆ replace_table_table()

int replace_table_table ( THD thd,
GRANT_TABLE grant_table,
std::unique_ptr< GRANT_TABLE, Destroy_only< GRANT_TABLE >> *  deleted_grant_table,
TABLE table,
const LEX_USER combo,
const char *  db,
const char *  table_name,
ulong  rights,
ulong  col_rights,
bool  revoke_grant 
)

Search and create/update a record for requested table privileges.

Parameters
thdThe current thread.
grant_tableCached info about table/columns privileges.
deleted_grant_tableIf non-nullptr and grant is removed from column cache, it is returned here instead of being destroyed.
tablePointer to a TABLE object for open mysql.tables_priv table.
comboUser information.
dbDatabase name of table to give grant.
table_nameName of table to give grant.
rightsTable privileges to set/update.
col_rightsColumn privileges to set/update.
revoke_grantSet to true if a REVOKE command is executed.
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen.
1No entry for request.

Variable Documentation

◆ initialized

bool initialized

◆ mysql_columns_priv_table_fields

const TABLE_FIELD_TYPE mysql_columns_priv_table_fields[MYSQL_COLUMNS_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {NULL, 0}},
{{STRING_WITH_LEN("User")},
{NULL, 0}},
{{STRING_WITH_LEN("Table_name")},
{STRING_WITH_LEN("char(64)")},
{NULL, 0}},
{{STRING_WITH_LEN("Column_name")},
{STRING_WITH_LEN("char(64)")},
{NULL, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{NULL, 0}},
{{STRING_WITH_LEN("Column_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','References')")},
{STRING_WITH_LEN("utf8")}}}

◆ mysql_db_table_fields

const TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT]
static

◆ mysql_default_roles_table_fields

const TABLE_FIELD_TYPE mysql_default_roles_table_fields[MYSQL_DEFAULT_ROLES_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("HOST")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("USER")},
{NULL, 0}},
{{STRING_WITH_LEN("DEFAULT_ROLE_HOST")},
{STRING_WITH_LEN("char(255)")},
{NULL, 0}},
{{STRING_WITH_LEN("DEFAULT_ROLE_USER")},
{NULL, 0}}}

◆ mysql_dynamic_priv_table_fields

const TABLE_FIELD_TYPE mysql_dynamic_priv_table_fields[MYSQL_DYNAMIC_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("USER")},
{NULL, 0}},
{{STRING_WITH_LEN("HOST")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("PRIV")}, {STRING_WITH_LEN("char(32)")}, {NULL, 0}},
{{STRING_WITH_LEN("WITH_GRANT_OPTION")},
{STRING_WITH_LEN("enum('N','Y')")},
{NULL, 0}}}

◆ mysql_password_history_table_fields

const TABLE_FIELD_TYPE mysql_password_history_table_fields[MYSQL_PASSWORD_HISTORY_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("User")},
{NULL, 0}},
{{STRING_WITH_LEN("Password_timestamp")},
{STRING_WITH_LEN("timestamp")},
{NULL, 0}},
{{STRING_WITH_LEN("Password")}, {STRING_WITH_LEN("text")}, {NULL, 0}}}

◆ mysql_procs_priv_table_fields

const TABLE_FIELD_TYPE mysql_procs_priv_table_fields[MYSQL_PROCS_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {NULL, 0}},
{{STRING_WITH_LEN("User")},
{NULL, 0}},
{{STRING_WITH_LEN("Routine_name")},
{STRING_WITH_LEN("char(64)")},
{STRING_WITH_LEN("utf8")}},
{{STRING_WITH_LEN("Routine_type")},
{STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')")},
{NULL, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{NULL, 0}},
{{STRING_WITH_LEN("Proc_priv")},
{STRING_WITH_LEN("set('Execute','Alter Routine','Grant')")},
{STRING_WITH_LEN("utf8")}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{NULL, 0}}}

◆ mysql_proxies_priv_table_fields

const TABLE_FIELD_TYPE mysql_proxies_priv_table_fields[MYSQL_PROXIES_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("User")},
{NULL, 0}},
{{STRING_WITH_LEN("Proxied_host")},
{STRING_WITH_LEN("char(255)")},
{NULL, 0}},
{{STRING_WITH_LEN("Proxied_user")},
{NULL, 0}},
{{STRING_WITH_LEN("With_grant")},
{STRING_WITH_LEN("tinyint")},
{NULL, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{NULL, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{NULL, 0}}}

◆ mysql_role_edges_table_fields

const TABLE_FIELD_TYPE mysql_role_edges_table_fields[MYSQL_ROLE_EDGES_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("FROM_HOST")},
{STRING_WITH_LEN("char(255)")},
{NULL, 0}},
{{STRING_WITH_LEN("FROM_USER")},
{NULL, 0}},
{{STRING_WITH_LEN("TO_HOST")},
{STRING_WITH_LEN("char(255)")},
{NULL, 0}},
{{STRING_WITH_LEN("TO_USER")},
{NULL, 0}},
{{STRING_WITH_LEN("WITH_ADMIN_OPTION")},
{STRING_WITH_LEN("enum('N','Y')")},
{STRING_WITH_LEN("utf8")}}}

◆ mysql_tables_priv_table_fields

const TABLE_FIELD_TYPE mysql_tables_priv_table_fields[MYSQL_TABLES_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")}, {STRING_WITH_LEN("char(255)")}, {NULL, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {NULL, 0}},
{{STRING_WITH_LEN("User")},
{NULL, 0}},
{{STRING_WITH_LEN("Table_name")},
{STRING_WITH_LEN("char(64)")},
{NULL, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{NULL, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{NULL, 0}},
{{STRING_WITH_LEN("Table_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','Delete','Create',"
"'Drop','Grant','References','Index','Alter',"
"'Create View','Show view','Trigger')")},
{STRING_WITH_LEN("utf8")}},
{{STRING_WITH_LEN("Column_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','References')")},
{STRING_WITH_LEN("utf8")}}}

◆ mysql_user_table_fields

const TABLE_FIELD_TYPE mysql_user_table_fields[MYSQL_USER_FIELD_COUNT]
static
NULL
#define NULL
Definition: types.h:55
STRING_WITH_LEN
#define STRING_WITH_LEN(X)
Definition: m_string.h:306
USERNAME_CHAR_LENGTH_STR
#define USERNAME_CHAR_LENGTH_STR
Definition: mysql_com.h:64