tl; dr:
Funciona, mas alguns pacotes podem sobrescrever sua configuração e, em seguida, você está ferrado.
Eu fiz algum progresso aqui. Eu sei como executar algo na tentativa de autenticação * every * .
Meu /etc/pam.d/common-auth:
#
# /etc/pam.d/common-auth - authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules. See
# pam-auth-update(8) for details.
# here are the per-package modules (the "Primary" block)
auth [success=2 default=ignore] pam_unix.so nullok_secure
# here's the fallback if no module succeeds
auth optional pam_exec.so quiet /usr/local/bin/onlogin.sh fail
auth requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth optional pam_exec.so quiet /usr/local/bin/onlogin.sh ok
auth required pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth optional pam_ecryptfs.so unwrap
# end of pam-auth-update config
Então, vamos começar do topo:
auth [success=2 default=ignore] pam_unix.so nullok_secure
Padrão, o sucesso é igual a 1 aqui. Ele informa ao PAM quantas linhas ele deve pular se o usuário tiver autenticado com sucesso. Eu mudei para 2, porque eu adicionei a linha:
auth optional pam_exec.so quiet /usr/local/bin/onlogin.sh fail
Portanto, auth
informa ao PAM para executar o comando em todas as autenticações, é claro. Então optional
deve passar o script mesmo se houver um erro, eu acho.
pam_exec.so
é uma biblioteca que executa o script /usr/local/bin/onlogin.sh
com fail
como um parâmetro, porque essa linha é executada quando o usuário digita credenciais erradas. Eu adicionei quiet
, porque na minha VM houve um erro em cada sudo
/ su
autenticação.
A próxima linha, terminando com pam_deny.so
, como o nome diz, impede o acesso do usuário. É o padrão aqui.
Em seguida, a mesma linha acima, mas terminando com ok
, para informar ao script que o usuário foi autenticado com êxito.
auth optional pam_exec.so quiet /usr/local/bin/onlogin.sh ok
Tudo estava funcionando corretamente, mas… O problema foi quando tentei fazer o login na conta de convidado do Ubuntu. Porque, uhm, não há autenticação . Nenhuma senha = sem autenticação. Neste caso, a solução fornecida por @NGRhodes funciona.
Na minha VM xenial do Ubuntu tudo funcionou corretamente, então eu mudei para a minha máquina física, reiniciei a máquina, conectei-me à minha conta, conectei-me ao convidado. Boa. Reinicialize novamente - funciona como um encanto.
Então, à noite, como todos os dias, atualizei minha máquina. Reinicie. Log in. Senha incorreta. Tentei novamente - senha incorreta… Inicializando alguma distro ao vivo, cd
into /etc/pam.d/
para desligar isso e o que eu vejo? success=2
se tornou success=1
e cada tentativa - com sucesso ou com falha - executou pam_deny.so
.
Iniciado novamente, logado com sucesso, tailf /var/log/apt/history.log | grep -i pam
e algum libpam-cgfs
selvagem aparece. Então, este pacote (provavelmente) substituiu parte de /etc/pam.d/common-auth
.
Anexando onlogin.sh
para descendentes :) - lembre-se de instalar o fswebcam primeiro.
#!/bin/bash
# $PAM_* variables are described in 'man pam_exec'
RESULT="${1}" # login result (ok/fail)
WEBCAM_DEV="/dev/video0" # webcam device
WEBCAM_RES="1280x720" # desired screen resolution (if too large fswebcam fallbacks to device's max)
FRAMES="1" # how many shots to take (also add nanoseconds to date in filename to prevent overwrite and/or fswebcam crash)
PHOTO_DIR="/opt/_webcam" # where to save photos
FILENAME="${RESULT}_${PAM_USER}_$(date +%Y-%m-%d_%H-%M-%S).jpg" # filename
OUTPUT="${PHOTO_DIR}/${FILENAME}" # dir+filename
# create dir
mkdir -p ${PHOTO_DIR}
# append to the log
if [[ ${RESULT} == 'ok' ]]; then
RESULT='succeed'
else
RESULT='failed'
fi
logger -t 'onlogin.sh' "Login ${RESULT} by ${PAM_SERVICE} at ${PAM_TTY} for user ${PAM_USER}"
# say cheeeeese (if authorization is provided by lightdm)
if [[ ${PAM_SERVICE} == "lightdm" ]]; then
fswebcam -d ${WEBCAM_DEV} -r ${WEBCAM_RES} --jpeg 90 -q -F ${FRAMES} ${OUTPUT}
else
# if authorization is provided by something else (e.g. sudo) do nothing
:
fi
Algumas mensagens foram muito úteis: