Description of problem:
If you setup postgresql to use pam authentication, it will fail to authenticate for pam_unix (local account) logins. It will work for pam_krb5 logins.
By reading the unix_chkpwd man page, I learned that it can also expect to be sgid in the shadow group. By adding a shadow group, making /usr/sbin/unix_chkpwd and /etc/shadow owned by root:shadow, and making /usr/sbin/unix_chkpwd suid root and sgid shadow, and finally making /etc/shadow 040 for permissions, I was able to get it to work. Unfortunately, when the new pam update came down, it blew away the file permissions and changed the ownership back on /usr/sbin/unix_chkpwd. It started working again, once I changed it back to how I described it.
Version-Release number of selected component (if applicable):
I believe this effects multiple versions, but I haven't checked them all.
The one I tested on RHEL 7.2 and 7.3 was pam-1.1.8-18 and whatever one comes as the default for RHEL 7.2 with it not yet updated.
Very reproducible and deterministic.
Steps to Reproduce:
I first figured it out on a 7.3 system. I took a RHEL 7.2 ISO and installed it into a VM clean, installed postgresql-server and setup a database with a user to match a local user account name. Next, I changed all of the methods to pam in pg_hba.conf, and restarted postgresql. I then attempted to connect to localhost using a local user account (testuser), and got the messages
unix_chkpwd: check pass; user unknown
unix_chkpwd: check pass; user unknown
unix_chkpwd: password check failed for user (testuser)
journal: nweb testxdb 188.8.131.52(37182) authentication: pam_unix(postgresql:auth): authentication failure; logname= uid=26 euid=26 tty= ruser= rhost=127.0.0.1 user=testuser
After making the changes I described above, I tried again, and was able to get authenticated.
(Some of this is from memory, so please forgive if I added an unneeded step as I'm walking through shell history.)
0. adduser testuser and give it a password.
1. yum install postgresql postgresql-contrib postgresql-server
2. su - postgres
5. systemctl start postgresql.service
6. su - postgres
7. createuser testuser
8. modify pg_hba.conf to have all methods changed from trust to pam.
8.? you may need to modify postgresql.conf's listen_addresses to be '*'.
10. systemctl stop postgresql.service
11. systemctl start postgresql.service
12. su - testuser
13. psql postgres
14. Enter the password. When it fails, check the results in /var/log/secure
15. exit # Back to root
The FIX (as root):
16. groupadd shadow
17. chown root:shadow /etc/shadow /usr/sbin/unix_chkpwd
18. chmod 6755 /usr/sbin/unix_chkpwd
19. chmod 0040 /etc/shadow
20. su - testuser
21. psql postgres
22. Enter the password, and you are in.
Unable to login to database. PAM Authentication fails for correct password. (I even changed the password to something horribly simple, and retried multiple times to make sure I wasn't typing my long password incorrectly.)
User should be able to login and have it authenticate against the local account.
I saw one place mention this on the web for centos 6 also. I did see some other pam_unix issues in bugzilla for other services, which may be having similar problems. I choose to document this for the use case I was having, since I can't be sure without testing it and knowing something about those services.
Something I forgot to mention, I did try changing the SELinux policy to permissive as a part of my testing, just to make sure I hadn't missed something in that area. I still got the same behavior.
I do not think we are going to modify the permissions on unix_chkpwd and /etc/shadow. One of the reasons is that it would break requirements of various security profiles. I would recommend either not to use the system account database for PostgreSQL and similar services at all or try to configure authentication to go through sssd as proxy for the local system accounts - it should work.
Development Management has reviewed and declined this request. You may appeal this decision by reopening this request.