MySQL 8.3.0
Source Code Documentation
sql_authorization.cc File Reference

AUTHORIZATION CODE. More...

#include "sql/auth/sql_authorization.h"
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <algorithm>
#include <boost/concept/usage.hpp>
#include <boost/function.hpp>
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphml.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/properties.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/range/irange.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/tuple/tuple.hpp>
#include <cstdlib>
#include <iterator>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "lex_string.h"
#include "m_string.h"
#include "map_helpers.h"
#include "mf_wcomp.h"
#include "my_alloc.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_macros.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/my_loglevel.h"
#include "mysql/mysql_lex_string.h"
#include "mysql/plugin_audit.h"
#include "mysql/psi/mysql_mutex.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql/strings/m_ctype.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "nulls.h"
#include "prealloced_array.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/auth/auth_internal.h"
#include "sql/auth/auth_utility.h"
#include "sql/auth/dynamic_privilege_table.h"
#include "sql/auth/partial_revokes.h"
#include "sql/auth/role_tables.h"
#include "sql/auth/roles.h"
#include "sql/auth/sql_auth_cache.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/auth/sql_user_table.h"
#include "sql/current_thd.h"
#include "sql/dd/dd_table.h"
#include "sql/debug_sync.h"
#include "sql/derror.h"
#include "sql/error_handler.h"
#include "sql/field.h"
#include "sql/handler.h"
#include "sql/item.h"
#include "sql/key_spec.h"
#include "sql/mdl.h"
#include "sql/mysqld.h"
#include "sql/nested_join.h"
#include "sql/protocol.h"
#include "sql/sp.h"
#include "sql/sql_admin.h"
#include "sql/sql_alter.h"
#include "sql/sql_audit.h"
#include "sql/sql_base.h"
#include "sql/sql_class.h"
#include "sql/sql_connect.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_show.h"
#include "sql/sql_view.h"
#include "sql/strfunc.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/thd_raii.h"
#include "sql_string.h"
#include "string_with_len.h"
#include "strxmov.h"
#include "template_utils.h"
#include "thr_lock.h"
#include "violite.h"

Classes

class  Grant_validator
 Class to handle sanity checks for GRANT ... AS ... statement. More...
 
class  Get_access_maps
 A graph visitor used for doing breadth-first traversal of the global role graph. More...
 
class  Silence_routine_definer_errors
 If the defining user for a routine does not exist, then the ACL lookup code should raise two errors which we should intercept. More...
 

Typedefs

typedef boost::graph_traits< Granted_roles_graph >::adjacency_iterator Role_adjacency_iterator
 

Functions

bool operator== (const Role_id &a, const std::string &b)
 
bool operator== (const std::pair< Role_id, bool > &a, const std::string &b)
 
static bool is_dynamic_privilege_registered (const std::string &privilege)
 The dynamic privilege is probed in the global map that keeps track of dynamic privileges registered with server. More...
 
static bool check_routine_level_acl (THD *thd, const char *db, const char *name, bool is_proc)
 
void get_granted_roles (Role_vertex_descriptor &v, List_of_granted_roles *granted_roles)
 Populates a list of authorization IDs that are connected to a specified graph vertex in the global roles graph. More...
 
bool revoke_role_helper (THD *thd, std::string &authid_role, std::string &authid_user, Role_vertex_descriptor *user_vert, Role_vertex_descriptor *role_vert)
 This utility function is used by revoke_role() and remove_all_granted_roles() for removing a specific edge from the role graph. More...
 
static void update_role_flag_of_acl_user (const Role_vertex_descriptor &role_vert, ACL_USER *acl_user)
 This utility function checks for the connecting vertices of the role descriptor(authid node) and updates the role flag of the corresponding ACL user. More...
 
void revoke_role (THD *thd, ACL_USER *role, ACL_USER *user)
 Used by mysql_revoke_role() for revoking a specified role from a specified user. More...
 
void rebuild_vertex_index (THD *thd)
 Since the gap in the vertex vector was removed all the vertex descriptors has changed. More...
 
bool drop_role (THD *thd, TABLE *edge_table, TABLE *defaults_table, const Auth_id_ref &authid_user)
 
bool revoke_all_roles_from_user (THD *thd, TABLE *edge_table, TABLE *defaults_table, LEX_USER *user_name)
 Used by mysql_drop_user. More...
 
bool revoke_all_granted_roles (THD *thd, TABLE *table, LEX_USER *user_from, List_of_granted_roles *granted_roles)
 If possible, it will revoke all roles and default roles from user_from and set them for user_to instead. More...
 
bool is_role_id (LEX_USER *authid)
 
void grant_role (ACL_USER *role, const ACL_USER *user, bool with_admin_opt)
 Grants a single role to a single user. More...
 
void create_role_vertex (ACL_USER *role_acl_user)
 Helper function for create_roles_vertices. More...
 
bool roles_rename_authid (THD *thd, TABLE *edge_table, TABLE *defaults_table, LEX_USER *user_from, LEX_USER *user_to)
 Renames a user in the mysql.role_edge and the mysql.default_roles tables. More...
 
void make_global_privilege_statement (THD *thd, ulong want_access, ACL_USER *acl_user, String *global)
 Maps a global ACL to a string representation. More...
 
void make_database_privilege_statement (THD *thd, ACL_USER *role, Protocol *protocol, const Db_access_map &db_map, const Db_access_map &db_wild_map, const DB_restrictions &restrictions)
 Maps a set of database level ACLs to string representations and sends them through the client protocol. More...
 
void make_proxy_privilege_statement (THD *thd, ACL_USER *user, Protocol *protocol)
 Maps a set of global level proxy ACLs to string representations and sends them through the client protocol. More...
 
void make_sp_privilege_statement (THD *thd, ACL_USER *role, Protocol *protocol, SP_access_map &sp_map, int type)
 Maps a set of database level ACLs for stored programs to string representations and sends them through the client protocol. More...
 
void make_with_admin_privilege_statement (THD *thd, ACL_USER *acl_user, Protocol *protocol, const Grant_acl_set &with_admin_acl, const List_of_granted_roles &granted_roles)
 
void make_dynamic_privilege_statement (THD *thd, ACL_USER *role, Protocol *protocol, const Dynamic_privileges &dyn_priv)
 
void make_roles_privilege_statement (THD *thd, ACL_USER *role, Protocol *protocol, List_of_granted_roles &granted_roles, bool show_mandatory_roles)
 
void make_table_privilege_statement (THD *thd, ACL_USER *role, Protocol *protocol, Table_access_map &table_map)
 
void get_sp_access_map (ACL_USER *acl_user, SP_access_map *sp_map, malloc_unordered_multimap< std::string, unique_ptr_destroy_only< GRANT_NAME > > *hash)
 
void get_table_access_map (ACL_USER *acl_user, Table_access_map *table_map)
 
void get_dynamic_privileges (ACL_USER *acl_user, Dynamic_privileges *acl)
 
bool has_wildcard_characters (const LEX_CSTRING &db)
 
void get_database_access_map (ACL_USER *acl_user, Db_access_map *db_map, Db_access_map *db_wild_map)
 
const ACL_internal_schema_accessget_cached_schema_access (GRANT_INTERNAL_INFO *grant_internal_info, const char *schema_name)
 Get a cached internal schema access. More...
 
const ACL_internal_table_accessget_cached_table_access (GRANT_INTERNAL_INFO *grant_internal_info, const char *schema_name, const char *table_name)
 Get a cached internal table access. More...
 
bool lock_tables_precheck (THD *thd, Table_ref *tables)
 Check privileges for LOCK TABLES statement. More...
 
bool create_table_precheck (THD *thd, Table_ref *tables, Table_ref *create_table)
 CREATE TABLE query pre-check. More...
 
bool check_readonly (THD *thd, bool err_if_readonly)
 Performs standardized check whether to prohibit (true) or allow (false) operations based on read_only and super_read_only state. More...
 
void err_readonly (THD *thd)
 Generates appropriate error messages for read-only state depending on whether user has SUPER privilege or not. More...
 
bool check_one_table_access (THD *thd, ulong privilege, Table_ref *all_tables)
 Check grants for commands which work only with one table and all other tables belonging to subselects or implicitly opened tables. More...
 
bool check_single_table_access (THD *thd, ulong privilege, Table_ref *all_tables, bool no_errors)
 Check grants for commands which work only with one table. More...
 
bool check_routine_access (THD *thd, ulong want_access, const char *db, char *name, bool is_proc, bool no_errors)
 
bool check_some_access (THD *thd, ulong want_access, Table_ref *table)
 Check if the given table has any of the asked privileges. More...
 
bool has_full_view_routine_access (THD *thd, const char *db, const char *definer_user, const char *definer_host)
 Check if user has full access to view routine's properties (i.e including stored routine code). More...
 
bool has_partial_view_routine_access (THD *thd, const char *db, const char *routine_name, bool is_proc)
 Check if user has partial access to view routine's properties (i.e. More...
 
bool check_access (THD *thd, ulong want_access, const char *db, ulong *save_priv, GRANT_INTERNAL_INFO *grant_internal_info, bool dont_check_global_grants, bool no_errors)
 Compare requested privileges with the privileges acquired from the User- and Db-tables. More...
 
bool check_table_access (THD *thd, ulong requirements, Table_ref *tables, bool any_combination_of_privileges_will_do, uint number, bool no_errors)
 Check if the requested privileges exists in either User-, DB- or, tables- tables. More...
 
bool check_table_encryption_admin_access (THD *thd)
 Check if a current user has the privilege TABLE_ENCRYPTION_ADMIN required to create encrypted table. More...
 
bool is_granted_table_access (THD *thd, ulong required_acl, Table_ref *table)
 Given a Table_ref object this function checks against. More...
 
bool has_grant_role_privilege (THD *thd, const List< LEX_USER > *roles)
 
bool report_missing_user_grant_message (THD *thd, bool user_exists, const char *user, const char *host, const char *object_name, int err_code)
 Helper method to check if warning or error should be reported based on: More...
 
int mysql_table_grant (THD *thd, Table_ref *table_list, List< LEX_USER > &user_list, List< LEX_COLUMN > &columns, ulong rights, bool revoke_grant, bool all_current_privileges)
 
bool mysql_routine_grant (THD *thd, Table_ref *table_list, bool is_proc, List< LEX_USER > &user_list, ulong rights, bool revoke_grant, bool write_to_binlog, bool all_current_privileges)
 Store routine level grants in the privilege tables. More...
 
bool mysql_revoke_role (THD *thd, const List< LEX_USER > *users, const List< LEX_USER > *roles)
 
bool has_dynamic_privilege_grant_option (Security_context *sctx, std::string priv)
 
static bool check_if_granted_role_recursive (LEX_CSTRING start, LEX_CSTRING start_host, LEX_CSTRING search_for, LEX_CSTRING search_for_host)
 Search if an auth_id (search_for@search_for_host) is granted either directly or indirectly to an auth_id (start@start_host) or to one of the mandatory roles. More...
 
bool mysql_grant_role (THD *thd, const List< LEX_USER > *users, const List< LEX_USER > *roles, bool with_admin_opt)
 Grants a list of roles to a list of users. More...
 
bool mysql_grant (THD *thd, const char *db, List< LEX_USER > &list, ulong rights, bool revoke_grant, bool is_proxy, const List< LEX_CSTRING > &dynamic_privilege, bool grant_all_current_privileges, LEX_GRANT_AS *grant_as)
 
bool check_grant (THD *thd, ulong want_access, Table_ref *tables, bool any_combination_will_do, uint number, bool no_errors)
 Check table level grants. More...
 
bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, size_t length, Security_context *sctx, ulong want_privilege)
 
bool check_column_grant_in_table_ref (THD *thd, Table_ref *table_ref, const char *name, size_t length, ulong want_privilege)
 Check the privileges for a column depending on the type of table. More...
 
bool check_grant_all_columns (THD *thd, ulong want_access_arg, Field_iterator_table_ref *fields)
 check if a query can access a set of columns More...
 
static bool check_grant_db_routine (THD *thd, const char *db, malloc_unordered_multimap< std::string, unique_ptr_destroy_only< GRANT_NAME > > *hash)
 
bool has_any_table_acl (Security_context *sctx, const LEX_CSTRING &str)
 
bool has_any_routine_acl (Security_context *sctx, const LEX_CSTRING &db)
 
bool check_grant_db (THD *thd, const char *db, const bool check_table_grant)
 Check if a user has the right to access a database. More...
 
bool check_grant_routine (THD *thd, ulong want_access, Table_ref *procs, bool is_proc, bool no_errors)
 
ulong get_table_grant (THD *thd, Table_ref *table)
 
ulong get_column_grant (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name)
 
void get_privilege_desc (char *to, uint max_length, ulong access)
 
void iterate_comma_separated_quoted_string (std::string str, const std::function< bool(const std::string)> &f)
 Iterate a string by comma separation and apply a function on each chunk separated by the commas. More...
 
std::pair< std::string, std::string > get_authid_from_quoted_string (std::string str)
 Return the unquoted authorization id as a user,host-tuple. More...
 
bool operator== (const std::pair< Role_id, bool > &rid, const Auth_id_ref &ref)
 
bool operator== (const Auth_id_ref &ref, const std::pair< Role_id, bool > &rid)
 
void get_privilege_access_maps (ACL_USER *acl_user, const List_of_auth_id_refs *using_roles, ulong *access, Db_access_map *db_map, Db_access_map *db_wild_map, Table_access_map *table_map, SP_access_map *sp_map, SP_access_map *func_map, List_of_granted_roles *granted_roles, Grant_acl_set *with_admin_acl, Dynamic_privileges *dynamic_acl, Restrictions &restrictions)
 
bool mysql_show_grants (THD *thd, LEX_USER *lex_user, const List_of_auth_id_refs &using_roles, bool show_mandatory_roles, bool have_using_clause)
 SHOW GRANTS FOR user USING [ALL | role [,role ...]]. More...
 
void roles_graphml (THD *thd, String *str)
 
static int remove_db_access_privileges (THD *thd, TABLE *table, const LEX_USER &lex_user)
 Remove db access privileges. More...
 
static int remove_column_access_privileges (THD *thd, TABLE *tables_priv_table, TABLE *columns_priv_table, const LEX_USER &lex_user)
 Remove column access privileges. More...
 
static int remove_procedure_access_privileges (THD *thd, TABLE *procs_priv_table, const LEX_USER &lex_user)
 Remove procedure access privileges. More...
 
bool mysql_revoke_all (THD *thd, List< LEX_USER > &list)
 
bool sp_revoke_privileges (THD *thd, const char *sp_db, const char *sp_name, bool is_proc)
 Revoke privileges for all users on a stored procedure. More...
 
bool sp_grant_privileges (THD *thd, const char *sp_db, const char *sp_name, bool is_proc)
 Grant EXECUTE,ALTER privilege for a stored procedure. More...
 
static bool update_schema_privilege (THD *thd, TABLE *table, char *buff, const char *db, const char *t_name, const char *column, size_t col_length, const char *priv, size_t priv_length, const char *is_grantable)
 
void fill_effective_table_privileges (THD *thd, GRANT_INFO *grant, const char *db, const char *table)
 
bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user, bool with_grant)
 
int fill_schema_user_privileges (THD *thd, Table_ref *tables, Item *)
 
int fill_schema_schema_privileges (THD *thd, Table_ref *tables, Item *)
 
int fill_schema_table_privileges (THD *thd, Table_ref *tables, Item *)
 
int fill_schema_column_privileges (THD *thd, Table_ref *tables, Item *)
 
bool is_privileged_user_for_credential_change (THD *thd)
 
bool check_global_access (THD *thd, ulong want_access)
 check for global access and give descriptive error message if it fails. More...
 
bool check_fk_parent_table_access (THD *thd, HA_CREATE_INFO *create_info, Alter_info *alter_info)
 Checks foreign key's parent table access. More...
 
bool check_lock_view_underlying_table_access (THD *thd, Table_ref *tbl, bool *fake_lock_tables_acl)
 For LOCK TABLES on a view checks if user in which context view is executed or user that has initiated this operation has SELECT and LOCK TABLES privileges on one of its underlying tables. More...
 
bool check_if_granted_role (LEX_CSTRING user, LEX_CSTRING host, LEX_CSTRING role, LEX_CSTRING role_host)
 Examines if a user@host authid is connected to a role@role_host authid by comparing all out-edges if the user@host vertex in the global role graph. More...
 
bool find_if_granted_role (Role_vertex_descriptor v, LEX_CSTRING role, LEX_CSTRING role_host, Role_vertex_descriptor *found_vertex)
 Given a vertex in the roles graph, this function finds a directly connected vertex given a (role, role_host) tuple. More...
 
void get_granted_roles (Role_vertex_descriptor &v, std::function< void(const Role_id &, bool)> f)
 
void activate_all_granted_roles (const ACL_USER *acl_user, Security_context *sctx)
 Activates all roles granted to the auth_id. More...
 
void activate_all_mandatory_roles (Security_context *sctx)
 Activates all the mandatory roles for the current user. More...
 
void activate_all_granted_and_mandatory_roles (const ACL_USER *acl_user, Security_context *sctx)
 
void get_granted_roles (LEX_USER *user, List_of_granted_roles *granted_roles)
 This is a convenience function. More...
 
void get_active_roles (const THD *thd, List_of_granted_roles *roles)
 Helper function for func_current_role used for Item_func_current_role. More...
 
void func_current_role (const THD *thd, String *active_role)
 Helper function for Item_func_current_role. More...
 
void get_default_roles (const Auth_id_ref &acl_user, List_of_auth_id_refs &authlist)
 Shallow copy a list of default role authorization IDs from an Role_id storage. More...
 
bool lock_and_get_mandatory_roles (std::vector< Role_id > *mandatory_roles)
 Copy a list of mandatory role authorization IDs. More...
 
bool clear_default_roles (THD *thd, TABLE *table, const Auth_id_ref &user_auth_id, std::vector< Role_id > *default_roles)
 Removes all default role policies assigned to user. More...
 
bool drop_default_role_policy (THD *thd, TABLE *table, const Auth_id_ref &default_role_policy, const Auth_id_ref &user)
 Drop a specific default role policy given the role- and user names. More...
 
bool mysql_alter_or_clear_default_roles (THD *thd, role_enum role_type, const List< LEX_USER > *users, const List< LEX_USER > *roles)
 Set the default roles to NONE, ALL or list of authorization IDs as roles, depending upon the role_type argument. More...
 
bool alter_user_set_default_roles_all (THD *thd, TABLE *def_role_table, LEX_USER *user)
 Set all granted role as default roles. More...
 
bool alter_user_set_default_roles (THD *thd, TABLE *table, LEX_USER *user, const List_of_auth_id_refs &new_auth_ids)
 Set the default roles for a particular user. More...
 
std::string create_authid_str_from (const LEX_USER *user)
 Helper used for producing a key to a key-value-map. More...
 
Auth_id_ref create_authid_from (const LEX_USER *user)
 
Auth_id_ref create_authid_from (const Role_id &user)
 
Auth_id_ref create_authid_from (const LEX_CSTRING &user, const LEX_CSTRING &host)
 
std::string create_authid_str_from (const ACL_USER *user)
 Helper used for producing a key to a key-value-map. More...
 
std::string create_authid_str_from (const Auth_id_ref &user)
 
Auth_id_ref create_authid_from (const ACL_USER *user)
 
bool mysql_set_active_role_none (THD *thd)
 Reset active roles. More...
 
bool mysql_set_role_default (THD *thd)
 Activates all the default roles in the current security context. More...
 
bool mysql_set_active_role_all (THD *thd, const List< LEX_USER > *except_users)
 Activates all granted role in the current security context. More...
 
bool mysql_set_active_role (THD *thd, const List< LEX_USER > *role_list)
 
bool is_granted_role (LEX_CSTRING user, LEX_CSTRING host, LEX_CSTRING role, LEX_CSTRING role_host)
 This function works just like check_if_granted_role, but also guarantees that the proper lock is taken so that the function can be used in a wider context. More...
 
bool is_mandatory_role (LEX_CSTRING role, LEX_CSTRING role_host, bool *is_mandatory)
 Determine if a role@role_host authid is a mandatory role. More...
 
bool grant_dynamic_privilege (const LEX_CSTRING &str_priv, const LEX_CSTRING &str_user, const LEX_CSTRING &str_host, bool with_grant_option, Update_dynamic_privilege_table &update_table)
 Grant one privilege to one user. More...
 
bool grant_grant_option_for_all_dynamic_privileges (const LEX_CSTRING &str_user, const LEX_CSTRING &str_host, Update_dynamic_privilege_table &update_table)
 Grant grant option to one user for all dynamic privileges. More...
 
bool revoke_grant_option_for_all_dynamic_privileges (const LEX_CSTRING &str_user, const LEX_CSTRING &str_host, Update_dynamic_privilege_table &update_table)
 Revoke grant option to one user for all dynamic privileges. More...
 
bool grant_dynamic_privileges_to_auth_id (const Role_id &id, const std::vector< std::string > &priv_list)
 Grant needed dynamic privielges to in memory internal auth id. More...
 
void revoke_dynamic_privileges_from_auth_id (const Role_id &id, const std::vector< std::string > &priv_list)
 Revoke dynamic privielges from in memory internal auth id. More...
 
bool revoke_dynamic_privilege (const LEX_CSTRING &str_priv, const LEX_CSTRING &str_user, const LEX_CSTRING &str_host, Update_dynamic_privilege_table &update_table)
 Revoke one privilege from one user. More...
 
bool revoke_all_dynamic_privileges (const LEX_CSTRING &user, const LEX_CSTRING &host, Update_dynamic_privilege_table &update_table)
 Revoke all dynamic global privileges. More...
 
bool rename_dynamic_grant (const LEX_CSTRING &old_user, const LEX_CSTRING &old_host, const LEX_CSTRING &new_user, const LEX_CSTRING &new_host, Update_dynamic_privilege_table &update_table)
 
void default_roles_init ()
 Initialize the default role map that keeps the content from the default_roles table. More...
 
void default_roles_delete ()
 Delete the default role instance. More...
 
void roles_graph_init ()
 Initialize the roles graph artifacts. More...
 
void roles_graph_delete ()
 Delete the ACL role graph artifacts. More...
 
void roles_init ()
 Initialize the roles caches that consist of the role graphs related artifacts and default role map. More...
 
void roles_delete ()
 Delete the role caches. More...
 
void dynamic_privileges_init ()
 
void dynamic_privileges_delete ()
 
User_to_dynamic_privileges_mapget_dynamic_privileges_map ()
 
void set_dynamic_privileges_map (User_to_dynamic_privileges_map *map)
 
User_to_dynamic_privileges_mapswap_dynamic_privileges_map (User_to_dynamic_privileges_map *map)
 
bool assert_valid_privilege_id (const List< LEX_USER > *priv_list)
 
bool check_authorization_id_string (THD *thd, LEX_STRING &mandatory_roles)
 
void get_mandatory_roles (std::vector< Role_id > *mandatory_roles)
 
void update_mandatory_roles (void)
 
bool operator== (const Role_id &a, const Auth_id_ref &b)
 
bool operator== (const Auth_id_ref &a, const Role_id &b)
 
bool operator== (const std::pair< const Role_id, Role_id > &a, const Auth_id_ref &b)
 
bool operator== (const Role_id &a, const Role_id &b)
 
bool operator< (const Auth_id_ref &a, const Auth_id_ref &b)
 
bool operator== (std::pair< const Role_id, std::pair< std::string, bool > > &a, const std::string &b)
 
bool operator== (const LEX_CSTRING &a, const LEX_CSTRING &b)
 
bool do_update_sctx (Security_context *sctx, LEX_USER *from_user_ptr)
 Checks if current user needs to be changed in case it is same as the LEX_USER. More...
 
void update_sctx (Security_context *sctx, LEX_USER *to_user_ptr)
 
bool check_system_user_privilege (THD *thd, List< LEX_USER > list)
 Checks if any of the users has SYSTEM_USER privilege then current user must also have SYSTEM_USER privilege. More...
 
bool check_valid_definer (THD *thd, LEX_USER *definer)
 Check if the definer is a valid one. More...
 

Variables

Granted_roles_graphg_granted_roles = nullptr
 
Role_index_mapg_authid_to_vertex = nullptr
 
static char g_active_dummy_user [] = "active dummy user"
 
bool initialized
 
Default_rolesg_default_roles
 
User_to_dynamic_privileges_mapg_dynamic_privileges_map = nullptr
 
const char * any_db = "*any*"
 
static const int GRANTEE_MAX_BUFF_LENGTH
 Grantee is of form 'user'@'hostname', so add +1 for '@' and +4 for the single quotes. More...
 

Detailed Description

AUTHORIZATION CODE.

Typedef Documentation

◆ Role_adjacency_iterator

typedef boost::graph_traits<Granted_roles_graph>::adjacency_iterator Role_adjacency_iterator

Function Documentation

◆ acl_check_proxy_grant_access()

bool acl_check_proxy_grant_access ( THD thd,
const char *  host,
const char *  user,
bool  with_grant 
)

◆ activate_all_granted_and_mandatory_roles()

void activate_all_granted_and_mandatory_roles ( const ACL_USER acl_user,
Security_context sctx 
)

◆ activate_all_granted_roles()

void activate_all_granted_roles ( const ACL_USER acl_user,
Security_context sctx 
)

Activates all roles granted to the auth_id.

Parameters
[in]acl_userACL_USER for which all granted roles to be activated.
[in]sctxPush the activated role to security context

◆ activate_all_mandatory_roles()

void activate_all_mandatory_roles ( Security_context sctx)

Activates all the mandatory roles for the current user.

Parameters
[in]sctxPush the activated role to security context

◆ alter_user_set_default_roles()

bool alter_user_set_default_roles ( THD thd,
TABLE table,
LEX_USER user,
const List_of_auth_id_refs new_auth_ids 
)

Set the default roles for a particular user.

Parameters
thdThread handle
tableTable handle to an open table
userAST component for the user for which we set def roles
new_auth_idsDefault roles to set
Return values
trueOperation failed
falseOperation was successful.

◆ alter_user_set_default_roles_all()

bool alter_user_set_default_roles_all ( THD thd,
TABLE def_role_table,
LEX_USER user 
)

Set all granted role as default roles.

Writes to table mysql.default_roles and binlog.

Parameters
thdThread handler
def_role_tableDefault role table
userThe user whose default roles are set.
Return values
trueAn error occurred and DA is set
falseSuccessful

◆ assert_valid_privilege_id()

bool assert_valid_privilege_id ( const List< LEX_USER > *  priv_list)

◆ check_access()

bool check_access ( THD thd,
ulong  want_access,
const char *  db,
ulong *  save_priv,
GRANT_INTERNAL_INFO grant_internal_info,
bool  dont_check_global_grants,
bool  no_errors 
)

Compare requested privileges with the privileges acquired from the User- and Db-tables.

Parameters
thdThread handler
want_accessThe requested access privileges.
dbA pointer to the Db name.
[out]save_privA pointer to the granted privileges will be stored.
grant_internal_infoA pointer to the internal grant cache.
dont_check_global_grantsTrue if no global grants are checked.
no_errorsTrue if no errors should be sent to the client.

'save_priv' is used to save the User-table (global) and Db-table grants for the supplied db name. Note that we don't store db level grants if the global grants is enough to satisfy the request AND the global grants contains a SELECT grant.

For internal databases (INFORMATION_SCHEMA, PERFORMANCE_SCHEMA), additional rules apply, see ACL_internal_schema_access.

See also
check_grant
Returns
Status of denial of access by exclusive ACLs.
Return values
falseAccess can't exclusively be denied by Db- and User-table access unless Column- and Table-grants are checked too.
trueAccess denied. The DA is set if no_error = false!

◆ check_authorization_id_string()

bool check_authorization_id_string ( THD thd,
LEX_STRING mandatory_roles 
)

◆ check_column_grant_in_table_ref()

bool check_column_grant_in_table_ref ( THD thd,
Table_ref table_ref,
const char *  name,
size_t  length,
ulong  want_privilege 
)

Check the privileges for a column depending on the type of table.

Parameters
thdthread handler
table_reftable reference where to check the field
namename of field to check
lengthlength of name
want_privilegewanted privileges

Check the privileges for a column depending on the type of table the column belongs to. The function provides a generic interface to check column privileges that hides the heterogeneity of the column representation - whether it belongs to a view or a base table.

Notice that this function does not understand that a column from a view reference must be checked for privileges both in the view and in the underlying base table (or view) reference. This is the responsibility of the caller.

Columns from temporary tables and derived tables are ignored by this function.

Returns
false if success, true if error (access denied)

◆ check_fk_parent_table_access()

bool check_fk_parent_table_access ( THD thd,
HA_CREATE_INFO create_info,
Alter_info alter_info 
)

Checks foreign key's parent table access.

Parameters
[in]thdThread handler
[in]create_infoCreate information (like MAX_ROWS, ENGINE or temporary table flag)
[in]alter_infoInitial list of columns and indexes for the table to be created
Return values
falseok.
trueerror or access denied. Error is sent to client in this case.

◆ check_global_access()

bool check_global_access ( THD thd,
ulong  want_access 
)

check for global access and give descriptive error message if it fails.

Parameters
thdThread handler
want_accessUse should have any of these global rights
Warning
One gets access right if one has ANY of the rights in want_access. This is useful as one in most cases only need one global right, but in some case we want to check if the user has SUPER or REPL_CLIENT_ACL rights.
Return values
0ok
1Access denied. In this case an error is sent to the client

◆ check_grant()

bool check_grant ( THD thd,
ulong  want_access,
Table_ref tables,
bool  any_combination_will_do,
uint  number,
bool  no_errors 
)

Check table level grants.

Parameters
thdThread handler
want_accessBits of privileges user needs to have.
tablesList of tables to check. The user should have 'want_access' to all tables in list.
any_combination_will_dotrue if it's enough to have any privilege for any combination of the table columns.
numberCheck at most this number of tables.
no_errorstrue if no error should be sent directly to the client.

If table->grant.want_privilege != 0 then the requested privileges where in the set of COL_ACLS but access was not granted on the table level. As a consequence an extra check of column privileges is required.

Specifically if this function returns false the user has some kind of privilege on a combination of columns in each table.

This function is usually preceded by check_access which establish the User-, Db- and Host access rights.

See also
check_access
check_table_access
Note
This functions assumes that either number of tables to be inspected by it is limited explicitly (i.e. is is not UINT_MAX) or table list used and thd->lex->query_tables_own_last value correspond to each other (the latter should be either 0 or point to next_global member of one of elements of this table list).
Returns
Access status
Return values
falseAccess granted; But column privileges need to be checked.
trueThe user did not have the requested privileges on any of the tables.

◆ check_grant_all_columns()

bool check_grant_all_columns ( THD thd,
ulong  want_access_arg,
Field_iterator_table_ref fields 
)

check if a query can access a set of columns

Parameters
thdthe current thread
want_access_argthe privileges requested
fieldsan iterator over the fields of a table reference.
Returns
Operation status
Return values
0Success
1Failure

This function walks over the columns of a table reference The columns may originate from different tables, depending on the kind of table reference, e.g. join, view. For each table it will retrieve the grant information and will use it to check the required access privileges for the fields requested from it.

◆ check_grant_column()

bool check_grant_column ( THD thd,
GRANT_INFO grant,
const char *  db_name,
const char *  table_name,
const char *  name,
size_t  length,
Security_context sctx,
ulong  want_privilege 
)

◆ check_grant_db()

bool check_grant_db ( THD thd,
const char *  db,
const bool  check_table_grant 
)

Check if a user has the right to access a database.

Access is accepted if the user has a database operations related grant (i.e. not including the GRANT_ACL) for any table/column/routine in the database.

Parameters
thdThe thread handler
dbThe name of the database
check_table_grantfalse by default, Access is granted for "show databases" and "show tables in database" when user has table level grant.
Return values
1Access is denied
0Otherwise

◆ check_grant_db_routine()

static bool check_grant_db_routine ( THD thd,
const char *  db,
malloc_unordered_multimap< std::string, unique_ptr_destroy_only< GRANT_NAME > > *  hash 
)
static

◆ check_grant_routine()

bool check_grant_routine ( THD thd,
ulong  want_access,
Table_ref procs,
bool  is_proc,
bool  no_errors 
)

◆ check_if_granted_role()

bool check_if_granted_role ( LEX_CSTRING  user,
LEX_CSTRING  host,
LEX_CSTRING  role,
LEX_CSTRING  role_host 
)

Examines if a user@host authid is connected to a role@role_host authid by comparing all out-edges if the user@host vertex in the global role graph.

Return values
truethe two vertices are connected (role is granted)
falsenot connected (role is not granted)

◆ check_if_granted_role_recursive()

static bool check_if_granted_role_recursive ( LEX_CSTRING  start,
LEX_CSTRING  start_host,
LEX_CSTRING  search_for,
LEX_CSTRING  search_for_host 
)
static

Search if an auth_id (search_for@search_for_host) is granted either directly or indirectly to an auth_id (start@start_host) or to one of the mandatory roles.

Searched if search_for@search_for_host is a direct or indirect descendant of start@start_host or to one of the mandatory roles

Parameters
startthe user name to check
start_hostthe host name to check
search_forthe user name of auth_id to look for
search_for_hostthe host name of the auth_id to look for
Return values
truesearch_for@search_for_host is granted directly or indirectly to start@start_host
falsethe two auth ids are not related

◆ check_lock_view_underlying_table_access()

bool check_lock_view_underlying_table_access ( THD thd,
Table_ref tbl,
bool *  fake_lock_tables_acl 
)

For LOCK TABLES on a view checks if user in which context view is executed or user that has initiated this operation has SELECT and LOCK TABLES privileges on one of its underlying tables.

Parameters
[in]thdThread context.
[in]tblTable list element for underlying table on which we check privilege.
[out]fake_lock_tables_aclSet to true if table in question is one of special I_S or P_S tables on which nobody can get LOCK TABLES privilege. So to preserve compatibility with dump tools we need to fake this privilege. Set to false otherwise.
Return values
falseSuccess.
trueAccess denied. Error has been reported.

◆ check_one_table_access()

bool check_one_table_access ( THD thd,
ulong  privilege,
Table_ref all_tables 
)

Check grants for commands which work only with one table and all other tables belonging to subselects or implicitly opened tables.

Parameters
thdThread handler
privilegerequested privilege
all_tablesglobal table list of query
Returns
false on success, true on access denied error

◆ check_readonly()

bool check_readonly ( THD thd,
bool  err_if_readonly 
)

Performs standardized check whether to prohibit (true) or allow (false) operations based on read_only and super_read_only state.

Parameters
thdThread handler
err_if_readonlyBoolean indicating whether or not to add the error to the thread context if read-only is violated.
Returns
Status code
Return values
trueThe operation should be prohibited. @ retval false The operation should be allowed.

◆ check_routine_access()

bool check_routine_access ( THD thd,
ulong  want_access,
const char *  db,
char *  name,
bool  is_proc,
bool  no_errors 
)

◆ check_routine_level_acl()

static bool check_routine_level_acl ( THD thd,
const char *  db,
const char *  name,
bool  is_proc 
)
static

◆ check_single_table_access()

bool check_single_table_access ( THD thd,
ulong  privilege,
Table_ref all_tables,
bool  no_errors 
)

Check grants for commands which work only with one table.

Parameters
thdThread handler
privilegerequested privilege
all_tablesglobal table list of query
no_errorsfalse/true - report/don't report error to the client (using my_error() call).
Return values
0OK
1access denied, error is sent to client

◆ check_some_access()

bool check_some_access ( THD thd,
ulong  want_access,
Table_ref table 
)

Check if the given table has any of the asked privileges.

Parameters
thdThread handler
want_accessBitmap of possible privileges to check for
tableThe table for which access needs to be validated
Return values
0ok
1error

◆ check_system_user_privilege()

bool check_system_user_privilege ( THD thd,
List< LEX_USER list 
)

Checks if any of the users has SYSTEM_USER privilege then current user must also have SYSTEM_USER privilege.

It is a wrapper over the Privilege_checker class that does privilege checks for one user at a time.

Parameters
[in]thdThread handle for security context
[in]listList of user being processed
Returns
If needed, whether current user has SYSTEM_USER privilege or not
Return values
falseEither none of the users in list has SYSTEM_USER privilege or current user has SYSTEM_USER privilege
trueFailed in get_current_user() OR one of the user in the list has SYSTEM_USER privilege but current user does not.

◆ check_table_access()

bool check_table_access ( THD thd,
ulong  requirements,
Table_ref tables,
bool  any_combination_of_privileges_will_do,
uint  number,
bool  no_errors 
)

Check if the requested privileges exists in either User-, DB- or, tables- tables.

Parameters
thdThread context
requirementsPrivileges requested
tablesList of tables to be compared against
no_errorsDon't report error to the client (using my_error() call).
any_combination_of_privileges_will_dotrue if any privileges on any column combination is enough.
numberOnly the first 'number' tables in the linked list are relevant.

The supplied table list contains cached privileges. This functions calls the help functions check_access and check_grant to verify the first three steps in the privileges check queue:

  1. Global privileges
  2. OR (db privileges AND host privileges)
  3. OR table privileges
  4. OR column privileges (not checked by this function!)
  5. OR routine privileges (not checked by this function!)
See also
check_access
check_grant
Note
This functions assumes that table list used and thd->lex->query_tables_own_last value correspond to each other (the latter should be either 0 or point to next_global member of one of elements of this table list).
Return values
falseOK
trueAccess denied; But column or routine privileges might need to be checked also.

◆ check_table_encryption_admin_access()

bool check_table_encryption_admin_access ( THD thd)

Check if a current user has the privilege TABLE_ENCRYPTION_ADMIN required to create encrypted table.

We skip the same for slave threads.

Parameters
thdCurrent thread
Return values
falseA user has the privilege TABLE_ENCRYPTION_ADMIN
trueA user doesn't have the privilege TABLE_ENCRYPTION_ADMIN

◆ check_valid_definer()

bool check_valid_definer ( THD thd,
LEX_USER definer 
)

Check if the definer is a valid one.

if the definer is different to the current session account, make sure it's OK to use it:

  • check for the right privs: SUPER, SET_USER_ID or SET_ANY_DEFINER
  • whether it doesn't violate system user

if it's not OK, generate an error.

Also checks if the user@host is a non-existent user account and if it is throws an error and returns true, given that SUPER, SET_USER_ID or ALLOW_NONEXISTENT_DEFINER are not granted. If the privs arent granted a warning is produced instead of an error.

Parameters
thdthe session
definerthe definer to check
Return values
false: success
true: failure

◆ clear_default_roles()

bool clear_default_roles ( THD thd,
TABLE table,
const Auth_id_ref user_auth_id,
std::vector< Role_id > *  default_roles 
)

Removes all default role policies assigned to user.

If the user is used as a default role policy, this policy needs to be removed too. Removed policies are copied to the vector supplied in the arguments.

Parameters
thdThread handler
tableOpen table handler
user_auth_idA reference to the authorization ID to clear
[out]default_rolesThe vector to which the removed roles are copied.
Return values
trueAn error occurred.
falseSuccess

◆ create_authid_from() [1/4]

Auth_id_ref create_authid_from ( const ACL_USER user)

◆ create_authid_from() [2/4]

Auth_id_ref create_authid_from ( const LEX_CSTRING user,
const LEX_CSTRING host 
)

◆ create_authid_from() [3/4]

Auth_id_ref create_authid_from ( const LEX_USER user)

◆ create_authid_from() [4/4]

Auth_id_ref create_authid_from ( const Role_id user)

◆ create_authid_str_from() [1/3]

std::string create_authid_str_from ( const ACL_USER user)

Helper used for producing a key to a key-value-map.

◆ create_authid_str_from() [2/3]

std::string create_authid_str_from ( const Auth_id_ref user)

◆ create_authid_str_from() [3/3]

std::string create_authid_str_from ( const LEX_USER user)

Helper used for producing a key to a key-value-map.

◆ create_role_vertex()

void create_role_vertex ( ACL_USER role_acl_user)

Helper function for create_roles_vertices.

Creates a vertex in the role graph and associate it with an ACL_USER. If the ACL_USER already exists in the vertex-to-acl-user index then we ignore this request.

Parameters
role_acl_userThe acial user to be mapped to a vertex.

◆ create_table_precheck()

bool create_table_precheck ( THD thd,
Table_ref tables,
Table_ref create_table 
)

CREATE TABLE query pre-check.

Parameters
thdThread handler
tablesGlobal table list
create_tableTable which will be created
Return values
falseOK
trueError

◆ default_roles_delete()

void default_roles_delete ( void  )

Delete the default role instance.

◆ default_roles_init()

void default_roles_init ( void  )

Initialize the default role map that keeps the content from the default_roles table.

◆ do_update_sctx()

bool do_update_sctx ( Security_context sctx,
LEX_USER from_user_ptr 
)

Checks if current user needs to be changed in case it is same as the LEX_USER.

This check is useful to take backup of security context in case current user renames itself.

Parameters
sctxThe security context to check
from_user_ptrUser name to be renamed
Return values
truesecurity context need to be updated
falseotherwise

◆ drop_default_role_policy()

bool drop_default_role_policy ( THD thd,
TABLE table,
const Auth_id_ref default_role_policy,
const Auth_id_ref user 
)

Drop a specific default role policy given the role- and user names.

Parameters
thdThread handler
tableAn open table handler to the default_roles table
default_role_policyThe role name
userThe user name
Return values
Errorstate
trueAn error occurred
falseSuccess

◆ drop_role()

bool drop_role ( THD thd,
TABLE edge_table,
TABLE defaults_table,
const Auth_id_ref authid_user 
)

◆ dynamic_privileges_delete()

void dynamic_privileges_delete ( void  )

◆ dynamic_privileges_init()

void dynamic_privileges_init ( void  )

◆ err_readonly()

void err_readonly ( THD thd)

Generates appropriate error messages for read-only state depending on whether user has SUPER privilege or not.

Parameters
thdThread handler

◆ fill_effective_table_privileges()

void fill_effective_table_privileges ( THD thd,
GRANT_INFO grant,
const char *  db,
const char *  table 
)

◆ fill_schema_column_privileges()

int fill_schema_column_privileges ( THD thd,
Table_ref tables,
Item cond 
)

◆ fill_schema_schema_privileges()

int fill_schema_schema_privileges ( THD thd,
Table_ref tables,
Item cond 
)

◆ fill_schema_table_privileges()

int fill_schema_table_privileges ( THD thd,
Table_ref tables,
Item cond 
)

◆ fill_schema_user_privileges()

int fill_schema_user_privileges ( THD thd,
Table_ref tables,
Item cond 
)

◆ find_if_granted_role()

bool find_if_granted_role ( Role_vertex_descriptor  v,
LEX_CSTRING  role,
LEX_CSTRING  role_host,
Role_vertex_descriptor found_vertex 
)

Given a vertex in the roles graph, this function finds a directly connected vertex given a (role, role_host) tuple.

The resulting vertex is returned to the caller through an out-param.

Parameters
vVertex descriptor of the authid which might have a granted role
roleUser name part of an authid
role_hostHost name part of an authid
[out]found_vertexThe corresponding vertex of the granted role.
Returns
Success state
Return values
trueThe role is granted and the corresponding vertex is returned.
falseNo such role is granted.

◆ func_current_role()

void func_current_role ( const THD thd,
String active_role 
)

Helper function for Item_func_current_role.

Parameters
thdThread handler
active_role[out] Comma separated list of auth ids

◆ get_active_roles()

void get_active_roles ( const THD thd,
List_of_granted_roles roles 
)

Helper function for func_current_role used for Item_func_current_role.

Parameters
thdThe thread handler
roles[out] A list of Role_id granted to the current user.

◆ get_authid_from_quoted_string()

std::pair< std::string, std::string > get_authid_from_quoted_string ( std::string  str)

Return the unquoted authorization id as a user,host-tuple.

Parameters
strThe quoted or unquoted string representation of an authid
Returns
The unquoted authorization id as a user,host-tuple

◆ get_cached_schema_access()

const ACL_internal_schema_access * get_cached_schema_access ( GRANT_INTERNAL_INFO grant_internal_info,
const char *  schema_name 
)

Get a cached internal schema access.

Parameters
grant_internal_infothe cache
schema_namethe name of the internal schema

◆ get_cached_table_access()

const ACL_internal_table_access * get_cached_table_access ( GRANT_INTERNAL_INFO grant_internal_info,
const char *  schema_name,
const char *  table_name 
)

Get a cached internal table access.

Parameters
grant_internal_infothe cache
schema_namethe name of the internal schema
table_namethe name of the internal table

◆ get_column_grant()

ulong get_column_grant ( THD thd,
GRANT_INFO grant,
const char *  db_name,
const char *  table_name,
const char *  field_name 
)

◆ get_database_access_map()

void get_database_access_map ( ACL_USER acl_user,
Db_access_map db_map,
Db_access_map db_wild_map 
)

◆ get_default_roles()

void get_default_roles ( const Auth_id_ref acl_user,
List_of_auth_id_refs authlist 
)

Shallow copy a list of default role authorization IDs from an Role_id storage.

Parameters
acl_userA valid authID for which we want the default roles.
[out]authlistThe target list to be populated. The target list is set to empty if no default role is found.

◆ get_dynamic_privileges()

void get_dynamic_privileges ( ACL_USER acl_user,
Dynamic_privileges acl 
)

◆ get_dynamic_privileges_map()

User_to_dynamic_privileges_map * get_dynamic_privileges_map ( )

◆ get_granted_roles() [1/3]

void get_granted_roles ( LEX_USER user,
List_of_granted_roles granted_roles 
)

This is a convenience function.

See also
get_granted_roles(Role_vertex_descriptor &v, List_of_granted_roles *granted_roles)
Parameters
userThe authid to check for granted roles
[out]granted_rolesA list of granted authids

◆ get_granted_roles() [2/3]

void get_granted_roles ( Role_vertex_descriptor v,
List_of_granted_roles granted_roles 
)

Populates a list of authorization IDs that are connected to a specified graph vertex in the global roles graph.

The constructed list contains references to a shared memory. The authIDs are not copied!

The list of granted roles is /appended/ to the out variable.

Parameters
vA valid vertex descriptor from the global roles graph
[out]granted_rolesA list of authorization IDs

◆ get_granted_roles() [3/3]

void get_granted_roles ( Role_vertex_descriptor v,
std::function< void(const Role_id &, bool)>  f 
)

◆ get_mandatory_roles()

void get_mandatory_roles ( std::vector< Role_id > *  mandatory_roles)

◆ get_privilege_access_maps()

void get_privilege_access_maps ( ACL_USER acl_user,
const List_of_auth_id_refs using_roles,
ulong *  access,
Db_access_map db_map,
Db_access_map db_wild_map,
Table_access_map table_map,
SP_access_map sp_map,
SP_access_map func_map,
List_of_granted_roles granted_roles,
Grant_acl_set with_admin_acl,
Dynamic_privileges dynamic_acl,
Restrictions restrictions 
)

◆ get_privilege_desc()

void get_privilege_desc ( char *  to,
uint  max_length,
ulong  access 
)

◆ get_sp_access_map()

void get_sp_access_map ( ACL_USER acl_user,
SP_access_map sp_map,
malloc_unordered_multimap< std::string, unique_ptr_destroy_only< GRANT_NAME > > *  hash 
)

◆ get_table_access_map()

void get_table_access_map ( ACL_USER acl_user,
Table_access_map table_map 
)

◆ get_table_grant()

ulong get_table_grant ( THD thd,
Table_ref table 
)

◆ grant_dynamic_privilege()

bool grant_dynamic_privilege ( const LEX_CSTRING str_priv,
const LEX_CSTRING str_user,
const LEX_CSTRING str_host,
bool  with_grant_option,
Update_dynamic_privilege_table update_table 
)

Grant one privilege to one user.

Parameters
str_privDynamic privilege being granted
str_userUsername part of the grantee
str_hostHostname part of the grantee
with_grant_optionFlag that determines if grantee can manage the dynamic privilege
update_tableTable update handler
Returns
Error state
Return values
trueAn error occurred. DA must be checked.
falseSuccess

◆ grant_dynamic_privileges_to_auth_id()

bool grant_dynamic_privileges_to_auth_id ( const Role_id id,
const std::vector< std::string > &  priv_list 
)

Grant needed dynamic privielges to in memory internal auth id.

Parameters
idauth id to which privileges needs to be granted
priv_listList of privileges to be added to internal auth id
Return values
TrueIn case privilege is not registered
FalseSuccess

◆ grant_grant_option_for_all_dynamic_privileges()

bool grant_grant_option_for_all_dynamic_privileges ( const LEX_CSTRING str_user,
const LEX_CSTRING str_host,
Update_dynamic_privilege_table update_table 
)

Grant grant option to one user for all dynamic privileges.

Parameters
str_userUsername part of the grantee
str_hostHostname part of the grantee
update_tableTable update handler
Returns
Error state
Return values
trueAn error occurred. DA must be checked.
falseSuccess

◆ grant_role()

void grant_role ( ACL_USER role,
const ACL_USER user,
bool  with_admin_opt 
)

Grants a single role to a single user.

The change is made to the in-memory roles graph and not persistent.

See also
mysql_grant_role
Parameters
roleA pointer to the role to be granted
userA pointer to the user which will be granted
with_admin_optTrue if the user should have the ability to pass on the granted role to another authorization id.

◆ has_any_routine_acl()

bool has_any_routine_acl ( Security_context sctx,
const LEX_CSTRING db 
)

◆ has_any_table_acl()

bool has_any_table_acl ( Security_context sctx,
const LEX_CSTRING str 
)

◆ has_dynamic_privilege_grant_option()

bool has_dynamic_privilege_grant_option ( Security_context sctx,
std::string  priv 
)

◆ has_full_view_routine_access()

bool has_full_view_routine_access ( THD thd,
const char *  db,
const char *  definer_user,
const char *  definer_host 
)

Check if user has full access to view routine's properties (i.e including stored routine code).

User must have GLOBAL SELECT or SHOW_ROUTINE privilege, or be the definer of this routine.

Parameters
thdThread handler
dbDatabase name
definer_userDefiner username
definer_hostDefiner host
Return values
falseno full access.
truehas full access.

◆ has_grant_role_privilege()

bool has_grant_role_privilege ( THD thd,
const List< LEX_USER > *  roles 
)

◆ has_partial_view_routine_access()

bool has_partial_view_routine_access ( THD thd,
const char *  db,
const char *  routine_name,
bool  is_proc 
)

Check if user has partial access to view routine's properties (i.e.

excluding stored routine code). User must have EXECUTE/CREATE/ALTER ROUTINE privileges.

Parameters
thdThread handler
dbDatabase name
routine_nameRoutine name
is_procTrue if this routine is a stored procedure, rather than a stored function.
Return values
falseno access.
truehas partial access.

◆ has_wildcard_characters()

bool has_wildcard_characters ( const LEX_CSTRING db)

◆ is_dynamic_privilege_registered()

static bool is_dynamic_privilege_registered ( const std::string &  privilege)
static

The dynamic privilege is probed in the global map that keeps track of dynamic privileges registered with server.

The policy is that

  • Plugin/Component may register a privilege ID
  • Any privilege ID that exist in mysql.global_grants is a valid privilege ID

This method assumes that caller must have acquired the necessory ACL_LOCK.

Parameters
[in]privilegePrivilege to be checked in the dynamic privilege map
Return values
truePrivilege is registered
falseOtherwise

◆ is_granted_role()

bool is_granted_role ( LEX_CSTRING  user,
LEX_CSTRING  host,
LEX_CSTRING  role,
LEX_CSTRING  role_host 
)

This function works just like check_if_granted_role, but also guarantees that the proper lock is taken so that the function can be used in a wider context.

Parameters
userThe user name part of a authid which should be tested
hostThe host name part of a authid which should be tested
roleThe role name part of the role authid
role_hostThe host name part of the role authid
Returns
success value
Return values
trueThe value user@host was previously granted role@role_host
falserole@role_host is not granted to user@host

◆ is_granted_table_access()

bool is_granted_table_access ( THD thd,
ulong  required_acl,
Table_ref table 
)

Given a Table_ref object this function checks against.

  1. global privileges
  2. db privileges
  3. table level privileges

This function only checks the existence of required ACL on a single table object. No special consideration is made for the table type (derived, view, temporary etc).

Parameters
thdThread handle
required_aclThe privileges which are required to continue
tableAn initialized, single Table_ref object
Return values
trueAccess is granted
falseAccess denied

◆ is_mandatory_role()

bool is_mandatory_role ( LEX_CSTRING  role,
LEX_CSTRING  role_host,
bool *  is_mandatory 
)

Determine if a role@role_host authid is a mandatory role.

Parameters
roleRole name.
role_hostHost name of role.
[out]is_mandatoryPointer to boolean hold status of check.
Return values
trueif failed to determine. e.g., ACL lock acquire failed.
falseotherwise.

◆ is_privileged_user_for_credential_change()

bool is_privileged_user_for_credential_change ( THD thd)

◆ is_role_id()

bool is_role_id ( LEX_USER authid)

◆ iterate_comma_separated_quoted_string()

void iterate_comma_separated_quoted_string ( std::string  str,
const std::function< bool(const std::string)> &  f 
)

Iterate a string by comma separation and apply a function on each chunk separated by the commas.

Parameters
strThe string to be iterated
fA function which will receive the comma separated strings.

◆ lock_and_get_mandatory_roles()

bool lock_and_get_mandatory_roles ( std::vector< Role_id > *  mandatory_roles)

Copy a list of mandatory role authorization IDs.

Parameters
[out]mandatory_rolesPointer to the target list to be populated. The target list is set to empty if no mandatory role is found.

◆ lock_tables_precheck()

bool lock_tables_precheck ( THD thd,
Table_ref tables 
)

Check privileges for LOCK TABLES statement.

Parameters
thdThread context.
tablesList of tables to be locked.
Return values
false- Success.
true- Failure.

◆ make_database_privilege_statement()

void make_database_privilege_statement ( THD thd,
ACL_USER role,
Protocol protocol,
const Db_access_map db_map,
const Db_access_map db_wild_map,
const DB_restrictions restrictions 
)

Maps a set of database level ACLs to string representations and sends them through the client protocol.

Parameters
thdThe thread handler
roleThe authid associated with the ACLs
protocolA handler used for sending data to the client
db_mapA list of database level ACLs
db_wild_mapA list of database level ACLs which use pattern matching
restrictionsList of databases on which there exists different restrictions for the ACL_USER.

◆ make_dynamic_privilege_statement()

void make_dynamic_privilege_statement ( THD thd,
ACL_USER role,
Protocol protocol,
const Dynamic_privileges dyn_priv 
)

◆ make_global_privilege_statement()

void make_global_privilege_statement ( THD thd,
ulong  want_access,
ACL_USER acl_user,
String global 
)

Maps a global ACL to a string representation.

Parameters
thdThread handler
want_accessAn ACL
acl_userThe associated user which carries the ACL
[out]globalThe resulting string

◆ make_proxy_privilege_statement()

void make_proxy_privilege_statement ( THD thd,
ACL_USER user,
Protocol protocol 
)

Maps a set of global level proxy ACLs to string representations and sends them through the client protocol.

Parameters
thdThe thread handler
userThe authid associated with the proxy ACLs.
protocolThe handler used for sending data through the client protocol

◆ make_roles_privilege_statement()

void make_roles_privilege_statement ( THD thd,
ACL_USER role,
Protocol protocol,
List_of_granted_roles granted_roles,
bool  show_mandatory_roles 
)

◆ make_sp_privilege_statement()

void make_sp_privilege_statement ( THD thd,
ACL_USER role,
Protocol protocol,
SP_access_map sp_map,
int  type 
)

Maps a set of database level ACLs for stored programs to string representations and sends them through the client protocol.

Parameters
thdA thread handler
roleThe authid associated with the ACLs
protocolThe handler used for sending data through the client protocol
sp_mapThe ACLs granted to role
typeEither 0 for procedures or 1 for functions

◆ make_table_privilege_statement()

void make_table_privilege_statement ( THD thd,
ACL_USER role,
Protocol protocol,
Table_access_map table_map 
)

◆ make_with_admin_privilege_statement()

void make_with_admin_privilege_statement ( THD thd,
ACL_USER acl_user,
Protocol protocol,
const Grant_acl_set with_admin_acl,
const List_of_granted_roles granted_roles 
)

◆ mysql_alter_or_clear_default_roles()

bool mysql_alter_or_clear_default_roles ( THD thd,
role_enum  role_type,
const List< LEX_USER > *  users,
const List< LEX_USER > *  roles 
)

Set the default roles to NONE, ALL or list of authorization IDs as roles, depending upon the role_type argument.

It writes to table mysql.default_roles and binlog.

Parameters
thdThread handler
role_typedefault role type specified by the user.
usersUsers for whom the default roles are set.
roleslist of default roles to be set.
Return values
trueAn error occurred and DA is set
falseSuccessful

◆ mysql_grant()

bool mysql_grant ( THD thd,
const char *  db,
List< LEX_USER > &  list,
ulong  rights,
bool  revoke_grant,
bool  is_proxy,
const List< LEX_CSTRING > &  dynamic_privilege,
bool  grant_all_current_privileges,
LEX_GRANT_AS grant_as 
)

◆ mysql_grant_role()

bool mysql_grant_role ( THD thd,
const List< LEX_USER > *  users,
const List< LEX_USER > *  roles,
bool  with_admin_opt 
)

Grants a list of roles to a list of users.

Changes are persistent and written in the mysql.roles_edges table.

Parameters
thdThread handler
usersA list of authorization IDs
rolesA list of authorization IDs
with_admin_optTrue if the granted users should be able to pass on the roles to other authorization IDs
Returns
Success state
Return values
trueAn error occurred and the DA is set.
falseThe operation was successful and DA is set.

◆ mysql_revoke_all()

bool mysql_revoke_all ( THD thd,
List< LEX_USER > &  list 
)

◆ mysql_revoke_role()

bool mysql_revoke_role ( THD thd,
const List< LEX_USER > *  users,
const List< LEX_USER > *  roles 
)

◆ mysql_routine_grant()

bool mysql_routine_grant ( THD thd,
Table_ref table_list,
bool  is_proc,
List< LEX_USER > &  user_list,
ulong  rights,
bool  revoke_grant,
bool  write_to_binlog,
bool  all_current_privileges 
)

Store routine level grants in the privilege tables.

Parameters
thdThread handle
table_listList of routines to give grant
is_procIs this a list of procedures?
user_listList of users to give grant
rightsTable level grant
revoke_grantIs this is a REVOKE command?
write_to_binlogTrue if this statement should be written to binlog
all_current_privilegesSet to true if this is GRANT/REVOKE ALL
Return values
falseSuccess.
trueAn error occurred.

◆ mysql_set_active_role()

bool mysql_set_active_role ( THD thd,
const List< LEX_USER > *  role_list 
)

◆ mysql_set_active_role_all()

bool mysql_set_active_role_all ( THD thd,
const List< LEX_USER > *  except_users 
)

Activates all granted role in the current security context.

This function acquires the acl_user->lock mutex.

Parameters
thdA valid THD handle
except_usersA pointer to a list of LEX_USER objects which represent roles that shouldn't be activated.
Returns
Error code
Return values
0Success; the specified role was activated.
!=0 Failure. DA is set.

◆ mysql_set_active_role_none()

bool mysql_set_active_role_none ( THD thd)

Reset active roles.

Parameters
[in]thdTHD handle
Returns
status of resetting active roles
Return values
falseSuccess
trueError

◆ mysql_set_role_default()

bool mysql_set_role_default ( THD thd)

Activates all the default roles in the current security context.

This function acquires the Acl_cache_lock_guard in read lock.

Parameters
thdA valid THD handle
Returns
Error code
Return values
0Success; the specified role was activated.
!=0 Failure. DA is set.

◆ mysql_show_grants()

bool mysql_show_grants ( THD thd,
LEX_USER lex_user,
const List_of_auth_id_refs using_roles,
bool  show_mandatory_roles,
bool  have_using_clause 
)

SHOW GRANTS FOR user USING [ALL | role [,role ...]].

Parameters
thdthread handler
lex_userThe user,host descriptor
using_rolesAn forward iterable container of LEX_STRING std::pair
show_mandatory_rolestrue means mandatory roles are listed
have_using_clausetrue means there's a non-empty USING clause specified
Returns
Success status

◆ mysql_table_grant()

int mysql_table_grant ( THD thd,
Table_ref table_list,
List< LEX_USER > &  user_list,
List< LEX_COLUMN > &  columns,
ulong  rights,
bool  revoke_grant,
bool  all_current_privileges 
)

◆ operator<()

bool operator< ( const Auth_id_ref a,
const Auth_id_ref b 
)

◆ operator==() [1/10]

bool operator== ( const Auth_id_ref a,
const Role_id b 
)

◆ operator==() [2/10]

bool operator== ( const Auth_id_ref ref,
const std::pair< Role_id, bool > &  rid 
)

◆ operator==() [3/10]

bool operator== ( const LEX_CSTRING a,
const LEX_CSTRING b 
)

◆ operator==() [4/10]

bool operator== ( const Role_id a,
const Auth_id_ref b 
)

◆ operator==() [5/10]

bool operator== ( const Role_id a,
const Role_id b 
)

◆ operator==() [6/10]

bool operator== ( const Role_id a,
const std::string &  b 
)

◆ operator==() [7/10]

bool operator== ( const std::pair< const Role_id, Role_id > &  a,
const Auth_id_ref b 
)

◆ operator==() [8/10]

bool operator== ( const std::pair< Role_id, bool > &  a,
const std::string &  b 
)

◆ operator==() [9/10]

bool operator== ( const std::pair< Role_id, bool > &  rid,
const Auth_id_ref ref 
)

◆ operator==() [10/10]

bool operator== ( std::pair< const Role_id, std::pair< std::string, bool > > &  a,
const std::string &  b 
)

◆ rebuild_vertex_index()

void rebuild_vertex_index ( THD thd)

Since the gap in the vertex vector was removed all the vertex descriptors has changed.

As a consequence we now need to rebuild the authid_to_vertex index.

◆ remove_column_access_privileges()

static int remove_column_access_privileges ( THD thd,
TABLE tables_priv_table,
TABLE columns_priv_table,
const LEX_USER lex_user 
)
static

Remove column access privileges.

Parameters
thdThread handler.
tables_priv_tablePointer to a TABLE object for opened table mysql.tables_priv_table.
columns_priv_tablePointer to a TABLE object for opened table mysql.columns_priv_table.
lex_userUser information.
Returns
Operation result
Return values
0OK.
1Application error happen, it is allowed continuing of operations.
<0 Engine error.

◆ remove_db_access_privileges()

static int remove_db_access_privileges ( THD thd,
TABLE table,
const LEX_USER lex_user 
)
static

Remove db access privileges.

Parameters
thdCurrent thread execution context.
tablePointer to a TABLE object for opened table mysql.db.
lex_userUser information.
Returns
Operation result
Return values
0OK.
1Application error happen, it is allowed continuing of operations.
<0 Engine error.

◆ remove_procedure_access_privileges()

static int remove_procedure_access_privileges ( THD thd,
TABLE procs_priv_table,
const LEX_USER lex_user 
)
static

Remove procedure access privileges.

Parameters
thdThread handler.
procs_priv_tablePointer to a TABLE object for opened table mysql.procs_priv_table.
lex_userUser information.
Returns
Operation result.
Return values
0OK.
1Application error happen, it is allowed continuing of operations.
<0 Engine error.

◆ rename_dynamic_grant()

bool rename_dynamic_grant ( const LEX_CSTRING old_user,
const LEX_CSTRING old_host,
const LEX_CSTRING new_user,
const LEX_CSTRING new_host,
Update_dynamic_privilege_table update_table 
)

◆ report_missing_user_grant_message()

bool report_missing_user_grant_message ( THD thd,
bool  user_exists,
const char *  user,
const char *  host,
const char *  object_name,
int  err_code 
)

Helper method to check if warning or error should be reported based on:

  1. IF EXISTS clause specified or not
  2. IGNORE UNKNOWN USER clause is specified or not
  3. Privilege being revoked is granted or not.

If user does not exists and IGNORE UNKNOWN USER clause is specified then report a warning. If user exists, privilege being revoked is not granted to specified user and IF EXISTS clause is specified report a warning. In none of the above case report error.

Parameters
thdCurrent thread
user_existsTrue if user exists in memory structure else false
useruser name
hosthost name
object_nameobject name on which privilege is being revoked
err_codeerror code
Return values
falsefor warning.
truefor error.

◆ revoke_all_dynamic_privileges()

bool revoke_all_dynamic_privileges ( const LEX_CSTRING user,
const LEX_CSTRING host,
Update_dynamic_privilege_table update_table 
)

Revoke all dynamic global privileges.

Parameters
userThe target user name
hostThe target host name
update_tableFunctor for updating a table
Returns
Error state
Return values
trueAn error occurred. DA might not be set.
falseSuccess

◆ revoke_all_granted_roles()

bool revoke_all_granted_roles ( THD thd,
TABLE table,
LEX_USER user_from,
List_of_granted_roles granted_roles 
)

If possible, it will revoke all roles and default roles from user_from and set them for user_to instead.

Parameters
thdThread handle
tableA table handler
user_fromThe name of the ACL_USER which will be renamed.
[out]granted_rolesA list of roles that were successfully revoked.
Returns
success state
Return values
trueEn error occurred
falseSuccessful

◆ revoke_all_roles_from_user()

bool revoke_all_roles_from_user ( THD thd,
TABLE edge_table,
TABLE defaults_table,
LEX_USER user_name 
)

Used by mysql_drop_user.

Will drop all

Parameters
thdTHD handle
edge_tableHandle to table that stores role grants
defaults_tableHandle to table that stores default role information
user_nameUser being dropped
Return values
trueAn error occurred
falseSuccess

◆ revoke_dynamic_privilege()

bool revoke_dynamic_privilege ( const LEX_CSTRING str_priv,
const LEX_CSTRING str_user,
const LEX_CSTRING str_host,
Update_dynamic_privilege_table update_table 
)

Revoke one privilege from one user.

Parameters
str_privPrivilege being revoked
str_userUsername part of the grantee
str_hostHostname part of the grantee
update_tableTable update handler
Returns
Error state
Return values
trueAn error occurred. DA must be checked.
falseSuccess

◆ revoke_dynamic_privileges_from_auth_id()

void revoke_dynamic_privileges_from_auth_id ( const Role_id id,
const std::vector< std::string > &  priv_list 
)

Revoke dynamic privielges from in memory internal auth id.

Parameters
idauth id from which privileges needs to be revoked
priv_listList of privileges to be removed for internal auth id

◆ revoke_grant_option_for_all_dynamic_privileges()

bool revoke_grant_option_for_all_dynamic_privileges ( const LEX_CSTRING str_user,
const LEX_CSTRING str_host,
Update_dynamic_privilege_table update_table 
)

Revoke grant option to one user for all dynamic privileges.

Parameters
str_userUsername part of the grantee
str_hostHostname part of the grantee
update_tableTable update handler
Returns
Error state
Return values
trueAn error occurred. DA must be checked.
falseSuccess

◆ revoke_role()

void revoke_role ( THD thd,
ACL_USER role,
ACL_USER user 
)

Used by mysql_revoke_role() for revoking a specified role from a specified user.

Parameters
thdThread handler
roleThe role which will be revoked
userThe user who will get its role revoked

◆ revoke_role_helper()

bool revoke_role_helper ( THD thd,
std::string &  authid_role,
std::string &  authid_user,
Role_vertex_descriptor user_vert,
Role_vertex_descriptor role_vert 
)

This utility function is used by revoke_role() and remove_all_granted_roles() for removing a specific edge from the role graph.

Parameters
thdThread handler
authid_roleThe role which should be revoked
authid_userThe user who will get its role revoked
[out]user_vertThe vertex descriptor of the user
[out]role_vertThe vertex descriptor of the role
Returns
Success state
Return values
trueNo such user
falseUser was removed

◆ roles_delete()

void roles_delete ( void  )

Delete the role caches.

◆ roles_graph_delete()

void roles_graph_delete ( void  )

Delete the ACL role graph artifacts.

◆ roles_graph_init()

void roles_graph_init ( void  )

Initialize the roles graph artifacts.

◆ roles_graphml()

void roles_graphml ( THD thd,
String str 
)

◆ roles_init()

void roles_init ( void  )

Initialize the roles caches that consist of the role graphs related artifacts and default role map.

In theory, default role map is supposed to be a policy which has to be kept in sync with role graphs.

◆ roles_rename_authid()

bool roles_rename_authid ( THD thd,
TABLE edge_table,
TABLE defaults_table,
LEX_USER user_from,
LEX_USER user_to 
)

Renames a user in the mysql.role_edge and the mysql.default_roles tables.

user_to must already exist in the acl_user cache, but user_from may not as long as it exist in the role graph.

Parameters
thdThread handler
edge_tableAn open table handle for mysql.edge_mysql
defaults_tableAn open table handle for mysql.default_roles
user_fromThe user to rename
user_toThe target user name
See also
mysql_rename_user
Return values
trueAn error occurred
falseSuccess

◆ set_dynamic_privileges_map()

void set_dynamic_privileges_map ( User_to_dynamic_privileges_map map)

◆ sp_grant_privileges()

bool sp_grant_privileges ( THD thd,
const char *  sp_db,
const char *  sp_name,
bool  is_proc 
)

Grant EXECUTE,ALTER privilege for a stored procedure.

Parameters
thdThe current thread.
sp_dbDB of the stored procedure.
sp_nameName of the stored procedure
is_procTrue if this is a SP rather than a function
Return values
falseSuccess
trueAn error occurred. Error message not yet sent.

◆ sp_revoke_privileges()

bool sp_revoke_privileges ( THD thd,
const char *  sp_db,
const char *  sp_name,
bool  is_proc 
)

Revoke privileges for all users on a stored procedure.

Use an error handler that converts errors about missing grants into warnings.

Parameters
thdThe current thread.
sp_dbDB of the stored procedure
sp_nameName of the stored procedure
is_procTrue if this is a SP rather than a function.
Return values
falseOK.
trueError. Error message not yet sent.

◆ swap_dynamic_privileges_map()

User_to_dynamic_privileges_map * swap_dynamic_privileges_map ( User_to_dynamic_privileges_map map)

◆ update_mandatory_roles()

void update_mandatory_roles ( void  )

◆ update_role_flag_of_acl_user()

static void update_role_flag_of_acl_user ( const Role_vertex_descriptor role_vert,
ACL_USER acl_user 
)
static

This utility function checks for the connecting vertices of the role descriptor(authid node) and updates the role flag of the corresponding ACL user.

If there are no incoming edges to this authid node then this is not a role id anymore. It assumes that acl user and role descriptor are, valid and passed correctly.

Parameters
[in]role_vertThe role vertex descriptor
[in,out]acl_userThe acl role

◆ update_schema_privilege()

static bool update_schema_privilege ( THD thd,
TABLE table,
char *  buff,
const char *  db,
const char *  t_name,
const char *  column,
size_t  col_length,
const char *  priv,
size_t  priv_length,
const char *  is_grantable 
)
static

◆ update_sctx()

void update_sctx ( Security_context sctx,
LEX_USER to_user_ptr 
)

Variable Documentation

◆ any_db

const char* any_db = "*any*"

◆ g_active_dummy_user

char g_active_dummy_user[] = "active dummy user"
static

◆ g_authid_to_vertex

Role_index_map* g_authid_to_vertex = nullptr

◆ g_default_roles

Default_roles* g_default_roles
extern

◆ g_dynamic_privileges_map

User_to_dynamic_privileges_map* g_dynamic_privileges_map = nullptr

◆ g_granted_roles

Granted_roles_graph* g_granted_roles = nullptr

◆ GRANTEE_MAX_BUFF_LENGTH

const int GRANTEE_MAX_BUFF_LENGTH
static
Initial value:
=
static constexpr int HOSTNAME_LENGTH
Definition: my_hostname.h:42
#define USERNAME_LENGTH
Definition: mysql_com.h:68

Grantee is of form 'user'@'hostname', so add +1 for '@' and +4 for the single quotes.

And +1 for null byte too.

Note that we use USERNAME_LENGTH and not USERNAME_CHAR_LENGTH here because the username can be utf8.

◆ initialized

bool initialized
extern