Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-20756

Default user name for libmysqlclient is empty

    XMLWordPrintable

    Details

      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

            Activity

              People

              Assignee:
              holyfoot Alexey Botchkov
              Reporter:
              GeoffMontee Geoff Montee
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated: