Secure LDAP for Solaris (via TLS/SSL)

This page is to hold hints on how to get solaris 8, and later, to fully
integrate with OpenLDAP.

The good news

OpenLDAP, in conjunction with OpenSSL, can let you use LDAP for your
information, including passwords, and have that information fully
encrypted.

The bad news

Solaris 8 does not natively support TLS-encryption with its LDAP client
tools.
[ But Solaris 9 DOES! (although I have not personally tried it)]
[flash! And now solaris 8 allegedly does, with
patch
108993 for sparc, or
patch
108994 for x86].
If you are interested in this, then go to the bottom of the
page for the
Solaris libraries with OpenLDAP server section

However, by following a nose-hair-pulling list of steps, which I shall
describe herein, you can use third-party modules to browbeat solaris into
doing the right thing.

If I'm missing any steps, please use the link at the bottom of the page to
email me. I HAVE IT WORKING NOW, so it's simply a matter of me adequately
documenting for you.

All the following should work on both intel and sparc. Making shared
libraries for openldap MIGHT require gcc (unless you like rewriting
makefiles). Otherwise, it shouldn't matter which compiler you use.

If you cannot use solaris-native TLS support, you will need the following
modules from www.padl.com:

Additionally, you will need GNU make, and (if you havent done a full install
of solaris 8, or arent running solaris 8) zlib, and perl.

The rest of this page is a collection of sections. Read the header for each
section. Some day soon I'll actually make an index for this page.

READ ALL THE SECTIONS AT LEAST ONCE

As I said earlier, this is a nasty long horrible sequence of steps, so even
if you think you know the information in a particular section, read it
anyway. There are special compile tweaks needed at pretty much every step
of the way.

STOP AND SAVE NOW

I. How to compile openssl appropriately

(see Solaris 9 note below, if you have it)

You'll want to first grab openssl, and then make sure you compile a shared
library version of it. It defaults to compiling a static library. However,
unless you want to recompile all your binaries the next time an update to
openssl comes out, I suggest you make a dynamic library.

Unfortunately, the latest versions of openssl (0.9.6a) don't
make this easy.

Note that this is the one component that does NOT use GNU configure

First edit the Configure script, and find the "solaris-x86-gcc" line.
[adjust similarly for solaris-sparcv9-gcc, etc. as needed]

Change "gnu-shared" to "solaris-shared".

add "-R/usr/local/ssl/lib " just before "-lsocket"

Then run

./Configure solaris-x86-gcc shared
make
make install

If you have done this correctly, you should be able to do

LD_LIBRARY_PATH=/usr/lib ldd /usr/local/ssl/lib/libssl.so

and see libcrypto linked okay.

Solaris 9 critical notes

Note: Solaris 9 ships with Sun's own version of the SSL libraries, not to
mention that its native LDAP clients now ship with TLS support. But if you
still want to compile and use OpenLDAP for some reason, you'll have to grab
OpenSSL from elsewhere, since Sun does not seem to ship the ssl include
files.

II. Hints on compiling OpenLDAP 2 on Solaris

Here are some hints on getting openldap 2.x to compile under solaris with
the best extra options. (Dont bother with openldap 1.x!!)
You will probably like to know these undocumented tips
on how to nicely compile OpenLDAP under solaris.
First of all, you should download and install:

Important notes on BerkeleyDB

If you are using the 3.x version, use v3.2, not v3.3!. I have heard rumors that
sleepycat changed the whole interface in 3.3, or something like that.
Bottom line: 3.2 compiles with openldap happily, and 3.3 does not.
(openldap v2.0.11)

Rather than fiddling with compiles, the really simple thing to do is
just add the packages from
opencsw.org
Note that that installs everything under /opt/csw, but you get EVERYTHING:
openldap, ssl, and everything else you need.

If you are compiling from source, do yourself a favour and
configure it with

./configure --prefix=/usr/local --enable-shared

[or --prefix=/opt/sfw, and optionally, --enable-compat185].
If you do not set the prefix, then unlike 99.9% of autoconf software
out there, the prefix defaults to /usr/local/BerkeleyDB-X, which
will probably trip you up.
Note also that some people report it will not work
without the --enable-compat185, which may require you to separately compile
and install "db-1.85". Hence the recommendation to use the binary package
instead.

You should probably do the following, before trying to ./configure
the actual openldap 2.x distribution

You should then carefully watch the output of ./configure to verify that it
picks up berkeleyDB and SSL support. It probably helps to force
things with

./configure --with-tls [other-options]

That way, if it doesnt find it, it will complain and stop.

Unfortunately, their "libtool" is pretty damn stupid, so there's another
step to do if you want to keep going and run pam_ldap/nss_ldap on top of
openldap. AFTER you've run configure, but
BEFORE
doing a make, edit libtool, and change LD="/usr/ccs/bin/ld" to

LD="/usr/ccs/bin/ld -R/usr/local/ssl/lib:/usr/local/lib"

Additionally, in case Sun ever fixes their client code, you'll want to add
this special patch to make OpenLDAP solaris-ldap compatible
for future use. (It makes your base dn show up as a "namingcontext" in the
rootDSE automatically)

NOW you can run a 'make depend', followed by 'make'

When you're all done, and have run make install, you know
you've done it right if you can do

LD_LIBRARY_PATH=/usr/lib ldd /usr/local/lib/libldap.so

and have no "file not found" lines, AND you see libssl + libcrypto
successfully mentioned.
If not, go to the top of this page, start recompiling everything, and
follow the instructions more carefully.

Setting up TLS/SSL+OpenLDAP server on Solaris

Okay, you've compiled the OpenLDAP server with TLS support... but now you
need to actually set up the encryption component, or it is useless to you.

Here's a quickie method that gets you up and running with TLS (SSL)
encrypted connections supported.

[First, edit /usr/local/etc/openldap/slapd.conf, play with it, and get it
running happily with no frills (however, you will probably want to
research what indexes to add). Then...]

Unfortunately, solaris 8 does not natively support TLS and
LDAP. So if you want to actually use TLS, you'll have to follow
all the steps in this page, and use the
padl pam_ldap and nss_ldap modules mentioned further down on this page.

III. Compiling the PAM and nss modules for Solaris (for client side
auth)

Then just run ./configure, followed by
gmake (GNU make), and you'll get good binaries.

Warning for solaris 64-bit folks
Please note that you need to compile two versions of the PAM library;
a 32-bit one for /usr/lib/security, and a 64-bit one to put
in /usr/lib/security/sparcv9

If you have netscape directory server on the same machine, you'll have to
specify ./configure --with-ldap-lib=openldap so that you do
not use the netscape LDAP libraries.

The interesting bit is in installation. I would have preferred to add
"open" somewhere in the names for both of them. Unfortunately, solaris
nsswitch.conf will not recognize arbitrary names, therefore you MUST
install the new nss_ldap, as "/usr/lib/nss_ldap.so.1". (Save the old
version first).

Once you've done this add "ldap" to whatever entries you like in
/etc/nsswitch.conf. This will enable things like "finger"
to work, once you actually put some user info in the LDAP database.

Happily, Solaris is more forgiving about PAM modules. So copy the padl PAM
module to /usr/lib/security/pam_openldap.so.1, rather than
pam_ldap.so.

/etc/ldap.conf for padl.com PAM and nss modules

This is the stuff that tells the padl modules "USE ENCRYPTION!!"

I recommend copying the sample ldap.conf over to /etc first,
[since it has fairly copious comments] and then adding the
following lines. Note that the ssl line is undocumented, but essential.

# Seem to need BOTH of these, PLUS port spec.
# You may need to put in your FQDN here
host 127.0.0.1
uri ldaps://127.0.0.1
#
# Undocumented, REQUIRED element for using TLS
ssl true
#
base dc=yourdom,dc=com
rootbinddn cn=Manager,dc=yourdom,dc=com
# Dont forget to put the LDAP Manager password in /etc/ldap.secret
port 636
# The rest of these are primarily for the nss stuff
# You'll probably want to add all the other lines mentioned in the comments
# too, but this will get "finger" and login working
pam_password exop
nss_base_passwd ou=People,dc=yourdom,dc=com?one
nss_base_shadow ou=People,dc=yourdom,dc=com?one
# You may also want to adjust 'bindcn' and 'bindpw', but they were
# not neccessary for my experiments.

/etc/pam.conf additions for use with padl PAM module

This is the stuff that tells SOLARIS, "hey, go use this extra
source of information for login authentication".

Except that the whole point of this is to get encrypted passwords.
So you'd never allow a non-encrypted medium to log in, right?
So here's how to allow ssh to use the information in your LDAP data source:

[The "try_first_pass" allows for transparent fallback to local accounts,
if there is no LDAP entry for a user]

Relatively painless... as long as you remembered to compile ssh with

./configure --with-pam

If you didn't... well, go recompile ssh now.

LDAP data needed for accounts

Oops... you now have everything you need... EXCEPT what kind of data format
you need to create LDAP-based accounts.

Keep reading for information on that stuff. Then you're all done. Have fun!

IV. LDAP Basics

LDAP has an unusual structure, if you are not used to X.500 style naming.
Things are either branches, or leaf nodes.
You can't just drop an object anywhere you like; You need to creat the
framework to support it. Sort of like if you wanted to put entries in
/etc/hosts, if the directory /etc did not exist.

First you mkdir /etc, Then you create the file. Then you start putting
things in the file.
The difference with LDAP and x.500 is that instead of paths separate by
slashes, you have paths separated by commas and '=' signs.

For example, if you want to make an object
"cn=ldaphost,ou=hosts,dc=yourdom,dc=com", you first have to make sure
"dc=yourdom,dc=com" exists.
Then make sure
"ou=hosts,dc=yourdom,dc=com" exists.THEN you can try
"cn=ldaphost,ou=hosts,dc=yourdom,dc=com"

V. Including the right stuff for your slapd

Once you have OpenLDAP v2 installed, add the following lines to slapd.conf,
below the "include core.schema" line:

include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/solaris.schema

Side note: newer versions of openldap seem to have broken solaris/nis
integration by removing some values. You can get a "solaris-nis" schema,
which you should use in place of "nis.schema", at
http://netmojo.ca/howto/solaris-nis.schema

For Solaris clients, you will need to make sure you have the following
object type in nis.schema:

you may also want some soalris-specific things, via
what is commonly named "solaris.schema":
new.solaris.schema (rename to
"solaris.schema" after download)

[The reason for all this extra stuff is that not all of the information in
rfc2307 is already in "nis.schema". If you need to add any extra stuff
from rfc2307, this is the place to put it. Then please let me know, so I
can update the page!]

You are now ready to start populating your LDAP server just like an
unsecure NIS server.

VI. Simple LDAP population

Here's a way to get the initial data framework loaded into your LDAP
server, so you can have useful account entries, etc. in there.
Remember that I am not addressing any security issues in this section.
If you are planning to grant access to ANYTHING on your network with this
info, you should think long and hard about access rights to each object,
etc. Then TEST your implementation to make sure no unauthorized folks can
get at the data.

First off:
The REALLY easy way, is to use the
PADL migration
stools. First, edit the config file, "migrate_common.ph". Then run
"migrate_base.pl". After that, you're ready to use any of the other
migrate_XXX.pl scripts to import data from the standard flat files in
either /etc, or /var/yp/src, into your LDAP server!

Other pre-canned ways are the "nsimport" script
from the old iPlanet LDAP server, or the newer "idsconfig"
from the successor, Sun JAVA LDAP server

If, however, you'd rather do things manually... or just want a better idea
of what's going on, then
here's how to get from ground zero, to having an initial host and user
entry in your LDAP data store.
Note that "yourpassword" mentioned below, is whatever you set as the rootdn
password in slapd.conf

Define your domain as the top-level

Without doing this first, you can't do much of anything.

ldapadd -D cn=Manager,dc=yourdom,dc=com -w yourpassword
dn: dc=yourdom,dc=com
objectclass: top
objectclass: dcObject
dc: yourdom
objectclass: nisDomainObject
nisDomain: yourdom.com
objectClass: organization
o: yourdom.com
#I used to have "objectclass: domain" rather than dcObject,
# but that seems to be broken in openldap 2.2 somehow now
# also, objectClass: organization seems to be a new
# requirement for top level openldap

Define the object container for each data map

This bit is sort of like creating a NIS "map" for hosts information. We
create an "Organizational Unit" for objects of type do with 'hosts'.
The solaris
nsswitch routines expect it to be called "hosts" by default.
There are ways to alter what it queries, however, so we could theoretically
call it anything we like.

After you add "ldap" to the "hosts:" entry in /etc/nsswitch.conf, you should
then be able to do

telnet ldaphost

and have solaris pull up the correct IP address.

Making "finger" and logins work

Interestingly enough, "finger" seems to query the "people" directory, not
"passwd", as you might expect.
But you still have to add "ldap" to the "passwd:" entry of
/etc/nsswitch.conf, it seems. So DONT USE IT, unless you are using the
special TLS version documented higher up in this page.

Sample basic account

Paste this into the stdin of
"ldapadd -Z -x -D cn=Manager,dc=yourdom,dc=com -W"

(assuming you have already added a few objects to your LDAP directory)

I have successfully used this command to observe TLS in action,
using solaris 8 and openldap 2.0.7.

Now I just have to get the SOLARIS ldapsearch to use TLS somehow.
(or 'ldaplist', or...) Sigh.
Putting "NS_LDAP_TRANSPORT_SEC= NS_LDAP_SEC_TLS" in
/var/ldap/ldap_client_file does NOT seem to work, oddly enough.

Sun has a semi-informative page on LDAP at its
Sun
Blueprints website. There is also a more generic "LDAP Basics" article
in this Sun
BluePrints article.

NOTE: Key OpenLDAP patch for Solaris here!

p.mayers also has a page dealing with
solaris 8
and ldap . This lists the actual source code hack to make
OpenLDAP 2.0.7 talk to the solaris native ldap tools.
However, you cannot cut-n-paste it, because it needs tabs in there.

in the servers/slapd directory. This gets "ldapclient" past the initial
"Can't find rootDN/namingcontexts" unhappiness, but then gets stuck later
on, for various reasons. One is that it expects the optional "virtual views"
LDAP spec implemented. The other is that it wont do TLS.

Solaris libraries, OpenLDAP server

Just for informational sake, here's the information I had
previously collected, about trying to get SUN's native ldap client to talk
to OpenLDAP.

Right now, the way of using the solaris 8 "ldapclient" to nicely configure
things is not known. Or rather, a possible way
has been mentioned on the "OpenLDAP" mailing list, but requires a
source patch, and does not seem to be the 100% solution anyway, since solaris
wants to use an "optional" part of the LDAP standard that openldap doesnt
implement.

The obvious problem is that "ldapclient" complains about not finding
"namingcontexts". But there IS a hardcode sneaky way to set up
ldap with the standard solaris 8 tools. You ignore 'ldapclient', and do
some file editing yourself.
BTW: to find the "namingcontexts" from a regular, non-vanilla-openldap server,
you can use

ldapearch -h servername -b '' -s base objectclass=\*

or simply point netscape at ldap://servername

To halfway hack the sun ldap client routines,
create /var/ldap/ldap_client_file with the following lines,
adjusted appropriately for your environment

You can then add "ldap" to various entries in /etc/nsswitch.conf, and use
ldap to look up things instead of other alternatives, once you actually put
data in the LDAP server.

Warning
You may now in theory have the capability of putting user passwords in
ldap. DO NOT DO THIS, even "crypted", since this is the
equivalent of making /etc/shadow readable.

This needs to wait until a method is found to have the encrypted
communications activated. [like the PAM module: see the appropriate
section of this page!]

Contrariwise, you can look at
http://www.ypass.net/solaris8/openldap/configuringsolaris.html
which gives a much more detailed sample ldap_client_file , along
with detailed comments on each line, along with a
ldap_client_cred file if you want to use something a little
more robust than anonymous access (It specifies a password to bind with)

This should allow you to use the solaris nss_ldap libraries, rather
than the padl.com ones.

LDAP, w2k integration

If you want to talk kerberos + w2k + OTHER machines, you may find this link
interesting: