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
      (Host, User, 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 allowable
      Host and User values are
      given in Section 5.4.3, “Specifying Account Names”.
    
      If the User column value is nonblank, the user
      name in an incoming connection must match exactly. If the
      User value 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 5.5.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.
    
| HostValue | UserValue | Allowable Connections | 
| 'thomas.loc.gov' | 'fred' | fred, connecting fromthomas.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 theloc.govdomain | 
| 'x.y.%' | 'fred' | fred, connecting fromx.y.net,x.y.com,x.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 the144.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 the
      user 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.
      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 orders the rows
      with the most-specific Host values first.
      Literal host names and IP numbers are the most specific. (The
      specificity if a literal IP number 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 '%' means
      “any host” and is least specific. 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). For the user table just shown,
      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 jeffrey from any host
      is matched by the second.
    
        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 the
      CURRENT_USER() function. (See
      Section 11.11.3, “Information Functions”.) It returns a value in
      user_name@host_nameUser 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.
    
      Another way to diagnose authentication problems is to print out
      the user table and sort it by hand to see where
      the first match is being made.
    


User Comments
If you do not trust the hostnames that may be seen by the MySQL server (after all, someone could be handing the server wrongly reverse-resolved hostnames), then do as described at http://dev.mysql.com/doc/refman/5.0/en/privileges-options.html : Start the server with "--skip-name-resolve": "Hostnames are not resolved. All Host column values in the grant tables must be IP numbers or localhost."
Add your own comment.