Symas OpenLDAP Knowledge Base

SLAPD.D Customization

NOTE: To modify a slapd.d configuration, the cn=config database rootdn and rootpw must be set. See the previous sections for instructions.

Convert SLAPD.conf to SLAPD.D

Slapd.conf is the static configuration file for slapd. Slapd.d is the

cn=config/dynamic config equivalent of slapd.conf. However, while the cn=config exists, but is not visible, slapd.d is a visible and editable folder that contains the ldif-based configuration.

Warning: There is no process to convert from slapd.d to slapd.conf. Additionally, while slapd.d is in use, changes to the slapd.conf file will not take effect.

To convert from slapd.conf to slapd.d, follow these steps:

  1. Stop ‘slapd’ (solserver)

     sudo service solserver stop
  2. Make slapd.d directory

     mkdir /opt/symas/etc/openldap/slapd.d
  3. Convert slapd.conf to slapd.d

     slaptest -f /opt/symas/etc/openldap/slapd.conf -F
     /opt/symas/etc/openldap/slapd.d
  4. Update ownership of the slapd.d directory

     sudo chown -R ldap:ldap /opt/symas/etc/openldap/slapd.d 

(Optional) Rename slapd.conf file (slapd.d directory will take precedence over

existing slapd.conf file)

    mv /opt/symas/etc/openldap/slapd.conf
    /opt/symas/etc/openldap/slapd.conf.converted
  1. Start the /opt/symas/etc/solserver service

     sudo service solserver start

Alternate SLAPD.D Location

Normally, the slapd.d directory is located in /opt/symas/etc/openldap

and solserver, by default, will look for it there when starting the slapd process. However, the slapd.d directory can reside anywhere within the file system. If using an alternate location, simply update the symas-openldap.conf file as follows:

    EXTRA_SLAPD_ARGS="-F /<alt>/<path>/<to>/slapd.d"

This change will require a restart of the slapd service

Export SLAPD.D to Editable LDIF

There are many reasons to export the cn=config database to an editable

text file including adding/modifying the rootdn and rootpw credentials for the cn=config database after converting from slapd.conf to slapd.d.

  1. Stop solserver

  2. Export the config database to a text file:

     slapcat -F /opt/symas/etc/openldap/slapd.d -l config.ldif -b cn=config
  3. Move the existing config database out of the way:

     mv /opt/symas/etc/openldap/slapd.d.old
  4. Create a new, empty config database:

     mkdir /opt/symas/etc/openldap/slapd.d
    
     sudo chown --reference=/opt/symas/etc/openldap/slapd.d.old
     /opt/symas/etc/openldap/slapd.d
  5. (optional) Edit the exported config.ldif file to add olcRootDN and olcRootPW to cn=config section or other changes as needed:

     vi /opt/symas/etc/openldap/config.ldif
  6. Import the edited LDIF into the new empty database directory:

     slapadd -F /opt/symas/etc/openldap/slapd.d -l config.ldif -b cn=config
  7. Start solserver

Warning: Slapadd of a complete configuration LDIF should always be done into an empty database. If an error occurs simply clear out the partial database before trying again.

Ordered Values

Throughout the slapd.d database entries and attributes are given a

unique identifier in curly brackets {#} known as an “ordered value”. This method of identification indicates the weight or priority of the attribute. When adding attributes or entries, be sure to check for the next available ordered value. This instructs slapd how to order the entries or attributes, {0}processed first, {1}, {2}, {3}… processed subsequently. If an ordered value is not specified the next available identifier will be assigned. For loaded modules, access control lists, overlays, etc. the order can be particularly important. Pay attention!

SLAPD.D Sections

Warning: cn=config does not support the deletion of objects and many attributes/values. This will probably be supported in OpenLDAP 2.5. However, use caution when making changes to the slapd.d database. In the event an unintended addition occurs, the following can be used as a workaround to remove it:

Run ’ slapcat -n0 -l /tmp/config.ldif’ which produces a single ldif of

the full config tree. Edit the resulting config.ldif to exclude the unneeded part of the configuration. Then stop solserver (slapd service), delete and recreate the /opt/symas/etc/openldap/slapd.d directory. Run ’ slapadd -n0 -l /tmp/config.ldif’ and start solserver (slapd service).

CN=Config

The cn=config container holds the global configuration settings including TLS, SASL, Authz, ServerID and Loglevel. It also contains sub-containers for modules, schemas, and databases such as frontend (overlays and backend- specific parameters applied globally such as Access Control Lists and Chaining configuration), config (contains the cn=config rootDN and password), mdb (backend database configuration) and monitor.

(Graphic missing)

Example ldapmodify commands:

  • Add Global Configuration Setting

      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=config
      changetype: modify
      add: olcLogFile
      olcLogFile: /<full>/<path>/<to>/<logfile> 

Extra Enter to execute Ctrl+d to terminate

  • Remove Global Configuration Setting

      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=config
      changetype: modify
      delete: olcLogLevel
      olcLogLevel: Stats
  • Modify Global Configuration Setting

      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=config
      changetype: modify
      replace: olcThreads
      olcThreads: 8
      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=config
      changetype: modify
      add: olcAuthzRegexp
      olcAuthzRegexp:
      {0}gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth cn =config

Add Database

Update olcDatabase’s weight {#} accordingly. Create the directory

before performing the ldapmodify. Update database maxsize, required indices and root credentials as needed.

    ldapadd -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={2}mdb,cn=config
    objectClass: olcMdbConfig
    objectClass: olcDatabaseConfig
    olcDatabase: {2}mdb
    olcDbDirectory: /var/symas/openldap-data/example1
    olcSuffix: dc=example1,dc=com
    olcAddContentAcl: FALSE
    olcReadOnly: FALSE
    olcRootDN: dc=example1,dc=com
    olcRootPW: secret
    olcSizeLimit: unlimited
    olcTimeLimit: unlimited
    olcMaxDerefDepth: 15
    olcDbNoSync: FALSE
    olcDbIndex: default eq
    olcDbIndex: objectClass eq
    olcDbIndex: entryUUID eq
    olcDbIndex: entryCSN eq
    olcDbIndex: cn eq
    olcDbMode: 0600
    olcDbMaxEntrySize: 0
    olcDbMaxReaders: 0
    olcDbMaxsize: 85899345920
    olcDbRtxnSize: 10000
    olcDbSearchStack: 16
    olcLastMod: TRUE
    olcMirrorMode: FALSE
    olcMonitoring: TRUE

For Consumer servers add attributes for olcSyncrepl, olcSyncUseSubentry

and olcUpdateRef as needed. For multi-master replication switch olcMirrorMode to True

    olcSyncrepl: rid=001 provider=ldap://gb1scoltest01.symas.net
    bindmethod=simple timeout=0 network-timeout=0
    binddn="dc=example,dc=com" credentials="secret" keepalive=0:0:0
    starttls=no filter="(objectclass=*)"
    searchbase="dc=example,dc=com" scope=sub schemachecking=off
    type=refreshAndPersist retry="60 +"
    olcSyncUseSubentry: FALSE
    olcUpdateRef: ldap://<producer server's FQDN> 
    olcMirrorMode: TRUE

CN=Module

The object class ModuleList contains a list of all included modules as

operational attributes. The ModulePath is also listed as an operational attribute and can be modified as needed. Note each module is given a unique identifier in curly brackets {#} known as an “ordered value”. This method of identification repeats throughout the slapd.d database. When adding attributes, be sure to check for the next available ordered value.

(Graphic missing)

Example ldapmodify commands:

  • Add module

      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=module{0},cn=config
      changetype: modify
      add: olcModuleLoad
      olcModuleLoad: {3}ppolicy.la

Extra Enter to execute Ctrl+d to terminate

  • Change module path

      ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
      DN: cn=module{0},cn=config
      changetype: modify
      replace: olcModulePath
      olcModulePath: /<full>/<path>/<to>/<modules> 

CN=Schema

Modifying the SchemaConfig object is more complicated in slapd.d and

special instructions for doing so are included at the end of this document. The cn=schema container shows all defined attribute types, syntaxes, object classes and object identifiers as multi-valued operational attributes from all schemas in use. However, each schema file is listed as a separate subtree with its own defined attribute types and object classes. Again, note the ordered values of the subtrees and the attribute values.

(Graphic missing)

olcDatabase={-1}frontend

The frontend contains backend-specific parameters applied globally such as Access Control Lists (ACLs). olcAccess is an ordered attribute by weight signified by {#}. This instructs slapd how to order the ACLs, {0} processed first, {1}, {2}, {3}… processed subsequently.

(Graphic missing)

Frontend also contains sub-containers for globally applied overlays such as Chaining. Note that the overlay contains subtrees for each database to which the overlay is applied.

(Graphic missing)

Add Access Control List

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={-1}frontend,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {2}to * by dn.base="cn=config" write break 

Extra Enter to execute Ctrl+d to terminate > NOTE: Any ACLs previously weighted 2 or higher will be automatically renumbered to 3 and higher.

Remove Access Control List using the Weight Only (Full ACL text is not required)

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={-1}frontend,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {2}

Remaining ACLs will renumber their weights automatically.

Change Access Control Lists

then add in the corrected value using the two processes above. However, if the number of existing olcAccess attributes is small, it may be easier to replace them all with a single ldapmodify command as follows:

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={-1}frontend,cn=config
    changetype: modify
    replace: olcAccess
    olcAccess: {0}to dn.base="" by * read 
    olcAccess: {1}to * by dn.base="cn=config" write break 
    olcAccess: {2}to * by self write by users read by anonymous auth by 
    sockurl.exact= "^ldapi:///$" write 

olcDatabase={0}Config

This section defines database 0, cn=config. Adding olcRootDN and

olcRootPW to this section will allow modifications to the entire slapd.d configuration. By default viewing and modification privileges to the cn=config database are restricted to the rootDN.

(Graphic missing)

Change cn=config RootPW

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={0}config,cn=config
    changetype: modify
    replace: olcRootPW
    olcRootPW: {SSHA}cuz7UaNFrHvzk57ugRC3lQqnLHrcWKt+

Add write permission for regular database user to modify cn=config database

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {1}to * by dn="uid=<username>,ou=people,dc=example,dc=com" write

olcDatabase={1}MDB

The database subtree contains all the configurations required for the database, plus subtrees for any applied overlays. The database subtree is automatically created when added to cn=config. Modifications to the individual tree can include olcRootDN, olcDbIndex, olcDbMaxSize, olcDbMultivalHi|Lo, olcSuffix, olcRootDN and olcRootPW.

(Graphic missing)

Add Index

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={1}mdb,cn=config
    changetype: modify
    add: olcDbIndex
    olcDbIndex: entryUUID eq

Modify Database Maxsize

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcDatabase={1}mdb,cn=config
    changetype: modify
    replace: olcDbMaxSize
    olcDbMaxSize: 10737418240

Additionally, overlays for the database can be configured.

(Graphic missing)

Add Overlay

    ldapadd -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config 
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: syncprov
    olcSpNoPresent: TRUE
    olcSpReloadHint: TRUE

Modify Overlay

    ldapmodify -x -H ldap://<ldap server fqdn> -D cn=config -w <password>
    DN: olcOverlay={0}pcache,olcDatabase={1}mdb,cn=config 
    changetype: modify
    replace: olcPcachePersist
    olcPcachePersist: TRUE

olcDatabase={2}Monitor

The monitor database contains a predefined set of analytics which

generate statistics. No modifications to this configuration are required.

(Graphic missing)

Modifying Existing Attributes

Periodically when you attempt to modify an existing attribute in the

cn=config database you will receive the UnwillingToPerform (53) error code. This may indicate other attributes are required before the existing attribute can be modified. For example, if you want to set olcTLSVerifyClient from never to demand, the olcTLSCACertificateFile, olcTLSCertificateFile and olcTLSCertificateKeyFile attributes would need to be added. Otherwise, TLS authentication would be required, but no cert/key pair would be recognized. You would essentially be locked out of your

Return to Static Configuration Files

While there is no way to convert slapd.d back to a static slapd.conf

file, it may be necessary to return to a static configuration for troubleshooting, development, etc. To do this simply move, rename or delete the /opt/symas/etc/openldap/slapd.d directory.

By default the solserver (slapd) service will read

/opt/symas/etc/openldap/slapd.d before it reads /opt/symas/etc/openldap/slapd.conf and if the slapd.d directory is found, slapd.conf will be ignored. By renaming, moving or deleting the slapd.d directory, solserver will defer to the static slapd.conf file.

NOTE: The slapd.conf file is not kept up-to-date by changes made to the slapd.d configuration. The slapd.conf file will need to be updated and solserver restarted to match the current slapd.d settings.

_____________________________________________________________

Updating Schemas

Remember: Custom schemas should always been saved in a directory apart from /opt/symas/etc/openldap/schema. This directory is replaced during uninstall and upgrade operations.

Adding/Removing Schemas

  • For SLAPD.conf

Additional schema files can be added by including them in the global

section of the /opt/symas/etc/openldap/slapd.conf file. Comment out or delete those to be removed.

    # Schema files. Note that not all of these schemas co-exist peacefully.
    # Use only those you need and leave the rest commented out.
    Include /opt/symas/etc/openldap/schema/core.schema
    # Include /opt/symas/etc/openldap/schema/cosine.schema
    Include /opt/symas/etc/openldap/schema/inetorgperson.schema 
    Include /opt/symas/etc/openldap/custom-schema/customcosine.schema

Warning: Restart the solserver (slapd) service before adding attributes from new schemas to the index.

Warning: DO NOT remove a schema if attributes and object classes defined in that schema are in use in the database. Doing so will result if a variety of errors including corrupting the database and preventing database restoration. If this is done accidentally, slapcat the database and remove any entries in CAPS (indicative of undefined attributes/object classes) from the resulting ldif file. Then recreate the database minus the undefined attributes/object classes using slapadd.

  • For SLAPD.D

Copy your custom schema to the /opt/symas/etc/openldap/custom-schema directory.

    cd /opt/symas/etc/openldap/
    cp schema/cosine.schema custom-schema/customcosine.schema 

files.

    cat > schema_conf << EOL
    > include /opt/symas/etc/openldap/schema/core.schema
    > include /opt/symas/etc/openldap/custom-schema/customcosine.schema
    > EOL

Convert the custom schema to an ldif file

    slaptest -f schema_conf -F custom-schema

Confirm file creation

    ll -r custom-schema
        ?Should see the following:
        ?total 8
        ?drwxr-x--- 3 root root 4096 Apr 14 14:40 cn=config
        ?-rw------- 1 root root 1029 Apr 14 14:40 cn=config.ldif 
    ll custom-schema/cn=config/cn=schema
        Should see the following:
        total 36
        -rw------- 1 root root 15546 Apr 14 14:40 cn={0}core.ldif
        -rw------- 1 root root 11363 Apr 14 14:40 cn={1}customcosine.ldif

Adjust the name of the schema ldif to be next in the list of

schemas already in use and then import the schema to the slapd.d configuration

    ll /opt/symas/etc/openldap/slapd.d/cn=schema
        Should return
        total 2
        cn={0}core
        cn={1}inetorgperson
    
    cd custom-schema/cn=config/cn=schema
    vi cn={1}customcosine.ldif

    Update the DN from
        cn=**{2}**customcosine
    To
        cn=**{3}**customcosine**,cn=schema,cn=config** 
    Update the CN from
        **{2}**customcosine
    To
        **{3}**customcosine

Important: Delete the following lines from the end of the file

        structuralObjectClass: olcSchemaConfig
        entryUUID: <random string>
        creatorsName: cn=config
        createTimestamp: <date time>
        entryCSN: <CSN info>
        modifiersName: cn=config
        ModifyTimestamp: <date time>

    ldapadd -x -H ldap://<server FQDN>/ -D <cn=config rootDN> -W -f customcosine.ldif

Use the cn=config database rootPW

Adding/Removing ObjectClasses and MUST Attributes

  • For SLAPD.CONF

Stop solserver (slapd process) on all LDAP servers

    /opt/symas/etc/solserver stop

Backup the Database

    slapcat -l /tmp/data.ldif

Update the schema file and add it to the includes in the global section of

/opt/symas/etc/openldap/slapd.conf

    vi /opt/symas/etc/openldap/slapd.conf
        include </full/path/to/schema file>
    :wq      (Save and Quit)

Import the database

    slapadd -l /tmp/data.ldif

Repeat on all LDAP servers

Start solserver on Producer servers, then on Consumer servers

    /opt/symas/etc/solserver start
  • For SLAPD.D

To add an attribute or objectClass first obtain the DN of the schema you

wish to update

    ldapsearch -x -H ldap://<server FQDN>/ -D <CN=Config rootDN> -W -b 
    cn=schema,cn=config -LLL dn

Results should look similar to this:

    dn: cn=schema,cn=config
    dn: cn={0}core,cn=schema,cn=config
    dn: cn={1}cosine,cn=schema,cn=config
    dn: cn={2]inetorpperson,cn=schema,cn=config
    dn: cn={3}customcosine,cn=schema,cn=config

For objectClasses you will also need the next available number of

objectClass entry in the cn=config database.

ldapsearch -x -H ldap:/// -D <CN=Config rootDN> -W -b cn={3}customcosine,cn=schema,cn=config -LLL olcObjectClasses

Use the cn=config database rootPW

Results should look similar to this:

    dn: cn={3}nis,cn=schema,cn=config
    olcObjectClasses: {0}( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
    DESC 'Abstraction of an account with POSIX attributes' SUP
    top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $
    homeDirectory ) MAY ( userPassword $ loginShell $ gecos $
    description ) )
    olcObjectClasses: {1}( 1.3.6.1.1.1.2.1 NAME
    'shadowAccount' DESC 'Additional attributes for shadow 
    passwords' SUP top AUXILIARY MUST uid MAY ( userPassword 
    $ shadowLastChange $ shadowMin $ shadowMax $
    shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag $
    description ) )
    olcObjectClasses: {2}( 1.3.6.1.1.1.2.2 NAME 'posixGroup'
    DESC 'Abstraction of a group of accounts' SUP top 
    STRUCTURAL MUST ( cn $ gidNumber ) MAY ( userPassword $
    memberUid $ description ) )
    olcObjectClasses: {3}( 1.3.6.1.1.1.2.3 NAME 'ipService'
    DESC 'Abstraction an Internet Protocol service' SUP top 
    STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtocol ) 
    MAY description )
    olcObjectClasses: {4}( 1.3.6.1.1.1.2.4 NAME 'ipProtocol'
    DESC 'Abstraction of an IP protocol' SUP top STRUCTURAL
    MUST ( cn $ ipProtocolNumber $ description ) MAY
    description )
    olcObjectClasses: {5}( 1.3.6.1.1.1.2.5 NAME 'oncRpc' DESC
    'Abstraction of an ONC/RPC binding' SUP top STRUCTURAL
    MUST ( cn $ oncRpcNumber $ description ) MAY description )
    olcObjectClasses: {6}( 1.3.6.1.1.1.2.6 NAME 'ipHost' DESC
    'Abstraction of a host, an IP device' SUP top AUXILIARY
    MUST ( cn $ ipHostNumber ) MAY ( l $ description $ manager
    ) )

NOTE: the numbers in the {brackets}. The new objectclass will use the next available number.

Next, create an ldif with the attributeType or objectClass information

you wish to add

    vi customattribute.ldif

Enter the following modified for the attributeType or objectClass:

    dn: cn={3}customcosine,cn=schema,cn=config
    changetype: modify
    add: olcAttributeTypes
    olcAttributeTypes: (1.3.6.1.1.1.1.12 NAME 'memberUid'
    EQUALITY caseExactIA5Match SUBSTR
    caseExactIA5SubstringsMatch SYNTAX
    1.3.6.1.4.1.1466.115.121.1.26 )

results above)

    dn: cn={3}customcosine,cn=schema,cn=config
    changetype: modify
    add: olcObjectClasses
    olcObjectClasses: {6}( 1.3.6.1.1.1.2.9 NAME 'nisMap' DESC
    'A generic abstraction of a NIS map' SUP top STRUCTURAL
    MUST nisMapName MAY description )

Finally, import the ldif using ldapmodify

    ldapmodify -x -H ldap://<server FQDN>/ -D <cn=config rootDN> -W -f
    customattribute.ldif

Use the cn=config database rootPW

When removing ObjectClasses or Attributes, ensure the value is not use

by performing a simple ldapsearch

    ldapsearch -x -H ldap://<server FQDN>/ -D <rootDN> -w <rootPW> -b
    dc=example,dc=com -LLL '(<attribute>=*)'
    
    ldapsearch -x -H ldap://<server FQDN>/ -D <rootDN> -w <rootPW> -b
    dc=example,dc=com -LLL '(Objectclass=<objectClass>)'

Next, create an ldif with the attributeType or objectClass information

you wish to delete

    vi customattribute.ldif

Enter the following modified for the attributeType or objectClass:

    dn: cn={3}customcosine,cn=schema,cn=config
    changetype: delete
    add: olcAttributeTypes
    olcAttributeTypes: (1.3.6.1.1.1.1.12 NAME 'memberUid'
    EQUALITY caseExactIA5Match SUBSTR
    caseExactIA5SubstringsMatch SYNTAX
    1.3.6.1.4.1.1466.115.121.1.26 )

Or (remember to update the number in the {brackets} from the search

results above)

    dn: cn={3}customcosine,cn=schema,cn=config
    changetype: modify
    delete: olcObjectClasses
    olcObjectClasses: {6}

Finally, import the ldif using ldapmodify

    ldapmodify -x -H ldap://<server FQDN>/ -D <cn=config rootDN> -W -f
    customattribute.ldif

Use the cn=config database rootPW

Adding/Removing MAY Attributes

  • For SLAPD.CONF

Add the MAY attribute to the custom schema file on all servers

Restart solserver on all servers (Consumers first, then Producers)

    /opt/symas/etc/solserver restart
  • For SLAPD.D

Follow the process for ObjectClasses and MUST Attributes above.