Skip to content

Commit 0c3a472

Browse files
Bug#31246179: USER WITH CREATE USER AND WITH ADMIN ROLE CAN GRANT ROLE TO ANONYMOUS USER AND CORRUPT DATABASE
Description: Inconsistency in representating an anonymous user in in-memory structures may cause issues while performing grant operations Fix: Consistently handled anoynmous users in various user management DDLs, SHOW GRANTS and FLUSH PRIVILEGES RB: 24367
1 parent bfcc92b commit 0c3a472

File tree

6 files changed

+80
-49
lines changed

6 files changed

+80
-49
lines changed

sql/auth/acl_table_user.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2018, 2020, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -1923,8 +1923,7 @@ void Acl_table_user_reader::read_password_require_current(ACL_USER &user) {
19231923
bool Acl_table_user_reader::read_user_attributes(ACL_USER &user) {
19241924
/* Read user_attributes field */
19251925
if (m_table->s->fields > m_table_schema->user_attributes_idx()) {
1926-
Auth_id auth_id(user.user ? user.user : "",
1927-
user.user ? strlen(user.user) : 0,
1926+
Auth_id auth_id(user.user ? user.user : "", user.get_username_length(),
19281927
user.host.get_host() ? user.host.get_host() : "",
19291928
user.host.get_host() ? strlen(user.host.get_host()) : 0);
19301929
Acl_user_attributes user_attributes(&m_mem_root, true, auth_id,

sql/auth/auth_common.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2015, 2020, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -116,7 +116,7 @@ Auth_id::Auth_id(const LEX_USER *lex_user)
116116
Auth_id::Auth_id(const ACL_USER *acl_user) {
117117
if (acl_user) {
118118
if (acl_user->user != nullptr) // Not an anonymous user
119-
m_user.assign(acl_user->user, strlen(acl_user->user));
119+
m_user.assign(acl_user->user, acl_user->get_username_length());
120120
m_host.assign(acl_user->host.get_host(), acl_user->host.get_host_len());
121121
create_key();
122122
}

sql/auth/sql_auth_cache.cc

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -165,6 +165,20 @@ bool validate_user_plugins = true;
165165
#define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3)
166166
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + 1 + USERNAME_LENGTH + 1)
167167

168+
/** Helper: Set user name */
169+
static void set_username(char **user, const char *user_arg, MEM_ROOT *mem) {
170+
DBUG_ASSERT(user != nullptr);
171+
*user = (user_arg && *user_arg) ? strdup_root(mem, user_arg) : nullptr;
172+
}
173+
174+
/** Helper: Set host name */
175+
static void set_hostname(ACL_HOST_AND_IP *host, const char *host_arg,
176+
MEM_ROOT *mem) {
177+
DBUG_ASSERT(host != nullptr);
178+
host->update_hostname((host_arg && *host_arg) ? strdup_root(mem, host_arg)
179+
: nullptr);
180+
}
181+
168182
/**
169183
Allocates the memory in the the global_acl_memory MEM_ROOT.
170184
*/
@@ -420,6 +434,14 @@ ACL_USER *ACL_USER::copy(MEM_ROOT *root) {
420434
return dst;
421435
}
422436

437+
void ACL_USER::set_user(MEM_ROOT *mem, const char *user_arg) {
438+
set_username(&user, user_arg, mem);
439+
}
440+
441+
void ACL_USER::set_host(MEM_ROOT *mem, const char *host_arg) {
442+
set_hostname(&host, host_arg, mem);
443+
}
444+
423445
void ACL_PROXY_USER::init(const char *host_arg, const char *user_arg,
424446
const char *proxied_host_arg,
425447
const char *proxied_user_arg, bool with_grant_arg) {
@@ -583,6 +605,22 @@ int ACL_PROXY_USER::store_data_record(TABLE *table, const LEX_CSTRING &hostname,
583605
return false;
584606
}
585607

608+
void ACL_PROXY_USER::set_user(MEM_ROOT *mem, const char *user_arg) {
609+
set_username(const_cast<char **>(&user), user_arg, mem);
610+
}
611+
612+
void ACL_PROXY_USER::set_host(MEM_ROOT *mem, const char *host_arg) {
613+
set_hostname(&host, host_arg, mem);
614+
}
615+
616+
void ACL_DB::set_user(MEM_ROOT *mem, const char *user_arg) {
617+
set_username(&user, user_arg, mem);
618+
}
619+
620+
void ACL_DB::set_host(MEM_ROOT *mem, const char *host_arg) {
621+
set_hostname(&host, host_arg, mem);
622+
}
623+
586624
/**
587625
Performs wildcard matching, aka globbing, on the input string with
588626
the given wildcard pattern, and the specified wildcard characters.
@@ -783,7 +821,7 @@ GRANT_COLUMN::GRANT_COLUMN(String &c, ulong y)
783821
void GRANT_NAME::set_user_details(const char *h, const char *d, const char *u,
784822
const char *t, bool is_routine) {
785823
/* Host given by user */
786-
host.update_hostname(strdup_root(&memex, h));
824+
set_hostname(&host, h, &memex);
787825
if (db != d) {
788826
db = strdup_root(&memex, d);
789827
if (lower_case_table_names) my_casedn_str(files_charset_info, db);
@@ -2752,10 +2790,8 @@ void acl_users_add_one(const char *user, const char *host,
27522790
*/
27532791
acl_user.can_authenticate = true;
27542792

2755-
acl_user.user =
2756-
user && *user ? strdup_root(&global_acl_memory, user) : nullptr;
2757-
acl_user.host.update_hostname(
2758-
host && *host ? strdup_root(&global_acl_memory, host) : nullptr);
2793+
acl_user.set_user(&global_acl_memory, user);
2794+
acl_user.set_host(&global_acl_memory, host);
27592795
DBUG_ASSERT(plugin.str);
27602796
if (plugin.str[0]) {
27612797
acl_user.plugin = plugin;
@@ -2923,9 +2959,8 @@ void acl_insert_db(const char *user, const char *host, const char *db,
29232959
ulong privileges) {
29242960
ACL_DB acl_db;
29252961
DBUG_ASSERT(assert_acl_cache_write_lock(current_thd));
2926-
acl_db.user = strdup_root(&global_acl_memory, user);
2927-
acl_db.host.update_hostname(*host ? strdup_root(&global_acl_memory, host)
2928-
: nullptr);
2962+
acl_db.set_user(&global_acl_memory, user);
2963+
acl_db.set_host(&global_acl_memory, host);
29292964
acl_db.db = strdup_root(&global_acl_memory, db);
29302965
acl_db.access = privileges;
29312966
acl_db.sort = get_sort(3, acl_db.host.get_host(), acl_db.db, acl_db.user);

sql/auth/sql_auth_cache.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -200,6 +200,9 @@ class ACL_USER : public ACL_ACCESS {
200200
ACL_USER *copy(MEM_ROOT *root);
201201
ACL_USER();
202202

203+
void set_user(MEM_ROOT *mem, const char *user_arg);
204+
void set_host(MEM_ROOT *mem, const char *host_arg);
205+
size_t get_username_length() const { return user ? strlen(user) : 0; }
203206
class Password_locked_state {
204207
public:
205208
bool is_active() const {
@@ -241,6 +244,9 @@ class ACL_USER : public ACL_ACCESS {
241244
class ACL_DB : public ACL_ACCESS {
242245
public:
243246
char *user, *db;
247+
248+
void set_user(MEM_ROOT *mem, const char *user_arg);
249+
void set_host(MEM_ROOT *mem, const char *host_arg);
244250
};
245251

246252
class ACL_PROXY_USER : public ACL_ACCESS {
@@ -276,9 +282,8 @@ class ACL_PROXY_USER : public ACL_ACCESS {
276282
const char *get_user() { return user; }
277283
const char *get_proxied_user() { return proxied_user; }
278284
const char *get_proxied_host() { return proxied_host.get_host(); }
279-
void set_user(MEM_ROOT *mem, const char *user_arg) {
280-
user = user_arg && *user_arg ? strdup_root(mem, user_arg) : nullptr;
281-
}
285+
void set_user(MEM_ROOT *mem, const char *user_arg);
286+
void set_host(MEM_ROOT *mem, const char *host_arg);
282287

283288
bool check_validity(bool check_no_resolve);
284289

sql/auth/sql_authorization.cc

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -985,7 +985,7 @@ void make_global_privilege_statement(THD *thd, ulong want_access,
985985
}
986986
}
987987
global->append(STRING_WITH_LEN(" ON *.* TO "));
988-
size_t len = acl_user->user == nullptr ? 0 : strlen(acl_user->user);
988+
size_t len = acl_user->get_username_length();
989989
append_identifier(thd, global, acl_user->user, len);
990990
global->append('@');
991991
append_identifier(thd, global, acl_user->host.get_host(),
@@ -1042,8 +1042,7 @@ void make_database_privilege_statement(THD *thd, ACL_USER *role,
10421042
db.append(STRING_WITH_LEN(" ON "));
10431043
append_identifier(thd, &db, db_name.c_str(), db_name.length());
10441044
db.append(STRING_WITH_LEN(".* TO "));
1045-
append_identifier(thd, &db, role->user,
1046-
role->user ? strlen(role->user) : 0);
1045+
append_identifier(thd, &db, role->user, role->get_username_length());
10471046
db.append('@');
10481047
// host and lex_user->host are equal except for case
10491048
append_identifier(thd, &db, role->host.get_host(),
@@ -1091,7 +1090,7 @@ void make_database_privilege_statement(THD *thd, ACL_USER *role,
10911090
rl_itr.first.length());
10921091
db.append(STRING_WITH_LEN(".* FROM "));
10931092
append_identifier(thd, &db, acl_user->user,
1094-
acl_user->user ? strlen(acl_user->user) : 0);
1093+
acl_user->get_username_length());
10951094
db.append('@');
10961095
// host and lex_user->host are equal except for case
10971096
append_identifier(thd, &db, acl_user->host.get_host(),
@@ -1180,8 +1179,7 @@ void make_sp_privilege_statement(THD *thd, ACL_USER *role, Protocol *protocol,
11801179
db.append(STRING_WITH_LEN("FUNCTION "));
11811180
db.append(sp_name.c_str(), sp_name.length());
11821181
db.append(STRING_WITH_LEN(" TO "));
1183-
append_identifier(thd, &db, role->user,
1184-
role->user ? strlen(role->user) : 0);
1182+
append_identifier(thd, &db, role->user, role->get_username_length());
11851183
db.append(STRING_WITH_LEN("@"));
11861184
// host and lex_user->host are equal except for case
11871185
append_identifier(thd, &db, role->host.get_host(),
@@ -1223,7 +1221,8 @@ void make_with_admin_privilege_statement(
12231221
}
12241222
if (found) {
12251223
global.append(STRING_WITH_LEN(" TO "));
1226-
append_identifier(thd, &global, acl_user->user, strlen(acl_user->user));
1224+
append_identifier(thd, &global, acl_user->user,
1225+
acl_user->get_username_length());
12271226
global.append('@');
12281227
append_identifier(thd, &global, acl_user->host.get_host(),
12291228
acl_user->host.get_host_len());
@@ -1259,7 +1258,8 @@ void make_dynamic_privilege_statement(THD *thd, ACL_USER *role,
12591258
/* Dynamic privileges are always applied on global level */
12601259
global.append(STRING_WITH_LEN(" ON *.* TO "));
12611260
if (role->user != nullptr)
1262-
append_identifier(thd, &global, role->user, strlen(role->user));
1261+
append_identifier(thd, &global, role->user,
1262+
role->get_username_length());
12631263
else
12641264
global.append(STRING_WITH_LEN("''"));
12651265
global.append('@');
@@ -1326,8 +1326,7 @@ void make_roles_privilege_statement(THD *thd, ACL_USER *role,
13261326
} // end while
13271327
if (found) {
13281328
global.append(STRING_WITH_LEN(" TO "));
1329-
append_identifier(thd, &global, role->user,
1330-
role->user ? strlen(role->user) : 0);
1329+
append_identifier(thd, &global, role->user, role->get_username_length());
13311330
global.append('@');
13321331
append_identifier(thd, &global, role->host.get_host(),
13331332
role->host.get_host_len());
@@ -1399,7 +1398,7 @@ void make_table_privilege_statement(THD *thd, ACL_USER *role,
13991398
global.append(STRING_WITH_LEN(" ON "));
14001399
global.append(qualified_table_name.c_str(), qualified_table_name.length());
14011400
global.append(STRING_WITH_LEN(" TO "));
1402-
append_identifier(thd, &global, role->user, strlen(role->user));
1401+
append_identifier(thd, &global, role->user, role->get_username_length());
14031402
global.append('@');
14041403
// host and lex_user->host are equal except for case
14051404
append_identifier(thd, &global, role->host.get_host(),
@@ -1589,7 +1588,7 @@ class Get_access_maps : public boost::default_bfs_visitor {
15891588
m_with_admin_acl(with_admin_acl),
15901589
m_dynamic_acl(dyn_acl),
15911590
m_restrictions(restrictions),
1592-
m_grantee{acl_user->user, strlen(acl_user->user),
1591+
m_grantee{acl_user->user, acl_user->get_username_length(),
15931592
acl_user->host.get_host(), acl_user->host.get_host_len()} {}
15941593
template <typename Vertex, typename Graph>
15951594
void discover_vertex(Vertex u, const Graph &) const {
@@ -5976,7 +5975,7 @@ bool find_if_granted_role(Role_vertex_descriptor v, LEX_CSTRING role,
59765975
ACL_USER acl_user =
59775976
get(boost::vertex_acl_user_t(),
59785977
*g_granted_roles)[boost::target(*ei, *g_granted_roles)];
5979-
if ((role.length == strlen(acl_user.user)) &&
5978+
if ((role.length == acl_user.get_username_length()) &&
59805979
(role_host.length == acl_user.host.get_host_len()) &&
59815980
!strncmp(role.str, acl_user.user, role.length) &&
59825981
(role_host.length == 0 ||
@@ -6007,7 +6006,7 @@ void get_granted_roles(Role_vertex_descriptor &v,
60076006
int with_admin_opt = edge_with_admin[*ei];
60086007
LEX_CSTRING tmp_user, tmp_host;
60096008
tmp_user.str = acl_user.user;
6010-
tmp_user.length = strlen(acl_user.user);
6009+
tmp_user.length = acl_user.get_username_length();
60116010
tmp_host.str = acl_user.host.get_host();
60126011
tmp_host.length = acl_user.host.get_host_len();
60136012
Role_id id(tmp_user, tmp_host);
@@ -6518,7 +6517,7 @@ Auth_id_ref create_authid_from(const LEX_CSTRING &user,
65186517
*/
65196518
std::string create_authid_str_from(const ACL_USER *user) {
65206519
String tmp;
6521-
size_t length = user->user == nullptr ? 0 : strlen(user->user);
6520+
size_t length = user->get_username_length();
65226521
append_identifier(&tmp, user->user, length);
65236522
tmp.append("@");
65246523
append_identifier(&tmp, user->host.get_host(), user->host.get_host_len());
@@ -6538,10 +6537,7 @@ Auth_id_ref create_authid_from(const ACL_USER *user) {
65386537
LEX_CSTRING username;
65396538
LEX_CSTRING host;
65406539
username.str = user->user;
6541-
if (user->user != nullptr)
6542-
username.length = strlen(user->user);
6543-
else
6544-
username.length = 0;
6540+
username.length = user->get_username_length();
65456541
host.str = user->host.get_host();
65466542
host.length = user->host.get_host_len();
65476543
id = std::make_pair(username, host);

sql/auth/sql_user.cc

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
22
This program is free software; you can redistribute it and/or modify
33
it under the terms of the GNU General Public License, version 2.0,
44
as published by the Free Software Foundation.
@@ -1754,9 +1754,9 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
17541754
*/
17551755
idx--;
17561756
} else if (user_to) {
1757-
acl_user->user = strdup_root(&global_acl_memory, user_to->user.str);
1758-
acl_user->host.update_hostname(
1759-
strdup_root(&global_acl_memory, user_to->host.str));
1757+
acl_user->set_user(&global_acl_memory, user_to->user.str);
1758+
acl_user->set_host(&global_acl_memory, user_to->host.str);
1759+
17601760
rebuild_cached_acl_users_for_name();
17611761
} else {
17621762
/* If search is requested, we do not need to search further. */
@@ -1774,9 +1774,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
17741774
acl_dbs->erase(idx);
17751775
idx--;
17761776
} else if (user_to) {
1777-
acl_db->user = strdup_root(&global_acl_memory, user_to->user.str);
1778-
acl_db->host.update_hostname(
1779-
strdup_root(&global_acl_memory, user_to->host.str));
1777+
acl_db->set_user(&global_acl_memory, user_to->user.str);
1778+
acl_db->set_host(&global_acl_memory, user_to->host.str);
17801779
} else {
17811780
/* If search is requested, we do not need to search further. */
17821781
break;
@@ -1826,10 +1825,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
18261825
idx--;
18271826
} else if (user_to) {
18281827
acl_proxy_user->set_user(&global_acl_memory, user_to->user.str);
1829-
acl_proxy_user->host.update_hostname(
1830-
(user_to->host.str && *user_to->host.str)
1831-
? strdup_root(&global_acl_memory, user_to->host.str)
1832-
: nullptr);
1828+
acl_proxy_user->set_host(&global_acl_memory, user_to->host.str);
18331829
} else {
18341830
/* If search is requested, we do not need to search further. */
18351831
break;

0 commit comments

Comments
 (0)