Single-Sign-On on Linux using LDAP with Active Directory

Michael Ganss (michael.ganss@oo-services.com)
Managing Director, O&O Services GmbH

This article discusses how you can integrate Linux into a Windows-based network by making it authenticate against an Active Directory server and having it get passwd and group information from Active Directory as well.

It starts by giving a quick rundown on traditional authentication mechanisms in UNIX, then delves into the details of setting up NSS and PAM with Active Directory.

The Problem

With the increasing proliferation of heterogenous IT infrastructures many enterprises are facing the problem of how to keep user data in a unified manner that makes administration and use as efficient as possible.

User data are involved in a number of processes, especially during authentication, which we will discuss in-depth here. Other possible uses includes enterprise-wide address books or the centralized supply of data about shared resources like file systems or printers.

During the design of a centralized directory service which has to build on existing infrastructures, which in turn rely on established, traditional processes, you have to keep a number of requirements in mind:

  • Centralized Administration (User data will only be manipulated at a central site)
  • "Ease of Use"® from the user's point of view (Data should be kept consistent across platforms and in one place only, i.e. only one password for all services)
  • Security (Passwords shouldn't be visible to attackers)

In this article we assume the following scenario:
A number of machines running Linux are to be integrated into an existing network consisting exclusively of Windows 2000/XP machines. Existing user accounts should be usable on the Linux machines with as few restrictions as possible, e.g. the Windows password should also be used for login.

Furthermore, the user should not have to revert to Windows-specific processes, e.g. the password should be changeable via passwd(1).

Our scenario assumes there is already a centralized user administration via Active Directory on a Windows 2000 server.

Traditional User Administration under UNIX

In order to better understand the problems during integration, we'll first give a short rundown of classic authentication mechanisms under UNIX.

/etc/passwd

The traditional user administration under UNIX stems from the era of mainframes and terminals, i.e. from an environment where joint user accounts on different computers in a network were not integrated into the concept.

In this model, user data are held in the files /etc/passwd and /etc/group (among others, which we'll abstract from here). Both files are readable for everyone. /etc/passwd contains one line per user with the following data:

login_name The login name of the user
password The crypted password
UID The numeric user id
GID The primary numeric group id
user_name A free-form field of additional user data, commonly used for the full user name, telephone number etc. Also called the GECOS-Field.
directory The home directory
shell The complete path to the login shell

For example:

username:Npge08pfz4wuk:503:100:Full Name:/home/username:/bin/sh

Authentication of a user is carried out at the start of a login session through login(1), which gathers the entry for the user logging in through getpwent(3) or a similar function. login(1) then crypts the password string typed by the user and compares it to the entry in /etc/passwd returned by getwpwent(3).

This form of user administration and authentication is still in use today. Over time, several enhancements were introduced to the process in order to combat some of its shortcomings.

/etc/shadow

As stated earlier, /etc/passwd is readable for everyone and contains the crypted password of each user. To make it harder for attackers to carry out dictionary attacks, shadow passwords were introduced. The password no longer resides in /etc/passwd but in /etc/shadow instead. /etc/shadow (and /etc/gshadow resp) is only readable for root and the group shadow.

Programs that need to access user data have to run suid root or sgid shadow.

NIS

In order for a number of machines to have access to information in /etc/passwd and /etc/group, Sun invented NIS (Network Information System, formerly Sun Yellow Pages).

With NIS, user data are kept in the same format as in /etc/passwd and /etc/group in a central database and are collected by remote machines via RPC.

In order to use NIS, no changes have to be applied to existing applications, only the C library has to be changed.

NSS

In order to be able to configure the source for the data in /etc/passwd and /etc/group, Sun also introduced NSS (Name Service Switch). In terms of NSS, a name service refers to the data in one of the configuration files traditionally kept in /etc/ (such as /etc/passwd) and is named according to the file name the data are traditionally kept in (such as passwd).

With NSS, the source for a certain type of data such as passwd, but also including others like hosts for data from /etc/hosts, is kept in a configuration file /etc/nsswitch.conf. This file is read by the C library which decides for each name service where the data is gathered from (files, nis, etc).

This method is very flexible, allowing for the implementation of arbitrary sources through dynamic libraries. For example, data can be gathered from an LDAP directory through the use of nss_ldap.

PAM

All methods described above have one problem in common: They all rely on authentication information solely represented by the old crypt(3)-encrypted password.

To gain flexibility in this respect, PAM (Pluggable Authentication Modules) were invented. With this library it is possible to have any number of authentication mechanisms, such as smart cards, finger print scanners etc. Authentication is no longer carried out by applications themselves but rather by the library which, depending on the actual configuration, can delegate the authentication step to various means.

Unfortunately, using PAM makes it necessary to change all authenticating applications in order for them to use PAM instead of getpwent(3) and crypt(3) for authentication purposes. Luckily, nearly all commonly used applications that do authentication have PAM support already.

There is a patch for CVS as well as nserver, an alternative to pserver that supports PAM.

Integration of Linux and Active Directory

Active Directory provides the central user administration means in a Windows network. It subsumes a number of services:

  • LDAP Server
  • DNS Server
  • Kerberos Server

Here we will use the LDAP server in order to provide NSS-Information and an authentication mechanism.

The Architecture

On the Linux side we'll use the libraries nss_ldap and pam_ldap by PADL to communicate via LDAP with the Active Directory server and to serve as an interface to NSS and PAM. Both are contained in most major distributions.

There is an LDAP schema that contains the information from /etc/passwd and /etc/group: RFC 2307.

Of course this schema is not supported by a default Active Directory server, in fact the Active Directory schema collides with RFC 2307 in certain aspects, e.g. the attribute homeDirectory. Nonetheless it is possible to extend the Active Directory schema in such a way that it is possible to enter the necessary information into Active Directory and have it read correctly by nss_ldap.

Security is ensured by using SSL/TLS in the communication between Active Directory and pam_ldap/nss_ldap.

Single-Sign-On-Architektur

Figure 1. Single-Sign-On Architecture

Extending the Active Directory Schema

Step-by-step instructions for changing the Active Directory Schema can be found in the HOWTO by JJ Streicher-Bremer.

It describes the steps necessary to change the Active Directory Schema analogous to those of Microsoft Services for UNIX.

As soon as the changes are in place, you can fill in the additional attributes for users and groups using any LDAP browser.

Maxime Batourine has created a plugin for Active Directory, which makes it possible to change user and group data right in Active Directory Users and Computers.

For testing purposes you might use the LDAP utilities from the OpenLDAP-Suite.

Configuration of nss_ldap and pam_ldap

As mentioned before, many distributions contain the libraries nss_ldap and pam_ldap. Unfortunately, they are sometimes not configured properly to work with Active Directory. It is necessary to configure nss_ldap with the options --enable-rfc2307bis and --enable-schema-mapping.

Important: Systems that use bash as their /bin/sh may have problems while umounting or shutting down if NSS lookups go over LDAP. This is because the shell script /etc/init.d/umountfs (may also be found under /etc/rc.d/init.d/umountfs) which umounts all filesystems during shutdown is executed by bash which in turn calls getpwnam(3), loading LDAP shared libraries. This can result in the filesystem where the LDAP shared libraries reside not being able to umount because it is busy with the mmapped shared libraries.

A possible workaround is to change the shebang-path in /etc/init.d/rc and /etc/init.d/umountfs from /bin/sh to /bin/ash (as well as all calls to sh in these scripts). Ash doesn't have the getpwnam(3) problem.

Both pam_ldap and nss_ldap work directly over SSL/TLS only if they are compiled with Netscape's LDAP SDK. If you use a different LDAP library you can use SSL/TLS via stunnel.

The configuration file for pam_ldap and nss_ldap is usually found in /etc/ldap.conf (both use the same configuration file). Different distributions may place the configuration file at different locations such as /etc/pam_ldap.conf or /etc/libnss_ldap.conf.

In order to level the incompatibilities between the Active Directory schema (Microsoft Services for UNIX, msSFU) and RFC 2307, it is necessary to make a few changes to ldap.conf. Here's an example:

# Your LDAP server. Must be resolvable without using LDAP.
host 192.168.100.1

# The distinguished name of the search base.
base dc=oo-services,dc=com

# The LDAP version to use (defaults to 3
# if supported by client library)
ldap_version 3

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
binddn cn=Guest,cn=Users,dc=oo-services,dc=com

# The credentials to bind with. 
# Optional: default is no credential.
bindpw secret

# The port.
port 389

# The search scope.
scope sub

nss_base_passwd CN=Users,DC=oo-services,DC=com
nss_base_shadow CN=Users,DC=oo-services,DC=com
nss_base_group CN=Group,DC=oo-services,DC=com
 
nss_map_objectclass posixAccount user
nss_map_attribute uid msSFUName
nss_map_attribute homeDirectory msSFUHomeDirectory
nss_map_objectclass posixGroup Group
nss_map_attribute cn msSFUName
nss_map_attribute userPassword msSFUPassword
nss_map_attribute uniqueMember member

pam_filter objectclass=user
pam_login_attribute sAMAccountName
pam_password ad

Configuring NSS

The configuration of NSS is done via /etc/nsswitch.conf. Changes in /etc/nsswitch.conf have immediate effect making it easy to lock yourself out unintentionally, e.g. if the connection to the ADS does not work right away.

It is recommended you keep a root shell open while testing the setup so you can always fix a faulty configuration.

The configuration of NSS in /etc/nsswitch.conf consists of one line for each name service, first the name of the service followed by the lookup methods in the order they are tried. For nss_ldap the following configuration might be used:

passwd:         files ldap
group:          files ldap
shadow:         files ldap

Configuring PAM

PAM can be configured by two different means, either in a single file for all applications (/etc/pam.conf) or in a separate directory /etc/pam.d with one file per application.

The pam_ldap distribution contains example files for most applications. For the login service the file /etc/pam.d/login might look like this:

#%PAM-1.0
auth       required     /lib/security/pam_securetty.so
auth       required     /lib/security/pam_nologin.so
auth       sufficient   /lib/security/pam_ldap.so
auth       required     /lib/security/pam_warn.so
auth       required     /lib/security/pam_unix_auth.so try_first_pass
account    sufficient   /lib/security/pam_ldap.so
account    required     /lib/security/pam_warn.so
account    required     /lib/security/pam_unix_acct.so
password   required     /lib/security/pam_ldap.so
session    required     /lib/security/pam_unix_session.so
session    required     /lib/security/pam_mkhomedir.so skel=/etc/skel/ umask=0022
session    optional     /lib/security/pam_console.so

The module pam_mkhomedir.so makes sure that a home directory is created during the first login. This makes sense if you don't want to create a home directory when you create a new user in Active Directory.

SSL via stunnel

In order to authenticate a user, pam_ldap carries out an LDAP-bind and transmits the password typed by the user in cleartext. In order to keep attackers from abusing this with protocol sniffers, you should use SSL/TLS between nss_ldap/pam_ldap and Active Directory.

A tool that comes in handy for this purpose is stunnel, which provides a proxy (or tunnel) between unsecure and secure connections.

Since the tunnel is running on the client side only, you don't need a certificate, only an unused port. If you have an LDAP server on the client side as well, you might have to move to another port than 389, which makes it necessary to patch ldap.conf accordingly.

If that isn't the case, simply start stunnel on the Linux machine as follows:

stunnel -c -d localhost:389 -r ads:636

where ads is the DNS name of the Windows 2000 server.

Conclusion

It is indeed possible to have an Active Directory server perform authentication and even host NSS data with users on both sides not noticing the difference. You have to watch out for some quirks though, most of which I have hopefully outlined in this article.

Resources

  • Check out these hands-on instructions on how to set up Active Directory and Linux.
  • You might want to download the Active Directory plugin to maintain UNIX-specific attributes in AD from CSS Solutions.
  • The Open-IT Project focuses on Directory Service management tools and system integration.
  • The LDAP Implementation HOWTO has an excellent section on authentication against LDAP.
  • PADL are the authors of the excellent pam_ldap and nss_ldap libraries.

About the Autor

Michael Ganss is Managing Director of O&O Services, based in Berlin, Germany.

You can reach the author at michael.ganss@oo-services.com.