Skip to content

Commit d278a87

Browse files
committed
Bug#28948915 DEFAULT ROLE IS NOT LOGGED INTO THE BINARY LOG
Description: ------------ Right before committing the ACL statement, we rewrite the ACL statement for binary log. We missed to write the 'DEFAULT ROLE' clause in the rewritten CREATE USER statement. Hence, this information was getting missed in the binary log. Fix: --- We were already adding 'default role' clause in the rewritten the query for SHOW CREATE USER statement. We now use the same method to rewirte both the CREATE USER and SHOW CREATE USER statements. Test: ----- - Added tests in the rpl.rpl_roles.test file - PB2 testing - push id: 15036507 - 2019-07-11 13:08:23 Review: ------- RB#22500
1 parent 9b19f2c commit d278a87

File tree

5 files changed

+158
-33
lines changed

5 files changed

+158
-33
lines changed

Diff for: mysql-test/suite/rpl/r/rpl_roles.result

+90-2
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,91 @@ FROM_HOST FROM_USER TO_HOST TO_USER WITH_ADMIN_OPTION
8989
[connection slave]
9090
START SLAVE IO_THREAD;
9191
include/wait_for_slave_io_to_start.inc
92+
93+
# Verify if 'DEFAULT ROLE' clause is bin-logged.
94+
95+
[connection master]
96+
connection master;
97+
CREATE USER u2@localhost DEFAULT ROLE r1, r2;
98+
CREATE USER u3@localhost DEFAULT ROLE r1;
99+
100+
SHOW GRANTS FOR u2@localhost;
101+
Grants for u2@localhost
102+
GRANT USAGE ON *.* TO `u2`@`localhost`
103+
GRANT `r1`@`%`,`r2`@`%` TO `u2`@`localhost`
104+
105+
SHOW GRANTS FOR u3@localhost;
106+
Grants for u3@localhost
107+
GRANT USAGE ON *.* TO `u3`@`localhost`
108+
GRANT `r1`@`%` TO `u3`@`localhost`
109+
include/sync_slave_sql_with_master.inc
110+
connection master;
111+
connection slave;
112+
connection slave;
113+
SHOW GRANTS FOR u2@localhost;
114+
Grants for u2@localhost
115+
GRANT USAGE ON *.* TO `u2`@`localhost`
116+
GRANT `r1`@`%`,`r2`@`%` TO `u2`@`localhost`
117+
SHOW GRANTS FOR u3@localhost;
118+
Grants for u3@localhost
119+
GRANT USAGE ON *.* TO `u3`@`localhost`
120+
GRANT `r1`@`%` TO `u3`@`localhost`
121+
122+
SHOW CREATE USER u2@localhost;
123+
CREATE USER for u2@localhost
124+
CREATE USER 'u2'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r1`@`%`,`r2`@`%` REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
125+
SHOW CREATE USER u3@localhost;
126+
CREATE USER for u3@localhost
127+
CREATE USER 'u3'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r1`@`%` REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
128+
[connection master]
129+
connection master;
130+
131+
ALTER USER u2@localhost DEFAULT ROLE NONE;
132+
SHOW GRANTS FOR u3@localhost;
133+
Grants for u3@localhost
134+
GRANT USAGE ON *.* TO `u3`@`localhost`
135+
GRANT `r1`@`%` TO `u3`@`localhost`
136+
ALTER USER u2@localhost DEFAULT ROLE r1;
137+
GRANT r2 TO u3@localhost;
138+
ALTER USER u3@localhost DEFAULT ROLE ALL;
139+
SHOW GRANTS FOR u3@localhost;
140+
Grants for u3@localhost
141+
GRANT USAGE ON *.* TO `u3`@`localhost`
142+
GRANT `r1`@`%`,`r2`@`%` TO `u3`@`localhost`
143+
ALTER USER u3@localhost DEFAULT ROLE r2;
144+
SHOW GRANTS FOR u2@localhost;
145+
Grants for u2@localhost
146+
GRANT USAGE ON *.* TO `u2`@`localhost`
147+
GRANT `r1`@`%`,`r2`@`%` TO `u2`@`localhost`
148+
SHOW GRANTS FOR u3@localhost;
149+
Grants for u3@localhost
150+
GRANT USAGE ON *.* TO `u3`@`localhost`
151+
GRANT `r1`@`%`,`r2`@`%` TO `u3`@`localhost`
152+
153+
include/sync_slave_sql_with_master.inc
154+
connection master;
155+
connection slave;
156+
connection slave;
157+
SHOW GRANTS FOR u2@localhost;
158+
Grants for u2@localhost
159+
GRANT USAGE ON *.* TO `u2`@`localhost`
160+
GRANT `r1`@`%`,`r2`@`%` TO `u2`@`localhost`
161+
SHOW GRANTS FOR u3@localhost;
162+
Grants for u3@localhost
163+
GRANT USAGE ON *.* TO `u3`@`localhost`
164+
GRANT `r1`@`%`,`r2`@`%` TO `u3`@`localhost`
165+
166+
SHOW CREATE USER u2@localhost;
167+
CREATE USER for u2@localhost
168+
CREATE USER 'u2'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r1`@`%` REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
169+
SHOW CREATE USER u3@localhost;
170+
CREATE USER for u3@localhost
171+
CREATE USER 'u3'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r2`@`%` REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
172+
92173
# Cleanup Statement
93174
[connection master]
94175
DROP ROLE r1, r2, r3,r4;
95-
DROP USER u1@localhost;
176+
DROP USER u1@localhost, u2@localhost, u3@localhost;
96177
include/sync_slave_sql_with_master.inc
97178
SELECT * FROM mysql.default_roles;
98179
HOST USER DEFAULT_ROLE_HOST DEFAULT_ROLE_USER
@@ -115,8 +196,15 @@ slave-bin.000001 # Query # # use `test`; CREATE ROLE r4
115196
slave-bin.000001 # Query # # use `test`; GRANT REPLICATION SLAVE ON *.* TO 'r4'@'%'
116197
slave-bin.000001 # Query # # use `test`; GRANT r4 to u1@localhost
117198
slave-bin.000001 # Query # # use `test`; ALTER USER u1@localhost DEFAULT ROLE ALL
199+
slave-bin.000001 # Query # # use `test`; CREATE USER 'u2'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r1`@`%`,`r2`@`%`
200+
slave-bin.000001 # Query # # use `test`; CREATE USER 'u3'@'localhost' IDENTIFIED WITH 'caching_sha2_password' DEFAULT ROLE `r1`@`%`
201+
slave-bin.000001 # Query # # use `test`; ALTER USER u2@localhost DEFAULT ROLE NONE
202+
slave-bin.000001 # Query # # use `test`; ALTER USER u2@localhost DEFAULT ROLE r1
203+
slave-bin.000001 # Query # # use `test`; GRANT r2 TO u3@localhost
204+
slave-bin.000001 # Query # # use `test`; ALTER USER u3@localhost DEFAULT ROLE ALL
205+
slave-bin.000001 # Query # # use `test`; ALTER USER u3@localhost DEFAULT ROLE r2
118206
slave-bin.000001 # Query # # use `test`; DROP ROLE r1, r2, r3,r4
119-
slave-bin.000001 # Query # # use `test`; DROP USER u1@localhost
207+
slave-bin.000001 # Query # # use `test`; DROP USER u1@localhost, u2@localhost, u3@localhost
120208
include/stop_slave.inc
121209
CHANGE MASTER TO MASTER_USER='root';
122210
Warnings:

Diff for: mysql-test/suite/rpl/t/rpl_roles.test

+42-1
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,51 @@ SELECT * FROM mysql.role_edges;
8585
START SLAVE IO_THREAD;
8686
--source include/wait_for_slave_io_to_start.inc
8787

88+
--echo
89+
--echo # Verify if 'DEFAULT ROLE' clause is bin-logged.
90+
--echo
91+
--enable_connect_log
92+
--source include/rpl_connection_master.inc
93+
CREATE USER u2@localhost DEFAULT ROLE r1, r2;
94+
CREATE USER u3@localhost DEFAULT ROLE r1;
95+
--echo
96+
SHOW GRANTS FOR u2@localhost;
97+
--echo
98+
SHOW GRANTS FOR u3@localhost;
99+
--source include/sync_slave_sql_with_master.inc
100+
# Check if roles are granted to the users on slave
101+
SHOW GRANTS FOR u2@localhost;
102+
SHOW GRANTS FOR u3@localhost;
103+
--echo
104+
SHOW CREATE USER u2@localhost;
105+
SHOW CREATE USER u3@localhost;
106+
--source include/rpl_connection_master.inc
107+
--echo
108+
ALTER USER u2@localhost DEFAULT ROLE NONE;
109+
SHOW GRANTS FOR u3@localhost;
110+
ALTER USER u2@localhost DEFAULT ROLE r1;
111+
GRANT r2 TO u3@localhost;
112+
ALTER USER u3@localhost DEFAULT ROLE ALL;
113+
SHOW GRANTS FOR u3@localhost;
114+
ALTER USER u3@localhost DEFAULT ROLE r2;
115+
# Now, u2 and u3 should have only one role on master
116+
SHOW GRANTS FOR u2@localhost;
117+
SHOW GRANTS FOR u3@localhost;
118+
--echo
119+
--source include/sync_slave_sql_with_master.inc
120+
# u2 and u3 should have only one role on slave as well
121+
SHOW GRANTS FOR u2@localhost;
122+
SHOW GRANTS FOR u3@localhost;
123+
--echo
124+
SHOW CREATE USER u2@localhost;
125+
SHOW CREATE USER u3@localhost;
126+
--disable_connect_log
127+
128+
--echo
88129
--echo # Cleanup Statement
89130
--source include/rpl_connection_master.inc
90131
DROP ROLE r1, r2, r3,r4;
91-
DROP USER u1@localhost;
132+
DROP USER u1@localhost, u2@localhost, u3@localhost;
92133
--source include/sync_slave_sql_with_master.inc
93134
SELECT * FROM mysql.default_roles;
94135
SELECT * FROM mysql.role_edges;

Diff for: sql/auth/sql_user.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2141,7 +2141,7 @@ bool mysql_create_user(THD *thd, List<LEX_USER> &list, bool if_not_exists,
21412141
fail the statement. If the role exists but isn't granted, this statement
21422142
performs an implicit GRANT.
21432143
*/
2144-
if (thd->lex->default_roles != 0 &&
2144+
if (thd->lex->default_roles != nullptr &&
21452145
thd->lex->sql_command == SQLCOM_CREATE_USER) {
21462146
List_of_auth_id_refs default_roles;
21472147
List_iterator<LEX_USER> role_it(*(thd->lex->default_roles));

Diff for: sql/sql_rewrite.cc

+23-27
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ Rewriter_user::Rewriter_user(THD *thd, Consumer_type type)
386386
bool Rewriter_user::rewrite() const {
387387
LEX *lex = m_thd->lex;
388388
String *rlb = &m_thd->rewritten_query;
389-
389+
rewrite_users(lex, rlb);
390+
rewrite_default_roles(lex, rlb);
390391
rewrite_ssl_properties(lex, rlb);
391392
rewrite_user_resources(lex, rlb);
392393
rewrite_password_expired(lex, rlb);
@@ -615,6 +616,27 @@ void Rewriter_user::rewrite_users(LEX *lex, String *str) const {
615616
}
616617
}
617618

619+
/**
620+
Append the DEFAULT ROLE clause for users iff it is specified
621+
622+
@param [in] lex LEX struct to check if clause is specified
623+
@param [in, out] str The string in which clause is suffixed
624+
*/
625+
void Rewriter_user::rewrite_default_roles(const LEX *lex, String *str) const {
626+
bool comma = false;
627+
if (lex->default_roles && lex->default_roles->elements > 0) {
628+
str->append(" DEFAULT ROLE ");
629+
lex->default_roles->sort(&lex_user_comp);
630+
List_iterator<LEX_USER> role_it(*(lex->default_roles));
631+
LEX_USER *role;
632+
while ((role = role_it++)) {
633+
if (comma) str->append(',');
634+
str->append(create_authid_str_from(role).c_str());
635+
comma = true;
636+
}
637+
}
638+
}
639+
618640
Rewriter_create_user::Rewriter_create_user(THD *thd, Consumer_type type)
619641
: Rewriter_user(thd, type) {}
620642

@@ -632,7 +654,6 @@ bool Rewriter_create_user::rewrite() const {
632654
if (lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
633655
rlb->append("IF NOT EXISTS ");
634656

635-
rewrite_users(lex, rlb);
636657
parent::rewrite();
637658
return true;
638659
}
@@ -708,7 +729,6 @@ bool Rewriter_alter_user::rewrite() const {
708729

709730
if (lex->drop_if_exists) rlb->append("IF EXISTS ");
710731

711-
rewrite_users(lex, rlb);
712732
parent::rewrite();
713733
return true;
714734
}
@@ -791,12 +811,9 @@ Rewriter_show_create_user::Rewriter_show_create_user(THD *thd,
791811
@retval true the query is rewritten
792812
*/
793813
bool Rewriter_show_create_user::rewrite() const {
794-
LEX *lex = m_thd->lex;
795814
String *rlb = &m_thd->rewritten_query;
796815
rlb->mem_free();
797816
rlb->append("CREATE USER ");
798-
rewrite_users(lex, rlb);
799-
rewrite_default_roles(lex, rlb);
800817
parent::rewrite();
801818
return true;
802819
}
@@ -873,27 +890,6 @@ void Rewriter_show_create_user::append_user_auth_info(LEX_USER *user,
873890
}
874891
}
875892
}
876-
/**
877-
Append the DEFAULT ROLE clause for users iff it is specified
878-
879-
@param [in] lex LEX struct to check if clause is specified
880-
@param [in, out] str The string in which clause is suffixed
881-
*/
882-
void Rewriter_show_create_user::rewrite_default_roles(const LEX *lex,
883-
String *str) const {
884-
bool comma = false;
885-
if (lex->default_roles && lex->default_roles->elements > 0) {
886-
str->append(" DEFAULT ROLE ");
887-
lex->default_roles->sort(&lex_user_comp);
888-
List_iterator<LEX_USER> role_it(*(lex->default_roles));
889-
LEX_USER *role;
890-
while ((role = role_it++)) {
891-
if (comma) str->append(',');
892-
str->append(create_authid_str_from(role).c_str());
893-
comma = true;
894-
}
895-
}
896-
}
897893

898894
Rewriter_set::Rewriter_set(THD *thd, Consumer_type type)
899895
: I_rewriter(thd, type) {}

Diff for: sql/sql_rewrite.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ class Rewriter_user : public I_rewriter {
181181
void rewrite_password_expired(const LEX *lex, String *str) const;
182182
/* Append the PASSWORD REQUIRE CURRENT clause for users */
183183
void rewrite_password_require_current(LEX *lex, String *str) const;
184+
/* Append the DEFAULT ROLE OPTIONS clause */
185+
void rewrite_default_roles(const LEX *lex, String *str) const;
184186
};
185187
/** Rewrites the CREATE USER statement. */
186188
class Rewriter_create_user final : public Rewriter_user {
@@ -228,8 +230,6 @@ class Rewriter_show_create_user final : public Rewriter_user {
228230
String *str) const override;
229231
void rewrite_password_history(const LEX *lex, String *str) const override;
230232
void rewrite_password_reuse(const LEX *lex, String *str) const override;
231-
/* Append the DEFAULT ROLE OPTIONS clause */
232-
void rewrite_default_roles(const LEX *lex, String *str) const;
233233
Show_user_params *show_params_;
234234
};
235235
/** Rewrites the SET statement. */

0 commit comments

Comments
 (0)