LightDM: How can I trigger a bash command everytime someone fail to login?

I'd like to take and save a picture from the webcam, every time someone tries to login into the system and fails. I know I can do that with:

mplayer -vo png -frames 1 tv://

The question is: How can I trigger this command when someone fails to login w/ LightDM?


Explanation

One way is to make use of the Authorization Log.

Authorization Log

The Authorization Log tracks usage of authorization systems, the mechanisms for authorizing users which prompt for user passwords, such as the Pluggable Authentication Module (PAM) system, the sudo command, remote logins to sshd and so on. The Authorization Log file may be accessed at /var/log/auth.log. This log is useful for learning about user logins and usage of the sudo command.

More here on LinuxLogFiles

On a failed login attempt, a record will be appended to the /var/log/auth.log file and the last line will contain something like:

pam_unix(gdm-password:auth): authentication failure;

If you constantly monitor the file for modification and check if the last line contains the keyword failure with for example grep failure then you know a failed login attempt has just occurred and you can run whatever command you want based on this action.


Solution

You can monitor the last line of the /var/log/auth.log file with a script like this:

#!/bin/bash

while true
do
       sleep 1


        if (( $(tail -1 /var/log/auth.log | grep failure | wc -l) == 1))

        then

                echo "failed login"

                # Your command here

        fi

done

Or even better, you can install inotify-tools and use inotifywait to monitor the file instead of the sleep 1 and the script will be like this:

#!/bin/bash

while inotifywait -q -e modify /var/log/auth.log >/dev/null

do

        if (( $(tail -1 /var/log/auth.log | grep failure | wc -l) == 1))

        then

                echo "failed login"

                # Your command here

        fi


done

inotify-tools can be installed with the following command:

sudo apt install inotify-tools

Implementation

To run this solution as a system service, please follow these steps:

  • Copy and paste the script code above ( without echo "failed login" as I added this line for debugging purposes only ) into a file in your home directory and name it TakePicture.sh and save the file.

  • Make the shell script file executable by running the following command in the terminal:

chmod +x ~/TakePicture.sh
  • Create and edit a custom systemd service to run the shell script at boot by running the following command in the terminal:
sudo nano /etc/systemd/system/TakePicture.service 
  • Copy and paste the following code into the editor, replace USERNAME with your username and save it by pressing Ctrl + X then press Y then press Enter :
[Unit]
Description=Take Picture

[Service]
Type=oneshot
ExecStart=/home/USERNAME/TakePicture.sh

[Install]
WantedBy=multi-user.target
  • Start the service by running the following command in the terminal:
sudo systemctl start TakePicture
  • Enable the service by running the following command in the terminal:
sudo systemctl enable TakePicture

Notice:

The authorization Log will contain all sorts of failed logins or authentications ( ie. GDM, SSH, terminal user authentication, sudo, ... etc. ).

If your aim is just to activate the script when an actual physical login happens ( ie. someone is sitting infront of your computer, using your keyboard and looking at your screen ), then you need to change the above if statement to be like this:

if (( $(tail -1 /var/log/auth.log | grep gdm | grep failure | wc -l) == 1))

if GDM is your login manager. This way the script will only be triggered if an actual failed physical login happens.

Best of luck