LPI exam 301 prep, Topic 305: Integration and migration

Senior Level Linux Professional (LPIC-3)

In this tutorial, Sean Walberg helps you prepare to take the Linux® Professional Institute Senior Level Linux Professional (LPIC-3) exam. In this fifth in a series of six tutorials, Sean walks you through integrating LDAP with your system's logins and applications. He also details the procedure to integrate your server into a foreign Microsoft® Active Directory.

Share:

Sean Walberg, Network engineer, 自由职业者

Photo of Sean WalbergSean Walberg has been working with Linux and UNIX since 1994 in academic, corporate, and Internet service provider environments. He has written extensively about systems administration over the past several years.



08 April 2008

Before you start

Learn what these tutorials can teach you and how you can get the most from them.

About this series

The Linux Professional Institute (LPI) certifies Linux system administrators at three levels: junior level (also called "certification level 1"), advanced level (also called "certification level 2"), and senior level (also called "certification level 3"). To attain certification level 1, you must pass exams 101 and 102. To attain certification level 2, you must pass exams 201 and 202. To attain certification level 3, you must have an active advanced-level certification and pass exam 301 ("core"). You may also pass additional specialty exams at the senior level.

developerWorks offers tutorials to help you prepare for the five junior, advanced, and senior certification exams. Each exam covers several topics, and each topic has a corresponding self-study tutorial on developerWorks. Table 1 lists the six topics and corresponding developerWorks tutorials for LPI exam 301.

Table 1. LPI exam 301: Tutorials and topics
LPI exam 301 topicdeveloperWorks tutorialTutorial summary
Topic 301LPI exam 301 prep:
Concepts, architecture, and design
Learn about LDAP concepts and architecture, how to design and implement an LDAP directory, and about schemas.
Topic 302LPI exam 301 prep:
Installation and development
Learn how to install, configure, and use the OpenLDAP software.
Topic 303LPI exam 301 prep:
Configuration
Learn how to configure the OpenLDAP software in detail.
Topic 304LPI exam 301 prep:
Usage
Learn how to search the directory and use the OpenLDAP tools.
Topic 305 LPI exam 301 prep:
Integration and migration
(This tutorial) Learn how to use LDAP as the source of data for your systems and applications. See the detailed objectives.
Topic 306 LPI exam 301 prep:
Capacity planning
Coming soon.

To pass exam 301 (and attain certification level 3), the following should be true:

  • You should have several years of experience with installing and maintaining Linux on a number of computers for various purposes.
  • You should have integration experience with diverse technologies and operating systems.
  • You should have professional experience as, or training to be, an enterprise-level Linux professional (including having experience as a part of another role).
  • You should know advanced and enterprise levels of Linux administration including installation, management, security, troubleshooting, and maintenance.
  • You should be able to use open source tools to measure capacity planning and troubleshoot resource problems.
  • You should have professional experience using LDAP to integrate with UNIX® services and Microsoft® Windows® services, including Samba, Pluggable Authentication Modules (PAM), e-mail, and Active Directory.
  • You should be able to plan, architect, design, build, and implement a full environment using Samba and LDAP as well as measure the capacity planning and security of the services
  • You should be able create scripts in Bash or Perl or have knowledge of at least one system programming language (such as C).

To continue preparing for certification level 3, see the series developerWorks tutorials for LPI exam 301, as well as the entire set of developerWorks LPI tutorials.

The Linux Professional Institute doesn't endorse any third-party exam preparation material or techniques in particular.

About this tutorial

Welcome to "Integration and migration," the fifth of six tutorials designed to prepare you for LPI exam 301. In this tutorial, you'll learn all about integration of LDAP with authentication and other UNIX services.

This tutorial is organized according to the LPI objectives for this topic. Very roughly, expect more questions on the exam for objectives with higher weights.

Objectives

Table 2 provides the detailed objectives for this tutorial.

Table 2. Integration and migration: Exam objectives covered in this tutorial
LPI exam objectiveObjective weightObjective summary
305.1
LDAP integration with PAM and NSS
2Integrate the core system authentication with LDAP.
305.2
NIS to LDAP migration
1Plan and implement a NIS migration strategy, including the deployment of a NIS to LDAP gateway.
305.3
Integrating LDAP with UNIX services
1Use your LDAP server as the source of data for SSH, FTP, HTTP, and other services.
305.4
Integrating LDAP with Samba
1Use your LDAP server as the source of data for Samba.
305.5
Integrating LDAP with Active Directory
2Use your LDAP server alongside an Active Directory service.
305.6
Integrating LDAP with e-mail services
1Integrate your e-mail services with your LDAP directory.

Prerequisites

To get the most from this tutorial, you should have advanced knowledge of Linux and a working Linux system on which to practice the commands covered.

If your fundamental Linux skills are a bit rusty, you may want to first review the tutorials for the LPIC-1 and LPIC-2 exams.

Different versions of a program may format output differently, so your results may not look exactly like the listings and figures in this tutorial.

System requirements

To follow along with the examples in these tutorials, you'll need a Linux workstation with the OpenLDAP package and support for PAM. Most modern distributions meet these requirements.


LDAP integration with PAM and NSS

This section covers material for topic 305.1 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 2.

In this section, learn how to:

  • Configure NSS to retrieve information from LDAP
  • Configure PAM to use LDAP for authentication
  • Configure PAM modules in various UNIX environments

In traditional UNIX fashion, PAM and the Name Service Switch (NSS) facilities abstract various components of authentication and lookup from their implementation, which allows the administrator to change backend data stores without recompiling any applications. For instance, moving from traditional /etc/passwd-based authentication to the Network Information Service (NIS) is transparent because NSS is implemented as part of the C library. Applications make use of the standard library calls such as getpwent(3) to look up users, but through some configuration magic, the data is redirected to another store like NIS.

PAM is a slightly different animal, because applications must be written specifically with PAM in mind. Administrators can use a rich set of libraries to customize the behavior of a PAM-aware application, such as requiring specific group membership and a login time in order to successfully authenticate.

PAM and NSS can work in tandem for user authentication. PAM-aware applications instruct PAM to check the user's credentials. The administrator can configure PAM to check the password through the NSS facility in addition to any other restrictions. PAM is used only for the password and shadow databases, not others like groups and hosts.

LDAP support for both PAM and NSS is provided by an open source package from PADL software.

Configure NSS to use LDAP

The NSS facility is implemented in the C library as a hook to traditional library calls to get information. The C library provides functions like getpwent to get user information and gethostbyname(3) for host information, which traditionally were implemented as lookups to /etc/passwd and /etc/hosts, respectively. The administrator can force hostname lookups to also use the Domain Name Service (DNS) by configuring NSS, meaning the application is unaware of the change.

Understand NSS

Table 3 outlines the databases that are handled by NSS. Most databases have a corresponding file in /etc, where the data is traditionally stored.

Table 3. NSS databases
Database nameDescription
aliasesMail aliases for sendmail, used to forward (alias) one local address to another address.
ethersMaps ethernet addresses to IP addresses. Rarely seen anymore because of the availability of the Address Resolution Protocol (ARP).
groupContains a list of groups and the users that belong to them.
hostsMaps IP addresses to host names.
netgroupUsed to group servers together. Most often used for NIS and Network File System (NFS) security.
networksA map of network names to numbers. Not often used because knowing the name of the network provides little value.
passwdStores user account information such as name, Userid, description, primary group, home directory, and sometimes a password.
protocolsMaps IP protocols to their name.
publickeyUsed to distribute keys for NFS and NIS+.
rpcMaps Remote Procedure Call (RPC) function names to numbers.
servicesMaps TCP and UDP service names to the port number.
shadowA protected, encrypted, password file. Usually the password field from /etc/passwd is stored in this file to keep it safe.

NSS is configured in /etc/nsswitchconf and contains one line per database from Table 3. Listing 1 shows a sample nsswitch.conf.

Listing 1. Sample nsswitch.conf
passwd:     files nis
shadow:     files nis
group:      files nis
hosts:      files nis dns

Listing 1 configures four maps: passwd, shadow, group, and hosts. The name of the map is followed by a colon (:) and then an ordered list of ways to access the data. The first three lines in Listing 1 are all the same: they first check the files for the requested information and then the NIS, sometimes known as the Yellow Pages. NIS is checked only if nothing is found in the files. The final line of the example checks the files (/etc/hosts), NIS, and then DNS for any hosts requests.

The methods available to be used in nsswitch.conf have a corresponding library in /lib that begins with libnss_. The functionality for files, for example, is found in /lib/libnss_files-2.5.so (the version number isn't important because it's resolved by the dynamic linker, ld-linux.so).

Introducing LDAP to NSS

After the previous discussion about dynamic libraries and the format of nsswitch.conf, it should come as no great surprise that LDAP integration with NSS is handled through a shared library called libnss_ldap and is referenced through the ldap keyword in /etc/nsswitch.conf. This shared library takes its configuration from /etc/ldap.conf (not to be confused with the OpenLDAP configuration file for the command-line clients, /etc/openldap/ldap.conf). Listing 2 shows a sample ldap.conf.

Listing 2. A sample ldap.conf to configure libnss_ldap
# Server IP address (or space-separated addresses)
host 192.168.1.138
# Search base
base dc=ertw,dc=com
# optional: bind credentials
binddn: cn=nssldap,dc=ertw,dc=com
bindpw: letmein
# If root is making the request, use this dn instead
# The password is stored in /etc/ldap.secret and only readable by root
rootbinddn cn=root,dc=ertw,dc=com
# Point the passwd, shadow, and group databases at a DN
# the ?one defines the scope
nss_base_passwd ou=People,dc=ertw,dc=com?one
nss_base_shadow ou=People,dc=ertw,dc=com?one
nss_base_group          ou=Group,dc=ertw,dc=com?one
# Don't look for secondary groups for any of these users
nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd

In addition to the content of /etc/ldap.conf shown in Listing 2, you also need to add the keyword ldap to the passwd, shadow, and group lines in /etc/nsswitch.conf. Always make sure to have files as the first entry; otherwise, you may find yourself waiting for downed servers to time out—or you may even be locked out of your system. (If you're locked out because of a problem with nsswitch.conf, boot to single-user mode, reset nsswitch.conf back to files, and then reboot.)

It's possible to use LDAP for all the databases, but the three listed here are the ones that are useful. The other maps rarely change and should be managed separately. The exception is the hosts database, which can use LDAP, although DNS is a much better choice.

Test it out

If you've got nsswitch.conf and ldap.conf configured properly, then you should be able to log in with an LDAP user, as long as the following attributes are available:

  • uid: The login name
  • uidNumber: The numeric userid
  • gidNumber: The number primary groupid
  • homeDirectory: The user's home directory
  • userPassword: The user's password, encrypted with the {crypt} routine (use slappasswd to generate this)

These attributes and more are added through the posixAccount objectClass.

To test, try to log in as a user who is in your LDAP tree but not in the local password files. You can also use the getent passwd command to look at all the user entries NSS knows about. If getent works but the login doesn't, your userPassword attribute is likely incorrect.

If you've verified your configuration on the client, and NSS and LDAP still don't work together, enable stats-level logging on the OpenLDAP server and see if your queries are being seen by the server, and if they're being allowed.

Configure PAM to use LDAP

PAM is much like NSS in that it abstracts a set of library calls from the actual implementation. Unlike NSS, PAM doesn't replace existing UNIX calls; instead, it provides a set of new calls that applications can use.

Understand PAM

PAM is implemented as a library that applications use. Applications call this library to use the PAM management functions of checking authentication, account management, session management, and password management.

Checking authentication is the prime purpose of PAM. The application asks the PAM libraries whether the user is authenticated. The PAM libraries, in turn, follow the rules laid out by the systems administrator to prompt the user for a password or perform any number of other checks.

Account management is run after a user provides valid credentials and is responsible for checking to see if the login is allowed. A login may not be allowed at certain times or to certain applications.

Session management gives the application an opportunity to set up the environment after a successful login. It's often desirable to give the user logged into the console some extra permissions, such as the use of the local CDROM or other devices; this is done at the session-management level.

Finally, password management provides a flexible way to change passwords. As you'll soon see, this functionality lets users change their LDAP passwords through the familiar passwd(1) program. PAM password management also allows you to specify password-strength policies that operate independently of the password backend.

To configure PAM for a service, you must create a file named after the service in /etc/pam.d, such as /etc/pam.d/sshd for the sshd service. This isn't a hard-and-fast rule, because the application specifies its own PAM service name. When in doubt, use the name of the binary, and check the logs for errors.

Each configuration file in /etc/pam.d specifies an ordered list of instructions for each of the PAM management functions. Each line in the file is of the form function control module arguments. The function is the management function, using keywords auth, account, session, and password.

The control specifies how the return value of the instruction being evaluated is to be used, and is one of the following keywords:

  • required -- This check must succeed if the function is to succeed. If this check fails, then PAM will continue to check the rest of the instructions for the given function, but the results are meaningless.
  • requisite -- This check must succeed if the function is to succeed. If this check fails, then PAM will stop checking the rest of the instructions and return a failure.
  • sufficient -- If this check succeeds, processing stops and the function returns successfully, assuming no previous "required" elements have failed. If this check fails, the failure is ignored and processing continues.
  • optional -- The results of the check are ignored.

The module and the arguments implement the check itself. The same module can implement one or more of the functions described, so you may see the same module listed several times. One module you'll see used often is pam_stack, which lets you call instruction stacks from other files. Listing 3 shows a PAM file that uses pam_stack.

Listing 3. Using pam_stack to call other instruction stacks
auth       required     pam_nologin.so
auth       required     pam_stack.so service=system-auth
account    required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth

Listing 3 shows the format of a PAM file. The auth function has two lines, both of which are required and therefore must succeed in order for a successful authentication to happen. The first auth line calls pam_nologin, whose job is to fail if a non-root user tries to log in when the /etc/nologin file exists. The next auth line calls the pam_stack module and passes it service=system-auth. pam_stack.so then reads the contents of /etc/pam.d/system-auth and checks all the instructions under the auth function. If that returns a success, pam_stack returns a successful result back to the file in Listing 3.

The other three functions—account, session, and password—make reference only to pam_stack and the system-auth service. If the respective functions from system-auth return successfully, then the result is considered a success.

Many systems have a common set of routines for authentication, so pam_stack is used in most files, with the system-auth (or equivalent) containing all the interesting parts. For the rest of this section, the system-auth file will be the one used to inject LDAP into the PAM process.

Introducing LDAP to PAM

Both the NSS and PAM modules use /etc/ldap.conf for configuration, so if you're following along, you're halfway to having a working PAM-LDAP system. It's possible to use NSS and PAM together so that both PAM-aware and legacy applications can authenticate to LDAP. PAM provides some new features on top of NSS, including the following:

  • Password changes by users
  • More granular configuration of authentication requirements
  • Support for more password encryption types
  • Centralized administration of user accounts

Ensure that pam_password md5 is in /etc/ldap.conf, and remove any other pam_password lines if they exist. This tells the pam_ldap library to hash the password with Message Digest 5 (MD5) locally before sending it to the LDAP server when changing passwords.

Edit your /etc/pam.d/system-auth (or equivalent) to add the references to pam_ldap, as shown in Listing 4. The line should go after any references to pam_unix (so that local accounts take precedence over LDAP accounts) but before any references to pam_allow and pam_deny (which provide a default allow or deny).

Listing 4. New system-auth that uses pam_ldap
auth        sufficient    pam_unix.so nullok try_first_pass
auth        sufficient    pam_ldap.so use_first_pass
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadowaccount     sufficient    pam_ldap.so
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    sufficient    pam_ldap.so use_authtok
password    required      pam_deny.so

session     required      pam_limits.so
session     required      pam_unix.so
session     optional      pam_ldap.so

The lines in bold show additions to the PAM configuration file. Note the addition of broken_shadow in the account function of pam_unix. This ensures that pam_unix.so doesn't return a failure if the user doesn't have a shadow entry (which it doesn't, because the account is in LDAP).

The use_first_pass option to the auth module of pam_ldap forces pam_ldap.so to use the password obtained from pam_unix.so rather than ask for a new password. use_authtok does a similar thing for the password function.

For authorization, the new configuration makes both UNIX passwords and LDAP passwords sufficient to log in: that is, the first one to succeed allows the user to log in. If neither returns success (either a failure, or "no such user"), then pam_deny causes a failure.

Test it out

Try to change a user's password through the passwd command, and then verify that the password was changed in the LDAP directory. Finally, ensure the user can still log in.

If you were able to get NSS working, PAM should also work. The biggest opportunity for error is mistyping the entries in the PAM configuration, putting the entries in the wrong file, or putting them in the wrong place in the file.


NIS to LDAP migration

This section covers material for topic 305.2 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

In this section, learn how to:

  • Analyze NIS structure prior to migration to LDAP
  • Analyze NIS structure prior to integration with LDAP
  • Automate NIS-to-LDAP migration
  • Create a NIS-to-LDAP gateway

NIS is the traditional method of central authentication for UNIX machines. NIS is simple to set up and works well. Despite being more complex, LDAP authentication is superior to NIS in several ways:

  • LDAP is more secure than NIS because you can encrypt the traffic and lock down the database.
  • LDAP can store more than just authentication data, whereas NIS is limited.
  • LDAP is accessible by more clients than is NIS.

You can choose to replace NIS with LDAP or use both simultaneously. When you use them together, LDAP is the canonical data source, and the NIS server uses data from LDAP instead of local files. This is a good approach for a longer-term migration or for supporting legacy operating systems that won't work with LDAP.

Approach 1: Migrate to LDAP

The general approach to migrating from NIS to LDAP is as follows:

  1. Determine which NIS databases need to be replaced.
  2. Load the NIS data into LDAP.
  3. Reconfigure the clients to use LDAP instead of NIS.

For the time between the start of step 2 and the end of step 3, you have two active databases with no connections. Any changes, such as adding a user or changing a user's password, must be done on both databases; otherwise, your data may become inconsistent. You may elect to put a freeze on all changes or go with an integration strategy as shown in the next section.

Analyze your existing NIS structure

Before performing any migration, you must determine which databases are being hosted by NIS. Log in to the NIS master server, and look in the database directory. On most systems, the files are stored in /var/yp/, in a directory named after the domain name. Listing 5 shows the files in a typical NIS server's database directory.

Listing 5. Determining which databases are served by NIS
# ls /var/yp/`domainname` 
group.bygid
group.byname
hosts.byaddr
hosts.byname
mail.aliases
netid.byname
passwd.byname
passwdbyuid
protocols.byname
protocols.bynumber
rpc.byname
rpc.bynumber
services.byname
services.byservicename
ypservers

Listing 5 uses the domainname command to display the domain name. When placed inside backticks (`), the result of this command is inserted in the command line. With the exception of the ypservers file, all the other files in this directory represent a NIS database. Gather the list of unique database names to determine which databases need to be moved to LDAP. NIS stores the same data with different lookup keys, such as by name and UID in the case of the password file; in this case, they both represent the password database. Some aren't obvious: for example, mail.aliases is the aliases table. If in doubt, look in /var/yp/Makefile to determine the source of the database.

After looking at the server, you may wish to examine some of your NIS clients to determine which maps they're using. To do so, look for the nis keyword in /etc/nsswitch.conf. You'll probably find that your server is storing more maps than are being used.

Use the migration tools

The most popular tools to migrate NIS data to LDAP are provided by PADL software, the makers of pam_ldap, nss_ldap, and the NIS-LDAP gateway discussed later. Chances are, your distribution includes the files; otherwise, you can find links to the tools in the Resources section. The PADL migration tools can take data from local files, NIS, or NIS+ and dump them into your LDAP server.

Before using the PADL tools, you must have your LDAP server up and running with no data. The tools will generate all the entries necessary, and you want to avoid duplication.

The migration tools consist of a set of shell and perl scripts. On RedHat systems, the scripts are part of the openldap-servers package and are found in /usr/share/openldap/migration directory. Debian users will want the migrationtools package. Look for a file called migrate_base.pl, or download the latest version from PADL.

These scripts take data from a variety of sources, convert it to LDIF, and then add it to your server. Data is added with the ldapadd command in online mode and through slapadd in offline mode, so you'll need administrative credentials for the former, and you'll need to have your LDAP process stopped for the latter.

Before getting started, you'll find it helpful to set some environment variables to set up the base domain name (DN) of the tree and your root DN. Listing 6 shows the bash commands to prepare for migration of the ertw.com domain.

Listing 6. Setting environment variables in preparation for an LDAP migration
export LDAP_BASEDN="dc=ertw,dc=com"
export LDAP_BINDDN="cn=root,dc=ertw,dc=com"
export LDAP_DEFAULT_MAIL_DOMAIN=ertw.com

The first line in Listing 6 is the base DN of the LDAP tree, which will be used to generate all the DNs later. The second line is your root DN. You need the password only if you're using online mode. The final line of Listing 6 sets the default domain name for e-mail addresses. Some of the tools won't prompt you for this information, so setting it now will prevent aggravation later on.

The tools are split into two categories. The files in the first category have names starting with migrate_all_. The second category includes the remaining files, which have names beginning with migrate_ followed by the name of a file or database. The scripts in the first category are used to gather the data together; the second category is used to convert the native format into LDIF.

You now have two options. You can use one of the migrate_all_ scripts, which will automatically grab all the common databases from your chosen location (NIS, files, NIS+m, and so on); or you can grab only the relevant data yourself and use the individual migration scripts to convert the data into LDIF. The first approach, when it works, is easier. Listing 7 shows the use of migrate_all_nis_online.sh to migrate all the data from NIS into LDAP in online mode.

Listing 7. Migrating data from NIS to LDAP using the migrate_all_nis_online.sh script
[root@server1 migration]# ./migrate_all_nis_online.sh 
Enter the NIS domain to import from (optional):  
No such map networks.byaddr. Reason: Internal NIS error
Enter the hostname of your LDAP server [ldap]: localhost
Enter the credentials to bind with: mypassword
Do you wish to generate a DUAConfigProfile [yes|no]? no

Importing into dc=ertw,dc=com...

Creating naming context entries...
Migrating groups...
Migrating hosts...
Migrating networks...
Migrating users...
Migrating protocols...
Migrating rpcs...
Migrating services...
Migrating netgroups...
Migrating netgroups (by user)...
sh: /etc/netgroup: No such file or directory
Migrating netgroups (by host)...
sh: /etc/netgroup: No such file or directory
adding new entry "dc=ertw,dc=com"

Importing into LDAP...
adding new entry "ou=Hosts,dc=ertw,dc=com"
..... output omitted ...
adding new entry "cn=rquotad,ou=Rpc,dc=ertw,dc=com"

adding new entry "cn=rquotad,ou=Rpc,dc=ertw,dc=com"
ldap_add: Already exists (68)

/usr/bin/ldapadd: returned non-zero exit status: saving failed LDIF to
 /tmp/nis.ldif.X17515

Listing 7 starts by running the migrate_all_nis_onlinesh script, which grabs data from NIS, converts it to LDIF, and then uses ldapadd to import the data. The first query from the script is the NIS domain; you can press Enter for the default NIS domain on the system. The script then imports the NIS data (on this system, a nonfatal error is printed because the networks map isn't used). The script prompts for information on the LDAP server, such as the hostname and the password (the bind DN and base DN were learned through the environment variables you entered in Listing 6). You should choose not to import a DUAConfigProfile unless you have a schema that supports it, which is unlikely.

If, at this point, you start getting errors about invalid DN syntax, be sure you've imported the nis.schema file inside slapd.conf.

If your schema is correct, the script will import data into your LDAP tree. It's likely that the script may die with an error such as the one seen at the end of Listing 7. Because of the way data is stored in NIS, you may have duplicate entries in some databases. This is fine in NIS but not in LDAP. There are a few solutions to this problem, depending on your needs:

  • Edit the LDIF file (/tmp/nis.ldif.X17515 in this case) to remove the duplicates, and then delete your LDAP database and import the file.
  • Tell ldapadd to ignore errors with the -c option. export LDAPADD="/usr/bin/ldapadd -c" will do this. (Note that the script will still report an error, but the data will have been imported.)
  • Edit migrate_all_nis_online.sh to set the value of ETC_SERVICES, ETC_PROTOCOLS, and ETC_RPC to /dev/null instead of a temporary file. Doing so skips processing the database. (Note that some of the migrate_all_ scripts can be overridden by environment variables, but not the NIS variant.)
  • Skip migrate_all_nis_online.sh, and migrate by hand.

The first three options are self explanatory and effective as long as you're comfortable with the results (such as not having protocols, RPC, and services in LDAP for the third option). The fourth option needs some explanation.

If all you want to do is move groups and users over to LDAP, you can just as easily copy the files yourself and generate the LDIF using the other scripts provided, and using ypcat to get the data out of NIS. Listing 8 shows the process.

Listing 8. Migrating groups and users by hand
[root@server1 migration]# ypcat passwd > /tmp/passwd.tmp
[root@server1 migration]# ypcat group > /tmp/group.tmp
[root@server1 migration]# ./migrate_base.pl > /tmp/ldif
[root@server1 migration]# ./migrate_passwd.pl /tmp/passwd.tmp >> /tmp/ldif
[root@server1 migration]# ./migrate_group.pl /tmp/group.tmp >> /tmp/ldif
[root@server1 migration]# ldapadd -x -D "cn=root,dc=ertw,dc=com" \
  -w "mypassword" -f /tmp/ldif
adding new entry "dc=ertw,dc=com"
adding new entry "ou=Hosts,dc=ertw,dc=com"
..... output omitted ...

The first two lines of Listing 8 use ypcat to get the data from NIS into a file in /tmp. The next three lines generate LDIF. migrate_base generates some basic entries in the tree, and the next two lines convert the password and group files to LDIF. Note the use of the append operator (>>), so the resulting file will contain the output of all three migration scripts. Finally, you call ldapadd to import the data.

Whichever way you go, perform some basic searches to make sure you can see the data. Be sure you can see the password hashes (use the root DN for this, because it's possible you have an access control list preventing passwords from being seen).

At this point, you have your NIS data in LDAP. Until all your NIS clients are moved over, all changes to NIS must be replicated to LDAP and vice versa.

Move the clients and verify results

Moving the clients is a simple matter of setting up NSS and PAM on the client. The previous section covered this in detail. In brief, you populate /etc/ldap.conf with your server information and edit /etc/nsswitch.conf to replace nis with ldap. If you're setting up PAM, then you need to edit the relevant files in /etc/pam.d to add references to pam_ldap.so.

Test your clients by logging in to them as a regular user and running the getent commands on the databases you moved to LDAP.

Approach 2: Integrate with LDAP

The second approach calls for the coexistence of NIS and LDAP. This can be helpful if you have clients that don't speak LDAP (either by not having a native LDAP module or by not supporting PAM), or if you want to spread out your transition over a longer period of time. The approach for a NIS/LDAP coexistence is similar to the first strategy:

  1. Determine which NIS databases are in use.
  2. Load the NIS data into LDAP.
  3. Replace your NIS servers with ypldapd.
  4. Reconfigure the clients that will be using LDAP.

The clients that will continue to use NIS need no changes because ypldapd is a fully functional NIS server. The only difference between it and the standard ypserv that comes with your operating system is that ypldapd gets its data from LDAP instead of local files.

The first two steps are the same as the first approach, so you begin at step 3.

Replace your NIS servers with ypldapd

ypldapd is a NIS server daemon that gets its information from LDAP instead of the database files in /var/yp. It's commercial software from PADL, but you can get a 30-day trial license by e-mailing PADL (see the Resources). Installation of ypldapd is a simple process:

  1. Untar the software to /opt/ypldapd.
  2. Copy the license to /opt/ypldapd/etc/padlock.ldif.
  3. Edit the configuration file, /opt/ypldapd/etc/ypldapd.conf
  4. Stop your existing NIS server.
  5. Start up ypldapd.

First, run mkdir -p /opt/ypldapd as root to make the ypldapd directory (and /opt, if it doesn't already exist). Change into this directory (cd /opt/ypldapd), and untar the ypldapd distribution with tar -xzf /tmp/ypldapd_linux-i386.tar.gz. This places the ypldapd files in the proper directory.

You'll have been given a license file, which you'll place in /opt/ypldapd/etc/padlock.ldif. If you're copying it from an e-mail, then make sure your e-mail client didn't wrap long lines: the key should be four lines long with a series of attribute:value pairs.

ypldapd's configuration file is in /opt/ypldapd/etc/ypldapd.conf. There is a file called ypldapd.conf.sample that you can copy to start with. As with the other utilities you've seen so far, you need to provide information about your LDAP server. Listing 9 shows a simple ypldapd.conf.

Listing 9. Sample ypldapd.conf
# The NIS domain name
ypdomain ertw
# The LDAP server and base DN
ldaphost localhost
basedn dc=ertw,dc=com
# Credentials... The user must be able to read the userPassword attribute
binddn cn=ypldapd,dc=ertw,dc=com
bindcred mypassword
# The map of NIS databases to DNs (relative to basedn)
# If you used the migration tools then you shouldn't have to change anything
namingcontexts namingcontexts.conf
# Should ypldapd cache data?
caching on
# Cache lifetime, in minutes
cache_dump_interval 15
# Should passwords be hidden?
hide_passwords off
# How many ypldapd servers can be running at a given time?
maxchildren 5

With ypldapd.conf in place, you can shut down all instances of ypserv and then run sbin/ypldapd, which starts ypldapd in the background.

Move the clients and verify results

To test your new NIS server, run ypwhich, which tells you which NIS server you're bound to. If you get an error, make sure that no other instances of ypserv are running and that only one ypldapd is running. Then, try to fetch a map by typing ypcat passwd (this assumes your server was also running a client).

Clients that will be staying with NIS should also be able to run ypwhich and ypcat against the new server. For clients that will be moving to LDAP, see the previous set of instructions for the migration.


Integrate LDAP with UNIX services

This section covers material for topic 305.3 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

In this section, learn how to:

  • Integrate SSH with LDAP
  • Integrate FTP with LDAP
  • Integrate HTTP with LDAP
  • Integrate FreeRADIUS with LDAP
  • Integrate print services with LDAP

Most applications will work correctly with LDAP if you've configured NSS and PAM. Some applications need to be told to use PAM, or provide additional functionality by accessing LDAP correctly. This section focuses on the common UNIX daemons and how they support LDAP integration.

Integrate SSH with LDAP

The OpenSSH distribution integrates with LDAP through PAM, as long as the functionality was compiled in. To check, run ldd /usr/sbin/sshd | grep pam to see if the PAM shared libraries are linked. If not, you must recompile sshd with --with-pam.

To use PAM, be sure you have a PAM configuration file named /etc/pam.d/sshd if one doesn't exist already. Listing 10 shows a sample PAM file that makes use of the system-auth stack.

Listing 10. A sample /etc/pam.d/system-auth
auth       required       pam_stack.so service=system-auth
account    required       pam_stack.so service=system-auth
password   required       pam_stack.so service=system-auth
session    required       pam_stack.so service=system-auth

With the PAM configuration file in place, you can configure sshd to work with PAM. In /etc/ssh/sshd_config, add UsePAM yes, and restart sshd.

Integrate FTP with LDAP

Many FTP daemons are available, and it isn't clear which ones apply to the LPIC 3 exam.

The easiest integration method is to rely on NSS integration. When the FTP server performs a password lookup, the NSS facility uses LDAP.

In modern times, though, FTP servers are likely to be built with PAM support. In these cases, you create your PAM configuration file in /etc/pam.d. This file is usually called ftp, but it can be overridden depending on the software and distribution. For example, RedHat packages the vsftpd daemon to use /etc/pam.d/vsftpd instead of the default /etc/pam.d/ftp.

Once the ftp daemon has found its PAM configuration file, it processes it just like any other PAM client. The configuration in Listing 10 is enough to get started. You may also consider using pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed and pam_shells in the auth phase to limit the users who can log in and the valid shells, like the legacy FTP servers did.

Integrate HTTP with LDAP

The Apache Web server has modules that handle basic HTTP authentication with an LDAP backend instead of the traditional htpasswd file-based backend. This is provided through the mod_authnz_ldap and mod_ldap modules. The first module provides the mechanisms to use LDAP information to authenticate a Web user, whereas mod_ldap provides an interface for mod_authnz_ldap (or any future LDAP-based module) to access LDAP, including connection pooling and caching.

The instructions in this section refer to Apache 2.2. If you're using Apache 2.0, the mod_auth_ldap module is used instead of mod_authnz_ldap. Configuration of these two modules is similar.

Both mod_ldap and mod_authnz_ldap are part of the Apache distribution. If you compile your Web server by hand, you need to add --enable-authnz-ldap --enable-ldap to your configure command. If you use your distribution's version of Apache, then install the appropriate module (for Red Hat distributions, the modules are part of the core httpd package).

When a user makes a request to a protected resource, Apache returns an error code 401 (unauthorized). At this point, the Web browser should prompt the user for a username and password. The Web browser then reissues the request with this information encoded in an Authorization header. If the username and password are accepted by the Web server, the page is served to the client; otherwise, the server returns another 401.

Apache, when configured to check passwords against LDAP, first binds to the server as a predefined user and performs a lookup on the user to find the DN. The server then rebinds as the user with the provided password. If the server can successfully bind as this user, the authentication is considered successful.

After a successful authentication, the server can be configured to perform additional authorization tasks, such as checking against the DN or attribute, or testing to see if the user passes a search filter. If any of these tests are configured, then the test must pass for the authorization to pass.

Configuration of mod_authnz_ldap is similar to the standard authentication method using text files. Listing 11 shows the simplest case of LDAP authentication with no authorization.

Listing 11. Apache configuration for LDAP authentication
LoadModule ldap_module modules/mod_ldap.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so

<Location /protected>
  AuthType basic
  AuthName ProtectedByLDAP
  AuthBasicProvider ldap

  AuthLDAPUrl ldap://192.168.1138/ou=People,dc=ertw,dc=com?uid
  # Anon bind for first phase
  #AuthLDAPBindDN
  #AuthLDAPBindPassword

  AuthzLDAPAuthoritative off
  require valid-user
</Location>

The first two lines of Listing 11 load the required modules into the Web server. The rest of the configuration is enclosed in a Location container, meaning it applies only to requests beginning with /protected. The configuration first declares Basic authentication and a name of ProtectedByLDAP. The Web browser shows the name to the user. The AuthBasicProvider line tells Apache that authentication is provided through LDAP.

Listing 11 continues with AuthLDAPUrl, which points Apache to the LDAP server. The form of the parameter is ldap://host:port/basedn?attribute?scope?filter. host and port define the LDAP server, and basedn is the base DN from which the initial search is performed. attribute refers to the attribute that will be searched along with the username during the initial search (the default is uid). scope is either one or sub to correspond with one level or all children. filter is an optional filter that will be logically ANDed with the search for the given user/attribute combination.

The example in Listing 11 has AuthLDAPBindDN and AuthLDAPBindPassword commented out, which results in an anonymous bind. If you want to specify a user here, you may. Either way, the user performing the initial bind must be able to search on the attribute provided in the AuthLDAPUrl command.

The final two lines disable authorization by allowing any validated user. AuthzLDAPAuthoritative off means that a later module can allow the access even if LDAP denies authorization (but not authentication). require valid-user comes from another module, so this deferral is required. Instead of these two lines, you can use LDAP-related ones, such as checking for group membership or an LDAP attribute. Listing 12 shows part of the configuration from Listing 11, but it restricts access to people with the ou=Engineering attribute and value.

Listing 12. Restricting access to a particular OU
AuthzLDAPAuthoritative  on
require ldap-filter ou=engineering

Two things are notable in Listing 12. First, AuthzLDAPAuthoritative is now on (this is the default) because your requirement can be handled by the LDAP module. Second, the ldap-filter doesn't include parentheses. Apache uses the given LDAP filter and also performs a logical AND with the uid (or whichever attribute you specified in the AuthLDAPUrl command) and builds the search filter with a simple string insertion. If you have extra quotes or parentheses in your filter, the resulting query becomes invalid. The authentication fails, and a log message is printed to the server's error_log.

Integrate FreeRADIUS with LDAP

FreeRADIUS is an open source Remote Authentication Dial In User Service (RADIUS) server that is often used for authentication of dial-up or other network devices. Clients use RADIUS to authenticate users, and the RADIUS server in turn uses LDAP to find its information.

You can integrate PAM and FreeRADIUS two ways: by using PAM, or by enabling native LDAP support through the rlm_ldap module. The choice depends on how you plan to use RADIUS. If all you need is authentication, or you don't wish to modify your LDAP schema, then use PAM. If you need to use RADIUS attributes, then it's easier to configure the LDAP module and store the attributes in LDAP (RADIUS allows the server to send configuration details to the device asking for authentication, which lets you provide different services to different users).

For PAM mode, ensure that you have PAM set up for LDAP like the other systems. The PAM configuration file for FreeRADIUS is /etc/pam.d/radiusd. Starting from the default configuration files that come with FreeRADIUS, uncomment the pam keyword in the authenticate section of radiusd.conf. Next, edit the users file and look for DEFAULT Auth-Type = System. Change the System keyword to PAM. Restart radiusd, and you're done.

The native LDAP module, rlm_ldap, is more complex. First, you must have FreeRADIUS installed on your system, built with the rlm_ldap module (--enable-ldap). FreeRADIUS is built like most other packages and so won't be covered here. Your Linux distribution, if it includes FreeRADIUS, likely includes the LDAP module.

FreeRADIUS includes an LDAP schema in a file called openldap.schema. Copy this to /etc/openldap/schema/freeradius.schema, and import it into OpenLDAP through the include directive in slapd.conf. The schema provides several attributes and two objectClasses. One of the objectClasses is radiusprofile; it's used for any users who will be authenticated with RADIUS. radiusprofile is an auxiliary objectClass and therefore can go on any entry. radiusObjectProfile is a structural objectClass used to create containers of radius profiles; it isn't necessary for operation.

Next, edit the default users file as in the PAM example, but instead of changing the default method to PAM, comment out that entire section. This file controls how users are authenticated and authorized. Removing the default method is enough to allow the LDAP module to take over and handle user authentication and authorization.

radiusd.conf needs more work. In both the authenticate and authorize sections, uncomment the ldap keyword that enables LDAP authentication and authorization. You must also find a section that looks like Auth-Type LDAP { ldap } and uncomment that. Finally, uncomment the ldap { ... } section, and enter your server's address, base DN, and optional authentication information. Like other software you've seen, the initial bind performs the lookup of the user's DN; then, a second bind is made as that user to confirm the password and retrieve the attributes. Therefore, the user you initially bind as (or anonymous if you have no configured user) must be able to perform searches on the uid attribute, and users must be able to read their own attributes.

Users who need to be authenticated by LDAP must use the radiusProfile objectClass and have a dialupAccess attribute with some value in it, such as "yes". With more advanced configurations, you can use the value to apply different settings, but for basic purposes, the attribute can take any value.

FreeRADIUS is an extremely robust RADIUS server, and a great deal of configuration can be required to get it to do what you need. The two configurations shown here focus only on what is needed to get LDAP working.

Integrate CUPS with LDAP

The Common UNIX Printing System (CUPS) is the currently favored printing daemon because of its ease of configuration, support for the Internet Printing Protocol (IPP), and backward compatibility with the traditional lpr tools. CUPS supports PAM, but it must be told how and when to authenticate.

First edit /etc/pam.d/cups so that it supports LDAP. Next, in /etc/cups/cupsd.conf, create for your printers a container that requires authentication, such as in Listing 13.

Listing 13. A printers container that requires authentication
<Location /printers>
        AuthType Basic
</Location>

Listing 13 shows a configuration that requires Basic authentication for any URL beginning with /printers. The CUPS configuration is almost identical to that of Apache, so this configuration should remind you of Listing 11. However, CUPS is using PAM instead of a native LDAP module, so no LDAP configuration is necessary. CUPS uses PAM for authentication because that is how it's configured. Now, when you try to browse a URL under /printers, which includes printing to a printer, you're prompted for a password. Listing 14 shows such a prompt.

Listing 14. Verifying that CUPS is working with LDAP
[sean@bob LPIC-III_5]$ lpr index.xml 
Password for sean on localhost? mypassword
[sean@bob LPIC-III_5]$

If the password were incorrect or PAM wasn't working, then Listing 14 would have reprompted for a password. PAM was successful, though, so the document was printed and the user was returned to the shell prompt.


Integrate LDAP with Samba

This section covers material for topic 305.4 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

In this section, learn how to:

  • Migrate from smbpasswd to LDAP
  • Understand the OpenLDAP Samba schema
  • Understand LDAP as a Samba password backend

Samba is the UNIX community's way of integrating with Microsoft Windows networks. With this software, you can share files with Microsoft networks (both client and server) and make your UNIX computer appear as a Windows computer to the other Windows clients.

Understand Samba authentication

Samba's goal is integration with Windows networks, so it must use the authentication mechanisms that Windows uses. If you're authenticating against a Windows server, this is fine, but often the Samba server is the repository for the credentials. Thus, two copies of password hashes are needed—one for the traditional UNIX passwords and another for the Microsoft hashes.

Microsoft passwords are similar to UNIX passwords in that they're hashes of the real password. A hash function is a one-way function that accepts a variable-length input (such as a password) and outputs a fixed-length hash (string). It's impossible to take the hash and recover the original password, although you could try billions of different inputs in hopes that the resulting hash will match.

Two different password hashes are stored for Microsoft passwords: the LANManager hash and the Windows NT hash. The first isn't as secure as the second because several things are done to the password before hashing that reduce the number of possible outputs. The Windows NT hash was designed to overcome these limitations. Even though both hashes are stored, you can choose to disable the LANManager support if all your clients support NT hashes (available on Windows NT SP 3 and above).

Samba has traditionally stored the password hashes in the smbpasswd file and uses tools like smbpasswd to manage the password file by the same name. This can easily be moved to LDAP so that multiple Samba servers can authenticate without needing to use Primary Domain Controllers or other Microsoft infrastructure. Storing the data in LDAP also reduces duplication of information across your network.

Understand the Samba schema

NT passwords are different from UNIX passwords and can't be stored in the userPassword attribute. Therefore, the LDAP schema must be extended to store the password hashes and other pieces of information that a Microsoft device expects to be available.

The schema file is distributed with the Samba suite as samba.schema. Copy this file to /etc/openldap/schema, and use the include directive in slapd.conf to make it a part of your server's schema.

samba.schema introduces several new objectClasses, which are explained in Table 4.

Table 4. objectClasses in samba.schema
objectClassDescription
sambaSamAccountProvides the information needed for an account (computer, user, and so on) in an NT environment.
sambaGroupMappingMaps a UNIX group to a Windows group.
sambaTrustPasswordProvides authentication information about trust relationships between domains.
sambaDomainStores information about the domain in the LDAP tree. You'll find one of these added automatically to your LDAP tree after you set up Samba/LDAP.

Configure Samba for LDAP

Configuring Samba for LDAP involves editing smb.conf to set up the LDAP data source and then manipulating your users' LDAP entries to make them aware of the new Samba attributes.

In your smb.conf, you'll find a line like passdb backend = tdbsam, which represents the smbpasswd file storage mechanism. Replace this with the code in Listing 15, modified for your environment.

Listing 15. Using the ldapsam password storage
# ldapsam requires the uri to the LDAP server
passdb backend = ldapsam:ldap://192.168.1.138/
# A user in your LDAP server that can read and write the new attributes
# The password will be entered later
ldap admin dn = cn=root,dc=ertw,dc=com
# Same as search base
ldap suffix = dc=ertw,dc=com
# OUs for users/computers/groups
ldap user suffix = ou=People
ldap machine suffix = ou=Computers
ldap group suffix = ou=Group

Once you've set up smb.conf, restart Samba and execute smbpasswd -W. You're prompted for the password for the LDAP admin DN you entered in smb.conf. At this point, Samba will use LDAP data to authenticate users.

Manage Samba users in LDAP

Users must be set up with the sambaSamAccount objectClass before they can use Samba, which includes setting the password hashes and assigning a security identifier (SID) to the user. This is easily handled by the smbpasswd utility, which traditionally added users to the smbpasswd file. smbpasswd will manage an LDAP user if smb.conf is configured to use LDAP, such as in Listing 15.

To set up a new user, first be sure the user's account is set up with the posixAccount objectClass and a uid attribute, which should already be there if the user logs in through LDAP and PAM or NSS. Next, run smbpasswd -a username to modify the user's LDAP entry, which includes setting the Samba password. Listing 16 shows a typical user's entry after being set up for Samba.

Listing 16. A Samba user's entry
dn: cn=Jim Joe,ou=people,dc=ertw,dc=com
givenName: Jim
sn: Joe
cn: Jim Joe
uid: jjoe
uidNumber: 1000
sambaSID: S-1-5-21-2287037134-1443008385-640796334-
userPassword:: e01ENX1yTDBZMjB6QytGenQ3MlZQek1TazJBPT0=
sambaLMPassword: 5BFAFBEBFB6A0942AAD3B435B51404EEsambaNTPassword: AC8E657F83DF82BEEA5D43BDAF7800CC
loginShell: /bin/bash
gidNumber: 4
homeDirectory: /home/a
sambaAcctFlags: [U]
objectClass: inetOrgPerson
objectClass: sambaSamAccount
objectClass: posixAccount
objectClass: top

The bold lines from Listing 16 were added by smbpasswd. Starting from the top, a SID is added to the account. Using smbpasswd frees you from needing to calculate this, because smbpasswd figures out what SID to use. Next, the LanManager and NT password hashes are stored. The sambaAcctFlags is used to store some attributes of the entry. Possible values of this flag are as follows:

  • N: No password required
  • D: Account disabled
  • H: Home directory required
  • T: Temporary duplicate of other account
  • U: Regular user account
  • M: MNS (Majority Node Set cluster) logon user account
  • W: Workstation Trust Account
  • S: Server Trust Account
  • L: Automatic locking
  • X: Password doesn't expire
  • I: Domain Trust Account

Finally, the sambaSamAccount objectClass enables all these attributes.

In addition to those described here, you can set many other options to carry more Windows-specific information. Consult the pdbedit manpage to learn about reading and modifying Samba user information from the command line. Samba can act as a Windows Primary Domain Controller (PDC), and the extra information is necessary for Windows clients to function correctly.

Password synchronization

Now that two sets of passwords exist (userPassword and the two Samba hashes), you must find a way to keep the passwords in sync with each other. If a user changes his or her Samba password, either from the command line or from a Windows client, the UNIX password should change. Likewise, if a user changes the UNIX password, the Samba password should change.

The first case is the easiest. Add ldap password sync = yes to the [global] section of smb.conf, and restart Samba. Any further password changes will change both the Samba and userPassword hashes.

Getting the Samba passwords changed when a user changes his or her password through the UNIX passwd command requires PAM. Samba comes with mod_smbpasswd, which is used to authenticate and change passwords through the Samba system. For now, there is no need to authenticate passwords, so only the password function will be used. Listing 17 shows part of a PAM configuration file that, when used, changes both UNIX and Samba passwords in LDAP.

Listing 17. A PAM password stack to change both UNIX and Samba passwords
password    requisite     pam_cracklib.so try_first_pass retry=3
password    optional      pam_smbpass.so use_authtok use_first_pass
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    sufficient    pam_ldap.so use_authtok
password    required      pam_deny.so

In Listing 17, the added line is shown in bold. The pam_smbpass module is listed as optional so that if a user isn't configured as a Samba user, that step will fall through. The Samba password change is before the UNIX and LDAP password changes, because these two are marked as sufficient, meaning the first one to succeed stops processing.

With Listing 17 in place, a user changing his or her password from the command line will also change the Samba password.

Migrate existing users to LDAP

When you move to an LDAP backend, you're likely to have existing users in a file-based password mechanism that you need to migrate. The pdbedit utility can copy accounts from one place to another to make this job easy.

Listing 18 shows the use of pdbedit to migrate users. The -i parameter sets the source of the data, and the -e parameter sets the destination. Before running the pdbedit command, you should have the ldapsam database set up in smb.conf.

Listing 18. Migrating users from tdbsam to ldapsam
[root@server1 ~]# pdbedit -e ldapsam -i tdbsam
Importing account for fred...ok
Importing account for jsmith...ok

If you're using the older smbpasswd password backend, use smbpasswd instead of tdbsam.


This section covers material for topic 305.5 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 2.

In this section, learn about:

  • Kerberos integration with LDAP
  • Cross-platform authentication
  • Single sign-on concepts
  • Integration and compatibility limitations between OpenLDAP and Active Directory

Microsoft Windows can be found in almost every company; there's a good chance that your environment already makes use of Active Directory, Microsoft's enterprise directory service. Active Directory is based on two open protocols: LDAP and Kerberos. By understanding these protocols and configuring the Linux system appropriately, your Linux box can authenticate against the enterprise directory and facilitate single sign on (SSO). This means you log in to your machine once, and your credentials are good throughout the network.

Understand Kerberos

Kerberos, named after the three-headed dog from Hades in Greek mythology, is a protocol that allows users and servers to prove their identity to each other over an untrusted network. It was developed at the Massachusetts Institute of Technology (MIT) for use on their network and has since found its place in many other networks. Microsoft chose to use Kerberos as part of Windows 2000's Active Directory.

Kerberos V is the currently developed stream, although you may run into Kerberos IV at times. Kerberos V provides backward compatibility for systems still using Kerberos IV.

The Kerberos protocol

Kerberos is a protocol that allows a service to authenticate the identity of a user without needing to see a password. This is achieved by having a mutually trusted server, called the Authentication Service (AS). The AS shares a secret with each user and service. The secret is used to protect information between the AS and the other end of the conversation; it even lets the AS give the user a message (called a ticket) destined for someone else. In this latter case, users can't read the ticket because they don't have the shared secret.

All clients and servers form a Kerberos realm, which is much like an NIS domain or, in some respects, the base DN of an LDAP tree. The realm defines all the devices and people that authenticate to a common set of Kerberos servers. Generally, the realm is the DNS zone of the organization written in uppercase, such as ERTW.COM. For the purposes of Kerberos, the clients are the computers that get tickets from a Kerberos server. The servers are the devices that provide the Kerberos services of granting tickets.

Everything that is authenticated in the Kerberos realm has a corresponding Kerberos principal that identifies it and is associated with the password or shared secret. When a user connects to a server, they're really connecting to a service running on the server. Each service is treated separately and must be registered as a principal with the Kerberos server. A service's principal is of the form servicename/servername@REALM, whereas a user's principal is of the form user@REALM.

The Kerberos protocol is shown in Figure 1.

Figure 1. The Kerberos protocol
The Kerberos protocol

The Kerberos protocol can be viewed as having two distinct phases: the initial login of the user to the realm, and the authenticating of the user to the service. The magic of Kerberos is that the initial login happens only once; the subsequent service authentication can happen many times to many servers.

The first phase of Kerberos starts with the user asking the Kerberos server (specifically, a component called the Key Distribution Center [KDC]) for a Ticket Granting Ticket (TGT), which will be used later to request service. The KDC generates a TGT, encrypts it with the user's password, and sends it back to the user.

The TGT has been likened to a visitor pass in a company. You show your identification to the security guard (KDC) and are granted a visitor pass that's valid for one day. This process allows you to keep your own ID secure and also limits the company's exposure to a stolen visitor pass. The TGT expires in a short period of time, usually around 8 hours.

In the second phase, the user decides he or she needs access to a service. The user sends a request to the Kerberos server's Ticket Granting Service (TGS) component, which includes the TGT and the name of the service (the principal). The TGS checks to see if the TGT is still valid and then issues a ticket that has been encrypted with the shared secret of the service. Finally, the user presents this ticket to the service. If the service can successfully decrypt the ticket, then the service knows the Kerberos system approved the request. No passwords ever crossed the network.

Kerberos thwarts replay attacks, where an attacker captures a ticket and uses it again, by imposing limited lifetimes on tickets and including timestamps in the encrypted ticket. A ticket for a service may be valid for 5 minutes, so the service has to remember just 5 minutes' worth of tickets to know if a ticket was replayed. All clocks must be synchronized for this to succeed.

Where does LDAP fit in?

Kerberos provides only an authentication framework, much like the PAM system does. User information isn't stored in the Kerberos database.

Kerberos secrets can be stored in the LDAP database or they can be left separate. The choice is up to the implementation of Kerberos. In either case, LDAP is used to store the user information such as home directory and personal information.

You must keep your Kerberos database secure regardless of where it's stored. The Kerberos keys are like passwords: they can be stolen and used to generate TGTs and tickets. Most guides strongly recommend keeping your Kerberos server on its own device and protecting it as much as possible.

Configure Microsoft Active Directory for your Linux guests

Active Directory uses implementations of Kerberos and LDAP that are compatible with those shipped with Linux. Microsoft has extended Kerberos to support Windows-specific attributes, but this doesn't prevent UNIX users from using it (see the Resources for Microsoft's documentation on the subject).

The Active Directory schema must be extended to support some of the UNIX attributes, which is easily done in Windows 2003 Server. Go to the Control Panel of your Domain Controller, and choose Add or Remove Programs > Add/Remove Windows Components. From the Active Directory Services component, choose the Identity Management for UNIX subcomponent. (If you have an earlier version of Windows, this component is sometimes called the Server for NIS.) Install this software, and the LDAP schema will be extended; your user dialogs will also include a UNIX Attributes tab, which will be used soon.

From the Active Directory Users and Computers application, edit the Domain Users security group. Note the new tab, UNIX Attributes. Assign a group and NIS domain to your Domain Users group, as shown in Figure 2. Doing so allows the group to be seen by the UNIX systems. This group will be the user's primary group.

Figure 2. Assigning UNIX attributes to a group
Assigning UNIX attributes to a group

Still in the Users container, find a user whom you want to use on your UNIX servers. Find the UNIX Attributes tab for this user, and assign the standard UNIX attributes to them. Figure 3 shows a sample user.

Figure 3. The UNIX attributes of a user
The UNIX attributes of a user

The user in Figure 3 has been assigned a primary group, a home directory, a shell, and a userid.

Next, you must create a service account that allows access to your LDAP tree, because anonymous access is disabled by default. Use the following configuration for this user:

  • Name: LDAP service account (or your choice)
  • User logon name: ldap (or your choice)
  • Password: Your choice
  • User can't change password: Selected
  • Password never expires: Selected
  • Primary group: Domain Guests

The service account should only be a member of Domain Guests. From the Member Of tab, add the Domain Guests group to the account, highlight it in the list of groups, then click the Set Primary Group button. With the group changed, you can remove the Domain Users group from the profile.

If your security policy prohibits the password options, you'll have to adjust your Linux configuration (described next) each time the password changes. Note that LDAP is used here only for directory information and not passwords, so the requirement to change passwords is lessened.

Configure Linux

The Linux side of the equation involves three steps. First, you set up directory access through /etc/ldap.conf. Next, you configure PAM for Kerberos authentication. Finally, configure Samba to use Active Directory information for authentication, and join it to the domain.

Before you start, you must ensure that your Linux machine is using your Microsoft server for both DNS and network time. Your Linux server must also have a host record in the Microsoft DNS zone for your domain.

Configure LDAP

LDAP is configured as it was earlier, except that some mapping is required from UNIX attributes to Microsoft attributes. Listing 19 shows /etc/ldap.conf configured to access a Microsoft LDAP directory using the user account set up previously.

Listing 19. Configuring ldap.conf to use a Microsoft directory
# Information about the directory
uri ldap://192.168.1.151
binddn ldap@ertw.com
bindpw ldap
ssl no
base dc=ertw,dc=com

# Map attributes
nss_map_objectclass posixAccount user
nss_map_objectclass shadowAccount user
nss_map_attribute uid sAMAccountName
nss_map_attribute homeDirectory unixHomeDirectory
nss_map_attribute shadowLastChange pwdLastSet
nss_map_objectclass posixGroup group
nss_map_attribute uniqueMember member
pam_login_attribute sAMAccountName
pam_filter objectclass=User
pam_password ad

The configuration shown in Listing 19 first points the module to the Microsoft LDAP server using the credentials set up earlier. The attributes are mapped from the UNIX name to the Microsoft name, such as using sAMAccountName for the userid.

Finally, add ldap winbind to the passwd, group, and shadow sections of /etc/nsswitchconf (leave files in there). This lets your system pull directory information from LDAP and Samba (the latter to be configured later).

After this step, you can run getent passwd to see the LDAP users. Note that you must set the UNIX attributes for the user in Active Directory for the user to show up in the list.

Configure Kerberos

Kerberos is configured through PAM and the /etc/krb5.conf file. If you're using your Microsoft DNS server for your DNS, then you only need to specify your realm, because the server will be learned automatically from DNS. Listing 20 shows the contents of /etc/krb5.conf

Listing 20. /etc/krb5.conf for the ERTW.COM realm
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = ERTW.COM
 dns_lookup_realm = false
 dns_lookup_kdc = true
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 ERTW.COM = {
  default_domain = ertw.com
 }

[domain_realm]
 .ertw.com = ERTW.COM
 ertw.com = ERTW.COM

[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
 }

krb5.conf is divided into sections, with the name of the section enclosed in square brackets. The logging section specifies the paths of various logfiles. The libdefaults sections configure the Kerberos libraries: in particular, the dns_lookup_kdc tells the library to look for server records (SRV) in DNS to find the KDC. The record looks like _kerberos._tcp.ERTWCOM., and the response is the name of a server and the port to contact.

The realms section defines the realms and the associated DNS zones. The domain_realm section does the reverse: it allows a host to determine its realm based on its fully qualified domain name (FQDN). Finally, the appdefaults section is for the applications using Kerberos; in this case, PAM has been configured with some default options.

In practice, there is little to configure in krb5.conf because the default configuration file has all the required elements. All you have to do is substitute your realm and domain name where appropriate. You can also use your system's Kerberos configuration utility, such as authconfig.

The configuration of PAM is just like the previous configurations of LDAP and smbpasswd. You insert a call to the Kerberos PAM library where appropriate. Listing 21 shows part of the Fedora system-auth file after Kerberos has been configured.

Listing 21. system-auth file after configuring Kerberos
auth        sufficient    pam_unix.so nullok try_first_pass
auth        sufficient    pam_krb5.so use_first_pass
auth        required      pam_deny.so

account     required      pam_unixso broken_shadow
account     [default=bad success=ok user_unknown=ignore] pam_krb5.so
account     required      pam_permit.so

password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    sufficient    pam_krb5.so use_authtok
password    required      pam_deny.so

session     required      pam_unix.so
session     optional      pam_krb5.so

Kerberos has been added directly after the UNIX password check in the authorization phase as a sufficient item. This means that if a UNIX password is found, Kerberos isn't consulted. If no UNIX password is found, then Kerberos is consulted. If Kerberos fails, the stack fails. If no user is found, then control passes to the pam_deny module, which causes a failure.

The account phase uses an alternative syntax to the one you've seen so far. Each PAM module can return different options, such as "success" or "no such user". The square brackets allow the administrator to take a different action based on each possible return code. Listing 21 implements a policy that says if pam_krb5 returns a successful result, then continue processing. If the user is unknown, then ignore the module completely. Anything else is considered a failure. This behavior is close to the required keyword, with the exception that an unknown user doesn't cause a failure. Consult the pam.conf(5) manpage for more details on this syntax, including the options.

The password and session phases include the module in the stack with no special options.

At this point, you should be able to log in to your Linux server using Active Directory credentials. The next step configures Samba and further secures the connection by creating a computer account for the server.

Configure Samba and join the domain

For Samba's configuration, you must first remove your existing password backend from smb.conf, and any of the tdb files in /etc/samba and /var/cache/samba. Listing 22 shows the directives you must add to the [global] section of smb.conf to allow Samba to use AD.

Listing 22. Samba configuration for AD integration
# Active directory security
security = ads
realm = ERTW.COM
use kerberos keytab = yes

# Identity mapping
idmap backend = ad
ldap idmap suffix = dc=ertw,dc=com

# LDAP configuration
ldap admindn = cn=ldap,cn=users,dc=ertw,dc=com
ldap suffix = dc=ertw,dc=com

# Winbind
winbind use default domain = yes
winbind nested groups = yes

Listing 22 starts by specifying that ADS security mode is used (remote Active Directory server), along with the Kerberos realm. The second section configures idmapping, which is a feature that maps remote Microsoft SIDs to local UNIX ids. This configuration specifies that Active Directory is the source of the information. The mapping is taken care of on the Microsoft side, because you've already entered the IDs in the UNIX Attributes tab of the users and groups. Your server just has to pull this information from LDAP.

The LDAP configuration is familiar; it sets the DN for the LDAP connection to the ldap user created earlier. Note that the container is cn=users instead of the ou=people that has been used so far. The password is entered through smbpasswd.

The last two lines enable Winbind, which is an implementation of some of the Microsoft Remote Procedure Calls (see Resources for more information on Winbind). It lets you get more information out of your Active Directory server, rather than only the groups and users for which you've added UNIX attributes.

After smb.conf is configured, start the Samba and winbind services.

The final steps in the Samba configuration are to set the admindn password and to join your domain. Listing 23 shows the computer joining the domain.

Listing 23. Setting the admindn password and joining the domain
[root@server1 ~]# smbpasswd -W
Setting stored password for "cn=ldap,cn=users,dc=ertw,dc=com" in secrets.tdb
New SMB password: ldap
Retype new SMB password: ldap

[root@server1 ~]# net ads join -U administrator
administrator's password: mypassword
Using short domain name -- ERTW0
Joined 'SERVER1' to realm 'ERTW.COM'

Test it out

You should be able to log in to your server with Active Directory credentials and browse file shares from a remote computer without having to log in. Some helpful commands to test are:

  • net ads testjoin: Tests the computer account
  • wbinfo -u: Shows a list of Active Directory users and tests winbind
  • klist: After you log in through Kerberos, shows your TGT and any service tickets that have been issued
  • smbclient -k -L '\\SERVERNAME': Shows a list of shares from SERVERNAME, using a Kerberos login

Integrate LDAP with e-mail services

This section covers material for topic 305.6 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

In this section, learn how to:

  • Plan LDAP schema structure for e-mail services
  • Create e-mail attributes in LDAP
  • Integrate Postfix with LDAP
  • Integrate sendmail with LDAP

sendmail and Postfix are two of the more popular mail transport agents (MTAs) in use. The job of the MTA is to receive messages from the systems and send them to be delivered to the end user or to the next hop MTA. MTAs also take messages from users and find the remote MTA that is capable of delivering the message.

Both sendmail and Postfix rely on various maps—key/value pairs that are normally held in flat files or hash databases like BDB. This type of lookup is also a good fit for LDAP. The advantages of LDAP are that many hosts can share the same configuration, and that it's easier to develop tools to manage the data in LDAP rather than in flat files that must then be rebuilt into hash tables. The overhead of LDAP versus disk reads should not be that onerous, especially if the LDAP tree is properly indexed.

Configure sendmail

The sendmail MTA is a complex creature, and adding LDAP to the mix only increases the complexity. You can do just about anything with sendmail because it's almost infinitely configurable. The downside is that things that should be simple tend to be more complicated than necessary.

Understand that sendmail is a program that interprets a language often called cf in order to process mail. Cf is a language made for easy parsing by sendmail, not humans. Fortunately, humans can use a language called M4, which has a much simpler syntax, to generate the resulting cf code.

sendmail maps

Many cf operations involve looking up information in maps, which are series of key-value pairs. Each map has a particular purpose, such as the aliases map for mail aliases and the mailertable map for static routing of e-mail. The map is a two-column entity; lookups are performed on the left-hand side (LHS), and the corresponding value from the right-hand side (RHS) is returned.

The concept of a map doesn't translate directly into LDAP. A single-key lookup in a sendmail map may return only one RHS entry (the RHS can have multiple values, but only one instance of the key may exist). sendmail works with this by defining a schema that allows key-value pairs to be stored in LDAP. Furthermore, sendmail translates each map request into an LDAP query filter that is designed to return a set of attributes from a single entry. You can choose to use the sendmail schema, or you can modify the filters to work with the data in your tree.

To get started, add the misc.schema schema (it comes with OpenLDAP) to your server's schema. This implements LDAP-based mail routing. Then, add sendmail.schema from the sendmail distribution, which lets you store maps in LDAP.

Configure LDAP mail routing

Some organizations have multiple mail servers to handle all their users, either because of geographical constraints or for managing capacity on the servers. In this case, a user's mailbox might be on a server called wpgertw.com but the user's e-mail address might be sean@ertw.com. LDAP mail routing allows any sendmail server to receive the message, perform an LDAP lookup, and rewrite the address to the internal version. It's then a simple matter to change the destination server by changing LDAP. In any case, the user's e-mail address stays the same.

The misc.schema implements an Internet draft for LDAP routing. This schema provides the inetLocalMailRecipient objectClass with the following attributes:

  • mailLocalAddress: An attribute that defines someone's e-mail address as it's seen by someone outside the organization
  • mailRoutingAddress: An attribute that defines the internal address of a user, which usually includes the server that holds the user's mailbox
  • mailHost: An attribute that defines the server that handles this user's e-mail

The host information for the user can be held in either mailRoutingAddress or mailHost. For example, a mailRoutingAddress of sean@wpg.ertw.com with a mailHost of mx.ertw.com seems like a contradiction. If the host is set, the mail will be delivered there regardless of the routing address. The address will still be rewritten to the routing address if that attribute exists. In the example of sean@wpg.ertw.com, the address in the envelope will be rewritten to sean@wpg.ertw.com, but the message will be delivered to mx.ertw.com.

Listing 24 shows the M4 code that enables LDAP routing. This should go in /etc/mail/sendmail.mc; then, you must rebuild your sendmail.cf. Usually this means going into /etc/mail/ and running make; or it may mean running m4 sendmail.mc > sendmail.cf.

Listing 24. Enabling LDAP routing in sendmail.mc
define(`confLDAP_DEFAULT_SPEC', `-h localhost -b dc=ertw,dc=com')
FEATURE(`ldap_routing')
LDAPROUTE_DOMAIN(`ertw.com')

The first line sets the default arguments for the internal LDAP client: the host and the search base. The second line enables the LDAP routing feature, and the third enables the ertw.com domain for LDAP routing.

The duplication of the mailLocalAddress attribute from inetLocalMailRecipient and the mail attribute from inetOrgPerson is worth looking at. sendmail lets you override the searches it uses internally by passing extra arguments to the ldap_routing feature. The first argument is the filter used to find the mailHost attribute, and the second is used to find mailRoutingAddress. Therefore, FEATURE(`ldap_routing', `ldap -1 -T<TMPF> -v mailHost -k (&(objectClass=inetLocalMailRecipient)(mail=%0))', `ldap -1 -T<TMPF> -v mailRoutingAddress -k (&(objectClass=inetLocalMailRecipient)(mail=%0))') enables sendmail to use the mail attribute instead of mailLocalAddress. The search filter is specified with the -k switch, and the attribute to return with -v. The rest of the arguments are standard for sendmail.

Configure aliases

sendmail implements LDAP aliases as a series of entries in the LDAP tree, keyed on an attribute called sendmailMTAKey using an objectClass of sendmailMTAAliasObject. You may wish to keep the aliases in their own container. Listing 25 shows the LDIF for a sendmail alias that takes mail for exec@ertw.com and sends it to hair@ertwcom and teeth@ertw.com.

Listing 25. Alias for exec@ertw.com
dn: sendmailMTAKey=execs,ou=aliases,dc=ertw,dc=com
objectClass: sendmailMTAAliasObject
sendmailMTACluster: external
sendmailMTAAliasGrouping: aliases
sendmailMTAKey: execs
sendmailMTAAliasValue: hair@ertwcom
sendmailMTAAliasValue: teeth@ertw.com

The first attribute, sendmailMTACluster, defines the servers that can use this alias. You must also define the cluster name in the sendmail.mc file, such as define(`confLDAP_CLUSTER', `external'). This cluster is used as part of the search filter, so if you forget to define it, your aliases will never be used. The alternative to defining a cluster is to set sendmailMTAHost, which makes the entry apply only to a particular host.

sendmailMTAAliasGrouping must be aliases; this is part of the search filter. The key refers to the name of the alias; finally, you have one or more values that are the targets.

The final step is to configure sendmail to use LDAP for the aliases file with the define(`ALIAS_FILE', `ldap:') M4 directive. In general, anywhere you're asked for a file in sendmail.mc, you can put ldap:, and the map will be referenced in LDAP. The sendmailMTAAliasGrouping then becomes the name of the map.

Configure Postfix

Postfix is designed to be simpler than sendmail but to remain compatible with sendmail. The concept of maps is still around, but instead of fitting the maps into a schema, you must define your own query filters that use your own attributes.

For most maps, you specify the target as ldap:/path/to/config.cf, with config.cf being a configuration file that defines the LDAP server, the query, and the attributes that form the response. For example, the local_recipient_maps directive specifies how Postfix will map e-mail addresses to local accounts. Specify local_recipient_maps = $aliases, ldap:/etc/postfix/localrecipients.cf to first check the aliases database (to come later) and then the regular address attached to a user's entry. Listing 26 shows the contents of localrecipients.cf.

Listing 26. The local recipients LDAP lookup
# LDAP server info
server_host = ldap://localhost
search_base = ou=people,dc=ertw,dc=com

# %s is the e-mail address...
query_filter = mail=%s

# the uid tells the account that gets the delivery
result_attribute = uid

Listing 26 specifies the local LDAP server and the People OU. Postfix consults the search filter and replaces the %s with the e-mail address. Thus, an e-mail for fred@ertw.com will result in a search for (mail=fred@ertw.com) in the People OU. The uid attribute is used to determine the mailbox. To test, you can run postmap -q fred@ertw.com ldap:/etc/postfix/localrecipients.cf, which runs the given e-mail address through the localrecipients.cf configuration file (note that NSS must be configured to return details about the fred account).


Summary

In this tutorial, you learned how to integrate LDAP with your current systems. NSS provides an easy way for core UNIX tools to make use of LDAP by redirecting the standard C library calls to the backend of your choice. PAM is yet another abstraction; it allows you to change the way applications authenticate in a granular fashion as long as the application is PAM aware. PAM also has hooks for account restrictions and password changes. The PAM files live in /etc/pam.d.

Migrating from NIS to LDAP involves planning which databases need to be moved and then running some utilities to extract the data and convert it to LDIF. If you still must support NIS in your environment, PADL has written a NIS server called ypldapd that translates between NIS and LDAP by presenting a NIS interface to applications, and that reads the data from LDAP.

Many applications are PAM aware, which means your migration to LDAP is as simple as changing a few files in /etc/pam.d. Some applications, like Apache, speak LDAP directly. Configuring Apache for LDAP involves using the mod_authnz_ldap module and specifying search filters that help Apache find the users in the tree.

Samba provides Windows services on a UNIX platform. You can configure Samba to use LDAP data or even to use Kerberos data to talk directly to Windows. In the latter case, LDAP is still used for directory information, and Kerberos is used for authentication.

E-mail is a natural fit for LDAP because of its similarity to a phone book. Both sendmail and Postfix allow maps to be served from LDAP.

This concludes the look at directory services for the LPIC 3 exam. The next and final tutorial in the series will focus on monitoring and predicting the performance of your Linux servers.

Resources

Learn

Get products and technologies

  • Firewall Builder simplifies the task of typing in iptables rules with a nice GUI and suite of tools to roll out updates to your firewalls.
  • Download pam_ldap and nss_ldap if your distribution does not include the PADL PAM and NSS LDAP libraries.
  • Download ypldapd if you're going to follow along with the NIS-LDAP gateway demonstration. The license is good for 30 days.
  • Download the LDAP migration tools from PADL's site.
  • Microsoft has developed gssMonger for verifying Kerberos authentication interoperability between Windows and other platforms.
  • OpenLDAP is a great choice for an LDAP server.
  • phpLDAPadmin is a Web-based LDAP administration tool. If the GUI is more your style, Luma is a good one to look at.
  • With IBM trial software, available for download directly from developerWorks, build your next development project on Linux.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Linux on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux, Open source
ArticleID=300208
ArticleTitle=LPI exam 301 prep, Topic 305: Integration and migration
publish-date=04082008