Debugging runZero LDAP support

Modified on Wed, Oct 25, 2023 at 12:50 PM

The OpenLDAP project maintains a command-line LDAP query utility called ldapsearch which can be run on a system hosting an Explorer or console, and used to check LDAP credential information against the LDAP server.

Note: Apple ships an old version of ldapsearch with macOS Sonoma (14.0) and below. It’s so old that it won’t connect using TLS 1.2 or 1.3, which means it won’t talk to many recent LDAP servers. You can install a newer version using HomeBrew (brew install openldap), but note that the binary ends up in /opt/homebrew/opt/openldap/bin/ldapsearch and isn’t placed in your path, so as not to clash with the system-provided one.

One of the things that makes LDAP “lightweight” is that it doesn’t define many standard attributes, so attribute names and syntax can vary a lot between implementations.

Here’s a typical command to test looking up data from an LDAP server using OpenLDAP client tools:

ldapsearch -D "uid=root,cn=users,dc=ldapserver,dc=example,dc=com" -w "password-goes-here" \
-H ldap://apollo.local:389/ -b "dc=orgunit,dc=example,dc=com" -s sub -z 1 -x "(objectClass=*)"

Here’s what the parameters mean:

  • -D specifies the bind DN. This is effectively the username to log in as. In this case it’s uid=root,cn=users,dc=ldapserver,dc=example,dc=com, a hierarchical DN under the base DN. It may not be in that format, though — the format depends on the LDAP server and how it has been set up.

  • -w specifies the password on the command line as the next parameter. Alternatively, -W will make the client prompt for the password.

  • -H specifies the URL of the LDAP server to connect to. Typically ldap is on port 389, ldaps is on port 636. (Same format runZero expects.)

  • -b specifies the base DN. This specifies the highest level of the directory that we want to query. In this case it’s dc=orgunit,dc=example,dc=com because the directory setup was generated from a DNS domain using domain components (dc). It’s also common to see X.500 style DNs such as ou=department,c=US,o=companyname with organizational unit, country, and organization elements.

  • -s sub specifies that the search scope should be the subtree underneath the base DN.

  • -x specifies use of simple authentication rather than SASL.

  • -z 1 specifies that we only want one sample result back, no matter how many matches there are.

  • The final parameter is the search query. All objects in an LDAP directory are required to have an objectClass to specify what type of object they are, so this query matches the entire contents of the directory.

The result should be some LDIF output with comments on lines starting with #, and some useful data on the non-comment lines. For example:

# extended LDIF
#
# LDAPv3
# base <dc=ldapserver,dc=example,dc=com> with scope subtree
# filter: (objectClass=*)
# requesting: ALL
#

# ldapserver.example.com
dn: dc=ldapserver,dc=example,dc=com
dc: ldapserver
objectClass: domain

# search result
search: 2
result: 4 Size limit exceeded

# numResponses: 2
# numEntries: 1

In the above example we’re getting the first result in the directory, which is typically the object representing the LDAP server itself.

If you don’t get any output, here are some things to try:

  • Check the hostname in the LDAP server URL resolves.
  • Check the port and protocol in the URL are correct.
  • Check the username syntax.
  • Try with -v for verbose, to see if there are any clues.

If you get TLS errors (in any of the runZero logs or from ldapsearch), you can debug TLS with certigo or openssl's s_client command:

openssl s_client -connect servername:636
certigo connect servername:636

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article