Encourage FUNIX

The consultation of the site is completely free and without advertisements. Donations are nevertheless appreciated to pay for hosting and encourage its author


Installing the OpenLDAP directory
[ Presentation | database format and definitions ( The Directory Information Tree , Attributes , Object classes , Schemas ) |  Installing OpenLDAP     ( Presentation , installation  ) | Setting up your directory schema ( Setting up object classes , choosing the suffix ) | Configuring the LDAP server   | Starting the server | Configuring an encrypted connection with SSL | Adding a record | Searching for a record | Modifying a record ( Adding an attribute to a record , modifying an attribute , deleting an attribute , deleting a record , exporting importing an LDAP database ) | Switching to encrypted connection ]

Last modified July 16, 2022

Installing the OpenLDAP directory

Network and system

This site has been automatically translated with Google Translate from this original page written in french, there may be some translation errors

Presentation

LDAP is a TCP/IP-based protocol that allows information databases to be shared on an internal (intranet) or external (internet) network. These databases are called electronic directories (Directories in English), they can contain any type of information, from information on people to system data. Who says database, says search, it is therefore possible to search the database using several criteria, but also of course to modify it, but unlike a DBMS, a directory is very fast in reading, but much less so in writing, in fact as a directory is rather read than modified it has been optimized for reading and does not have the complex transaction mechanisms that DBMS have to process large volumes of data. LDAP
or Lightweight Directory Access Protocol is the TCP/IP version of the DAP protocol , the latter being the protocol for accessing the OSI protocol of the X500 directory service. At first LDAP was just the interface to X500 directories, but now LDAP can completely manage databases (standalone LDAP ).

If we go into details, the LDAP protocol is of the client server type, the server contains the database, and the client consults the database, the protocol provides the bases for this communication between the client and the server (standardized by the IETF by RFC2251), and the commands necessary for the client to search, create, modify or delete data. LDAP is of course secure for the transfer and access to data, with encryption tools such as SSL and authentication.
In addition, LDAP provides tools so that LDAP servers can communicate with each other, so we have the possibility of creating mirror servers that can synchronize, or simply link the servers together, the servers automatically redirecting requests that do not concern them.

There are many examples of LDAP applications :
- employee databases,
- product databases,
- databases for certain applications, example:
        * all the information containing the users of your network (password, shell, homedirectory, ...) can be in the database, so we have many more possibilities than a simple /etc/passwd file , authentication can therefore use LDAP rather than passwd or shadow or even NIS . Your users will thus be able to change their password and some of their attributes from a web interface.
        * application or environment preferences ( netscape , KDE graphical environment, ...) are saved in the database, so the user can move from one machine to another and find his preferences.

This page is an introduction to LDAP, it does not cover certain aspects such as links with other databases (duplication, mirror, ...), security (access control, SSL, ...). Its only purpose is to set up a simply configured LDAP server so that you can make your "first steps" in the field. For more information, refer to Laurent Mirtain 's excellent page.

To use an LDAP database from a PHP script, see my Apache page.

To see how to set up a user authentication system using LDAP in the NIS way see my other page on LDAP.

 

Base format and definitions

The Directory Information Tree

Standalone LDAPs use the LDBM database format , which uses the hierarchical model like the UNIX file system, that is to say it is similar to a tree, which is called DIT ( Directory Information Tree). At the top of this tree is the root or suffix and at each node of the tree there is a DSE (Directory Service Entry) which corresponds to an entry in the directory. The entry located at the root is called rootDSE (root Directory Specific Entry), which describes the structure of the tree (the DIT ) as well as its content. Each entry is known uniquely in the tree thanks to its dn (Distinguished Name). The dn indicates the path to follow from the top to reach the corresponding entry. For example, to identify a person, we start with the country (fr), then the domain name ( kervao ), the work group and finally the name of the person, all of these parameters are the DN which uniquely identifies a person.

The attributes

Each entry can be considered as an object (in the C++ sense) therefore having certain attributes, for example if a person is an entry, the attributes can be, the name, the first name, the age, .... We can also define mandatory attributes and other optional ones, in other words, the mandatory attributes must be filled in but not necessarily the optional ones. There are also for each DSE administration attributes which are only used by the server.

Object Classes

We group objects that are of the same domain in an object class, this one is characterized by mandatory or optional attributes and a type. The types of object class are:
- structural type because it contains concrete objects of the directory (people, groups of people, ...),
- auxiliary type, these are object classes that can be created, to add additional information (attributes) to already existing structural type object classes. In C++ we will say that the auxiliary class derives from a structural class,
- abstract type, these are the object classes that exist by default and that have no concrete meaning, for example the top class is the generic object class, all the other classes derive from this class.

The principle is therefore the same as in C++, we find a tree structure, with the top class at the root , all the other object classes derive from this generic class, each class inherits the properties of a parent class and has additional attributes compared to the latter.

The diagrams

A schema describes all the rules that the LDAP server uses to describe object classes (attributes, syntax, ...).

Installing OpenLDAP

There are many LDAP servers , we will use OpenLDAP which as its name indicates is under GPL license. I chose to make it simple to install the packaged version of my distribution, you will need to install the openldap-servers and openldap-clients packages . If necessary you will find the latest stable version at the URL http://www.openldap.org

Setting up your directory schema

Setting up object classes

The slapd.conf file calls /usr/share/openldap/schema/core.schema which describes object classes. Here is an example with the " person " class

objectclass (2.5.6.6 NAME 'person'
        DESC 'RFC2256: a person'
        SUP top STRUCTURAL
        MUST (sn $cn)
        MAY (userPassword $telephoneNumber $seeAlso $description))

MUST corresponds to the mandatory attributes and MAY to the optional ones
objectClass is the name of the class which itself descends from the top class
sn corresponds to surname
cn corresponds to common name
I'll let you guess the meaning of the other attributes.

We see that it is necessary to provide the attributes sn (surname) and cn (common name), the password ( userPassword ), the telephone number ( telephoneNumber ), the links ( seeAlso ) and the description are optional.

The attributes are defined in the same file, the syntax is as follows for telephoneNumber for example:

attributetype ( 2.5.4.20 NAME 'telephoneNumber'
        DESC 'RFC2256: Telephone Number'
        EQUALITY telephoneNumberMatch
        SUBSTR telephoneNumberSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )

I will present the syntax later, we can initially limit ourselves to the available attributes. To create a breizhPerson object class derived from person , with the mandatory title attribute in addition and the optional arguments ou (workgroup) and l (location). We will type in the core.schema file just after the definition of the person class

objectclass (2.5.6.6.2 NAME 'breizhPerson' SUP person STRUCTURAL
    MUST (title)
    MAY (or $l))

You will notice the number 2.5.6.6.2, this number must be unique in the file, it derives directly from the number of the person object class which has the number 2.5.6.6. It is obvious that as breizhPerson derives from person, the sn and cn attributes are also mandatory.

Choice of suffix

The rootDSE or suffix corresponds to the entry at the very top of the tree ( DIT ) of the directory, we generally use the domain name, with the following syntax  dc=kervao, dc=fr  for the domain kervao.fr ( dc corresponds to Domain Component).

LDAP Server Configuration

We will create an LDAP directory for your private domain kervao.fr. We must modify the slapd.conf and ldap.conf files located under /etc/openldap. That's it for the slapd.conf configuration file.

# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.6 2001/04/20 23:32:43 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
# Modified by Christian Zoffoli <czoffoli@linux-mandrake.com>
# Version 0.2

include /usr/share/openldap/schema/core.schema
include /usr/share/openldap/schema/cosine.schema
include /usr/share/openldap/schema/corba.schema
include /usr/share/openldap/schema/inetorgperson.schema
include /usr/share/openldap/schema/java.schema
include /usr/share/openldap/schema/krb5-kdc.schema
include /usr/share/openldap/schema/kerberosobject.schema
include /usr/share/openldap/schema/misc.schema
include /usr/share/openldap/schema/nis.schema
include /usr/share/openldap/schema/openldap.schema
include /usr/share/openldap/schema/autofs.schema
include /usr/share/openldap/schema/samba.schema
include /usr/share/openldap/schema/kolab.schema
include /usr/share/openldap/schema/evolutionperson.schema
include /usr/share/openldap/schema/calendar.schema
include /usr/share/openldap/schema/sudo.schema
include /usr/share/openldap/schema/dnszone.schema
include /usr/share/openldap/schema/dhcp.schema

include /etc/openldap/schema/local.schema

# Define global ACLs to disable default read access and provide default
# behavior for samba/pam use
include /etc/openldap/slapd.access.conf

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org

pidfile /run/ldap/slapd.pid
argsfile /run/ldap/slapd.args

modulepath /usr/lib64/openldap

# database backend modules available:
moduleload back_mdb.la 

# To allow TLS-enabled connections, create /etc/ssl/openldap/ldap.pem
# and uncomment the following lines.
#TLSCertificatePath /etc/ssl/openldap/

#TLSCACertificateFile /etc/ssl/cacert.pem

TLSCACertificateFile /etc/pki/tls/certs/ldap.pem

######################################################################
# database definitions
#####################################################################

database mdb
suffix "dc=kervao,dc=fr"
rootdn "cn=Manager,dc=kervao,dc=fr"

# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret

# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd/tools. Mode 700 recommended, directory where the database is located
directory /var/lib/ldap

# Tuning settings, please see the man page for slapd-bdb for more information
# as well as the DB_CONFIG file in the database directory
# commented entries are at their defaults
# In-memory cache size in entries
#cachesize 1000
# Checkpoint the bdb database after 256kb of writes or 5 minutes have passed
# since the last checkpoint
checkpoint 256 5

# Indices to maintain
index objectClass eq

# persion-type searches
index cn,mail,surname,givenname eq,subinitial

# nss_ldap exact searches:
index uidNumber,gidNumber,memberuid,member,uniqueMember eq
# username completion via nss_ldap needs uid indexed sub:
index uid eq,subinitial

# samba:
index sambaSID,sambaDomainName,displayName eq

# autofs:
#index nisMapName eq

# bind sdb_ldap:
#index zoneName,relativeDomainName eq

# sudo
#index sudoUser eq

# syncprov
#index entryCSN,entryUUID eq


# Replicas running syncrepl as non-rootdn need unrestricted size/time limits:
limits group="cn=Replicator,ou=Group,dc=example,dc=com"
 size=unlimited
 time=unlimited

# Basic ACL (deprecated in favor of ACLs in /etc/openldap/slapd.access.conf)
access to attrs=userPassword
         by self write
         by anonymous auth
         by dn="cn=Manager,dc=kervao,dc=fr" write
         by * none
#
access to *
         by dn="cn=Manager,dc=kervao,dc=fr" write
         by * read

The LDAP database was created by default under /var/lib/ldap

The ldap.conf file may initially be empty or even nonexistent.

The administrator password is secret in clear text, if you don't like it and want to encrypt it, you will have to type

slappasswd

we enter our password

New password:
Re-enter new password:

and here is the result

{SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI

Instead of

rootpw secret

In slapd.conf, you will therefore put:

rootpw          {SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI

Server Launch

For launching with systemd there is a slapd.service file under /usr/lib/systemd/system/ here is its content

After=syslog.target

[Service]
Type=forking
PIDFile=/run/ldap/slapd.pid
Environment="SLAPDURLLIST=ldap:///ldapi:///" "LDAP_USER=ldap" "LDAP_GROUP=ldap" "SLAPDSYSLOGLOCALUSER=local4" "SLAPDSYSLOGLEVEL=0"
EnvironmentFile=/etc/sysconfig/slapd
ExecStartPre=/usr/share/openldap/scripts/ldap-config check
ExecStart=/usr/sbin/slapd -u ${LDAP_USER} -g ${LDAP_GROUP} -h ${SLAPDURLLIST} -l ${SLAPDSYSLOGLOCALUSER} -s ${SLAPDSYSLOGLEVEL}

[Install]
WantedBy=multi-user.target

 
now so that the service is launched at each boot of the machine you will have to type

systemctl enable slapd.service

here is the result

Created symlink from /etc/systemd/system/multi-user.target.wants/slapd.service to /usr/lib/systemd/system/slapd.service.

to launch it now just type

systemctl start slapd.service
 

and to know his condition

systemctl status slapd.service

here is the result

● slapd.service - OpenLDAP Server Daemon
     Loaded: loaded (/usr/lib/systemd/system/slapd.service; disabled; vendor preset: disabled)
     Active: active (running) since Sat 2022-07-16 11:24:49 CEST; 2h 13min ago
    Process: 3267 ExecStartPre=/usr/share/openldap/scripts/ldap-config check (code=exited, status=0/SUCCESS)
    Process: 3302 ExecStart=/usr/sbin/slapd -u ${LDAP_USER} -g ${LDAP_GROUP} -h ${SLAPDURLLIST} -l ${SLAPDSYSLOGLOCALUSER} -s ${SLAPDSYSLOGLEVEL} (code=exited, status=0/SUCCESS)
   Main PID: 3303 (slapd)
      Tasks: 3 (limit: 9283)
     Memory: 3.1M
        CPU: 57ms
     CGroup: /system.slice/slapd.service
             └─3303 /usr/sbin/slapd -u ldap -g ldap -h ldap:/// ldapi:/// -l local4 -s 0

Jul 16 11:24:48 server-slapd.kervao.fr systemd[1]: Starting OpenLDAP Server Daemon...
Jul 16 11:24:48 server-slapd.kervao.fr su[3274]: (to ldap) root on none
Jul 16 11:24:49 slapd-server.kervao.fr su[3274]: pam_unix(su:session): session opened for user ldap by (uid=0)
Jul 16 11:24:49 slapd-server.kervao.fr su[3274]: pam_unix(su:session): session closed for user ldap
Jul 16 11:24:49 server-slapd.kervao.fr ldap-config[3267]: Checking the configuration file /etc/openldap/slapd.conf: [ OK ]
Jul 16 11:24:49 server-slapd.kervao.fr systemd[1]: Started OpenLDAP Server Daemon.

[ Back to top of page ]

Encrypted connection with SSL

For an encrypted connection with SSL between the client and the LDAP server, everything is done almost automatically with an installation under mageia with the openldap-servers package. This installation will create the certificate containing the public key /etc/pki/tls/certs/ldap.pem and the private key /etc/pki/tls/private/ldap.pem. The certificate is self-signed and is therefore only valid for a private network. Note that on my mageia 8, I find the same files respectively under /etc/ssl/certs and /etc/ssl/private.

In the file /etc/ldap/slapd.conf we will find the following lines which point to the correct files

# To allow TLS-enabled connections, create /etc/ssl/openldap/ldap.pem
# and uncomment the following lines.
TLSCertificateFile /etc/pki/tls/certs/ldap.pem
TLSCertificateKeyFile /etc/pki/tls/private/ldap.pem
TLSCACertificateFile /etc/pki/tls/certs/ldap.pem

You will also need to modify the /etc/sysconfig/slapd file and add the SSL connection on LDAP, ldaps like this

# SLAPD URL list
SLAPDURLLIST="ldap:/// ldapi:/// ldaps:///"

If the files have not been created, you will need to install the openssl-perl package to create a self-signed personal certificate that will only work on a private network as I was able to do for sendmail and dovecot. We will start by creating a CA certificate. We will type for that

CA.pl -newca

here is the result

CA certificate filename (or enter to create)

Making CA certificate ...
====
openssl req -new -keyout /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/careq.pem
Generating a RSA private key
.........++++++
................................+++++
writing new private key to '/etc/pki/CA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

I put a password at this level

-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:FR
State or Province Name (full name) []:Bretagne
Locality Name (eg, city) [Default City]:Brest
Organization Name (eg, company) [Default Company Ltd]:none
Organizational Unit Name (eg, section) []:none
Common Name (eg, your name or your server's hostname) []:serveur-slapd.kervao.fr
Email Address []:olivier.hoarau@funix.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:

I put another password here, remember to write them down afterwards!

An optional company name []:
==> 0
====
====
openssl ca -create_serial -out /etc/pki/CA/cacert.pem -days 1095 -batch -keyfile /etc/pki/CA/private/cakey.pem -selfsign -extensions v3_ca -infiles /etc/pki/CA/careq.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:

we enter the PEM password entered above

Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            11:b4:74:e2:eb:82:f6:f5:08:7d:2d:2f:81:75:e3:1e:2e:70:08:e2
        Validity
            Not Before: Jul 16 11:48:56 2022 GMT
            Not After: Jul 15 11:48:56 2025 GMT
        Subject:
            countryName = FR
            stateOrProvinceName = Bretagne
            organizationName = none
            organizationalUnitName = none
            commonName = server-slapd.kervao.fr
            emailAddress = olivier.hoarau@funix.org
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                5F:EF:90:A6:C4:C5:17:65:77:EE:DA:62:14:23:A4:D8:98:5D:FF:C8
            X509v3 Authority Key Identifier:
                keyid:5F:EF:90:A6:C4:C5:17:65:77:EE:DA:62:14:23:A4:D8:98:5D:FF:C8

            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Jul 15 11:48:56 2025 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
==> 0
====
CA certificate is in /etc/pki/CA/cacert.pem


we now copy the files to the correct locations (directory to be created beforehand if necessary)

cp newcert.pem /etc/ssl/public/ldapcrt.pem
cp newreq.pem /etc/ssl/ldap/ldapkey.pem
chown ldap:ldap /etc/ssl/ldap/ldapkey.pem ldap

user must own it

chown ldap:ldap /etc/ssl/ldap/ldapkey.pem

This will prevent us from making a mistake like this.

slapd[5803]: main: TLS init def ctx failed: -1

now we will modify the file /etc/openldap/slapd.conf we add the following lines

TLSCACertificateFile /etc/pki/CA/cacert.pem
TLSCertificateFile /etc/pki/CA/private/cakey.pem
TLSCertificateKeyFile /etc/pki/CA/cacert.pem

Now on the client workstations we will copy the signed certificate of the LDAP server wherever you want (in my example under/etc/pki/tls/certs/) with 644 rights.

chmod 644 ldapcrt.pem

We edit the file
/etc/openldap/ldapd.conf and thus modify

# SSL/TSL configuration. With CA-signed certs, TLS_REQCERT should be
# "demand", with the CA certificate accessible
#TLS_REQCERT    ([demand],never,allow,try)
# We ship with allow by default as some LDAP clients (e.g. evolution) have
# no interactive SSL configuration
TLS_REQCERT     allow

# CA Certificate locations
# Use the default self-signed cert generated by openldap-server postinstall
# by default
TLS_CACERT      /etc/pki/tls/certs/ldap.pem

restart slapd

systemctl stop sladp
systemctl start slapd

See here to test the configuration


Add a record

You have different ways to add data to the directory, for a better understanding we will first discuss the manual method. To add data to the LDAP server you must provide yourself with a file in LDIF format (for LDAP Directory Interchange Format), the format is an easily readable text format unlike the internal format of the directory. Here is an example of an LDIF file, note that:
- each record in the file is separated from the previous and the next by a blank line,
- spaces are taken into account. WARNING, it is very important that there is no space at the end of the line. In this case you risk getting an error like

ldap_add: Invalid syntax (21)
        additional info: objectClass: value #0 invalid per syntax

The syntax of the LDIF format is as follows:

dn : description of the distinguished name
objectclass : original object class
...
objectclass : derived object class
type attribute: value
...

For example, we will use the breizPerson class defined above to describe a new person Veronique Hoarau that we will add to the directory. She belongs to the service ( organizationalUnit ) staff, this same service belonging to the organization kervao.fr
Or the entree.ldif file

dn:     dc=kervao, dc=fr
objectClass: dcObject
objectClass:    organization
dc:     kervao
o:      kervao.fr

dn: ou=staff, dc=kervao, dc=fr
objectclass:    organizationalUnit
ou: staff

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
objectclass: person
objectclass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame

A few comments, the first group corresponds to the definition of your organization, the second to that of the work group ( organizationalUnit ) and the last to the person. This one is defined by its dn ( Distinguished Name ), we start from the top bz ( suffix of the domain name), then the domain name, the work group and finally the person. The tree ( DIT ) could look like this:

 

                                                                                                                         dc=fr
                                                                                                                            |
                                                                                                                     dc=kervao
                                                                                                                            |
                                                          ------------------------------------------------------------------------------------------------------------
                                                            |                                              |                                                              |                                |
                                                        ou=staff                                ou=informatique                ou=production            ou=achat
                                                            |
               ------------------------------------------------------------------
                    |                                                                |-b 'dc=kervao, dc=fr' '(objectclass=*)'
            cn=Veronique Hoarau                            cn=Olivier Hoarau

At the level of the definition of the person:

objetclass : person defines the parent class of the breizPerson class,
objetclass : breizPerson class describing the person,
cn and sn are mandatory attributes,
title is a mandatory attribute

We will add the record using the following syntax (as a simple user):

ldapadd -x -D "administrator dn description" -W -f ldif-file-name

Concrete example:

l dapadd -x -D "cn=Manager, dc=kervao, dc=fr" -W -f entree.ldif
Enter LDAP Password: secret
adding new entry "dc=kervao, dc=fr"

adding new entry "ou=staff, dc=kervao, dc=fr"

adding new entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

To subsequently add another record in the staff group , it will no longer be necessary to add the definition of the group and the organization. Either the entree.ldif file

dn: cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr
objectclass: person
objectclass: breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title: monsieur

Then we type the command:

ldapadd -x -D "cn=Manager, dc=kervao, dc=fr" -W -f entree.ldif
Enter LDAP Password:
adding new entry "cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr"

Search for a record

We will use the ldapsearch function . To view the entire directory we can type:

ldapsearch -x -b 'dc=kervao, dc=fr' '(objectclass=*)'

This is the result

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

# kervao.fr
dn: dc=kervao,dc=fr
objectClass: dcObject
objectClass: organization
dc: kervao
o: kervao.fr

# staff, kervao.fr
dn: ou=staff,dc=kervao,dc=fr
objectClass: organizationalUnit
ou: staff

# Veronique Hoarau, staff, kervao.fr
dn: cn=Veronique Hoarau,ou=staff,dc=kervao,dc=fr
objectClass: person
objectClass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame

# Olivier Hoarau, staff, kervao.fr
dn: cn=Olivier Hoarau,ou=staff,dc=kervao,dc=fr
objectClass: person
objectClass: breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title: monsieur

# search result
search: 2
result: 0 Success

# numResponses: 5
# numEntries: 4

Edit a record

Add an attribute to a record

We will add the optional location attribute ( l ) to the Veronique Hoarau record. We will create a modif.ldif file containing:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
add: l
title: bureau36

Then we type

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

Edit an attribute

We will modify the title attribute of the Veronique Hoarau record. We will create a modif.ldif file containing:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: modify
replace: title
title: mademoiselle

Then we type

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"

Delete an attribute

We will remove the location attribute ( l ) from the Veronique Hoarau record. We will create a modif.ldif file containing:

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
delete: l

Then we type

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
modifying entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr

Delete a record

To delete the Veronique hoarau record, we will create a modif.ldif file containing

dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: delete

Then we type:

ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f modif.ldif
Enter LDAP Password:secret
deleting entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr

ATTENTION You cannot delete a mandatory attribute like title for the breizhPerson class .

Export and import an LDAP database

The principle is to export a database on server A to reimport it on server B. To export a database on server A, type

slapcat > base.ldif

Now we return to server B on which we will have recovered the base.ldif file, we will first stop slapd by typing

systemctl stop slapd

then to import

slapadd -l base.ldif

here is the result

62d2baf8 /etc/openldap/slapd.conf: line 185: rootdn is always granted unlimited privileges.
62d2baf8 /etc/openldap/slapd.conf: line 189: rootdn is always granted unlimited privileges.
_#################### 100.00% eta none elapsed none fast!        
Closing DB...

Be careful if the base already contains duplicate pre-existing elements, it will cause an error like this

62d2b3b7 /etc/openldap/slapd.conf: line 185: rootdn is always granted unlimited privileges.
62d2b3b7 /etc/openldap/slapd.conf: line 189: rootdn is always granted unlimited privileges.
_# 8.38% eta 27s elapsed 02s spd 155.6 /s 62d2b3b9 mdb_id2entry_put: mdb_put failed: MDB_KEYEXIST: Key/data pair already exists(-30799) "dc=kervao,dc=fr"
62d2b3b9 => mdb_tool_entry_put: id2entry_add failed: err=-30799
62d2b3b9 => mdb_tool_entry_put: txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
slapadd: could not add entry dn="dc=kervao,dc=fr" (line=1): txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
.# 8.38% eta 27s elapsed 02s spd 0.0 /s
Closing DB..

In this case, you will have to clean up the database by simply deleting it.

rm -f /var/lib/ldap/*

we restart slapd to create a minimal base

systemctl start slapd

then we cut it to type

slapadd -l base.ldif

we then restart slapd

systemctl start slapd

[ Back to top of page ]

Switch to encrypted connection

Just add the -Z option to switch to encrypted connection, with debug mode in addition (-d 1), you should get this kind of message

TLS trace: SSL_connect:before SSL initialization
TLS trace: SSL_connect:SSLv3/TLS write client hello
TLS trace: SSL_connect:SSLv3/TLS write client hello
TLS trace: SSL_connect:SSLv3/TLS read server hello
TLS trace: SSL_connect:TLSv1.3 read encrypted extensions
TLS certificate verification: depth: 0, err: 0, subject: /CN=serveur-slapd.kervao.fr/OU=default ldap cert for server-slapd.kervao.fr/emailAddress=root@serveur-slapd.kervao.fr, issuer: /CN=serveur-slapd.kervao.fr/OU=default ldap cert for server-slapd.kervao.fr/emailAddress=root@serveur-slapd.kervao.fr
TLS trace: SSL_connect:SSLv3/TLS read server certificate
TLS trace: SSL_connect:TLSv1.3 read server certificate verify
TLS trace: SSL_connect:SSLv3/TLS read finished
TLS trace: SSL_connect:SSLv3/TLS write change cipher spec
TLS trace: SSL_connect:SSLv3/TLS write finished
ldap_sasl_bind
ldap_send_initial_request
ldap_send_server_request

(...)

TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSLv3/TLS read server session ticket
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSLv3/TLS read server session ticket

(...)

ldap_free_connection 1 1
ldap_send_unbind
ber_flush2: 7 bytes to sd 3
TLS trace: SSL3 alert write:warning:close notify
ldap_free_connection: actually freed

there is an error with the certificate which is self-signed but as we put TLS_REQCERT allow in the ldap.conf file it is not blocking. On the server side it gives this

Jul 16 14:26:32 slapd-server.kervao.fr slapd[5289]: conn=1001 fd=11 ACCEPT from IP=127.0.0.1:37634 (IP=0.0.0.0:389)
Jul 16 14:26:32 slapd-server.kervao.fr slapd[5289]: conn=1001 op=0 EXT oid=1.3.6.1.4.1.1466.20037
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 op=0 STARTTLS
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 op=0 RESULT oid= err=0 text=
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 fd=11 TLS established tls_ssf=256 ssf=256
Jul 16 14:26:32 slapd-server.kervao.fr slapd[5289]: conn=1001 op=1 BIND dn="" method=128
Jul 16 14:26:32 slapd-server.kervao.fr slapd[5289]: conn=1001 op=1 RESULT tag=97 err=0 text=
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 op=2 SRCH base="dc=kervao,dc=fr" scope=2 deref=0 filter="(objectClass=*)"
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 op=2 SEARCH RESULT tag=101 err=0 nentries=4 text=
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 op=3 UNBIND
Jul 16 14:26:32 server-slapd.kervao.fr slapd[5289]: conn=1001 fd=11 closed

 
[ Back to FUNIX home page ]