Doing two rewrites with apache and rewrite module together with webdav

apache-2.2mod-rewritewebdav

I'm trying to setup a WebDAV server which uses the username for redirecting to a private DAV directory. In each private directory there's also a folder named SharedFolder.

The idea is that when the user logs in, he will first be redirected to his private directory. Using the rewrite module, there won't be any path shown in the URL, only the hostname, which prevents users from entering another private directory. When the user opens the fixed folder named SharedFolder, mod_rewrite will fire on the matching RewriteCond foldername and redirect to the corresponding shared folder as designated in the RewriteMap.

My virtualhost configuration:

LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
DBDriver mysql
DBDParams "host=db.example.com user=username pass=password dbname=webdav"

<VirtualHost *:80>
    Servername webdav.example.com

    DocumentRoot /var/www

    Options +FollowSymlinks
    RewriteLog "/var/log/httpd/rewrite.log"
    RewriteLogLevel 5
    RewriteEngine on

    RewriteRule ^(.*) /webdav/%{LA-U:REMOTE_USER}$1

    RewriteMap usergroup txt:/etc/httpd/usersingroups
    RewriteCond %{REQUEST_URI} ^/SharedFolder/ [NC]
    RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]

    <Directory "/var/www">
        DAV on
        Options +Indexes
                AuthName "example.com"
                AuthType Digest
                AuthDigestDomain /

                AuthDigestProvider dbd
                AuthDBDUserRealmQuery "SELECT digest FROM users WHERE username = %s AND unix_timestamp() < (ts+900) "

                Require valid-user
    </Directory>
</VirtualHost>

The contents of the RewriteMap is as follows:

fred sales/indoor/
bob sales/outdoor/
alice production/warehouse

The layout of the filesystem is all under the DocumentRoot /var/www. In /var/www there are two folders. One is named /var/www/webdav which contains all the private directories. The other folder is named /var/www/sharedfolders which contains directories belonging to different groups. By defining the path name in the RewriteMap I can determine which group directory is displayed in the users SharedFolder.

The problem I'm facing is that the redirect to the SharedFolder doesn't work correct. Every file or folder in the users private directory is accessible and usable. Except the SharedFolder. When I open that SharedFolder, I can see it's contents (which are a txt-file and a folder), but I can't open that file (that's what my desktop says). The rewrite log shows:

[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) rewrite '/webdav/fred/SharedFolder/Readme.txt/' -> '/sharedfolders/sales/indoor/'
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) local path result: /sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) prefixed with document_root to /var/www/sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (1) go-ahead with /var/www/sharedfolders/sales/indoor/ [OK]

When I read the rewrite log, it tells me that the file (Readme.txt) isn't rewritten in the end to be opened.

The other problem is with opening a folder inside the SharedFolder. I continuously see the contents of SharedFolder inside itself. From the WebDAV-disk: SharedFolder/folder a/folder a/folder a/folder a and so on. Inside each 'folder a' I also see the file 'Readme.txt'. Here's what the rewrite log has to say about that:

[webdav.example.com/sid#8ffd998][rid#905d898/initial] (2) rewrite '/SharedFolder/bla/bla/bla/' -> '/webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904b850/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) rewrite '/webdav/fred/SharedFolder/bla/bla/bla/' -> '/webdav//webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) local path result: /webdav//webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) prefixed with document_root to /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (1) go-ahead with /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/ [OK]

I believe I got a few steps further, but not far enough 🙂

Some background info: I initially tried to accomplish the same objective with the SharedFolder using symbolic links, however that seems impossible in combination with WebDAV enabled (I couldn't get it working).

OS: RHEL5.8
Apache version: 2.2.3

Thanks in advance

UPDATE
With the suggestions by @Jenny_D I made a few changes. I've updated my current configuration in the code section in this question. Things I've changed:

  1. Removed the $1 at the end of RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}
  2. Added [L] at the end of that same line.
  3. Changed the <Directory "/var/www/webdav"> to <Directory "/var/www"> so that the rewritten path (/var/www/sharedfolders) is also DAV-enabled.

This last change (no. 3) made a big difference: I can now see the contents of the SharedFolder I placed earlier (without WebDAV).

Best Answer

The problem is here:

RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}$1

What you're doing is catching the directory used in the URL, storing it in $1, and then appending $1 to the end of the line. If you don't what that part of the URL appended, just remove the $1 at the end.

To stop the rewrite after the sharedfolders rule, add the flag [L] to the end.

So the rule should end up looking like this:

RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]