ODRecordAuthenticationAllowed does not check for expired accounts or loginHours restrictions

Originator:realvnc
Number:rdar://32072177 Date Originated:09-May-2017 11:21 AM
Status:Open Resolved:
Product:macOS + SDK Product Version:Sierra
Classification:Security Reproducible:Always
 
Area:
Something not on this list

Summary:
When calling ODRecordAuthenticationAllowed(), it checks for certain conditions on accounts, such as whether the account is disabled.

However, other conditions are not checked:
* ActiveDirectory accounts which have expired
* ActiveDirectory accounts where the loginHours restriction has been applied

Note that ODRecordVerifyPassword() does verify both of these conditions; yet, when a non-password-based authentication is being used (eg certificate, public-key, or Kerberos) these restrictions are not checked.

Note that pam_opendirectory invokes ODRecordAuthenticationAllowed() in its "account" actions, and ODRecordVerifyPassword() in its "auth" actions. This issue therefore allows users to log in the macOS's SSH server when the users should be denied.

This is a security defect, since it indirectly affects your SSH server.

The expected return codes from ODRecordAuthenticationAllowed() are kODErrorCredentialsAccountExpired and kODErrorCredentialsInvalidLogonHours. Preferably this should be fixed in the OpenDirectory framework, so that all applications are fixed, rather than hacking in a fix in pam_opendirectory or your OpenSSH distribution.

Steps to Reproduce:
1. Set up SSH for public key authentication (copy your public key to ~/.ssh/authorizedKeys)
2. Set an expiry time in the past for the ActiveDirectory account (or alternatively, deny access to the account via a "loginHours" restriction)
3. Attempt to authenticate using password authentication
4. Attempt to authenticate using the SSH keyfile

Expected Results:
I would expect both password and keyfile authentication to fail, since the account has expired (or restricted via "loginHours").

Actual Results:
Actually, password authentication does fail as expected, but keyfile access is incorrectly granted.

Version:
Sierra 10.12.4 (Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64)

Comments

Also, another security problem: when an account has been locked out due to too many failed authentication attempts (using the LDAP "lockoutTime" attribute), ODRecordVerifyPassword() succeeds when it should fail. Note that I (personally) don't expect ODRecordAuthenticationAllowed() to fail in this case, since account lockout applies to password-based authentication. Ideally of course, we wouldn't have to guess at all, if OpenDirectory behaviour were documented more thoroughly.

Note that when loginHours restrictions are applied, ODRecordVerifyPassword () incorrectly returns kODErrorCredentialsAccountExpired, when the correct return code is clearly kODErrorCredentialsInvalidLogonHours.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!