I have a question about access control in Apache 2. I don't think it's relevant, but I'm running it on a Raspberry Pi 2 with Raspbian.
There are multiple users that can use the website. However, there is one folder in which every user has his own folder. Every user should only have access to his own folder, and no other folders.
The problem I have is that it seems that the only way to do this is by adding each folder to the configuration file, which makes it rather time-intensive to add a user. So is there another way?
x
, y
and z
.https://example.com/
, but no user other than user x
should have access to https://example.com/private/x/
, no one besides user y
should have access to https://example.com/private/y/
, and only user z
should have access to https://example.com/private/z/
.
/private
, in the hope I could then give the different users access to their respective folders./private/%{REMOTE_USER}/
and /private/%{REMOTE_IDENT}/
, which both didn't work.<If>
directive to check if the URL matched to /private/%{REMOTE_USER}/
, but that didn't work either.
I've tried to find something in the apache documentation that can help me, but I couldn't find anything that could bring me closer to the answer.
PS: I almost forgot and I'm not sure if it's relevant, but the authentication is done using PAM, in about the following manner:
<IfModule mod_authnz_external.c>
AddExternalAuth pwauth /usr/sbin/pwauth
SetExternalAuthMethod pwauth pipe
AddExternalGroupMethod unixgroup environment
</IfModule>
AuthType Basic
AuthBasicProvider external
AuthExternal pwauth
GroupExternal unixgroup
Require unix-group www-priv
From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of URLs to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.
<LocationMatch "^/combined/(?<sitename>[^/]+)">
require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</LocationMatch>
(Last part of the LocationMatch directive from the apache documentation.)
Now I thought to make use of this in the following manner:
<LocationMatch "^/private/(?<user>[^/]+)">
Require expr "%{REMOTE_USER} == %{MATCH_USER}"
</LocationMatch>
But Apache now won't restart. It will restart when the Require
line is commented out, but not otherwise. The following did not work either:
<LocationMatch "^/private/(?<user>[^/]+)">
<RequireAll>
Require valid-user
Require expr "%{REMOTE_USER} == %{MATCH_USER}"
<RequireAll>
</LocationMatch>
So I'm still looking to solve this question, but the focus has shifted slightly. If there is an answer to How can I use Require
to check if the authenticated user is the user from a variable?, then that would possibly solve the whole question.
As always, thanks in advance for any input!
Desirius
Edit 2:
I found out that also Require expr "true"
does not work. I'm suspecting Require expr
to create the problems...
Ok, I've found the answer. Just after I edited my question, I found the remark at the Require Directives: Since v2.4.8, expressions are supported within the user require directives.
.
So I realized I could just use Require user "%{env:MATCH_USER}"
(together with the part from my edit).
To give a more complete picture, this is what the configuration looks like now:
<IfModule mod_authnz_external.c>
AddExternalAuth pwauth /usr/sbin/pwauth
SetExternalAuthMethod pwauth pipe
AddExternalGroupMethod unixgroup environment
</IfModule>
AuthType Basic
AuthBasicProvider external
AuthExternal pwauth
GroupExternal unixgroup
Require unix-group www-priv
<Location /private>
Require all denied
</Location>
<LocationMatch "^/radicale/(?<user>[^/]+)">
Require user "%{env:MATCH_USER}"
</LocationMatch>
To everyone who took the time to read my question, I thank you!
I hope this answer will help someone else one day.