Wednesday, May 9, 2012

HOWTO : OpenLDAP 2.4 NFSv4 Automount Map Repository on CentOS 6.2

We continue our OpenLDAP 2.4 series with goal number 6.
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
In this document, we will learn how to setup an NFS server along with an NFS client which runs autofs(5) version 5. This daemon will fetch his automount maps from our OpenLDAP 2.4 server. The client will then be configured to mount users home directories from the NFS server. All OpenLDAP users DN will be modified to reflect this change. We will also create a central NFS software repository.

Server NFS Configuration

Install the required packges.

sudo yum -y install nfs-utils nfs4-acl-tools openldap-clients nss-pam-ldapd

Create a directory in which user's homes will reside (/export/home) and the central software repository (/export/install)

sudo mkdir -p /export/home /export/install

Keep in mind that we need to create a home directory for each users. Since our users are stored in OpenLDAP, we must make sure that the NFS server is also an LDAP client. That means editing the LDAP client file.

Then making sure the nslcd(8) is properly configured and starts at boot time.

sudo chkconfig nslcd on

Start the daemon.

sudo /etc/init.d/nslcd start

Edit the name service switch configuration file to enable LDAP lookups.

Test to see if the test user is part of the local /etc/passwd file? It should not be.

grep ^test.user /etc/passwd

Now test to see if we can fetch it's data from the LDAP server?

getent passwd test.user
test.user:x:1101:1101:Test User:/nfs/home/test.user:/bin/bash

getent group*:1101:

sudo getent shadow test.user

As we can see, one must be UID zero if we are to get any shadow data. That is the expected behavior. We can now create a test case. Fortunately, we have our test.user!

sudo mkdir /export/home/test.user
sudo cp /etc/skel/.* /export/home/test.user
sudo chown -R /export/home/test.user

If we don't remember your test.user's password, now is the update it.

ldappasswd -xZWD cn=admin,dc=company,dc=com -S cn=test.user,ou=users,dc=company,dc=com

Configure the /etc/exports file to enable NFS exports.

sudo vi /etc/exports

Configure the NFS daemons.

Enable the NFS daemons.

sudo chkconfig rpcbind on
sudo /etc/init.d/rpcbind start
sudo chkconfig nfs on
sudo /etc/init.d/nfs start
sudo chkconfig nfslock on
sudo /etc/init.d/nfslock start

Check to see if the filesystems are exported?

showmount -e

Export list for
/export/install *
/export/home    *

LDAP Server Configuration

Now that our NFS server is configured, we need to add the automount schema to our LDAP server. The easiest way to get the schema is to install the autofs package.

sudo yum -y install autofs

This package comes with the required schema.

rpm -ql autofs | grep schema

Which means to add the autofs schema, we just need to do the same thing we did with sudo in one of my previous blog post. Start by creating a temporary configuration file. Notice that we need the core.schema in this temporary configuration file. Otherwise we get an error saying : « objectclass: AttributeType not found: "ou" » because the autofs.schema file depends on the "ou" objectClass.

echo "include /etc/openldap/schema/core.schema" > ~/ldap/autofs.conf
rpm -ql autofs | grep -i schema | sed 's/^/include /g' >> ~/ldap/autofs.conf

Next, use slapcat(8C) to generate the new autofs schema in LDIF format.

slapcat -f ~/ldap/autofs.conf -F ~/ldap -n 0

The new LDIF schema file is dumped in ~/ldap/cn\=config/cn\=schema/cn\=\{1\}autofs.ldif. As was the case with the sudo schema, we first need to sanitize this new file before we can add it to our OpenLDAP server. A few quick sed(1) commands should do the trick.

sed -re "/^(structuralObjectClass|entry[C|U]|creat[e|o]|modif[i|y])/d" ~/ldap/cn\=config/cn\=schema/cn\=\{1\}autofs.ldif > ~/ldap/autofs.schema.ldif
sed -i.bak -e "s/{1}autofs/autofs/g" ~/ldap/autofs.schema.ldif
sed -i.bak -e "s/cn=autofs/cn=autofs,cn=schema,cn=config/g" ~/ldap/autofs.schema.ldif

The resulting LDIF file is quite small.

We can now add this to our OpenLDAP server.

sudo ldapmodify -aH ldapi:/// -f ~/ldap/autofs.schema.ldif

If we take a look to our server log file, we will see that our new schema has been included.

slapd[10783]: conn=1067 op=2 ADD dn="cn=autofs,cn=schema,cn=config"

We can double check that of course.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn | grep auto

dn: cn={14}autofs,cn=schema,cn=config

Good! Now let's add the autofs container and some configuration values. Edit yet another LDIF file.

Check to see if our changes are now part of the OpenLDAP server?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b ou=autofs,ou=services,dc=company,dc=com dn

Excellent! We're now ready to configure a client machine.

Client Configuration

Here we assume that the client is already an LDAP client of our OpenLDAP server. If not, then read my previous blog posts on the subject.

As always, make sure the required packages are installed.

sudo yum -y install rpcbind nfs-utils nfs4-acl-tools nss-pam-ldapd openldap-clients autofs

Configure idmapd(8).

Make sure various daemons are started at boot and start them manually. NOTE : I had a problem where idmapd required a complete client AND server reboot for it to work. If it doesn't work for you, try it.

sudo chkconfig rpcbind on
sudo /etc/init.d/rpcbind start
sudo chkconfig nfslock on
sudo /etc/init.d/nfslock start
sudo chkconfig rpcidmapd on
sudo /etc/init.d/rpcidmapd start

Configure the name service switch file so that the automount: keyword uses the ldap directory.

sudo vi /etc/nsswitch.conf

automount: ldap

Configure the automount(8) daemon.

Configure LDAP authentication for the autmount(8) daemon.

Fix permissions on the file. Otherwise we get this error which is pretty clear :)

automount[4570]: parse_ldap_config: lookup(ldap): Configuration file /etc/autofs_ldap_auth.conf exists, but is not usable. Please make sure that it is owned by root, group is root, and the mode is 0600.

Make sure the automount daemon starts when the client machine boots and start the daemon.

sudo chkconfig autofs on
sudo /etc/init.d/autofs start

Check the server and the client log files. If all is good, then test your configuration.

cd /nfs/install
df -h .
Filesystem            Size  Used Avail Use% Mounted on
                      770G   17G  714G   3% /nfs/install

VoilĂ ! Goal number 6 is done!
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
In future blog posts, I will show how to use a Kerberos principal and SASL GSSAPI to authenticate the autofs daemon.

Stay tuned!



  1. When I run autofs only /nfs is being mounted


    Starting automounter version 5.0.6, master map auto.master
    using kernel protocol version 5.02
    lookup_nss_read_master: reading master ldap auto.master
    parse_init: parse(sun): init gathered global options: (null)
    master_do_mount: mounting /nfs
    automount_path_to_fifo: fifo name /var/run/autofs.fifo-nfs
    lookup_nss_read_map: reading map ldap ldap:ou=auto.nfs,ou=autofs,ou=services,dc=ldap,dc=example,dc=net
    parse_init: parse(sun): init gathered global options: rsize=8192,wsize=8192
    mounted indirect on /nfs with timeout 300, freq 75 seconds
    st_ready: st_ready(): state = 0 path /nfs

    I can mount the nfs shares directly but not using autofs

    bottom portion of autofs ldif:

    # Create the auto.nfs map container.
    dn: ou=auto.nfs,ou=autofs,ou=services,dc=ldap,dc=example,dc=net
    ou: auto.nfs
    objectClass: top
    objectClass: automountMap

    # Create the home value for the auto.nfs map.
    dn: cn=home,ou=auto.nfs,ou=autofs,ou=services,dc=ldap,dc=example,dc=net
    objectClass: top
    objectClass: automount
    cn: home

    # Create the install value for the auto.nfs map.
    dn: cn=install,ou=auto.nfs,ou=autofs,ou=services,dc=ldap,dc=example,dc=net
    objectClass: top
    objectClass: automount
    cn: install

  2. hi david, just wanted to find out that if "" is the name of which server, ldap or nfs?


    1. Hello Anonymous,

      The machine called is the NFS server.



  3. Just my take on the /home directories.. I wanted home directories to be auto created, so I did the following:
    NFS Server -
    ll /exports:
    drwxr-xr-x. 4 nfsnobody nfsnobody 4096 May 20 23:46 home
    drwxr-xr-x. 2 nfsnobody nfsnobody 4096 May 20 23:01 install

    Then in the /etc/exports file:

    Now I can create new users and the first time they log in, they get a home directory setup for them.

    That way it avoids the whole creating directories on the NFS server prior to logging into a machine.

    You may have a better way, but hey I wanted to put it out there. :)


    1. Hi Pete,

      Great, thanks for the info. Are you using the PAM module to create the directory?


    2. Hey David,

      Yes I am, it's the default module, so there is no configuration required. Well at least on 6.4.

      Well your guide has been awesome, I have been going through it and setting up a test lab at home and learning all about ldap. Of course putting my own spin on it all once complete I am going to write it up in puppet scripts as an exercise now that should be amusing. :)


    3. Hey Pete,

      I don't know if is the default on all versions of CentOS? But it's clearly a very cool module indeed.

      Thanks for the good words, I'm glad I could help! If you do make those Puppet scripts, then would you be so kind as to let me know? I'll link your blog post here so that others have a chance to benefit from your work on Puppet (which is such a great piece of software :)



  4. Hello David,

    I've just finished this post, and each step is very clear and well understable, Fabulous !!!
    Just one point :
    When I checked my /var/log/slapd.log on final step, client's configuration, and one thing is disturbing me.
    I mean :
    <= bdb_equality_candidates: (ou) not indexed
    conn=1054 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=
    conn=1054 op=3 SRCH base="ou=auto.master,ou=autofs,ou=services,dc=berok,dc=org" scope=2 deref=0 filter="(objectClass=automount)"

    Is it usual ??

    Again thanks for your very well post and maybe your reply...


    1. Hello Fredouille,

      The « bdb_equality_candidates: (ou) not indexed » error simply means that you're missing an equality index (i.e. eq) on the ou object.

      Check this URL for more info on OpenLDAP indexes :

      This error will not prevent your OpenLDAP server from working. But ideally, you want to get rid of the error. The trick is to add an index on the ou object. I believe this index is created when you follow this blog post :

      Search for index and you'll see how to setup a new index.



  5. Hello David,

    OK I understand your answer about missing index on OU object...
    And of course you're right, again, I didn't create any index as I don't have finish all setups (specialy which seems to be very important and error's source)...

    Sorry for my mistake..



  6. Hi David,
    incredible howto, but I stuck in this chapter for a while becouse of "BROWSE_MODE=no". It is worth to say that in this mode mounted directory /nfs appears to be empty but it isn't! We need go directly to exported location using e.g cd /nfs/home to see its content.
    Oh I lost 2 hours becouse of that... ;)


    1. Hello Alan,

      Thank you for the good words, I appreciate them :)

      I'll add your comment to the text so that others won't have to loose their time. Sorry about that!


  7. This comment has been removed by a blog administrator.

  8. Hi David, the article is awesome. Two things to point:

    1. When i run the ldapmodify command, i get this :

    [root@ldapserv ldap]# sudo ldapmodify -aH ldapi:/// -f ~/ldap/autofs.schema.ldif
    SASL/LOGIN authentication started
    Please enter your password:
    ldap_sasl_interactive_bind_s: Invalid credentials (49)
    additional info: SASL(-13): user not found: checkpass failed

    2. ~/ldap/autofs.ldif file does not contain info about the ou=services. I had to modify to get the ou=services in place. is that right?

    1. Hey Ravindra,

      The first error you're hitting appears to be caused by the absence of the root user within your OpenLDAP directory tree. I'm not sure why? Have you followed the blog articles right from the very first or started at this one?

      As for the second error, it may well be an error on my part. But, again, if you've started this blog post from this page and did not follow all the instructions from the very start, then you might have missing pieces. This OpenLDAP blog series is meant to be followed from the start.



    2. Hey David,

      I did follow from beginning except the part on tls.. Trying to review again as to what i have missed .

    3. Hi David,

      I kept fiddling around with the command and following works:
      ldapmodify -xZWD cn=admin... -aH ldapi:/// -f autofs.schema.ldif

    4. Ravindra. I got the additional info: SASL(-13): user not found: checkpass failed a couple times, not for your specific issue, but following along this tutorial.

      What David wrote in the blog to do was:
      sudo ldapmodify -a -H ldapi:/// -f ~/ldap/posixAccount.indexes.ldif
      That returned the error:
      SASL(-13): user not found: checkpass failed
      So I appended the command to
      sudo ldapmodify -a -Y EXTERNAL-H ldapi:/// -f ~/ldap/posixAccount.indexes.ldif
      That seemed to do the trick.

    5. Thanks Anonymous for the help, appreciate it!