Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.2.27, 10.3.18, 10.4.8
-
None
Description
This bug is similar to CONC-441, but this bug applies to tools that use the built-in libmysqlclient, while the other bug applies to clients that use MariaDB Connector/C.
For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user.
From the MySQL documentation:
On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only.
https://dev.mysql.com/doc/refman/5.7/en/user-names.html
And from the MariaDB documentation:
-u, --user=name User for login, if not current user.
https://mariadb.com/kb/en/library/mysql-command-line-client/
However, at the moment, this does not happen. Instead, an empty user name (i.e. '') is used by default.
How the Default User Name is Determined
libmysqlclient determines the default user name by calling read_user_name() to get the current user. Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default:
https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40
The embedded server (libmysqld) has a "more correct" version of this function:
https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423
And so does MariaDB Connector/C:
https://github.com/MariaDB/mariadb-connector-c/blob/v3.1.3/libmariadb/mariadb_lib.c#L498
read_user_name() is called in send_client_reply_packet():
https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426
The "more correct" version of the read_user_name() function gets the user name by checking the following items in the following order:
- If geteuid() returns 0, then root is used.
- If getlogin() is not NULL, then its return value is used.
- If getpwuid(geteuid()) is not NULL, then its return value is used.
- If the USER environment variable is set, then its assigned value is used.
- If the LOGNAME environment variable is set, then its assigned value is used.
- If the LOGIN environment variable is set, then its assigned value is used.
However, even this order can cause unexpected results in some cases. See CONC-441 for more details about that.
How to Reproduce
mariabackup still seems to use libmysqlclient, according to gdb output, which shows that it calls the versions of mysql_real_connect() and run_plugin_auth() defined in sql-common/client.c:
(gdb) where
|
#0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6
|
#1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6
|
#2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6
|
#3 0x00007fb16193754e in getc () from /lib64/libc.so.6
|
#4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68
|
#5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162
|
#6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024)
|
at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106
|
#7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159
|
#8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21,
|
data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0)
|
at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767
|
#9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0)
|
at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363
|
#10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148
|
#11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830
|
#12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294
|
#13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137
|
Let's run mariabackup without providing a user name:
$ mkdir /tmp/backup
|
$ mariabackup --backup --target-dir=/tmp/backup
|
[00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set
|
Password:
|
[00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO).
|
Authentication will fail, because the user name is empty.
The error message sent by the server references the empty user name:
Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO).
|
And the error log on the server shows the same thing:
2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO)
|
Suggested Fix
libmysqlclient's version of the read_user_name() function should be fixed to use the effective user as the default user.
Attachments
Issue Links
- relates to
-
CONC-441 Default user name for C/C is wrong if login user is different from effective user
-
- Closed
-
Activity
Description |
This bug is similar to For example, {{mariabackup}} seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. However, at the moment, the wrong user name is used by default in some cases. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ libmysqlclient even has a useful function called {{read_user_name()}} that is intended to handle this exact case: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 However, it appears that this function may be returning the wrong value. We can reproduce this by executing a client and not providing a user name. First, let's check which user account we are: {noformat} $ whoami mysql $ printenv USER mysql 2$ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) {noformat} And then let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references this incorrect empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
This bug is similar to For example, {{mariabackup}} seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. However, at the moment, the wrong user name is used by default in some cases. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ libmysqlclient even has a useful function called {{read_user_name()}} that is intended to handle this exact case: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 However, it appears that this function may be returning the wrong value. We can reproduce this by executing a client and not providing a user name. First, let's check which user account we are: {noformat} $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) {noformat} And then let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references this incorrect empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
Assignee | Sergei Golubchik [ serg ] | Alexey Botchkov [ holyfoot ] |
Description |
This bug is similar to For example, {{mariabackup}} seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. However, at the moment, the wrong user name is used by default in some cases. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ libmysqlclient even has a useful function called {{read_user_name()}} that is intended to handle this exact case: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 However, it appears that this function may be returning the wrong value. We can reproduce this by executing a client and not providing a user name. First, let's check which user account we are: {noformat} $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) {noformat} And then let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references this incorrect empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
This bug is similar to For example, {{mariabackup}} seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. libmysqlclient calls {{read_user_name()}} to get the current user: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. This order can cause unexpected results in some cases. For example, let's say that we change users by doing something like this: {noformat} $ whoami ec2-user $ sudo -u mysql bash $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) $ cat /proc/self/loginuid 1000 $ id 1000 uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user),4(adm),10(wheel),190(systemd-journal) {noformat} In this case, our effective user is {{mysql}}, but the login user is still {{ec2-user}}. Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
Summary | Default user name for libmysqlclient is wrong | Default user name for libmysqlclient is wrong if login user is different from effective user |
Description |
This bug is similar to For example, {{mariabackup}} seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. libmysqlclient calls {{read_user_name()}} to get the current user: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. This order can cause unexpected results in some cases. For example, let's say that we change users by doing something like this: {noformat} $ whoami ec2-user $ sudo -u mysql bash $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) $ cat /proc/self/loginuid 1000 $ id 1000 uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user),4(adm),10(wheel),190(systemd-journal) {noformat} In this case, our effective user is {{mysql}}, but the login user is still {{ec2-user}}. Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. This order can cause unexpected results in some cases. h2. How to Reproduce For example, let's say that we change users by doing something like this: {noformat} $ whoami ec2-user $ sudo -u mysql bash $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) $ cat /proc/self/loginuid 1000 $ id 1000 uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user),4(adm),10(wheel),190(systemd-journal) {noformat} In this case, our effective user is {{mysql}}, but the login user is still {{ec2-user}}. {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} It is still unclear to me why {{mariabackup}} is using an empty string for the user name, rather than using the login user. |
Description |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 It is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. This order can cause unexpected results in some cases. h2. How to Reproduce For example, let's say that we change users by doing something like this: {noformat} $ whoami ec2-user $ sudo -u mysql bash $ whoami mysql $ printenv USER mysql $ printenv LOGNAME mysql $ printenv LOGIN $ id uid=997(mysql) gid=994(mysql) groups=994(mysql),1005(shadow) $ cat /proc/self/loginuid 1000 $ id 1000 uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user),4(adm),10(wheel),190(systemd-journal) {noformat} In this case, our effective user is {{mysql}}, but the login user is still {{ec2-user}}. {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} It is still unclear to me why {{mariabackup}} is using an empty string for the user name, rather than using the login user. |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
Summary | Default user name for libmysqlclient is wrong if login user is different from effective user | Default user name for libmysqlclient is empty |
Description |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} h2. Suggested Fix libmysqlclient's version of the {{read_user_name()}} function should be fixed to use the effective user as the default user. |
Description |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} h2. Suggested Fix libmysqlclient's version of the {{read_user_name()}} function should be fixed to use the effective user as the default user. |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: https://github.com/MariaDB/mariadb-connector-c/blob/v3.1.3/libmariadb/mariadb_lib.c#L498 {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} h2. Suggested Fix libmysqlclient's version of the {{read_user_name()}} function should be fixed to use the effective user as the default user. |
Description |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, the wrong user name is used by default if the login user is different from the effective user. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user: Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: https://github.com/MariaDB/mariadb-connector-c/blob/v3.1.3/libmariadb/mariadb_lib.c#L498 {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is wrong. The error message sent by the server references an empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} h2. Suggested Fix libmysqlclient's version of the {{read_user_name()}} function should be fixed to use the effective user as the default user. |
This bug is similar to For command-line tools, if no user name is provided, then the default behavior is supposed to be that the client will use the name of the current Unix user. From the MySQL documentation: {quote} On Unix, most MySQL clients by default try to log in using the current Unix user name as the MySQL user name, but that is for convenience only. {quote} https://dev.mysql.com/doc/refman/5.7/en/user-names.html And from the MariaDB documentation: {quote} -u, --user=name User for login, if not current user. {quote} https://mariadb.com/kb/en/library/mysql-command-line-client/ However, at the moment, this does not happen. Instead, an empty user name (i.e. {{''}}) is used by default. h2. How the Default User Name is Determined libmysqlclient determines the default user name by calling {{read_user_name()}} to get the current user. Unfortunately, libmysqlclient's version of this function just sets the user name to the empty string by default: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql/client_settings.h#L40 The embedded server (libmysqld) has a "more correct" version of this function: https://github.com/MariaDB/server/blob/mariadb-10.2.27/libmysqld/libmysql.c#L423 And so does MariaDB Connector/C: https://github.com/MariaDB/mariadb-connector-c/blob/v3.1.3/libmariadb/mariadb_lib.c#L498 {{read_user_name()}} is called in {{send_client_reply_packet()}}: https://github.com/MariaDB/server/blob/mariadb-10.2.27/sql-common/client.c#L2426 The "more correct" version of the {{read_user_name()}} function gets the user name by checking the following items in the following order: * If {{geteuid()}} returns {{0}}, then {{root}} is used. * If {{getlogin()}} is not {{NULL}}, then its return value is used. * If {{getpwuid(geteuid())}} is not {{NULL}}, then its return value is used. * If the {{USER}} environment variable is set, then its assigned value is used. * If the {{LOGNAME}} environment variable is set, then its assigned value is used. * If the {{LOGIN}} environment variable is set, then its assigned value is used. However, even this order can cause unexpected results in some cases. See h2. How to Reproduce {{mariabackup}} still seems to use libmysqlclient, according to {{gdb}} output, which shows that it calls the versions of {{mysql_real_connect()}} and {{run_plugin_auth()}} defined in {{sql-common/client.c}}: {noformat} (gdb) where #0 0x00007fb1619aef70 in __read_nocancel () from /lib64/libc.so.6 #1 0x00007fb16193bb14 in __GI__IO_file_underflow () from /lib64/libc.so.6 #2 0x00007fb16193cce2 in __GI__IO_default_uflow () from /lib64/libc.so.6 #3 0x00007fb16193754e in getc () from /lib64/libc.so.6 #4 0x00007fb15e94afe0 in get_password (length=1023, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., file=0x7fb161c87640 <_IO_2_1_stdin_>) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:68 #5 get_tty_password (prompt=prompt@entry=0x7fb15e94b0d0 "", buffer=buffer@entry=0x7ffed185a030 '\377' <repeats 200 times>..., length=length@entry=1023) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/libmariadb/get_password.c:162 #6 0x00007fb15e94aeac in auth_dialog_native_prompt (mysql=<optimized out>, type=2, prompt=<optimized out>, buffer=0x7ffed185a030 '\377' <repeats 200 times>..., buffer_len=1024) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:106 #7 0x00007fb15e94ad1d in auth_dialog_open (vio=0x7ffed185a490, mysql=0x5629645279d8) at /usr/src/debug/MariaDB-10.3.18/src_0/libmariadb/plugins/auth/dialog.c:159 #8 0x000056296166f10e in run_plugin_auth (mysql=mysql@entry=0x5629645279d8, data=<optimized out>, data@entry=0x56296452c13a "_password", data_len=<optimized out>, data_len@entry=21, data_plugin=data_plugin@entry=0x56296452c14f "\f_client_name\blibmysql\004_pid\004\065\067\070\065\017_client_version\a10.3.18\f_server_host\tlocalhost\t_platform\006x86_64", db=db@entry=0x0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:2767 #9 0x00005629616710db in mysql_real_connect (mysql=0x5629645279d8, host=<optimized out>, user=<optimized out>, passwd=<optimized out>, db=<optimized out>, port=<optimized out>, unix_socket=<optimized out>, client_flag=0) at /usr/src/debug/MariaDB-10.3.18/src_0/sql-common/client.c:3363 #10 0x0000562961656766 in xb_mysql_connect () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/backup_mysql.cc:148 #11 0x0000562961641c66 in xb_init () at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:5830 #12 0x00005629616423f4 in main_low (argv=0x562964526d90) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6294 #13 0x00005629616218e5 in main (argc=9, argv=0x7ffed185bda0) at /usr/src/debug/MariaDB-10.3.18/src_0/extra/mariabackup/xtrabackup.cc:6137 {noformat} Let's run {{mariabackup}} without providing a user name: {noformat} $ mkdir /tmp/backup $ mariabackup --backup --target-dir=/tmp/backup [00] 2019-10-05 01:04:56 Connecting to MySQL server host: localhost, user: not set, password: not set, port: not set, socket: not set Password: [00] 2019-10-05 01:05:02 Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} Authentication will fail, because the user name is empty. The error message sent by the server references the empty user name: {noformat} Failed to connect to MySQL server: Access denied for user ''@'localhost' (using password: NO). {noformat} And the error log on the server shows the same thing: {noformat} 2019-10-05 1:05:02 32 [Warning] Access denied for user ''@'localhost' (using password: NO) {noformat} h2. Suggested Fix libmysqlclient's version of the {{read_user_name()}} function should be fixed to use the effective user as the default user. |
Workflow | MariaDB v3 [ 100195 ] | MariaDB v4 [ 141579 ] |
Fix Version/s | 10.2 [ 14601 ] |
Fix Version/s | 10.3 [ 22126 ] |