Redhat – Need help understanding PAM directives

freeradiusgoogle-authenticatorldappamredhat

I have the following directives in my /etc/pam.d/sshd file on a RHEL5 box and I'm a bit confused. These directives are there to make LDAP+RADIUS+OTP work. What I'm trying to do is tell pam not to check users UID < 499 for LDAP+RADIUS+OTP and also to exclude UID = 30027 from being checked for the same.

This directive works as intended. It checks if UID >= 499 and if it is, it skips (auth sufficient pam_unix.so nullok_secure).

auth [success=1 default=ignore] pam_succeed_if.so uid >= 499 quiet

I'm confused here. This should do LDAP+RADIUS+OTP since success=1 but somehow it still works. Shouldn't it be skipping the next rule if true?

auth [success=1 default=ignore] pam_succeed_if.so uid eq 30027 quiet
auth sufficient pam_unix.so nullok_secure
auth sufficient  pam_radius_auth.so
auth required /lib/security/pam_google_authenticator.so forward_pass

Although, I've gotten things to work as I want them to, I'm confused behind the logic of it.


Update

Ok, so this is what I get in /var/log/secure when I ssh using a local user that has an uid of 30327 –

Aug  8 08:21:30 journey sshd[9357]: Accepted keyboard-interactive/pam for sidd from 10.1.1.178 port 51242 ssh2
Aug  8 08:21:30 journey sshd[9357]: pam_unix(sshd:session): session opened for user sidd by (uid=0)

This is what I get ssh using root who has a uid of 0 (<499).

Aug  8 08:25:51 journey sshd[9402]: Accepted keyboard-interactive/pam for root from 10.1.1.178 port 51246 ssh2
Aug  8 08:25:51 journey sshd[9402]: pam_unix(sshd:session): session opened for user root by (uid=0)

This is what I get when I use an ldap user with just LDAP password and no OTP –

Aug  8 08:27:04 journey sshd[9447]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=journey  user=schoure
Aug  8 08:27:05 journey sshd(pam_google_authenticator)[9447]: Failed to read "/home/schoure/.google_authenticator"
Aug  8 08:27:07 journey sshd[9445]: error: PAM: Cannot make/remove an entry for the specified session for schoure from journey

This is what I get when I use an ldap user with LDAP + OTP –

Aug  8 08:28:13 journey sshd[9452]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=journey  user=schoure
Aug  8 08:28:13 journey sshd[9450]: Accepted keyboard-interactive/pam for schoure from 10.1.1.178 port 43068 ssh2
Aug  8 08:28:13 journey sshd[9450]: pam_unix(sshd:session): session opened for user schoure by (uid=0)

So you are right – pam_unix does fail for LDAP users but since it's set to "sufficient" it's not terminal. Thanks for clearing that up.

As to your other point of –

auth [success=1 default=ignore] pam_succeed_if.so uid eq 30027 quiet

not getting evaluated, I see that it is getting evaluated. If I comment out that directive, I get

Aug  8 08:34:39 journey sshd(pam_google_authenticator)[9537]: Failed to read "/home/sidd/.google_authenticator"
Aug  8 08:34:42 journey sshd[9535]: error: PAM: Cannot make/remove an entry for the specified session for sidd from journey

So I am still confused as to how this works since clearly 30327 > 499 and hence it should skip the second line. The only reason I can see this working if PAM some how adds an implicit OR between the first two lines.

UPDATE 2

Ah, I see what is happening. That line in effect is just a place holder. I changed that UID to some random UID that doesn't exist and it still worked. So I understand the logic –

  1. Line 1 checks UID. If it's more than 499, it skips to line 3 where it is checked locally. Since UID > 499 are not local, that condition fails but being a non-terminal directive, it moves on to LDAP + RADIUS + OTP.
  2. If I comment out line 2 which has a particular UID set, what happens is PAM completely skips over local authentication because of the success=1.

So in effect, me doing something wrong made it work. I get what I need to do and it's working for me.

I don't want local users to be authenticated via LDAP + RADIUS + OTP, so these three lines should do the job for me. They are working but I would just like confirmation that they are right –

auth sufficient pam_unix.so nullok_secure
auth sufficient  pam_radius_auth.so
auth required /lib/security/pam_google_authenticator.so forward_pass

Best Answer

Are you really sure it's skipping pam_unix.so?

sufficient is a "non-terminal" behavior on failure. Even if the pam_unix.so check fails, authentication will go on to attempt pam_radius_auth.so.

My interpretation is:

  • The uid eq 30027 check will never return true. The test will only run if the uid is <499, making it impossible for the condition of uid eq 30027 to be true.
  • pam_unix.so would be attempted in all scenarios, and if it fails, pam_radius_auth.so would be attempted.
  • pam_google_authenticator.so will be attempted if both of them fail.

Check your logs again. The radius logins may not be failing, but the pam_unix.so check probably is logging a failure. It just isn't preventing your logins.


This answer accurately covers the scope of the original question. Any additional questions that have been posed through updates or comments will not be covered.