Manage and Use LDAP Servers without RootDN

A blog about C++ programming, more or less.

Are you tired of typing password when running LDAP commands with -W, but feel nervous about using plain text password with -w? Are you looking for a way to run LDAP commands that is both passwordless and secure? Then this post is for you.

Introduction

The differences between the following two commands are pretty clear to people who are familiar with LDAP administration.

sudo ldapadd -H ldapi:// -Y EXTERNAL -Q
ldapadd -H ldap:// -x -D cn=admin,dc=yyang-pplus,dc=github,dc=io -W

As we have already discussed in my previous post, basically, the first command uses the SASL authentication method through ldapi interface to bind as the superuser of the localhost; the second command uses simple authentication with normal ldap scheme to bind as the so-called rootDN of the DIT. For ease of discussion, in the rest part of the post, let’s name the first command as the ldapi command, and call the second command as the rootDN command.[1]

In general, people use the rootDN commands to maintain the content of LDAP databases in the normal DIT. And use the ldapi commands to manage the configuration of LDAP servers within the administrative DIT, which also known as the cn=config DIT.[1] Those two kinds of commands exist because that’s just how LDAP servers are configured by default.

In this post, I am going to present a way to manage both the administrative DIT and the normal DIT using only the ldapi commands. To be more specific, we want to be able to run the following test command successfully:

$ sudo ldapadd -H ldapi:// -Y EXTERNAL -Q <<EOF
dn: dc=yyang-pplus,dc=github,dc=io
objectClass: dcObject
objectClass: organization
o: yyang-pplus
EOF

Instead of getting an error message, says:

ldap_add: Insufficient access (50)
    additional info: no write access to parent

Environment

All the code and commands, posted here, were tested in the following environment:

$ cat /etc/redhat-release
CentOS release 6.10 (Final)

$ ldapadd -VV
ldapadd: @(#) $OpenLDAP: ldapmodify 2.4.40 (Mar 22 2017 06:29:57)

Also, the test command, given in the precious section, require the LDAP server has domain suffix configured properly. To check if your environment meets the requirement, run the following command:

$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" "(olcSuffix=*)" olcSuffix -LLL -Q
dn: olcDatabase={2}bdb,cn=config
olcSuffix: dc=yyang-pplus,dc=github,dc=io

You should get similar outputs on your machine, if not, I recommend you follow the instructions of this post “Configure LDAP Server” to setup the test bed properly.

Solution

The solution is actually pretty simple, just use the same authentication DN for root or sudo users of the OS in the place of where rootDN usually is.

$ sudo ldapmodify -Y EXTERNAL -H ldapi:// -Q <<EOF
dn: olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
-
delete: olcRootPW
EOF
modifying entry "olcDatabase={2}bdb,cn=config"

dn: olcDatabase={2}bdb,cn=config is the DN of the normal DIT you want the ldapi commands to have access to, and it may vary from server to server. Please refer to the last command in the Environment section for an example of how to get the normal DIT DN on your machine.

olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth is the authentication DN for the localhost’s superuser. Please check my previous post for how to query this information from the openLDAP servers. Also olcRootPW has to be deleted as well, because it can only be set when root DN is under suffix.

This solution works, because the olcRootDN directive need not refer to an entry in the database or even in the directory, and it may refer to a SASL identity. Also, regardless of what access control policy is defined, the olcRootDN is always allowed full rights (i.e., auth, search, compare, read, and write) on everything and anything within the DIT.[2:§8.1]

Test

When you run the test command again, you should now get something like this:

adding new entry "dc=yyang-pplus,dc=github,dc=io"

Which means our solution works as expected. Just to double-check, you can query the entry you have just added:

$ ldapsearch -H ldap:// -x -b "dc=yyang-pplus,dc=github,dc=io" -LLL
dn: dc=yyang-pplus,dc=github,dc=io
objectClass: dcObject
objectClass: organization
o: yyang-pplus
dc: yyang-pplus

Easy. Right?

Also note how the dc attribute was added automatically to the entry by the LDAP server.

Conclusion

Well, you may ask: why does anyone bother to do something like this? Because it is quite convenient. In this way, you don’t need the rootDN and its password anymore. I think having one less thing to remember is always good.

The only catch is that simple authentication for root DN will no longer works, so this configuration is not a good fit for LDAP-enabled applications that require root DN simple authentication.

References

  1. Introduction to ldapwhoami and LDAP Authtication Mechanisms
  2. OpenLDAP Software 2.4 Administrator’s Guide