urbanserj/entente — pull request #2 by dbaarda (2014-01-14 06:17:46+00:00)
Title: Make auth_pam() non-blocking.

Thanks for your warning about the pam_authenticate being blocking.

I did a bunch of digging around and found the following;

a) Your code was doing pam_fail_delay(pamh, 0) in an attempt to turn off the failure delay. This wouldn't work for 2 reasons;
1) The && after the pam_start() attempt would mean this would only be executed if pam_start() failed.
2) pam_fail_delay() doesn't set the delay, it requests a minimum delay. Any pam modules can set a delay and the longest delay requested is what is used.

b) You can mess with your /etc/pam.d/ settings to turn off the delay. In particular, pam_unix.so has a nodelay option, and there is a pam_faildelay.so that can be used to set the delay. See;
http://www.krenel.org/pam-adjusting-timeout-in-invalid-logins-nodelay-faildelay/

c) You can pam_set_item() for PAM_FAIL_DELAY to set your own delay handler function.

This fix chooses option c) for now to use an empty delay handler. Note that clients using pam_ldap auth can set up their own /etc/pam.d/ settings to do the failure delay client-side (I haven't looked, but it's possible the default pam_ldap auth configs already do that).

I may in the future add support in that delay handler for delaying in an async-friendly way, and maybe even delay all followup bind attempts by the same user. This would make the system more resistant to brute force attacks talking directly to the ldap server.