Você pode fazer isso com pam_exec module e alguns PAM trickery. A configuração PAM é geralmente muito diferente nas distribuições, então você terá que entender sua configuração e tentar ajustá-la.
Para o Debian (testado com 7.1) edite /etc/pam.d/common-auth (comentários deixados de fora para maior clareza)
-
antes
auth [success=1 default=ignore] pam_unix.so nullok_secure auth requisite pam_deny.so auth required pam_permit.so -
depois
auth [success=2 default=ignore] pam_unix.so nullok_secure auth optional pam_exec.so /common-auth-pam_exec auth requisite pam_deny.so auth required pam_permit.so
O que realmente está acontecendo, é que no caso de pam_unix.so ser bem-sucedido, ele irá pular 2 módulos seguintes e pular para o pam_permit.so que sempre terá sucesso. Em caso de falha de autenticação PAM continua com a execução do nosso script primeiro, seguido por pam_deny . Esse sempre falhará, e porque ele tem requisite flag flag set nenhum outro módulo será executado.
Para fins de conclusão, o programa gerado por pam_exec é executado com o ID do usuário real do processo de chamada (a opção setuid o faz executar com um ID de usuário efetivo) e o ambiente de processo é semelhante a este
PAM_SERVICE=login
PAM_RHOST=
PAM_USER=<username_here>
PAM_TYPE=auth
PAM_TTY=/dev/tty1