23

MySQL is installed on my laptop and it works fine, except that I am allowed to log in without supplying the root password. I can also log in by supplying the root password. If the supplied password doesn't match, it denies access. The root password was changed to something of my own choosing when I originally installed MySQL. I just noticed the no-password logins today.

So, I need to stop access to the root account when a password isn't supplied. What I've tried so far is to reset the root password with:

mysqladmin -u root password TopSecretPassword

I then logged in to the console and issued:

mysql> flush privileges;  exit;

I'm still able to log in to MySQL with:

%> mysql -u  {enter}

How do I stop this behavior?

ADDITIONAL DETAILS:

%> mysql -u  {enter}

mysql>SELECT USER(), CURRENT_USER();
> root@localhost, root@localhost

mysql>SELECT COUNT(*) FROM mysql.users WHERE user='root' AND password='';
> COUNT(*)
> 0

mysql>SELECT COUNT(*) FROM mysql.users WHERE user='';
> COUNT(*)
> 0

mysql>SELECT COUNT(*) FROM mysql.users WHERE user='root';
> COUNT(*)
> 1

%> vi /etc/my.cnf
/skip-grant-tables
> E486: Pattern not found: skip-grant-tables

Whitewall
  • 597
  • 1
  • 7
  • 18
a coder
  • 7,530
  • 20
  • 84
  • 131
  • 1
    It's possible that you have user and password provided in my.cnf file and MySQL client automatically provides the password from the file, if no password is given. The user actually has a password, and that's the reason you can't find it in the user table. – Maxim Krizhanovsky Aug 24 '11 at 18:18
  • Please display this query : `SELECT user,host,password FROM mysql.user;` and place that display in your answer. Don't worry about the password. It should be MD5 encrypted. – RolandoMySQLDBA Aug 24 '11 at 18:27
  • 1
    @a coder: until SO allows [``](http://meta.stackexchange.com/questions/1777/what-html-tags-are-allowed-on-stack-overflow-server-fault-and-super-user), you can mark screen samples with `
    `. Edit your question and try it out. Code (when you have it) can be marked by indenting each line with four spaces.
    – outis Aug 24 '11 at 19:43
  • It's a little better now I think. Any input on the post content? – a coder Aug 24 '11 at 19:49
  • @Rolando: MD5 doesn't offer encryption, it's a hashing function. Moreover, MySQL has never used MD5 to hash its passwords. Posting even hashed passwords publicly is never safe. MySQL's password hashing scheme is vulnerable to rainbow tables, but even if it weren't, it would be possible to brute force. – outis Aug 26 '11 at 06:56
  • @coder: which version of the mysql server (`SELECT @@version;`) and client (`mysql -V`) are you using? `mysql -u` should result an error if you don't give a user name. Can you login if you provide the user name but no password (`mysql -u root`)? – outis Aug 26 '11 at 07:06

5 Answers5

30

Users encountering this behaviour in newer versions of MySQL/MariaDB (e.g. Debian Stretch, etc) should be aware that in the mysql.user table, there is column called 'plugin'. If the 'unix_socket' plugin is enabled, then root will be able to log in via commandline without requiring a password. Other log in mechanisms will be disabled.

To check if that's the case:

SELECT host, user, password, plugin FROM mysql.user;

which should return something like this (with unix_socket enabled):

+-----------+------+--------------------------+-------------+
| host      | user | password                 | plugin      |
+-----------+------+--------------------------+-------------+
| localhost | root | <redacted_password_hash> | unix_socket |
+-----------+------+--------------------------+-------------+

To disable that and require root to use a password:

UPDATE mysql.user SET plugin = '' WHERE user = 'root' AND host = 'localhost';
FLUSH PRIVILEGES;

Note: As noted by @marioivangf (in a comment) in newer versions of MySQL (e.g. 5.7.x) you may need to set the plugin to 'mysql_native_password' (rather than blank).

Then restart:

service mysql restart

Problem fixed!:

root@lamp ~# mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

Source: https://stackoverflow.com/a/44301734/3363571 Big thanks to @SakuraKinomoto (please go up vote his answer if you find this useful).

Jeremy Davis
  • 741
  • 10
  • 16
7

Looks like you may have one or more anonymous users.

To see them run this query:

SELECT user,host,password FROM mysql.user WHERE user='';

To see that you authenticated as such, run this:

SELECT USER(),CURRENT_USER();

This will show how you tried to login and how mysql allowed you to login.

Run these two queries:

DELETE FROM mysql.user WHERE user='';
FLUSH PRIVILEGES;

That should do it !!!

CAVEAT #1

If this does not work, check /etc/my.cnf for this option:

skip-grant-tables

If that is in my.cnf, remove it and restart mysql.

CAVEAT #2

Something else to watch out for is having multiple root users. Please run this:

SELECT user,host,password FROM mysql.user WHERE user='root';

If you defined root to have a password and still get in as root, this is indicative of having multiple root users. There may be these entries in mysql.user

  • root@localhost
  • root@127.0.0.1
  • root@'hostnameofserver'

mysql may allow authentication from any of the root users if a root user has no password. This should manifest itself when you run SELECT USER(),CURRENT_USER(); because the output of each function will show up as different.

If one root user has the MD5 password and all other root users do not, you can spread that MD5 password to the other root users as follows:

UPDATE mysql.user
SET password = 
(
    SELECT password FROM mysql.user
    WHERE user='root' AND password <> ''
)
WHERE user='root' AND password = '';
FLUSH PRIVILEGES;
Community
  • 1
  • 1
RolandoMySQLDBA
  • 43,883
  • 16
  • 91
  • 132
  • 0 rows affected. There are no anon users in mysql.user. – a coder Aug 24 '11 at 17:55
  • Please display this query : SELECT user,host,password FROM mysql.user ; and place that display in your answer. Don't worry about the password. It should be MD5 encrypted. – RolandoMySQLDBA Aug 24 '11 at 17:57
  • I've added details to my original question. – a coder Aug 24 '11 at 18:05
  • skip-grant-tables is not in my.cnf. – a coder Aug 24 '11 at 18:08
  • You should have a table called `mysql.user` NOT `mysql.users`. Please run those queries using mysql.user – RolandoMySQLDBA Aug 24 '11 at 18:17
  • that was a type-o. My apologies. I was querying mysql.user. Output of the two functions are the same: root@localhost (which has a password, and there is only one root account in the user table). – a coder Aug 24 '11 at 19:22
  • 2
    Please DON'T post the MD5 hash of your passwords on the internet. You shouldn't share any hashes, but MD5 in particular is very weak (some would say broken) and bad guys could determine the original password. – Eli Aug 24 '11 at 19:25
  • I would never post MD5 hashes, real usernames, real script names, actual IPs, or real variable names (other than what I did with root) online. Even though my system is behind a secured firewall I have to assume that firewall doesn't exist, and that someone gained access to my machine. – a coder Aug 24 '11 at 19:46
  • 3
    Realize this answer has a couple upvotes and contains useful info - however it did not address my situation. Client specified passwords defined in my.cnf files are not affected by the solution presented in this answer. See selected answer for more. – a coder Oct 04 '14 at 14:15
  • After struggling hours, this helps! Thanks mate! – Maduka Jayalath Dec 22 '15 at 03:30
  • This is the answer that I was looking for (using MariaDB 10.4.15 on Alpine 3.12). Thank you! – Krizalys Jan 09 '21 at 02:07
7

I know this question is a few months old, but I had the same issue.

In my case, it was due to the presence of a user-specific configuration file located at ~/.my.cnf that contained the user and password. In my case, cPanel created this config file.

[client]
pass="ROOT_PASSWORD_WAS_HERE!"
user=root

User-specific configuration files are a feature of MySQl, and the location of all the config files read are detailed in the documentation: http://dev.mysql.com/doc/refman/5.1/en/option-files.html.

If you're running mysql on a *nix dist, run the following command to see if you have a user-specific config file:

cat ~/.my.cnf 
coffeefiend
  • 81
  • 1
  • 2
  • 2
    I eventually worked around the issue by changing the root password to something else. Now that you replied, I checked and found the .my.cnf file in my user's home folder, and it did contain the root user/pass. That was the problem all along. Marking yours as the answer - thanks! – a coder Mar 13 '12 at 12:44
  • If you need a password in a file, it is better to use mysql_config_editor to create a ~/.mylogin.cnf containing user-password-host entries, with password encrypted. when entry can then be selected using --login-path option from command line. See bigger discussion in http://stackoverflow.com/questions/20751352/suppress-warning-messages-using-mysql-from-within-terminal-but-password-written – anthony Sep 02 '16 at 06:47
  • I also install a mysql 8 server and was not able to disable password less root login. Usually you could use the script mysql_secure_installation. But the script is not suitable for me. I found out, that per default on ubuntu 20.04 auth_socket plugin is used to identify user. – perber Mar 14 '21 at 16:19
6

Current answers are no longer ok for MySQL 8. Indeed:

In MySQL 8.0, caching_sha2_password is the default authentication plugin rather than mysql_native_password, which was the default in MySQL 5.7.

So the solution is to run mysql, then

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'yourpasswd'; EXIT;

and then mysql -uroot -p to try if it worked. (I don't remember if service mysql restart was necessary).

If you already applied the technique from the main answer of this actual question, here is how to revert it for MySQL 8:

UPDATE mysql.user SET plugin = 'caching_sha2_password' WHERE user = 'root' AND host = 'localhost'; 
FLUSH PRIVILEGES;
Basj
  • 41,386
  • 99
  • 383
  • 673
4

If anyone comes across this post while searching how to change root password and stop root-logins without password, Percona saved my ass once again:

https://www.percona.com/blog/2016/03/16/change-user-password-in-mysql-5-7-with-plugin-auth_socket/

basically the command that worked for me:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'test';

SomeOne_1
  • 808
  • 10
  • 10