1

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).

2 Answers 2

1

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]
7
  • If I remove the $1 at the end of that line, the RewriteLog seems OK. But I don't see the file I placed in the SharedFolder beforehand (not using WebDAV). When I create a folder or drag a file into the SharedFolder, I get into an infamous rewrite loop (continuously appending /index.html)
    – D43m0n
    Jul 19, 2012 at 17:23
  • 1
    At this point I'm a little out of my depth. But I'm wondering whether the problem may be that you're having both rewrites happening. The first thing you do is to rewrite all requests to /webdav/, the second thing is a special case for only the SharedFolder ones. How about doing the special case first instead of last?
    – Jenny D
    Jul 19, 2012 at 17:48
  • I'm getting a different result now, I also believe we're closer at achieving the goal. I think the RewriteRule that rewrites all requests to /webdav/username is interfering with the RewriteCond for ^/SharedFolder/ [NC]. I see several rewrites in the log: (1) go-ahead with /var/www/webdav/sharedfolders/sales/indoor/ [OK] Which is exactly what I want to achieve, but then the other RewriteRule steps in: (1) go-ahead with /var/www/webdav/fred/sharedfolders/sales/indoor/ [OK] If only the username %{LA-U:REMOTE_USER} would not end up in the final result, it should be allright.
    – D43m0n
    Jul 20, 2012 at 7:34
  • OK, what you need to do now is to tell mod_rewrite to stop rewriting after it's done the sharedfolders thing. You do that by adding the flag [L] after that RewriteRUle - that means "this is the last rule I want you to use". I've edited my answer above to show it.
    – Jenny D
    Jul 20, 2012 at 7:36
  • I now have it as follows: 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] When I open the SharedFolder apache ends up in that Rewrite-loop with appending /index.html. I've also tried switching the order of the rules (first the SharedFolder part) but that leaves the same result. Might [PT] be an option?
    – D43m0n
    Jul 20, 2012 at 7:49
0

I've found a working configuration. I now use the following:

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 2
RewriteEngine on

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

RewriteCond %{REQUEST_URI} !^/SharedFolder [NC]
RewriteRule ^(.*)$ /webdav/%{LA-U:REMOTE_USER}$1

<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>

I created an if-then-else construct by skipping lines if a certain condition needs to apply. Besides that, I also made the RewriteRule for the SharedFolder a bit more specific. That basically did the trick. After that I was set on the wrong foot by the Traffic Manager (a reversed proxy) which does SSL-offloading to this host (hence the :80 in <VirtualHost *:80>. Viewing, uploading and deleting worked just fine, except renaming. It turns out that when you rename a file or folder in WebDAV, the entire destination header is sent, instead of just a path when uploading or deleting a file or a folder. So keep that in mind when you're doing some form of SSL-offloading.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .