Description\n-----------\n\nEven when using the pam authentication plugin, the authenticating PAM user account still needs to exist in MariaDB, and the account needs to have privileges in the database. Creating these MariaDB accounts and making sure the privileges are correct can be a lot of work. To decrease the amount of work involved, some users would like to be able to map a PAM user to a different MariaDB user. For example, let’s say that alice and bob are both DBAs. It would be nice if each of them could log into MariaDB with their own PAM username and password, while MariaDB sees both of them as the same dba user. That way, there is only one MariaDB account to keep track of.\n\nAlthough most PAM modules usually do not do things like this, PAM supports the ability to change the user name in the process of authentication.The MariaDB pam authentication plugin fully supports this feature of PAM.\n\nThe pam_user_map PAM Module\n\nRather than building user and group mapping into the pam authentication plugin, MariaDB thought that it would cover the most use cases and offer the most flexibility to offload this functionality to an external PAM module. The pam_user_map PAM module was implemented by MariaDB to facilitate this. This PAM module can be configured in the PAM service used by the pam authentication plugin, just like other PAM modules.\n\nLack of Support for MySQL/Percona Group Mapping Syntax\n\nUnlike MariaDB, MySQL and Percona implemented group mapping in their PAM authentication plugins. If you've read through MySQL's PAM authentication documentation on group mapping or Percona's PAM authentication documentation on group mapping, you've probably seen syntax where the group mappings are provided in the CREATE USER statement like this:\n\n``sql\nCREATE USER ''@''\n  IDENTIFIED WITH authentication_pam\n  AS 'mysql, root=developer, users=data_entry';\n`\n\nSince MariaDB's user and group mapping is performed by an external PAM module, MariaDB's pam authentication plugin does not support this syntax. Instead, the user and group mappings for the pam_user_map PAM module are configured in an external configuration file. This is discussed in a later section.\n\nInstalling the pam_user_map PAM Module\n\nThe pam_user_map PAM module gets installed as part of all our MariaDB server packages.\n\nSome Linux distributions have not picked up this change in their own packages yet. When using such an installation, it may be necessary to compile the PAM module from source as described in the next section, or to manually extract it from one of our server packages and copy it to the target system.\n\nInstalling the pam_user_map PAM Module from Source\n\nInstalling Compilation Dependencies\n\nBefore the module can be compiled from source, you may need to install some dependencies.\n\nOn RHEL, CentOS, and other similar Linux distributions that use RPM packages, you need to install gcc, pam-devel and MariaDB-devel:\n\n`bash\nsudo yum install gcc pam-devel MariaDB-devel\n`\n\nOn Debian, Ubuntu, and other similar Linux distributions that use DEB packages, you need to install gcc, libpam0g-dev:\n\n`bash\nsudo apt-get install gcc libpam0g-dev libmariadb-dev\n`\n\nCompiling and Installing the pam_user_map PAM Module\n\nThe pam_user_map PAM module can be built by downloading plugin/auth_pam/mapper/pam_user_map.c file from the MariaDB source tree and compiling it after minor adjustments. Once it is built, it can be installed to the system's PAM module directory, which is typically /lib64/security/:\n\n`bash\nwget https://raw.githubusercontent.com/MariaDB/server/10.4/plugin/auth_pam/mapper/pam_user_map.c\nsed -ie 's/config_auth_pam/plugin_auth_common/' pam_user_map.c\ngcc -I/usr/include/mysql/ pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so\nsudo install --mode=0755 pam_user_map.so /lib64/security/\n`\n\nYou also need to adjust the major version number in the URL on the first line to match your installed MariaDB version, and the #-I include path argument on the gcc line, as depending on operating system and MariaDB server version, the plugin_auth_common.h file may be installed in a directory other than /usr/include/mysql/ .\n\nConfiguring the pam_user_map PAM Module\n\nThe pam_user_map PAM module uses the configuration file at the path /etc/security/user_map.conf to determine its user and group mappings. The file's format is described below.\n\nTo map a specific PAM user to a specific MariaDB user:\n\n`\norig_pam_user_name: mapped_mariadb_user_name\n`\n\nOr to map any PAM user in a specific PAM group to a specific MariaDB user, the group name is prefixed with @:\n\n`\n@orig_pam_group_name: mapped_mariadb_user_name\n`\n\nFor example, here is an example /etc/security/user_map.conf:\n\n`\n=========================================================\n#comments and empty lines are ignored\njohn: jack\nbob:  admin\ntop:  accounting\n@group_ro: readonly\n`\n\nConfiguring PAM\n\nWith user and group mapping, configuring PAM is done similar to how it is normally done with the pam authentication plugin. However, when configuring the PAM service, you will have to add an auth line for the pam_user_map PAM module to the service's PAM configuration file:\n\n`\nauth required pam_unix.so audit\nauth required pam_user_map.so\naccount required pam_unix.so audit\n`\n\nCreating Users\n\nWith user and group mapping, creating users is done similar to how it is normally done with the pam authentication plugin. However, one major difference is that you will need to GRANT the PROXY privilege on the mapped user to the original user.\n\nConsider having the following configured in /etc/security/user_map.conf:\n\n`\nfoo: bar\n@dba:dba\n`\n\nThen you could execute the following to grant the relevant privileges:\n\n`sql\nCREATE USER 'bar'@'%' IDENTIFIED BY 'strongpassword';\nGRANT ALL PRIVILEGES ON . TO 'bar'@'%' ;\n\nCREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';\nGRANT ALL PRIVILEGES ON . TO 'dba'@'%' ;\n\nCREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';\nGRANT PROXY ON 'bar'@'%' TO ''@'%';\nGRANT PROXY ON 'dba'@'%' TO ''@'%';\n`\n\nNote that the ''@'%' account is a special catch-all anonymous account. Any login by a user that has no more specific account match in the system will be matched by this anonymous account.\n\nAlso note that you might not be able to create the ''@'%' anonymous account by default on some systems without doing some extra steps first. See Fixing a Legacy Default Anonymous Account for more information.\n\nVerifying that Mapping is Occurring\n\nIn case any user mapping is performed, the original user name is returned by the SQL function USER(), while the authenticated user name is returned by the SQL function CURRENT_USER(). The latter actually defines what privileges are available to a connected user.\n\nConsider having the following configured:\n\n`\nfoo: bar\n`\n\nThen the following output would verify that it is working properly:\n\n`bash\n$ mysql -u foo -h 172.30.0.198\n[mariadb] Password:\nWelcome to the MariaDB monitor.  Commands end with ; or \\g.\nYour MariaDB connection id is 22\nServer version: 10.3.10-MariaDB MariaDB Server\n\nCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nMariaDB [(none)]> SELECT USER(), CURRENT_USER();\n+------------------------------------------------+----------------+\n| USER()                                         | CURRENT_USER() |\n+------------------------------------------------+----------------+\n| foo@ip-172-30-0-198.us-west-2.compute.internal | bar@%          |\n+------------------------------------------------+----------------+\n1 row in set (0.000 sec)\n`\n\nWe can verify that our foo PAM user was properly mapped to the bar MariaDB user by looking at the return value of CURRENT_USER().\n\nLogging\n\nBy default, the pam_user_map PAM module does not perform any logging. However, if you want to enable debug logging, then you can add the debug module argument to the service's PAM configuration file:\n\n`\nauth required pam_unix.so audit\nauth required pam_user_map.so debug\naccount required pam_unix.so audit\n`\n\nWhen debug logging is enabled, the pam_user_map PAM module will write log entries to the same syslog location as other PAM modules, which is typically /var/log/secure on many systems.\n\nFor example, this debug log output can look like the following:\n\n`\nJan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.\nJan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'alice'.\nJan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 2 groups [alice,dba].\nJan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': YES\nJan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'dba'\nJan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.\nJan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'bob'.\nJan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 2 groups [bob,dba].\nJan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': YES\nJan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'dba'\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'foo'.\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 1 group [foo].\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': NO\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if username 'foo': YES\nJan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'bar'\n`\n\nKnown Issues\n\nPAM User with Same Name as Mapped MariaDB User Must Exist\n\nWith user and group mapping, any PAM user or any PAM user in a given PAM group can be mapped to a specific MariaDB user account. However, due to the way PAM works, a PAM user with the same name as the mapped MariaDB user account must exist.\n\nConsider the configuration file for the PAM service file containing the following:\n\n`\nauth required pam_sss.so\nauth required pam_user_map.so debug\naccount sufficient pam_unix.so\naccount sufficient pam_sss.so\n`\n\nConsider etc/security/user_map.conf containing the following:\n\n`\n@dba: dba\n`\n\nIn that case, any PAM user in the PAM group dba are mapped to the MariaDB user account dba. But if a PAM user with the name dba doesn't exist, the pam_user_map PAM module's debug logging writes errors to the syslog, like the following:\n\n`\nSep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Opening file '/etc/security/user_map.conf'.\nSep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Incoming username 'alice'.\nSep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): User belongs to 4 groups [dba,mongod,mongodba,mysql].\nSep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Check if user is in group 'mysql': YES\nSep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): User mapped as 'dba'\nSep 27 17:17:05 dbserver1 mysqld: pam_unix(mysql:account): could not identify user (from getpwnam(dba))\nSep 27 17:17:05 dbserver1 mysqld: pam_sss(mysql:account): Access denied for user dba: 10 (User not known to the underlying authentication module)\nSep 27 17:17:05 dbserver1 mysqld: 2018-09-27 17:17:05 72 [Warning] Access denied for user 'alice'@'localhost' (using password: NO)\n`\n\nIn the above log snippet, notice that both the pam_unix and the pam_sss PAM modules are complaining that the dba PAM user does not appear to exist, and that these complaints cause the PAM authentication process to fail, which causes the MariaDB authentication process to fail as well.\n\nThis can be fixed by creating a PAM user with the same name as the mapped MariaDB user account, which is dba in this case.\n\nYou may also be able to work around this problem by essentially disabling PAM's account verification for the service with the pam_permit PAM module. For example, in the above case, that would be:\n\n`\nauth required pam_sss.so\nauth required pam_user_map.so debug\naccount required pam_permit.so\n``\n\nSee MDEV-17315 for more information.\n\nTutorials\n\nYou may find the following PAM and user mapping-related tutorials helpful:\n\n Configuring PAM Authentication and User Mapping with Unix Authentication\n Configuring PAM Authentication and User Mapping with LDAP Authentication\n\nURL: https://mariadb.com/docs/server/reference/plugins/authentication-plugins/authentication-with-pluggable-authentication-modules-pam/user-and-group-mapping-with-pam