I'm trying to allow root access from a regular user shell based on the successful execution of a special program, and the goal is to have both su
and sudo
respond to the new PAM configuration. The special program is the sole criteria for authorization.
The config I'm trying on Debian 9 in /etc/pam.d/common-auth is:
auth [success=done default=die] pam_exec.so seteuid /usr/bin/whoami
…where whoami
is a program that returns successful status as a placeholder for the special program. The rest of the common-auth file is commented-out.
The /etc/pam.d/su file has:
auth sufficient pam_rootok.so
session required pam_env.so readenv=1
session required pam_env.so readenv=1 envfile=/etc/default/locale
session optional pam_mail.so nopen
session required pam_limits.so
@include common-auth
@include common-account
@include common-session
The result is that sudo
will be authorized, but su
will not be:
$ su
su: Permission denied
(Same results on Fedora 25 using the system-auth file: sudo works and su doesn't.)
It looks as if su
simply refuses to work with pam_exec. At this point I'm at a loss and could use some clues to work through this issue…
Looking through /var/log/messages, this gets logged when su
is attempted:
Mar 18 08:46:39 localhost kernel: [ 61.622184] audit: type=1100 audit(1489841199.166:114): pid=1107 uid=1000 auid=1000 ses=1 msg='op=PAM:authentication acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/0 res=success'
Mar 18 08:46:39 localhost kernel: [ 61.622480] audit: type=1101 audit(1489841199.166:115): pid=1107 uid=1000 auid=1000 ses=1 msg='op=PAM:accounting acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/0 res=success'
Mar 18 08:46:39 localhost kernel: [ 61.623224] audit: type=1103 audit(1489841199.167:116): pid=1107 uid=1000 auid=1000 ses=1 msg='op=PAM:setcred acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/0 res=failed'
For comparison, here is what happens with sudo
:
Mar 18 08:47:00 localhost kernel: [ 82.750720] audit: type=1123 audit(1489841220.294:117): pid=1110 uid=1000 auid=1000 ses=1 msg='cwd="/home/user" cmd=67726570202D69206175646974202F7661722F6C6F672F6D65737361676573 terminal=pts/0 res=success'
Mar 18 08:47:00 localhost kernel: [ 82.751369] audit: type=1110 audit(1489841220.295:118): pid=1110 uid=0 auid=1000 ses=1 msg='op=PAM:setcred acct="root" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=failed'
Mar 18 08:47:00 localhost kernel: [ 82.751814] audit: type=1105 audit(1489841220.295:119): pid=1110 uid=0 auid=1000 ses=1 msg='op=PAM:session_open acct="root" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
UPDATE
I arrived at a solution reflecting Debian's way of handling this issue, which is getting a solid determination of success or fail despite various commands which authenticate in different contexts, as @hildred pointed out. First, I'll show relevant lines from Debian's default common-auth:
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth requisite pam_deny.so
auth required pam_permit.so
And here is the replacement that utilizes the Qubes auth prompt:
auth [success=1 default=ignore] pam_exec.so seteuid /usr/lib/qubes/qrexec-client-vm dom0 qubes.VMAuth /bin/grep -q ^1$
auth requisite pam_deny.so
auth required pam_permit.so
This "skips one" to permit only on success, otherwise deny.
The suggestion from @hildred to 'prime' the stack with a pam_permit line before the pam_exec line (where the decision is made) is less expressive but does also work and it put me on the path of finding a clear solution.
Best Answer
There are two issues I see right off the bat (other than trying experimental pam configs on common instead of just one service) is that su always authenticates as root whereas sudo usually authenticates as the user, and su has a auth sufficient line and you use bracket notation in the common file. The bracket notation does not always set your success state. This can be fixed by adding an auth requires permit line before the exec or dropping the bracket notation as for your use case it is not needed or by also using bracket notation on the root ok line so that failing the sufficient test does not set negative success.