From: Subject: Security with LDAP Date: Fri, 7 Feb 2003 10:42:11 +0100 MIME-Version: 1.0 Content-Type: multipart/related; type="text/html"; boundary="----=_NextPart_000_0007_01C2CE95.91CBD9A0" X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 This is a multi-part message in MIME format. ------=_NextPart_000_0007_01C2CE95.91CBD9A0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.skills-1st.co.uk/papers/security-with-ldap-jan-2002/security-with-ldap.html Security with LDAP

Security with LDAP

Andrew Findlay

Skills 1st = Ltd

andrew.findlay@skills-1st.co.uk

Network Information Services

When managing a large number of computers it is = convenient to=20 store configuration data in a central location rather than maintain = separate=20 files on each machine. Thus, DNS quickly replaced large /etc/hostsfiles on the Internet, and a = number of=20 more general nameservices were developed to serve more local needs. = Sun's=20 YP/NIS is probably the best known, but Hesiod[1] does a = similar=20 job and protocol suites such as XNS and NetBIOS also = include=20 nameservices of one sort or another.

The more general nameservices support a number of `maps', = each of=20 which translates from keys to values. A NIS serving Unix machines has = maps such=20 as passwd, group, automount, services, and rpc. Often there are two or = more key=20 fields in a map: the passwd map for example has to service lookups both = by=20 username and by uid. Data is accessed with the same library calls that=20 originally handled local files, so most application programs are not = aware that=20 the underlying storage has changed.

A network using a NIS relies on it completely for normal = operation=20 so maintaining its integrity is vital. Most NIS systems in use today = have very=20 little protection against active attackers: they depend on the IP = address of the=20 server being widely known and assume that nobody has taken over its = address.=20 This is obviously insecure in a world where TCP connections can be = hijacked at a=20 distance, so system designers are turning to cryptography to provide = assurance=20 that good data is being used.

Network Authentication Service

Authenticating users is one of the more visible aspects of = computer=20 security. People are used to providing usernames and passwords when they = want to=20 use a machine or other resource.

One approach to authentication in a network is simply to = use the NIS=20 to access conventional Unix password hashes and to do the validation = locally on=20 the desktop machine. This scheme is commonly used with YP/NIS but = it=20 suffers from having to make all password hashes available to all desktop = machines. There are shadow-password schemes that prevent `ordinary' = users from=20 getting hold of the hash data, but these are fairly easy to bypass when = used=20 with a NIS. With access to a collection of password hashes, a cracker = can mount=20 a dictionary attack with a good chance of success so it would be better = to keep=20 the hashes away from client machines entirely.

Another approach is to use a special-purpose = authentication protocol=20 such as RADIUS or TACACS+. These were originally developed to control = access to=20 modem banks, but are equally usable with desktop computers. Kerberos is = another=20 way to do authentication without exposing secrets: this also has the = benefit of=20 providing a complete single-sign-on environment if it is fully = implemented.=20 Several other protocols have been pressed into service for = authentication over=20 the years: SMB allows authentication against an NT domain, and I have = even heard=20 of POP being used in this way! It comes as no surprise to find that LDAP = is now=20 used an authentication protocol as well.

Ideally, a network authentication service should provide = reliable=20 answers, be fast, and should work without exposing any information about = the=20 password. This is harder than it first looks, as the client does not = want to=20 expose the password to the server in case the server turns out to be=20 compromised. Similarly, the server should not expose any hash data to = the=20 client. Network snoopers should not be able to gather any data that can = be=20 replayed later to gain unauthorised access. Each protocol tackles these = problems=20 in different ways, with varying degrees of success. LDAP has a number of = authentication and security options which can provide very good security = if used=20 correctly, though as ever there is a trade-off between security and ease = of=20 management.

LDAP Basics

LDAP[6] is a directory-access protocol derived from X.500. = It works=20 with a tree structure where each node or object in the tree contains a = set of=20 attribute-value data. Each object belongs to one or more objectclasses, = which=20 define the mandatory and optional attributes. The original application = of both=20 X.500 and LDAP was to provide a `white pages' directory service, where = most=20 objects in the tree represented people and the tree had a geographic or=20 organisational structure.

Storing NIS Data in an LDAP Directory

RFC2307[2] describes a schema for storing NIS data in an = LDAP=20 directory. Mappings are provided for all the common databases: passwd, = group,=20 hosts, shadow, services, netgroup, protocol, ethers etc. The RFC = describes=20 objectclasses and attributes, but does not mandate a particular tree = structure.=20 A common practice is to use a structure like this:

3D"Diagram

Here, domain-component naming is used to match the domain = name=20 example.org and separate subtrees are provided for each type of=20 information. Data from the passwd file goes into ou=3DPeople rather than = ou=3Dpasswd=20 because it is assumed that each person has one primary account and that = other=20 information will be added to the same entry (phone number, e-mail = address=20 etc).

Passwd data

Typical data in an account entry looks like = this:

dn: uid=3Dandrew,ou=3DPeople,dc=3Dexample,dc=3Dorg
uid: andrew
cn: Andrew Findlay
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
shadowLastChange: 11296
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 500
gidNumber: 500
homeDirectory: /home/andrew
gecos: Andrew Findlay
userPassword: {crypt}$1$uQSw.ohy$XuiRSCq0kp...

The first line sets the Distinguished Name - the unique = name=20 identifying this entry in the tree. uid is used as the naming = attribute:=20 this refers to the User ID that we would normally call `username' in a = Unix=20 context. There is one aspect of uid to be particularly aware of: = it is=20 matched in a case-insensitive way so it is not possible to represent = distinct=20 accounts `fred' and `FRED'.

Notice that the uid attribute occurs again inside = the entry,=20 along with uidNumber and gidNumber: there must be exactly = one of=20 each of these attributes and they are used when resolving calls to=20 getpwnam() etc.

The full name of the account owner appears twice: first as = cn=20 (Common Name) which is an attribute that can take multiple values and is = much=20 used by white-pages lookups. The extra copy in the gecos = attribute allows=20 control over the exact string returned to getpwnam() calls.

The objectClass attributes refer to aspects = of the=20 RFC2307 schema. They set the list of mandatory and optional attributes = for the=20 entry, and are also useful in searches. A call of the form=20 getpwnam("andrew") is likely to result in an LDAP search of the=20 form (uid=3Dandrew) AND = (objectClass=3DposixAccount)

Group data

As we have seen, data from passwd and shadow files maps = line-by-line=20 into the account entry. Data from the group file is handled in a similar = way. A=20 conventional Unix group file has one group per line, with every group = member=20 listed:

ldapbods:x:389:tim,steve,colin,damy,andrew

This is convenient for seeing who is in a group, but = extremely=20 inefficient for the most common operation: listing the groups that a = particular=20 user is a member of at login time. The usual algorithm is to enumerate = every=20 entry in the group map looking for occurrences of the username.

RFC2307 defines group membership using the = memberUid=20 attribute in a posixGroup object. Because memberUid is a=20 multi-valued attribute, the group map can now be searched very = efficiently. The=20 example group entry above would look like this in the = directory:

dn: cn=3Dldapbods,ou=3DGroup,dc=3Dexample,dc=3Dorg
objectClass: posixGroup
objectClass: top
cn: ldapbods
userPassword: {crypt}x
gidNumber: 389
memberUid: tim
memberUid: steve
memberUid: colin
memberUid: damy
memberUid: andrew

Now, to find the list of groups that a user belongs to, = the search=20 is of the form:

(objectClass=3DposixGroup) AND = (memberUid=3Dandrew)

The LDAP server can be configured with indexes on any = attribute, so=20 searches of this form can be made very efficient and large databases can = be=20 handled without performance penalties.

Putting it all together

So much for the theory, but how much of this actually = works? To find=20 out, I built a testbed on a portable PC running Red Hat 7.1 and = supporting=20 several VMware virtual machines with diverse operating systems. I also = connected=20 a Sun Ultra 5 running Solaris 8.

The LDAP server was slapd from OpenLDAP = 2.0.18 (a=20 security advisory has since been issued requiring upgrade to 2.0.21). = The config=20 file is shown in Appendix 1. slapd sends logging data to syslog, and it = is a=20 good idea to separate this into a file of its own with a line like this=20 in /etc/syslog.conf:

local4.* /var/log/slapd.log

I find it convenient to keep a wide window on screen = running=20 'tail -f' on the = logfile while=20 testing.

To create the initial data I used the migration = tools from=20 PADL software. These are often included with Linux distributions, but it = is=20 worth fetching the latest version from www.padl.com The tools need very = little=20 configuration, and will load data from existing files in /etcinto the LDAP directory. Note that = the tools=20 create the container entries ou=3DPeople etc but they do not = create the=20 top-level entry (dc=3Dexample,dc=3Dorg in this case) so it must = be created by=20 hand before the tools will run. To do this, create a file of the=20 form:

dn: dc=3Dexample,dc=3Dorg
objectClass: dcObject
objectClass: organization
o: The Example Organisation
dc: example

and load it with a command like this:

ldapmodify =
-a -H ldap://localhost/ -r -c -x \
	-D 'cn=3DManager,dc=3Dexample,dc=3Dorg' -W \
	-f <filename>

At this stage, the LDAP server can be tested with = command-line tools=20 such as ldapsearch. Once it is working it is possible to = configure=20 systems to use it as a NIS.

The Name Service Switch and nss_ldap

NSS is a facility found in Solaris and Linux which allows = new=20 name-resolution code to be installed as shared objects without having to = rebuild=20 existing libraries. Some versions of FreeBSD and AIX have a similar = concept=20 called the Information Retrieval System, apparently derived from BIND 8=20 code.

In principle you can install a new name-resolution system = just by=20 placing a shared library in the right directory and editing = /etc/nsswitch.conf.=20 Solaris and many Linux distributions come with LDAP modules for NSS, = though they=20 are often derived from fairly old code and you may need to fetch the = latest=20 version from www.padl.com if you want all the security features.

I tested nss_ldap on a virtual machine with a small = Red=20 Hat 7.2 installation. The first thing to do is to configure the = LDAP=20 parameters in /etc/ldap.conf:

# =
ldap.conf
#
# Location of LDAP server.
# Must be resolvable without using LDAP!
#
host brick.skills-1st.co.uk
#
# The distinguished name of the search base.
#
base dc=3Dexample,dc=3Dorg
#

This simple config is enough to get things going, though = we will=20 return to add more security later.

To make the machine use LDAP for passwd and group = lookups,=20 edit /etc/nsswitch.confand = change lines=20 as shown:

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

The effect of this is that lookups will use local files = first and=20 progress to LDAP for anything not found locally. This allows for system = accounts=20 to be kept in /etc files (necessary during bootup) while user accounts = are held=20 centrally.

If the name service cache daemon (nscd) is running, it may = be=20 necessary to restart it before LDAP lookups work. Similarly, = nsswitch.conf is=20 normally only read once per process so don't expect any existing = processes to=20 notice until they are restarted (and that includes the shell that you = used to=20 set all this up from!)

An easy test is to find the home-directory of a user that = is listed=20 in the LDAP store but not in the local password file:

echo ~fred

The Solaris version of nss_ldap is based on the iPlanet = LDAP=20 libraries and it does not use /etc/ldap.conf, preferring instead to use = a=20 program called ldapclient to set up the parameters. The problem = with=20 ldapclient is that it depends on a feature that is implemented=20 differently in different LDAP servers so it does not easily work with = OpenLDAP.=20 There are a number of mailing-list archives containing discussion of the = problem=20 and suggesting various workarounds, though I have not yet made it work=20 myself.

FreeBSD is supposed to be able to use the PADL nss_ldap = code, but it=20 requires a rebuild of at least the main C library to make it work. = Again, I have=20 not had time to test this, but in principle it should work with the same = data=20 that supports Linux.

Authentication with pam_ldap

The usual way of using LDAP for user authentication is to = locate the=20 account entry in the directory and then try to `bind' to the directory = as that=20 account, presenting the password or other credentials as received from = the user.=20 In the simplest case, the password is presented to the directory server = in=20 clear, but there are a number of more secure schemes.

Most Unix-like systems now implement Pluggable = Authentication=20 Modules (PAMs) of some form. This allows authentication methods to be = changed=20 easily without having to re-compile every program that might need to = check a=20 password. PAMs can also implement policy such as time-of-day = restrictions and=20 other security requirements. A particularly powerful feature is that = PAMs can be=20 stacked, allowing for a choice of authentication methods and perhaps = several=20 different policy modules to be active as well. As with NSS, PAM is = implemented=20 with shared libraries so re-configuration is quite easy.

Red Hat, SuSE, Mandrake, and FreeBSD all provide pam_ldap = modules=20 derived from the PADL code. Solaris includes a module based on iPlanet = code,=20 though it is quite possible to replace this with the PADL version if = required.=20 In all cases, configuration is shared with the equivalent NSS module so = little=20 extra work is required.

To use LDAP for authentication is a matter of = installing the=20 pam_ldap module and editing the appropriate PAM config: either = /etc/pam.confor one or more files = in /etc/pam.d. Look for the line = describing pam_unix=20 and add pam_ldap at that point. On Red Hat Linux the file is /etc/pam.d/system-authand it looks like = this:

auth required /lib/security/pam_env.so
auth sufficient /lib/security/pam_unix.so likeauth nullok
auth sufficient /lib/security/pam_ldap.so use_first_pass
auth required /lib/security/pam_deny.so
account required /lib/security/pam_unix.so
account required /lib/security/pam_ldap.so
password required /lib/security/pam_cracklib.so \
retry=3D3 type=3D
password sufficient /lib/security/pam_unix.so nullok \
use_authtok md5 shadow
password sufficient /lib/security/pam_ldap.so use_authtok
password required /lib/security/pam_deny.so
session required /lib/security/pam_limits.so
session required /lib/security/pam_unix.so
session optional /lib/security/pam_ldap.so

Note that you should not edit the file directly on Red Hat = Linux:=20 use the authconfig program to maintain it.

Note also that the example config files supplied with=20 thepam_ldap source code might give LDAP more control than you = want,=20 including the ability to supply an alternate password for = root.

Solaris uses /etc/pam.conf so the format is slightly = different. Here=20 is a snippet describing the authentication requirements for = rlogin:

rlogin auth sufficient \
		 /usr/lib/security/$ISA/pam_ldap.so.1
rlogin auth sufficient \
		/usr/lib/security/$ISA/pam_rhosts_auth.so.1
rlogin auth required \
		/usr/lib/security/$ISA/pam_unix.so.1

Note the $ISA variable: this is the Instruction Set = Architecture,=20 which allows for 32-bit and 64-bit programs to co-exist. Strictly this = means=20 that if you replace any PAM modules you should provide both 32-bit and = 64-bit=20 versions but so far I have not found any 64-bit programs using = authentication=20 This will probably change...

FreeBSD also uses /etc/pam.conf but has a slightly = different layout.=20 Here is part of the section for login (and thus rlogin = too):

login auth sufficient pam_skey.so
login auth requisite pam_cleartext_pass_ok.so
login auth sufficient /usr/local/lib/pam_ldap.so \
try_first_pass
login auth required pam_unix.so try_first_pass

Where a PAM password clause has been defined (as in the = Red Hat=20 example above), pam_ldap supports changing passwords using LDAP so the = user need=20 never know that LDAP is being used rather than local files.

With both nss_ldap and pam_ldap in place on client = machines, all=20 user-management can be done through the directory.

Now add Windows: SAMBA PDC

Samba has had the ability to act as an NT-style Primary = Domain=20 Controller for some time. Recent releases have added a facility to store = the PDC=20 SAM data in an LDAP directory. This is clearly marked as experimental = code in=20 Samba 2.2.2 though the Samba-TNG project claims to be more advanced in = this=20 area. The two versions have different approaches: mainstream Samba aims = to=20 provide Windows-Unix integration, where Samba-TNG aims for a complete = PDC=20 implementation that just happens to run on Unix rather than Windows.

If Samba is installed on a machine using nss_ldap = and=20 pam_ldap it will of course use them, so networks running SMB with = cleartext passwords may not need to do more than that. There are = advantages to=20 the PDC model though, so Samba's move to closer integration with LDAP is = particularly welcome.

To enable LDAP storage for the PDC, Samba must be = configured with=20 the ­­with­ldapsam option. This completely overrides local = storage=20 of SAM data so you cannot use the same binary in both modes.

The LDAP-specific parts of the Samba config file look like = this:

ldap admin dn =3D cn=3Dmanager,dc=3Dexample,dc=3Dorg
ldap server =3D brick.skills-1st.co.uk
ldap suffix =3D dc=3Dexample,dc=3Dorg

A minimal Samba PDC config is shown in Appendix 2.

Note that the LDAP suffix given here matches the search = base used by=20 nss_ldap and pam_ldap. This allows Samba to share the entries that = already exist=20 to describe people/accounts. Note also that the admin DN is given: in = this case=20 I have used the name of the DSA manager (equivalent to root in directory = terms),=20 but it should be possible to use a less powerful ID if ACLs are set up=20 carefully. Samba needs to bind to the directory as a user with write = permission=20 so that it can insert new attributes in entries. The password is stored = in the=20 secrets database using the command:

smbpasswd -w <password>

Unfortunately, the password has to be typed on the command = line so=20 make sure you clear out any command-history files afterwards!

Samba introduces several new attributes, so it's = schema file=20 must be copied from samba-2.2.2/examples/LDAP/samba.schemato the server=20 schema directory and an appropriate include statement has to be added to = slapd.conf. The schema file supplied tries to re-define=20 displayName so this clause must be commented out before = restarting the=20 server.

Samba needs to set up two new password hashes and several = other=20 attributes for each user. The password hashes cannot be derived from the = Unix=20 password data, so be prepared to supply new passwords for each user:

smbpasswd -a <username>

Unfortunately, this is where the experimental nature of = the code=20 starts to show through. Some of the attributes get bad values: in = particular,=20 rid gets set to zero, and both smbHome and = profilePath get=20 values including %-expansions that are not properly handled when the = data is=20 used. These need to be fixed by hand: I used ldapsearch to = extract the=20 complete attribute set into a file for editing, and ldapmodify to = put the=20 updated values back.

Before a Windows client can join a domain, it needs a = `trust=20 account' to be set up on the PDC. With the appropriate scripts = configured on=20 Samba, this can be largely automated but for test purposes I created = Unix-style=20 accounts by hand. These have usernames formed by appending `$' to the = Windows=20 `computername', and are made ready for use with the command:

smbpasswd -a -m <computername>

With these preparations done, I was able to join an NT = client to my=20 domain and log in using the same username and password used with the = Unix=20 clients.

There is obviously some work still needed on the LDAP PDC = code, but=20 once stable there are some interesting possibilities. One option would = be to do=20 away with backup domain controllers altogether, and support distribution = and=20 resilience by having replicated LDAP servers each serving the same data = to one=20 or more Samba PDCs. I have yet to work out the exact effect of moving a = Windows=20 client from one such domain controller to another.

Looking at the problem the other way round, it should be = possible to=20 run nss_ldap and pam_ldap against an Active Directory = system. The=20 sample /etc/ldap.conf shipped with the PADL code includes an example=20 configuration for this purpose, though I have not tried it.

Security

With such a concentration of data in the directory, = security becomes=20 very important[3]. Anyone who could modify the data could give = themselves access=20 to vast numbers of machines at a stroke. Some data needs to be protected = from=20 unauthorised viewing: although all passwords are hashed, anyone who can = read the=20 hashes can mount a dictionary attack. More subtly, anyone who can hijack = a=20 client-server connection can feed bogus data to an individual client, or = use the=20 client's privileges to modify server data. All these things can be = protected=20 against, and LDAP now has most of the tools needed to do it.

Access Control

Control over who may read what and who may change what is = exercised=20 with Access Control Lists (ACLs). This is one of the non-standardised = areas of=20 LDAP, and it varies a lot from one server to another. However, all = modern=20 servers provide enough control to protect passwords. Here is a simple = ACL=20 section from OpenLDAP:

access to attrs=3DuserPassword
by self write
by anonymous auth
by * none
access to *
by * read

This allows authenticated users to change their own = passwords,=20 allows un-authenticated users to authenticate, and prevents all other = access to=20 the userPassword. It permits read access to everything else. = Obviously if=20 Samba PDC data is being stored then similar protection must be extended = to=20 lmPassword and ntPassword.

Client Authentication

The simplest form of client authentication is to bind to = the server=20 using a cleartext password. This is the method normally used by = pam_ldap=20 for checking login passwords. For security, this method should only be = used with=20 encrypted connections.

A more secure method is to use one of the SASL = authentication=20 mechanisms, such as DIGEST-MD5[4]. This is based on a secret known to = both the=20 client and the server, allowing for a simple challenge-response scheme. = SASL is=20 also capable of negotiating data encryption to protect subsequent=20 operations.

LDAP also supports encryption and authentication using = Transport=20 Layer Security[5]. TLS is closely related to the older SSL scheme, and = uses the=20 same certificate-based methods. In its simplest form, TLS provides proof = of=20 server identity and protection of data in transit so it is useful where=20 plaintext passwords might be passed across the net. The same mechanism = can also=20 be used to prove the identity of the client to the server, where the = client has=20 been issued with a suitable X.509 certificate.

It is often more appropriate (and cheaper) to use a = private=20 Certification Authority for this purpose rather than getting = certificates from a=20 public supplier. This is easy to set up using OpenSSL:

openssl =
genrsa -des3 -out ca.key 2048
openssl req -new -x509 -days 365 -key ca.key -out ca.cert

You will be prompted to supply some information. The = result of the=20 commands above will be two files: a key file and a certificate file. = These are=20 the basis of the Certification Authority.

openssl genrsa -out =
ldap.key 1024
openssl req -new -key ldap.key -out ldap.csr

You will again be asked for information to fill in the = Certificate=20 Signing Request. The critical item is to put the LDAP server name in = when=20 prompted for `Common Name'. This should be the exact name that = clients=20 will use when contacting the server. It is best to use a fully-qualified = domain=20 name. Note that the ldap.key file is not encrypted as it must be = read by=20 the LDAP server: protect this file very carefully! Use the CA to sign = the=20 certificate:

openssl x509 -req -in ldap.csr -out ldap.cert -CA =
ca.cert \
	-CAkey ca.key -CAcreateserial -days 365

The result is a file called ldap.cert containing = the=20 certificate for the LDAP server. You can examine certificates with the=20 command:

openssl x509 -in ldap.cert -text -noout

The LDAP server needs copies of its own certificate and = key files,=20 and also a copy of the CA certificate. The key file must only be = readable by the=20 server process, so make it mode 400 and owned by the owner of the server = (OpenLDAP can be run as root, or can be told to set UID to another user = after=20 binding the TCP ports). Add lines to slapd.conf to tell the = server about=20 the new files:

TLSCertificateFile /etc/openldap/keys/server.cert
TLSCertificateKeyFile /etc/openldap/keys/server.key
TLSCACertificateFile /etc/openldap/keys/ca.cert

When the server is next restarted it will be able to = use TLS.=20 It will also support SSL if told to bind to an ldaps:///URL. To make nss_ldap = and=20 pam_ldap use TLS, add a line to /etc/ldap.conf on the client=20 machines:

ssl start_tls

This provides transport-level encryption of LDAP sessions, = thus=20 giving some protection to passwords etc. However, it does not guard = against=20 bogus servers: to get this extra protection it is necessary to give the = client=20 machines a copy of the CA certificate that was used to sign the server=20 certificate. Recent versions of nss_ldap and pam_ldap will = verify=20 the server identity if lines of this form are added to = /etc/ldap.conf:

tls_checkpeer yes
tls_cacertfile /etc/ssl/ca.cert

Now, if a bogus server is encountered the client will = immediately=20 close the LDAP connection and deny the attempted login. Note that the = reason for=20 the denied login can be hard to find in the client logfiles: it may be = necessary=20 to turn on a high level of debugging to see the relevant message! Note = also that=20 certificate verification is a fairly recent addition to nss_ldap = and=20 pam_ldap so the versions shipped with most OS distributions do = not yet=20 have it.

Samba-2.2.2 has the option to use TLS when accessing LDAP, = though it=20 does not yet have code to check server certificates. To enable TLS add = this to=20 the global section of the config file:

ldap ssl =3D start tls

Other nameservice clients like Automount and AMD do not = yet have the=20 ability to use TLS at all, so unfortunately there are still chinks in = the=20 armour.

Management Tools

This area is still rather lacking. The PADL migration = tools are good=20 for converting and loading the initial data, but once LDAP is in use as = the=20 nameservice you will need other tools to create and manage accounts etc. = Scripts=20 can be built around ldapsearch and ldapmodify from the = OpenLDAP=20 distribution, or around one of the Perl modules that support LDAP. = Another=20 useful tool is GQ - a general-purpose LDAP browser/modifier.

There is at least one project under way to develop = specific=20 management tools for LDAP NIS systems. ldaputils is based at = SourceForge=20 and eventually plans to have a web-based management interface.

Performance

An LDAP server providing NIS service is likely to handle = much more=20 traffic than one just servicing `white pages' requests so performance is = an=20 important consideration in a large network. When sizing servers it is = necessary=20 to know how much traffic to expect: Table 1 summarises the results of = some=20 simple tests with both pam_ldap and nss_ldap = configured.

More recent versions of nss_ldap make much more = efficient use=20 of the server than the older ones. The use of a cache daemon also helps, = though=20 it does result in one more long-lived LDAP connection per client = machine.

An LDAP server with logging turned off should not have any = difficulty in servicing 500 searches per second, but if TLS is in use = the cost=20 of connection setup and binding is likely to far outweigh the search = load. A=20 large pool of clients will also result in many hundreds of connections = being=20 held open, so the server and its supporting operating system must be = configured=20 to support a sufficient number of open files.

LDAP servers can be configured to replicate data from a = master=20 server, so the read-only query load can be spread across as many = machines as=20 necessary. Operations (like password changing) that result in changes to = the=20 database get referred back to the master server. The format of = /etc/ldap.conf=20 supports multiple servers in the form of a space-separated list, and the = servers=20 are tried in turn until one answers or the list is exhausted.

Client & Operation

Connect

Bind

Search

Connections Held Open

Per session

Red Hat 7.1 login

8

8

13*

Red Hat 7.1 login with nscd

5

5

3

1=A4

Samba connect (not PDC)

5

5

19

1

Samba connect with nscd (not PDC)

6

6

8

1=A4

Samba connect with PDC and nscd

2

2

5

0=A4

Red Hat 7.2 login with nscd

2

4

6

1=A4

* Two of these try to return every entry from = the Group=20 table

=A4 Plus one connection per client machine for = nscd

Table 1: LDAP load imposed by=20 clients

Conclusions

It is quite possible to use LDAP as a Network Information = Service,=20 though at the moment it is not quite an `out of the box and into = production'=20 product. There is potential for much greater security than most other = forms of=20 NIS, and with a bit of planning it should provide good performance = too.

References

1. The Hesiod Name Server, Stephen P Dyer, Project = Athena,=20 Proceedings of the USENIX Winter 1988 Technical Conference=20 www.mit.edu/afs/athena.mit.edu/astaff/project/hesioddev/hesiod.dist/doc/h= esiod.PS

2. RFC2307 An Approach for Using LDAP as a Network = Information=20 Service, L Howard. Work is under way to update the RFC:=20 http://www.padl.com/~lukeh/rfc2307bis.txt

3. RFC2829 Authentication Methods for LDAP

4. RFC2222 Simple Authentication and Security Layer.

5. RFC2830 Lightweight Directory Access Protocol (v3): = Extension for=20 Transport Layer Security

6. RFC2251 Lightweight Directory Access Protocol (v3)

Sources

OpenLDAP

www.openldap.org

OpenSSL

www.openssl.org

Cyrus SASL

asg.web.cmu.edu/cyrus/

Berkeley DB

www.sleepycat.com

NSS LDAP
PAM LDAP
Migration tools

www.padl.com/software.html

GQ

biot.com/gq/

LDAPutils

sourceforge.net/projects/ldaputils/

This paper and others by Andrew Findlay

www.skills­1st.co.uk/papers/afindlay.html

Appendix 1: slapd.conf

# slapd.conf

# Log level is a bitfield. 768 provides
# reasonable activity logging
# Logging goes to syslog with facility code
# LOCAL4
loglevel 768

include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/java.schema
include /usr/local/etc/openldap/schema/krb5-kdc.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/nadf.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/openldap.schema
include /usr/local/etc/openldap/schema/corba.schema
include /usr/local/etc/openldap/schema/samba.schema

pidfile /usr/local/var/slapd.pid
argsfile /usr/local/var/slapd.args

# How we want passwords stored
password-hash {SSHA}

# Define SSL and TLS properties (optional)
TLSCertificateFile /etc/openldap/keys/server.cert
TLSCertificateKeyFile /etc/openldap/keys/server.key
TLSCACertificateFile /etc/openldap/keys/ca.cert

# Define SASL properties (optional)
sasl-realm green
sasl-host brick.skills-1st.co.uk
sasl-secprops minssf=3D112

########################################################
# database definition
########################################################
database ldbm

suffix "dc=3Dexample,dc=3Dorg"
rootdn "cn=3DManager,dc=3Dexample,dc=3Dorg"

# Cleartext passwords, especially for the rootdn, should
# be avoided
# See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication is encouraged.
rootpw secret

# The database directory MUST exist prior to running slapd
# AND should only be accessible by the slapd/tools.
# Mode 700 is recommended.
directory /usr/local/var/openldap-ldbm

# Indices to maintain
index uid eq
index uidNumber eq
index gidNumber eq
index cn eq
index memberUid eq
index ipServicePort eq

# Access Control
# Users can change their own passwords
# Everyone can read everything except passwords
access to attrs=3DuserPassword
	by self write
	by anonymous auth
	by * none
access to *
	by * read

###########################################################
# end of slapd.conf
###########################################################

Appendix 2: Samba config

[global]
	netbios name =3D vm15
	workgroup =3D S2
	encrypt passwords =3D Yes
	preferred master =3D Yes
	wins support =3D Yes
	log level =3D 1

	# Make this a PDC
	domain logons =3D Yes
	os level =3D 34
	local master =3D yes
	domain master =3D yes

	# LDAP params
	ldap admin dn =3D cn=3Dmanager,dc=3Dexample,dc=3Dorg
	ldap server =3D brick.skills-1st.co.uk
	ldap suffix =3D dc=3Dexample,dc=3Dorg
	ldap ssl =3D start tls

# Required share on PDC
[netlogon]
	comment =3D Domain logon service
	path =3D /var/samba/netlogon
	public =3D no
	writeable =3D no
	browsable =3D no

# Profile store for NT/2k
[profile]
	path =3D /var/samba/profile
	create mask =3D 0600
	directory mask =3D 0700
	nt acl support =3D no
	read only =3D no

[homes]
	guest ok =3D no
	read only =3D no
------=_NextPart_000_0007_01C2CE95.91CBD9A0 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.skills-1st.co.uk/papers/security-with-ldap-jan-2002/security-with-ldap.gif R0lGODlhYgGRAOcAAAAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAABiAZEA QAj+AAMIHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKE8CADBwJUuB K1u+XBgT5kyXBGvaTMmzp8+fQIP61Cm0qNGjSJNCxKm0qdOnUKPSJCq1qtWrWKliTah1q9evVnUy DSCWpcuzOcvuJDuTrcy3a93KvPmy5tiuYPPq3cu3r9+/fscCHky4sEnBhhMrXlwRMePHh/FCZtu2 sOOskh9fnkx58eawmRl/hjy6b+mopzmrXs36L9XUFEPzRAy7te3Qr+u2tXs2t0K8vuW+5R3RN9Gy vdMeVAsX7nHdBWU33/l8Ltrpxiv/rkzcee/ddLH+czcLXvz087bTq1/Pvr3796ulw59PX2Pwrt/L KxfOv3/9/wDapF2ABBbYmHwGJqhgWgMu6KBp48XF4HUSItdgZ3ExJ6Fb3W344IfrIQjiiHnVRuKJ 7JmI4oqtqcjiXvnFKOOMNNZo44045qjjjjz26OOPQPpo3XcC5ldkcrOJaJmSXrmIlJOuMTkYlFdR WZSVfGGZpZQvdunll0dpWF1DMpqXIV3hyTXmdt7tNxWZa2qoppxwtokeQneJmSaee665nW7Qudmh cHna6R9o9XGJkqJgNuroo5BGKulPjE5qqVJoPVcbktShSd6loFp034BGnjdocKGmWlyplFH4J4X+ uRGp6qygcUrrrSFpieuuJOnK668f+QrssPZVSmyqxmJ64bH/xTikdLIylSd54WUqmLOE2sqse6NK lJlW0va5Z38xDbptszhpiiCs+gmYbXPVsTvhufRelGy9+Oarr0PC7usvhv8GLOq9Auvbb8H1Hozw uQovzC/BYDX8JMRJLssntjMe6apKFDfZcVISR2axZx9jNjKMJYucXsi1knzyUyxLFbPMKRs1s0g3 w1xzVTlTuvNIPTss9NBEE4Ztri9X/HPRF/spH7jgQX0tteNu/GrVJ1+mloXtztnqRJz6yWa5VEdn tUG2is3nmcvJCy+gGhdpaqBrserhhNd1qxz+b7JyFWGcfccqp951R/iw2fxx7fTfSRM+Z9riutmp oO3yPXXY1h5+teKe5t25bKUmt26ZG7IqOqDaMhR65nU+y/nmnR+KduR4W/5phWi2ujRIu3tMM9PA By/88MQXb/zxyCcPWO/Kg8l88ycebbffmD+eOvSJGo5f3+TS3T32BTquuaHfg08gcm/rjiqd6Jt/ frpRjz717GS7z/C49jMbdP4tPs//h/v734MCKMAFEbCACTogAsPnvwUaSIEOBBAEI/iVnQWtgRTc CAZxlrQMXgl+eHuI23A3v3ftrVDW8aCy5pK+N9kJcCzEkKZe2DUVAkV8Goufq7Y3wsExLof+HbQh 0hB3KLtJZmN6amHpbrdBIcLuc1kjUrhyh0ITAvFM13MiiJqoxRQFsYtgDKMYAzbBMcaHi2ZUTRnT OJk1slEzaHwjHL8oRwe5sY6JuSMel0THPT4wjn7kYyC/pMd8BemQiEykIhfJyEY6MkhGe6QkJ0nJ SlrykkBy3RRXNz2VrQyQSOujzUDZk0JWzGV6MeWiSFlKVnpElSJ05SpFGRhZcgSWD6PllnS5S1SW yJaevA0wi8XLGw6zV8dEZjGhgks4LTNiyQRaNAf2zFZW02PXxKYvoZlNk6mnmRkB51S6WaVphnKQ 6EynOtfJzna6036k4x05qck9AWIQakP2nFjbFgi6wNXQb2b7XO2gSLd6Ni1ckgOo6pjoz/0cLZee SyhAyebPLObQTG+yluAQmr7qxa18Y5reQ0OqvR8mzmLZoZxHh4TRwjnUcK0bTuW4J7b6jc+l3oGc Er8HwxZuj4hqW5tCZwdUkyoppXei3z5xV9SXEjGmk0sqUecmu6WSD1q0W+JJMaqurLZPpMuqop7S xDep+jR3F42hWtcnLrjdjU04BZgRo6bEb3nVdj0tn9fcxdS4djWgb53qq+gXryp+DaJ0repBrchS Brn0bAu9XGCfyiHaQDaEjlVsXbUDuYJ2zXKpnCfKfoc8c6YkmaZVSkAAADs= ------=_NextPart_000_0007_01C2CE95.91CBD9A0--