"Excuse me please. My ear is full of milk..."

– Oliver Hardy, Going Bye Bye (1934)

Skip on down to the menu.

Using pam_mount

This article describes what I've done in openSUSE 10.2 to automatically mount user network shares. It should probably work in many other distributions, but I'm not making any guarantees because I currently don't use any others.

For some time I tried and tried to use pam_mount to mount user shares on login, but could never get it to work. Finally I figured out that the problem was due to the Samba winbind separator.

The problem occurs because the winbind separator is set to "\". Windows likes this as the winbind separator, since it is the native separator for Active Directory, but many Linux applications treat the "\" character as the escape character and the winbind separator disappears. For example, the command "user=DOMAIN\username" becomes "user=DOMAINusername".

This happens when pam_mount.conf passes the DOMAIN\username and DOMAIN\groupname to mount, mount.cifs, smbmount, or whatever.

To rectify this situation I wrote a perl script to replace all occurences of the "DOMAIN" with "DOMAIN\\". The first "\" character escapes the second "\" character, thus the correct DOMAIN\username is sent.

Here's a listing of the script minus most of the comments.

#!/usr/bin/perl -w

# pam-mount-cifs.pl
#
# Revision History
#   2007-07-27, Tom Sneddon (tsneddonexcusemeplease.org)
#     Initial release.

my @args = @ARGV;
my $domain = shift @args;
my $mount_prog = shift @args;
my $wb_separator = '\\';
for (@args) {
  s/=$domain/=$domain$wb_separator/g;
  $cmd_line .= "$_ ";
}
qx($mount_prog $cmd_line);

To minimize unwanted replacements in other command line parameters, this script only replaces the DOMAIN if it directly follows a "=". Not very sophisticated, but it's better than nothing.

Note: The above instructions use DOMAIN to illustrate the domain name. The actual domain name is passed to this script as the second parameter (see below).

Usage:

pam-mount-cifs.pl DOMAIN /my/mount/program param1 param2 ... param(n)

  where: pam-mount-cifs.pl = This program
         DOMAIN = The Windows domain name.  Always use UPPER CASE.
         /my/mount/program = The full path to whatever program
                             actually mounts the network share.
                             Examples: /bin/mount
                                       /sbin/mount.cifs
         param1 ... param(n) = Command line parameters sent from
                               pam_mount to /my/mount/program.

How to configure pam_mount.conf:

Change the cifs mount line from

    cifsmount /bin/mount -t cifs //%(SERVER)/%(VOLUME) %(MNTPT) -osmbf 
    "user=%(USER),uid=%(USERUID),gid=%(USERGID)%(before=\",\" OPTIONS)"

 - or -

    cifsmount /sbin/mount.cifs //%(SERVER)/%(VOLUME) %(MNTPT) -o 
    "username=%(USER),uid=%(USERUID),gid=%(USERGID)%(before=\",\" OPTIONS)"

 - to -

    cifsmount /usr/bin/pam-mount-cifs.pl DOMAIN 
    /sbin/mount.cifs //%(SERVER)/%(VOLUME) %(MNTPT) -o 
    "username=%(USER),uid=%(USERUID),gid=%(USERGID)%(before=\",\" OPTIONS)"

Each of the preceeding commands is to be written on one continuous line. The modified configuration above is indicating that the pam-mount-cifs.pl script is located in the /usr/bin directory. You may want something different.

volume commands in pam_mount.conf become like the following

volume * cifs servername sharename ~/mount-point dmask=0751 - -

Don't add username, uid, gid or any other parameters or it probably won't work.

Mounting shared resources with spaces in the unc pathname can be problematic. I don't recommend it.

Good luck!

Tom Sneddon
2007-07-26