I was trying to use pam_exec.so on Ubuntu to call a script, prompt for user input and allow the user to log in through SSH if the script exits with an exit code of 0. I was unable to get this to work. So I wrote a simple script as follows to test pam_exec.so and see if the problem was with my original script. However I am getting the same issues even with this simple script.


echo -n "Please enter your name:"
read name
echo "Hello $name"

I called it by including the following line after @include common-auth in /etc/pam.d/sshd

auth    required        pam_exec.so stdout /usr/local/bin/test.sh

But when I SSH into this system as seen below, I do not get a prompt to enter any input. As soon as I enter the password, I get logged in. However, the output of the script is visible. enter image description here

Then I changed the above script as follows to exit with an exit code of 1 if no input is given.

echo -n "Please enter your name:"
read name
if [ -z "$name" ]
        exit 1
        echo "Hello $name"
        exit 0

Then I am unable to SSH into the system (screenshot below) even when I enter the correct password and I do not see any output of the script.

enter image description here

So what I want to know is how can I correct this problem and use pam_exec.so to run a script, get user input, and allow ssh authorization only if that script exits with an exit code of 0?

  • 1
    pam_exec doesn't handle user input, so you have to look for a different solution. – Ipor Sircer Nov 7 '17 at 7:12
  • 1
    @IporSircer, do you know any PAM module for this task that can accept user input? I was unable to find one – Nilushan Costa Nov 8 '17 at 10:03

I'm not familiar with pam_exec.so implementation but I've done a small PAM and I think it's tricky for any module to handle interactive session with a third-party script due to the way PAM conversation works (pam_conv_* functions) and the need to know when the third party script would be reading from stdin or not (as the script is not simply exec by the module in foreground).

Depending on the amount of effort one is willing to go, building a PAM is not complicated and you have easy to read examples in python or golang

Another (maybe quicker) option is to use stdin option in pam_exec.so.
Security aside, and depending on your use case, this might be enough as it sends the password to the script stdin.

If having your script input concatenated with password is an option for you (like some 2FA implementations where you input password + OTP in the password field):

  • Add stdin option to your pam_exec.so line
  • In your script, split password from your second input
  • Handle password authentication itself (as pam_unix will fail to do it with the extra input)
  • Make use of your extra input
| improve this answer | |
  • From be manual on Debian the stdin option seem to be called expose_authtok – MrCalvin Feb 23 at 16:47

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.