Skip to content

Instantly share code, notes, and snippets.

@mhlulani
Last active April 5, 2021 16:14
Show Gist options
  • Save mhlulani/1e0c6db22b0cf42f9f966cf5e84327ea to your computer and use it in GitHub Desktop.
Save mhlulani/1e0c6db22b0cf42f9f966cf5e84327ea to your computer and use it in GitHub Desktop.
LDAP crash course

LDAP Getting Stared

from https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks

Jargon

  • DN = Distinguished Name
  • RDN = Relative Distinguished Name
  • DC = Domain Component
  • OU = Organizational Unit
  • OID = Object Identifier

Installation

OpenLDAP

$ sudo dnf -y install openldap-servers openldap-clients

# Force SELinux Policy
$ ausearch -c 'slapd' --raw | audit2allow -M slapd
$ sudo semodule -i slapd.pp

389 Directory Server

$ sudo dnf install -y 389-ds
$ DIRSRV_FQDN=example.org \
DIRSRV_ADMIN_USERNAME=admin \
DIRSRV_ADMIN_PASSWORD=topsecret \
DIRSRV_PORT=389 \
DIRSRV_ID=dir \
DIRSRV_SUFFIX=dc=example,dc=org \
DIRSRV_ROOT_DN=cn=directory\ manager \
DIRSRV_ROOT_DN_PASSWORD=topsecret \
DIRSRV_SAMPLE_ENTRIES=no \
DIRSRV_ORG_ENTRIES=no \
DIRSRV_INSTALL_LDIF=suggest \
DIRSRV_ADMIN_PORT=9380

$ setup-ds.pl --silent --debug \
      "General.FullMachineName=$DIRSRV_FQDN" \
      "General.StrictHostCheck=false" \
      "General.SuiteSpotUserID=dirsrv" \
      "General.SuiteSpotGroup=dirsrv" \
      "General.ConfigDirectoryAdminID=$DIRSRV_ADMIN_USERNAME" \
      "General.ConfigDirectoryAdminPwd=$DIRSRV_ADMIN_PASSWORD" \
      "slapd.ServerPort=$DIRSRV_PORT" \
      "slapd.ServerIdentifier=$DIRSRV_ID" \
      "slapd.Suffix=$DIRSRV_SUFFIX" \
      "slapd.RootDN=$DIRSRV_ROOT_DN" \
      "slapd.RootDNPwd=$DIRSRV_ROOT_DN_PASSWORD" \
      "slapd.AddSampleEntries=$DIRSRV_SAMPLE_ENTRIES" \
      "slapd.AddOrgEntries=$DIRSRV_ORG_ENTRIES" \
      "slapd.InstallLdifFile=$DIRSRV_INSTALL_LDIF" \
      "admin.Port=$DIRSRV_ADMIN_PORT" \
      "admin.ServerAdminID=$DIRSRV_ADMIN_USERNAME" \
      "admin.ServerAdminPwd=$DIRSRV_ADMIN_PASSWORD"

On Debian

$ sudo apt-get update
$ sudo apt-get install slapd ldap-utils

# During the installation, you will be asked to select and confirm an administrator password for LDAP. You can actually put anything here because you'll have the opportunity to change it in just a moment.

Reconfigure slapd to Select Better Settings

$ sudo dpkg-reconfigure slapd

Typical configuration:

  • Omit OpenLDAP server configuration?
    • No
  • DNS domain name?
    • awesome.com (or choose whatever you like)
  • Database backend?
    • MDB (uses a new storage format and requires less configuration than BDB or HDB)
  • Remove the database when slapd is purged?
    • No
  • Move old database?
    • Yes
  • Allow LDAPv2 protocol?
    • No

OpenLDAP Online Configuration

LDAP systems organize the data they store into hierarchical structures called Directory Information Trees or DITs for short. Starting with version 2.3, the actual configuration for OpenLDAP servers is managed within a special DIT, typically rooted at an entry called cn=config.

Finding Things

# List all things
# the "+" means show hidden attributes
$ ldapsearch -H ldap:// -x -s base -b "" -LLL "+"

# List DITs managed by this server
$ ldapsearch -H ldap:// -x -s base -b "" -LLL "namingContexts"

# List configurations
$ ldapsearch -H ldap:// -x -s base -b "" -LLL "configContext"

Accessing Configuration

To make this work, you need to use sudo before the command and replace the -x in our previous ldapsearch commands with -Y EXTERNAL to indicate that we want to use a SASL authentication method. You also need to change the protocol from ldap:// to ldapi:// to make the request over a Unix socket. This allows OpenLDAP to verify the operating system user, which it needs to evaluate the access control properties. We then use the cn=config entry as the basis of our search.

# This can only be run by the root user by default
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q

# Shows a more focused configuration entries
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q dn

# Shows what is stored configuration entries
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q -s base

Find Admin Entry

Now that you have access to the cn=config DIT, we can find the rootDNs of all of the DITs on the system. A rootDN is basically the administrative entry. We can also find the password (usually hashed) that can be used to log into that account.

$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" "(olcRootDN=*)" olcSuffix olcRootDN olcRootPW -LLL -Q

Viewing Schema Information

$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=schema,cn=config" -s base -LLL -Q | less
# Show just the names 
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=schema,cn=config" -s one -Q -LLL dn

# List a specifi schema
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn={3}inetorgperson,cn=schema,cn=config" -s base -LLL -Q | less

Modules

Reverse Group Membership Maintenance

First check configurations

The first this to do is check the type of database you are using by running:

$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q dn

Output

dn: cn=config

dn: cn=module{0},cn=config

dn: cn=module{1},cn=config

dn: cn=module{2},cn=config

dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: olcBackend={0}mdb,cn=config

dn: olcDatabase={-1}frontend,cn=config

dn: olcDatabase={0}config,cn=config

dn: olcDatabase={1}mdb,cn=config

dn: olcDatabase={1}mdb,cn=config is the important configuration, we are using MDB in this case, just keep that in mind for the time being.

Load Modules

Create a file named load-modules.ldif with the following contents:

dn: cn={2}module,cn=config
objectClass: olcModuleList
cn: {2}module
olcModulePath: /usr/lib64/openldap:/usr/lib/ldap
olcModuleLoad: memberof.la
olcModuleLoad: refint.la

Execute the configuration

$ sudo ldapadd  -vQ -Y EXTERNAL -H ldapi:/// -f path/to/load-modules.ldif

Install MemberOf Module

Create a file named backend-memberof.ldif with the following contents (please note the database type is MDB as we've defined this earlier, please use your configured database type):

dn: olcOverlay=memberof,olcDatabase={2}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf

Execute the configuration

$ sudo ldapadd  -vQ -Y EXTERNAL -H ldapi:/// -f path/to/backend-memberof.ldif

Install Referential Intergrity Module

Create a file named backend-refint.ldif with the contents (please note the database type is MDB as we've defined this earlier, please use your configured database type)

dn: olcOverlay=refint,olcDatabase={2}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
olcOverlay: refint

Execute the configuration

$ sudo ldapadd  -vQ -Y EXTERNAL -H ldapi:/// -f path/to/backend-refint.ldif

Verify that modules are installed correctly

$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q dn

Output

dn: cn=config

dn: cn=module{0},cn=config

dn: cn=module{1},cn=config

dn: cn=module{2},cn=config

dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: olcBackend={0}mdb,cn=config

dn: olcDatabase={-1}frontend,cn=config

dn: olcDatabase={0}config,cn=config

dn: olcDatabase={1}mdb,cn=config

dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config

dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config

Ensure that the following are listed in your output (database type may differ depending on your configuration):

  • dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
  • dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config

Test your module (create sample users and roles)

dn: ou=person,dc=example,dc=org
objectclass: organizationalUnit
ou: person

dn: uid=thabo,ou=person,dc=example,dc=org
objectclass: inetOrgPerson
uid: thabo
cn: Thabo
sn: Zuma
mail: [email protected]
postalCode: 88441
userPassword: {SHA}EiAf5eICiDvUX8l+hzZuoFGD4OQ=

dn: uid=james,ou=person,dc=example,dc=org
objectclass: inetOrgPerson
uid: james
cn: James
sn: Bones
mail: [email protected]
postalCode: 88441
userPassword: {SHA}EiAf5eICiDvUX8l+hzZuoFGD4OQ=

dn: uid=hlamalani,ou=person,dc=example,dc=org
objectclass: inetOrgPerson
uid: hlamalani
cn: Hlamalani
sn: Ngwenya
mail: [email protected]
postalCode: 88441
userPassword: {SHA}EiAf5eICiDvUX8l+hzZuoFGD4OQ=

dn: ou=role,dc=example,dc=org
objectclass: organizationalUnit
ou: role

dn: cn=chef,ou=role,dc=example,dc=org
objectclass: groupOfNames
cn: chef
description: Cooks in the kitchen
member: uid=hlamalani,ou=person,dc=example,dc=org

dn: cn=waiter,ou=role,dc=example,dc=org
objectclass: groupOfNames
cn: waiter
description: Serves the customers
member: uid=hlamalani,ou=person,dc=example,dc=org
member: uid=james,ou=person,dc=example,dc=org

dn: cn=customer,ou=role,dc=example,dc=org
objectclass: groupOfNames
cn: customer
description: General public
member: uid=thabo,ou=person,dc=example,dc=org
$ ldapsearch -x -LLL -W -D cn=admin,dc=example,dc=org -b uid=hlamalani,ou=person,dc=example,dc=org dn memberof

output

Enter LDAP Password: 
dn: uid=hlamalani,ou=person,dc=example,dc=org
memberOf: cn=waiter,ou=role,dc=example,dc=org
memberOf: cn=chef,ou=role,dc=example,dc=org

So as you can see hlamalani has 2 roles namely:

  • chef
  • waiter

Thats it, your done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment