Mounting WebDAV resources with pam_mount
February 2022 (republished in March 2026)
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Trying to mount a WebDAV resource at SSH login via pam_mount on a Ubuntu 20.04 server I had to realize that this is not as straight forward as it should be. Although there is mount.davfs, a buggy security feature in pam_mount and permission problems with storing secrets in a user-owned file prevent using the obvious combination of pam_mount and mount.davfs. In the end I had to use the rather old and no longer maintained wdfs tool and FUSE to get things working.
Fiddling with this problem took several hours. Mounting WebDAV resources via pam_mount seems to be a rarely used feature, at least in my desired user configurable setting. Searching the web yields only very few results, most of them outdated. So here comes an up-to-date account of mounting WebDAV resources at login on a Linux machine.
What we want to achieve
On a multi-user Linux server we want to mount WebDAV resources (cloud storage) specified and owned by the user. The user shall be able to control which resources to mount (personal cloud storage) and the admin shouldn’t be involved in managing secrets required for accessing the user’s WebDAV resources. Of course, if the user stores its secrets to a file in his home directory the admin may see them. But writing secrets to a file shouldn’t be done by the admin, so a well-behaved admin won’t ever see them.
Attempt 1: per-user pam_mount configuration (failed)
Having a line
<luserconf name=".pam_mount.conf.xml" />
in pam_mount’s global configuration file /etc/security/pam_mount.conf.xml allows for additional user-owned configuration files /home/username/.pam_mount.conf.xml. Such user-owned configuration files may contain additional <volume>...</volume> sections, which are only evaluated if the corresponding user logs in to the server. If you use this feature, don’t forget to set
<mntoptions allow="..." />
<mntoptions deny="..." />
<mntoptions require="..." />
in the global configuration file to values appropriate for your setting and users.
To mount a WebDAV resource, the user has to put
<volume fstype="davfs" path="WEBDAV_URL" options="SOME_OPTIONS" />
into its .pam_mount.conf.xml. Secrets will be read from the file ~/.davfs2/secrets or may be specified as username=WEBDAV_USERNAME,password=WEBDAV_PASSWORD in options attribute.
This obvious setup fails due to a bug in pam_mount. To prevent users doing bad things in their .pam_mount.conf.xml pam_mount checks whether the resource to mount is a file owned by the user. Of course, there are some exceptions for remote resources, but file systems of type davfs are not considered to be remote by pam_mount. Logs show
(rdconf2.c:132):
user-defined volume (https://location/of/webdav), volume not owned by user
Thinking that the specified path goes to a file in the server’s file system, pam_mount tries to get its ownership, which fails. So using davfs in user-specified volume descriptions for pam_mount doesn’t work.
I did not write a bug report on this issue for two reasons:
- Development of
pam_mountisn’t really active, an increasing problem with several widely used but not so prominent open source tools. - Having the bug fixed, we would run into permission problems caused by
davfs’s security measures. During loginpam_mountis run as root anddavfsexpects the secrets file to be owned by the mounting user (that is, by root) and to have permissions600. So the user won’t be able to access its secrets file. See below for details.
Attempt 2: davfs in the global pam_mount config file (failed)
In my setup there is a cloud service potentially used by all users. So at least this WebDAV resource could be configured in the global pam_mount config file. Secrets should be kept in user-owned secrets files. Using pam_mount’s variables like %(USER) the volume specification looks the same for all users (luckily, user names in the resource’s URL are identical to the server’s user names). The secrets file’s permission has to be 600 and the file has to be owned by the user and the user’s group. That’s an explicit requirement by mount.davfs.
First log in with this new configuration shows
(mount.c:76): /sbin/mount.davfs:
file /home/username/.davfs2/secrets has wrong owner
in the logs. The reason for this failure is that pam_mount is run as root and root doesn’t own the user’s secrets file.
A way out would be to provide user secretes as options, requiring one volume block per user in the config file. But then the admin would have to explicitly ask all users for their cloud passwords. Not an acceptable solution in my setting. So mount.davfs is dead for my purposes.
Attempt 3: using FUSE with something similar to sshfs (successful)
Trying to get attempt 1 fixed (configuration by user) we have to find a file system type considered “remote” by pam_mount and being flexible enough to cope with WebDAV. A good candidate is type="fuse", which I already use to mount via SSH using sshfs. The problem is to find something similar to sshfs which mounts WebDAV resources. With sshfs we may run sshfs SERVER MOUNT_POINT from the shell to mount via SSH. So we need a program doing the same thing with WebDAV.
Searching the web yields two candidates:
fusedav, last updated in 2006,wdfs, last updated 2007, moved to a GitHub repository by someone in 2010 with minor updates in 2015.
So let’s try wdfs. It’s not packaged with Ubuntu, we have to compile it on our own. First clone the git repository:
cd ~
git clone https://github.com/jmesmon/wdfs
cd wdfs
Then install dependencies (running configure tells us what’s missing):
sudo apt install libglib2.0-dev libfuse-dev libneon27-dev
Compile and install (autoreconf seems to be needed due to some time stamp issues caused by using git):
autoreconf -f -i
./configure
make
sudo make install
Successful?
wdfs -h
It remains to put
<volume
fstype="fuse"
path="wdfs#https://location/of/webdav"
mountpoint="/home/username/mount_point"
options="password=WEBDAV_PASSWORD,username=WEBDAV_USERNAME,
nodev,nosuid,uid=%(USERUID),gid=%(USERGID)"
/>
into the user-owned .pam_mount.conf.xml and mounting at login works like a charme.