Pluggable Authentication Overview

You are viewing an old version of this article. View the current version here.

The authentication of users is delegated to plugins.

Supported Authentication Plugins

The authentication process is a conversation between the server and a client. MariaDB implements both server-side and client-side authentication plugins.

Supported Server Authentication Plugins

MariaDB provides six server-side authentication plugins:

MariaDB starting with 10.4

In MariaDB 10.4 and later, the following server-side authentication plugins are installed by default:

  • The unix_socket authentication plugin is installed by default in all builds on Unix and Linux.
  • The named_pipe authentication plugin is installed by default in all builds on Windows.
MariaDB until 10.3

In MariaDB 10.3 and below, the following server-side authentication plugins are installed by default:

  • The unix_socket authentication plugin is installed by default in new installations that use the .deb packages provided by Debian's default repositories in Debian 9 and later and Ubuntu's default repositories in Ubuntu 15.10 and later.
  • The named_pipe authentication plugin is installed by default in all builds on Windows.

The mysql_native_password authentication plugin implements MySQL password authentication with a 20 byte scramble, which was first introduced in MySQL 4.0.

The mysql_old_password authentication plugin implements MySQL password authentication with a 9 byte scramble, which was first introduced in MySQL 3.23.

The unix_socket authentication plugin allows a user to connect via the unix socket file configured by the socket system variable, if the user is already authenticated to the OS. For example:

$ mysql -uroot
MariaDB []> CREATE USER serg IDENTIFIED VIA unix_socket;
MariaDB []> CREATE USER monty IDENTIFIED VIA unix_socket;
MariaDB []> quit
Bye
$ whoami
serg
$ mysql --user=serg
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.2.0-MariaDB-alpha-debug Source distribution
MariaDB []> quit
Bye
$ mysql --user=monty
ERROR 1045 (28000): Access denied for user 'monty'@'localhost' (using password: NO)

In this example, a user serg is already logged into the operating system and has full shell access. He has already authenticated with the operating system and his MariaDB account is configured to use the unix_socket authentication plugin, so he does not need to authenticate again for the database. MariaDB accepts his operating system credentials and allows him to connect. However, any attempt to connect to the database as another operating system user will be denied.

Supported Client Authentication Plugins

MariaDB provides seven client-side authentication plugins:

Client authentication plugins are loaded into the client library automatically on demand. Clients that do not use the libmysqlclient or MariaDB Connector/C libraries or clients that are not bundled with either library's optional client authentication plugins can only use the conventional authentication plugins (like mysql_native_password and mysql_old_password) and the non-conventional authentication plugins that don't require special client-side authentication plugins (like unix_socket and named_pipe).

Most clients and utilities support two command line arguments related to client authentication plugins:

OptionDescription
--plugin-dir=pathDirectory for client-side plugins.
--default-auth=nameDefault authentication client-side plugin to use.

Developers who are using MariaDB Connector/C can implement similar functionality in their application by setting the MYSQL_PLUGIN_DIR and MYSQL_DEFAULT_AUTH options with the mysql_optionsv function.

mysql_options(mysql, MYSQL_PLUGIN_DIR, "path");
mysql_options(mysql, MYSQL_DEFAULT_AUTH, "name");

Extended SQL Syntax

MariaDB has extended the SQL standard GRANT, CREATE USER, and ALTER USER statements, so that they support specifying different authentication plugins for specific users. An authentication plugin can be specified with these statements by providing the IDENTIFIED VIA clause.

For example, the GRANT syntax is:

GRANT <privileges> ON <level> TO <user> IDENTIFIED VIA <plugin> [ USING <string> ]

And the CREATE USER syntax is:

CREATE USER <user> IDENTIFIED VIA <plugin> [ USING <string> ]

And the ALTER USER syntax is:

ALTER USER <user> IDENTIFIED VIA <plugin> [ USING <string> ]

The optional USING clause allows users to provide an authentication string to a plugin. The authentication string's format and meaning is completely defined by the plugin.

For example, for the mysql_native_password authentication plugin, the authentication string should be a password hash:

CREATE USER mysqltest_up1 
   IDENTIFIED VIA mysql_native_password USING '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';

Since mysql_native_password is the default authentication plugin, the above is just another way of saying the following:

CREATE USER mysqltest_up1 
   IDENTIFIED BY PASSWORD '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';

In contrast, for the pam authentication plugin, the authentication string should refer to a PAM service name:

CREATE USER mysqltest_up1 
   IDENTIFIED VIA pam USING 'mariadb';
MariaDB starting with 10.4

In MariaDB 10.4 and later, a user account can be associated with multiple authentication plugins.

For example, to configure the root@localhost user account to try the unix_socket authentication plugin, followed by the mysql_native_password authentication plugin as a backup, you could execute the following:

CREATE USER root@localhost 
   IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD("verysecret");

See Authentication from MariaDB 10.4 for more information.

Default Authentication Plugin

Default Server Authentication Plugin

The mysql_native_password authentication plugin is currently the default authentication plugin in all versions of MariaDB if the old_passwords system variable is set to 0, which is the default.

The mysql_old_password authentication plugin becomes the default authentication plugin in all versions of MariaDB if the old_passwords system variable is explicitly set to 1. However, this is not recommended.

On a system with the old_passwords system variable set to 0, this means that if you create a user account with either the GRANT or CREATE USER statements, and if you do not specify an authentication plugin with the IDENTIFIED VIA clause, then MariaDB will use the mysql_native_password authentication plugin for the user account.

For example, this user account will use the mysql_native_password authentication plugin:

CREATE USER username@hostname;

And so will this user account:

CREATE USER username@hostname IDENTIFIED BY 'notagoodpassword';

Default Client Authentication Plugin

According to the Client Server Protocol the server first sends the handshake packet to the client, then the client replies with a packet containing the user name of the user account that is requesting access. The server handshake packet initially tells the client to use the default server authentication plugin, and the client reply initially tells the server that it will use the default client authentication plugin.

However, the server-side and client-side authentication plugins mentioned in these initial packets may not be the correct ones for this specific user account. The server only knows what authentication plugin to use for this specific user account after reading the user name from the client reply packet and finding the appropriate row for the user account in either the mysql.user table or the mysql.global_priv table, depending on the MariaDB version.

If the server finds that either the server-side or client-side default authentication plugin does not match the actual authentication plugin that should be used for the given user account, then the server restarts the authentication on either the server side or the client side.

This means that, if you know what client authentication plugin your user account requires, then you can avoid an unnecessary authentication restart and you can save two packets and two round-trips.between the client and server by configuring your client to use the correct authentication plugin by default.

Most clients and utilities support a command line argument that can be used to set the default client authentication plugin:

OptionDescription
--default-auth=nameDefault authentication client-side plugin to use.

Developers who are using MariaDB Connector/C can implement similar functionality in their application by setting the MYSQL_DEFAULT_AUTH option with the mysql_optionsv function.

mysql_options(mysql, MYSQL_DEFAULT_AUTH, "name");

Authentication Plugin API

The authentication plugin API is extensively documented in the source code in the following files:

  • mysql/plugin_auth.h (server part)
  • mysql/client_plugin.h (client part)
  • mysql/plugin_auth_common.h (common parts)

The MariaDB source code also contains some authentication plugins that are intended explicitly to be examples for developers. They are located in plugin/auth_examples.

The definitions of two example authentication plugins called two_questions and three_attempts can be seen in plugin/auth_examples/dialog_examples.c. These authentication plugins demonstrate how to communicate with the user using the dialog client authentication plugin.

The two_questions authentication plugin asks the user for a password and a confirmation ("Are you sure?").

The three_attempts authentication plugin gives the user three attempts to enter a correct password.

The password for both of these plugins should be specified in the plain text in the USING clause:

CREATE USER insecure IDENTIFIED VIA two_questions USING 'notverysecret';

Dialog Client Authentication Plugin - Client Library Extension

The dialog client authentication plugin, strictly speaking, is not part of the client-server or authentication plugin API. But it can be loaded into any client application that uses the libmysqlclient or MariaDB Connector/C libraries. This authentication plugin provides a way for the application to customize the UI of the dialog function.

In order to use the dialog client authentication plugin to communicate with the user in a customized way, the application will need to implement a function with the following signature:

extern "C" char *mysql_authentication_dialog_ask(
  MYSQL *mysql, int type, const char *prompt, char *buf, int buf_len)

The function takes the following arguments:

  • The connection handle.
  • A question "type", which has one of the following values:
    • 1 - Normal question
    • 2 - Password (no echo)
  • A prompt.
  • A buffer.
  • The length of the buffer.

The function returns a pointer to a string of characters, as entered by the user. It may be stored in buf or allocated with malloc().

Using this function a GUI application can pop up a dialog window, a network application can send the question over the network, as required. If no mysql_authentication_dialog_ask function is provided by the application, the dialog client authentication plugin falls back to fputs() and fgets().

Providing this callback is particularly important on Windows, because Windows GUI applications have no associated console and the default dialog function will not be able to reach the user. An example of Windows GUI client that does it correctly is HeidiSQL.

See Also

  1. MySQL manual about pluggable authentication
  2. MySQL manual about writing authentication plugins

Comments

Comments loading...
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.