Erro de token ao tentar alterar a senha através do pam-mysql

2

Atualmente, estou preparando uma máquina para um serviço de hospedagem, e decidi usar o MySQL para armazenar todos os nossos usuários (já que o resto de nossos serviços já o utilizam). Para isso, estou usando libnss-mysql e pam-mysql . No entanto, embora a maior parte da configuração esteja funcionando, estou enfrentando um problema ao tentar alterar a senha de um usuário com passwd .

No momento, é possível criar um usuário ( INSERT INTO ) e fazer login como esse usuário usando su . A máquina não solicita uma senha e o acesso ao shell do usuário é fornecido diretamente. No entanto, uma vez que eu estou logado como este usuário, passwd termina com:

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

De acordo com os logs do MySQL, uma consulta é feita quando passwd é chamado, portanto, a conexão com o MySQL não é um problema. Além disso, quando tento chamar passwd com um usuário inexistente, recebo um passwd: user 'doesnotexist' does not exist apropriado. passwd encontra um usuário, mas não pode modificar suas informações. O arquivo de log auth.log diz:

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.

Ao chamar passwd -Sa para obter o status de todas as contas, a conta myuser aparece. Além disso, getent passwd e getent shadow retornam uma entrada válida para 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

No entanto, ao solicitar informações antigas sobre myuser :

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

Ao todo:

  • su encontra o usuário e executa um login sem senha em todos os casos (se eu for root, caso contrário, será solicitada uma senha e o erro do token).
  • chage não consegue encontrar o usuário; parece procurar /etc/passwd em vez do DB.
  • passwd encontra o usuário, mas retorna um erro de token ao tentar editá-lo.

Aqui estão algumas amostras de configuração:

/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
  • Meus IDs de usuário começam em 1 no banco de dados, mas devem começar em 5000 para o sistema (5000 + id).
  • /bin/bash para todos.
  • O diretório $HOME de myuser é /home/members/myuser .
  • Todos pertencem ao grupo members , cujo GID é de 5.000.

/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

O que eu tentei:

  • Definindo uma senha (SHA512 hash, $6$... ) no banco de dados por myuser .
  • Excluindo a senha primeiro ( passwd -d ): informa que myuser não pode ser encontrado em /etc/passwd . O mesmo acontece se eu tentar bloquear a conta ou forçar a expiração da senha.
  • Chamando passwd da conta raiz, sem alterações.
  • Efetuando log a partir de um terminal na máquina (em vez de su ): recebo o erro de manipulação de token de autenticação e sou enviado de volta ao prompt de login. O mesmo quando tento conectar-me ao SSH (mais os avisos de expiração da senha, que são lógicos).

Para mim, parece que a parte gerenciamento de usuários (conta / sessão?) está corretamente vinculada ao MySQL, mas a parte gerenciamento de senhas parece depender parcialmente de% código%. Eu perdi algo na configuração?

    
por John WH Smith 28.06.2014 / 23:23

1 resposta

2

Ok, eu encontrei a solução para isso. Primeiro: recomendo veementemente que alguém entre nessa seção para estudar os princípios básicos dos módulos do PAM . Isso realmente ajuda a entender a coisa toda. Agora, vamos dar uma olhada nos meus arquivos common-* . Todos eles têm a mesma estrutura:

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

Agora, depois de ler mais sobre os módulos do PAM, isso parece ridículo para mim. Aqui está alguma documentação sobre os flags de controle do PAM:

required : if the module succeeds, the rest of the chain is executed, and the request is granted unless some other module fails. If the module fails, the rest of the chain is also executed, but the request is ultimately denied.

sufficient : if the module succeeds and no earlier module in the chain has failed, the chain is immediately terminated and the request is granted. If the module fails, the module is ignored and the rest of the chain is executed.

Basicamente, minha configuração faz o PAM se comportar da seguinte maneira: a autenticação do UNIX através de /etc/passwd e /etc/shadow deve ser bem-sucedida em todos os casos. A pesquisa do MySQL também será executada, mas se a autenticação do UNIX falhar, seu resultado não será levado em conta.

Com essa configuração, o mecanismo de autenticação do MySQL é inutilizado em todas as situações. Uma configuração adequada seria:

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

Qual diz: O mecanismo de autenticação do MySQL é suficiente. Se for bem sucedido, nenhum outro mecanismo deve ser testado. Se falhar, no entanto, a autenticação do UNIX deve ser bem-sucedida. Como terei mais usuários do MySQL que usuários do UNIX, é mais lógico autenticar em relação ao MySQL primeiro.

Também é importante notar a diferença nas funções do PAM e do NSS. Com a minha configuração, a autenticação funcionou perfeitamente desde que a configuração do NSS estava correta. O NSS lida com a autenticação básica do UNIX, mas não gerenciamento de conta / sessão, nem conexões específicas de serviço (SSH / FTP / ...). Todos estes são manipulados pelo PAM. Essa separação é a razão pela qual era possível que root se conectasse como um usuário MySQL: o NSS encontrou a entrada, e como root não precisa autenticar nada para ter a identidade de um usuário, os módulos PAM nunca foram chamados .

    
por 30.06.2014 / 03:27