diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:39:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:39:13 +0000 |
commit | 86fbb58c3ac0865482819c10a3e81f2eea001c36 (patch) | |
tree | 28c9e526ea739c6f9b89e36115e1e2698bddf981 /sql/sql_acl.cc | |
parent | Releasing progress-linux version 1:10.11.6-2~progress7.99u1. (diff) | |
download | mariadb-86fbb58c3ac0865482819c10a3e81f2eea001c36.tar.xz mariadb-86fbb58c3ac0865482819c10a3e81f2eea001c36.zip |
Merging upstream version 1:10.11.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | sql/sql_acl.cc | 86 |
1 files changed, 68 insertions, 18 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 029b12ad..c6080e5b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -957,6 +957,7 @@ class User_table_tabular: public User_table int get_auth(THD *thd, MEM_ROOT *root, ACL_USER *u) const { + mysql_mutex_assert_owner(&acl_cache->lock); u->alloc_auth(root, 1); if (have_password()) { @@ -2316,6 +2317,9 @@ static bool validate_password(THD *thd, const LEX_CSTRING &user, static int set_user_salt(ACL_USER::AUTH *auth, plugin_ref plugin) { st_mysql_auth *info= (st_mysql_auth *) plugin_decl(plugin)->info; + + mysql_mutex_assert_owner(&acl_cache->lock); + if (info->interface_version >= 0x0202 && info->preprocess_hash && auth->auth_string.length) { @@ -2351,6 +2355,8 @@ static int set_user_auth(THD *thd, const LEX_CSTRING &user, plugin_ref plugin= get_auth_plugin(thd, auth->plugin, &unlock_plugin); int res= 1; + mysql_mutex_assert_owner(&acl_cache->lock); + if (!plugin) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -2427,10 +2433,13 @@ static bool set_user_salt_if_needed(ACL_USER *user_copy, int curr_auth, if (auth_copy->salt.str) return 0; // already done + mysql_mutex_lock(&acl_cache->lock); if (set_user_salt(auth_copy, plugin)) + { + mysql_mutex_unlock(&acl_cache->lock); return 1; + } - mysql_mutex_lock(&acl_cache->lock); ACL_USER *user= find_user_exact(user_copy->host.hostname, user_copy->user.str); // make sure the user wasn't altered or dropped meanwhile if (user) @@ -3403,10 +3412,18 @@ end: check_role_is_granted_callback, NULL) == -1)) { - /* Role is not granted but current user can see the role */ - my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", - MYF(0), thd->security_ctx->priv_user, - thd->security_ctx->priv_host, rolename); + /* This happens for SET ROLE case and when `--skip-name-resolve` option + is used. In that situation host can be NULL and current user is always + target user, so printing `priv_user@priv_host` is not incorrect. + */ + if (!host) + my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", + MYF(0), thd->security_ctx->priv_user, + thd->security_ctx->priv_host, rolename); + else + /* Role is not granted but current user can see the role */ + my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", + MYF(0), user, host, rolename); } else { @@ -3477,6 +3494,7 @@ ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo, const Account_options &options, const privilege_t privileges) { + mysql_mutex_assert_owner(&acl_cache->lock); user= safe_lexcstrdup_root(&acl_memroot, combo.user); update_hostname(&host, safe_strdup_root(&acl_memroot, combo.host.str)); hostname_length= combo.host.length; @@ -3493,6 +3511,8 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth, const privilege_t privileges) { ACL_USER_PARAM::AUTH *work_copy= NULL; + mysql_mutex_assert_owner(&acl_cache->lock); + if (nauth) { if (!(work_copy= (ACL_USER_PARAM::AUTH*) @@ -5201,6 +5221,7 @@ update_role_mapping(LEX_CSTRING *user, LEX_CSTRING *host, LEX_CSTRING *role, return 0; } + mysql_mutex_assert_owner(&acl_cache->lock); /* allocate a new entry that will go in the hash */ ROLE_GRANT_PAIR *hash_entry= new (&acl_memroot) ROLE_GRANT_PAIR; if (hash_entry->init(&acl_memroot, user->str, host->str, @@ -5265,6 +5286,7 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, DBUG_ENTER("replace_proxies_priv_table"); + mysql_mutex_assert_owner(&acl_cache->lock); if (!table) { my_error(ER_NO_SUCH_TABLE, MYF(0), MYSQL_SCHEMA_NAME.str, @@ -8373,11 +8395,6 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, INSERT_ACL : SELECT_ACL); } - if (tl->with || !tl->db.str || - (tl->select_lex && - (tl->with= tl->select_lex->find_table_def_in_with_clauses(tl)))) - continue; - const ACL_internal_table_access *access= get_cached_table_access(&t_ref->grant.m_internal, t_ref->get_db_name(), @@ -12159,8 +12176,8 @@ static my_bool count_column_grants(void *grant_table, This must be performed under the mutex in order to make sure the iteration does not fail. */ -static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_column_grants(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_ULONG; var->value= buff; @@ -12176,8 +12193,8 @@ static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_database_grants(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_database_grants(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_UINT; var->value= buff; @@ -13568,8 +13585,37 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) DBUG_RETURN(0); } + +/** + Determine if the client is MySQL Connector/NET. + + Checks whether the given connection attributes blob corresponds to + MySQL Connector/NET by examining the "_client_name" attribute, which is + expected to be the first attribute in the blob. + + @param connection_attrs - The connection attributes blob. + @param length - The length of the blob. + + @return true if the client is MySQL Connector/NET, false otherwise. +*/ +static inline bool is_connector_net_client(const char *connection_attrs, + size_t length) +{ + constexpr LEX_CSTRING prefix= + {STRING_WITH_LEN("\x0c_client_name\x13mysql-connector-net")}; + + if (length < prefix.length) + return false; + + /* Optimization to avoid following memcmp in common cases.*/ + if (connection_attrs[prefix.length - 1] != prefix.str[prefix.length - 1]) + return false; + + return !memcmp(connection_attrs, prefix.str, prefix.length); +} + static bool -read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs) +read_client_connect_attrs(char **ptr, char *end, THD* thd) { ulonglong length; char *ptr_save= *ptr; @@ -13592,10 +13638,14 @@ read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs) if (length > 65535) return true; - if (PSI_CALL_set_thread_connect_attrs(*ptr, (uint)length, from_cs) && + if (PSI_CALL_set_thread_connect_attrs(*ptr, (uint)length, thd->charset()) && current_thd->variables.log_warnings) sql_print_warning("Connection attributes of length %llu were truncated", length); + + /* Connector/Net crashes, when "show collations" returns NULL IDs*/ + if (is_connector_net_client(*ptr, length)) + thd->variables.old_behavior |= OLD_MODE_NO_NULL_COLLATION_IDS; return false; } @@ -13729,7 +13779,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) } if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) && - read_client_connect_attrs(&next_field, end, thd->charset())) + read_client_connect_attrs(&next_field, end, thd)) { my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR), MYF(0)); @@ -13979,7 +14029,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) && read_client_connect_attrs(&next_field, ((char *)net->read_pos) + pkt_len, - mpvio->auth_info.thd->charset())) + mpvio->auth_info.thd)) return packet_error; /* |