Openldap configuration

From wikinotes

modern versions of LDAP are configured dynamically on the commandline, rather than using a single configuration file.
Directives like ldapadd, ldapdelete, ldapmodify are used to modify the configuration.


WARNING:

the configuration is stored within /etc/ldap/slapd.conf/ in various .ldif files. Do not edit these files directly!! . Instead use the slapd-config command.

Locations

/etc/ldap/slapd.d/cn=config/*.ldif configuration files
/etc/ldap/slapd.d/cn=module/*.ldif dynamically loaded modules
/etc/ldap/slapd.d/cn=schema/*.ldif contains references to all schema definitions that are hard-coded into slapd.

Changing Configuration

Starting in ldap 2.4, ldap is no longer configured using a configuration file.
Instead it is configured using the commandline tools ldapmodify, ldapadd, ldapdelete.

See openldap usage (at least slapcat/ldapsearch) before reading this section.

Viewing Config

You can read the default configurations stored under /etc/ldap/slapd.d/cn=config/*, but it might be more useful to see the actual configuration that is currently in use.

# produces a list of
#  * config-module containing info, then underneath it:
#     * all suffixes
#     * each suffix's administrator user
#     * the hash of each administrative user's password

slapcat -b 'cn=olcDatabase*,cn=config' \
    | grep --color -E '(dn:|olc(Suffix:|Root.*:))'

Changing Config

In this example, we'll change the suffix of a server.

Create an ldif file, with your desired changes:

#### change_suffix.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcSuffix
olcSuffix: dc=mydomain,dc=com
-
add: olcSuffix
olcSuffix: dc=example,dc=com
-
delete: olcRootDN
olcRootDN: cn=admin,dc=mydomain,dc=com
-
add: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com

Apply the modifications

ldapmodify -Y EXTERNAL -H ldapi:/// -f change_suffix.ldif

Verify modification

# if your change was invalid, this
# command will not run, and indicate the error
slapcat -b 'cn=olcDatabase*,cn=config' | grep -E 'olc(Suffix:|Root.*:)'

Changing olcRootPW

This is all starting to become very understandable. Now here we'll change an encrypted value, like the olcRootPW.

Changing the admin password works just like any other information. Simply type the password in plaintext, and it will be saved encrypted. Just like that :)

Defining a Hierarchy in your Suffix

Wahoo! Now you have a suffix, and an admin user for your suffix! Now you'll need to create a hierarchy for your objects to exist in.

The following LDIF file will create objects arranged as follows:

#### hierarchy.ldif

# (dc=com)
#     |
# (dc=example)
#     |
#     +----------------+---------------+-------------+
#     |                |               |             |
# (ou=employees)  (ou=accounts)   (customers)    (devices)
#
dn: dc=com
objectclass: domain
dc: com

dn: dc=example,dc=com
objectclass: domain
dc: example

dn: ou=employees,dc=example,dc=com
objectclass: organizationalUnit
ou: employees

dn: ou=accounts,dc=example,dc=com
objectclass: organizationalUnit
ou: accounts

dn: ou=devices,dc=example,dc=com
objectclass: organizationalUnit
ou: devices

dn: ou=customers,dc=example,dc=com
objectclass: organizationalUnit
ou: customers
# make sure that -D points to the olcRootDN
ldapadd -c -D "dc=admin,dn=example,dn=com" -w "mypassword" -f hierarchy.ldif

Now search your suffix, to make sure that everything got added alright:

# search for all objects under dc=example,dc=com
ldapsearch -x -b 'dc=example,dc=com'

# or search with authentication as 'admin'
ldapsearch -D 'cn=admin,dc=example,dc=com' -b 'dc=example,dc=com' -w password

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

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

# devices, tma.com
dn: ou=devices,dc=example,dc=com
objectClass: organizationalUnit
ou: devices

# accounts, tma.com
dn: ou=accounts,dc=example,dc=com
objectClass: organizationalUnit
ou: accounts

# customers, tma.com
dn: ou=customers,dc=example,dc=com
objectClass: organizationalUnit
ou: customers

# employees, tma.com
dn: ou=employees,dc=example,dc=com
objectClass: organizationalUnit
ou: employees

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

Initial Configuration

Your operating system or linux distro may enforce that you setup ldap using an automated tool of their choosing. I kind of prefer to administer the server using configurations, because that knowledge is more portable across different distrobutions.

dpkg-reconfigure slapd debian/ubuntu

Suffix

A suffix marks the beginning of a new DIT (tree). It is composed of a combination of toplevel attributes, that have been assigned values. While any attribute is valid, If you want your LDAP server to be at all compliant with Microsoft's Active Directory, your suffix should point to the domain-name (ex: dn: dc=subdomain,dc=example,dc=com => http://subdomain.example.com ).

Create an ldif file, with your desired changes:

#### change_suffix.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcSuffix
olcSuffix: dc=mydomain,dc=com
-
add: olcSuffix
olcSuffix: dc=example,dc=com
-
delete: olcRootDN
olcRootDN: cn=admin,dc=mydomain,dc=com
-
add: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com

Apply the modifications

ldapmodify -Y EXTERNAL -H ldapi:/// -f change_suffix.ldif

Verify modification

# if your change was invalid, this
# command will not run, and indicate the error
slapcat -b 'cn=olcDatabase*,cn=config' | grep -E 'olc(Suffix:|Root.*:)'

See Also:

ACLs (Permissions)

You can modify a user's access to entries within the LDAP directory, either by

  • dn (the tree pathway to the entry)
  • filter (entries falling under certain pathways of the tree)

ACL Syntax

Example

Roughly, as pseudocode here is how to define ALCs:

access to  {target} {target_filter}
{target_attributes}
by {target} {permission}

Note that for one access to target, you may define multiple sets of permissions for various groups:

access to {target} {target_filter}
{target_attributes}
by {target} {permission}
by {target} {permission}

Here is an example using real LDIF syntax:

access to dn.subtree="ou=people,dc=example,dc=com" filter=(objectClass=person)
attrs="userPassword,description"
by dn.subtree="ou=employees,dc=example,dc=com" manage
by anonymous auth
by * none

Access Control is Quite Expressive, the manner each layer of a rule can be defined in a variety of different ways.

Target (access to, by)

This describes the options that you have available to you when you are configuring access to something, or by something.

* all users (anonymous, athenticated)
anonymous only non-authenticated users
users only authenticated users
self user associated with target entry (?)
dn.base="ou=employees,dc=example,dc=com" determines the base you are targeting (base, one, subtree, children)

See the very helpful https://technet.microsoft.com/en-us/library/cc978021.aspx

group.exact="ou=employees,dc=example,dc=com" determines the group you are targeting (exact, expand)
dn.regex="^.*,dc=example,dc=com$" perform a regex match on all DNs (less efficient)

Example:

access to  dn.subtree="ou=employees,dc=example,dc=com"  by *                                       read
access to  *                                            by dn.one="ou=employees,dc=example,dc=com" read
access to dn.subtree"ou=employees,dc=example,dc=com" by users write

Privileges

none 0 no access
disclose d needed for information disclosure on error
auth dx need to authenticate
compare cdx needed to compare
search scdx needed to apply search filters
read rscdx needed to read search results
write wrscdx needed to modify/rename
manage mwrscdx needed to manage

These privileges apply to the by section of the ACL.

Example:

access to * by * write
access to * by * read

Modifying ACLs

Modifying ACLs is performed the same way that the configuration file is modified.


First, find the index of the olcAccess entry that you'd like to change, or the last index (so you can append a new rule).

For example, for the following rule olcAccess: {2}to * by * read, the index would be {2}.

sudo -i   # login as root
slapcat -b cn=config \
    | ack --passthru --color olcAccess  \
    | less -Ri

Write an LDIF file defining a new, or modified olcAccess rule. Note that there are NOT quotes around the DN values below.

#### modify_user.ldif
#
# the user willjp can manage ALL entries under dc=tma,dc=com
#

dn: olcDatabase{1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {3}to dn.subtree=dc=tma,dc=com   by dn.base=cn=willjp,ou=employees,dc=tma,dc=com   manage

Add the rule to the configuration

ldapmodify -Y EXTERNAL -H ldapi:/// -f modify_user.ldif

Verify rule was added to the configuration

slapcat -b cn=config \
    | ack --passthru --color olcAccess  \
    | less -Ri

See Also

The official openldap documentation is actually really good at describing how to create and modify ACLs.

Other

Changing a User's Password

NOTE:

does not change the root ldap password. For instructions on changing rootdn's password, see the suffix configuration instructions above.

sudo -i   # login as root

ldappasswd -H ldap://localhost             \
   -D  "uid=<user>,ou=serviceaccounts,dc=example,dc=com"  `# the user account whose password we are changing` \
   -S  `# prompt for new password`         \
   -W  `# prompt for bind password`        \
   -ZZ `# perform operation over StartTLS`