Codiwan.com

The blog for Design Patterns, Linux, HA and Myself!

OpenLDAP Installation and Tutorial on Ubuntu

OpenLDAP installation on Ubuntu with practical examples using ldapadd, ldapmodify, etc.

The document presents the installation steps for OpenLDAP in an Ubuntu server and some practical examples of LDAP commands that will help you in setting up the OpenLDAP server once the installation is complete. This document is divided into the following topics:

OpenLDAP installation on Ubuntu machine

In this step we will install the OpenLDAP server. I’ll be using the root user for the installation. Here’s the OS version:

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=21.04
DISTRIB_CODENAME=hirsute
DISTRIB_DESCRIPTION="Ubuntu 21.04"
NAME="Ubuntu"
VERSION="21.04 (Hirsute Hippo)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 21.04"
VERSION_ID="21.04"
VERSION_CODENAME=hirsute
UBUNTU_CODENAME=hirsute

OpenLDAP server can be installed using the following command:

$ apt install slapd ldap-utils

while the installation will be ongoing it will ask for the Administrator user’s password. We can add a temporary password here as we’ll change the Administrator password later in this document.

Pop up for the Administrator Password
Please enter the same password for it to continue.

Pop up for the Administrator Password Confirmation
$ apt install slapd ldap-utils
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
:
:
Processing triggers for ufw (0.36-7.1)
Processing triggers for man-db (2.9.4-2)
Processing triggers for libc-bin (2.33-0ubuntu5)

Updating the BaseDN, admin password and the suffix of the Directory Information Tree(DIT)

Once the installation is complete, we can find the OpenLDAP server’s configuration in the /etc/ldap/sladp.d directory:

$ cd /etc/ldap/slapd.d/
$ ls
'cn=config.ldif' 'cn=config'
$ tree
.
├── cn=config
│ ├── cn=module{0}.ldif
│ ├── cn=schema
│ │ ├── cn={0}core.ldif
│ │ ├── cn={1}cosine.ldif
│ │ ├── cn={2}nis.ldif
│ │ └── cn={3}inetorgperson.ldif
│ ├── cn=schema.ldif
│ ├── olcDatabase={0}config.ldif
│ ├── olcDatabase={-1}frontend.ldif
│ └── olcDatabase={1}mdb.ldif
└── cn=config.ldif

2 directories, 10 files

The configuration present here is in the LDAP directory format instead of a text file. To update the configuration we’ll have to use the ldapmodify command in which we’ll have to pass the ldif files that will contain the updates. Here’s the content of the olcDatabase={1}mdb.ldif file. It contains the default Suffix(olcSuffix), Administrator’s Distinguished Name(olcRootDN), and it’s password(olcRootPW) along with the several other configuration keys.

$ cat cn\=config/olcDatabase\=\{1\}mdb.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 bc731387
dn: olcDatabase={1}mdb
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=nodomain
olcAccess: {0}to attrs=userPassword by self 
 write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self
 write by * read
olcAccess: {2}to * by * read
olcLastMod: TRUE
olcRootDN: cn=admin,dc=nodomain
olcRootPW:: e1NTSEF9amtIOXY5Sm1ScnJjTVNrUC***
olcDbCheckpoint: 512 30
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
olcDbMaxSize: 1073741824
structuralObjectClass: olcMdbConfig
entryUUID: b809a076-6545-103b-914f-910c8b7d4efd
creatorsName: cn=admin,cn=config
createTimestamp: 20210619122921Z
entryCSN: 20210619122921.571612Z#000000#000#000000
modifiersName: cn=admin,cn=config
modifyTimestamp: 20210619122921Z

Next, we’ll update the olcSuffix, olcRootDN and olcRootPW configuration. To update the administrator’s password we’ve to first encrypt the new password. We can use slappasswd to do that:

$ slappasswd
New password:
Re-enter new password:
{SSHA}sZyeF53/dQio+iLUiBaHXKb2nL/NuWEj

Here’s the mdb.ldif file that I’ve created for updating those configurations. I’ve changed the olcSuffix to dc=codiwan,dc=com, olcRootDN to cn=ldapadmin,dc=codiwan,dc=com and olcRootPW to the output of the previous command.

$ cat ldap-changes/mdb.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=codiwan,dc=com

dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=ldapadmin,dc=codiwan,dc=com

dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
# Same as the slappasswd command output
olcRootPW: {SSHA}sZyeF53/dQio+iLUiBaHXKb2nL/NuWEj

We can update the configuration using the ldapmodify.

$ ldapmodify -Y EXTERNAL -H ldapi:/// \
    -f ldap-changes/mdb.ldif
SASL/EXTERNAL authentication started
SASL SSF: 0
modifying entry "olcDatabase={1}mdb,cn=config"

modifying entry "olcDatabase={1}mdb,cn=config"

modifying entry "olcDatabase={1}mdb,cn=config"

Now that our configuration is complete we can move to the section on adding users and groups into OpenLDAP.

Adding Groups and Users into the OpenLDAP using ldapadd

In this section we’ll create a dummy hierarchy containing two groups and two users and then we’ll perform the search using ldapsearch on those entries. The hierarchy looks like this:

LDAP Hierarchy

The first step is to add the suffix:

$ cat ldap-changes/add-suffix.ldif
dn: dc=codiwan,dc=com
dc: codiwan
objectClass: top
objectClass: domain

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-suffix.ldif
Enter LDAP Password:
adding new entry "dc=codiwan,dc=com"

Then we create the two organization units:

$ cat ldap-changes/add-people-org-unit.ldif
dn: ou=People,dc=codiwan,dc=com
objectClass: organizationalUnit
ou: People

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-people-org-unit.ldif
Enter LDAP Password:
adding new entry "ou=People,dc=codiwan,dc=com"
$ cat ldap-changes/add-groups-org-unit.ldif
dn: ou=Groups,dc=codiwan,dc=com
objectClass: organizationalUnit
ou: Groups

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-groups-org-unit.ldif
Enter LDAP Password:
adding new entry "ou=Groups,dc=codiwan,dc=com"

Now we’ll add the two users: Alice and Bob:

$ cat ldap-changes/add-alice.ldif
dn: uid=alice,ou=People,dc=codiwan,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: alice
sn: Doe
givenName: Alice
cn: Alice Doe
displayName: Alice Doe
uidNumber: 10001
gidNumber: 5001
userPassword: {CRYPT}password
loginShell: /bin/bash
homeDirectory: /home/alice

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-alice.ldif
Enter LDAP Password:
adding new entry "uid=alice,ou=People,dc=codiwan,dc=com"

$ cat ldap-changes/add-bob.ldif
dn: uid=bob,ou=People,dc=codiwan,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: bob
sn: Doe
givenName: Bob
cn: Bob Doe
displayName: Bob Doe
uidNumber: 10002
gidNumber: 5001
userPassword: {CRYPT}password
loginShell: /bin/bash
homeDirectory: /home/bob

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-bob.ldif
Enter LDAP Password:
adding new entry "uid=bob,ou=People,dc=codiwan,dc=com"

The password for both these users can be ignored right now as we’ll update their passwords in the later steps in this document. Their objectClass is different from the previous entries we made for the organization units. Due to these different organization units we can add the field like displayName or givenName because they are defined inside the inetOrgPerson objectClass.

Next we add the codiwanadmin and codiwangeneral groups:

$ cat ldap-changes/add-codiwan-admin-group.ldif
dn: cn=codiwanadmin,ou=Groups,dc=codiwan,dc=com
objectClass: posixGroup
cn: codiwanadmin
gidNumber: 5001

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W -f \
    ldap-changes/add-codiwan-admin-group.ldif
Enter LDAP Password:
adding new entry \ 
    "cn=codiwanadmin,ou=Groups,dc=codiwan,dc=com"

$ cat ldap-changes/add-codiwan-general-group.ldif
dn: cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com
objectClass: posixGroup
cn: codiwangeneral
gidNumber: 5002

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W -f \
    ldap-changes/add-codiwan-general-group.ldif
Enter LDAP Password:
adding new entry \
    "cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com"

Adding Users into the LDAP Groups

Now that we’ve created our users, and the groups, we can now proceed to add the users into the groups.

Here we add Alice user to the codiwanadmin group and the user Bob to the codiwangeneral group:

$ cat ldap-changes/add-alice-to-codiwanadmin.ldif
dn: cn=codiwanadmin,ou=Groups,dc=codiwan,dc=com
changetype: modify
add: memberUid
memberUid: alice

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-alice-to-codiwanadmin.ldif
Enter LDAP Password:
modifying entry \
    "cn=codiwanadmin,ou=Groups,dc=codiwan,dc=com"

$ cat  ldap-changes/add-bob-to-codiwangeneral.ldif
dn: cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com
changetype: modify
add: memberUid
memberUid: bob

$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/add-bob-to-codiwangeneral.ldif
Enter LDAP Password:
modifying entry \
    "cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com"

You can notice here that we’ve used the uid attribute to reference the users.

Changing the user’s password using ldappasswd

As we’ve not configured the correct passwords for the users, let’s do it now. To update the Alice’s password execute:

$ ldappasswd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -S uid=alice,ou=People,dc=codiwan,dc=com
New password:
Re-enter new password:
Enter LDAP Password:

We’re using the administrator user to update the password. The first and the second field is for the Alice’s password, however, the 3rd prompt is for the administrator’s password.

We perform the same operation for the user Bob as well:

$ ldappasswd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -S uid=bob,ou=People,dc=codiwan,dc=com
New password:
Re-enter new password:
Enter LDAP Password:

Just like the administrator the user can also change their password:

$ ldappasswd -x -D uid=bob,ou=People,dc=codiwan,dc=com -W \
    -S uid=bob,ou=People,dc=codiwan,dc=com
New password:
Re-enter new password:
Enter LDAP Password:

However, they cannot change someone else’s password:

$ ldappasswd -x -D uid=bob,ou=People,dc=codiwan,dc=com -W \
    -S uid=alice,ou=People,dc=codiwan,dc=com
New password:
Re-enter new password:
Enter LDAP Password:
Result: Insufficient access (50)
$ ldappasswd -x -D uid=alice,ou=People,dc=codiwan,dc=com -W \
    -S uid=bob,ou=People,dc=codiwan,dc=com
New password:
Re-enter new password:
Enter LDAP Password:
Result: Insufficient access (50)

Querying or Searching the OpenLDAP server using ldapsearch

In this section we’ll look into ldapsearch command to find the users.

Here’s a simple search query to find the user Bob. We’ve set the filter to (uid=bob).

$ ldapsearch -x -D "uid=alice,ou=People,dc=codiwan,dc=com" -W \
    -b "ou=People,dc=codiwan,dc=com"  '(uid=bob)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <ou=People,dc=codiwan,dc=com> with scope subtree
# filter: (uid=bob)
# requesting: ALL
#

# bob, People, codiwan.com
dn: uid=bob,ou=People,dc=codiwan,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: bob
sn: Doe
givenName: Bob
cn: Bob Doe
displayName:: Qm9iIERvZSA=
uidNumber: 10002
gidNumber: 5001
loginShell: /bin/bash
homeDirectory: /home/bob

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

The previous ldapsearch was executed using the alice user and this why we did not get the password field in the results. If we execute the same search using the ldapadmin then userPassword field will be shown.

$ ldapsearch -x  -D "cn=ldapadmin,dc=codiwan,dc=com" -W \
    -b "ou=People,dc=codiwan,dc=com"  '(uid=bob)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <ou=People,dc=codiwan,dc=com> with scope subtree
# filter: (uid=bob)
# requesting: ALL
#

# bob, People, codiwan.com
dn: uid=bob,ou=People,dc=codiwan,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: bob
sn: Doe
givenName: Bob
cn: Bob Doe
displayName:: Qm9iIERvZSA=
uidNumber: 10002
gidNumber: 5001
loginShell: /bin/bash
homeDirectory: /home/bob
userPassword:: e1NTSEF9RkhiTGFmZkIzM2

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

To search for the groups that the user Bob is part of, execute the following command, the filter criteria is (memberuid=bob). We used to same attribute name to add the user into the group.

$ ldapsearch -x  -D "cn=ldapadmin,dc=codiwan,dc=com" -W \
    -b "dc=codiwan,dc=com"  '(memberuid=bob)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=codiwan,dc=com> with scope subtree
# filter: (memberuid=bob)
# requesting: ALL
#

# codiwangeneral, Groups, codiwan.com
dn: cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com
objectClass: posixGroup
cn: codiwangeneral
gidNumber: 5002
memberUid: bob

# search result
search: 2
result: 0 Success

Removing a user from the group in OpenLDAP using ldapmodify

The process of removing a user from the group is very same as adding. Instead of the add attribute we need to put the delete attribute:

$ cat ldap-changes/remove-bob-from-codiwangeneral.ldif
dn: cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com
changetype: modify
delete: memberUid
memberUid: bob
$ ldapadd -x -D cn=ldapadmin,dc=codiwan,dc=com -W \
    -f ldap-changes/remove-bob-from-codiwangeneral.ldif
Enter LDAP Password:
modifying entry "cn=codiwangeneral,ou=Groups,dc=codiwan,dc=com"

$ ldapsearch -x \
    -D "cn=ldapadmin,dc=codiwan,dc=com" -W \
    -b "dc=codiwan,dc=com"  '(memberuid=bob)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=codiwan,dc=com> with scope subtree
# filter: (memberuid=bob)
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1

Changing the port of the OpenLDAP server

Until now, we’ve not provided the OpenLDAP server’s URI to any of the commands we’ve used. This is because it has started on the default host and the port without TLS. The configuration for the hostname and the port, along with the other configuration, are present in the file /etc/default/slapd. The hostname and port can be changed here:

$ cat slapd
# SLAPD_SERVICES="ldap:/// ldapi:///"
SLAPD_SERVICES="ldap://192.168.56.104:3389/"

Update the SLAPD_SERVICES config to the desired host and the port and then restart the slapd service:

$ systemctl restart slapd
$ systemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server
     Loaded: loaded (/etc/init.d/slapd; generated)
    Drop-In: /usr/lib/systemd/system/slapd.service.d
             └─slapd-remain-after-exit.conf

Pass the new hostname and port to the ldap commands using the -H flag:

$ ldapsearch -x  -H ldap://192.168.56.104:3389 \
    -D "cn=ldapadmin,dc=codiwan,dc=com" -W \
    -b "dc=codiwan,dc=com"  '(memberuid=bob)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=codiwan,dc=com> with scope subtree
# filter: (memberuid=bob)
# requesting: ALL
#

# search result
search: 2
result: 0 Success

# numResponses: 1
Loading Comments... Disqus Loader
comments powered by Disqus