summaryrefslogtreecommitdiffstats
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 13:39:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 13:39:13 +0000
commit86fbb58c3ac0865482819c10a3e81f2eea001c36 (patch)
tree28c9e526ea739c6f9b89e36115e1e2698bddf981 /sql/sql_acl.cc
parentReleasing progress-linux version 1:10.11.6-2~progress7.99u1. (diff)
downloadmariadb-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 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc86
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;
/*