OpenLDAP
OpenLDAP Software is an open source implementation of the Lightweight Directory Access Protocol: http://www.openldap.org/
The older slapd.conf file is deprecated, and the newer configuration files under slapd.d should be edited using LDAP utilities rather than manually: http://www.openldap.org/doc/admin/slapdconf2.html
Configuration
Dump all configuration:
$ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"
Configuration is modified by creating an LDAP Data Interchange Format (LDIF) file with the desired changes and running:
$ ldapmodify -Y EXTERNAL -H ldapi:/// -f ${file}.ldif
In recent versions, the main configuration is contained in LDIF files under some directory such as /etc/openldap/slapd.d/cn=config; however, these files should not be edited directly. Instead, create an LDIF file with the changes and run ldapmodify.
For example, in a simple configuration, it is common to change
olcSuffix, olcRootDN, olcRootPW, and olcAccess. Create an
update_configuration.ldif file, replace dc=example,dc=com with your
domain, and run slappasswd
to generate the input for
olcRootPW:
dn: olcDatabase={0}config,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}ugwz71gwNPJuw5bQzyqIMATp8wOPu7Io
-
dn: olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=com
-
replace: olcRootDN
olcRootDN: cn=Manager,dc=example,dc=com
-
replace: olcRootPW
olcRootPW: {SSHA}ugwz71gwNPJuw5bQzyqIMATp8wOPu7Io
-
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by
dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
read by dn.base="cn=Manager,dc=example,dc=com" read by * none
-
Input this file to ldapmodify:
$ ldapmodify -Y EXTERNAL -H ldapi:/// -f update_configuration.ldif
LDAP Data Interchange Format (LDIF)
LDIF is specified through RFC 2849: https://tools.ietf.org/html/rfc2849
The general form is:
# Comment
key: value
continuation
- A continuation occurs when a line starts with one space. That one space is removed and the rest is concatenated to the previous line. Therefore, it's almost always necessary to use two spaces so that there is a space between the concatentation.
- If a key is followed by two colons, the value is Base-64 encoded.
- When using
ldapmodify
, operations are separated by a line with a dash in it, followed by a blank line. This does not apply toldapadd
.
ldapadd
Instead of creating an LDIF file beforehand, you may omit
-f
, enter the LDIF in the standard input and then type
Ctrl+D. For example:
$ ldapadd -D cn=Manager,dc=example,dc=com -w password
dn: ...
Ctrl+D
Example: Create Organization
Here is an example create_organization.ldif with a single user:
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example
dn: ou=Users,dc=example,dc=com
objectClass: organizationalUnit
ou: Users
dn: cn=User1,ou=Users,dc=example,dc=com
cn: User1 LastName
sn: LastName
objectClass: inetOrgPerson
userPassword: password
uid: 1
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=Group1,ou=Users,dc=example,dc=com
cn: Group1
objectClass: groupOfNames
member: cn=User1,ou=Users,dc=example,dc=com
Then add all of the items with:
$ ldapadd -f create_organization.ldif -D cn=Manager,dc=example,dc=com -W
Example: Add User
$ ldapadd -D cn=Manager,dc=example,dc=com -w password
dn: cn=Admin,ou=Users,dc=example,dc=com
cn: Admin
sn: Admin
objectClass: inetOrgPerson
userPassword: {SSHA}baYn/l/wd41jpw5k0GvSPn99DboceyQZ
uid: 2
^D
ldapsearch
Example output:
$ ldapsearch -LLL -x -b 'dc=example,dc=com' '(objectclass=*)'
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example
dn: ou=Users,dc=example,dc=com
objectClass: organizationalUnit
ou: Users
dn: cn=User1,ou=Users,dc=example,dc=com
cn: User1 LastName
cn: User1
sn: LastName
objectClass: inetOrgPerson
userPassword:: cGFzc3dvcmQ=
uid: 1
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=Group1,ou=Users,dc=example,dc=com
cn: Group1
objectClass: groupOfNames
member: cn=User1,ou=Users,dc=example,dc=com
Example: Find Users by Attribute
$ ldapsearch -LLL -x -b 'dc=example,dc=com' '(&(sn=LastName)(objectclass=inetOrgPerson))'
dn: cn=User1,ou=Users,dc=example,dc=com
cn: User1 LastName
cn: User1
sn: LastName
objectClass: inetOrgPerson
uid: 1
userPassword:: e1NTSEF9M0FjcXdzMFVPRmlSQ1Z2cGZaR3JQUWczNXRsejhOMng=
Example: Find Groups that Contain a User
$ ldapsearch -LLL -x -b "dc=example,dc=com" -D cn=Manager,dc=example,dc=com -w password "(&(objectclass=groupOfNames)(member=cn=User1,ou=Users,dc=example,dc=com))"
dn: cn=Group1,ou=Users,dc=example,dc=com
cn: Group1
objectClass: groupOfNames
member: cn=User1,ou=Users,dc=example,dc=com
ldapmodify
Instead of creating an LDIF file beforehand, you may omit
-f
, enter the LDIF in the standard input and then type
Ctrl+D. For example:
$ ldapmodify -D cn=Manager,dc=example,dc=com -w password
dn: ...
changetype: ...
Ctrl+D
Example: Modify User Password
$ ldapmodify -D cn=Manager,dc=example,dc=com -w password
dn: cn=User1,ou=Users,dc=example,dc=com
changetype: modify
replace: userPassword
userPassword: {SSHA}3Acqws0UOFiRCVvpfZGrPQg35tlz8N2x
^D
Example: Add Member to Existing Group
$ ldapmodify -D cn=Manager,dc=example,dc=com -w password
dn: cn=Group1,ou=Users,dc=example,dc=com
changetype: modify
add: member
member: cn=Admin,ou=Users,dc=example,dc=com
^D
ldapwhoami
Use ldapwhoami
to test user credentials.
Example success:
$ ldapwhoami -vvv -D "cn=User1,ou=Users,dc=example,dc=com" -x -w password
ldap_initialize( <DEFAULT> )
dn:cn=User1,ou=Users,dc=example,dc=com
Result: Success (0)
Example failure:
$ ldapwhoami -vvv -D "cn=User1,ou=Users,dc=example,dc=com" -x -w test
ldap_initialize( <DEFAULT> )
ldap_bind: Invalid credentials (49)
Monitoring
OpenLDAP monitoring: https://www.openldap.org/doc/admin24/monitoringslapd.html
Examples:
Print all statistics:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Monitor' -s sub '(objectClass=*)' '*' '+' 2>/dev/null
Number of active connections:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Current,cn=Connections,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorCounter:
monitorCounter: 1
Number of available connections:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Total,cn=Connections,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorCounter:
monitorCounter: 1057
Maximum configured threads:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Max,cn=Threads,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitoredInfo:
monitoredInfo: 16
Active threads:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Active,cn=Threads,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitoredInfo:
monitoredInfo: 1
Bytes used:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Bytes,cn=Statistics,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorCounter:
monitorCounter: 23738
Number of entries:
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Entries,cn=Statistics,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorCounter:
monitorCounter: 225
Total number of operations (note that this query itself adds to the operation count):
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Operations,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorOp
monitorOpInitiated: 215
monitorOpCompleted: 214
Total number of searches (note that this query itself adds to the search count):
# ldapsearch -LLL -H ldapi:// -Y EXTERNAL -b 'cn=Search,cn=Operations,cn=Monitor' -s base '(objectClass=*)' '*' '+' 2>/dev/null | grep monitorOp.*:
monitorOpInitiated: 71
monitorOpCompleted: 70