Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a WebDAV user set up that currently gets usernames and passwords from my MySQL Database. I give users the option to use WebDAV for large file uploads (this is for a file sharing service I'm currently developing) but I've reached a little issue I can't seem to figure out.

First of all - how would I go about each user having their own WebDAV root so they can't look into other user's files? I already run a cronjob that checks for any users that enabled WebDAV and automatically creates the directories with the appropriate permissions. I just need some method of telling apache this.

Thanks for any help, I really appreciate it.

I also am aware I could just run a cronjob every minute to generate me an apache config and reload the apache config, but this would just be a little too much overhead and I'd like some more flexibility.

share|improve this question
    
One question per question, please. Otherwise you won't be able to pick an accepted answer for each. –  womble Jul 17 '11 at 2:48
    
Alright, I'll remember that for next time I post a question. –  Tristan Seifert Jul 17 '11 at 3:07
    
It'd be worth fixing (or replacing) this question, too. I won't be answering this one as currently written. –  womble Jul 17 '11 at 4:05
    
I fixed the question. –  Tristan Seifert Jul 17 '11 at 5:14
    
JIC you're interested, here is another similar question with an useful answer: serverfault.com/questions/85197/… –  d-_-b Nov 27 '12 at 2:17

2 Answers 2

As far as I could tell (2-3 years ago), you need to add a per user/directory config.

# cat /etc/apache2/conf.d/dav_store.conf
# First you need to say that a share under location X will be a webdav share:

Alias /store /home/davfs/storage/                                                                                                                                                 
<Directory /home/davfs/storage/>
        DAV On
        AuthType Basic
        AuthName "sample"

        Auth_MySQL On
        Auth_MySQL_Authoritative On
        Auth_MySQL_Host localhost
        Auth_MySQL_User _admin
        Auth_MySQL_Password 123
        Auth_MySQL_DB dav
        Auth_MySQL_Password_Table auth_user
        Auth_MySQL_Username_Field username
        Auth_MySQL_Password_Field password
        Auth_MySQL_Empty_Passwords Off
        Auth_MySQL_Encryption_Types Django #This was custom.
        #AuthMySQLUserCondition = "is_active = 1"

        # non root users cannot view this directory
        Options -Indexes -MultiViews
        AllowOverride None
        require user root;

</Directory>


<Directory /home/davfs/storage/*/>
        DAV On
        require user root;
</Directory>

Include /home/davfs/etc/conf.d/*.dvu

And the per user config file locks a user to a dir. Here's a sample

<Directory /home/davfs/storage/lm/lmwangi/>                                                                                                                                     
        # We need this in subdirs.. otherwise error messages such as
        # "DAV Off" cannot be used to turn off a subtree of a DAV-enabled location.
        # will fill up your log
        DAV On

        require user lmwangi
</Directory>

And that's all there's to it. I think you have to reload Apache on every config change. It would be wonderful if these tasks could be done using an Apache module... (No more crons to generate configs, no more reloads etc)

share|improve this answer
    
I'm fairly certain the OP knows how to setup WebDAV... it's the "avoiding the reload" that's the point of the question, I believe. –  womble Jul 17 '11 at 5:44
    
Yes, I do have my WebDAV all set up. I guess I could have these config files in a different location, like /home/tristan/webdav_config/ and then just include these? I could then use PHP to write these config files as a user enables WebDAV, but I guess that's the way I'm gonna have to use. Also, I presume "Include /home/davfs/etc/conf.d/*.dvu" includes all files with the .dvu extension in one directory? Also, this goes into my VirtualHost for DAV? –  Tristan Seifert Jul 17 '11 at 6:05
    
Wait for a body to finish writing an answer that requires a bit of research and testing... –  womble Jul 17 '11 at 6:18
    
Anyways, I've set it up like above, and it works in only allowing the user to go into their directory, but they can still see other user's directories, but just can't go in them, and can still upload to the root of the WebDAV share. I don't think a DocumentRoot will work inside my per-user config files, and everything I've tried to prevent WebDAV upload to the root didn't solve it. I'm right now running a cron job to clean this up every minute, but that just screams wrong. Any suggestions/pointers? –  Tristan Seifert Jul 17 '11 at 20:36
    
If you have the 'require user root', for the base of your webdav share, only the user root will be able to write there. Alternatively, try limit the operations allowed on your root (using the limit directive?). The config's can live anywhere and the dvu was a per user directive in it's own file generated by cron –  Lmwangi Jul 18 '11 at 10:35

It's rather a pity that Apache's config isn't as flexible as nginx's, so you could do something like:

Alias /dav /path/to/dav/store/$REMOTE_USER

However, you can use REMOTE_USER in a rewrite rule, like so:

RewriteEngine On
RewriteRule ^/dav(.*)$ /__davinternal/%{LA-U:REMOTE_USER} [PT]

Then put all your auth/DAVish loveliness into a <Location /__davinternal> and bob's your auntie's live-in lover.

This works great if you've got consistent locations in your filesystem for all your users (say /path/to/dav/store/<username>); if you've got user folders scattered across the filesystem (with a mapping in MySQL), you can still map your user locations, but you've got to use a RewriteMap:

RewriteMap davdirs txt:/path/to/user/dir/map.txt
RewriteRule /^dav(.*)$ /__davinternal/${davdirs:%{LA-U:REMOTE_USER}}

You can do a RewriteMap straight out of MySQL (via an external script), but I'd try and get my app to update a dbm file whenever that mapping information changed and use a dbm map instead -- much better performance, and doesn't hammer your database into the ground.

I've not covered the security implications of these setups in this answer, partially because I'm not entirely sure myself, and because I don't know what your exact security policy might be.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.