Skip to content
/ server Public

Commit 43678d9

Browse files
committed
MDEV-38550: add LENENC support for COM_CHANGE_USER
Add support for CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA in COM_CHANGE_USER packet parsing, allowing passwords >= 251 bytes. Changes: - Server: parse_com_change_user_packet() now handles LENENC-encoded password length when CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA is set - Server: fix db pointer calculation for old protocol without CLIENT_SECURE_CONNECTION (need +1 to skip null terminator) - Add regression test for COM_CHANGE_USER with long passwords
1 parent 7fed014 commit 43678d9

File tree

3 files changed

+106
-7
lines changed

3 files changed

+106
-7
lines changed

mysql-test/suite/plugins/r/mdev38431.result

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,46 @@ GRANT ALL ON *.* TO verylonguser;
2929
db
3030
mdev38431_db
3131
#
32+
# Test 4: COM_CHANGE_USER with short password
33+
# Verify mysql_change_user() works correctly with database parameter
34+
#
35+
CREATE USER changeusertest IDENTIFIED VIA cleartext_plugin_server USING 'changepwd';
36+
GRANT ALL ON *.* TO changeusertest;
37+
SELECT DATABASE() AS db;
38+
db
39+
mdev38431_db
40+
#
41+
# Test 5: COM_CHANGE_USER with long password (260 bytes)
42+
# This works because auth plugin switching sends password in a SECOND packet
43+
# (via ma_net_write), bypassing the 255-byte limit in send_change_user_packet()
44+
#
45+
# Note: If connection used cleartext directly (no auth switch), it would fail
46+
# due to libmariadb's 255-byte limit in send_change_user_packet()
47+
#
48+
CREATE USER changeuserlongpwd IDENTIFIED VIA cleartext_plugin_server USING 'cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc';
49+
GRANT ALL ON *.* TO changeuserlongpwd;
50+
SELECT DATABASE() AS db;
51+
db
52+
mdev38431_db
53+
#
54+
# Test 6: COM_CHANGE_USER with long password - no auth switch
55+
# Connection uses cleartext directly, password goes in first packet
56+
# Requires LENENC support in both client and server for COM_CHANGE_USER
57+
#
58+
connect cleartext_con, 127.0.0.1, changeuserlongpwd, $change_pwd, mdev38431_db, $MASTER_MYPORT, , , mysql_clear_password;
59+
SELECT DATABASE() AS db;
60+
db
61+
mdev38431_db
62+
SELECT CURRENT_USER() AS user;
63+
user
64+
changeuserlongpwd@%
65+
SELECT DATABASE() AS db;
66+
db
67+
mdev38431_db
68+
connection default;
69+
disconnect cleartext_con;
70+
#
3271
# Cleanup
3372
#
34-
DROP USER shortuser, longuser, verylonguser;
73+
DROP USER shortuser, longuser, verylonguser, changeusertest, changeuserlongpwd;
3574
DROP DATABASE mdev38431_db;

mysql-test/suite/plugins/t/mdev38431.test

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,49 @@ GRANT ALL ON *.* TO verylonguser;
5151

5252
--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u verylonguser -p"$very_long_pwd" --database=mdev38431_db -e "SELECT DATABASE() AS db"
5353

54+
--echo #
55+
--echo # Test 4: COM_CHANGE_USER with short password
56+
--echo # Verify mysql_change_user() works correctly with database parameter
57+
--echo #
58+
CREATE USER changeusertest IDENTIFIED VIA cleartext_plugin_server USING 'changepwd';
59+
GRANT ALL ON *.* TO changeusertest;
60+
61+
# Use change_user command to switch user with password and database
62+
change_user changeusertest,changepwd,mdev38431_db;
63+
SELECT DATABASE() AS db;
64+
change_user root;
65+
66+
--echo #
67+
--echo # Test 5: COM_CHANGE_USER with long password (260 bytes)
68+
--echo # This works because auth plugin switching sends password in a SECOND packet
69+
--echo # (via ma_net_write), bypassing the 255-byte limit in send_change_user_packet()
70+
--echo #
71+
--echo # Note: If connection used cleartext directly (no auth switch), it would fail
72+
--echo # due to libmariadb's 255-byte limit in send_change_user_packet()
73+
--echo #
74+
--let $change_pwd=`SELECT REPEAT('c', 260)`
75+
eval CREATE USER changeuserlongpwd IDENTIFIED VIA cleartext_plugin_server USING '$change_pwd';
76+
GRANT ALL ON *.* TO changeuserlongpwd;
77+
78+
change_user changeuserlongpwd,$change_pwd,mdev38431_db;
79+
SELECT DATABASE() AS db;
80+
change_user root;
81+
82+
--echo #
83+
--echo # Test 6: COM_CHANGE_USER with long password - no auth switch
84+
--echo # Connection uses cleartext directly, password goes in first packet
85+
--echo # Requires LENENC support in both client and server for COM_CHANGE_USER
86+
--echo #
87+
--connect (cleartext_con, 127.0.0.1, changeuserlongpwd, $change_pwd, mdev38431_db, $MASTER_MYPORT, , , mysql_clear_password)
88+
SELECT DATABASE() AS db;
89+
SELECT CURRENT_USER() AS user;
90+
change_user changeuserlongpwd,$change_pwd,mdev38431_db;
91+
SELECT DATABASE() AS db;
92+
--connection default
93+
--disconnect cleartext_con
94+
5495
--echo #
5596
--echo # Cleanup
5697
--echo #
57-
DROP USER shortuser, longuser, verylonguser;
98+
DROP USER shortuser, longuser, verylonguser, changeusertest, changeuserlongpwd;
5899
DROP DATABASE mdev38431_db;
59-
# Note: Do not uninstall cleartext_plugin_server as it was pre-loaded by MTR

sql/sql_acl.cc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13613,10 +13613,30 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
1361313613
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
1361413614
*passwd > 127 and become 2**32-127+ after casting to uint.
1361513615
*/
13616-
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
13617-
(uchar) (*passwd++) : (uint)strlen(passwd));
13618-
13619-
db+= passwd_len + 1;
13616+
size_t passwd_len;
13617+
if (!(thd->client_capabilities & CLIENT_SECURE_CONNECTION))
13618+
{
13619+
passwd_len= strlen(passwd);
13620+
db= passwd + passwd_len + 1; /* +1 to skip null terminator */
13621+
}
13622+
else if (!(thd->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA))
13623+
{
13624+
passwd_len= (uchar)(*passwd++);
13625+
db= passwd + passwd_len;
13626+
}
13627+
else
13628+
{
13629+
ulonglong len= safe_net_field_length_ll((uchar**)&passwd,
13630+
end - passwd);
13631+
if (len > packet_length)
13632+
{
13633+
my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR),
13634+
MYF(0));
13635+
DBUG_RETURN(1);
13636+
}
13637+
passwd_len= (size_t)len;
13638+
db= passwd + passwd_len;
13639+
}
1362013640
/*
1362113641
Database name is always NUL-terminated, so in case of empty database
1362213642
the packet must contain at least the trailing '\0'.

0 commit comments

Comments
 (0)