WebDAV CGI - Documentation
Content of this topic:
Back to the WebDAV CGI home
- Requirements
- Installation
- Upgrade
- WebDAV CGI Setup
- Hints
- Database Setup
- UID/GID Wrapper
- Folder Sharing / Group Access
- Web interface
- Web interface and logout button
- CalDAV & CardDAV support
- AFS Support
- GFS Support
- SMB/CIFS Support
- DBB database backend
- RCS backend
- Performance
- Speedy Support
- Troubleshooting
Back to the WebDAV CGI home
Requirements
- all required Perl modules: see Installation
- a database (SQLite3, PostgreSQL, MySQL, ... (all supported by a Perl DBI driver))
- a Web server software (Apache recommended)
- a little bit configuration: Apache setup (see Installation) and a WebDAV CGI Setup
- WebDAV CGI works only with a UNIX/Linux server (Ubuntu recommended, Windows/MacOS-X not tested and not supported)
Installation
Note: All steps are done with root rights.
Upgrade Note: Please take a look at the Upgrade section for further information.
- download WebDAV CGI
- install required CPAN modules (Debian/Ubuntu package name):
- CGI (included in most Linux dists; older dists need that: libcgi-perl)
- DBI (libdbi-perl) and a database driver, e.g. DBD::SQLite (libdbd-sqlite3-perl) - (since v0.3.0)
- Date::Parse (libtimedate-perl) - (since v0.2.1)
OSSP::uuid (libossp-uuid-perl or from http://www.ossp.org/pkg/lib/uuid/) - (since v0.3.0)(since v0.8.0 replaced by UUID::Tiny)- UUID::Tiny (libuuid-tiny-perl) - (since 0.8.0)
- XML::Simple (libxml-simple-perl)
- Quota (libquota-perl) - (since v0.3.4)
- Archive::Zip (libarchive-zip-perl) - (since v0.5.0)
Image::Magick (perlmagick) - (since v0.5.1)(since v0.5.3 replaced by Graphics::Magick)- Graphics::Magick (libgraphics-magick-perl or http://www.graphicsmagick.org/perl.html) - (since v0.5.3)
- File::Spec::Link (libfile-copy-link-perl) - (since v0.5.2)
- IO::Compress::Gzip (included in most Linux dists) - (since 0.7.0)
- IO::Compress::Deflate (included in most Linux dists) - (since 0.7.0)
- Module::Load (included in most Linux dists, older need libmodule-load-perl) - (since 0.8.0)
- optional (for SMB backend): Filesys::SmbClient (libfilesys-smbclient-perl) - (since 0.8.0)
- optional (for RCS backend): Rcs (librcs-perl) - (since 0.8.0)
perl -MCPAN -e "install <ModuleName>"
' or with 'apt-get install <PackageName>
'.## Debian/Ubuntu quick install: apt-get install libdbi-perl libdbd-sqlite3-perl libtimedate-perl \ libuuid-tiny-perl libxml-simple-perl libquota-perl \ libarchive-zip-perl libgraphics-magick-perl libmodule-load-perl \ libfile-copy-link-perl
- change directory to your preferred installation path, e.g.
cd /etc
- unpack WebDAV CGI:
unzip webdavcgi-latest.zip
ortar jxf webdavcgi-latest.tar.gz2
- change directory to the source base (e.g:
cd webdavcgi*
) and callbash install.sh
OR install CGI script and wrapper by hand↓- compile your wrapper, change the permissions, and put it into your cgi-bin, e.g:
gcc -o cgi-bin/webdavwrapper helper/webdavwrapper.c strip cgi-bin/webdavwrapper chown root:root cgi-bin/webdavwrapper chmod ug+s,a+rx cgi-bin/webdavwrapper ln -s `pwd`/cgi-bin/webdavwrapper /usr/lib/cgi-bin
- fix permissions and put the WebDAV CGI
webdav.pl
into your cgi-bin, e.g:chmod a+rx cgi-bin/webdav.pl ln -s `pwd`/cgi-bin/webdav.pl /usr/lib/cgi-bin
- compile your wrapper, change the permissions, and put it into your cgi-bin, e.g:
- configure webdav.pl
- configure your web server:
- you can do that with rewrite rules
- or with a handler action
a2enmod rewrite
) - and don't forget to take a look at the backend specific configurations AFS, GFS, SMB/CIFS, or DBB### EXAMPLE 1: a .htaccess file to handle a complete folder with WebDAV CGI: ### (Prerequisites: /cgi-bin/webdavwrapper is a script alias and ### 'AllowOverride AuthConfig FileInfo' is set for the current folder) RewriteEngine On RewriteRule .* /cgi-bin/webdavwrapper [E=WEBDAVCONF:/path/to/my/config/file,E=PERLLIB:/etc/webdavcgi/lib/perl] AuthType Basic AuthName "A protected WebDAV folder" AuthUserFile /path-to-my-auth-file require valid-user
### EXAMPLE 2: a complete (virtual) server root handled by WebDAV CGI: ### (you don't need actions, handler, or error documents) <Location /cgi-bin/webdavwrapper> AuthType Basic AuthName "WebDAV/CalDAV/CardDAV space" AuthUserFile /path-to-my-auth-file Require valid-user </Location> RewriteEngine On RewriteRule ^/icons(.*) /usr/share/apache2/icons$1 [L] RewriteRule ^/ /cgi-bin/webdavwrapper [PT,E=WEBDAVCONF:/path/to/my/config/file,E=PERLLIB:/etc/webdavcgi/lib/perl,L]
### EXAMPLE 3: a virtual path /webdav <Location /cgi-bin/webdavwrapper> AuthType Basic AuthName "WebDAV space" AuthUserFile /path-to-my-auth-file Require valid-user </Location> # if you want to map this to a real path, do that: # (end setup $VIRTUAL_BASE and $DOCUMENT_ROOT in your WebDAV CGI config) RewriteEngine On RewriteRule ^/webdav /cgi-bin/webdavwrapper [PT,E=WEBDAVCONF:/path/to/my/config/file,E=PERLLIB:/etc/webdavcgi/lib/perl,L]
Upgrade
Upgrading from 0.8.2 to 0.8.3
- changed
@UNSELECTABLE_FOLDERS
default to()
(relevant for AFS backend users) - changed
helper/webdavwrapper-smb.c
to fix a Kerberos ticket bug (relevant for SMB backend users)
Upgrading from 0.8.1 to 0.8.2
- see Speedy support section to improve the WebDAV CGI performance
Upgrading from 0.8.0 to 0.8.1
-
%AUTOREFRESH
was added for the new auto-refresh feature
Upgrading from 0.7.x to ≥0.8.0
- a new Perl module is needed:
Module::Load
(Ubuntu/Debian package: libmodule-load-perl) -
OSSP::uuid
Perl module was replaced byUUID::Tiny
(Ubuntu/Debian package: libuuid-tiny-perl) - WebDAV CGI comes with some own modules so you need to set a additional Perl library path:
- add
E=PERLLIB:/etc/webdavcgi/lib/perl
to your rewrite rule options in the Apache configuration - OR add
SetEnv PERLLIB /etc/webdavcgi/lib/perl
to your Apache configuration (don't forget to activate/install env module, e.g.a2enmod env; /etc/init.d/apache restart
) - OR change shebang of webdav.pl to
#!/usr/bin/perl -I/etc/webdavcgi/lib/perl
- add
-
$IGNOREFILEPERMISSIONS
config variable was removed -
$BACKEND
variable was added and is required (allowed values: 'FS', 'AFS', 'GFS', 'SMB', 'DBB') -
$SHOW_MIME
and$SHOW_PERM
were removed: use the new options@ALLOWED_TABLE_COLUMNS
and@VISIBLE_TABLE_COLUMNS
instead -
%MIMETYPES
format was changed: only a single filename suffix is allowed as a key (instead of a space separted list of suffixes); please use$MIMEFILE
instead -
@EXTENSIONS
parameter was added: contains a list of extensions -
$ENABLE_SYSINFO
was removed: add'SysInfo'
to the@EXTENSIONS
list -
$ENABLE_PROPERTIES_VIEWER
was removed: add'PropertiesViewer'
to the@EXTENSIONS
list -
$ENABLE_SIDEBAR
was removed: use@SUPPORTED_VIEWS
instead -
$MAXLASTMODIFIEDSIZE
was removed -
$MAXNAVPATHSIZE
was added
Upgrading from ≤0.6.x to ≥0.7.x
- two new Perl modules are used by WebDAV CGI:
IO::Compress::Gzip
andIO::Compress::Deflate
(both are integraded in most Linux dists) - WebDAV CGI is not longer a single file distribution therefore:
- unpack the new installation package in your preferred installlation path, e.g.
cd /etc; unzip webdavcgi-0.7.?.zip
- link the path for easier upgrades, e.g.
ln -s /etc/webdavcgi-0.7.? /etc/webdavcgi
- copy the webdav.pl script to your CGI directory and allow execution, e.g.
cp /etc/webdavcgi/cgi-bin/webdav.pl /usr/lib/cgi-bin chmod a+x /usr/lib/cgi-bin/webdav.pl
- add the
$INSTALL_BASE
variable to your existingwebdav.conf
, e.g.echo "\$INSTALL_BASE='/etc/webdavcgi/';" >> /path/to/my/config/file/webdav.conf
- check your config file and modules, e.g.
#> perl -c /path/to/my/config/file/webdav.conf webdav.conf syntax OK #> perl -I/etc/webdavcgi/lib/perl -c /usr/lib/cgi-bin/webdav.pl webdav.pl syntax OK #> bash /etc/webdavcgi/checkenv +++ Checking perl: perl /usr/bin/perl ++++ Checking required modules: CGI installed DBI installed POSIX installed File::Temp installed Date::Parse installed UUID::Tiny installed XML::Simple installed Quota installed Archive::Zip installed IO::Compress::Gzip installed IO::Compress::Deflate installed Digest::MD5 installed Module::Load installed ++++ Checking optional modules: DBD::SQLite installed DBD::mysql installed DBD::Pg installed ++++ Checking required modules for FS backend: File::Spec::Link installed ++++ Checking required modules for AFS backend: File::Spec::Link already checked ++++ Checking required modules for GFS backend: File::Spec::Link already checked ++++ Checking required modules for SMB backend: Filesys::SmbClient installed ++++ Checking optional binaries: smbclient /usr/bin/smbclient #### Summary: All modules found. All binaries found.
- unpack the new installation package in your preferred installlation path, e.g.
- WebDAV CGI has a new Web interface and some configuration defaults were changed and new options were added. See CHANGELOG in your installation path and take a look into webdav.pl for further information.
WebDAV CGI Setup
The WebDAV CGI can be easier upgraded if you use a configuration file instead of changing the setup section ofwebdav.pl
.
- Create a
webdav.conf
wherever you want (e.g. /etc/webdav.conf or /etc/apache2/webdav.conf) with a minimal setup and don't forget to fix file permissions:chmod a+r webdav.conf
:## the install base is needed to find webdav-ui.* and locale files ## (don't forget the trailing slash): $INSTALL_BASE = '/etc/webdavcgi/'; ## the backend module (supported: FS, AFS, GFS, SMB, DBB): $BACKEND = 'FS'; ## this is an example if a user starts with home dir (http://mywebdavserver/ -> user home): $VIRTUAL_BASE = '/'; $DOCUMENT_ROOT = '/home/'.$ENV{REMOTE_USER}.'/'; ## if you use a complex home folder structure, try this: # $DOCUMENT_ROOT=(getpwnam($ENV{REMOTE_USER}))[7].'/'; $DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $DBI_USER=''; $DBI_PASS=''; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db';
- Please take a look at backend specific configuration sections AFS, GFS, SMB/CIFS, or DBB
- If you need to change other options simply copy the parameter from the
webdav.pl
setup section into your config file. - Don't forget to check the config file syntax:
perl -c webdav.conf
- configure your Apache web server
Hints
Apache and webdav.pl setup:- You can use Apache's
'SetEnv VAR VAL'
or'RewriteRule ... [E=VAR:VAL]'
in conjunction with'$ENV{VAR}'
in your config to setup WebDAV CGI. This allows you a path based, virtual host based or user based configuration. - see Performance section for more.
- RedHat/Fedora/CentOS: see https://bugzilla.redhat.com/show_bug.cgi?id=527143#c2
- You can use Image::Magick instead but it makes trouble in conjunction with Speedy:
sed -i -e 's@Graphics::Magick@Image::Magick@g' \ checkenv \ lib/perl/WebInterface/View/classic/Renderer.pm \ lib/perl/WebInterface/Renderer.pm
Database Setup
Common Instructions
- Install the necessary Perl DBI driver (Debian/Ubuntu package: libdbd-...-perl)
- Create the database and the schema
- Configure WebDAV CGI (
$DBI_SRC, $DBI_USER, $DBI_PASS
)
SQLite 3
- DBI driver for SQLite3: Debian/Ubuntu package:
libdbd-sqlite3-perl
- You can use the auto create feature (
$CREATE_DB=1;
) - Example config:
$DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'$ENV{REMOTE_USER}.'.db'; $DBI_USER=""; $DBI_PASS=""; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db';
PostgreSQL
- DBI driver for PostgreSQL: Debian/Ubuntu package:
libdbd-pg-perl
- Disable the auto create feature (
$CREATE_DB = 0;
) and create the database schema with following statements (the database 'webdavcgi' must exists), e.g:psql webdavcgi <<EOF CREATE TABLE webdav_locks (basefn VARCHAR(255) NOT NULL, fn VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, scope VARCHAR(255), token VARCHAR(255) NOT NULL, depth VARCHAR(255) NOT NULL, timeout VARCHAR(255) NULL, owner TEXT NULL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP); CREATE TABLE webdav_props (fn VARCHAR(255) NOT NULL, propname VARCHAR(255) NOT NULL, value TEXT); CREATE INDEX webdav_locks_idx1 ON webdav_locks (fn); CREATE INDEX webdav_locks_idx2 ON webdav_locks (basefn); CREATE INDEX webdav_locks_idx3 ON webdav_locks (fn,basefn); CREATE INDEX webdav_locks_idx4 ON webdav_locks (fn,basefn,token); CREATE INDEX webdav_props_idx1 ON webdav_props (fn); CREATE INDEX webdav_props_idx2 ON webdav_props (fn,propname); EOF
- Example config:
$DBI_SRC='dbi:Pg:dbname=webdavcgi;host=localhost;port=5432'; $DBI_USER='pguser'; $DBI_PASS='changeme'; $CREATE_DB = 0;
MySQL
- DBI driver for MySQL: Debian/Ubuntu-Package:
libdbd-mysql-perl
- Disable the auto create feature (
$CREATE_DB = 0;
) and create the database schema with following statements (the database 'webdavcgi' must exists), e.g.:mysql -p webdavcgi <<EOF CREATE TABLE webdav_locks (basefn VARCHAR(255) NOT NULL, fn VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, scope VARCHAR(255), token VARCHAR(255) NOT NULL, depth VARCHAR(255) NOT NULL, timeout VARCHAR(255) NULL, owner TEXT NULL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP); CREATE TABLE webdav_props (fn VARCHAR(255) NOT NULL, propname VARCHAR(255) NOT NULL, value TEXT); CREATE INDEX webdav_locks_idx1 ON webdav_locks (fn); CREATE INDEX webdav_locks_idx2 ON webdav_locks (basefn); CREATE INDEX webdav_locks_idx3 ON webdav_locks (fn,basefn); CREATE INDEX webdav_locks_idx4 ON webdav_locks (fn,basefn,token); CREATE INDEX webdav_props_idx1 ON webdav_props (fn); CREATE INDEX webdav_props_idx2 ON webdav_props (fn,propname); EOF
- Example config:
$DBI_SRC='DBI:mysql:database=webdavcgi;host=localhost;port=3306'; $DBI_USER='mysqluser'; $DBI_PASS='changeme'; $CREATE_DB=0;
UID/GID Wrapper
If you use the example wrapper (webdavwrapper.c
or webdavwrapper-krb.c
) you should consider this:
- Your operating system have to know all your WebDAV users. The following command should display a complete passwd entry (replace UID with a account name):
getent passwd UID # OR getent passwd # should display all users
Configure NSSWITCH (/etc/nsswitch.conf) to make your user accounts usable. - The owner and group must be root:
chown root:root webdavwrapper
- The
webdavwrapper
binary needs set-user-ID and the set-group-ID bit to change the user ID and the group ID at runtime. Of course it needs also execute flags.chmod ug+s,a+x webdavwrapper
webdavwrapper-krb.c
instead of webdavwrapper.c
(see AFS Support section)
Folder Sharing / Group Access
There are two ways to share a folder between users of a group (not for AFS users - see AFS note below):- Add all users to UNIX/Posix group (/etc/groups, a LDAP group, ...) - recommended:
- create a group, e.g:
groupadd GROUP
- create a folder to share:
mkdir SHAREDFOLDER
- change the group:
chgrp GROUP SHAREDFOLDER
- set set-GID-flag to the folder and make it readable/executable/writeable for the group:
chmod g+srwx SHAREDFOLDER
- set the
$UMASK
parameter in your WebDAV CGI config file:$UMASK = 0002;
- create a group, e.g:
- Use the UID/GID Wrapper to map all users to a common user:
- create a common user, e.g.:
adduser USER
- create a folder to share:
mkdir SHAREDFOLDER
- change the owner:
chown USER SHAREDFOLDER
- set the WEBDAV_USER environment variable: add
E=WEBDAV_USER:USER
to your Apache rewrite rule option
- create a common user, e.g.:
- Create a AFS group and add AFS users to the group.
- Set lookup, read, write, delete, insert, and lock rights for that group to the shared folder.
- Don't forget to set lookup rights for the AFS group to all upper folders.
Web interface
How to add a new translation
Copy the
locale/webdav-ui_default.msg
to locale/webdav-ui_<MYLANGCODE>.msg
and translate all values (leave the keys unchanged; format: key "value"
).
And don't forget to sent me your translation. Thanx :-)
How to change CSS styles
There are many ways to do it:- Add a
webdav-ui-custom.css
to thelib/
directory of the WebDAV CGI installation (recommended). Note: webdav.pl delivers this style file with a cache timeout of one week. You can compress the style sheet to speed up file transfers: (gzip webdav-ui-custom.css
). If webdav-ui-custom.css and webdav-ui-custom.css.gz exist then the uncompressed version is delivered. - Add the following to your WebDAV CGI configuration file:
$CSS .= <<EOF .filelist { font-size: 0.9em; } EOF ;
- Set
$CSSURI
variable in your WebDAV CGI config, e.g.$CSSURI='http://myserver/mystyle.css';
- Set the
$HTMLHEAD
variable in your WebDAV CGI config (e.g.$HTMLHEAD='<link .../>';
or$HTMLHEAD='<style>...</style>';
) - ...
How to add or change icons
Here are some examples to do that in the WebDAV CGI configuration file:$ICONS{'mymime/type'}='/uripath/to/my/icons/test.gif';
%ICONS = ( %ICONS, ( 'mymime/type1'=>'/uripath/to/my/icons/test1.gif', 'mymime/type2'=>'/uripath/to/my/icons/test2.gif', ) );
How to customize error messages/documents
Two HTTP status codes are supported for customized error documents: '404 Not Found
' and '403 Forbidden
'
You have to use '.html' or '.txt' extensions for your error documents to determine a correct MIME type.
- put your error documents to the
$INSTALL_BASE/htdocs
folder or wherever you want (should be readable by your users) - add following options to your WebDAV CGI configuration file:
$ERROR_DOCS{'404 Not Found'} = "$INSTALL_BASE/htdocs/404.html"; $ERROR_DOCS{'403 Forbidden'} = "$INSTALL_BASE/htdocs/403.html";
How to integrate a WYSIWYG editor
Here is an example for CKEditor™:- Download and install CKEditor™ (e.g. into the
/srv
folder - or use another server) - Configure the web server to access all CKEditor™ files, e.g.
RewriteRule /ckeditor /srv/ckeditor [PT,L]
- Configure WebDAV CGI:
if ($cgi->param('edit') && $cgi->param('edit') =~ /\.html?$/i) { $HTMLHEAD = q@ <script type="text/javascript" src="/ckeditor/ckeditor.js"></script> <style>.textdataresizer { display: none; }</style> @; my $_lang = $cgi->param('lang') || $cgi->cookie('lang') || $LANG; $SIGNATURE .= qq@ <script> CKEDITOR.replace('textdata', { fullPage : true, language: '$_lang', removePlugins: 'save', baseFloatZIndex: (parseInt(getCookie('dragZIndex')) == 'NaN') ? 10000 : parseInt(getCookie('dragZIndex'))+1000 }); </script> @; }
- Allow only HTML files to edit with a WYSIWYG editor.
- Disable 'save' button or reconfigure it to submit 'savetextdata'.
- Use the id 'textdata' for the editor replacement.
- Disable the WebDAV CGI integrated resizer if the editor comes with its own (set display to none for style .textdataresizer).
- Enable full page editing to allow changing complete HTML pages.
- Setup z-index style for editor to a value larger than 'dragZIndex' cookie value.
Variable substitution in $HEADER, $SIGNATURE, $LANGSWITCH, and %ICONS
Following variables are substituted:$CLOCK | a clock with client time formatted with locale value for key 'vartimeformat' |
$ENV{_VAR_} | value of environment variable _VAR_ |
$LANG | current language code |
$NOW | current date formatted with locale value for key 'varnowformat' |
$PATH_TRANSLATED | locale folder name corresponding to the request URI |
$REQUEST_URI | request URI without query string |
$TIME | current time formatted with locale value for key 'vartimeformat' |
$TL{_KEY_} | locale value for key _KEY_ |
$USER | current user id |
$VBASE | virtual host base matching $VIRTUAL_BASE |
$VHTDOCS | virtual htdocs path $VHTDOCS to the $INSTALL_BASE/htdocs |
Web interface and logout button
The WebDAV CGI Web interface has no logout button by default. A logout depends on the used authentication type. For a simple HTTP basic authentication you can use the sample logout script (seecgi-bin/logout-dist
in your WebDAV CGI source base).
It's quiet easy to integrate a logout button:
- install logout script,e.g (be in the WebDAV CGI source base):
cp cgi-bin/logout-dist cgi-bin/logout chmod a+rx cgi-bin/logout ln -s `pwd`/cgi-bin/logout /usr/lib/cgi-bin
- Edit
cgi-bin/logout
: changeREALM
andHOMEURL
values - Add a rewrite rule to your Apache configuration, e.g:
RewriteRule /logout /usr/lib/cgi-bin/logout [PT,L]
Note: this rule should precede the webdavwrapper rule - Add the following to your WebDAV CGI config:
$HEADER = '<div class="header">WebDAV CGI - Web interface: You are logged in as <span title="'.`id -a`.'">' .$ENV{REMOTE_USER}.'</span> (<a href="/logout">Logout</a>).</div>';
CalDAV & CardDAV support
CalDAV
WebDAV CGI supports CalDAV (calendar and todo sharing). Older clients need only the URL to your CalDAV enabled folder. Newer clients like iPod Touch 4, MacOS X 10.6.x, ... need some configuration efforts:
- WebDAV CGI script must handle the root context of your Web server (see CardDAV section how to do that).
- Setup WebDAV CGI:
... ### https://myhost/ -> /home/userid/ $DOCUMENT_ROOT = '/home/'.$ENV{REMOTE_USER}.'/'; $VIRTUAL_BASE = '/'; $ENABLE_CALDAV = 1; ## Note: all listed folders are not CalDAV enabled; ## you must create and use subfolders for calendars: %CALENDAR_HOME_SET = ( default => '/.calendar/' ); ## Create .calendar folder (home set) if it does not exists: ## Note: The home set folder is not a useable calendar folder. ## Current clients need subfolders for calendar entries. mkdir("${DOCUMENT_ROOT}.calendar") unless -e "${DOCUMENT_ROOT}.calendar"; ## Create default calendar(s) (subfolder(s) of the home set): ## Note: Without a default calendar a iPhone, iPod, ... cannot use CalDAV. foreach my $cal (('calendar','private')) { mkdir("${DOCUMENT_ROOT}.calendar/$cal") unless -e "${DOCUMENT_ROOT}.calendar/$cal"; } ...
CardDAV
For CardDAV support (addressbook sharing) the WebDAV CGI script must handle the root context of your Web server. There are several ways to do that if your Web server is not a only used for WebDAV CGI:
- use a new host name (alias) for your Web server and configure named virutal hosting.
NameVirtualHost *:443 <VirtualHost myvirtualhost:443> ... </VirtualHost>
- add a new IP to your server and configure IP based virtual hosting.
<VirtualHost 10.0.0.0:443> ... </VirtualHost>
- or bind your Web server to a special port and configure a virtual host for this new port.
Listen 8888 <VirtualHost __default__:8888> ... </VirtualHost>
... ### https://myhost/ -> /home/userid/ $DOCUMENT_ROOT = '/home/'.$ENV{REMOTE_USER}.'/'; $VIRTUAL_BASE = '/'; $ENABLE_CARDDAV = 1; %ADDRESSBOOK_HOME_SET = ( default => '/.addressbook/' ); ## create .addressbook folder if it does not exists: mkdir("${DOCUMENT_ROOT}.addressbook") unless -e "${DOCUMENT_ROOT}.addressbook"; ...
AFS Support
WebDAV CGI can be used as a Web frontend for AFS and as a WebDAV-AFS bridge. It's a complete replacement for filedrawers.Requirements:
- mod_auth_kerberos installed (Debian/Ubuntu package: libapache2-mod-auth-kerb)
- a keytab file for your server (service name: HTTP/<YOUR SERVER NAME>@<YOUR DOMAIN>, e.g. HTTP/webafs.cms.hu-berlin.de@CMS.HU-BERLIN.DE)
- mod_waklog installed
- OpenAFS client installed on your server (Debian/Ubuntu package: openafs-client) and configured (
kinit ...; aklog
should work) - webdavwrapper-krb.c:
gcc -o webdavwrapper webdavwrapper-krb.c && cp webdavwrapper /usr/lib/cgi-bin && chown root:root /usr/lib/cgi-bin/webdavwrapper; chmod ug+s,a+rx /usr/lib/cgi-bin/webdavwrapper
KrbMethodNegotiate off KrbMethodK5Passwd on # required: KrbSaveCredentials on Krb5Keytab /etc/webafs.keytab AuthName "WebAFS" AuthType Kerberos require valid-user WaklogEnabled On WaklogUseUserTokens On RewriteRule ^/icons/ - [L] RewriteRule ^/ /cgi-bin/webdavwrapper [PT,E=WEBDAVCONF:/usr/lib/cgi-bin/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl,L]
webdav.conf
example:
$INSTALL_BASE = '/etc/webdavcgi'; $BACKEND = 'AFS'; $DOCUMENT_ROOT = '/afs/'; $VIRTUAL_BASE='/'; $DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $DBI_USER=''; $DBI_PASS=''; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $AFSQUOTA='/usr/bin/fs listquota $FS'; $ENABLE_AFSACLMANAGER = 1; $ALLOW_AFSACLCHANGES = 1; $ENABLE_AFSGROUPMANAGER = 1; $ALLOW_AFSGROUPCHANGES = 1; $ALLOW_SEARCH = 0; $ALLOW_CHANGEPERM = 0; $ENABLE_AFS = 1; $MIMEFILE='/etc/mime.types';
GFS Support
The GFS backend replaces only the quota command. Requirements:- a mounted GFS filesystem
-
gfs_quota
command executable by a user
webdav.conf
example:
$INSTALL_BASE = '/etc/webdavcgi/'; $BACKEND='GFS'; $DOCUMENT_ROOT = '/mygfsmountpoint/'; $VIRTUAL_BASE = '/'; $DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $DBI_USER=''; $DBI_PASS=''; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $GFSQUOTA='/usr/sbin/gfs_quota -f';
SMB/CIFS Support
Requirements:- a Active Directory integrated Windows or Samba file server
- mod_auth_kerberos installed (Debian/Ubuntu: libapache2-mod-auth-kerb)
- a keytab file for the kerberos module:
- create a Windows/ADS user account with a good password (e.g.
exampleuser
) - disable password change requirements (policies) for your Windows/ADS user account
- create a keytab file as a domain admin on your domain controller:
C:>ktpass -princ HTTP/my_www_server_name@MY.EXAMPLE.DOMAIN.ORG -mapuser exampleuser@MY.EXAMPLE.DOMAIN.ORG -pass MySeCreTexampleuserPassw0rd -out keytab.HTTP
- copy the keytab file
keytab.HTTP
to a Web server path, e.g./etc/keytab.HTTP
- create a Windows/ADS user account with a good password (e.g.
-
Filesys::SmbClient
perl module installed (Debian/Ubuntu package: libfilesys-smbclient-perl) - optional the
/usr/bin/smbclient
binary for quota information (Debian/Ubuntu package: smbclient) - You must not use a setuid/setgid wrapper because mod_auth_kerberos creates a ticket cache file and the WebDAV CGI script needs read rights for the Kerberos ticket cache.
- You need a wrapper if you use Speedy (see Speed Support section) because the SMB backend needs a fresh Kerberos ticket.
- unough temporary file space for thumbnails and ZIP upload/download
KrbVerifyKDC off KrbMethodNegotiate on KrbMethodK5Passwd on KrbAuthoritative on KrbServiceName HTTP Krb5Keytab /etc/keytab.HTTP KrbSaveCredentials on KrbAuthRealms MY.EXAMPLE.DOMAIN.ORG MYSECOND.EXAMPLE.DOMAIN.ORG AuthType Kerberos AuthName "MY.EXAMPLE.DOMAIN.ORG Account" require valid-user RewriteEngine on RewriteRule ^/ /cgi-bin/webdav.pl [PT,E=WEBDAVCONF:/usr/lib/cgi-bin/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl,L]
webdav.conf
example:
$INSTALL_BASE = '/etc/webdavcgi/'; $DOCUMENT_ROOT = '/'; $VIRTUAL_BASE = '/'; $BACKEND='SMB'; $DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $DBI_USER=''; $DBI_PASS=''; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $SHOW_QUOTA = -x '/usr/bin/smbclient'; $ALLOW_CHANGEPERM = 0; $ALLOW_SYMLINK = 0; #### SMB backend setup: ### required entries: defaultdomain, domains, fileserver ### optional entries: sharefilter, usersharefilter, shares, sharealiases %SMB = ( defaultdomain => 'MY.EXAMPLE.DOMAIN.ORG', #required ## a global share filter (filter out admin shares with trailing $): sharefilter => [ qr/\$$/, ], #optional usersharefilter => { #optional ## admin has no matching filter so he can see all shares (overwrites sharefilter): myadminexample => [ qr/__NEVER_MATCH/, ], }, sharesep => '~', #optional - servername-share separator symbol (default: '~') ## don't use a separator symbol like '$', '-', '_', '#', '%', '?', '&', '/', '\', or letters/numbers ## good alternative separators are '!', ':', '=', '\'', '"', '`', '+', '*', or '@' domains => { #required 'MY.EXAMPLE.DOMAIN.ORG' => { #required (multiple domain entries allowed for forrests) ## a domain based filter (overwrites sharefilter and userfilter above): sharefilter => [ qr/\$$/, ], #optional usersharefilter => { #optional ## a domain based user filter (overwrites all sharefilter and global filter): myadminexample => [ qr/__NEVER_MATCH/, ], }, fileserver => { #required 'mywindowsfileserver1.my.example.domain.org' => { #required ## a fileserver based share filter (overwrites all domain based filter): sharefilter => [ qr/\$/, ], #optional usersharefilter => { #optional ## overwrites all sharefilter and domain based filter myadminexample => [ qr/__NEVER_MATCH/ ] }, ## disables all filter and (slow) automatic share detection: shares => [ 'MyFirstShare', 'MySecondShare', 'MyThirdShare/start/here' ], #optional ## defines a initial directory for a share (don't forget the initial '/'): initdir => { #optional 'MyFirstShare' => '/starthere', 'MySecondShare'=> '/start/here' }, sharealiases => { #optional ## shows 'H: (Home)' instead of ## 'mywindowsfileserver1.my.example.domain.org~MyFirstShare' in the Web interface 'MyFirstShare' => 'H: (Home)/', ## shows 'S: (Scratch)' instead of ## 'mywindowsfileserver1.my.example.domain.org~MySecondShare' in the Web interface 'MySecondShare' => 'S: (Scratch)/', 'MyThirdShare/start/here' => 'T: Temp (/start/here/)', }, }, }, }, }, );
DBD database backend
The DBD backend module is an example module. It shows the possibility to put all your data to your own backend and not only to file systems.
Features:- puts all data to a single database table (binaries too)
- the requrired database table will be created by the backend
- a database driver (DBD perl module; by default SQLite; Ubuntu/Debian package: libdbd-sqlite3-perl)
webdav.conf
example:
$INSTALL_BASE='/etc/webdavcgi/'; $VIRTUAL_BASE = '/'; $DOCUMENT_ROOT='/'; $DBI_SRC='dbi:SQLite:dbname=/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $DBI_USER=''; $DBI_PASS=''; $CREATE_DB = !-e '/tmp/webdav.'.$ENV{REMOTE_USER}.'.db'; $THUMBNAIL_CACHEDIR="/tmp"; $ALLOW_CHANGEPERM = 0; $ALLOW_SYMLINK = 0; $BACKEND = 'DBB'; %DBB = ( dsn => 'dbi:SQLite:dbname=/tmp/webdavcgi-dbdbackend-'.$ENV{REMOTE_USER}.'.db', username => '', password => '', );
RCS backend
The RCS backend is a showcase for a revision controlled backend. It needs another backend like FS, or SMB to work because it's a simple backend wrapper.
How it works:
Known issues:
- only files are under revision control
- the backend creates a revision file with RCS for any uploaded file
- a revision file is stored in the
rcsdirname
folder (e.g..rcs/test.txt,v
) relative to the folder of a file - the RCS backend creates a virtual folder structure (
rcsdirname/virtualrcsdir
) with revision files, rcs log entries, and revision comparision (diff) - revisions, logs, and diffs are located under
rcsdirname/virtualrcsdir/filename/
(e.g..rcs/RCS/test.txt/
)
- if you copy or move files over existing files the overwritten files and revisions are lost
- if you delete a folder all containing revisions and files are deleted and lost
-
Rcs
Perl module (Debian/Ubuntu package: librcs-perl) - rcs binaries (Debian/Ubuntu package: rcs)
- another backend like FS, GFS, AFS, DBB, or SMB and don't forget to configure the other backend
- a little bit temporary space for all RCS operations (ci, co, rcsdiff, rlog, zip download)
webdav.conf
example:
... $BACKEND = 'RCS'; %RCS = ( ## backend used for versioning: backend=>'FS', # required ## relative path in a directory for revision files ## (slashes are not allowed): rcsdirname=>'.rcs', # required ## RCS binary path: bindir=>'/usr/bin', # required ## a relative virtual path in 'rcsdirname' to access ## all revisions, logs and diffs of a file ## (slashes are not allowed): virtualrcsdir=>'REVISIONS', # required ## limits the number of revisions for a file: ## note: maxrevisions includes the current revision that means: ## you have to set maxrevisions to 4 if you need access to 3 old revisions # maxrevision=>31, # optional ## ignore suffixes (check is case insensitive): # ignoresuffixes => [ 'jpg', 'gif', 'png', ], # optional ## allowed suffixes (check is case insensitive): # allowedsuffixes => [ 'txt', 'html' ], # optional ## ignore filenames (check is case insensitive): # ignorefilenames=> [ '.*~'], # optional ); ...
Performance
- Use a fast (local) database.
- Don't use mod_auth_external without auth caching.
- Use load balancing cluster (Attention: use a central, single database for all nodes)
- Disable all features you don't need (take a look at all
$ALLOW_...
and$ENABLE_...
parameters in the WebDAV CGI setup section):$ENABLE_LOCK = 0;
- disable WebDAV locking support but it is unsafe in conjunction with shared group folders and some clients make trouble.- Web interface:
$ENABLE_THUMBNAIL=0;
- disables thumbnail support$ENABLE_THUMBNAIL_CACHE=1;
- enables the thumbnail cache and reduces CPU usage (only useful if$ENABLE_THUMBNAIL=1;
)$ENABLE_THUMBNAIL_PDFPS=0;
- disables thumbnails for PDF/PS documents and reduces CPU usage (only useful if$ENABLE_THUMBNAIL=1;
$DISABLE_SEARCH=0;
- disables file name search
- Compression of HTML, JavaScript, and CSS is enabled by default (
$ENABLE_COMPRESSION = 1;
) but this option can increase the load on your server. - Filter and limit large folders (
$FILECOUNTLIMIT
,$FILECOUNTPERDIRLIMIT
,$FILEFILTERPERDIR
) - Limit folder depth for copy/move operations (
$LIMIT_FOLDER_DEPTH
) - Change the bufsize for upload/download operations (
$BUFSIZE
) - Since WebDAV CGI v0.5.3 you can use Speedy to improve the performance (AFS backend does not work with Speedy). Attention: You must set "MaxRuns" because perl and/or WebDAV CGI runs out of memory.
- disable
$CREATE_DB
after first WebDAV access (PROPFIND request). If you use a file based database like SQLite you can enable/disable it automatically:$CREATE_DB = !-e <mydatabasefile.db>
- Slow response working with WebDAV resources on Windows Vista or Windows 7: KB2445570
Speedy Support
Speedy or PersistentPerl allows you to increase the request/response speed of WebDAV CGI. WebDAV CGI is up to 7 times faster with Speedy than without. The AFS backend does not work with Speedy.
Setup:
- Install Speedy (Debian/Ubuntu:
apt-get install speedy-cgi-perl
) - Change the shebang of webdav.pl:
OLD: #!/usr/bin/perl NEW: #!/usr/bin/speedy -- -r20 -M5
The-r20
limits the requests per Speedy process. This is necessary because Perl runs out of memory (you can set it higher but watch your Apache error log). The-M5
limits the count of Speedy processes (seeman speedy
). If you do not use a setuid/setgid wrapper (e.g. if you use the SMB backend) you should remove the-M5
or set it higher because all your clients using the same Speedy processes and you need one Speedy process per request. - Only for the SMB backend:
- Check and change the ticket lifetime in
helper/webdavwrapper-smb.c
:#define TICKET_LIFETIME 28800
The ticket (renewal) lifetime depends on your domain controller setup (Kerberos policy of your domain group policy). You can check it (Debian/Ubuntu:apt-get install krb5-user
):kinit mydomainaccount@MY.EXAMPLE.DOMAIN.ORG klist
- Compile the
helper/webdavwrapper-smb.c
:gcc helper/webdavwrapper-smb.c -o cgi-bin/webdavwrapper-smb
- Change the Apache rewrite rule:
OLD: RewriteRule ^/ /cgi-bin/webdav.pl ... NEW: RewriteRule ^/ /cgi-bin/webdavwrapper-smb ...
- Known issue: every request creates a new service ticket therefore the file size of ticket cache file grows for every request; Solution: reduce the TICKET_LIFETIME in the webdavwrapper-smb.c to reduce the temporary file space consumption
- Check and change the ticket lifetime in
- That's all and don't forget to check the notes below.
- If you change your
webdav.conf
you have to touch webdav.pl (touch cgi-bin/webdav.pl
) or kill all speedy processes (pkill -f speedy_backend
) because Speedy checks only the modification time of webdav.pl. - If you do not use a setuid/setgid wrapper you have to use a single database for all users.
- You can increase the performance if you enable persistent database connections in your
webdav.conf
:$DBI_PERSISTENT = 1;
Troubleshooting
Timeout
Maybe it helps to increase theTimeout
value in your Apache configuration (300 is a good minimum value).
If a larger
Timeout
value does not fix the problem perhaps the Apache mod_reqtimeout is loaded. You should disable this module (Debian/Ubuntu: a2dismod reqtimeout; /etc/init.d/apache2 restart
) or configure it with larger values.
Apache error log: Request exceeded the limit of X internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
This is a typical rewrite misconfiguration.
A common mistake is to take the .htaccess
rewrite rule example for the Apache configuration.
A rule like RewriteRule .* ...
in the Apache configuration runs into a 'endless' recursion only stopped by the Apache limit (LimitInternalRecursion
).
Please use a rule like RewriteRule ^/ ...
to fix this problem.
In a .htaccess
makes the pattern ^/
no sense because this pattern will never match.
Rewite rule patterns in a .htaccess
have to be relative to the current path therefore .*
works fine.
If this does not help put the following to your Apache configuration:
RewriteLogLevel 3 RewriteLog /var/log/apache2/rewrite.logand analyze the
rewrite.log
after a single access to your WebDAV area and don't forget to set the RewriteLogLevel
back to 0
after your debug session.
Not Found / 500 Internal Server Error / 'Premature end of script headers'
Please check the following:- Apache error log - Apache writes sometimes helpful things into logs
- read and execute file permissions of
webdavwrapper
andwebdav.pl
and fix it if necessary (owner/group too):chmod a+rx webdav.pl chmod a+rx,ug+s webdavwrapper chown root:root webdavwrapper
- shebang of
webdav.pl
: path to the Perl interpreter have to be correct -
webdav.conf
syntax (maybe a broken config):#> perl -c webdav.conf webdav.conf syntax OK
-
webdav.pl
syntax (maybe a broken config or a missing Perl module):#> perl -I/etc/webdavcgi/lib/perl -c webdav.pl webdav.pl syntax OK #> bash /etc/webdavcgi/checkenv +++ Checking perl: perl /usr/bin/perl ++++ Checking required modules: CGI installed DBI installed POSIX installed File::Temp installed Date::Parse installed UUID::Tiny installed XML::Simple installed Quota installed Archive::Zip installed IO::Compress::Gzip installed IO::Compress::Deflate installed Digest::MD5 installed Module::Load installed ++++ Checking optional modules: DBD::SQLite installed DBD::mysql installed DBD::Pg installed ++++ Checking required modules for FS backend: File::Spec::Link installed ++++ Checking required modules for AFS backend: File::Spec::Link already checked ++++ Checking required modules for GFS backend: File::Spec::Link already checked ++++ Checking required modules for SMB backend: Filesys::SmbClient installed ++++ Checking optional binaries: smbclient /usr/bin/smbclient #### Summary: All modules found. All binaries found.
- Check your database setup (
$DBI_SRC
,$DBI_USER
,$DBI_PASS
). - Call webdav.pl from a shell:
#> env WEBDAVCONF=/etc/webdav.conf perl -I/etc/webdavcgi/lib/perl webdav.pl DAV: 1, 2, 3, <http://apache.org/dav/propset/fs/1>, extended-mkcol, access-control, calendar-access, calendarserver-private-comments, calendar-auto-schedule, addressbook, bind MS-Author-Via: DAV Status: 404 Not Found Date: Mon, 14 Mar 2011 12:51:35 GMT Etag: "d41d8cd98f00b204e9800998ecf8427e" Content-length: 0 Content-Type: text/plain; charset=utf-8
- Call webdavwrapper from a shell:
#> ./webdavwrapper Status: 404 Not Found Content-Type: text/plain 404 Not Found - your wrapper
- Contact the author
FreeBSD/OpenBSD: all LOCK requests result in a segmentation fault error (signal 11)
In some installations OSSP::uuid module lets Perl crashing with a segmentation fault. A solution is to replace OSSP::uuid with UUID::Tiny (thx Tony Wijnhard):- install UUID::Tiny:
perl -MCPAN -e 'install UUID::Tiny'
- replace
use OSSP:uuid;
withuse UUID::Tiny;
:sed -i -e 's@use OSSP::uuid;@use UUID::Tiny;@g' webdav.pl
- replace
sub getuuid {
withsub _unused_getuuid {
:sed -i -e 's@^sub getuuid@sub _unused_getuuid@g' webdav.pl
- add a new getuuid routine to webdav.pl:
cat - >>webdav.pl <<'EOF' sub getuuid { my ($fn) = @_; my $uuid_ns = create_UUID(UUID_V1, "opaquelocktoken:$fn"); my $uuid = create_UUID(UUID_V3, $uuid_ns, "$fn".time()); debug("_LOCK after uuid made in method:"); return UUID_to_string($uuid); } EOF
Web interface: Copy/Cut/Paste and bookmarks do not work as expected.
WebDAV CGI uses the 'secure' flag for cookies. If you access the Web interface without encryption (http instead of https) all cookie based actions do not work.Web interface: missing stylesheets, locales, and/or icons
- Check your
$INSTALL_BASE
variable in yourwebdav.conf
- Check webdav.conf syntax:
perl -c webdav.conf
- Check your Apache rewrite rule: the path to your webdav.conf must be correct:
E=WEBDAVCONF:/path/to/my/webdav.conf
Web interface: wrong date/time/number formatting for a language
WebDAV CGI uses language specific formattings for date/time/numbers. Check your locales#> locale -a de_DE.utf8 en_US.utf8 fr_FR.utf8 it_IT.utf8and install missing locales for the language with a wrong date/time/number formatting, e.g. Ubuntu:
# add new locale entry to the list: echo fr_FR.UTF-8 UTF-8 >> /var/lib/locales/supported.d/local # or add all supported locales (! slows down package installation/updates): ### cp /usr/share/i18n/SUPPORTED /var/lib/locales/supported.d/local # and don't forget to compile locale definition files: locale-gen
Slow response working with WebDAV resources on Windows Vista or Windows 7
RedHat/Fedora/CentOS: Graphics::Magick does not compile
© ZE CMS, Humboldt-Universität zu Berlin | Written 2011, 2012 by Daniel Rohde