Monday, September 2, 2013

MySQL localhost connect string vs %

MySQL users having host as % and localhost are not one and the same.
localhost is used only when protocol is Unix Socket.

See below information from dev.mysql.com

On Unix, MySQL programs treat the host name localhost specially, in a way that is likely different from what you expect compared to other network-based programs. For connections to localhost, MySQL programs attempt to connect to the local server by using a Unix socket file. This occurs even if a --port or -P option is given to specify a port number. To ensure that the client makes a TCP/IP connection to the local server, use --host or -h to specify a host name value of 127.0.0.1, or the IP address or name of the local server. You can also specify the connection protocol explicitly, even for localhost, by using the --protocol=TCP option. For example:
shell> mysql --host=127.0.0.1
shell> mysql --protocol=TCP
The --protocol option enables you to establish a particular type of connection even when the other options would normally default to some other protocol.

Unix to localhost are made using a Unix socket file by default:
shell> mysql --host=localhost
To force a TCP/IP connection to be used instead, specify a --protocol option:
shell> mysql --host=localhost --protocol=TCP
The following table shows the permissible --protocol option values and indicates the platforms on which each value may be used. The values are not case sensitive.

When you attempt to connect to a MySQL server, the server accepts or rejects the connection based on your identity and whether you can verify your identity by supplying the correct password. If not, the server denies access to you completely. Otherwise, the server accepts the connection, and then enters Stage 2 and waits for requests.
Your identity is based on two pieces of information:
  • The client host from which you connect
  • Your MySQL user name
Identity checking is performed using the three user table scope columns (HostUser, and Password). The server accepts the connection only if the Host and User columns in some user table row match the client host name and user name and the client supplies the password specified in that row. The rules for permissible Host and Uservalues are given in Section 6.2.3, “Specifying Account Names”.
If the User column value is nonblank, the user name in an incoming connection must match exactly. If the Uservalue is blank, it matches any user name. If the user table row that matches an incoming connection has a blank user name, the user is considered to be an anonymous user with no name, not a user with the name that the client actually specified. This means that a blank user name is used for all further access checking for the duration of the connection (that is, during Stage 2).
The Password column can be blank. This is not a wildcard and does not mean that any password matches. It means that the user must connect without specifying a password.
Nonblank Password values in the user table represent encrypted passwords. MySQL does not store passwords in plaintext form for anyone to see. Rather, the password supplied by a user who is attempting to connect is encrypted (using the PASSWORD() function). The encrypted password then is used during the connection process when checking whether the password is correct. This is done without the encrypted password ever traveling over the connection. See Section 6.3.1, “User Names and Passwords”.
From MySQL's point of view, the encrypted password is the real password, so you should never give anyone access to it. In particular, do not give nonadministrative users read access to tables in the mysql database.
The following table shows how various combinations of Host and User values in the user table apply to incoming connections.
Host ValueUserValuePermissible Connections
'thomas.loc.gov''fred'fred, connecting from thomas.loc.gov
'thomas.loc.gov'''Any user, connecting from thomas.loc.gov
'%''fred'fred, connecting from any host
'%'''Any user, connecting from any host
'%.loc.gov''fred'fred, connecting from any host in the loc.gov domain
'x.y.%''fred'fred, connecting from x.y.netx.y.comx.y.edu, and so on; this is probably not useful
'144.155.166.177''fred'fred, connecting from the host with IP address144.155.166.177
'144.155.166.%''fred'fred, connecting from any host in the 144.155.166class C subnet
'144.155.166.0/255.255.255.0''fred'Same as previous example
It is possible for the client host name and user name of an incoming connection to match more than one row in theuser table. The preceding set of examples demonstrates this: Several of the entries shown match a connection from thomas.loc.gov by fred.
When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows:
  • Whenever the server reads the user table into memory, it sorts the rows.
  • When a client attempts to connect, the server looks through the rows in sorted order.
  • The server uses the first row that matches the client host name and user name.
The server uses sorting rules that order rows with the most-specific Host values first. Literal host names and IP addresses are the most specific. (The specificity of a literal IP address is not affected by whether it has a netmask, so 192.168.1.13 and 192.168.1.0/255.255.255.0 are considered equally specific.) The pattern '%' meansany host and is least specific. The empty string '' also means any host but sorts after '%'. Rows with the same Host value are ordered with the most-specific User values first (a blank User value means any user and is least specific).
To see how this works, suppose that the user table looks like this:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
When the server reads the table into memory, it sorts the rows using the rules just described. The result after sorting looks like this:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
When a client attempts to connect, the server looks through the sorted rows and uses the first match found. For a connection from localhost by jeffrey, two of the rows from the table match: the one with Host and User values of 'localhost' and '', and the one with values of '%' and 'jeffrey'. The 'localhost' row appears first in sorted order, so that is the one the server uses.
Here is another example. Suppose that the user table looks like this:
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| % | jeffrey | ...
| thomas.loc.gov | | ...
+----------------+----------+-
The sorted table looks like this:
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| thomas.loc.gov | | ...
| % | jeffrey | ...
+----------------+----------+-
A connection by jeffrey from thomas.loc.gov is matched by the first row, whereas a connection by jeffreyfrom any host is matched by the second.
Note
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. The preceding example illustrates this, where a connection from thomas.loc.gov by jeffrey is first matched not by the row containing'jeffrey' as the User column value, but by the row with no user name. As a result, jeffrey is authenticated as an anonymous user, even though he specified a user name when connecting.
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. To find out what account the server used to authenticate you, use theCURRENT_USER() function. (See Section 12.14, “Information Functions”.) It returns a value inuser_name@host_name format that indicates the User and Host values from the matching user table row. Suppose that jeffrey connects and issues the following query:
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
The result shown here indicates that the matching user table row had a blank User column value. In other words, the server is treating jeffrey as an anonymous user.

No comments: