How to set up a CIFS Multiuser Mount
CIFS is a session-based protocol. This means that the session runs with the privileges of the user who logged on for the CIFS session. Therefore, the normal way of using CIFS is to mount the shares at user login time with the privileges of the user logging in. This is what the protocol was designed for.
Nontheless, the Linux CIFS driver offers a way to mount the share at startup time already. This is called a multiuser mount. The strategy for a multiuser mount is to mount the share at startup time with minimal privileges. For every user accessing the share, the CIFS driver will internally create a separate CIFS session with the server.
When a user accesses the multiuser-mounted share for the first time, the CIFS driver needs to create a CIFS session with the fileserver for this user. This requires security information, e.g. a username and a password. Because the driver cannot prompt for login data, it will look into the kernel keyring for the current Linux user. If a suitable security information can be found, then the CIFS driver will use it to create a CIFS session for the current user with the fileserver and the user can access the share.
This post may look like a howto, but in fact it is meant as a collection of possible pitfalls.
Step 1: Create a share SHARE
at the fileserver FILESERVER
and a local user CIFS_GUEST
on the fileserver with minimal privileges. The user must only be allowed to mount the share from a remote machine. The password of the user must never expire.
Notes & Pitfalls:
- The user does not need to be in the local "Remote Desktop Users" group of
FILESERVER
.
If the share SHARE
is a so-called "administrative share", then the users (including CIFS_GUEST
) would have to have administrative privileges. It is recommended to create a share of the normal, non-administrative type.
Step 2: Mount the share from your Linux machine, e.g.
mount.cifs //FILESERVER/SHARE /mnt --verbose -o domain=FILESERVER,username=CIFS_GUEST
This should mount the share properly. If not, I recommend a look at the manpage mount.cifs(8)
.
Notes & Pitfalls:
- Make sure to specify the option
domain=FILESERVER
. Otherwise, the fileserver may assume that CIFS_GUEST
is a domain (non-local) user and deny access.
- If you run into trouble with authentication, check the logs of the server(e.g. Windows event logs in case of a Windows fileserver)
- You may want to add the mount option
noperm
to disable permission checking on the client side. The permissions are enforced by the server anyway.
Step 3: Mount again with the multiuser
option:
umount /mnt
mount.cifs //FILESERVER/SHARE /mnt -v -o multiuser,domain=FILESERVER,username=CIFS_GUEST
Verify that multiuser
has been used:
mount | grep cifs
Step 4: Create a credentials file for automatic, non-interactive mounting. Protect it against all non-root access.
File contents of /etc/cifs.SHARE.cred
:
username=CIFS_GUEST
password=<pass>
Domain=FILESERVER
Then execute:
chown root /etc/cifs.SHARE.cred
chmod 600 /etc/cifs.SHARE.cred
Notes & Pitfalls:
- Make sure that the credentials file does not contain a byte order mark (BOM) when using UTF-8 encoding. Otherwise you may get a spurious "Credential formatted incorrectly" message from
mount.cifs
.
Step 5: Try to Mount the share with the credentials file. This should be completely non-interactive now:
umount /mnt
mount.cifs //FILESERVER/SHARE /mnt -v -o multiuser,credentials=/etc/cifs.SHARE.cred
If this works, you can add the mount to /etc/fstab
:
...
//FILESERVER/SHARE /mnt cifs rw,auto,multiuser,credentials=/etc/cifs.SHARE.cred 0 0
...
Notes & Pitfalls:
- The option
auto
has been added for automatic mounting of the share.
Step 6: Login as normal user at the Linux machine now. Try to access the mounted share, e.g.
cd /mnt
ls
The permission should be denied.
Then, manually store CIFS credentials in the session keyring:
cifscreds add FILESERVER -u <username>
You will be prompted for a password. Afterwards, you should be able to access the share, if <username>
has access permission for the share on the fileserver.
Notes & Pitfalls:
- You can use your Windows Explorer to verify that
<username>
has Access permissions for the share. This way, you can rule out that the error is on FILESERVER
.
- If
cifscreds
gives a warning about a non-persistent session keyring, then type keyctl session
and try again.
- You can display the contents of the keyring with
keyctl show -3
.
- The
cifscreds
will not create the CIFS session with the fileserver. It merely puts security info into the keyring, so that the CIFS driver can use it to create a CIFS session when you access the share. This means that changing the key in the keyring with cifscreds update ...
will leave you logged on with the old user (!).
Step 7: Finally, the step of feeding the keyring can be automatized. As root, add the following lines to your PAM configuration (e.g. /etc/pam.d/login
):
...
auth optional pam_cifscreds.so debug
...
session optional pam_cifscreds.so domain=<AD Domain> debug
...
The first line captures the password on login. The password is stored until the session is created. When the session is created, then the second line will put the record into the keyring. There will be no need to call cifscreds
and the share should be accessible immediately after login.
Notes & Pitfalls:
- You may want to remove the
debug
option after testing to reduce logging verbosity.
- Make sure that both lines are executed in every case in the PAM stack. (sequence of entries in the configuration file)
- You can replace the
optional
with required
to enforce authentication with the fileserver.
- Before the second line, the existence of a permanent session keyring should be ensured. If in doubt, add the following line immediately before the second line:
session required pam_keyinit.so
- Both lines should leave a messages in the system logs when using the
debug
option.
- The same modifications should also be made to the configuration of other PAM-Aware login programs, e.g. to
/etc/pam.d/sshd
, /etc/pam.d/xdm
, ...
Up to this point, the access permissions to files and folders on the share are enforced by the FILESERVER
. The permissions, user names and group names displayed on the Linux side are completely wrong. In order to get them properly, add the mount option cifsacl
and set identity mapping. However, this probably requires, among other things, setting up the Winbind Service. Additional information can be found in the manpage mount.cifs(8)
.