MySQL Workbench - 'Access Denied' without port forwarding - mysql

I'm running mysql workbench on my 2011 macbook pro. I use it to connect to a mysql database on a remote ubuntu server. I was able to connect no problem from my macbook pro to the mysql database on the remote server until I had to do a hard reboot on my mac. After that I would get the error below.
However once I port forwarded with the command below on my mac for the specified user it connects to the database on the remote server with mysql workbench no problem. What does this tell us about the issue connecting from my mac to the database on the remote server? I would rather not portforward for every user I want to login with from my mac. Does anyone have a suggestion how to fix this?
command:
ssh -N -f -L localhost:3306:localhost:3306 username#192.168.50.122
previous error:
Failed to connect to MySQL at xxx.xxx.xx.xxx:3306 with user username Access denied for user 'username'#'xxx.xxx.xx.xxx' (using password: YES)
Update:
When I try looking up the grants for the username with the ip address I'm not finding them and getting the error message below. When I try to look up the sql_show_grants table I get another error message. When I try looking up the same username with '%' I'm finding all the grants below. So does it make sense that the user still can't connect from any ip? Is there something else I need to do?
show grants for 'username'#'xxx.xxx.xx.xxx';
ERROR 1141 (42000): There is no such grant defined for user 'username' on host 'xxx.xxx.xx.xxx'
SELECT sql_grants FROM common_schema.sql_show_grants;
ERROR 1049 (42000): Unknown database 'common_schema'
show grants for 'username'#'%';
+--------------------------------------------------------------+
| Grants for username#% |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO `username`#`%` |
| GRANT ALL PRIVILEGES ON `finances`.* TO `username`#`%` |
| GRANT ALL PRIVILEGES ON `geographical`.* TO `username`#`%` |
| GRANT ALL PRIVILEGES ON `realestate`.* TO `username`#`%` |
| GRANT ALL PRIVILEGES ON `sandbox`.* TO `username`#`%` |
| GRANT ALL PRIVILEGES ON `stocks`.* TO `username`#`%` |
+--------------------------------------------------------------+

The account you are trying to connect with does not have permission to access the server from your clients IP address. If you use SSH port forwarding, you are being connected from localhost (from the server to the server), and hence get a different permission scheme applied.
On the MySQL server, start a mysql shell as an administrator, and run
SHOW GRANTS FOR 'username'#'xxx.xxx.xx.xxx'
(replacing 'username'#'xxx.xxx.xx.xxx' with what it showed you in the error message).
If it does not show any results, your user does not have any permissions from the respective IP address, and you would need to alter or create it.
If it does show permissions, make sure SELECT is underneath them.
If you cannot locate your user, attempt to view all grants:
SELECT sql_grants FROM common_schema.sql_show_grants;
If you say it worked before, it is possible that the original user was added with a dynamic IP address, which changed after the reboot of your client.
If this is the case, and the last statement shows your user with a wrong IP address, use the following to update it:
RENAME USER 'username'#'ipaddress1' TO 'username'#'ipaddress2';
You might want to consider using '%' instead of 'ipaddress2', if you are using dynamic IP addresses and want to grant the user access from all source addresses. Whether this is a security issue, depends on your environment.

Related

AWS MySQL RDS can't create new DB user while having ALL PRIVILEGES

Using my Ubuntu terminal mysql, I have successfully connected to AWS MySQL RDS instance using my master_account account and yet, when I run the standard
CREATE USER 'new_user'#'%' IDENTIFIED BY '12345';
I'm getting the typical ERROR 1227 (42000): Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation error message.
When I run SHOW GRANTS FOR 'master_account', I get:
+-----------------------------+
| Grants for master_account#%
|
+-----------------------------+
| GRANT USAGE ON *.* TO 'master_account'#'%'
|
| GRANT ALL PRIVILEGES ON `dbname`.* TO
'master_account'#'%' WITH GRANT OPTION |
+----------------------+
I must be doing something wrong, but I'm not sure what the issue is as the 'master_account has all privileges, and therefore, I should be able to create new users?
BTW, this RDS instance has been PROMOTED from a read replica for development purposes. Would that be the reason?
So it turned out that while I was logged in with a USERNAME that has all the privileges to manage this specific database, I was not logged in with the AWS MASTER USERNAME that has the privileges to manage DB users.
BTW the MASTER USERNAME is listed in your RDS console under the Configuration tab.

MySQL Access denied for user Error when application hosted on different server from DB

I have 2 different server, one server (server1) hosts the perl application and the other server (server2) hosts the MYSQL DB (DBNAME= hpdb).
The perl application on server1 is suppose to get mysql results from server2. When I try to do this I get the error message Access denied for user 'userrego'#'server1.domain.com' (using password: YES).
However, when I host the perl application on server2, the application works as expected.
I tried to GRANT ALL PRIVILEGES ON hpdb.* TO 'userrego'#'server1.domain.com' but still couldn't get it to work.
mysql> SHOW GRANTS FOR 'userrego'#'server1.domain.com';
+---------------------------------------------------------------------+
| Grants for userrego#server1.domain.com |
+---------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'userrego'#'server1.domain.com' |
| GRANT ALL PRIVILEGES ON `hpdb`.* TO 'userrego'#'server1.domain.com' |
+---------------------------------------------------------------------+
2 rows in set (0.01 sec)
There are a couple of things you should please verify:
Please make sure skip-networking in my.cnf is disabled. If bind-address is set, make sure it is appropriately set, depending on the network config of server2. Do a service mysql restart if you changed anything.
If it still does not work I would verify that the password and source ip is not the issue by (if possible) creating another user to connect with - you can always remove it after testing. Issue a grant with:
GRANT ALL PRIVILEGES ON hpdb.* TO 'userregotest'#'%' IDENTIFIED BY 'xxxxxx'
With that you will be sure of the correct password and that the source ip address is not the issue since any source address will be able to connect.
If none of this works, we might need to inspect things a bit closer.

How to create user with MySQL Workbench when username is an e-mail address?

From the MySQL command line, I can execute the following SQL to create a user whose username is his e-mail address:
CREATE USER 'julio#gmail.com'#'%'
IDENTIFIED BY 'password';
However, I need to create the users from the Schema Privileges section of the MySQL Workbench and then forward engineer them into a database.
I am using Workbench 6.1 Community Edition and MySQL Server 5.6. I have tried several different formats for the usernames but all of them create the wrong user or fail when I try to forward engineer them.
julio#gmail.com - makes the user julio at the host gmail.com
'julio#gmail.com' - attempts to make the user ''julio'#'gmail.com'' which simply fails
'julio#gmail.com'#'%' - also fails
How can I create a user from the MySQL Workbench when the user name is an e-mail address?
I find no problem using MySQL Workbench 6.1.6 to create a user with an # character.
I can subsequently query mysql.user and see the user name as I entered it.
mysql> select host, user from mysql.user where user like 'j%';
+------+-----------------+
| host | user |
+------+-----------------+
| % | julio#gmail.com |
+------+-----------------+
I can grant privileges to the user.
mysql> grant all privileges on test.* to 'julio#gmail.com'#'%';
I can also connect with the command-line client:
$ mysql -h 127.0.0.1 -u julio#gmail.com -p
Here's a screen shot of creating the user:

MySql 'INTO OUTFILE ' from MySql commandline

Here is my(dummy) query, which runs fine on the machine where mysql-server is hosted BUT fails on another machine, when I connect using the same user. (root)
SELECT *
FROM data
INTO OUTFILE '/tmp/dump.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Error I get on mysql> prompt :
ERROR 1045 (28000): Access denied for user 'root'#'foobar.com' (using password: YES)
I have granted "ALL PRIVILEGES" to 'root'#'%'
Am I missing something ?
Adding some more data :
Following query works fine , which means the user is connected to right database and has read permission at the least.
SELECT *
FROM data limit 5;
I did do a server side FLUSH privileges;
How much time I am supposed to wait ? Any ballpark number ? I doubt it would be longer than few minutes.
Make sure you have created an account 'root'#'foobar.com' on the server. You can check it like this:
use information_schema;
select user, host from user;
mysql> select user, host from user;
+------+-----------+
| user | host |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1 |
| root | localhost |
+------+-----------+
3 rows in set (0.00 sec)
You might also have an issue mixing wild card users (%) and users with explicit host, if both match mysql should deny access.
After looking at the error number ERROR 1045 (28000) following are the possible reasons why you are getting this error. Assuming user here is mysql user but not Linux/Windows user of the machine
You are trying to connect to a different TCP/IP port from which the server is listening. Use --port option to correct this.
Check the server configuration whether it is allowing network connection if you are trying to connect from a remote machine. Check --skip-networking option in configuration file
If bind-address=127.0.0.1 then mysql server will listen only the local connections and it will not listen to remote connections
May be a firewall is blocking your connection. To verify this Telnet or ssh to the server from a remote machine. As shown below.
$telnet 192.168.1.1 3306
In the above query you are trying to write a csv file from the query. Make sure that you have the appropriate user permissions to write the file.
As you said you have already did FLUSH PREVILEGES. Try to use the mysqladmin flush-previleges from the root prompt for you machine.
I have given some ideas to debug your problem. Probably above solutions will help you in solving your problem. Cheers

User can't access a database

In my PHP script, I'm accessing two databases db1 and db2. I have a user myuser#localhost that can access db1 but can't access db2.
When selecting from mysql.user table, there is one record and the host for that user is a wildcard %, there isn't a localhost host.
SELECT user, host FROM mysql.user WHERE user = 'myuser'; give me:
+------------+------+
| user | host |
+------------+------+
| myuser | % |
+------------+------+
1 row in set (0.00 sec)
Looking at GRANTS for that user, I see same permissions for db1 as for db2
SHOW GRANTS FOR 'myuser'#'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for myuser#% |
+-----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'%' |
| GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'%' |
+-----------------------------------------------------------------------------------------------------------+
In my PHP script I can access db1 however I get an error: INSERT command denied to user 'myuser'#'localhost' for table 'HISTORY'.
It says user is myuser#localhost and people suggested adding permission for myuser#localhost however, why does this user have access to db1 and not to db2?
localhost does not match % in MySQL. It seems like it should, but in fact it doesn't. You'd have to separately grant privileges to user#localhost, both for the USAGE privilege, and for the privileges on each database.
Or you can connect as user#127.0.0.1 which does match %. Using the IP address for localhost seems like it should work identically to localhost, but it doesn't. You need to have two lines in the mysql.user table (and also in the mysql.db table in your case) to enable both.
To demonstrate the difference between localhost and 127.0.0.1:
Connecting as mysql -h localhost uses the UNIX socket interface, and bypasses TCP/IP. This can be slightly better for performance, but it has the effect on grant matching described above.
You can force a local TCP/IP connection by connecting as mysql -h 127.0.0.1. Then it will pick up the grants you have made to myuser#%.
So to get the same user, password, and privileges for both the socket interface and the TCP/IP interface, you'd need to run all of the following statements:
GRANT USAGE ON *.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT USAGE ON *.* TO 'myuser'#'localhost' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'%'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'localhost'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'%'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'localhost'
If you haven't done that already, you need to run flush privileges so that mysql knows there was a change and reloads the privileges table for users:
FLUSH PRIVILEGES;
This very likely has nothing to do with GRANTs.
A very common reason for having incorrect access rights is because of default users that exist in MySQL. Specially ones with '' for User (anonymous users) and/or Host in mysql.user table. Because of the way MySQL handles authentication and proxy users, and the sorting rules used on mysql.user table entries, one could end up using an unexpected user than the one they used for authentication.
Use SELECT USER(); to find out the connecting user that was used during authentication and SELECT CURRENT_USER(); to find out the effective user whose privileges apply during the current session.
And from http://dev.mysql.com/doc/refman/5.6/en/connection-access.html
It is a common misconception to think that, for a given user name, all
rows that explicitly name that user are used first when the server
attempts to find a match for the connection. This is not true.
If you are able to connect to the server, but your privileges are not
what you expect, you probably are being authenticated as some other
account.
A mysql.user table similar to following
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ... (root from any host)
| % | jeffrey | ... (jeffrey from any host)
| localhost | root | ... (root from localhost)
| localhost | | ... (any user from localhost)
+-----------+----------+-
becomes,
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
whenever the server reads the user table into memory, in order to handle multiple matches.
When a client attempts to connect, the server looks through the rows in sorted order and uses the first row that matches the client host name and user name.
Precedence is given as: values (IP address, host name, user name, etc.) > '%' > ''
Most of the time application server/client is running in the same host as the database, causing the host name to be picked up as localhost during authentication.
mysql -u jeffrey uses jeffrey#localhost which gets matched against ''#localhost instead of jeffrey#%.
Executing $MYSQL_HOME/bin/mysql_secure_installation will remove anonymous users, while securing the installation, alleviating this unexpected behaviour.
Also check:
[1] http://bugs.mysql.com/bug.php?id=36576 (check comment before last)
[2] http://bugs.mysql.com/bug.php?id=69570
Just thought I'd add an answer. I was trying this on ubuntu. Tried the grants, flushes, nothing worked (this is immediately after by apt-get install mysql-server). Just for grins I bounced the server, that worked and my new user can now login. I did:
sudo service mysql restart
I don't know what that worked, but it did.
You must GRANT privileges also to 'myuser'#'localhost':
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'localhost';
GRANT ALL PRIVILEGES ON `db2_beta`.* TO 'myuser'#'localhost';
Otherwise the anonymous user #localhost created during db install takes precedence among your user with the wildcard hostname (%), as described here:
http://dev.mysql.com/doc/refman/5.5/en/adding-users.html
According to the mysql manual here:
If you modify the grant tables indirectly using account-management
statements such as GRANT, REVOKE, or SET PASSWORD, the server notices
these changes and loads the grant tables into memory again
immediately.
If you modify the grant tables directly using statements such as
INSERT, UPDATE, or DELETE, your changes have no effect on privilege
checking until you either restart the server or tell it to reload the
tables. If you change the grant tables directly but forget to reload
them, your changes have no effect until you restart the server. This
may leave you wondering why your changes do not seem to make any
difference!
This does seem to be true in most cases. However, in my situation I was working with an Amazon Web Services (AWS) RDS mysql instance. After many unsuccessful attempts to grant the user permissions I tried a FLUSH PRIVILEGES and the database was immediately visible to the user. If you come across this while looking for a solution on the Amazon Web Services RDS platform you might want to give this a try and see if it helps.
This SO question contains the most complete solutions to this problem and is the first in most search results so I wanted to add this response for anyone using RDS. Hopefully it will save RDS admins some time.
I have run into the same problem in the past. Have you tried the following?
GRANT ALL ON `db1`.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...';
GRANT ALL ON `db2`.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...';
FLUSH PRIVILEGES;