Назад | Перейти на главную страницу

Ошибка токена при попытке изменить пароль через pam-mysql

В настоящее время я готовлю машину для службы веб-хостинга, и я решил использовать MySQL для хранения всех наших пользователей (поскольку остальные наши службы уже используют его). Для этого я использую libnss-mysql и pam-mysql. Однако, несмотря на то, что большая часть настройки работает, я столкнулся с проблемой при попытке изменить пароль пользователя с помощью passwd.

На данный момент есть возможность создать пользователя (INSERT INTO) и войдите как этот пользователь, используя su. Машина не запрашивает пароль, и доступ к оболочке пользователя предоставляется напрямую. Однако как только я зарегистрируюсь как этот пользователь, passwd заканчивается на:

$ passwd myuser
passwd: Authentication token manipulation error
passwd: password unchanged

Согласно журналам MySQL, запрос выполняется, когда passwd вызывается, поэтому соединение с MySQL не является проблемой. Кроме того, когда я пытаюсь позвонить passwd с несуществующим пользователем я получаю соответствующий passwd: user 'doesnotexist' does not exist. passwd находит пользователя, но не может изменять его информацию. В auth.log файл журнала говорит:

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.

При звонке passwd -Sa чтобы получить статус всех аккаунтов, myuser счет действительно появляется. Кроме, getent passwd и getent shadow оба возвращают действительную запись для 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

Однако при запросе информации о старении myuser :

$ chage -l myuser
chage: user 'myuser' does not exist in /etc/passwd

В целом :

Вот несколько примеров конфигурации:

/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

/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

Что пробовал:

Мне кажется, что Управление пользователями часть (учетная запись / сеанс?) правильно связана с MySQL, но управление паролями часть, кажется, частично полагается на /etc/passwd. Я что-то упустил в конфигурации?

Хорошо, я нашел решение для этого. Первое: я настоятельно рекомендую всем, кто занимается этим, изучить Основы работы с модулями PAM. это действительно помогает понять все. Теперь давайте посмотрим на мою common-* файлы. Все они имеют одинаковую структуру:

facility    required    pam_unix.so [...]
facility    sufficient  pam_mysql.so [...]

Теперь, когда я больше прочитал о модулях PAM, мне это кажется смешным. Вот некоторая документация о флагах управления PAM:

обязательный : если модуль завершается успешно, выполняется остальная часть цепочки, и запрос удовлетворяется, если какой-либо другой модуль не дает сбой. Если модуль выходит из строя, остальная часть цепочки также выполняется, но запрос в конечном итоге отклоняется.

достаточно : если модуль завершился успешно и ни один из предыдущих модулей в цепочке не отказал, цепочка немедленно прерывается и запрос удовлетворяется. Если модуль выходит из строя, модуль игнорируется и выполняется остальная часть цепочки.

По сути, моя конфигурация заставляет PAM вести себя следующим образом: аутентификация UNIX через /etc/passwd и /etc/shadow должен иметь успех во всех случаях. Поиск MySQL также будет выполнен, но если аутентификация UNIX не удалась, его результат не будет принят во внимание.

При такой настройке механизм аутентификации MySQL становится бесполезным во всех ситуациях. Правильная конфигурация будет:

facility    sufficient  pam_mysql.so [...]
facility    required    pam_unix.so [...]

Что говорит: Достаточно механизма аутентификации MySQL. Если это удастся, дальнейшие механизмы тестирования не подлежат. Однако в случае неудачи аутентификация UNIX должна быть успешной. Поскольку у меня будет больше пользователей MySQL, чем пользователей UNIX, логичнее сначала пройти аутентификацию по MySQL.

Также важно отметить разницу в ролях PAM и NSS. С моей настройкой аутентификация был полностью функциональным, так как конфигурация NSS была правильной. NSS обрабатывает базовую аутентификацию UNIX, но не управление учетной записью / сеансом, а также подключения к конкретным службам (SSH / FTP / ...). Всем этим занимается PAM. Это разделение является причиной того, что было возможно root для подключения в качестве пользователя MySQL: NSS действительно нашел запись, и поскольку root не требует аутентификации против чего-либо, чтобы получить идентификационные данные пользователя, модули PAM никогда не вызывались.