WL#7724: Expand proxy user capabilities for built-in auth plugins

Affects: Server-5.7   —   Status: Complete

MySQL Server has an existing concept of "proxy users" which can support a major
use case for of SQL Roles - the ability to abstract user credentials/identity
from the privileges assigned.  This allows multiple users - identified, logged
and audited in distinct manner - to share a single set of managed privileges. 
For deployments with many users having identical privileges, this can provide
major operational benefits, but proxy users can currently only be leveraged by
external authentication plugins.  Built-in auth plugins should be extended to
support proxy users.
FR1:  Behavior will be unchanged for all built-in authentication plugins by default.

FR2:  No SQL syntax changes will be introduced.

FR3:  Three new server options will be introduced:  check_proxy_users,
mysql_native_password_proxy_users, sha256_password_proxy_users.

FR3.1:  Allowable options shall be ON or OFF

FR3.2:  Default value shall be OFF for all three new options.

FR3.3:  All three new option will allow dynamic modification by users with SUPER
privilege only.

FR4.  When mysql_native_password_proxy_users = ON,
mysql_native_password plugin will return a flag value indicating a
successfully-authenticated user may proxy another user account.

FR 4.1  When mysql_native_password_proxy_users = OFF, users defined with
mysql_native_password plugin will not be mapped to proxy users.

FR5.  When sha256_password_proxy_users = ON, sha256_password plugin will return
a flag value indicating a successfully-authenticated user may proxy another user

FR 5.1  When sha256_password_proxy_users = OFF, users defined with
sha256_password plugin will not be mapped to proxy users.

FR6:  When check_proxy_users = ON, MySQL Server will check for allowed proxy
user accounts when flag values are received from the authentication plugin, and
if any exist, will use one as the proxied user.

FR6.1:  Only non-anonymous user accounts (not blank user names) will be mapped
based on proxy privileges.  GRANT PROXY ... ON ''@host will be allowed, but will
not be automatically mapped during authentication.

FR6.2:  When one account has multiple associated proxy user privileges, the
selected proxy user account will be non-deterministic.

FR6.3:  User activity will create appropriate logging and audit records (same as
existing proxy user output).

The existing PROXY USER functionality is limited to authentication plugins which
can internally map one user account to another during the authentication
process.  This excludes mysql_native_password and sha256_password plugins, which
currently return identical values for the user and authenticated_as (proxied
user) values for successfully-authenticated connections.  The following work
will be necessary to enable mysql_native_password and sha256_password plugins to
leverage PROXY USER capabilities.

The mysql_native_password and sha256_password plugins will each be modified to
return a signal value of "" (empty string) as authenticated_as when the
mysql_native_password_proxy_users or sha256_password_proxy_users options
(respectively) are set to ON.  The default value of
mysql_native_password_proxy_users and sha256_password_proxy_users will be OFF,
resulting in compatibility with existing behavior for accounts defined with
these plugins.  These configuration options will require SUPER privileges to
modify dynamically.

A new configuration option - check_proxy_users - will be added to MySQL Server.
 This option will allow dynamic modification by users with SUPER privileges, and
may be set via server start-up command-line option or options file.  Leaving
check_proxy_users=OFF (default) will cause MySQL Server behavior consistent with
current/legacy behavior.

When check_proxy_users=ON and the signal empty string authenticated_as value is
found, MySQL Server will find the first (non-deterministic) matching record in
proxies_priv where the proxy user matches the authenticated user and where a
proxied user record with non-blank user name and host values exists.  If no such
proxy record exists, the user will not be proxied, and the privileges assigned
to the authenticated user will be applied.  

Proxy privilege chains will not be followed, so:

GRANT SELECT ON db1.* TO user1@localhost;
GRANT SELECT ON db2.* TO user2@localhost;
GRANT SELECT ON db3.* TO user3@localhost;

GRANT PROXY ON user1@localhost TO user2@localhost;
GRANT PROXY ON user2@localhost TO user3@localhost;

Connecting as user3@localhost will result in SELECT privileges on db2.* (only)
in the example above.

General query logging will need to be relocated in the code path to properly log
the proxy user information.  Currently, logging is done immediately after plugin
authentication succeeds, but this is too early when proxy user identity is
established later.

Existing behavior of proxy user functionality will not be modified.  The
existing syntax for GRANT PROXY will be unchanged, as will the resulting
underlying persistence.  This information will be used differently with
check_proxy_users=ON and authentication plugins configured to return flag values
- it will be used to generate the mapping between proxy and proxied users, while
previously (and with check_proxy_user=OFF) it is used only
to verify mapping supplied by the authentication plugins.