User can't access a database

后端 未结 7 2273
太阳男子
太阳男子 2020-12-29 10:30

In my PHP script, I\'m accessing two databases db1 and db2. I have a user myuser@localhost that can access db1 but can\'

相关标签:
7条回答
  • 2020-12-29 11:00

    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

    0 讨论(0)
  • 2020-12-29 11:00

    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

    0 讨论(0)
  • 2020-12-29 11:01

    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;
    
    0 讨论(0)
  • 2020-12-29 11:10

    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.

    0 讨论(0)
  • 2020-12-29 11:12

    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'
    
    0 讨论(0)
  • 2020-12-29 11:13

    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.

    0 讨论(0)
提交回复
热议问题