[Samba] Lessons learned

Vijay Avarachen vavarachen at gmail.com
Sun Dec 18 20:30:30 GMT 2005

     I would like to share few things I have learned over time in my attempt
to integrate all my Linux clients to an existing corporate Windows 2000
Active Directory (AD).  I am a Linux admin for a small division in a large
company and do not posses any special rights as far as AD goes.  I ONLY have
privileges on my division part of the tree in AD.

- Integrate all Linux client to existing AD so the AD Dynamic DNS will
register hostnames
- Enable AD users to logon to Linux clients.  No users should be maintained
in local passwd files.
- Seem less samba share access from Windows.

I have accomplished all the goals listed above and here are a few things
that I learned:

- Distro
After much trial and error, I learned that the version of Samba shipped with
RHEL 3.0 is not very reliable when it comes to handling sites with large
amount of users.  Regardless of the idmap back end, winbind will die.  I
have standardized on RHEL 4.0 for workstations, Gentoo for back end servers.

My initial attempts to achieve above listed golas used local tdb files for
keeping track of idmaps.  As our Linux environment grew from two
workstations to 13, and users started to move files around, all sort of
permission issues started to appear.  This happens because if you use local
tdb files for idmapping, the user might not get assigned the same UID, GID
on all the Linux hosts.  Even if you have a small userbase in AD, I highly
recomment using LDAP for idmap backend.

In RHEL place the following rules to enable Samba related activity
(/etc/sysconfig/iptables).  You might want to consider tightening the rules
further using -s (source).
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 137 -j
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 138 -j

/usr/bin/testparm (RHEL) is your friend.  Every time you make changes to
smb.conf, use it to verify your changes.  Also smb.conf man

You will need the following RPM's:
#Samba base
>= samba-3.0.10-1.4E.2
>= samba-client-3.0.10-1.4E.2
>= samba-common-3.0.10-1.4E.2
# OpenLDAP for idmap backend
>= openldap-2.2.13-4
>= nss_ldap-226-10
>= openldap-clients-2.2.13-4
# Kerberos

- Kerberos
/etc/krb5.conf is the key.  Without getting this file right you will not be
able to get a kerberos ticket from your AD.  The configuration of this file
really depends on your particular site.  You will know you got the contents
of this file right when you do kinit domain.user at YOUR.REALM and after
entering the password you get no errors.  Also doing klist should show you
the tickets and the expiration time 7 date.

- smb.conf Log Level
log level = 1 ads:10 auth:10 sam:10 rpc:10 winbind:5
Tail the log files and watch for errors.  (tail -f /var/log/samba/{smbd.log,

- AD Binding
Our corporate team does not allow anonymous binding to AD.  One easy was for
you to test this is to use either a command line utility like ldapsearch
(*nix) or Softerra LDAP browser (free).  Try connecting to your AD LDAP
anonymously, if you cannot then you need to use a non-privileged service
account with winbind for LDAP lookups. You might want to set this users
account to "Password never expires", or write a simple script that updates
settings on all Linux clients when the password changes.
wbinfo --set-auth-user=nonpriv.user%good.password

-OpenLDAP Privileged User
For OpenLDAP to serve as IDMAP backend, you must store a privileged users
credentials in secrets.tdb file.
In smb.conf I have:
ldap admin dn = cn=priv_ldap.user,o=company
ldap idmap suffix = ou=Idmap
ldap suffix = o=company
idmap backend = ldap:ldaps://ldapserver.company.com
#Keep the following consistant across all linux clients
idmap uid = 150000-550000
idmap gid = 150000-550000

To store the password for priv_ldap.user in secrets.tdb do:
smbpasswd -w good.password

priv_ldap.user is used to populate the idmap ou.  This user has no
relationship with AD LDAP lookup user.  One exists in AD ldap
(nonpriv.user) and the other in OpenLDAP (priv_ldap.user).  The user
only needs write
access to idmap ou.  So rather than using the ldap admin user, try setting
permissions in your slapd.conf file for a normal user with only write access
to idmap ou.

Kerberos heavily depends on time.  Make sure your Linux clients synchronize
to the same time server as your AD Domain Controller (ADDC).  If not, you
will see error messages similar to "clock skew too great".

- Check List
[1] Ensure smb, winbind, nscd are not running.

[2] Delete/move all old tdb files.

[3] Add OpenLDAP server and AD Domain controller entries to /etc/hosts.
This is in case there is a DNS faliure.

[4] Ensure system time is same as your ADDC.  /etc/init.d/ntpd start
Gentoo NTP guide<http://www.gentoo.org/proj/en/infrastructure/config-ntp.xml>

[5] Edit your /etc/ldap.conf file and your /etc/openldap/ldap.conf file.
Make sure they are pointing to your OpenLDAP server.  A very nice guide to
get a basic OpenLDAP server up and running can be found at Gentoo

[6] Edit your /etc/samba/smb.conf file.  Follow the Samba By
Run testparm to make sure the file does not contain any errors.
[7] Store OpenLDAP priv_ldap.user password in secrets.tdb

[8] If anonymous binding is disabled on your AD, then setup auth user for

[9] Edit /etc/krb5.conf

[10] Try getting kerberos ticket using AD domain admin account
kinit AD.admin at COMPANY.REALM
The REALM should always be upper-case (not sure why)
Verify ticket using klist command

[11] Moment of truth.  Time to join the Linux client to AD.
net ads join -w NA -U AD.admin -S addc.company.com
This command should not prompt your for a password if you got a kerberos
ticket for your AD.admin account in step [10 ] above.

[12] Edit /etc/nsswitch.conf to use AD as a source for user related info
passwd: files winbind
shadow: files winbind
group: files winbind

if you plan to add users to your LDAP (which won't be part of AD) and would
like to use those too, add ldap to above lines.  This is useful for service
accounts such as for a cluster queuing system.  I have placed such users
under DSA (Domain Service Accounts) and DSG (Domain Service Groups).

[13] Even though the Samba by example tells you to start nmbd, winbind and
then smbd in this order, I noticed that this is not important.  On the RHEL
4.x boxes I simply do
/etc/init.d/smb start (this starts smbd and nmbd)
/etc/init.d/winbind start

Before you can continue you need to make sure winbind was able to establish
trust with AD.  This is done by doing
wbinfo -t
However, be careful.  Our AD has thousands of users and groups, and because
of this and slow connection it takes a long time to establish this trust.
(long = 5-10 mins).
One easy way to know when winbind is done establishing the trust is to tail
to log file.  When it becomes less chatty, its a good time to test.
You should see something similar to:
~ $ wbinfo -t
checking the trust secret via RPC calls succeeded

[14] Once this trust is established, its time to see if the system sees AD
users and groups.  Use getent for this purpose.  What getent shows in its
output strictly depends on your nsswitch.conf.  If you only have 'files'
listed for passwd, group and shadow, you will only see local entries.  If
you specify 'winbind' then you should also see AD users.  'ldap' will show
OpenLDAP users (assuming you configured /etc/ldap.conf right).
getent passwd (get user list)
getent group (get group list)

Warning: Depending on the size of your AD, the output can be large.

[15] PAM time
Authentication in RHEL 4.x is all handled by Pluggable Authentication Module
(PAM).  I do not know much about PAM, just enough to get it working.  For AD
users to be able to authenticate, the only file I had to edit was
/etc/pam.d/system-auth  (this file is referenced by others services such as
/etc/pam.d/{ssh, login, gdm etc.}

I added the following lines:
auth        sufficient    /lib/security/$ISA/pam_ldap.so use_first_pass
auth        sufficient    /lib/security/$ISA/pam_winbind.so use_first_pass
account     [default=bad success=ok user_unknown=ignore]
account     [default=bad success=ok user_unknown=ignore]
password    sufficient    /lib/security/$ISA/pam_ldap.so use_authtok
password    sufficient    /lib/security/$ISA/pam_winbind.so use_authtok
session     required      /lib/security/$ISA/pam_unix.so
session     optional      /lib/security/$ISA/pam_ldap.so

Couple of things to keep in mind:
* Depending on what you set 'template shell' in smb.conf, that is what the
users will get by default.
* Depending on what you set 'template homedir' in smb.conf, that is what the
users home directory will be when he/she logs in.  In system.auth there is a
way you can set it to create the home directories automatically.  Search for
mkhomedir parameter.
* if you do not get a valid output for getent passwd user.name authentication
is not going to work
# getent passwd vijay.avarachen

Once you have everything working, I recommend turning on nscd.  Nscd will
never cache passwords.  Passwords are always verified live against AD.

I hope this helps people out there....I know there is more I can write
....which I probably will.  At my company I have my Linux environment well
integrated with AD.  I have a NAS device serving home directories to all
Linux hosts, so users get the same desktop settings no matter what
workstation they use (roaming profile of sorts).  Also I am able to tighten
security by issuing all users RSA keys for ssh authentication. Also I am
able to control who can SSH into a server/workstation by using AllowGroups
parameter in sshd_conf file.

There are also few issues that I am trying to figure out with GDM, KDM.

Vijay Avarachen

"Knowledge is the only wealth that grows as you spend it, and diminishes as
you save it."
-- ancient Sanskrit saying

More information about the samba mailing list