I am currently preparing a machine for a web hosting service, and I decided to use MySQL to store all our users (since the rest of our services use it already). For that, I am using libnss-mysql and pam-mysql. However, even though most of the setup is functioning, I am facing a problem when trying to change a user's password with passwd
.
At the moment, it is possible to create a user (INSERT INTO
) and log in as this user using su
. The machine does not prompt for a password, and access to the user's shell is directly given. However, once I'm logged as this user, passwd
ends with :
$ passwd myuser
passwd: Authentication token manipulation error
passwd: password unchanged
According to the MySQL logs, a query is made when passwd
is called, therefore the connection with MySQL isn't a problem. Besides, when I try calling passwd
with an unexisting user, I get an appropriate passwd: user 'doesnotexist' does not exist
. passwd
does find a user, but cannot modify its information. The auth.log
log file says :
pam_unix(passwd:chauthtok): user "myuser" does not exist in /etc/passwd
pam_mysql - option verbose is set to "1"
pam_mysql - pam_sm_chauthtok() called.
pam_mysql - pam_mysql_open_db() called.
pam_mysql - pam_mysql_open_db() returning 0.
pam_mysql - pam_sm_chauthtok() returning 0.
pam_mysql - pam_mysql_release_ctx() called.
pam_mysql - pam_mysql_destroy_ctx() called.
pam_mysql - pam_mysql_close_db() called.
When calling passwd -Sa
to get the status of all accounts, the myuser
account does appear. Besides, getent passwd
and getent shadow
both return a valid entry for myuser
.
$ passwd -Sa
...
messagebus L 06/28/2014 0 99999 7 -1
mysql L 06/28/2014 0 99999 7 -1
myuser P 01/01/1970 0 99999 7 -1
$ getent passwd myuser
myuser:x:5001:5000:First Last:/home/members/myuser:/bin/bash
$ getent shadow myuser
myuser:$6$...:0:0:99999:7:::0
However, when requesting ageing information about myuser
:
$ chage -l myuser
chage: user 'myuser' does not exist in /etc/passwd
All in all :
su
does find the user, and performs a password-less login in all cases (if I am root, otherwise I am prompted for a password, and get the token error).chage
cannot find the user ; it seems to search/etc/passwd
instead of the DB.passwd
does find the user, but returns a token error when trying to edit it.
Here are some configuration samples :
/etc/pam.d/common-account
account sufficient pam_unix.so
account required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-auth
auth sufficient pam_unix.so nullok_secure
auth required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-session
session sufficient pam_unix.so
session required pwam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-passwd
password sufficient pam_unix.so obscure sha512
password required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/libnss-mysql.cfg
getpwnam SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users \
WHERE username='%1$s' \
LIMIT 1
getpwuid SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users \
WHERE (5000+id)='%1$u' \
LIMIT 1
getspnam SELECT username,password,0,'0','99999','7','-1','-1','0' \
FROM users \
WHERE username='%1$s' \
LIMIT 1
getpwent SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users
getspent SELECT username,password,0,'0','99999','7','-1','-1','0' \
FROM users
getgrnam SELECT '%1$s','members',5000
getgrgid SELECT name,password,'%1$u'
getgrent SELECT 'members','members',5000
memsbygid SELECT username \
FROM users
gidsbymem SELECT 5000
- My user IDs start at 1 in the DB, but must start at 5000 for the system (5000+id).
/bin/bash
for everyone.- The
$HOME
directory formyuser
is/home/members/myuser
. - Everyone belongs to the
members
group, the GID of which is 5000.
/etc/pam-mysql.conf
users.host = localhost
users.database = mydatabase
users.db_user = root
users.db_passwd = root_password
users.table = users
users.user_column = username
users.password_column = password
users.password_crypt = 1
/etc/nsswitch.conf
passwd: compat mysql
group: compat
shadow: compat mysql
What I tried :
- Setting a password (SHA512 hash,
$6$...
) in the DB formyuser
. - Deleting the password first (
passwd -d
) : tells memyuser
cannot be found in/etc/passwd
. Same happens if I try to lock the account or force its password expiration. - Calling
passwd
from the root account, no changes. - Logging from a terminal on the machine (instead of
su
) : I get the authentication token manipulation error, and get sent back to the login prompt. Same when I try to connect with SSH (plus the password expiration warnings which are logical).
To me, it seems like the user management part (account/session ?) is correctly linked to MySQL, yet the password management part seems to rely partially on /etc/passwd
. Have I missed something in the configuration?