31

Using LDAP is checking a username/password as simple as attempting to bind as that user and noting the results, or is there a special LDAP "check password" function?

I'm trying to get a bit more "behind the scenes" understanding while working on a messy LDAP repository setup issue.

(Note: This is for situations in which the password is not stored as a hash in a custom property; that situation is easy to manage)

codeforester
  • 39,467
  • 16
  • 112
  • 140
DrStalker
  • 9,061
  • 17
  • 43
  • 47

5 Answers5

17

LDAP supports a compare of userPassword. You send the password, the server does the compare and returns true or false. This is the not-requiring a login way to authenticate users.

geoffc
  • 4,030
  • 7
  • 44
  • 51
  • 3
    How would you "compare" if the password in the LDAP server is encrypted? – Ashwin Apr 23 '13 at 14:45
  • @Ashwinkumar There is a specific function to do a password compare. You supply the password to test, it is similarly encrypted, then you can compare the two values. The distinction is between attempting to bind with these creds, or explicitly calling the ldapCompare function. – geoffc Apr 23 '13 at 17:45
  • 2
    hmm.. In a recent question I posted http://stackoverflow.com/questions/16168293/how-to-do-password-authentication-for-a-user-using-ldap, I was suggested to use bind for the search result with the password. Binding with latest 'dn' works. However, binding is essentially a 'login'. doing a LDAP 'ldap_compare_s' failed. Is there a way I can get a password compared against LDAP user's password? – Ashwin Apr 24 '13 at 01:24
  • 15
    can you please provide exact function name or code showing how to compare passwords. I could not find such method in class javax.naming.ldap.InitialLdapContext – Kaushik Lele May 21 '13 at 05:57
  • Here's more info on the spec associated with this concept -- http://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html . Not sure how widely adopted it is! – Jeff Allen Oct 29 '13 at 16:30
  • 1
    We've seen that comparing against `userPassword` using LDAP on Microsoft Windows Server 2016 ActiveDirectory users yields this error: `problem 1001 (NO_ATTRIBUTE_OR_VAL) (userPassword)`. Apparently this ActiveDirectory doesn't _have_ `userPassword` for its users. See [google](https://www.google.com/search?q=ldap+compare+userpassword+NO_ATTRIBUTE_OR_VAL) – Peter V. Mørch Nov 11 '19 at 19:42
  • Downvote because: "Some applications may utilize a Compare Request on the userPassword attribute. This is a poor practice and should not be utilized as some of the built in features such as Password Expiration and Intruder Detection may be bypassed when performing a Compare Request on the userPassword attribute." Source: https://ldapwiki.com/wiki/LDAP%20Authentication – nCessity Apr 26 '22 at 10:16
  • @nCessity I agree it is a bad idea, but it is still an approach some use. – geoffc Apr 26 '22 at 14:29
15

Look into the WhoAmI Extended Operation (RFC 4532).

WhoAmI serves one purpose really - validate submitted bind credentials. It should not affect nor provoke any "login restrictions" (that I know of).

WhoAmI can be done using a dedicated binary (such as "ldapwhoami"), or it can be done using Net::LDAP::Extension::WhoAmI (Perl) or some other such language that supports LDAP operations. Do note that "testing a password" using some "Search" function is an ill-advised test method.

For example, if my DN is "uid=max,ou=users,dc=company,dc=com" and my password is "@secret", one could do this via the dedicated binary on a Linux box (note -ZZ is used for TLS confidentiality, which is possibly unsupported or optional in your environment):

ldapwhoami -x -w "@secret" -D uid=max,ou=users,dc=company,dc=com -ZZ -H ldap://address.of.your.ldapserver/

If the user/pass combination is correct, the answer returned is:

dn:uid=max,ou=users,dc=company,dc=com

If the user/pass combination is NOT correct, the answer returned is (usually):

(49) Invalid Credentials

This could mean, as I said, the password and/or username is wrong, the user does not exist, or the LDAP server's ACLs are broken in such a way that authentication is not possible. More often than not, its the user/pass combo being mistyped, or the user not existing.

In closing, the LDAPWhoAmI operation is a very lightweight and simple method of validating credentials. It also works via other mechanisms too (e.g: Kerberos Single Sign-On, Digest-MD5, etc etc).

mpromonet
  • 11,326
  • 43
  • 62
  • 91
maximum ldap
  • 425
  • 1
  • 4
  • 5
  • 2
    The username and password aren't even sent as part of the `WhoAmI`request. All the `WhoAmi` operation does is tell you who you are currently bound as. It is therefore nonsense to say that it 'validates submitted bind credentials'. It doesn't. It just returns them, or rather just the username. It is the *bind* step which does the validation: it alone is therefore sufficent. In the example given, `ldapwhoami` first binds, which may fail with `Invalid Credentials`, and then executes the `WhoAmI` operation. *Any* LDAP operation would have done. It didn't have to be `WhoAmi`. – user207421 Oct 15 '14 at 22:11
  • Mind: There is a lot that can go wrong. Especially MS Active Directory defaults to a rather sloppy configuration. Example: `ldapwhoami -x -w "" -D -H ` will not fail despite an empty password. So checking for `[ "$?" -eq "0" ]` wont do the trick. AD will just return an empty string and so ldapwhoami will exit 0. – nCessity Apr 26 '22 at 10:27
7

Watch out using bind for checking username/password, on some systems it will count as a login, and with login restrictions it might fail.

Using compare is a better option for just checking the password.

  • 3
    Also a login with a null password counts as an anonymous bind, which will always succeed. – geoffc Jul 21 '11 at 15:28
  • 2
    I guess the "right" approach depends on what you're trying to do. In the common case of writing an application that delegates authentication to an external directory, login restrictions are usually *desirable*, no? – Mark E. Haase Sep 09 '13 at 18:10
  • I don't know what the difference between 'check password' and 'login' could possibly be, or rather why you would ever want to do one without the other. @geoffc An anonymous bind will only succeed if the server is configured to allow them. – user207421 Oct 15 '14 at 22:53
2

Binding as that user is sufficient. The password is checked in the process of binding.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

ldapsearch -v -h $hostname -p $port
-D 'uid=$UID'
-w '$PWD'
-b 'DC=$companyname,DC=$topleveldomain' '(objectClass=*)'

Replace the $xxx values with your related values. If you get return code=0, you can get in, not just that the UID/PWD combination is correct.

access_granted
  • 1,807
  • 20
  • 25