The Lightweight Directory Access Protocol (LDAP) is an application layer protocol used to access, modify, and authenticate objects using a distributed directory information service. Think of it as a phone or record book which stores several levels of hierarchical, homogeneous information. It is used in Active Directory and OpenLDAP networks and allows users to access to several levels of internal information utilizing a single account. For example, email authentication, pulling employee contact information, and internal website authentication might all make use of a single user account in the LDAP server's record base.
This section provides a quick start guide for configuring an LDAP server on a FreeBSD system. It assumes that the administrator already has a design plan which includes the type of information to store, what that information will be used for, which users should have access to that information, and how to secure this information from unauthorized access.
LDAP uses several terms which should be understood before starting the configuration. All directory entries consist of a group of attributes. Each of these attribute sets contains a unique identifier known as a Distinguished Name (DN) which is normally built from several other attributes such as the common or Relative Distinguished Name (RDN). Similar to how directories have absolute and relative paths, consider a DN as an absolute path and the RDN as the relative path.
An example LDAP entry looks like the
	following.  This example searches for the entry for the
	specified user account (uid),
	organizational unit (ou), and organization
	(o):
%ldapsearch -xb "uid=# extended LDIF # # LDAPv3 # base <uid=trhodes,ou=users,o=example.com> with scope subtree # filter: (objectclass=*) # requesting: ALL # # trhodes, users, example.com dn: uid=trhodes,ou=users,o=example.com mail: trhodes@example.com cn: Tom Rhodes uid: trhodes telephoneNumber: (123) 456-7890 # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1trhodes,ou=users,o=example.com"
This example entry shows the values for the
	dn, mail,
	cn, uid, and
	telephoneNumber attributes.  The
	cn attribute is the
	RDN.
More information about LDAP and its
	terminology can be found at http://www.openldap.org/doc/admin24/intro.html.
FreeBSD does not provide a built-in LDAP server. Begin the configuration by installing net/openldap-server package or port:
#pkg install openldap-server
There is a large set of default options enabled in the
	
	  package.  Review them by running
	pkg info openldap-server.  If they are not
	sufficient (for example if SQL support is needed), please
	consider recompiling the port using the appropriate framework.
The installation creates the directory
	/var/db/openldap-data to hold the data.
	The directory to store the certificates must be
	created:
#mkdir /usr/local/etc/openldap/private
The next phase is to configure the Certificate Authority.
	The following commands must be executed from
	/usr/local/etc/openldap/private.  This is
	important as the file permissions need to be restrictive and
	users should not have access to these files.  More detailed
	information about certificates and their parameters can be
	found in Section 13.6, “OpenSSL”.  To create the
	Certificate Authority, start with this command and follow the
	prompts:
#openssl req -days365-nodes -new -x509 -keyout ca.key -out ../ca.crt
The entries for the prompts may be generic
	except for the
	Common Name.  This entry must be
	different than the system hostname.  If
	this will be a self signed certificate, prefix the hostname
	with CA for Certificate Authority.
The next task is to create a certificate signing request and a private key. Input this command and follow the prompts:
#openssl req -days365-nodes -new -keyout server.key -out server.csr
During the certificate generation process, be sure to
	correctly set the Common Name attribute.
	The Certificate Signing Request must be signed with the
	Certificate Authority in order to be used as a valid
	certificate:
#openssl x509 -req -days365-in server.csr -out ../server.crt -CA ../ca.crt -CAkey ca.key -CAcreateserial
The final part of the certificate generation process is to generate and sign the client certificates:
#openssl req -days365-nodes -new -keyout client.key -out client.csr#openssl x509 -req -days 3650 -in client.csr -out ../client.crt -CA ../ca.crt -CAkey ca.key
Remember to use the same Common Name
	attribute when prompted.  When finished, ensure that a total
	of eight (8) new files have been generated through the
	proceeding commands.
The daemon running the OpenLDAP server is
	slapd.  Its configuration is performed
	through slapd.ldif: the old
	slapd.conf has been deprecated by
	OpenLDAP.
Configuration
	  examples for slapd.ldif are
	available and can also be found in
	/usr/local/etc/openldap/slapd.ldif.sample.
	Options are documented in slapd-config(5).  Each section
	of slapd.ldif, like all the other LDAP
	attribute sets, is uniquely identified through a DN.  Be sure
	that no blank lines are left between the
	dn: statement and the desired end of the
	section.  In the following example, TLS will be used to
	implement a secure channel.  The first section represents the
	global configuration:
# # See slapd-config(5) for details on configuration options. # This file should NOT be world readable. # dn: cn=config objectClass: olcGlobal cn: config # # # Define global ACLs to disable default read access. # olcArgsFile: /var/run/openldap/slapd.args olcPidFile: /var/run/openldap/slapd.pid olcTLSCertificateFile: /usr/local/etc/openldap/server.crt olcTLSCertificateKeyFile: /usr/local/etc/openldap/private/server.key olcTLSCACertificateFile: /usr/local/etc/openldap/ca.crt #olcTLSCipherSuite: HIGH olcTLSProtocolMin: 3.1 olcTLSVerifyClient: never
The Certificate Authority, server certificate and server
	private key files must be specified here.  It is recommended
	to let the clients choose the security cipher and omit option
	olcTLSCipherSuite (incompatible with TLS
	clients other than openssl).  Option
	olcTLSProtocolMin lets the server require a
	minimum security level: it is recommended.  While
	verification is mandatory for the server, it is not for the
	client: olcTLSVerifyClient: never.
The second section is about the backend modules and can be configured as follows:
# # Load dynamic backend modules: # dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModulepath: /usr/local/libexec/openldap olcModuleload: back_mdb.la #olcModuleload: back_bdb.la #olcModuleload: back_hdb.la #olcModuleload: back_ldap.la #olcModuleload: back_passwd.la #olcModuleload: back_shell.la
The third section is devoted to load the needed
	ldif schemas to be used by the databases:
	they are essential.
dn: cn=schema,cn=config objectClass: olcSchemaConfig cn: schema include: file:///usr/local/etc/openldap/schema/core.ldif include: file:///usr/local/etc/openldap/schema/cosine.ldif include: file:///usr/local/etc/openldap/schema/inetorgperson.ldif include: file:///usr/local/etc/openldap/schema/nis.ldif
Next, the frontend configuration section:
# Frontend settings
#
dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: {-1}frontend
olcAccess: to * by * read
#
# Sample global access control policy:
#	Root DSE: allow anyone to read it
#	Subschema (sub)entry DSE: allow anyone to read it
#	Other DSEs:
#		Allow self write access
#		Allow authenticated users read access
#		Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
#	by self write
#	by users read
#	by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn.  (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
olcPasswordHash: {SSHA}
# {SSHA} is already the default for olcPasswordHashAnother section is devoted to the configuration backend, the only way to later access the OpenLDAP server configuration is as a global super-user.
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: to * by * none
olcRootPW: {SSHA}iae+lrQZILpiUdf16Z9KmDmSwT77Dj4UThe default administrator username is
	cn=config.  Type
	slappasswd in a shell, choose a password
	and use its hash in olcRootPW.  If this
	option is not specified now, before
	slapd.ldif is imported, no one will be
	later able to modify the
	global configuration section.
The last section is about the database backend:
#######################################################################
# LMDB database definitions
#######################################################################
#
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 1073741824
olcSuffix: dc=domain,dc=example
olcRootDN: cn=mdbadmin,dc=domain,dc=example
# Cleartext passwords, especially for the rootdn, should
# be avoided.  See slappasswd(8) and slapd-config(5) for details.
# Use of strong authentication encouraged.
olcRootPW: {SSHA}X2wHvIWDk6G76CQyCMS1vDCvtICWgn0+
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
olcDbDirectory:	/var/db/openldap-data
# Indices to maintain
olcDbIndex: objectClass eqThis database hosts the actual
	  contents of the LDAP
	directory.  Types other than mdb are
	available.  Its super-user, not to be confused with the global
	one, is configured here: a (possibly custom) username in
	olcRootDN and the password hash in
	olcRootPW; slappasswd
	can be used as before.
This repository
	contains four examples of slapd.ldif.  To
	convert an existing slapd.conf into
	slapd.ldif, refer to this
	  page (please note that this may introduce some
	unuseful options).
When the configuration is completed,
	slapd.ldif must be placed in an empty
	directory.  It is recommended to create it as:
#mkdir /usr/local/etc/openldap/slapd.d/
Import the configuration database:
#/usr/local/sbin/slapadd -n0 -F /usr/local/etc/openldap/slapd.d/ -l /usr/local/etc/openldap/slapd.ldif
Start the slapd daemon:
#/usr/local/libexec/slapd -F /usr/local/etc/openldap/slapd.d/
Option -d can be used for debugging,
	as specified in slapd(8).  To verify that the server is
	running and working:
#ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts# extended LDIF # # LDAPv3 # base <> with scope baseObject # filter: (objectclass=*) # requesting: namingContexts # # dn: namingContexts: dc=domain,dc=example # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
The server must still be trusted. If that has never been done before, follow these instructions. Install the OpenSSL package or port:
#pkg install openssl
From the directory where ca.crt is
	stored (in this example,
	/usr/local/etc/openldap), run:
#c_rehash .
Both the CA and the server certificate are now correctly
	recognized in their respective roles.  To verify this, run
	this command from the server.crt
	directory:
#openssl verify -verbose -CApath . server.crt
If slapd was running, restart it.  As
	stated in /usr/local/etc/rc.d/slapd, to
	properly run slapd at boot the
	following lines must be added to
	/etc/rc.conf:
lapd_enable="YES" slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/ ldap://0.0.0.0/"' slapd_sockets="/var/run/openldap/ldapi" slapd_cn_config="YES"
slapd does not provide debugging at
	boot.  Check /var/log/debug.log,
	dmesg -a and
	/var/log/messages for this
	purpose.
The following example adds the group
	team and the user john
	to the domain.example
	LDAP database, which is still empty.
	First, create the file
	domain.ldif:
#cat domain.ldifdn: dc=domain,dc=example objectClass: dcObject objectClass: organization o: domain.example dc: domain dn: ou=groups,dc=domain,dc=example objectClass: top objectClass: organizationalunit ou: groups dn: ou=users,dc=domain,dc=example objectClass: top objectClass: organizationalunit ou: users dn: cn=team,ou=groups,dc=domain,dc=example objectClass: top objectClass: posixGroup cn: team gidNumber: 10001 dn: uid=john,ou=users,dc=domain,dc=example objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount cn: John McUser uid: john uidNumber: 10001 gidNumber: 10001 homeDirectory: /home/john/ loginShell: /usr/bin/bash userPassword: secret
See the OpenLDAP documentation for more details.  Use
	slappasswd to replace the plain text
	password secret with a hash in
	userPassword.  The path specified as
	loginShell must exist in all the systems
	where john is allowed to login.  Finally,
	use the mdb administrator to modify the
	database:
#ldapadd -W -D "cn=mdbadmin,dc=domain,dc=example" -f domain.ldif
Modifications to the global
	  configuration section can only be performed by
	the global super-user.  For example, assume that the option
	olcTLSCipherSuite: HIGH:MEDIUM:SSLv3 was
	initially specified and must now be deleted.  First, create a
	file that contains the following:
#catdn: cn=config changetype: modify delete: olcTLSCipherSuiteglobal_mod
Then, apply the modifications:
#ldapmodify -f global_mod -x -D "cn=config" -W
When asked, provide the password chosen in the
	configuration backend section.  The
	username is not required: here, cn=config
	represents the DN of the database section to be modified.
	Alternatively, use ldapmodify to delete a
	single line of the database, ldapdelete to
	delete a whole entry.
If something goes wrong, or if the global super-user cannot access the configuration backend, it is possible to delete and re-write the whole configuration:
#rm -rf /usr/local/etc/openldap/slapd.d/
slapd.ldif can then be edited and
	imported again.  Please, follow this procedure only when no
	other solution is available.
This is the configuration of the server only. The same machine can also host an LDAP client, with its own separate configuration.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
    documentation may be
    sent to <freebsd-questions@FreeBSD.org>.
    Send questions about this document to <freebsd-doc@FreeBSD.org>.