Internet-Goods.com

Redhat 9.0, Samba, Winbind, and Openldap Integration

by nate on Oct.04, 2009, under Open Source Linux, Samba

Some old notes I took on integrating these tools:

Samba, winbind, and openldap for Idmaping storage on Redhat 9.0
7/12/2004

Software versions:
Samba 3.0.4
Openldap 2.1
Redhat 9.0
Also I recommend gq or ldapbrowser to see gui representations of the openldap database.

This document covers howto setup an OpenLDAP server as a backend for a Samba client doing
idmappings with winbind, to allow Linux workstations to log into a windows 2003 domain.

Step 1: Get winbind and samba working as per the document:
“Configuring Samba for Active Directory Logins”
The configuration options listed in the previous document for samba 3.0.2 work with the newer samba 3.0.4 just fine.

After you successfully are able to run getent passwd and see all the domain users listed, we must configure the Samba server to use openldap as a backend. Without openldap, samba will store the idmappings to the following file:
/var/lib/samba/winbindd_idmap.tdb

Samba uses this file as a cache, even when configured to use openldap as a backend, so if your server seems to not be looking to the openldap backend, delete this file and restart winbind, and that will force it to do a lookup instead of just looking to its cached copy.

Step 2: Download, and install OpenLDAP 2.1

Read OpenLDAP 2.1 Administrator’s Guide:
http://www.openldap.org/doc/admin21/

Download openldap 2.1 source:
ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-2.1.30.tgz

uncompress the sources
# tar zvxf openldap-2.1.30.tgz

go into the sources directory
# cd openldap-2.1.30

Setup the nessicary environment variables to insure configure finds SSL/TLS libraries:
# export CPPFLAGS=”-I/usr/include/openssl -I/usr/kerberos/include”
# export LDFLAG=”-L/usr/include/openssl”

run configure on the sources, with options laid out in the OpenLDAP SSL/TLS howto
openldap-2.1.30# ./configure –prefix=/usr –with-tls –enable-slapd –enable-ldbm –disable-bdb
Enter the following command to build dependencies and look for errors:
#make depend
Enter the following command to build the system and look for errors:
#make
Enter the following command to install the binaries and man pages.
#make install

Step 3) configure openldap

The configure option –prefix=/usr will install the openldap binaries into a directory most users will have a default path to, which is good. However samba will not look in the correct directory for the openldap configuration file it needs, so we also make a symlink to redirect it.

Samba will look in here: /usr/local/etc/openldap/ldap.conf
but our ldap.conf file is configured to reside in here: /usr/etc/openldap/ldap.conf
so we make the directories and a symlink to redirect samba to the correct file:
#mkdir /usr/local/etc
#mkdir /usr/local/etc/openldap
#cd /usr/local/etc/openldap
openldap]# ln -s /usr/etc/openldap/ldap.conf ldap.conf

Also delete the directory /etc/openldap, and /etc/ldap.conf and then make a symlink to where our openldap config files actualy live as installed by the source:
# rm -rf /etc/openldap/
#rm -rf /etc/ldap.conf
#ln -s /usr/etc/openldap/ldap.conf /etc/ldap.conf
#ln -s /usr/etc/openldap/ /etc/openldap

This should help reduce confusion as redhat rpms setup the /etc/openldap directory but we are not using rpms for neither samba nor openldap.

Openldap has 2 configuration files that need changes:
/usr/etc/openldap/ldap.conf <--client settings
/usr/etc/openldap/slapd.conf <--server settings
Note that any reference to dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
should contain the functional dns name of the openldap server. It is very important that lines that refernce a domain name go to a name that actualy works with dns, even if just by a corresponding entry in /etc/hosts, for example:
140.192.40.103 voyager.research.cti.depaul.edu

/usr/etc/openldap/ldap.conf should contain these lines and nothing else:
(changing the BASE and HOST lines to reflect your servers actual DNS resolvable hostname)
BASE dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
HOST voyager.research.cti.depaul.edu

Copy the samba.schema into the openldap schema directory, openldap needs this file inorder to understand the data samba will be storing.

# cp /root/samba-3.0.4/examples/LDAP/samba.schema /usr/etc/openldap/schema/

/usr/etc/openldap/slapd.conf should look like this:

# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/etc/openldap/schema/core.schema
include /usr/etc/openldap/schema/cosine.schema
include /usr/etc/openldap/schema/inetorgperson.schema
include /usr/etc/openldap/schema/nis.schema
include /usr/etc/openldap/schema/samba.schema

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

# rootdn can always write!
#######################################################################
# ldbm database definitions
#######################################################################

database ldbm
suffix “dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu”
rootdn “cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu”
# Cleartext passwords, especially for the rootdn, should
# be avoid. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret2
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools. Mode 700 recommended.
directory /usr/var/openldap-data
# Indices to maintain
index objectClass eq

The preceeding slapd.conf sets the rootdn’s password to secret2, which is what is provided along with the BIND dn=”cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu“
in order to have full access to the openldap database, sort of like a login and password for a root user in linux.

In order to setup a logfile used by syslog, add this line to the end of /etc/syslog.conf

local4.* /var/log/openldap.log

and restart syslog:
#/sbin/service syslog restart
Now you should be able to watch the server accept connections and requests which are logged to /var/log/openldap.

First we will test the openldap server though, to make sure it is working in a plaintext mode.
Run the following command in a terminal windows as root to start the openldap server:
# /usr/libexec/slapd -4 -d9 -h “ldap:///”
-4 tell it to use ipv4 only
-d9 is the debugging level, 9 gives useful information on tls/ssl which we’ll need later
-h “ldap:///” tells it which urls to service

you should see a bunch of output and then it stops at:
daemon: select: listen=6 active_threads=0 tvp=NULL
daemon: select: listen=7 active_threads=0 tvp=NULL

Now the server is listening on port 389 (ldap), it will log to the console at the level if detail specified by -d#

Try to connect and run a search, watching for output to /var/log/openldap.log and the console window where openldap was started:

# ldapsearch -x -b ” -s base ‘(objectclass=*)’ namingContexts

You should see something like result:
dn:
namingContexts: dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Now we can setup the entries openldap needs. Make a file, entries.ldif containing this:

dn: dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
objectclass: dcObject
objectclass: organization
dc: voyager
o: Example Company
description: example corp

dn: cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
objectclass: organizationalRole
cn: Manager
description: Directory Manager

Save the file, making sure to replace dc: voyager with your servers name, and the dn: listings with equivelents that match your server’s full dns name. While the openldap server is still running, run this command, which should take the contents of the .ldif file and create corresponding entries in the openldap database.

# ldapadd -f entries.ldif -x -D “cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” -w secret2

You should see something like this:
adding new entry “dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu”

adding new entry “cn=Manager,dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu”

If you don’t get an error, run the ldapsearch command mentioned before again to check that it was added.

# ldapsearch -x -b ‘dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu’ ‘(objectclass=*)’

You should see something that ends with:
# Manager, linuxlab1.research.cti.depaul.edu
dn: cn=Manager,dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu
objectClass: organizationalRole
cn: Manager
description: Directory Manager

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

Now we want to add the ldap OU that samba will use to store idmappings. Taken from the samba howtos, create a file idmap.ldif that contains these lines:

dn: ou=Idmap,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
objectClass: organizationalUnit
ou: idmap

Then load it in with this command:
ldapadd -f idmap.ldif -x -D “cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” -w secret2

you should see a similar result to this:

adding new entry “ou=Idmap,dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu”

Run a ldapsearch command or use gq to make sure the OU=idmap was added, then we must edit the /etc/samba/smb.conf file to tell samba to store its idmap in the openldap server.

Step 4: Configure samba to use the openldap backend to store its Idmap

Add the following lines (again changed to reflect your actual hostname) after “winbind separator = +” :

ldap suffix = dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
ldap idmap suffix = ou=Idmap
ldap admin dn = “cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu”
idmap backend = ldap:ldap://voyager.research.cti.depaul.edu

And set the password samba uses to connect to the openldap server:
# smbpasswd -w secret2
then you should see:
Setting stored password for “cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” in secrets.tdb

This stores the password in /etc/samba/secrets.tdb, make sure this file is only readable by root! Also note that the password must be set for every client computer as well.

Now restart smb and winbind:
#/sbin/service smb restart; /sbin/service winbind restart

If winbind connects sucessfuly, you should see the following in your /var/log/openldap.log

Jul 12 15:24:32 voyager slapd[19300]: conn=2 fd=8 ACCEPT from IP=140.192.40.103:39137 (IP=0.0.0.0:389)
Jul 12 15:24:33 voyager slapd[19300]: conn=2 op=1 BIND dn=”cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” method=128
Jul 12 15:24:33 voyager slapd[19300]: conn=2 op=1 BIND dn=”cn=Manager,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” mech=SIMPLE ssf=0
Jul 12 15:24:33 voyager slapd[19300]: conn=2 op=1 RESULT tag=97 err=0 text=
Jul 12 15:24:33 voyager slapd[19300]: conn=2 op=2 SRCH base=”ou=Idmap,dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu” scope=2 filter=”(objectClass=sambaUnixIdPool)”
Jul 12 15:24:33 voyager slapd[19300]: conn=2 op=2 SRCH attr=uidNumber gidNumber objectClass
Jul 12 15:24:34 voyager slapd[19300]: conn=2 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=

Now,winbind will use the openldap server to lookup any SID->uid/gid mappings not already stored in /var/lib/samba/winbindd_idmap.tdb.

After you see the previous logs signifying a sucessful connection between samba/winbind and openldap, stop smb and winbind, delete the winbindd_idmap.tdb file, then restart smb and winbind.

# /sbin/service smb stop; /sbin/service winbind stop
# rm /var/lib/samba/winbindd_idmap.tdb
# /sbin/service smb start; /sbin/service winbind start
# getent passwd RESEARCH+user (or any other user you have in the domain)

This should output the specific user’s (RESEARCH+user for example) passwd information, as well as do a lookup to the openldap server for the correct UID and GID. If winbindd_idmap.tdb has been deleted, Winbind will recreate the winbindd_idmap.tdb file with the information it gets from openldap. You should also see entries in /var/log/openldap.log showing the SID -> UID/GID mappings being stored in the openldap server. Like this for example:

Jul 14 16:56:19 linuxlab1 slapd[3629]: conn=2 op=9 ADD dn=”sambaSID=S-1-5-21-1513915784-205087697-1902910507-513,ou=Idmap,dc=linuxlab1,dc=research,dc=cti,dc=depaul,dc=edu”

If you have gotten this far, you have a functional openldap server holding idmappings for your windows domain accounts. The configurations up until now reflect a samba/winbind server which also runs a openldap backend.

In order to setup a client, configure it so winbind is functioning, and make the same additions to /etc/samba/smb.conf that you did on the server. Then stop smb and winbind, and delete the winbindd_idmap.tdb cache. and restart smb and winbind, watching the logs on the server to see the client is connecting. If you see only err=0 in the logs, and wbinfo -u works, your client is now using the openldap server for its idmappings!

Step 5: Securing Openldap via TLS/SSL

Openldap by default is sending its password in the clear, using a sniffer you can actualy see it transmit “secret2″. This is not good, so we will be enabling TLS encryption. This allows the server to create certificates to enable clients to connect, afterwards only clients with the correct certificates will be able to connect the the openldap server.

In order to get a feel for how this all works, read this document:
Read OpenLDAP SSL/TLS How-To: http://www.openldap.org/pub/ksoper/OpenLDAP_TLS_howto.html

The area of interest to us is section 4.2 “CA Issue Certificate”
The openldap server will be acting as a Openssl “certificate authority” which makes both the server certificates, as well as the client certificates.

Follow these steps to create a CA and some certificates:

Create any directory for creating and signing your certificates.
For example, /var/myca.

# mkdir /var/myca
# cd /var/myca

now run the OpenSSL CA script:
# /usr/share/ssl/misc/CA -newca
CA certificate filename (or enter to create)

Making CA certificate …
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
……………………..++++++
…………………….++++++
writing new private key to ‘./demoCA/private/./cakey.pem’
Enter PEM pass phrase: <---remember this password, you will need it!
Verifying password - Enter PEM pass phrase:
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Unit
Common Name (eg, YOUR name) []:example.com <--make sure this matchs what youve been using
Email Address []:.
#

This creates demoCA/cacert.pem and demoCA/private/cakey.pem (CA cert and private key).

Now we make your server certificate signing request (CSR):
# openssl req -newkey rsa:1024 -nodes -keyout newreq.pem -out newreq.pem
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
…………..++++++
……………………..++++++
writing new private key to ‘newreq.pem’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Org Unit
Common Name (eg, YOUR name) []:myserver.com <--make sure this is your full DNS name!
Email Address []:ldap@myserver.com

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:

<--just hit ENTER here don't set a password
An optional company name []:.
#

The result is newreq.pem.

Have the CA sign the CSR:

# /usr/share/ssl/misc/CA -sign

Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase: <-- the password you set while making the CA
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:’US’
stateOrProvinceName :PRINTABLE:’Texas’
localityName :PRINTABLE:’Austin’
organizationName :PRINTABLE:’Example Org’
organizationalUnitName:PRINTABLE:’Example Org Unit’
commonName :PRINTABLE:’myserver.com’
emailAddress :IA5STRING:’ldap@myserver.com’
Certificate is to be certified until Apr 10 18:58:58 2004 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
Version: 3 (0×2)
Serial Number: 1 (0×1)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Unit, CN=example.com
Validity
Not Before: Apr 11 18:58:58 2003 GMT
Not After : Apr 10 18:58:58 2004 GMT
Subject: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Org Unit, CN=myserver.com/Email=ldap@myserver.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
< ... >
Exponent: 65537 (0×10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
D0:C0:9D:46:30:65:2A:9C:63:63:6A:E6:FE:E4:AC:F7:21:F8:33:61
X509v3 Authority Key Identifier:
keyid:31:2E:0D:FB:A0:74:5A:0B:4B:C5:C4:E0:69:7F:32:6D:AF:46:82:F1
DirName:/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
serial:00

Signature Algorithm: md5WithRSAEncryption
< ... >
—–BEGIN CERTIFICATE—–
< ... >
—–END CERTIFICATE—–
Signed certificate is in newcert.pem
#

This creates newcert.pem (server certificate signed by CA) with private key, newreq.pem.

5. Now the certificates can be moved to the desired certificate repository and renamed.
I prefer /usr/var/openldap-data as my certificate directory.

# cp demoCA/cacert.pem /usr/var/openldap-data/cacert.pem
# mv newcert.pem /usr/var/openldap-data/servercrt.pem
# mv newreq.pem /usr/var/openldap-data/serverkey.pem
# chmod 400 /usr/var/openldap-data/serverkey.pem

The last command makes the private key read-only by the user who runs slapd. A ‘chown’ command will be necessary if the owner of the server key is not the same as the user who runs slapd. The certificates should be publicly readable.

6. Make the CA certificate available to your LDAP clients.
If the client is on the same machine, copy cacert.pem to a location accessible by the client. If clients are on other machines, then cacert.pem will have to be copied to those machines and also made accessible.

What this means is each client is going to need a copy of the “cacert.pem” file.
So use scp:
# scp /usr/var/openldap-data/cacert.pem root@clienthost:/usr/var/openldap-data/

Next from the openldap server, we have to make each client’s certs, we follow similar steps:

/var/myca# openssl req -newkey rsa:1024 -nodes -keyout newreq.pem -out newreq.pem
(hit enter for the password, and make SURE:

Common Name (eg, YOUR name) []:myserver.com

Is set to the hostname of the client.

Then sign the certs:
/var/myca# /usr/share/ssl/misc/CA -sign
again enter the CA password.
and say Yes to sign them.

If the client is running from the server, these steps work. Else run these steps on the client machine and copy the newcert.pem and newreq.pem to the client via scp and rename them to match the names in your ldap.conf and ldaprc files.

# mkdir /root/certs
# mkdir /root/certs/keys
/var/myca# mv newcert.pem /root/certs/ldap.client.pem
/var/myca# mv newreq.pem /root/certs/keys/ldap.client.key.pem
# chmod 400 /root/certs/keys/ldap.client.key.pem

So each client needs client.pem, client.key.pem, and cakey.pem. cakey.pem is the same on all clients, but the openldap server with the CA will need to create each clients client.key.pem and client.pem and somehow get them to the correct directory on the clients (I recomend using scp).

next we create a file on each client, /root/ldaprc which contains:

TLS_REQCERT demand
TLS_CERT /root/certs/ldap.client.pem
TLS_KEY /root/certs/keys/ldap.client.key.pem

and edit your /usr/etc/openldap/ldap.conf, adding the TLS lines below:

BASE dc=voyager,dc=research,dc=cti,dc=depaul,dc=edu
HOST voyager.research.cti.depaul.edu
TLS_CACERT /usr/var/openldap-data/cacert.pem
TLS_REQCERT demand

Next edit your /usr/etc/openldap/slap.conf and add the following lines about the “rootdn can always write” line:

TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCACertificateFile /usr/var/openldap-data/cacert.pem
TLSCertificateFile /usr/var/openldap-data/servercrt.pem
TLSCertificateKeyFile /usr/var/openldap-data/serverkey.pem
TLSVerifyClient demand

Also, edit /etc/init.d/winbind and change the line daemon winbindd to daemon –user root winbindd

This makes the service script use the ldaprc and find the correct client keys in order to establish a TLS connection.

Now stop slapd, and restart it with this:
#/usr/libexec/slapd -4 -d9 -h “ldap:///”

The -d9 will give TLS/ssl debugging information that will help if there are problems establishing a secure connection.

Then restart winbind:
# /sbin/service smb restart; /sbin/service/winbind restart

Now look at the /var/log/openldap.log, if you see a successful connection and bind, the openldap server is now encrypting the communications with samba. Note that this setup requires all clients to have certificates to connect, else the server will not allow any connection.

Thats all!


Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!