HOWTO: setup home directories with debian, pam_mount, smbfs/cifs, sshd

Setting up SAMBA based home directories on a Linux workstation can be a rather painfull experience. I'll explain the settings we had to change on a debian (etch) Linux client to make it work with a Linux based SAMBA server (PDC).

Before you follow this guide: pam_cifs and/or ldap may be a better choice depending on what you try to achieve.

This howto does not strive to be a complete help guide! These settings work for us, your mileage may vary. I do not explain the settings in detail but

man smb.conf
can be of help to understand them;-)

CHALLENGES:

PRE-SETUP:

You may want to start with a system update, in other words

apt-get update
apt-get install kernel-image-2.6-686
apt-get dist-upgrade
update-grub
sync
reboot

PKG INSTALL:

The packages we need for this to work are:

apt-get install winbind
apt-get install smbfs
apt-get install libpam-mount
apt-get install lsof

cd /usr/lib/
ln -s /lib/libnss_wins.so.2 libnss_wins.so
ln -s /lib/libnss_winbind.so.2 libnss_winbind.so

GET WINBIND UP:

We need to edit the /etc/samba/smb.conf settings to set the right domain name. Here is a sample setup for the machine fast02 in the domain GZH with the primary domain controller (PDC) at 10.10.10.5

   workgroup = GZH
   netbios name = fast02
   server string = %h server (Samba %v)
   wins support = no
   wins server = 10.10.10.5
   dns proxy = no

   log level = 1
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0

   security = domain
   encrypt passwords = true
   obey pam restrictions = yes
   invalid users = root
   unix password sync = no

   load printers = no
   disable spoolss = yes
   socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

   winbind use default domain = yes
   #winbind separator =
   idmap backend = rid:"BUILTIN=2000-9999,GZH=10000-50000"
   allow trusted domains = No
   idmap uid = 2000-50000
   idmap gid = 2000-50000
   winbind enum users = yes
   winbind enum groups = yes
   template shell = /bin/bash
   # use %U for the user, use %D for the domain
   template homedir = /import/smbhome/%U
   #template primary group = users

Once you have smb.conf configured, you are ready to join the domain.

/etc/init.d/winbind stop; /etc/init.d/samba stop
/etc/init.d/samba start; /etc/init.d/winbind start
net join GZH -S <your_server_name> -U <your_domain_admin>

As you may notice we are using the rid backend to map windows user/group sids to unix uid/gid. This gives a consistent mapping accross client unix machines (lower limit + last part of sid). Make sure that the results are within the upper limit.

However, be aware that winbindd has an unexpected memory - once it has mapped a sid to a uid it stores the results in its tdb files to keep the mapping constant - even if the backend is rid. If you want to change your mappings you also have to delete these files. Also removing group mappings from previous configurations can be grucial.

/etc/init.d/winbind stop
rm -f /var/cache/sammba/winbindd_cache.tdb
rm -rf /var/lib/samba/winbindd_idmap.tdb
net groupmap cleanup
/etc/init.d/winbind start

You are ready to check if winbind is working. With

wbinfo -p
wbinfo -g
wbinfo -u

If this worked, we shall get winbind into our user/group name resolution; so let's edit /etc/nsswitch.conf . Be sure to make a backup and dont log out, before you either made it work or copied back the old version.

passwd:         files winbind
group:          files winbind
shadow:         compat
hosts:          files wins dns
networks:       files

Having done this, we should be able to see the users and groups with getent.

getent group
getent passwd
groups <some_user_name>

Some people have trouble when their windows group names contain spaces. So you may want to consider renaming those i.e.

net rpc group rename "Domain Users" "Domain_Users" -U <your_domain_admin>

SSH SETUP (PAM):

In order for pam_mount to work with ssh, we need to change the /etc/ssh/sshd_config settings. Make sure that you understand what this change means in terms of security (I mean it). Make your backup copy and do not log out until it works or you restored the backup.

ChallengeResponseAuthentication no
PasswordAuthentication yes
UsePAM yes

You will have to restart sshd to see if your system still works. sshd is pretty smart about restarting itself - existing sessions stay open, so you can do this from remote.

/etc/init.d/ssh reload

After the ssh restart, make sure that you can still login - especially as root.

PAM_MOUNT SETUP:

This is where the real fun begins. You will be modifying the pam settings. Please be aware, that PAM is anything but trivial. Doing a wrong manipulation may lock you out of your system to the point where only single user mode works. So backup any pam file you change and dont logout your primary ssh session before you verified (in a different session) that you can still login!

The following assumes that your system is setup rather defaultish - i.e. the pam config files for the different daemans import common-auth and common-session. Here are the settings that work for us.

/etc/pam.d/common-auth

# allow users with valid unix account or valid winbind account
# success=3 jumps over the next 3 commands
auth    [success=2 default=ignore]      pam_unix.so nullok_secure
auth    [success=1 default=ignore]      pam_winbind.so  use_first_pass
auth    requisite       pam_deny.so
auth    optional        pam_mount.so    use_first_pass

/etc/pam.d/common-session

session required        pam_unix.so

# we create the user home directory as a mount point for smbmount
session optional        pam_mkhomedir.so silent
session optional        pam_mount.so

In the session phase pam_mount tries to mount the user home directory. For this to work, the mount point needs to exist - hence I'm calling pam_mkhomedir. The session entry is also responsibe for unmounting (end of session).

In the auth phase, pam_mount does nothing but storing the user password. This is confusing, but it's the only way for pam_mount to get hold of the password for the later mounting process. We deliberatly use the rather convincing "goto" style configuration where pam_unix and pam_winbind are called before pam_mount and pam_mount is never called if the login didn't succeed. As pam_mount is no longer maintained, this is mainly to give a little protection against possible remote exploits in pam_mount.

pam_mount uses a counter to decide when a user is no longer logged in and his share can be unmounted. We need to create the directory for the counters and set the permissions:

mkdir /var/run/pam_mount/
chmod 777 /var/run/pam_mount/

I'm not kidding - this is world writable. You may find a smarter solution for your specific setup later on, but keep it like this for the moment. pam_mount will be called by a user process when trying to unmount and it tries to unlink its file in /var/run/pam_mount/.

Last step is to tell pam_mount about our required mounts. We need to change /etc/security/pam_mount.conf

smbmount /usr/bin/sudo -u \#%(USERUID) -P /usr/bin/smbmount   //%(SERVER)/%(VOLUME) %(MNTPT) -o "username=%(USER),uid=%(USERUID),gid=100%(before=\",\" OPTIONS)"
volume * smbfs filer_zh_1 & /import/smbhome/& - - -

The first line is not strictly required. However, without the sudo trick you may realise, that user home directories are not correctly unmounted on logout. That's because the mount is performed while sshd is still running with uid=root but the unmount happens when sshd runs with uid=<the_user_uid>

GO:

Well that's it. I hope I didn't forget any other changes I had to made to the system.

LINKS:

(c) joachim(et)buechse.ch. This description is in the public domain.