Spec-Zone .ru
спецификации, руководства, описания, API
|
The PAM authentication plugin is a commercial extension. To learn more about commercial products (MySQL Enterprise Edition), see http://www.mysql.com/products/.
As of MySQL 5.6.10, commercial distributions of MySQL include an authentication plugin that enables MySQL Server to use PAM (Pluggable Authentication Modules) to authenticate MySQL users. PAM enables a system to use a standard interface to access various kinds of authentication methods, such as Unix passwords or an LDAP directory.
The PAM plugin uses the information passed to it by MySQL Server (such as user name, host name, password, and
authentication string), plus whatever method is available for PAM lookup. The plugin checks the user credentials
against PAM and returns 'Authentication succeeded, Username is
or user_name
''Authentication
failed'
.
The PAM authentication plugin provides these capabilities:
External authentication: The plugin enables MySQL Server to accept connections from users defined outside the MySQL grant tables.
Proxy user support: The plugin can return to MySQL a user name different from the
login user, based on the groups the external user is in and the authentication string provided. This
means that the plugin can return the MySQL user that defines the privileges the external
PAM-authenticated user should have. For example, a PAM user named joe
can
connect and have the privileges of the MySQL user named developer
.
The following table shows the plugin and library file names. The file name suffix might be different on your
system. The file location must be the directory named by the plugin_dir
system variable. For installation information, see Section
6.3.7.3.1, "Installing the PAM Authentication Plugin".
Table 6.11. MySQL PAM Authentication Plugin
Server-side plugin name | authentication_pam |
Client-side plugin name | mysql_clear_password |
Library object file name | authentication_pam.so |
The library file includes only the server-side plugin. The client-side plugin is built into the libmysqlclient
client library. See Section
6.3.7.5, "The Cleartext Client-Side Authentication Plugin".
The server-side PAM authentication plugin is included only in commercial distributions. It is not included in MySQL community distributions. The client-side clear-text plugin that communicates with the server-side plugin is built into the MySQL client library and is included in all distributions, including community distributions. This permits clients from any 5.6.10 or newer distribution to connect to a server that has the server-side plugin loaded.
The PAM authentication plugin has been tested on Linux and Mac OS X. It requires MySQL Server 5.6.10 or newer.
For general information about pluggable authentication in MySQL, see Section 6.3.7, "Pluggable Authentication". For proxy user information, see Section 6.3.8, "Proxy Users".
The PAM authentication plugin must be located in the MySQL plugin directory (the directory named by the plugin_dir
system variable). If necessary, set the value of plugin_dir
at server startup to tell the server the location of the
plugin directory.
To enable the plugin, start the server with the --plugin-load
option. For example, put the following lines in your my.cnf
file. If object files have a suffix different from .so
on your system, substitute the correct suffix.
[mysqld]plugin-load=authentication_pam.so
Use the plugin name authentication_pam
in the IDENTIFIED
WITH
clause of CREATE USER
or GRANT
statements for MySQL accounts that should be authenticated with
this plugin.
To verify plugin installation, examine the INFORMATION_SCHEMA.PLUGINS
table or use the SHOW PLUGINS
statement. See Section
5.1.8.2, "Obtaining Server Plugin Information".
This section describes how to use the PAM authentication plugin to connect from MySQL client programs to the server. It is assumed that the server-side plugin is enabled and that client programs are recent enough to include the client-side plugin.
The client-side plugin with which the PAM plugin communicates simply sends the password to the server in clear text so it can be passed to PAM. This may be a security problem in some configurations, but is necessary to use the server-side PAM library. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using SSL. See Section 6.3.7.5, "The Cleartext Client-Side Authentication Plugin".
To refer to the PAM authentication plugin in the IDENTIFIED WITH
clause of a CREATE USER
or GRANT
statement, use the name authentication_pam
.
For example:
CREATE USERuser
IDENTIFIED WITH authentication_pam AS 'authentication_string
';
The authentication string specifies the following types of information:
PAM supports the notion of "service name," which is a name that the system administrator can use to configure the authentication method for a particular application. There can be several such "applications" associated with a single database server instance, so the choice of service name is left to the SQL application developer. When you define an account that should authenticate using PAM, specify the service name in the authentication string.
PAM provides a way for a PAM module to return to the server a MySQL user name other than the login name supplied at login time. Use the authentication string to control the mapping between login name and MySQL user name. If you want to take advantage of proxy user capabilities, the authentication string must include this kind of mapping.
For example, if the service name is mysql
and users in the root
and users
PAM groups should be mapped to the
developer
and data_entry
users, respectively, use
a statement like this:
CREATE USER user
IDENTIFIED WITH authentication_pam AS 'mysql, root=developer, users=data_entry';
Authentication string syntax for the PAM authentication plugin follows these rules:
The string consists of a PAM service name, optionally followed by a group mapping list consisting of one or more keyword/value pairs each specifying a group name and a SQL user name:
pam_service_name
[,group_name
=sql_user_name
]...
Each
pair must be preceded by a comma.
group_name
=sql_user_name
Leading and trailing spaces not inside double quotation marks are ignored.
Unquoted pam_service_name
, group_name
, and sql_user_name
values can contain anything except equal sign, comma, or space.
If a pam_service_name
, group_name
, or sql_user_name
value is quoted with double quotation marks,
everything between the quotation marks is part of the value. This is necessary, for example, if the
value contains space characters. All characters are legal except double quotation mark and backslash
('\'
). To include either character, escape it with a backslash.
The plugin parses the authentication string on each login check. To minimize overhead, keep the string as short as possible.
If the plugin successfully authenticates a login name, it looks for a group mapping list in the authentication string and uses it to return a different user name to the MySQL server based on the groups the external user is a member of:
If the authentication string contains no group mapping list, the plugin returns the login name.
If the authentication string does contain a group mapping list, the plugin
examines each
pair in the list from left to
right and tries to find a match for the group_name
=sql_user_name
group_name
value
in a non-MySQL directory of the groups assigned to the authenticated user and returns sql_user_name
for the first match it finds. If the
plugin finds no match for any group, it returns the login name. If the plugin is not capable of
looking up a group in a directory, it ignores the group mapping list and returns the login name.
The following sections describe how to set up several authentication scenarios that use the PAM authentication plugin:
No proxy users. This uses PAM only to check login names and passwords. Every external user permitted to connect to MySQL Server should have a matching MySQL account that is defined to use external PAM authentication. Authentication can be performed by various PAM-supported methods. The discussion shows how to use traditional Unix passwords and LDAP.
PAM authentication, when not done through proxy users or groups, requires the MySQL account to have the same user name as the Unix account. Because MySQL user names are limited to 16 characters (see Section 6.2.2, "Privilege System Grant Tables"), this limits PAM nonproxy authentication to Unix accounts with names of at most 16 characters.
Proxy login only and group mapping. For this scenario, create a few MySQL accounts that define different sets of privileges. (Ideally, nobody should log in through these directly.) Then define a default user authenticating through PAM that uses some mapping scheme (usually by the external groups the users are in) to map all the external logins to the few MySQL accounts holding the privilege sets. Any user that logs in is mapped to one of the MySQL accounts and uses its privileges. The discussion shows how to set this up using Unix passwords, but other PAM methods such as LDAP could be used instead.
Variations on these scenarios are possible. For example, you can permit some users to log in directly but require others to connect through proxy users.
The examples make the following assumptions. You might need to make some adjustments if your system is set up differently.
The PAM configuration directory is /etc/pam.d
.
The PAM service name is mysql
, which means that
you must set up a PAM file named mysql
in the PAM configuration
directory (creating the file if it does not exist). If you use a different service name, the file
name will be different and you must use a different name in the AS
clause of CREATE USER
and
GRANT
statements.
The examples use a login name of antonio
and
password of verysecret
. Change these to correspond to the users you
want to authenticate.
The PAM authentication plugin checks at initialization time whether the AUTHENTICATION_PAM_LOG
environment value is set. If so, the plugin enables logging of diagnostic messages to the standard output.
These messages may be helpful for debugging PAM-related problems that occur when the plugin performs
authentication. For more information, see Section
6.3.7.3.3, "PAM Authentication Plugin Debugging".
This authentication scenario uses PAM only to check Unix user login names and passwords. Every external user permitted to connect to MySQL Server should have a matching MySQL account that is defined to use external PAM authentication.
Verify that Unix authentication in PAM permits you to log in as antonio
with password verysecret
.
Set up PAM to authenticate the mysql
service.
Put the following in /etc/pam.d/mysql
:
#%PAM-1.0auth include password-authaccount include password-auth
Create a MySQL account with the same user name as the Unix login name and define it to authenticate using the PAM plugin:
CREATE USER 'antonio'@'localhost' IDENTIFIED WITH authentication_pam AS 'mysql';GRANT ALL PRIVILEGES ON mydb.* TO 'antonio'@'localhost';
Try to connect to the MySQL server using the mysql command-line client. For example:
mysql --user=antonio --password=verysecret mydb
The server should permit the connection and the following query should return output as shown:
mysql> SELECT USER(),
CURRENT_USER(), @@proxy_user;
+-------------------+-------------------+--------------+| USER() | CURRENT_USER() | @@proxy_user |+-------------------+-------------------+--------------+| antonio@localhost | antonio@localhost | NULL |+-------------------+-------------------+--------------+
This shows that antonio
uses the privileges granted to the
antonio
MySQL account, and that no proxying has occurred.
This authentication scenario uses PAM only to check LDAP user login names and passwords. Every external user permitted to connect to MySQL Server should have a matching MySQL account that is defined to use external PAM authentication.
Verify that LDAP authentication in PAM permits you to log in as antonio
with password verysecret
.
Set up PAM to authenticate the mysql
service
through LDAP. Put the following in /etc/pam.d/mysql
:
#%PAM-1.0auth required pam_ldap.soaccount required pam_ldap.so
If PAM object files have a suffix different from .so
on your
system, substitute the correct suffix.
MySQL account creation and connecting to the server is the same as previously described in Section 6.3.7.3.2.1, "Unix Password Authentication without Proxy Users".
This authentication scheme uses proxying and group mapping to map users who connect to the MySQL server through PAM onto a few MySQL accounts that define different sets of privileges. Users do not connect directly through the accounts that define the privileges. Instead, they connect through a default proxy user authenticating through PAM that uses a mapping scheme to map all the external logins to the few MySQL accounts holding the privileges. Any user who connects is mapped to one of the MySQL accounts and uses its privileges.
The procedure shown here uses Unix password authentication. To use LDAP instead, see the early steps of Section 6.3.7.3.2.2, "LDAP Authentication without Proxy Users".
Verify that Unix authentication in PAM permits you to log in as antonio
with password verysecret
and
that antonio
is a member of the root
or users
group.
Set up PAM to authenticate the mysql
service.
Put the following in /etc/pam.d/mysql
:
#%PAM-1.0auth include password-authaccount include password-auth
Create the default proxy user that maps the external PAM users to the
proxied accounts. It maps external users from the root
PAM group to
the developer
MySQL account and the external users from the users
PAM group to the data_entry
MySQL account:
CREATE USER ''@'' IDENTIFIED WITH authentication_pam AS 'mysql, root=developer, users=data_entry';
The mapping list following the service name is required when you set up proxy users. Otherwise, the plugin cannot tell how to map the name of PAM groups to the proper proxied user name.
Create the proxied accounts that will be used to access the databases:
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'very secret password
';GRANT ALL PRIVILEGES ON mydevdb.* TO 'developer'@'localhost';CREATE USER 'data_entry'@'localhost' IDENTIFIED BY 'very secret password
';GRANT ALL PRIVILEGES ON mydb.* TO 'data_entry'@'localhost';
If you do not let anyone know the passwords for these accounts, other users cannot use them
to connect directly to the MySQL server. Instead, it is expected that users will
authenticate using PAM and that they will use the developer
or
data_entry
account by proxy based on their PAM group.
Grant the PROXY
privilege to the proxy account for the proxied accounts:
GRANT PROXY ON 'developer'@'localhost' TO ''@'';GRANT PROXY ON 'data_entry'@'localhost' TO ''@'';
Try to connect to the MySQL server using the mysql command-line client. For example:
mysql --user=antonio --password=verysecret mydb
The server authenticates the connection using the ''@''
account. The privileges antonio
will have depends on what PAM
groups he is a member of. If antonio
is a member of the root
PAM group, the PAM plugin maps root
to the developer
MySQL user name and returns that name to the
server. The server verifies that ''@''
has the PROXY
privilege for developer
and permits the connection. the following query
should return output as shown:
mysql> SELECT USER(),
CURRENT_USER(), @@proxy_user;
+-------------------+---------------------+--------------+| USER() | CURRENT_USER() | @@proxy_user |+-------------------+---------------------+--------------+| antonio@localhost | developer@localhost | ''@'' |+-------------------+---------------------+--------------+
This shows that antonio
uses the privileges granted to the
developer
MySQL account, and that proxying occurred through the
default proxy user account.
If antonio
is not a member of the root
PAM group but is a member of the users
group, a similar process occurs, but the plugin maps user
group membership to the data_entry
MySQL user name and returns that name to the server.
In this case, antonio
uses the privileges of the data_entry
MySQL account:
mysql> SELECT USER(),
CURRENT_USER(), @@proxy_user;
+-------------------+----------------------+--------------+| USER() | CURRENT_USER() | @@proxy_user |+-------------------+----------------------+--------------+| antonio@localhost | data_entry@localhost | ''@'' |+-------------------+----------------------+--------------+
The PAM authentication plugin checks at initialization time whether the AUTHENTICATION_PAM_LOG
environment value is set (the value does not matter). If so, the plugin enables logging of diagnostic
messages to the standard output. These messages may be helpful for debugging PAM-related problems that occur
when the plugin performs authentication.
Some messages include reference to PAM plugin source files and line numbers, which enables plugin actions to be tied more closely to the location in the code where they occur.
The following transcript demonstrates the kind of information produced by enabling logging. It resulted from a successful proxy authentication attempt.
entering auth_pam_serverentering auth_pam_next_tokenauth_pam_next_token:reading at [cups,admin=writer,everyone=reader], sep=[,]auth_pam_next_token:state=PRESPACE, ptr=[cups,admin=writer,everyone=reader],out=[]auth_pam_next_token:state=IDENT, ptr=[cups,admin=writer,everyone=reader],out=[]auth_pam_next_token:state=AFTERSPACE, ptr=[,admin=writer,everyone=reader],out=[cups]auth_pam_next_token:state=DELIMITER, ptr=[,admin=writer,everyone=reader],out=[cups]auth_pam_next_token:state=DONE, ptr=[,admin=writer,everyone=reader],out=[cups]leaving auth_pam_next_token on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/parser.c:191auth_pam_server:password 12345qq receivedauth_pam_server:pam_start rc=0auth_pam_server:pam_set_item(PAM_RUSER,gkodinov) rc=0auth_pam_server:pam_set_item(PAM_RHOST,localhost) rc=0entering auth_pam_server_convauth_pam_server_conv:PAM_PROMPT_ECHO_OFF [Password:] receivedleaving auth_pam_server_conv on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/authentication_pam.c:257auth_pam_server:pam_authenticate rc=0auth_pam_server:pam_acct_mgmt rc=0auth_pam_server:pam_setcred(PAM_ESTABLISH_CRED) rc=0auth_pam_server:pam_get_item rc=0auth_pam_server:pam_setcred(PAM_DELETE_CRED) rc=0entering auth_pam_map_groupsentering auth_pam_walk_namevalue_listauth_pam_walk_namevalue_list:reading at: [admin=writer,everyone=reader]entering auth_pam_next_tokenauth_pam_next_token:reading at [admin=writer,everyone=reader], sep=[=]auth_pam_next_token:state=PRESPACE, ptr=[admin=writer,everyone=reader], out=[]auth_pam_next_token:state=IDENT, ptr=[admin=writer,everyone=reader], out=[]auth_pam_next_token:state=AFTERSPACE, ptr=[=writer,everyone=reader],out=[admin]auth_pam_next_token:state=DELIMITER, ptr=[=writer,everyone=reader],out=[admin]auth_pam_next_token:state=DONE, ptr=[=writer,everyone=reader], out=[admin]leaving auth_pam_next_token on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/parser.c:191auth_pam_walk_namevalue_list:name=[admin]entering auth_pam_next_tokenauth_pam_next_token:reading at [writer,everyone=reader], sep=[,]auth_pam_next_token:state=PRESPACE, ptr=[writer,everyone=reader], out=[]auth_pam_next_token:state=IDENT, ptr=[writer,everyone=reader], out=[]auth_pam_next_token:state=AFTERSPACE, ptr=[,everyone=reader], out=[writer]auth_pam_next_token:state=DELIMITER, ptr=[,everyone=reader], out=[writer]auth_pam_next_token:state=DONE, ptr=[,everyone=reader], out=[writer]leaving auth_pam_next_token on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/parser.c:191walk, &error_namevalue_list:value=[writer]entering auth_pam_map_group_to_userauth_pam_map_group_to_user:pam_user=gkodinov, name=admin, value=writerexamining member rootexamining member gkodinovsubstitution was made to mysql user writerleaving auth_pam_map_group_to_user on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/authentication_pam.c:118auth_pam_walk_namevalue_list:found mappingleaving auth_pam_walk_namevalue_list on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/parser.c:270auth_pam_walk_namevalue_list returned 0leaving auth_pam_map_groups on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/authentication_pam.c:171auth_pam_server:authenticated_as=writerauth_pam_server: rc=0leaving auth_pam_server on/Users/gkodinov/mysql/work/x-5.5.16-release-basket/release/plugin/pam-authentication-plugin/src/authentication_pam.c:429