- Posted In
- Red Hat Enterprise Linux
RHEL 7 and pam_pwhistory - old password can still be re-used
The intent is to prevent a user from re-using old passwords. We elect to remember 4 previous passwords in our requirements. We are trying to implement this on RHEL 7.2.1511.
Previously, this should be done via pam_unix.so, but we now have pam_pwhistory.so, so I base my attempts around it.
First, we examine /etc/pam.d/passwd to see what is used for the service:
#%PAM-1.0 auth include system-auth account include system-auth password substack system-auth -password optional pam_gnome_keyring.so use_authtok password substack postlogin
Surprisingly, it's not password-auth, but rather system-auth that's used (probably because password-auth is used for remote authentication (e.g. sshd), whereas system-auth is geared more towards local authentication -- just my guess).
So, we look at the system-auth: ls -l /etc/pam.d/system-auth results in:
lrwxrwxrwx. 1 root root 16 Aug 2 16:34 /etc/pam.d/system-auth -> system-auth-ac
As system-auth-ac is overwritten automatically by authconfig, it's recommended to create a different file and link it to your system-auth. We choose to call ours "system-auth-paid". Here are its contents:
auth include system-auth-ac account include system-auth-ac password include system-auth-ac session include system-auth-ac
Next, we modify it to use our specs:
auth include system-auth-ac account include system-auth-ac password substack system-auth-ac password required pam_pwhistory.so debug use_authtok remember=4 session include system-auth-ac
Only two things changed here:
1) I included password directives from "system-auth-ac" as a substack, rather than plain include (had to do this after some testing).
2) I added a new line for pam_pwhistory.so with three parameters (debug, use_authtok, remember=4).
Now I try to test this with a non-elevated user.
I had already changed the password once, so I have two values for passwords: CURRENT_PASSWORD and OLD_PASSWORD.
passwd # here, I am logged in as a non-elevated user called 'testuser' Changing password for user testuser. Changing password for testuser. (current) UNIX password: CURRENT_PASSWORD New password: OLD_PASSWORD Retype new password: OLD_PASSWORD Password has been already used. Choose another. passwd: Have exhausted maximum number of retries for service
This would appear to be exactly what we want. The problem is that now OLD_PASSWORD is actually set as my password, despite the system telling me that it was rejected (?!)
At the same time, I am tailing /var/log/messages to see what "debug" directive from pam_pwhistory.so spits out.
Snippet from /var/log/messages
Aug 3 12:27:48 localhost passwd: pam_unix(passwd:chauthtok): password changed for testuser Aug 3 12:27:48 localhost passwd: pam_pwhistory(passwd:chauthtok): pam_sm_chauthtok entered Aug 3 12:27:48 localhost passwd: pam_pwhistory(passwd:chauthtok): got new auth token Aug 3 12:27:48 localhost passwd: pam_pwhistory(passwd:chauthtok): check against old password file Aug 3 12:27:48 localhost pwhistory_helper: New password already used # <--- this is good Aug 3 12:27:48 localhost passwd: pam_pwhistory(passwd:chauthtok): Aborted, too many tries Aug 3 12:27:48 localhost passwd: gkr-pam: no password set, and use_authtok was specified # <--- ???
1) Right now, although OLD_PASSWORD appears to have been rejected, it's actually my new password!
2) Looking at /var/log/messages last line, I thought I should remove use_authtok. But if I do so, then I obviate previous directives (e.g. from pam_pwquality.so) which are very useful and should be passed onto this stage.
3) Also, if I do go ahead and remove use_authtok, so that my line looks like this:
password required pam_pwhistory.so debug remember=4
I still have the same problem. So, I chose to leave use_authtok in.
Finally, if I change "required" directive to "requisite", so that it looks like this:
password requisite pam_pwhistory.so debug use_authtok remember=4
I still have the same problem.
Looking for any ideas/help. Greatly appreciated.
Small update: I was confused by this line in /var/log/messages:
It turns out that this is a gnome-keyring message. So something funky is going on with gnome-keyring and passwd binary, in conjunction to password-auth file. I will explore further.
gnome-keyring repoted some problems in /var/log/audit/audit.log
First, I placed SELinux in Permissive mode to see if it would help. It didn't, original problem persisted.
I returned SELinux to Enforcing state.
Then I still ran 'sealert -a /var/log/audit/audit.log' with this result:
I then ran audit2allow, as specified in log above and applied the policy.
Again, no changes.
I wonder if there is a bug in gkr-pam?
So, there's a solution, but it's a dirty one.
At issue is how we include authconfig-generated "system-auth-ac" file into my custom file "system-auth-paid".
To remind you, I created a file called "system-auth-paid" and it contains these values:
I then made a symbolic link called "system-auth", which points to "system-auth-paid" (this is the best practice, according to RHEL security guide; it's advised because authconfig will overwrite system-auth-ac so you want to have your overrides in a separate file).
However, this inclusion did not work.
So instead, I copied the contents of system-auth-ac directly into system-auth-paid custom file and changed the ordering slightly. I embedded my directive smack in the middle of "password" block of system-auth-ac.
My custom system-auth-paid now looks like this:
This works as expected: old password is remembered and rejected. I must select a new password and cycle through 4 previous ones.
Since I had to insert my directive in the middle of the stack, I see no way to work around this by in-lining the system-auth-ac and then putting my instruction after it. It looks like I must modify the file directly.
However, if I modify it, I lose any changes from authconfig to system-auth-ac in the future.
So, what's the sanctioned way of going about this?
There is apparently no way. This feature was requested, but rejected for no reason: https://bugzilla.redhat.com/show_bug.cgi?id=1271804
the "reason" , is that this is Red Hat, and... Red Hat never, EVER, actually fix anything.