Skip to content

Commit e3eae96

Browse files
committed
Merge branch 'mysql-8.0-bug30600321' into mysql-8.0
2 parents 00b8ccf + 11e5717 commit e3eae96

File tree

9 files changed

+133
-32
lines changed

9 files changed

+133
-32
lines changed

mysql-test/suite/ndb/r/stored_grants_error_handling.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,17 @@ CREATE USER "mcmd"@"localhost";
22
GRANT ALL PRIVILEGES ON *.* to "mcmd"@"localhost";
33
CALL mtr.add_suppression("NDB: Error 626, Tuple did not exist");
44
GRANT ALL PRIVILEGES ON *.* to "mcmd"@"localhost";
5+
Expect 33
6+
max_questions
7+
33
8+
Expect 0
9+
max_questions
10+
0
11+
Expect 55
12+
max_questions
13+
55
14+
Expect 0
15+
max_questions
16+
0
517
DROP USER mcmd@localhost;
18+
DROP USER lu1@a;

mysql-test/suite/ndb/t/stored_grants_error_handling.test

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
--source include/have_ndb.inc
22
--source suite/ndb/include/ndb_find_tools.inc
33

4+
#
5+
# Open connections
6+
#
7+
connect(mysqld2,127.0.0.1,root,,test,$MASTER_MYPORT1);
8+
9+
#
410
# Bug#30556487 MYSQLD HANG IN NDB_STORED_GRANTS CODE ON CREATE USER
11+
#
512
CREATE USER "mcmd"@"localhost";
613
GRANT ALL PRIVILEGES ON *.* to "mcmd"@"localhost";
714

@@ -13,6 +20,60 @@ GRANT ALL PRIVILEGES ON *.* to "mcmd"@"localhost";
1320
CALL mtr.add_suppression("NDB: Error 626, Tuple did not exist");
1421
GRANT ALL PRIVILEGES ON *.* to "mcmd"@"localhost";
1522

23+
#
24+
# Bug#30600321 MAX_QUERIES_PER_HOUR 0 ONLY REMOVES THE LIMIT ON 1 MYSQLD
25+
#
26+
--enable_result_log
27+
--disable_query_log
28+
29+
# Bug#30600321 Test (1): Alter resource limit of stored user
30+
ALTER USER "mcmd"@"localhost" WITH MAX_QUERIES_PER_HOUR 33;
31+
32+
connection mysqld2;
33+
echo Expect 33;
34+
SELECT max_questions from mysql.user where user = 'mcmd';
35+
36+
connection default;
37+
ALTER USER "mcmd"@"localhost" WITH MAX_QUERIES_PER_HOUR 0;
38+
39+
connection mysqld2;
40+
let $max= `SELECT max_questions from mysql.user where user = 'mcmd'`;
41+
if ($max != 0)
42+
{
43+
die Test failed -- max_questions was not zero;
44+
}
45+
46+
# Bug#30600321 Test (2): Alter both resource limit and password of stored user
47+
connection default;
48+
ALTER USER "mcmd"@"localhost" WITH MAX_QUERIES_PER_HOUR 44;
49+
ALTER USER "mcmd"@"localhost" IDENTIFIED BY "Garb_farb_earb" WITH MAX_QUERIES_PER_HOUR 0;
50+
51+
connection mysqld2;
52+
echo Expect 0;
53+
SELECT max_questions from mysql.user where user = 'mcmd';
54+
55+
# Bug#30600321 Test (3): Alter resource limit of stored and non-stored users
56+
connection default;
57+
CREATE USER "lu1"@"a";
58+
ALTER USER "lu1"@"a", "mcmd"@"localhost" WITH MAX_QUERIES_PER_HOUR 55;
59+
60+
connection mysqld2;
61+
echo Expect 55;
62+
SELECT max_questions from mysql.user where user = 'mcmd';
63+
64+
connection default;
65+
ALTER USER "lu1"@"a", "mcmd"@"localhost" WITH MAX_QUERIES_PER_HOUR 0;
66+
67+
connection mysqld2;
68+
echo Expect 0;
69+
SELECT max_questions from mysql.user where user = 'mcmd';
70+
71+
--enable_query_log
72+
73+
#
1674
# Cleanup
75+
#
76+
connection default;
1777
DROP USER mcmd@localhost;
78+
DROP USER lu1@a;
1879

sql/auth/acl_change_notification.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2727
#include "my_sqlcommand.h" // enum_sql_command
2828
#include "sql/table.h" // LEX_USER, LEX_CSTRING, List
2929

30+
class Rewrite_params; // forward declaration
31+
3032
class Acl_change_notification {
3133
public:
3234
struct User {
@@ -39,23 +41,24 @@ class Acl_change_notification {
3941

4042
Acl_change_notification(class THD *thd, enum_sql_command op,
4143
const List<LEX_USER> *users,
44+
Rewrite_params *rewrite_params,
4245
const List<LEX_CSTRING> *dynamic_privs);
4346

4447
private:
4548
enum_sql_command operation;
4649
std::string db;
47-
std::string query;
4850
std::vector<User> user_list;
4951
std::vector<std::string> dynamic_privilege_list;
52+
Rewrite_params *rewrite_params;
5053

5154
public:
5255
enum_sql_command get_operation() const { return operation; }
5356
const std::string &get_db() const { return db; }
54-
const std::string &get_query_for_logging() const { return query; }
5557
const std::vector<User> &get_user_list() const { return user_list; }
5658
const std::vector<std::string> &get_dynamic_privilege_list() const {
5759
return dynamic_privilege_list;
5860
}
61+
Rewrite_params *get_rewrite_params() const { return rewrite_params; }
5962
};
6063

6164
#endif

sql/auth/auth_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ bool log_and_commit_acl_ddl(THD *thd, bool transactional_tables,
209209
bool log_to_binlog = true);
210210
void acl_notify_htons(THD *thd, enum_sql_command operation,
211211
const List<LEX_USER> *users,
212+
std::set<LEX_USER *> *rewrite_users = nullptr,
212213
const List<LEX_CSTRING> *dynamic_privs = nullptr);
213214

214215
/* sql_authorization */

sql/auth/sql_authorization.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3592,7 +3592,7 @@ bool mysql_grant(THD *thd, const char *db, List<LEX_USER> &list, ulong rights,
35923592
my_ok(thd);
35933593
/* Notify storage engines */
35943594
acl_notify_htons(thd, revoke_grant ? SQLCOM_REVOKE : SQLCOM_GRANT, &list,
3595-
granted_dynamic_privs);
3595+
nullptr, granted_dynamic_privs);
35963596
}
35973597

35983598
return error;

sql/auth/sql_user.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,11 +1578,11 @@ bool change_password(THD *thd, LEX_USER *lex_user, const char *new_password,
15781578
authentication_plugin.c_str(), is_role, nullptr, nullptr);
15791579
} /* Critical section */
15801580

1581-
/* Notify storage engines */
1581+
/* Notify storage engines (including rewrite list) */
15821582
if (!(result || commit_result)) {
15831583
List<LEX_USER> user_list;
15841584
user_list.push_back(lex_user);
1585-
acl_notify_htons(thd, SQLCOM_SET_PASSWORD, &user_list);
1585+
acl_notify_htons(thd, SQLCOM_SET_PASSWORD, &user_list, &users);
15861586
}
15871587

15881588
return result || commit_result;
@@ -2819,8 +2819,8 @@ bool mysql_alter_user(THD *thd, List<LEX_USER> &list, bool if_exists) {
28192819
reset_mqh(thd, extra_user, false);
28202820
}
28212821
}
2822-
/* Notify storage engines */
2823-
acl_notify_htons(thd, SQLCOM_ALTER_USER, &list);
2822+
/* Notify storage engines (including rewrite list) */
2823+
acl_notify_htons(thd, SQLCOM_ALTER_USER, &list, &extra_users);
28242824
}
28252825

28262826
if (result == 0) {

sql/auth/sql_user_table.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,10 @@ ulong get_access(TABLE *form, uint fieldnr, uint *next_field) {
558558
*/
559559
Acl_change_notification::Acl_change_notification(
560560
THD *thd, enum_sql_command op, const List<LEX_USER> *users,
561-
const List<LEX_CSTRING> *dynamic_privs)
562-
: operation(op), db(thd->db().str, thd->db().length) {
563-
if (thd->rewritten_query().length()) {
564-
query.assign(thd->rewritten_query().ptr(), thd->rewritten_query().length());
565-
} else {
566-
query.assign(thd->query().str, thd->query().length);
567-
}
561+
Rewrite_params *rewrite, const List<LEX_CSTRING> *dynamic_privs)
562+
: operation(op),
563+
db(thd->db().str, thd->db().length),
564+
rewrite_params(rewrite) {
568565
if (users) {
569566
/* Copy data out of List<LEX_USER> */
570567
user_list.reserve(users->size());
@@ -581,11 +578,12 @@ Acl_change_notification::Acl_change_notification(
581578
}
582579
}
583580

584-
void acl_notify_htons(THD *thd MY_ATTRIBUTE((unused)),
585-
enum_sql_command operation MY_ATTRIBUTE((unused)),
586-
const List<LEX_USER> *users MY_ATTRIBUTE((unused)),
587-
const List<LEX_CSTRING> *dynamic_privs
588-
MY_ATTRIBUTE((unused))) {
581+
void acl_notify_htons(
582+
THD *thd MY_ATTRIBUTE((unused)),
583+
enum_sql_command operation MY_ATTRIBUTE((unused)),
584+
const List<LEX_USER> *users MY_ATTRIBUTE((unused)),
585+
std::set<LEX_USER *> *rewrite_users MY_ATTRIBUTE((unused)),
586+
const List<LEX_CSTRING> *dynamic_privs MY_ATTRIBUTE((unused))) {
589587
DBUG_TRACE;
590588
DBUG_PRINT("enter", ("db: %s query: '%s'", thd->db().str, thd->query().str));
591589
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@@ -594,7 +592,9 @@ void acl_notify_htons(THD *thd MY_ATTRIBUTE((unused)),
594592
So, instantiate it and send a notification only if the Server is
595593
built with ndbcluster SE.
596594
*/
597-
Acl_change_notification notice(thd, operation, users, dynamic_privs);
595+
User_params rewrite_user_params(rewrite_users);
596+
User_params *rewrite = rewrite_users ? &rewrite_user_params : nullptr;
597+
Acl_change_notification notice(thd, operation, users, rewrite, dynamic_privs);
598598
ha_acl_notify(thd, &notice);
599599
#endif
600600
}

storage/ndb/plugin/ha_ndbcluster_binlog.cc

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "sql/rpl_injector.h"
4141
#include "sql/rpl_slave.h"
4242
#include "sql/sql_lex.h"
43+
#include "sql/sql_rewrite.h"
4344
#include "sql/sql_table.h" // build_table_filename
4445
#include "sql/sql_thd_internal_api.h"
4546
#include "sql/thd_raii.h"
@@ -596,8 +597,17 @@ static void ndbcluster_acl_notify(THD *thd,
596597
return;
597598
}
598599

599-
const std::string &query = notice->get_query_for_logging();
600+
/* Obtain the query in a form suitable for writing to the error log.
601+
The password is replaced with the string "<secret>".
602+
*/
603+
std::string query;
604+
if (thd->rewritten_query().length())
605+
query.assign(thd->rewritten_query().ptr(), thd->rewritten_query().length());
606+
else
607+
query.assign(thd->query().str, thd->query().length);
608+
DBUG_ASSERT(query.length());
600609
ndb_log_verbose(9, "ACL considering: %s", query.c_str());
610+
601611
std::string user_list;
602612
bool dist_use_db = false; // Prepend "use [db];" to statement
603613
bool dist_refresh = false; // All participants must refresh their caches
@@ -632,6 +642,19 @@ static void ndbcluster_acl_notify(THD *thd,
632642

633643
DBUG_ASSERT(strategy == Ndb_stored_grants::Strategy::STATEMENT);
634644
ndb_log_verbose(9, "ACL change distribution: STATEMENT");
645+
646+
/* If the notice contains rewrite_params, query is an ALTER USER or SET
647+
PASSWORD statement and must be rewritten again, as if for the binlog,
648+
replacing a plaintext password with a crytpographic hash.
649+
*/
650+
if (notice->get_rewrite_params()) {
651+
String rewritten_query;
652+
mysql_rewrite_acl_query(thd, rewritten_query, Consumer_type::BINLOG,
653+
notice->get_rewrite_params(), false);
654+
query.assign(rewritten_query.c_ptr_safe(), rewritten_query.length());
655+
DBUG_ASSERT(query.length());
656+
}
657+
635658
if (!schema_dist_client.acl_notify(
636659
dist_use_db ? notice->get_db().c_str() : nullptr, query.c_str(),
637660
query.length(), dist_refresh))

storage/ndb/plugin/ndb_stored_grants.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -617,16 +617,17 @@ int ThreadContext::drop_users(ChangeNotice *notice,
617617
from SHOW CREATE USER, so its exact format is known. For idempotence, it
618618
must be rewritten as several statements. The final result is:
619619
CREATE USER IF NOT EXISTS user@host;
620-
ALTER USER user@host ... ;
621620
REVOKE ALL ON *.* FROM user@host;
622-
GRANT ... TO user@host;
623-
GRANT ... TO user@host;
624-
ALTER USER user@host DEFAULT ROLE r;
621+
ALTER USER user@host ...; [CLEAR RESOURCE LIMITS]
622+
ALTER USER user@host ...; [SET VALUES FROM SHOW CREATE USER]
625623
*/
626624
void ThreadContext::create_user(std::string &name, std::string &statement) {
627625
const std::string create_user("CREATE USER IF NOT EXISTS ");
628626
const std::string alter_user("ALTER USER ");
629627
const std::string revoke_all("REVOKE ALL ON *.* FROM ");
628+
const std::string set_resource_defaults(
629+
" WITH MAX_QUERIES_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 "
630+
" MAX_CONNECTIONS_PER_HOUR 0 MAX_USER_CONNECTIONS 0");
630631

631632
/* Run statement CREATE USER IF NOT EXISTS */
632633
if (!get_local_user(name)) {
@@ -635,6 +636,12 @@ void ThreadContext::create_user(std::string &name, std::string &statement) {
635636
run_acl_statement(create_user + name);
636637
}
637638

639+
/* Revoke any privileges the user may have had prior to this snapshot. */
640+
run_acl_statement(revoke_all + name);
641+
642+
/* Clear resource limits (this is not included in SHOW CREATE USER) */
643+
run_acl_statement(alter_user + name + set_resource_defaults);
644+
638645
/* Rewrite CREATE to ALTER */
639646
statement = statement.replace(0, 6, "ALTER");
640647

@@ -658,9 +665,6 @@ void ThreadContext::create_user(std::string &name, std::string &statement) {
658665

659666
/* Run the rest of the statement. */
660667
run_acl_statement(statement.erase(default_role_pos, role_clause_len));
661-
662-
/* Revoke any privileges the user may have had prior to this snapshot. */
663-
run_acl_statement(revoke_all + name);
664668
}
665669

666670
/* Apply the snapshot in m_current_rows,
@@ -849,10 +853,6 @@ Ndb_stored_grants::Strategy ThreadContext::handle_change(ChangeNotice *notice) {
849853
/* ALTER USER, SET PASSWORD, or GRANT or REVOKE of misc. privileges */
850854
rebuild_local_cache = false;
851855
update_list = &m_intersection;
852-
/* Distribute ALTER USER and SET PASSWORD as snapshot refreshes
853-
in order to avoid transmitting plaintext passwords. */
854-
if (operation == SQLCOM_ALTER_USER || operation == SQLCOM_SET_PASSWORD)
855-
dist_as_snapshot = true;
856856
}
857857

858858
/* drop_users() will DROP USER or REVOKE NDB_STORED_USER, as appropriate */

0 commit comments

Comments
 (0)