I know how to execute an action on login, by adding a line to /etc/profile. But that only gets executed, if the login was successful. I would like to have action executed even when login fails. For example run a script script.sh.

I suspect, this can be set up in pam, but I have no idea where to start.


You can do this with pam_exec module and some PAM trickery. PAM configuration is usually very different across distributions so you will have to understand your configuration and try to tweak it.

For Debian (tested with 7.1) edit /etc/pam.d/common-auth (comments left out for clarity)

  • before

    auth    [success=1 default=ignore]    pam_unix.so nullok_secure
    auth    requisite                     pam_deny.so
    auth    required                      pam_permit.so
  • after

    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

What is actually happing, is that in case pam_unix.so succeeds, it will skip 2 following modules and jump to the pam_permit.so which will always succeed. In case of authentication failure PAM continues with execution of our script first, followed by pam_deny. That one will always fail, and because it has requisite control flag set no other module will be executed.

For completeness, program spawned by pam_exec runs with real user ID of the calling process (setuid option makes it run with effective user ID) and the process environment looks like this

| improve this answer | |
  • I have just realized that I can use pam_exec.so /bin/echo, but pam_exec.so /bin/echo > /tmp/foo does not work (nothing happens). Do you know why? – Martin Vegter Jul 26 '14 at 11:10
  • @MartinVegter That is because the > character is a redirect operator, which is supported in shells. PAM is not calling a shell to run the command, though - it's just calling the command directly. You could try to manually spool up a shell with pam_exec.so /bin/sh -c 'echo > /tmp/foo' and see if that works – JamesTheAwesomeDude Sep 21 '15 at 0:24
  • Is there any way to redirect output to the current terminal prompting for authentication? – tetris11 Oct 6 '16 at 21:44
  • Edit: current hack involves echoing everything to /dev/pts/{0,1,2} but this is messy for obvious reasons. Second hack involves in PTS=$(lsof | grep /dev/pts | grep -vP "(bash|lsof|grep)" > $tmp && awk '{print $NF}' $tmp | uniq; rm $tmp) but there's no gaurantee on this one either. – tetris11 Oct 6 '16 at 22:02
  • Found it: PTS=`lsof | grep -P "^$PAM_TTY\s.*/dev/pts" | awk '{print $NF}'| uniq` – tetris11 Oct 6 '16 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.