LDAP
— print (last updated: Aug 12, 2009) print

Select font size:
Personalize this online document by providing values relevant to you.
  1. Replace the generic LOGIN by the actual login:
       
  2. Replace the generic MACHINE name by its actual name:
       
LDAP stands for Lightweight Directory Access Protocol. It is a protocol for accessing directory services on the network. The term directory services can translate into virtually any information services such as telephone directory, account information, address book data used by mail clients, etc. This scheme is found virtually everywhere these days for network-based information services and validation (e.g., at WCU itself). A good discussion can be found in the wikipedia:
http://en.wikipedia.org/wiki/LDAP
In this document we are interested in it for maintaining Linux User accounts which can be used for network validation. We use an LDAP version called OpenLDAP, an open-source version of LDAP.

Initial LDAP server setup

Install the basic needs with this line:
$ sudo apt-get install slapd ldap-utils
slapd package configuration:
Administrator password:  password-for-LOGIN-on-MACHINE
Confirmation:
So far, I have never seen the need for this password when using LDAP. Configure slapd further:
$ sudo dpkg-reconfigure slapd
do this:
• No (default) - meaning don't omit configuration, i.e., configure it
• DNS domain: MACHINE
• Organization name: cs.wcupa.edu (default)
• backend database: HDB (default)
• Do you want the database to be removed ...? No (default)
• Move old database: Yes (default)
• Administrator password: admin
• Allow LDAPv2? No (default)
This last configuration step can be re-run to change things, but your LDAP database will be destroyed! Having admin's password be admin saves you remembering another password, and is OK for the demonstration purposes of this document, but I recommend enabling the UFW firewall. See the Virtualization with KVM document.

Files

The relevant files for LDAP client/server configuration are primarily these:
/etc/default/slapd
/etc/ldap/
      ldap.conf       client information for ldap-utils
      sasl2/
      schema/         class definitions for LDAP
      slapd.d/        contains "config" information
/etc/ldap.conf        client connection to an LDAP server
/var/lib/ldap         database files
The configuration presented by this Ubuntu version breaks from previous OpenLDAP versions by having the configuration information in LDAP format per se, much like MySQL, in which the configuration information is in a MySQL database.

Other versions (like in the most recent Fedora systems) still rely upon the key file:
/etc/ldap/slapd.conf
The directory which slapd.conf reside can be named differently, but the file name is consistently slapd.conf. Ubuntu's version replaces this single file by the files and directories in
/etc/ldap/slap.d/
This directory is accessible only by root and the contents look very strange at first glance. I am still struggling to come to terms with just how to work with this system.

ldap-utils clients

The client-side commands in the ldap-utils package offer a way to configure LDAP itself and create our database structure. Get a listing of these commands by:
$ ldap[TAB][TAB]
We need to edit the file /etc/ldap/ldap.conf which these command rely upon in order to simplify the usage. Edit this file and look for
#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
Underneath these, add the line, save changes and exit.
BASE    dc=MACHINE
Then run the command:
$ ldapsearch -x
The fact that you get the following records means that it's working.
# MACHINE
dn: dc=MACHINE
objectClass: top
objectClass: dcObject
objectClass: organization
o: cs.wcupa.edu
dc: MACHINE

# admin, MACHINE
dn: cn=admin,dc=MACHINE
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
The output is in the common LDIF (LDAP Data Interchange Format) notation. Some terminology:
dn:  distinguished name, a unique identifier for the record
dc:  domain component
cn:  common name, often a simple way to refer to the record
o:   organization
The objectClass designator signifies that LDAP is an object-oriented system whereby records belong to classes which specify elements (required, optional, etc) belonging to the record. The classes are described in so-called schema files held in /etc/ldap/schema. The multiple occurrences of objectClass suggests that LDAP is using multiple inheritance.

The domain components (dc entries) are suggestive of a DNS domain, which is often the case. LDAP would map the DNS entry MACHINE.cs.wcupa.edu into its own form as:
dc=MACHINE,dc=cs,dc=wcupa,dc=edu
In a real-world situation, this would be preferable to simply "dc=MACHINE" but LDAP doesn't require any relationship between the its names and DNS names, so you can make it what you like.

Create Basic Entities

We want to create entries for user logins and groups. For this we create two entities People and Group, respectively, called organizational units in LDAP terminology. The choice of names, People and Group, are somewhat arbitrary, but they are the defaults assumed by the LDAP client configuration files.

We will employ a home-grown script to create our LDAP entities. Create a dedicated directory for you LDAP files:
$ mkdir ~/ldap
$ cd ~/ldap
In this directory, create the file ldif-add and make it executable:
#!/bin/bash
# ldif-add

domain="dc=MACHINE"
adminDN="cn=admin,$domain"

[ $# -ne 1 ] && { echo $(basename $0) LDIF-FILE; exit 1; }

ldapadd -xW -D $adminDN -f "$1"
Then create these this LDIF file describing the two entities:
PeopleGroup.ldif:
dn: ou=People,dc=MACHINE
objectClass: organizationalUnit
objectClass: top
ou: People

dn: ou=Group,dc=MACHINE
objectClass: organizationalUnit
objectClass: top
ou: Group
Add these entities to the database by doing
$ ldif-add PeopleGroup.ldif
Enter LDAP Password: admin
adding new entry "ou=People,dc=MACHINE"
adding new entry "ou=Group,dc=MACHINE"
Verify the additions by running the command:
$ ldapsearch -x

LDAP client setup

Having a server is only useful if there is a client as well. It's useful to see your machine acting as an LDAP client of itself. We need these packages:
$ sudo apt-get install libnss-ldap
A configurator runs to configure the package ldap-auth-config. Here are the steps:
LDAP server:                           ldapi:///var/run/slapd/ldapi
Distinguished name base:               dc=MACHINE
LDAP version:                          3    (default)
Make local root Database admin:        No   (not the default)
Does the LDAP database require login?  No 
LDAP account for root:                 cn=admin,dc=MACHINE
LDAP root account password:            admin
The "ldapi:///var/run/slapd/ldapi" means to use the file ldapi referred to here as a UNIX file socket. Alternatively we could use the network socket
ldap://127.0.0.1
but file sockets are more efficient. The file which has been configured is /etc/ldap.conf, which you should go through and double-check for these uncommented settings:
base dc=MACHINE
uri ldapi:///var/run/slapd/ldapi
ldap_version 3
pam_password md5
The one change I would suggest making is to comment out the last of these:
#pam_password md5
and then searching for and uncommenting this line:
pam_password exop
Certain aspects of the documentation indicates that the ldapi URL should be this bewildering form:
ldapi://%2fvar%2frun%2fslapd%2fldapi
Actually "%2f" is the URL encoding of "/". Using "/" doesn't affect what we do in this document, but it may be necessary for certain LDAP queries (I don't know).

If you need to change your LDAP client configuration, Ubuntu suggests doing this:
$ sudo dpkg-reconfigure ldap-auth-config
Next, create the setup that allows system clients to authenticate against LDAP:
$ sudo auth-client-config -t nss -p lac_ldap
$ sudo pam-auth-update
The last command asks you to indicate which configurations to use. All three should be checked by default. Just tab to OK, and Enter. The affected files in total are these:
  1. /etc/ldap.conf
  2. /etc/nsswitch.conf     cat this file and observe the changes:
    # pre_auth-client-config # passwd:         compat
    passwd: files ldap
    # pre_auth-client-config # group:          compat
    group: files ldap
    # pre_auth-client-config # shadow:         compat
    shadow: files ldap
    
  3. These PAM files affect all system authentication features.
    /etc/pam.d/common-account
    /etc/pam.d/common-auth
    /etc/pam.d/common-password
    /etc/pam.d/common-session
    
We need to make one editing change to
/etc/pam.d/common-password
Look for the line:
password    [success=1 ...]    pam_ldap.so use_authtok try_first_pass
Remove the "use_authtok" from the line, getting
password    [success=1 ...]    pam_ldap.so try_first_pass
To pick up the low-level changes, it's easiest to reboot your computer.

Create a User

We want to populate our LDAP database with users and groups. This will involve creating and setting yet another password. The Php tool, phpLDAPadmin, is useful. Install it:
$ sudo apt-get install phpldapadmin
After installation, you need to double-check the configuration settings. Edit the file /etc/phpldapadmin/config.php and look for these key lines:
$ldapservers->SetValue($i,'server','host','ldapi:///var/run/slapd/ldapi');
$ldapservers->SetValue($i,'server','base',array('dc=kirk'));
$ldapservers->SetValue($i,'login','dn','cn=admin,dc=kirk');
$queries[$q]['base'] = 'dc=kirk';
Again, it may be important for some later functionality that the ldapi URL be this:
ldapi://%2fvar%2frun%2fslapd%2fldapi
Then open the phpLDAPadmin URL:
http://localhost/phpldapadmin
Click Login on the left side and then, on the right side,
Login DN:  cn=admin,dc=MACHINE
Passord:   admin
Open up the dc=MACHINE entry on the left side to reveal the three entries.

The LDAP user info

I cannot seem to achieve the creation of an new user and group directly in phpLDAPadmin, so we'll use an LDIF file to specify the information and modify it in phpLDAPadmin. Create this file:
entries.ldif:
dn: uid=aperson,ou=People,dc=MACHINE
uid: aperson
cn: A. Person
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:
shadowLastChange: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1234
gidNumber: 1234
homeDirectory: /home/aperson
gecos: A. Person

dn: cn=aperson,ou=Group,dc=MACHINE
objectClass: posixGroup
objectClass: top
cn: aperson
userPassword: {crypt}x
gidNumber: 1234
Like we did above, add using the ldif-add script by:
$ ldif-add entries.ldif
adding new entry "uid=aperson,ou=People,dc=MACHINE"
adding new entry "cn=aperson,ou=Group,dc=MACHINE"
Go back to phpLDAPadmin and click the refresh button on the left to reveal the entries added to Group and People. We want to set a password for the aperson login.
  1. Expand People, select uid=aperson.
  2. Scroll down to the shadowLastChange field. Click the calendar icon on the right. Click Today in the calendar.
  3. Scroll to the bottom to the userPassword field. Enter some password into the field. This should not be your password for LOGIN-on-MACHINE.
  4. Select md5crypt from the drop-down on the right.
  5. Click Save Changes.
  6. Confirm the changes.
  7. Make sure that the shadowLastChange and userPassword settings both "took."
We want to verify that this authentication works, so do this:
$ ldapsearch -xW -D "uid=aperson,ou=People,dc=MACHINE"
Enter LDAP Password: password-for-aperson
You should see a "representation" of the userPassword field. Compare this to
$ ldapsearch -x
in which userPassword is hidden. The former search method accesses by self, whereas the latter search method uses anonymous access. Rightly so, anonymous access does not reveal the encrypted password. The other important non-anonymous access is by admin:
$ ldapsearch -xW -D "cn=admin,dc=MACHINE"

Verify system integrity of new user

First verify that the computer system authentication "sees" everything by looking for the aperson entry in each of these:
$ getent passwd
$ getent group
$ sudo getent shadow
As a first "login" test, you should be able to use SASL to authenticate, because it defaults to the PAM mechanism:
$ testsaslauthd -u aperson -p password-for-aperson
Thus, you can use such an LDAP account as a shell-less account for Apache ModAuthSASL authentication, although you should probably change the loginShell value in the aperson entry to be /bin/false.

Add the home directory

If you decide to make aperson a valid shell user, you simply need to give him/her a home directory on your system. Do so by hand as follows:
$ sudo cp -r /etc/skel /home/aperson
$ sudo chown -R aperson:aperson /home/aperson
Then, you should be able to log in to aperson from the shell through the su command:
$ su - aperson
Password: password-for-aperson
aperson@MACHINE $
To fully convince yourself, log out of GNOME and log back in as aperson.

Open issues

One issue that I have not solved yet is getting the password change command, passwd, to work in this circumstance.

The other important issue I'm grappling with is how to configure LDAP. What knowledge I have comes from Chapter 6 in the Ubuntu Server Guide. For example, this command can be used to reveal the important database access features of current configuration:
$ ldapsearch -xLLL -b cn=config -D cn=admin,cn=config -W olcDatabase={1}hdb
Enter LDAP Password: admin
The admin DN can be used to reset the configuration, but the exact details are not yet within my grasp.


© Robert M. Kline