Forum Moderators: phranque
We host reports meant for about 1000 users under a directory tree like "D:\Reports\<username>\". We wanted to provide access to users folder through web so that :
1. A logged in user goes straight to his folder
2. No user does not get access to others folders.
I hoped that I could get this done using mod_rewrite. But, I am unable to form the right RewriteCondition/RewriteRule for this. What I tried to do was :
----------------------------------
Alias /Reports "D:\Reports"
<Directory D:/Reports>
AuthType Basic
AuthName "Nothing"
AuthBasicProvider file
AuthUserFile conf/passwd
Require valid-user
RewriteEngine on
RewriteBase /Reports
RewriteCond %{REQUEST_URI}!^/Reports/%{REMOTE_USER}.* [NC]
RewriteRule ^.*$ /Reports/${REMOTE_USER}/ [NC,R,NS,L]
Options Indexes Multiviews FollowSymLinks
IndexOptions +HTMLTable +IgnoreCase +NameWidth=*
IndexIgnore *.log *.old *.png *.db
Order allow,deny
Allow from all
</Directory>
----------------------------------
From the logs I see that %{REMOTE_USER} in RewriteCond ConditionPattern is not evaluated. Going thourgh the Apache documentation, I realise that I can use only a regex there. Here is an edited sample of the log :
----------------------------------
strip per-dir prefix: D:/Reports/SUNILS/ -> SUNILS/
applying pattern '^.*$' to uri 'SUNILS/'
RewriteCond: input='/Reports/sunils/' pattern='!^/Reports/%{REMOTE_USER}.*' [NC] => matched
rewrite 'SUNILS/' -> '/Reports/sunils/'
explicitly forcing redirect with [10.10.0.3...]
trying to replace prefix D:/Reports/ with /Reports
escaping [10.10.0.3...] for redirect
redirect to [10.10.0.3...] [REDIRECT/302]
----------------------------------
Can any one suggest how to do it right?
TIA
Sunil
I'd suggest creating per-user directories, and having the reports appear in those private directories only after the user logs in to that directory (using mod_auth). You could also use per-user subdomains if that has any appeal to you or your users -- e.g. username.example.com/reports.
The report themselves could be generated and stored in a different location in the filespace, and only appear to be in a subdirectory of the user's subdirectory -- this implemented with mod_alias, an internal rewrite, or even *nix symbolic links.
Jim
[edited by: jdMorgan at 11:37 pm (utc) on Sep. 19, 2007]
Thank you for your quick response (and sorry about my delayed reply).
1. Could you elaborate on the idea of per user directory - is there a way to ensure that a user logs into his own directory only, without per directory configuration specifying require user directive?
2. Per-user sub-domain is difficult in our situation.
3. We are on Windows and symbolic links are also not possible.
I considered another option. I tried :
--------------------------------
Alias /vfolders "D:\vfolders"
RewriteLog logs/rewrite.log
RewriteLogLevel 9
RewriteMap testmap "prg:c:/perl/bin/perl.exe c:/Apache2/bin/rewritemap.pl"
<Directory "D:/vfolders>
Options Indexes Multiviews FollowSymLinks
Order allow,deny
Allow from all
AuthType Basic
AuthName "Nothing"
AuthBasicProvider file
AuthUserFile conf/passwd
Require valid-user
RewriteEngine on
RewriteBase /vfolders/
RewriteCond ${testmap:%{REQUEST_URI}:%{REMOTE_USER}} ^REWRITE$[NC]
RewriteRule ^.*$/vfolders/%{REMOTE_USER}/ [R,L,NS]
</Directory>
---------------------------------
# C:/Apache2/bin/rewritemap.pl listing :
$¦=1;
while(<STDIN>){
chomp; my ($URI,$USER)=(split /:/);
print "REWRITE\n" unless $URI=~/^\/vfolders\/$USER/;
}
---------------------------------
and edited output of rewrite.log on "curl -u sunils:password [localhost...] is :
---------------------------------
11:26:40 initial (3) [perdir D:/vfolders/] add path info postfix: D:/vfolders/abcd -> D:/vfolders/abcd/
11:26:40 initial (3) [perdir D:/vfolders/] strip per-dir prefix: D:/vfolders/abcd/ -> abcd/
11:26:40 initial (3) [perdir D:/vfolders/] applying pattern '^.*$' to uri 'abcd/'
11:26:40 initial (5) map lookup FAILED: map=testmap key=/vfolders/abcd/:sunils
11:26:40 initial (4) [perdir D:/vfolders/] RewriteCond: input='' pattern='^REWRITE$' [NC] => not-matched
11:26:40 initial (1) [perdir D:/vfolders/] pass through D:/vfolders/abcd
---------------------------------
Apparently rewritemap program is not executed and consequently RewriteCond had a '' to compare with pattern. I tried rewritemap.exe (compiled version) too. Is there any other directive on which execution of prg:program would depend?
Regards
Sunil
Well, my OS is Windows. #! does not apply there, right?
As you can see the line in httpd.conf includes path to interpreter :
RewriteMap testmap "prg:c:/perl/bin/perl.exe c:/Apache2/bin/rewritemap.pl"
Besides, as I had mentioned earlier, I tried rewritemap.exe (compiled with pp) as :
RewriteMap testmap "prg:c:/Apache2/bin/rewritemap.exe"
Both failed to work with "map lookup FAILED: map=testmap" message in the log. And, the script works as expected when run from command line.
I am clueless!
Regards
Sunil
RewriteEngine on
RewriteBase /
RewriteCond [b]${testmap:%{REQUEST_URI}}[/b] ^REWRITE$[NC]
RewriteCond $1 !^/vfolders/
RewriteRule (.*) /vfolders/%{REMOTE_USER}/$1 [L]
Also, check that RewriteBase directive...
You might actually want to consider commenting out the RewriteBase and the RewriteMap reference, testing until the rest works, and then adding them back in one-at-a-time. RewriteMaps are hard to debug, because so many little things can cause an error.
Jim
I intended to pass REQUEST_URI and REMOTE_USER concatenated by a ":" with no default value; then only I can check if the request is OK - that username and /vfolders/username are matching. The way I understood the documentation on rewritemap is, %{REWRITE_URI}:%{REMOTE_USER} will be evaluated to first parameter. This inference seems to be correct because of log entries like :
11:26:40 initial (5) map lookup FAILED: map=testmap key=/vfolders/abcd/:sunils
Key is evaluated correctly to "/vfolders/abcd/:sunils"
In my case default '' is returned due to lookup failure (default in absence of "¦default" in rewritemap)
I feel that the perl script is failing to get executed.
If it matters, I am using binary from [apachelounge.com...]
Server version:Apache/2.2.4 (Win32)
Server built: Feb 24 2007 13:17:21
I had tested without RewriteMap and RewriteBase already; the only place where it does not work as expected seems to be at the RewriteMap.
Regards
Sunil
# C:/Apache2/bin/rewritemap.pl listing :
$¦=1;
while (my $inpvars = <STDIN>)
{
chomp ($inpvars);
my ($URI,$USER) = split(/:/, $inpvars);
print "REWRITE\n" unless $URI=~/^\/vfolders\/$USER/;
}
Jim
I had tested the script rewritemap.pl earlier from command line and it worked as expected. Like your script, I also did not code for any output unless the URI needed rewriting. BOTH scripts are behaving in the same way from command line. Here is a sample :
-------------------------
C:\Apache2\bin>perl rewritemap-jim.pl
/vfolders/sunils:sunils
/vfolders/sunils:shruthi
REWRITE
^Z^Z
C:\Apache2\bin>perl rewritemap.pl
/vfolders/sunils:sunils
/vfolders/sunils:shruthi
REWRITE
^Z^Z
---------------------------
Still it looks like the rewritemap program is just not being run. What ever you give there, even if it a non-existing program, apache does not say a word about it in the error logs....
Regs
Sunil
It's unlikely that I am going to be able to come up with a "magic" fix that suddenly makes this all work -- All I can do is make suggestions. However, there are a lot of clues here and if you look, you may see something that is not obvious to me as an 'outsider' who does not have access to all the information you do.
Another thing you can do is to modify the rules and the script slightly -- even moving away from the actual solution you want to end up with, in order to facilitate testing. So, today's suggestion is to make the script always outputs something, so you can verify that it it keeps running forever (as it should) and that it is being invoked:
# C:/Apache2/bin/rewritemap.pl listing :
$¦=1;
while (my $inpvars = <STDIN>)
{
chomp ($inpvars);
my ($URI,$USER) = split(/:/, $inpvars);
if ($URI = ~/^\/vfolders\/$USER/)
{
print ("NOREWRITE\n");
}
else
{
print ("REWRITE\n");
}
}
Jim
1. Yes, there is no .htaccess file anywhere in the test server, all config is in httpd.conf.
2. I agree that the two entries ("strip per-dir prefix" and "applying pattern '^.*$' to uri") are unexpected. Despite this, the key passwd to map is correct. (map lookup FAILED: map=testmap key=/vfolders/shruthi/:sunils)
3. I tried the script you suggested slightly modified as below:
-------------------c:/Apache2/bin/rewritemap-jim.pl listing
$¦=1;
open(tmp,">>c:/Apache2/logs/rewritemap.log") or die;
print tmp time()," -------- RewriteMap program STARTED ----------\n";
while (my $inpvars = <STDIN>) {
chomp ($inpvars);
print tmp time()," inpvars=$inpvars\n";
my ($URI,$USER) = split(/:/, $inpvars);
print tmp time()," URI=$URI, USER=$USER\n";
if ($URI=~/^\/vfolders\/$USER/) {
print ("NOREWRITE\n");
} else { print ("REWRITE\n"); }
}
print tmp time()," -------- RewriteMap program ENDED ------------\n";
close tmp;
-------------------
Just tried to log what happens inside the script into rewritemap.log. However, the rewritemap.log does not even get created when we run apache. From command line the script works as expected and creates the log all right. rewrite map has entries as before - "map lookup FAILED", and the rewritecond fails as the comparison - as before - is against ''. (RewriteCond: input='' pattern='^REWRITE$' [NC] => not-matched)
It is almost obvious that the RewriteMap program did not get launched.
Regards,
Sunil
I think we are stuck. There is no file permission/local security policy issue on the test machine. And no entry in the EventLog too.
I will repost this issue here as a rewritemap issue on win32 and lets hope that some one has gone through this before.
I am now planning to look for some work around like Squid-2.6 in reverse proxy config with url_rewrite moving the authentication from apache to reverse proxy.
Thank you very much.
Regards
Sunil