Authentication against Active Directory

Unix servers use the PAM protocol for authentication. This can be configured for local user accounts and passwords or for accessing networked directories like Microsoft Active Directory or LDAP.

LDAP provides a single store for all user information in Microsoft Active Directory (AD) and avoids the replication of such details, and in particular passwords, in more than one place. The Kerberos protocol is used for password management. Using LDAP and Kerberos for authentication against AD is strongly recommended on sites with multiple KCML application servers.

Most PAM based LDAP authenticators will require the use of the standard RFC2307 schema when used to authenticate against an LDAP server such as AD. The default AD schema lacks crucial attributes needed by PAM but Microsoft provide the Windows Services for Unix (SFU) product to extend the schema to bridge this gap. SFU ships with Windows 2003R2 (though it is still an option that needs to be explicitly installed) and is available as a free download for earlier versions of AD. This article assumes you are using Windows 2003R2 with the RFC2307 schema enabled or have installed SFU3.5 on an earlier version of Windows but if you cannot do so then there is still a way to use pure LDAP, with some restrictions, documented here.

Network considerations

Kerberos uses ports tcp/88, tcp/749 and udp/464. LDAP uses tcp/389 and tcp/636.

On the Active Directory server

On at least one DC install the "Server for NIS" option to add the "Unix Attributes" tab to the Users and Groups properties.

Using the AD Management tool make sure there is an Organisational Unit called Groups at the same level as Users under the domain, creating it if necessary. Add a group representing the KCML users and allocate it a GID in the Unix Attributes tab. The tool will autoallocate GIDs in the 10000+ range.

When you add or modify the KCML users you can set UID, GID, default shell and home directory attributes with the new tab. AD should autoallocate unique UIDs starting at 10000. They must not be less than 500. Put the KCML users into the group created earlier so they share a common GID and a home directory which you should create in advance and chgrp to the common GID. The choice of shell is immaterial. All other AD users should not have Unix attributes set thus denying them access to the Unix systems.

Again using the AD Management tool create a special proxy user adbrowse in the Users object container with read-only access for use by PAM to access Users and Groups. On Win2003R2 the Unix attributes are visible by default but if using Windows 2000 AD and SFU 3.5 then the extra Unix attributes will not be readable by the user by default and must be made so with AD management console thus:

  1. Select the Users container
  2. Choose "Delegate Control" from the Action menu
  3. The Delegation of Control Wizard starts, click "Next"
  4. On the following screen, click "Add" to get a list of users groups. Choose the adbrowse user, and click "Add" and "OK"
  5. Back to the screen to select users and groups, click "Next"
  6. You are given the screen to identify the scope of the task you want to delegate. Choose "Only the following objects in folder", check "Group objects", click "Next"
  7. You are given a screen to select the permissions, choose "Property-specific" and the following permissions:
  8. Then click Next
  9. You are given the screen which confirms your configuration, click on "finish" if everything is correct, otherwise, click "Back" to change.
  10. Repeat above steps to delegate user posix attributes to the adbrowse user by choosing "User objects" in 6), and choose the following posix user attributes in 7):

For each Unix server create a user account (not a computer account) for use by the Kerberos service accessing that computer. At the command prompt type:

ktpass -princ host/fqdn@REALM -mapuser account -crypto DES-CBC-MD5 +DesOnly -pass password -ptype KRB5_NT_PRINCIPAL -out filename.keytab

where fqdn is the name of the Unix server with its fully qualified domain name, e.g. apps1.adpdsi.com, REALM is the uppercase Kerberos realm for the AD server, e.g. ADPDSI.COM, password is the password set for the new computer account and filename.keytab is the filename of the keytab that will be generated. Then securely copy the keytab file to the Unix server and rename it /etc/krb5.keytab. It should be publicly readable but writeable only by root. You can check that it installed properly by using klist -k as root

With a Windows 2003R2 AD you can avoid the ktpass step and join the computer to the domain automatically using Samba. See Scott Lowe's article.

On the application servers

On each application server

  1. Ensure you have PAM, pam_krb5, nss_ldap, OpenLDAP, Samba and Kerberos installed.
  2. Verify that the the AD servers and application servers have synchronised times. Enable NTP if necessary
  3. In /etc/hosts make sure the servers own IP and fully qualified domain name are defined. Ensure the AD server name is defined here or in the DNS.
  4. On RedHat run /usr/sbin/authconfig, /usr/sbin/authconfig-tui for curses text mode, or the GUI equivalent on the authentication menu. Tick LDAP for user information and Kerberos for authentication:
                              +-------------¦ Authentication Configuration +-------------+
                              ¦                                                          ¦
                              ¦  User Information        Authentication                  ¦
                              ¦  [*] Cache Information   [*] Use MD5 Passwords           ¦
                              ¦  [ ] Use Hesiod          [*] Use Shadow Passwords        ¦
                              ¦  [*] Use LDAP            [ ] Use LDAP Authentication     ¦
                              ¦  [ ] Use NIS             [*] Use Kerberos                ¦
                              ¦  [ ] Use Winbind         [ ] Use SMB Authentication      ¦
                              ¦                          [ ] Use Winbind Authentication  ¦
                              ¦                                                          ¦
                              ¦          +--------+                   +------+           ¦
                              ¦          ¦ Cancel ¦                   ¦ Next ¦           ¦
                              ¦          +--------+                   +------+           ¦
                              ¦                                                          ¦
                              ¦                                                          ¦
                              +----------------------------------------------------------+

On clicking Next it will ask for details of the LDAP server. Enter the IP address of the AD server and fill in the base DN for accessing Users, usually just the domain DN, e.g.

                                 +-----------------¦ LDAP Settings +-----------------+
                                 ¦                                                   ¦
                                 ¦          [ ] Use TLS                              ¦
                                 ¦  Server: 10.10.10.10_____________________________ ¦
                                 ¦ Base DN: dc=adpdsi,dc=local______________________ ¦
                                 ¦                                                   ¦
                                 ¦         +------+                +------+          ¦
                                 ¦         ¦ Back ¦                ¦ Next ¦          ¦
                                 ¦         +------+                +------+          ¦
                                 ¦                                                   ¦
                                 ¦                                                   ¦
                                 +---------------------------------------------------+

It will then prompt for Kerberos settings. The KDC and Admin server should be set to the host names of the AD server.

                               +-----------------¦ Kerberos Settings +------------------+
                               ¦                                                        ¦
                               ¦        Realm: ADPDSI.COM______________________________ ¦
                               ¦          KDC: kerberos.adpdsi.com:88__________________ ¦
                               ¦ Admin Server: kerberos.adpdsi.com:749_________________ ¦
                               ¦               [ ] Use DNS to resolve hosts to realms   ¦
                               ¦               [ ] Use DNS to locate KDCs for realms    ¦
                               ¦                                                        ¦
                               ¦          +------+                    +----+            ¦
                               ¦          ¦ Back ¦                    ¦ Ok ¦            ¦
                               ¦          +------+                    +----+            ¦
                               ¦                                                        ¦
                               ¦                                                        ¦
                               +--------------------------------------------------------+

The Redhat authconfig tool will write many of the configuration files for you. However check they are consistent with these

Ensure the Unix Kerberos configuration file /etc/krb5.conf looks something like this (shown for a REALM of ADPDSI.COM and a dns domain of adpdsi.com. The AD KDC is host.adpdsi.com. This must be resolvable from the Unix servers.

[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
 
[libdefaults]
default_realm = ADPDSI.COM
dns_lookup_realm = false
dns_lookup_kdc = false
 
[realms]
ADPDSI.COM = {
kdc = host.adpdsi.com:88
admin_server = host.adpdsi.com:749
default_domain = adpdsi.com
}
 
[domain_realm]
.adpdsi.com = ADPDSI.COM
adpdsi.com = ADPDSI.COM
 
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
 
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}

Ensure the LDAP configuration file /etc/ldap.conf looks something like this. Replace the IP 10.10.10.10 with the IP address of the AD server and set the binddn and bindpw attributes to the user and password we set up for read-only access to the directory.

host 10.10.10.10
base dc=adpdsi,dc=com
# browse user/password
binddn cn=adbrowse,cn=Users,dc=adpdsi,dc=com
bindpw secret
#use this to limit access to members of a particular group
#pam_groupdn cn=k8users,ou=Groups,dc=adpdsi,dc=com
scope sub
ssl no
pam_password md5
# map directory attributes to NIS names
nss_map_objectclass posixAccount user
nss_map_objectclass shadowAccount user
nss_map_objectclass posixGroup group
# use these mappings for Win2000/Win2003R1 and SFU 3.5
nss_base_passwd dc=adpdsi,dc=com
nss_base_shadow dc=adpdsi,dc=com
nss_base_group dc=adpdsi,dc=com
nss_map_attribute uid sAMAccountName
nss_map_attribute uidNumber msSFU30UidNumber
nss_map_attribute gidNumber msSFU30GidNumber
nss_map_attribute loginShell msSFU30LoginShell
nss_map_attribute gecos name
nss_map_attribute userPassword msSFU30Password
nss_map_attribute homeDirectory msSFU30HomeDirectory
nss_map_attribute uniqueMember msSFU30PosixMember
nss_map_attribute cn cn
# use these RFC2307 mappings for Win2003R2
#nss_base_passwd dc=adpdsi,dc=com?sub
#nss_base_shadow dc=adpdsi,dc=com?sub
#nss_base_group dc=adpdsi,dc=com?sub?&(objectCategory=group)(gidnumber=*)
#nss_map_attribute gecos cn
#nss_map_attribute homeDirectory unixHomeDirectory
#nss_map_attribute uniqueMember member

In the /etc/nsswitch.conf file ensure that these three attributes have these values so that lookups on users will first check the local files then use LDAP.

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

In Redhat Linux a common PAM configuration file, /etc/pam.d/system-auth, is written by the authconfig tool and referenced by most PAM configurations, in particular the one used by the KCML connection manager (either kcc or kcml, connection manager gets the name of the PAM configuration file from the service name used to start it in xinetd). The system-auth file should look something like this:

auth        required      /lib/security/$ISA/pam_env.so
auth        sufficient    /lib/security/$ISA/pam_unix.so likeauth nullok debug
auth        sufficient    /lib/security/$ISA/pam_krb5.so use_first_pass debug
auth        required      /lib/security/$ISA/pam_deny.so
account     required      /lib/security/$ISA/pam_unix.so broken_shadow debug
account     sufficient    /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet
account     [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_krb5.so debug
account     required      /lib/security/$ISA/pam_permit.so
password    requisite     /lib/security/$ISA/pam_cracklib.so retry=3
password    sufficient    /lib/security/$ISA/pam_unix.so nullok use_authtok md5 shadow
password    sufficient    /lib/security/$ISA/pam_krb5.so use_authtok
password    required      /lib/security/$ISA/pam_deny.so
session     required      /lib/security/$ISA/pam_limits.so
session     required      /lib/security/$ISA/pam_unix.so
session     optional      /lib/security/$ISA/pam_krb5.so

To verify this setup use kinit to get a Kerberos ticket for a user in the AD e.g.

$ kinit TestUser
Password for [email protected]: 
$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: [email protected]
Valid starting     Expires            Service principal
04/03/08 16:32:38  04/04/08 02:32:49  krbtgt/[email protected]
	renew until 04/04/08 16:32:38
Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached
$ kdestroy
$ 

Check the user is visible over LDAP

$ getent passwd TestUser
TestUser:ABCD!efgh12345$67890:10001:500:TestUser:/home/TestUser:/bin/sh
$

Some versions of getent may not support (and ignore) filtering by user in which case just use getent passwd for them all. As a final check that NSS is working create a temporary file, have it owned by the uid and gid of a network user, and make sure that ls can resolve that user and group e.g.

$ >/tmp/a
$ chown 10001 /tmp/a
$ chgrp 5000 /tmp/a
$ ls -l /tmp/a
-rw-rw-rw-  1 TestUser kccUser 0 Mar 20 12:06 /tmp/a
$ 

Now you should be able to use connection manager to connect to KCML. Check /var/log/messages and /var/log/secure in case of problems.

Single sign on with Active Directory

Using PAM still requires the user to enter a userid and password in the client. It is possible, if the client Windows PC is logged into the AD domain, to have the client use the Windows logon credentials to authenticate and thus avoid the need for a password prompt. This mechanism does not support the LDAP lookup of the users details so the user must exist in the Unix server /etc/password or NIS database in order to be identified on the server.

Configuration for SSO requires that the server be configured for Kerberos v5 as above. You can use the same computer account in AD. Ideally there should be a keytab entry for a HTTP service rather than a host service but reusing an existing host service created for PAM will work too.

ktpass -princ HTTP/fqdn@REALM -mapuser account -crypto DES-CBC-MD5 +DesOnly -pass password -ptype KRB5_NT_PRINCIPAL -out filename.keytab

Install this keytab on the server and verify that it is visible to kerberos using klist -k while running as root.

Connection manager on the server will need to be configured for SSO by adding the -g switch to its command line. This switch is followed by the principal name exactly as entered for the -princ argument to ktpass. e.g. in /etc/inetd.conf

kcml  stream  tcp  nowait  root  /usr/local/kcml/kwebserv   /usr/local/kcml/kwebserv -g HTTP/[email protected]

Remember to restart inetd. When running this way the connection manager will accept only Kerberos or NTLM SSO connections. To avoid fallback to the insecure NTLM protocol use -G rather than -g to force the use of Kerberos.

See Also:

Authentication in the Connection Manager
LDAP authentication
Configuring PAM
Scott Lowe's excellent How-To article for Win2003R2
Scott Lowe's other How-To article for Win2000 and Win2003R1
Scott Lowe's article on SSO over HTTP