Conditional PAM modules

I spent some time trying to setup PAM so that I could authenticate (locally for now) using my Yubikey. There are several resources on how to do that out there, so I won’t discuss the Yubikey setup and all, but I thought I’d drop a note about how I ended up doing “conditional” PAM entries.

Specifically, I wanted to achieve the following:

  • login as a regular user (which has no sudo powers) using either the Yubikey in challenge-response mode (and configured to require a button press), or the user’s password
  • login as root using both the Yubikey and the root password

The difficulty here is that the pam_yubico module is sufficient for a regular user, but required for root. After a few failed attempts in which I tried to use pam_rootok.so, I ended up with the following PAM configuration (using pam_succeed_if.so user = root) in /etc/pam.d/system-local-login:

# yubico module switcher: requisite for root, sufficient for non-root
# ("ignore=ignore" is *required*, otherwise the lightdm greeter fails on pam_setcred() with something about "PAM dispatch" and "ignore")
auth        [success=ok ignore=ignore default=2]    pam_succeed_if.so quiet user = root
# root
auth        requisite   pam_yubico.so mode=challenge-response chalresp_path=/var/lib/yubico
auth        [default=1] pam_permit.so
# non-root
auth        sufficient  pam_yubico.so mode=challenge-response chalresp_path=/var/lib/yubico

auth        include     system-login
account     include     system-login
password    include     system-login
session     include     system-login

It feels like assembly: if the user is not root, skip over the 2 entries for root users and end up on the sufficient entry for pam_yubico; if it is root, go on with the requisite entry (like required but failing early), then jump over the sufficient entry for non-root users. It’s not exactly pretty though.

Leave a Reply

Your email address will not be published. Required fields are marked *