So, requiring both is doable, for both sudo and login (assuming you’re using gdm, not sure how to do it with others). The others, not quite. I’m using Arch, so you may need to adjust for your distro.
For user login, assuming you’re using GDM, replace the contents of both /etc/pam.d/gdm-fingerprint
and /etc/pam.d/gdm-password
with this:
#%PAM-1.0
auth requisite pam_fprintd.so
auth include system-local-login
auth optional pam_gnome_keyring.so
account include system-local-login
password include system-local-login
password optional pam_gnome_keyring.so use_authtok
session include system-local-login
session optional pam_gnome_keyring.so auto_start
To be clear, this is the original contents of gdm-password
with this line added as the first auth line:
auth requisite pam_fprintd.so
With that change, GDM will ask for a fingerprint then let you enter a password.
Then, for sudo, you can make it require both by editing /etc/pam.d/sudo
and replacing the sufficient
on the auth line for pam_fprintd.so
to required
. My config looks like this:
#%PAM-1.0
auth required pam_fprintd.so
auth include system-auth
account include system-auth
session include system-auth
Now, 3-5 are trickier. PAM does have a timestamp plugin that mirrors sudo’s in some ways, but it doesn’t quite fit exactly what you’re looking for – for case 3, it doesn’t cache correctly with sudo (as it seems to be more intended for caching logins than for sudo). When authenticating, sudo requests that you authenticate as yourself, so the target user for the PAM timestamp is yourself. However, when generating timestamps, the PAM plugin uses the target user for the session – which in this case, is root (or whatever other user you’re running as).
This is the verbose log when attempting to authenticate for sudo using the cached timestamp (reverse order):
Jan 17 14:49:48 Xenon sudo[513117]: pam_timestamp(sudo:auth): cannot open timestamp `/var/run/pam_timestamp/animus/tty3': No such file or directory
Jan 17 14:49:48 Xenon sudo[513117]: pam_timestamp(sudo:auth): using timestamp file `/var/run/pam_timestamp/animus/tty3'
Jan 17 14:49:48 Xenon sudo[513117]: pam_timestamp(sudo:auth): tty is `/dev/tty3'
Jan 17 14:49:48 Xenon sudo[513117]: pam_timestamp(sudo:auth): currently user `animus'
Jan 17 14:49:48 Xenon sudo[513117]: pam_timestamp(sudo:auth): becoming user `animus'
Then, after it authenticates, as part of the session management, it creates a timestamp, but this time the target user is whatever user you’re running as:
Jan 17 14:49:52 Xenon sudo[513117]: pam_timestamp(sudo:session): updated timestamp file `/var/run/pam_timestamp/animus/tty3:root'
Jan 17 14:49:52 Xenon sudo[513117]: pam_timestamp(sudo:session): using timestamp file `/var/run/pam_timestamp/animus/tty3:root'
Jan 17 14:49:52 Xenon sudo[513117]: pam_timestamp(sudo:session): tty is `/dev/tty3'
Jan 17 14:49:52 Xenon sudo[513117]: pam_timestamp(sudo:session): currently user `animus'
Jan 17 14:49:52 Xenon sudo[513117]: pam_timestamp(sudo:session): becoming user `root'
So, not sure it’s easily doable. If you’re determined, I’d make a custom PAM module based off the timestamp module. You could modify it not to make a different timestamp for different target users, then point your sudo configuration at that one. After letting PAM handle the caching, you can disable sudo’s built in password caching by setting the default timestamp_timeout
in /etc/sudoers
to 0.
Scenario 4 also is similar to the timestamp plugin’s functionality, but the timestamp plugin is based on last authentication (aka when you logged in/unlocked), not when you went idle. I’m not sure PAM is notified when you lock the screen/session, so I’m not sure how doable it is as you specify it. My workaround would be to use the timestamp plugin to allow you to unlock using only a fingerprint if you’ve authenticated fairly recently. You could do this by making the fingerprint required first, then have the timestamp be sufficient after (in gdm-password
and gdm-fingerprint
).
Scenario 5 is technically doable (the sleep part at least), by creating a systemd unit that runs on sleep that wipes the timestamps used by PAM. It would look something like this (note: I just wrote that off the cuff, haven’t tested it. It’s roughly based off a script I used for power management so it may need tweaking, particularly the remain/stop bits).