ADMIRAL ACL file access control
From ImageWeb
Contents |
Introduction
Controlling access to files for users connecting via CIFS (Samba), HTTP and WebDAV, ads well as local users, can be a tricky problem on Linux systems.
At heart, the problem occurs because the web server used for HTTP and WebDAV access always runs as user www-data and group www-data (or some local equivalents), so files created by these route will always have owner and group set as www-data. But for local access, and access via CIFS, files are created using the ownership of the authenticated user. Thus, it can be tricky for files created via HTTP to be properly accessible locally or via CIFS, and vice versa.
For example, we require that a file created by user "Alice" via HTTP or WebDAV can be read and modified by Alice using CIFS, but that the same file is protected from access by user "Bob" using any of these mechanisms. This requires that all files can potentially be updated by the web server (i.e. by user www-data), and that all files created by the web server are protected from access by some but not all users. We assume that the web server is configured and trusted to make appropriate access control decisions based on the user credentials it receives via HTTP requests.
The case of files created locally, or by CIFS, can be handled by arranging that all files are created with the appropriate user id and group www-data, and allowing user and group to have read/write access to all files. But, because Linux allows only one group to be associated with a file, this prevents using the group mechanism to allow some other user, such as a group leader, to have read-only access to all files. Using this mechanism, the converse case is even harder: for files created by the web server have owner and group www-data, so there is no way to allow any single user to have distinct access rights to such a file.
These problems are overcome using Linux file ACLs. File ACLs allow access control decisions be be made separately from the actual user or group ownership of a file, and can be inherited (or defaulted) from a parent directory without regard for the user/group of the creating process (assuming that process has rights to create the file in the first place).
Using ACLs, all files are created with full access for both the user who owns the directory and for www-data, so they can be updated either by the user concerned (locally or via CIFS), or by the web server. We still require the web server itself to make appropriate access control decisions. Additional ACLs can be set to allow arbitrary other users or groups to have specified levels of access to the files. By setting the required ACLs as defaults on a user's directory, we can ensure that all newly created files in this area have the same ACLs.
Prerequisites
To use ACLs, first install the "acl" package:
sudo apt-get install acl
Commands to create user directory ACLs
This sequence of commands would be used to create an area for use by Alice, within which Alice and www-data can read and write files, and members of group RGleader can read the files.
A particular point to note, which may not be obvious from the normal documentation, is that Alice must be given explicit permissions to files in her directories, otherwise she can't access files created via HTTP, which have www-data ownership.
# Create directory with "normal" access control limiting access to just "Alice" mkdir /home/data/Alice chown Alice:Alice /home/data/Alice chmod 700 /home/data/Alice # Is this needed? # chmod g-s /home/data/Alice # Allow group leader to read but not write Alice's files setfacl -m g:RGLeader:rx /home/data/Alice # Allow web server to read and write Alice's files setfacl -m u:www-data:rwx /home/data/Alice # Allow Alice to read and write Alice's files (!) # NOTE: this does not happen automatically for files created by www-data setfacl -m u:Alice:rwx /home/data/Alice # Make specified ACL default for newly created files (check this propagates downwards to subdirectories) getfacl --access /home/data/Alice | setfacl -d -M- /home/data/Alice
Apache web server access control configuration
As noted above, our scheme depends on the web server correctly applying access control decisions, because the file-system access control deployed provides a "pass all areas" to the web server.
Currently, this is being handled directives added to the Apache configuration, @@TODO: but some of these should be moved into .htaccess files created as users are added to the system. The current Apache access control configuration is along the lines shown below. For the most part, this consists of normal Apache access control directives, a little more complex than usual to allow for file writing and well as reading, and differentiating between users. @@TODO: It is the differentiation between users that should be moved to .htaccess files.
NOTE: references to user "GroupLeader" should become group "RGLeader"; i.e. a role-based rather than user-based permission - but we haven't been able to get this to work so far.
Alias /webdav /home/data <Directory /home/data/> Options Indexes MultiViews AllowOverride None Order allow,deny allow from all </Directory> <Location /webdav> Dav On AuthName "Restricted" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative on AuthLDAPURL "ldap://zoo-admiral-silk.zoo.ox.ac.uk:389/dc=zoo-admiral-silk,dc=zoo,dc=ox,dc=ac,dc=uk" AuthLDAPBindDN "cn=admin,dc=zoo-admiral-silk,dc=zoo,dc=ox,dc=ac,dc=uk" AuthLDAPBindPassword "..." Require valid-user </Location> <Location /webdav/UserA> <LimitExcept REPORT GET OPTIONS PROPFIND> Require user UserA </LimitExcept> <Limit PROPFIND OPTIONS GET REPORT> Require user UserA GroupLeader </Limit> </Location> <Location /webdav/UserB> <LimitExcept REPORT GET OPTIONS PROPFIND> Require user UserB </LimitExcept> <Limit PROPFIND OPTIONS GET REPORT> Require user UserB GroupLeader </Limit> </Location> <Location /webdav/GroupLeader> Require user GroupLeader </Location> <Location /webdav/shared> Require group RGMember RGLeader </Location> <Location /webdav/public> <LimitExcept REPORT GET OPTIONS PROPFIND> </LimitExcept> </Location> </VirtualHost>

