Red Hat Bugzilla – Bug 849241
SSHD sends garbage to pam_authenticate() if the user's shell is not installed on the target system
Last modified: 2013-06-20 10:27:37 EDT
Description of problem:
While testing SSSD's AD provider, I found this bug in the openssh server. The test user I was using had the following output from 'getent passwd testuser':
testuser:*:1886004704:1886000513:Test User.2 (EXT-RedHat/Espoo):/:/bin/ksh
I do not have the ksh package installed on my local system. This user was also marked in AD as "User must change password at next logon".
When I log in as that user using 'su', I am prompted to change my password. However, if I try to log in as that user with ssh, the user is rejected (and system logs show that the password was refused by the KDC).
When I instrumented SSSD to show the password in the debug logs (which it normally will not do, by design), it revealed that SSHD was sending us garbage data in the authtok field of the pam_data struct. This, naturally, fails to authenticate the user against the AD KDC.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. Create a user in AD with services for unix enabled
2. Set the user's shell to something that does not exist on the ssh server system.
3. Configure SSSD to authenticate against AD.
4. Follow the directions above.
SSH sends garbage to SSSD, which fails to evaluate it.
SSH should either fail earlier with a warning about the user's shell, or send the appropriate password to pam_authenticate() (and fail login later on due to the shell).
The SSSD team can aid you in setting up a reproducer if needed.
It is logged into /var/log/secure file:
Jun 20 13:48:13 f17-openssh sshd: User ksh not allowed because shell /bin/ksh does not exist
The openssh login process tries to not to expose information to client why login fails in order not to give a potential attacker information. So it follows the same steps for an illegal user as for a regular one.
Petr, while I agree there, I do have to ask why you call pam_authenticate() at all, once you know that the shell doesn't exist. Furthermore, why does it get called with bad data?
I'm not sure where it's getting the garbage it sends, either. Uninitialized buffer?
(In reply to Stephen Gallagher from comment #2)
> Petr, while I agree there, I do have to ask why you call pam_authenticate()
> at all, once you know that the shell doesn't exist. Furthermore, why does it
> get called with bad data?
openssh requires users to have a valid shell. It handles all invalid users same way - a non-existent user, a user with a locked password, a user with an invalid shell, ... and it tries to prevent username leaks via timing, so it calls pam_authenticate() with a bad password.
> I'm not sure where it's getting the garbage it sends, either. Uninitialized
It uses the hardcoded bad password:
static char badpw = "\b\n\r\177INCORRECT";