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'


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.

  • 1
    Do you see some AVCs from SELinux in audit log?
    – Jakuje
    Mar 18, 2017 at 12:23
  • /var/log/auth.log has entries like this: Mar 18 08:24:11 localhost su[1989]: Successful su for root by root Mar 18 08:24:11 localhost su[1989]: + ??? root:root Mar 18 08:24:11 localhost su[1989]: pam_setcred: Permission denied
    – tasket
    Mar 18, 2017 at 12:31
  • No, audit log is in /var/log/audit/audit.log
    – Jakuje
    Mar 18, 2017 at 12:32
  • No such file. The kernel has 'audit=0' parameter. Will try it without...
    – tasket
    Mar 18, 2017 at 12:35
  • The audit.log doesn't appear, but I got audit entries in /var/log/messages. Will append to main question.
    – tasket
    Mar 18, 2017 at 12:51

1 Answer 1


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.

  • If I understand you, there are three separate suggestions here: 1) use pam_permit before the pam_exec line, 2) change auth [... to auth required simple notation, 3) change auth sufficient pam_rootok to use bracketed criteria like [success=done default=die].
    – tasket
    Jul 1, 2017 at 11:59
  • I think #1 is not an option bc it grants access unconditionally. Also, #2 seems to have no effect. That leaves #3; I think you're saying that sufficient causes an auth failure regardless of what happens afterward in common-auth. But docs say 'failure of a sufficient module is ignored' and processing continues.
    – tasket
    Jul 1, 2017 at 12:09
  • There actually is four suggestions but let's start with 1) permit always succeeds but does not always allow access except with sufficient, in all other cases other cases the other modules also have a say. 2) excellent, now I know exactly what your failure is. See four. 3) it is ignored, but it is stored if you don't have a success somewhere else. this does the right thing if you only have sufficient modules and they all fail you don't get in. 4)remember sudo authenticates as the user you are changing from and su as the user you are changing to, and your code is confused by this. Cont ...
    – hildred
    Jul 1, 2017 at 15:19
  • ... cont. You can verify this by replacing your script with /bin/true for testing, or by running sudo as root.
    – hildred
    Jul 1, 2017 at 15:22
  • Adding required pam_permit before the pam_exec line does (sort of) work. As for /bin/true test, it does not work for su...same as using the original tool, which BTW is a part of the Qubes qrexec interface:
    – tasket
    Jul 4, 2017 at 6:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .