[Samba] LDAP Upgrades (both Unix and Samba)

Brian White bcwhite at precidia.com
Tue May 23 18:09:15 GMT 2006

The latest version of this document can be found at


Last Updated:  2006-05-23

I just upgraded our company's network from a system created 6 years ago 
(NIS and SMBPASSWD) to an up-to-date one (for 2006, at least) including 
a central LDAP server.  It was a far from painless experience, so I 
thought I'd write up the experience in the hope that it may help others. 
  If I've left anything out, please let me know. 
mailto:bcwhite at precidia.com (or if I've left there, 
mailto:bcwhite at pobox.com).

I used my own "cfile" utility (http://sf.net/projects/cfile) to manage 
all the configuration files across multiple machines.  I hope to package 
it up for Debian soon.

Here's what I did...  Note that I'm using Debian 3.1 as my installed system.

Create an LDAP Server  (apt-get install slapd)

Ref:    http://www.metaconsultancy.com/whitepapers/ldap.htm

SLAPD has to be one of the most difficult things to wrap your head 
around I've ever come across.  Perhaps if you spoke LDAP in your sleep, 
it would all be obvious, but I've smoothed out the brick wall next to me 
banging my head against it these past few days.

Getting SLAPD (v2.2.23) started wasn't much trouble.  I set my suffix 
(aka "base") to "dc=precidia".  This would typically be 
"dc=precidia,dc=com", but I'm lazy.  I also set my default password 
style to SSHA (salted-SHA) and set an administrator access point.  Since 
I planned on disabling this access point later, I just used a basic 
"crypt" to store the password.

         # "secret" is password, "XX" is salt (use any two letters or 
         perl -e 'print crypt("secret","XX"),"\n"'

         password-hash SSHA
         rootdn cn=root,dc=precidia
         rootpw {crypt}XXIABNgk3eFuw

Also, create all the appropriate indices for speed:

         index           objectClass             eq
         index           cn                      pres,sub,eq
         index           sn                      pres,sub,eq
         index           uid                     pres,sub,eq
         index           displayName             pres,sub,eq
         index           uidNumber               eq
         index           gidNumber               eq
         index           memberUid               eq
         index           sambaSID                eq
         #index          sambaPrimaryGroups      eq
         index           sambaDomainName         eq
         index           default                 sub

Push these changes with: /etc/init.d/slapd force-reload

In brief, LDAP is an object storage system where objects are grouped 
(typcially) by an "organizationalUnit", or "ou" for short.  Of course, 
you can't simply store an object specifying a new "ou=something"; you 
first have to create an object that describes it.  Thus, before you can 
store objects in "ou=Domains" you first have to store the object:

         dn: ou=Domains,dc=precidia
         ou: Domains
         objectClass: top
         objectClass: organizationalUnit

The first line is the "distinuguished name" and is the unique identifier 
for this object.  Every object has one and it details the hierarchy 
under which the object is stored.  In this case, my "base" (the root of 
my tree) is "dc=precidia" and the sub-tree is "Domains".  Despite the 
fact that I said you cannot store an object in a "ou=Domains" without 
first creating it, it is possible to create it and store it there at the 
same time.

Enabing Ssecure LDAP ("ldaps") is left as an exercise to the reader! 
(That means I haven't yet done it at the time this was written.)

Luckily, the LDAP Account Manager will do much of that for you...

Migrate Existing UNIX Information

Ref:    http://www.linuxjournal.com/article/6266

For this, I used the "ldapmigrate" perl script desribed above.  For this 
to run, you'll have to install "libnet-ldap-perl" and maybe a few 
others.  Then, on your ldap server, do:

         cd /var/data/ldap
         /etc/init.d/slapd stop
         rm -f *
         /etc/init.d/slapd start

This will give you a clean database to start from.  I restarted from 
this point many, many times.

Create an "admin" account for LDAP administration.  It will need a valid 
password but should have an invalid shell to prevent unix login (because 
it will eventually have root access -- see Samba section).  A vaild home 
directory may be useful, though.

Before doing the migration, I edited the "ldapmigrate" script and 
changed all occurances of "Group" to "Groups" for naming consistancy and 
to match the defaults of the LDAP Account Manager.

Then do the migration...

         ldapmigrate -D $LDAPBIND -w $LDAPPASS -b $LDAPBASE -h $LDAPHOST 
--extschema --extconts --prepdb
         ldapmigrate -D $LDAPBIND -w $LDAPPASS -b $LDAPBASE -h $LDAPHOST 
--extschema --minuid=1001 --mingid=1000 -f /etc/passwd passwd
         ldapmigrate -D $LDAPBIND -w $LDAPPASS -b $LDAPBASE -h $LDAPHOST 
--extschema --minuid=1001 --mingid=1000 -f /etc/group group

It's important to use the "--extschema" so that the objects will be 
ready to accept Samba information.  Your minuid/maxuid and mingid/maxgid 
may be different than mine.

Add Additional Information

At this point, I wrote my own Perl script using Net::LDAP to add 
additional information (phone number, fax number, email, etc.) from an 
internal database of that information.  I also generated samba SID 
information from the /etc/smbpasswd file.  I'll try to make it available 
for reference, but it's not likely to be directly usable by anyone.  The 
LDAP Account Manager should allow you to add the samba information by hand.

Install LDAP Account Manager  (apt-get install ldap-account-manager)

Ref:    http://lam.sourceforge.net/

Before you can use this for editing, you have to get it installed. 
Version 0.4.9 goes in to "apache" automatically (I think) but to use it 
with "apache2" you need to do something like:

         cd /etc/apache2/sites-available
         ln -s /etc/ldap-account-manager/apache.conf ldap-account-manager
         cd ../sites-enabled
         ln -s ../sites-available/ldap-account-manager 010-lam
         /etc/init.d/apache2 restart

Then you should be able to log in with http://hostname/lam/ and get a 
login page.  Additional Apache configuration is left as an exercise to 
the reader. Once you do get a login page...

Select the "configuration login" from the upper right corner.  The 
default password is "lam".  You'll need to change all the suffix 
parameters to match the suffix you chose when you configured slapd.  I use:

         UserSuffix:     ou=people,dc=precidia
         GroupSuffix:    ou=groups,dc=precidia
         HostSuffix:     ou=hosts,dc=precidia
         DomainSuffix:   ou=domains,dc=precidia
         PasswordHash:   SSHA

Set the "ranges" fields to match what you want for your site.  Set the 
list of valid users to whatever is appropriate.  I set it to:


Finally, create a new configuration password (it's group with the "list 
of valid users" under "security settings" but it only applies to getting 
to this configuration screen) and submit the changes.

Go back to the login screen and login as "admin" with the password for 
that account (_not_ the configuration password you just changed).  It 
should tell you that some LDAP parts are missing and offer to create 
them for you.  Let it do so.

Create a new domain.  To get the SID for a domain you're migrating from 
a legacy system, go to your legacy system and run:

         net getlocalsid precidia

Don't change the "algorithmic RID base" unless you've changed it 
previously. I haven't yet discovered exactly whan the "next ... rid" 
options do so I haven't played with them, yet.  I believe they allow you 
to specify starting RIDs that increment normally rather that being 
generated by some function of your userid/groupid.

Note:  There is also a "phpldapadmin" package that provides more 
detailed control of the LDAP directory, but because it's a generic 
interface you have to know much more to do account management.

Configure Linux Authentication  (apt-get install libnss-ldap libpam-ldap 

Ref:    http://www.metaconsultancy.com/whitepapers/ldap-linux.htm

In brief, this involved editing several configuration files...

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

         host admin1.ott.precidia.com
         base dc=precidia
         ldap_version 3
         rootbinddn uid=admin,ou=People,dc=precidia
         pam_filter &(objectclass=posixAccount)(!(uidNumber=0))
         pam_password exop

         uri ldap://admin1.ott.precidia.com ldap://admin2.ott.precidia.com
         base dc=precidia

         account sufficient      pam_unix.so
         account sufficient      pam_ldap.so
         account required        pam_deny.so

         auth    sufficient      pam_ldap.so
         auth    sufficient      pam_unix.so shadow use_first_pass
         auth    required        pam_deny.so

         session sufficient      pam_ldap.so
         session required        pam_unix.so

         password        requisite       pam_passwdqc.so 
min=12,10,10,8,6 random=25 retry=3 passphrase=2
         password        sufficient      pam_ldap.so     type=network 
use_authtok first_pass
         password        sufficient      pam_unix.so     type=machine 
use_authtok md5
         password        required        pam_deny.so

Once all of this is done, you should be able to "su - user" and become 
that user.  Whew!

Configure Samba Authentication  (apt-get install samba)

Ref:    http://www.unav.es/cti/ldap-smb/smb-ldap-3-howto.html
         man smb.conf

Congratulations on getting this far!  The following was done with Samba 

You'll need to import the samba scheme in to slapd.conf by adding this 
line. If the file is not in /etc/ldap/schema, you'll probably find a 
gzipped version here: /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz

         include         /etc/ldap/schema/samba.schema

Then add the following to your working smb.conf configuration file:

         passdb backend = ldapsam:ldap://admin1.ott.precidia.com

         ldap admin dn = uid=samba,ou=Services,dc=precidia
         ldap suffix = dc=precidia
         ldap user suffix = ou=People
         ldap group suffix = ou=Groups
         ldap idmap suffix = ou=Idmap
         ldap machine suffix = ou=Hosts
         ldap replication sleep = 1000
         ldap password sync = true
         ldapsam:trusted = true

A few notes: The man pages for version 3.0.14a indicates that the 
specific suffix directives replace the default "ldap suffix".  In fact, 
they simply prepend to it.  Also, don't put quote marks around the values!

This configuration assumes a user "samba" created in the "Services" unit 
of the directory.  You'll have to do that manually with a command like:

         ldapadd -D cn=root,dc=precidia -w secret -b dc=precidia -h
         dn: uid=samba,ou=Services,dc=precidia
         objectClass: top
         objectClass: account
         objectClass: posixAccount
         cn: Samba Server
         uid: samba
         uidNumber: 3000
         gidNumber: 3000
         homeDirectory: /tmp

         ldappasswd -x -D cn=root,dc=precidia -w secret -h -s 
SOMETHING uid=samba,ou=Services,dc=precidia

The last command sets the password for the 
"uid=samba,ou=Services,dc=precidia" account to "SOMETHING".  Obviously, 
choose something other than SOMETHING. Now you need to tell samba what 
it is.  The reason for creating a special service account with these 
permissions is because it's stored on disk by samba.  As such, it's not 
good to use an ordinary user account which may require it's password 
changed if an employee leaves or something.

         smbpasswd -w SOMETHING

Finally, you have to give that account special permission in the 
"slapd.conf" file so it can update records in the directory as it runs. 
  To do that, change the admin rule to something like:

         access  to *
                 by dn="uid=admin,ou=People,dc=precidia" write
                 by dn="uid=samba,ou=Services,dc=precidia" write
                 by * read

At the same time, add the following so that the samba passwords are 
protected.  (These encrypted passwords are actually "plain text 
equivalents" which means that knowing them allows access just as though 
one knew the original password from which they were derived -- thank 
you, Microsoft security experts.)

         access  to attrs=sambaLMPassword,sambaNTPassword
                 by dn="uid=samba,ou=Services,dc=precidia" write
                 by * none

Doing /etc/init.d/samba restart should start quickly.  If it appears to 
hang while starting "smbd" then there is probably problems accessing the 
ldap server.  The /var/log/syslog file on the LDAP server may have 
useful information as to what was being accessed.

If your log level is set to zero, the "smbd" process will exit quietly 
on an LDAP failure.  The LDAP activity found in /var/log/syslog can be 
quite helpful but don't expect it to be easy.

At this point, you should be able to use Windows Explorer to browse the 
samba host and access shared drives using usernames and password that 
were imported in to the LDAP directory.  Connecting to the domain still 
needs more work, though.

Connecting to a domain needs a privileged account.  I used the same 
"admin" account that had its information originally imported from a unix 
account.  For this to work in samba, though, _MUST_ be user-id 0 (yes, 
ZERO).  I understood this requrirement when samba had to create new 
local accounts, but seems to still be the case for LDAP directories. 
This is unfortunate as it means you have a root account in your ldap 
directory, but we'll mitigate this risk as much as possible.  Log out of 
the LDAP Account Manager and do a "configuration login".  Set the 
minimum UID number to "0" (zero), submit, and login normally. Edit the 
"admin" user and set the UID number to 0.  Previously it was stated to 
not have a valid login password for this account during the initial 
migration, but set the login shell to /bin/false, too.  When done change 
the minimum UID back to what you want.

Lastly, you have to choose between manual or automatic addition of new 
hosts. You can use the LDAP Account Manager to manually add all new 
hosts before connecting them to the domain, or you can have samba create 
those accounts during the first join attempt.  For now, I'm just 
sticking with the manual addition.  There appears to be no easy way to 
get samba to do it automatically.  You can find instructions on how this 
can be done here


but configuration is complex and I was unable to get the tools to work 
properly.  That's annoying!  This should be a built-in feature of Samba!


And that's it.  Wasn't that easy!  You know, I love the power and 
flexibility of the GNU/Linux operating system, but it took me two weeks 
to figure out all of the above.  There were many times I yearned for a 
simple graphical setup program under Windoze.

I'm trying to help out some by writing this, but I'm afraid it will 
become just one more HOWTO is the huge mess of them, none of them 
complete.  Writing this after the fact instead of during the process 
wasn't so smart, either; I'm sure there are things I have forgotten to 
mention.  I have this idea of duplicating the Wikipedia site 
(http://www.wikipedia.org) but making it Linux documentation.  Maybe 
it's already out there...

One of the drawbacks of the "bazzaar" model is that developers 
concentrate on getting the software to do the things they want it to do 
and not on making easy installation.  After all, installation only has 
to be done once, they know how to do it, and a set installation program 
would only limit easy expansion of the software itself.  There is 
something to be said for the czar of the cathedral decreeing, "you 
people over there -- go and make a good install interface so our 
software will get chosen in the first place".

                                  ( bcwhite at precidia.com )

           Until we are first independent, we cannot be interdependent.

More information about the samba mailing list