OpenLDAP (Lightweight Directory Access Protocol) Notes

The main site is OpenLDAP.org, where on 8-8-2006, I downloaded version 2.3.25 and installed on linux2.

Turns out that I should have just installed the openldap-servers and krb5-server packages (under Servers->Network Servers in the system-cdinstall-helper program) from the RHEL AS v4 disc 4 of 4. The rest of what I need (openldap, nss_ldap, openldap-clients, cyrus-sasl) are already installed.

LDAP stands for Lightweight Directory Access Protocol and is described in RFC 2251 and RFC 3377
Its dn's (Distinguished Names) are described in RFC 2253.
The documentation is here, for example, the OpenLDAP Software 2.3 Administrator's Guide.
The Wikipedia article is pretty informative.


There are different LDAP implementations going by different names,


Some common terms,


OpenLDAP

On linux2's RHEL AS v4 install, all the OpenLDAP packages are installed,
  • openldap
  • openldap-clients
  • openldap-servers
  • openldap-devel
  • nss_ldap
  • perl-LDAP
  • python-ldap
  • php-ldap
I had the following in /usr/bin
  • ldapadd
  • ldapcompare
  • ldapdelete
  • ldapmodify
  • ldapmodrdn
  • ldappasswd
  • ldapsearch
  • ldapwhoami
Also, there are these slapd database utilities in /usr/sbin,
  • slapadd
  • slapcat
  • slapindex
  • slapacl
  • slapauth
  • slapdn
  • slappasswd
  • slaptest

Finding the LDAP server can utilize SRV (Service) DNS RR (Resource Records) entries. For example,
    _ldap._tcp.jasperfamily.org IN SRV 0 0 398 ldap.jasperfamily.org.
(not that I have this in my DNS - ZoneEdit doesn't provide for SRV records. FreeDNS.afraid.org does, but it doesn't allow wildcarding, which I use.)
The underscores are a part of the RFC 2782 that describes SRV RR DNS records.

Besides LDAP, other SRV records are SIP (remember the 8x8 VOIP interview?), FTP, HTTP, HTTPS, etc.


I changed/added the following 3 lines in /etc/openldap/slapd.conf, to use jasperfamily.org and a password of "secret" when I do ldapadd commands for example.

I later used slappasswd to generate an encrypted password and went back and changed this /etc/openldap/slapd.conf file instead of having this in the clear, but I still used secret for the password. ;-)

Note that there are two ldap.conf files, /etc/ldap.conf that was provided by the nss_ldap package, and /etc/openldap/ldap.conf provided by the openldap package. I'm not sure why there's two. The /etc/ldap.conf file says This is the configuration file for the LDAP nameservice switch library and the LDAP PAM module. Also, the /etc/ldap.conf file is bigger.

I changed the following 2 lines in both ldap.conf files,

To start the slapd daemon now and after future reboots,

    service ldap start
    chkconfig ldap on      (Creates /etc/rc.d/rc*.d/*ldap links)

Following the example in the OpenLDAP Quick-Start Guide, I created this example.ldif file,
dn: dc=jasperfamily,dc=org
objectclass: dcObject
objectclass: organization
o: Jasper Family
dc: jasperfamily

dn: cn=Manager,dc=jasperfamily,dc=org
objectclass: organizationalRole
cn: Manager
and ran
      ldapadd -v -x -D "cn=Manager,dc=jasperfamily,dc=org" -W -f example.ldif
(using my secret password) which added those two entries in my LDAP database, which by way, is at /var/lib/ldap.

A

      ldapsearch -h ldap -x -b 'dc=jasperfamily,dc=org' '(objectclass=*)'
command now returns
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# jasperfamily.org
dn: dc=jasperfamily,dc=org
objectClass: dcObject
objectClass: organization
o: Jasper Family
dc: jasperfamily

# Manager, jasperfamily.org
dn: cn=Manager,dc=jasperfamily,dc=org
objectClass: organizationalRole
cn: Manager

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

LDAP Authentication Methods

LDAP has two basic authentication methods. The discussion says "It will be assumed that you have Kerberos V deployed, you are familiar with the operation of the system, and that your users are trained in its use. This section also assumes you have familiarized yourself with the use of the GSSAPI mechanism by reading Configuring GSSAPI and Cyrus SASL (provided with Cyrus SASL in the doc/gssapi file) and successfully experimented with the Cyrus provided sample_server and sample_client applications. General information about Kerberos is available at http://web.mit.edu/kerberos/www so it's time to learn about Kerberos.

Kerberos

See How to Kerberize your Site. Specifically, see "Configuring the Kerberos kdc".

  1. Edit /etc/krb5.conf changing the default_realm to JASPERFAMILY.ORG (the convention is to make your realm the same as your domain except to use all capital letters to differientiate the two) in 7 places, extending ticket lifetimes from 10 hours to 30 days, and noting the kdc profile is at/var/kerberos/krb5kdc/kdc.conf.
  2. vi /var/kerberos/krb5kdc/kdc.conf file, changing the domain.
  3. Create the Kerberos database. Note that my "root kerberos installation" is /usr/kerberos instead of /krb5.
       /usr/kerberos/sbin/kdb5_util create -r JASPERFAMILY.ORG -s
       Loading random data
       Initializing database '/var/kerberos/krb5kdc/principal' for realm 'JASPERFAMILY.ORG',
       master key name 'K/M@JASPERFAMILY.ORG'
       You will be prompted for the database Master Password.
       It is important that you NOT FORGET this password.
       Enter KDC database master key:                    (I entered r-3)
       Re-enter KDC database master key to verify:
    
    This created 5 files in /var/kerberos/krb5kdc, and had a couple of minor complaints in the /var/log/kadmind.log file, "... No dictionary file specified, continuing without one."
  4. Change the /var/kerberos/krb5kdc/kadm5.acl file to
         */admin@JASPERFAMILY.ORG *
  5. Add an administrator account to the Kerberos database,
       kadmin.local
       Authenticating as principal root/admin@JASPERFAMILY.ORG with password.
       kadmin.local: addprinc admin/admin@JASPERFAMILY.ORG
       WARNING: no policy specified for admin/admin@JASPERFAMILY.ORG; defaulting to no policy
       Enter password for principal "admin/admin@JASPERFAMILY.ORG": global
       Re-enter password for principal "admin/admin@JASPERFAMILY.ORG":
       Principal "admin/admin@JASPERFAMILY.ORG" created.
       kadmin.local: quit
    
  6. Start the kerberos daemons now and at the next system boot,
       service krb5kdc start
       service kadmin start               (not kadmind as service --status-all shows)
       chkconfig --level 2345 krb5kdc on  (Creates /etc/rc.d/rc*.d/*krb5kdc links)
       chkconfig --level 2345 kadmin on   (Creates /etc/rc.d/rc*.d/*kadmin links)
    
    Starting kadmin for the first time will write a kadm5.keytab file in the /var/kerberos/krb5/kdc directory.

    krb5kdc listens on UDP ports 88 (kerberos) & 750 (kerberos-iv), and
    kadmind listens on UDP port 464 (kpasswd) & TCP 749 (kerberos-adm),
    so I had to authorize these ports in the

       system-config-securitylevel
    
    tool to tweak the SELinux firewall, allowing "88:udp, 464:udp, 749:tcp, 389:tcp" in the "Other ports:" field. Port 389 is the ldap port and is what slapd listens to.
  7. To add a user's principal to the kerberos database,
       kadmin -p admin/admin
       Authenticating as principal admin/admin with password.
       Password for admin/admin@JASPERFAMILY.ORG: global
    
       kadmin: addprinc root/admin
       WARNING: no policy specified for root/admin@JASPERFAMILY.ORG; defaulting to no policy
       Enter password for principal "root/admin@JASPERFAMILY.ORG": global
       Re-enter password for principal "root/admin@JASPERFAMILY.ORG":
       Principal "root/admin@JASPERFAMILY.ORG" created.
    
       kadmin: addprinc rick
       WARNING: no policy specified for rick@JASPERFAMILY.ORG; defaulting to no policy
       Enter password for principal "rick@JASPERFAMILY.ORG": r-3
       Re-enter password for principal "rick@JASPERFAMILY.ORG":
       Principal "rick@JASPERFAMILY.ORG" created.
       kadmin.loocal: quit
    
  8. On client machines, the kerberos client binaries are already there, so all one has to do is modify /etc/krb5.conf, changing all instances of EXAMPLE.COM or example.com to JASPERFAMILY.ORG or jasperfamily.org, and viola! The kinit command works.
  9. To get kerberos login authentication to work,
       system-config-authentication
    
    go to the "Authentication" tab, and click on the "Enable Kerberos Support" button. This changes the following 2 files,

Cyrus SASL

Ok, Kerberos is installed and running ok, but the OpenLDAP Software 2.3 Administrator's Guide next talks about Cyrus SASL. What the heck is that?

According to this LDAPv3 How To, Cyrus SASL This is the layer between OpenLDAP and Kerberos. It gives you a secure way of AUTHENTICATING access to the LDAP server.

The best description of SASL though, was what I found in SASL Programmer's Guide. Basically, SASL is a way for an application writer (say FTP or mail client or LDAP) to authenticate without getting bogged down in the details of Kerberos IV versus Kerberos V, or CRAM MD5. All the application writer need do to work with these and any future authentication scheme that might get developed, is to code to the SASL spec. Ths SASL libraries will take care of the authentication details.

I've already installed the cyrus-sasl packages and have various sasl commands in /usr/bin and /usr/sbin.


Back to OpenLDAP

I found Redhat-specific directions on this web page, so that's what I'm going to follow.

There's a set of LDAP Migration Tools in the /usr/share/openldap/migration directory provided by the openldap-servers package. I used migrate_base to generate a base.ldif file that will populate my LDAP directory with a standard structure.

   /usr/share/openldap/migration/migrate_base > base.ldif
In it was typical LDIF stanzas for jasperfamily.org and 12 second-level dn's.
  • Aliases
  • Group
  • Hosts
  • Mounts
  • Netgroup
  • Networks
  • nisMapName=netgroup.byhost
  • nisMapName=netgroup.byuser
  • People
  • Protocols
  • Rpc
  • Services

To put them into my LDAP directory,

   ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f base.ldif
Uh, oh. A problem. After a reboot, my LDAP/slapd daemon won't run. The lines in /var/log/messages say
   Sep 12 10:50:14 linux2 slapd[3983]: sql_select option missing
   Sep 12 10:50:14 linux2 slapd[3983]: auxpropfunc error no mechanism available
   Sep 12 10:50:17 linux2 slapd[3988]: sql_select option missing
   Sep 12 10:50:17 linux2 slapd[3988]: auxpropfunc error no mechanism available
A check on the forums suggest
   cd /etc/openldap
   chmod ldap:ldap ldap.conf slapd.conf
but that didn't fix anything.

Somebody suggested starting slapd in debug mode with "slapd -d -1". This created 300 lines of stuff, apparently this is the problem.

   slapd startup: initiated.
   bdb_db_open: dc=jasperfamily,dc=org
   bdb_db_open: dbenv_open(/var/lib/ldap)
   bdb(dc=jasperfamily,dc=org): Program version 4.2 doesn't match environment version
   bdb_db_open: dbenv_open failed: Invalid argument (22)
   backend_startup: bi_db_open(0) failed! (22)
   slapd shutdown: initiated
The system DID die overnight and there are cases where the Berkely database (bdb) doesn't recover from crashes with these messages. Forums suggest
   db_stat -e
but I can't figure out the full syntax. Another suggestion was to run
   cd /var/lib/ldap
   db_recover -v
which appears to have done something. Hey! Now slapd runs ok. Whew!

And now my ldapadd command runs ok except for the below expected error (dc=jasperfamily,dc=org already existed), which is why I specified the -c option (keep going even if there's an error).

   ldapadd -c -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f base.ldif
   Enter LDAP Password:
   ldap_add: Already exists (68)
   adding new entry "dc=jasperfamily,dc=org"
   adding new entry "ou=Hosts,dc=jasperfamily,dc=org"
   adding new entry "ou=Rpc,dc=jasperfamily,dc=org"
   adding new entry "ou=Services,dc=jasperfamily,dc=org"
   adding new entry "nisMapName=netgroup.byuser,dc=jasperfamily,dc=org"
   adding new entry "ou=Mounts,dc=jasperfamily,dc=org"
   adding new entry "ou=Networks,dc=jasperfamily,dc=org"
   adding new entry "ou=People,dc=jasperfamily,dc=org"
   adding new entry "ou=Group,dc=jasperfamily,dc=org"
   adding new entry "ou=Netgroup,dc=jasperfamily,dc=org"
   adding new entry "ou=Protocols,dc=jasperfamily,dc=org"
   adding new entry "ou=Aliases,dc=jasperfamily,dc=org"
   adding new entry "nisMapName=netgroup.byhost,dc=jasperfamily,dc=org"

To add my rick (501:501) userid, create the following rick.ldif file,

  dn: uid=rick,ou=People,dc=jasperfamily,dc=org
  cn: Rick Jasper
  sn: Jasper
  objectClass: top
  objectClass: person
  objectClass: posixAccount
  objectClass: shadowAccount
  uid: rick
  uidNumber: 501
  gidNumber: 501
  loginShell: /bin/bash
  homeDirectory: /home/rick
and add it with
   ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f rick.ldif
   Enter LDAP Password:
   adding new entry "uid=rick,ou=People,dc=jasperfamily,dc=org"
You can display this with
   ldapsearch -x 'cn=Rick Jasper'

LDAP on Client Machines

To configure LDAP on the client machines, as root,
  1. system-config-authentication
  2. On the "User Information" tab, click on "Enable LDAP Support"
  3. Click "Configure LDAP..."
  4. Change "LDAP Search Base DN" to "dc=jasperfamily,dc=org"
  5. and "LDAP Server" to ldap
(Remember that I had already configured Kerberos Authentication")

This is almost perfect. I can login as rick, but I get this error message when I do,

   id: cannot find name for group ID 501
There are hints that perhaps the group line in /etc/nsswitch.conf isn't right, but it's set to group: files ldap which seems right.

I'm guessing it's because I left out a gid: rick line in my rick.ldif file. There's a uid: line. So, to delete my rick entry and readd,

   ldapdelete -x -w secret -D "cn=Manager,dc=jasperfamily,dc=org"
       "uid=rick,ou=People,dc=jasperfamily,dc=org"
   ldapadd -a -W -x -D "cn=Manager,dc=jasperfamily,dc=org" -f rick.ldif
Nope, that wasn't it. Revert. Checking Google again ...

How 'bout adding a 501 Group? Here's a group501.ldif file,

   dn: gidNumber=501,ou=Group,dc=jasperfamily,dc=org
   cn: rick
   gidNumber: 501
   objectClass: top
   objectClass: posixGroup
and a
   ldapadd -a -w secret -x -D "cn=Manager,dc=jasperfamily,dc=org" -f group501.ldif
   adding new entry "gidNumber=501,ou=Group,dc=jasperfamily,dc=org"
gets it so I can login and my group DOES show up just fine. Bingo!

There's a problem on the client reboot though. See this Redhat bug for a solution, which is to vi /etc/ldap.conf and

On the LDAP server (linux2), you may want it to also look at the LDAP database when resolving userids and groups. Add "ldap" to these 3 lines in the /etc/nsswitch.conf file,

   passwd:	files ldap
   shadow:	files ldap
   groups:	files ldap

So to recap, to add a user, say adam/502, create an adam.ldif file like so (the blank line is required),

   dn: uid=adam,ou=People,dc=jasperfamily,dc=org
   cn: Adam Jasper
   sn: Jasper
   objectClass: top
   objectClass: person
   objectClass: posixAccount
   objectClass: shadowAccount
   uid: adam
   uidNumber: 502
   gidNumber: 502
   loginShell: /bin/bash
   homeDirectory: /home/adam

   dn: gidNumber=502,ou=Group,dc=jasperfamily,dc=org
   cn: adam
   gidNumber: 502
   objectClass: top
   objectClass: posixGroup
and add it to the LDAP database like so,
   ldapadd -a -w secret -x -D "cn=Manager,dc=jasperfamily,dc=org" -f adam.ldif

You'll have to create the home directories on each system (or share them somehow) by hand. A quick and dirty way to create it is

   adduser adam -u 502
   userdel adam

Finally, you'll need to add this new userid to the Kerberos database.

   kadmin -p admin/admin
   Authenticating as principal admin/admin with password.
   Password for admin/admin@JASPERFAMILY.ORG: global
   kadmin: addprinc adam
   WARNING: no policy specified for rick@JASPERFAMILY.ORG; defaulting to no policy
   Enter password for principal "rick@JASPERFAMILY.ORG": adampw
   Re-enter password for principal "rick@JASPERFAMILY.ORG": adampw
   Principal "rick@JASPERFAMILY.ORG" created.
   kadmin.loocal: quit

Grennan's LDAP How To page also mentions using migrate_password.pl & migrate_group.pl to populate existing userid information into your LDAP database.

He also likes this LDAP Browser/Editor. I didn't check it out.


This page was last updated on Tuesday, 07-Nov-2006 15:15:22 Pacific Standard Time