Context
We have a Windows server with an Active Directory domain and a network share.
I have a Linux machine and I want to mount the share.
sudo mount -t cifs //server/share /mnt/share -o user=[act-dir user],domain=[domain],uid=[linux user],gid=[linux group]
It's more or less OK. My Linux user gets mapped to all files on the share and some of the ACL are translated. But I want to go a level further:
- More than one user is connected to the Linux box
- Each Linux user has a dedicated Active Directory account
- I want each Windows owner to be mapped to the corresponding Linux owner if it exists
A solution and the problem
Samba offers the mount option cifsacl
which requires to set-up cifs.idmap
and winbindd
. Both are installed, I've read both man pages and tried to configure them but it does not work. The newly mount command is now:
sudo mount -t cifs //server/share /mnt/share -o user=[act-dir user],domain=[domain],cifsacl
But everything is mapped to root:root, which means the cifs.idmap could not be performed.
Actually, I'm not all surprised because I did not understand where to write the actual mapping so where should I write that Windows userX actually maps to Linux userY? And I'm not sure that the winbindd configuration is correct, what should be the minimum set of parameters and is smbd and/or nmbd require to run? Do I need to open the port in the firewall?
Background infos
Share structure
The shared directory has several sub directories, some commons and some "privates" (although the private ones are actually readable by everyone). Each user would need to access from time to time the common space, and also other user private directories, but mainly/often their own directory.
Tech data
- RHEL 6, Samba 3.5.6
- Ubuntu 12.04, Samba 3.6.3
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 fileserverFILESERVER
and a local userCIFS_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:
FILESERVER
.If the share
SHARE
is a so-called "administrative share", then the users (includingCIFS_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:
domain=FILESERVER
. Otherwise, the fileserver may assume thatCIFS_GUEST
is a domain (non-local) user and deny access.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:Verify that
multiuser
has been used: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
:Then execute:
Notes & Pitfalls:
mount.cifs
.Step 5: Try to Mount the share with the credentials file. This should be completely non-interactive now:
If this works, you can add the mount to
/etc/fstab
:Notes & Pitfalls:
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.
The permission should be denied.
Then, manually store CIFS credentials in the session keyring:
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:
<username>
has Access permissions for the share. This way, you can rule out that the error is onFILESERVER
.cifscreds
gives a warning about a non-persistent session keyring, then typekeyctl session
and try again.keyctl show -3
.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 withcifscreds 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
):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:
debug
option after testing to reduce logging verbosity.optional
withrequired
to enforce authentication with the fileserver.session required pam_keyinit.so
debug
option./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 optioncifsacl
and set identity mapping. However, this probably requires, among other things, setting up the Winbind Service. Additional information can be found in the manpagemount.cifs(8)
.You would probably need to use the username map functionality inside samba (winbind) for the mapping to work so that winbind knows about the AD account for every Linux user. I believe username map can take commands and lists (and some pattern conversions), but it's far easier if the Linux usernames can match the AD usernames, by using pam_winbind for instance. I guess that when the mapping is working you can actually start verifying whether the share is working as well.