17.4.13

sssd in Samba 4.0

sssd: the final hurdle to AD

** Updated to include sssd version 1.11.0
** New minimalist sssd.conf for sssd version 1.11.5 in this post.

Introduction
We've tried winbind and nslcd to pull the rfc2307 attributes from AD. The former is tricky to setup and doesn't yet work on the DC itself. nss-ldapd/nslcd works fully on both client and server and is documented for Ubuntu clients here.  So here's what will probably be the final chapter for us as we investigate the third and perhaps best solution for sharing Linux and Windows resources on the same lan. Let's hear it for sssd.

What does it do?
Well, the same as winbind and nslcd but with all configuration in a single 'you'll not believe how simple this is' file under /etc.

Let's go.

apt-get install samba-common-bin sssd sssd-tools autofs krb5-user

Our test setup was:
Ubuntu 12.10
DC: samba 4.0.6 hostname, doloresdc.dolores.site, 192.168.1.100
Client: hostname, algorfa, DHCP
Realm: DOLORES.SITE

Get the latest sssd here.

##UPDATE: The latest sssd 1.10.1 now includes sssd dynamic dns updates for our Linux clients.

smb.conf, DC
[global]
workgroup = DOLORES
realm = DOLORES.SITE
netbios name = DOLORESDC
server role = active directory domain controller
dns forwarder = 192.168.1.1
idmap_ldb:use rfc2307 = yes

[netlogon]
path = /usr/local/samba/var/locks/sysvol/dolores.site/scripts
read only = No

[sysvol]
path = /usr/local/samba/var/locks/sysvol
read only = No

[users]
path = /home/users
read only = No

[profiles]
 path = /home/profiles
 read only = No

keytabs for the DC
If you are installing sssd on the DC then you'll need a keytab:
samba-tool domain exportkeytab /etc/krb5.keytab --principal=DOLORESDC$

smb.conf client
[global]
workgroup = DOLORES
realm = DOLORES.SITE
security = ADS
kerberos method = system keytab

sssd versions 1.9.6 and earlier
/etc/sssd/sssd.conf on the DC. Same for the client except for one line. See the comments which begin '##'.

[sssd]
services = nss, pam
config_file_version = 2
domains = default
[nss]
[pam]
[domain/default]
ldap_schema = rfc2307bis
access_provider = simple
enumerate = FALSE
cache_credentials = true
id_provider = ldap
auth_provider = krb5
chpass_provider = krb5
krb5_realm = DOLORES.SITE
krb5_server = doloresdc.dolores.site
krb5_kpasswd = doloresdc.dolores.site
ldap_referrals = false
ldap_uri = ldap://doloresdc.dolores.site/
ldap_search_base = dc=hh3,dc=site
ldap_user_search_base = cn=Users,dc=dolores,dc=site
#ldap_tls_cacertdir = /usr/local/samba/private/tls
#ldap_id_use_start_tls = true
ldap_user_object_class = user
ldap_user_name = samAccountName
ldap_user_uid_number = uidNumber
ldap_user_gid_number = gidNumber
ldap_user_home_directory = unixHomeDirectory
ldap_user_shell = loginShell
ldap_group_object_class = group
ldap_group_search_base = cn=Users,dc=dolores,dc=site
ldap_group_name = cn
ldap_group_member = member
#ldap_user_search_filter =(&(objectCategory=User)(uidNumber=*))
ldap_sasl_mech = gssapi
ldap_sasl_authid = DOLORESDC$
##for the client use:
## ldap_sasl_authid=ALGORFA$
krb5_keytab = /etc/krb5.keytab
ldap_krb5_init_creds = true

sssd versions 1.10.0 and above /usr/local/etc/sssd/sssd.conf
[sssd]
services = nss, pam
config_file_version = 2
domains = default
[nss]
[pam]
[domain/default]
#debug_level=6
dyndns_update=true
#dyndns_refresh_interval=16
ad_hostname = pinoso.hh3.site
ad_server = hh16.hh3.site
ad_domain = hh3.site
ldap_schema = ad
id_provider = ldap
access_provider = simple
enumerate = FALSE
cache_credentials = true
#entry_cache_timeout = 60
auth_provider = ad
chpass_provider = ad
krb5_realm = HH3.SITE
krb5_server = hh16.hh3.site
krb5_kpasswd = hh16.hh3.site

ldap_id_mapping=false
ldap_referrals = False
ldap_uri = ldap://hh16.hh3.site
ldap_search_base = dc=hh3,dc=site
ldap_user_search_base = dc=hh3,dc=site
#ldap_tls_cacertdir = /usr/local/samba/private/tls
#ldap_id_use_start_tls = true
#entry_negative_timeout = 1
ldap_user_object_class = user
ldap_user_name = samAccountName
ldap_user_uid_number = uidNumber
ldap_user_gid_number = gidNumber
ldap_user_home_directory = unixHomeDirectory
ldap_user_shell = loginShell
ldap_group_object_class = group
ldap_group_search_base = cn=Users,dc=hh3,dc=site
ldap_group_name = cn
ldap_group_member = member

ldap_sasl_mech = gssapi
ldap_sasl_authid = PINOSO@HH3.SITE
krb5_keytab = /etc/krb5.keytab
ldap_krb5_init_creds = true

We use autofs for the clients:

/etc/auto.master
/home/users /etc/auto.users

/etc/auto.users
* -fstype=cifs,sec=krb5,multiuser,username=ALGORFA$ ://doloresdc/users/&

Method
- join the domain
Add:
127.0.0.1 algorfa.dolores.site localhost
127.0.0.1 algorfa 
to /etc/hosts
and make sure that /etc/hostname conatns only algorfa without the domain.
hostname -s MUST return just algorfa and hostname -f must return algorfa.dolores.site
Go no further until they do.
Now adjust your primary DNS to point at 192.168.1.100 with dolores.site as the only search domain.
Then take a deep breath and:
sudo net ads join -UAdministrator

- restart the services
sudo service sssd restart
sudo service autofs restart

To make things humanly possible, here is part of our script to add users and groups on the DC. Although not needed for AD, we add the posixAccount onbectClass. This seems to speed up lookups. It should get you started. The full suite, s4bind,  is available here. Here is part of the script to add a user:

## UPDATE: Recent versions of Samba4 allow you to add the attributes when you create new users:
samba-tool user add steve --uid-number=3000021 --gid-number=20513 --login-shell=/bin/bash

#!/bin/bash 
function useradd {
###Creates a user in the Domain Users Group with a /$BASEDIR/$2/$1 in
### e.g. if BASEDIR (set in the setup file) is 'home' then
### s4bind useradd steve2 users
### the user will have his home directory at /home/users/steve2
#Pls set /home to wherever you like in the file setup
#
# We have already posix-ified Domain Users with the gidNumber 20513
# s4bind upgradegroup "Domain Users" 20513
#
echo user: $1
echo share/folder: $2

a="/$BASEDIR/$2"
if [ ! -d "$a" ]
then
echo Directory $a does not exist
exit 1
fi

a=$(check -u "$1")

if [ "$a" == "y" ]
then
echo "$1 already exists"
exit 0
fi

gid=$(ldbsearch --url=$db $auth cn="Domain Users" | grep gidNumber| cut -d ":" -f 2)
if [ -z $gid ]
then
echo "This looks like the first run. Domain Users not yet upgdraded"
echo Please try e.g. s4bind setgid "Domain Users" 20513
exit 1
fi

echo "Creating user $1"
echo "Pls enter passwd for $1"
samba-tool user add $1
samba-tool user setexpiry $1 --noexpiry

# get the uidNumber 
#getent passwd | cut -d ":" -f3 | sort -n > /tmp/uid.txt
#maxnum=$(sort -n /tmp/uid.txt |tail -1)
#uid=$(expr $maxnum + 1)
uid=$(wbinfo -i $1 | cut -d ":" -f3)
echo "Allocating uidNumber = $uid"

unixhome="/$BASEDIR/$2/$1"

echo $unixhome

echo "dn: cn=$1,cn=Users,$basedn
changetype: modify
add: objectClass
objectClass: posixAccount
-
add: uidNumber
uidNumber: $uid
-
add: gidNumber
gidNumber: $gid
-
add:unixHomeDirectory
unixHomeDirectory: $unixhome
-
add: loginShell
loginShell: /bin/bash" > /tmp/$1
ldbmodify --url=$db $auth /tmp/$1
echo sleeping. . .
sleep 10
if [ -d "$unixhome" ]
then
echo "Home folder already exists. Use it? Y or N"
read D
if [ $D == "Y" ]
then
chown -R $1:Domain\ Users $unixhome
fi
else
#cp -a /data/user-template $unixhome
mkdir $unixhome
chown -R "$1":"Domain Users" $unixhome
fi

echo "dn: CN=$1,CN=Users,$basedn
changetype: modify
add: profilePath
profilePath: \\\\$HOSTNAME\\profiles\\$1
-
add: homeDrive
homeDrive: Z:
-
add: homeDirectory
homeDirectory: \\\\$HOSTNAME\\$2\\$1" > /tmp/$1
sleep 1
ldbmodify --url=$db $auth /tmp/$1
samba-tool user setexpiry $1 --noexpiry

echo "New user: $1"
echo "uidNumber: $uid"
echo "gidNumber: " $gid
echo "Group: Domain Users"
getent passwd $1
echo "user SID " $(wbinfo --uid-to-sid=$uid)
ldbsearch --url=$db $auth cn=$1 | grep \\\\$HOSTNAME
ldbsearch --url=$db $auth cn=$1 | grep homeDrive
rm /tmp/$1
}