June 3, 2009

Configuring a Samba File sharing server with AD auth

Configuring a Samba server to use AD (LDAP) authentication can be a little tricky, especially because of the the little PAM tricks you need to do. I have searched a lot for info and tutorials, each giving you a little bit of the picture, and tested them until I came to a solution.  I hope to spare you some of the work of digging and testing ;) Here goes!

This how-to is tested and works on a Debian system (4.0 / 5.0) using Samba version 3.2.5. It should work on other distros with minimum modifications but I do not guarantee it. Also, this is a copy / paste how-to, although I provided some small explanations at the end. You just need to modify generic info like “YOUR.DOMAIN” to your systems specific details.

Installing the packages

First we are going to install the needed packages:

sudo apt-get install samba samba-common libkrb53 libpam-krb5 krb5-config krb5-user winbind

Configuring nsswitch

Edit the file /etc/nsswitch.conf in order to have the following contents:

# /etc/nsswitch.conf
# Example configuration of GNU Name Service Switch functionality.
# If you have the 'glibc-doc-reference' and 'info' packages installed, try:
# info libc "Name Service Switch" for information about this file.

# The next 3 lines are modified for winbind password checking before *nix password checking

passwd:         winbind compat
group:          winbind compat
shadow:         winbind compat

hosts:          files dns wins
networks:       files dns

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

Configuring Kerberos5:

Now you need to edit the file /etc/krb5.conf to have the following contents:

default_realm =  YOUR.DOMAIN
forwardable = true
ticket_lifetime = 24000
dns_lookup_kdc = false
dns_lookup_realm = false

kdc =  your.AD.server
admin_server = your.AD.server
default_domain = YOUR.DOMAIN

.your.domain =  YOUR.DOMAIN
your.domain =  YOUR.DOMAIN

krb4_convert = true
krb4_get_tickets = false

default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false

Configuring PAM

The next step is to configure PAM to first try to use Winbind authentication instead of local *nix style authenticaion. This will NOT mess with your local authentication for terminal or SSH access. First file we need to edit is /etc/pam.d/common-account:

# /etc/pam.d/common-account - authorization settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authorization modules that define
# the central access policy for use on the system.  The default is to
# only deny service to users whose accounts are expired in /etc/shadow.

# PAM Winbind plugin before *nix accounting
account sufficient      pam_winbind.so
account required        pam_unix.so

Next one is /etc/pam.d/common-auth:

# /etc/pam.d/common-auth - authentication settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.).  The default is to use the
# traditional Unix authentication mechanisms.

# PAM winbind plugin before *nix authentication
auth       required     /lib/security/pam_securetty.so
auth       sufficient   /lib/security/pam_winbind.so
auth       sufficient   /lib/security/pam_unix.so use_first_pass
auth       required     /lib/security/pam_nologin.so

And the last one is /etc/pam.d/common-password:

# /etc/pam.d/common-password - password-related modules common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of modules that define  the services to be
#used to change user passwords.  The default is pam_unix

# The "nullok" option allows users to change an empty password, else
# empty passwords are treated as locked accounts.
# (Add `md5' after the module name to enable MD5 passwords)
# The "obscure" option replaces the old `OBSCURE_CHECKS_ENAB' option in
# login.defs. Also the "min" and "max" options enforce the length of the
# new password.

password   sufficient pam_winbind.so
password   sufficient pam_unix.so nullok obscure md5

Configuring Samba and the share

First create the directories that you will use for the shares. In this example we will use /opt/data/samba in which we will make 2 other directories: public and restricted. Now edit the file /etc/samba/smb.conf:

debug level = 3
kernel oplocks = no
workgroup = DOMAIN  ### domain name without the TLD - .com for example ###
netbios name = <A name by which the server will be seen in the network>
server string =  File Server
load printers = no
log file = /var/log/samba/debug.log
max log size = 50
local master = no
domain master = no
preferred master = no
security = ADS
password server =  your.AD.server
encrypt passwords = yes
socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
wins proxy = no
dns proxy = no
winbind enum users = yes
winbind enum groups = yes
winbind use default domain = yes
winbind separator = +
winbind refresh tickets = yes
idmap uid = 10000-20000
idmap gid = 10000-20000

path = /opt/data/samba/public
comment = Public access folder
read only = no
force user = %U
force group = "DOMAIN+domain users"
force create mode = 0666
force directory mode = 2777
force directory security mode = 0777
valid users = @"DOMAIN+domain users"

path = /opt/data/samba/it
comment = Restricted access folder
writable = yes
force user = %U
force group = "DOMAIN+<AD group that is allowed to access>"
force create mode = 0660
create mask = 0660
force directory mode = 0770
force directory security mode = 0770
valid users = @"DOMAIN+<AD group that is allowed to access>"

I will explain some of the configuration directives used here for smb.conf. The first two are: > security = ADS > password server = your.AD.server

This will tell Samba to use Active Directory security and that the server Samba needs to verify the passwords against is the local domain controller (the one that holds the AD tree).

The next two are: > winbind use default domain = yes > winbind separator = +

If the first directive is set to “yes”, you won’t need to use the domain also when setting file permissions. Samba / Winbind will know to use what you have set in the “realm” directive in front of every group / user used for authentication or authorization. The second one just tells Samba what to use as separator between the “realm” and user or group.

This directive: > winbind refresh tickets = yes

will tell Samba to refresh the kerberos tickets after joining the domain, as not to “unjoin” it and become unable to authenticate against the AD.

As for the shares, you can use the variable “%U” as the authenticated user to force the ownership or to grant access. Also, you can use groups in the AD to allow access using the directive “valid users =” followed by the name of the group with the domain in front. Example: valid users = @”DOMAIN+restricted-access-group” . Please use the separator that you have set above with “winbind separator” The rest of the directives are usual Samba directives.

Now restart Samba and Winbind:

sudo /etc/init.d/samba restart
sudo /etc/init.d/winbind restart

Joining the domain

For Samba to be able the verify usernames and passwords against the Active Directory, the server must first be joined in the domain. To do that we need to use the “net ads join” command:

net ads join -S your.AD.server -U user%password

The user and password must be valid a valid user in the domain that has the permission to join it. To verify that the server has joined the domain you can use the following commands:

net ads status -S your.AD.server -U user%password


net ads info

Also, to be safe run the following commands:

wbinfo -u
wbinfo -g

The first one should list all the domain users and the second one the domain groups. If this is so and you have seen the user and group list that means that the server is joined and is able to see verify the usernames / passwords.

Setting file permissions

Now that Samba is configured and the server joined the domain, the last thing to do is to set the Unix style file permissions on the share folders. But now, you can use the users and groups in the domain as the owner and group settings of the folders and files. For example:

chown "jon.doe" /opt/data/samba/restricted -R
chgrp "restricted-access-group" /opt/data/samba/restricted -R
chmod g+rw /opt/data/samba/restricted -R

or to make all the users in the domain able to read and write the public folder:

chgrp "domain users" /opt/data/samba/public -R
chmod g+rw /opt/data/samba/public -R

That’s it! Now you should be able to access Samba shares using your AD username and password!