One of the capabilities that pluggable authentication makes possible is proxy users (see Proxy Users). For a server-side authentication plugin to participate in proxy user support, these conditions must be satisfied:
- When a connecting client should be treated as a proxy user, the plugin must return a different name in the - authenticated_asmember of the- MYSQL_SERVER_AUTH_INFOstructure, to indicate the proxied user name. It may also optionally set the- external_usermember, to set the value of the- external_usersystem variable.
- Proxy user accounts must be set up to be authenticated by the plugin. Use the - CREATE USERor- GRANTstatement to associate accounts with plugins.
- Proxy user accounts must have the - PROXYprivilege for the proxied accounts. Use the- GRANTstatement to grant this privilege.
            In other words, the only aspect of proxy user support
            required of the plugin is that it set
            authenticated_as to the proxied user
            name. The rest is optional (setting
            external_user) or done by the DBA using
            SQL statements.
          
            How does an authentication plugin determine which proxied
            user to return when the proxy user connects? That depends on
            the plugin. Typically, the plugin maps clients to proxied
            users based on the authentication string passed to it by the
            server. This string comes from the AS
            part of the IDENTIFIED WITH clause of the
            CREATE USER statement that
            specifies use of the plugin for authentication.
          
The plugin developer determines the syntax rules for the authentication string and implements the plugin according to those rules. Suppose that a plugin takes a comma-separated list of pairs that map external users to MySQL users. For example:
CREATE USER ''@'%.example.com'
  IDENTIFIED WITH my_plugin AS 'extuser1=mysqlusera, extuser2=mysqluserb'
CREATE USER ''@'%.example.org'
  IDENTIFIED WITH my_plugin AS 'extuser1=mysqluserc, extuser2=mysqluserd'When the server invokes a plugin to authenticate a client, it passes the appropriate authentication string to the plugin. The plugin is responsible to:
- Parse the string into its components to determine the mapping to use 
- Compare the client user name to the mapping 
- Return the proper MySQL user name 
            For example, if extuser2 connects from an
            example.com host, the server passes
            'extuser1=mysqlusera,
            extuser2=mysqluserb' to the plugin, and the plugin
            should copy mysqluserb into
            authenticated_as, with a terminating null
            byte. If extuser2 connects from an
            example.org host, the server passes
            'extuser1=mysqluserc,
            extuser2=mysqluserd', and the plugin should copy
            mysqluserd instead.
          
            If there is no match in the mapping, the action depends on
            the plugin. If a match is required, the plugin likely will
            return an error. Or the plugin might simply return the
            client name; in this case, it should not change
            authenticated_as, and the server will not
            treat the client as a proxy.
          
            The following example demonstrates how to handle proxy users
            using a plugin named auth_simple_proxy.
            Like the auth_simple plugin described
            earlier, auth_simple_proxy accepts any
            nonempty password as valid (and thus should not be used in
            production environments). In addition, it examines the
            auth_string authentication string member
            and uses these very simple rules for interpreting it:
          
- If the string is empty, the plugin returns the user name as given and no proxying occurs. That is, the plugin leaves the value of - authenticated_asunchanged.
- If the string is nonempty, the plugin treats it as the name of the proxied user and copies it to - authenticated_asso that proxying occurs.
            For testing, set up one account that is not proxied
            according to the preceding rules, and one that is. This
            means that one account has no AS clause,
            and one includes an AS clause that names
            the proxied user:
          
CREATE USER 'plugin_user1'@'localhost'
  IDENTIFIED WITH auth_simple_proxy;
CREATE USER 'plugin_user2'@'localhost'
  IDENTIFIED WITH auth_simple_proxy AS 'proxied_user';
            In addition, create an account for the proxied user and
            grant plugin_user2 the
            PROXY privilege for it:
          
CREATE USER 'proxied_user'@'localhost'
  IDENTIFIED BY 'proxied_user_pass';
GRANT PROXY
  ON 'proxied_user'@'localhost'
  TO 'plugin_user2'@'localhost';
            Before the server invokes an authentication plugin, it sets
            authenticated_as to the client user name.
            To indicate that the user is a proxy, the plugin should set
            authenticated_as to the proxied user
            name. For auth_simple_proxy, this means
            that it must examine the auth_string
            value, and, if the value is nonempty, copy it to the
            authenticated_as member to return it as
            the name of the proxied user. In addition, when proxying
            occurs, the plugin sets the external_user
            member to the client user name; this becomes the value of
            the external_user system
            variable.
          
static int auth_simple_proxy_server (MYSQL_PLUGIN_VIO *vio,
                                     MYSQL_SERVER_AUTH_INFO *info)
{
  unsigned char *pkt;
  int pkt_len;
  /* read the password as null-terminated string, fail on error */
  if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
    return CR_ERROR;
  /* fail on empty password */
  if (!pkt_len || *pkt == '\0')
  {
    info->password_used= PASSWORD_USED_NO;
    return CR_ERROR;
  }
  /* accept any nonempty password */
  info->password_used= PASSWORD_USED_YES;
  /* if authentication string is nonempty, use as proxied user name */
  /* and use client name as external_user value */
  if (info->auth_string_length > 0)
  {
    strcpy (info->authenticated_as, info->auth_string);
    strcpy (info->external_user, info->user_name);
  }
  return CR_OK;
}
            After a successful connection, the
            USER() function should
            indicate the connecting client user and host name, and
            CURRENT_USER() should
            indicate the account whose privileges apply during the
            session. The latter value should be the connecting user
            account if no proxying occurs or the proxied account if
            proxying does occur.
          
            Compile and install the plugin, then test it. First, connect
            as plugin_user1:
          
$> mysql --user=plugin_user1 --password
Enter password: xIn this case, there should be no proxying:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G
*************************** 1. row ***************************
         USER(): plugin_user1@localhost
 CURRENT_USER(): plugin_user1@localhost
   @@proxy_user: NULL
@@external_user: NULL
            Then connect as plugin_user2:
          
$> mysql --user=plugin_user2 --password
Enter password: x
            In this case, plugin_user2 should be
            proxied to proxied_user:
          
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G
*************************** 1. row ***************************
         USER(): plugin_user2@localhost
 CURRENT_USER(): proxied_user@localhost
   @@proxy_user: 'plugin_user2'@'localhost'
@@external_user: 'plugin_user2'@'localhost'