# WebDAV CGI - Documentation

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

You do not need mod_dav for the Apache Web server. WebDAV CGI replaces mod_dav completely.

## Installation

Note: All steps are done with root rights.

Upgrade Note: Please take a look at the Upgrade section for further information.

1. download WebDAV CGI
2. 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 v0.7.0)
   - IO::Compress::Deflate (included in most Linux dists) - (since v0.7.0)
   - Module::Load (included in most Linux dists, older need libmodule-load-perl) - (since v0.8.0)
   - optional (for SMB backend): Filesys::SmbClient (libfilesys-smbclient-perl) - (since v0.8.0)
   - optional (for RCS backend): Rcs (librcs-perl) - (since v0.8.0)
   You can do that with '`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

       ## only for SMB backend users:
       apt-get install libfilesys-smbclient-perl

       ## only for RCS backend users:
       apt-get install librcs-perl

3. install additional binaries/packages for a better WebDAV CGI experience:
   - Speedy - increases the performance of WebDAV CGI (Debian/Ubuntu package: speedy-cgi-perl)
   - Ghostscript - allowes the web interface of WebDAV CGI to generate thumbnails for PDF/PS files (Debian/Ubuntu package: ghostscript)
   - smbclient (only for SMB backend users) - allowes the web interface to show quota information (Debian/Ubuntu package: smbclient)
   - kinit (only for SMB and AFS backend users) - allowes you to omit mod_auth_kerberos (Debian/Ubuntu package: krb5-user)

       ## Debian/Ubuntu quick install:
       apt-get install speedy-cgi-perl ghostscript

       ## only for SMB backend users:
       apt-get install smbclient

       ## only for SMB and AFS backend users:
       apt-get install krb5-user

4. change directory to your preferred installation path, e.g. `cd /etc`
5. unpack WebDAV CGI: `unzip webdavcgi-latest.zip` or `tar jxf webdavcgi-latest.tar.gz2`
6. change directory to the source base (e.g: `cd webdavcgi*`) and call `bash install.sh` to compile all wrappers and to fix file permissions
7. configure webdav.pl
8. configure your web server:
   - you can do that with rewrite rules (recommended)
   - or with a handler action (unsupported)
   Examples for Apache 2.x: (you need the Apache rewrite module: `a2enmod rewrite`) - and don't forget to take a look at the backend specific configurations AFS, GFS, SMB/CIFS, DBB, or RCS

       ### EXAMPLE 1: a complete (virtual) server root handled by WebDAV CGI:
       ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper
       # ScriptAlias /logout /etc/webdavcgi/cgi-bin/logout
       <Location /webdavcgi>
               AuthType Basic
               AuthName "WebDAV/CalDAV/CardDAV space"
               AuthUserFile /path-to-my-auth-file
               Require valid-user
       </Location>
       RewriteEngine On
       # RewriteRule /logout - [L]
       RewriteRule ^/ /webdavcgi [PT,E=WEBDAVCONF:/etc/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl,L]

       ### EXAMPLE 2: a virtual path /webdav
       ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper
       # ScriptAlias /webdav/logout /etc/webdavcgi/cgi-bin/logout
       <Location /webdavcgi>
               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='/webdav/?' and $DOCUMENT_ROOT in your WebDAV CGI config)
       RewriteEngine On
       # RewriteRule ^/webdav/logout - [L]
       RewriteRule ^/webdav /webdavcgi  [PT,E=WEBDAVCONF:/etc/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl,L]

       ### EXAMPLE 3: a .htaccess file to handle a complete folder with WebDAV CGI:
       ### Prerequisites: /webdavcgi is a script alias
       ##       (ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper) and
       ###      'AllowOverride AuthConfig FileInfo' is set for the current folder
       RewriteEngine On
       RewriteRule .* /webdavcgi [E=WEBDAVCONF:/etc/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl]

       AuthType Basic
       AuthName "A protected WebDAV folder"
       AuthUserFile /path-to-my-auth-file
       Require valid-user

## Upgrade

### Upgrading from 0.8.3 to 0.8.4

1. The new install.sh script does not copy or link webdav.pl and webdavwrapper to your cgi-bin directory. You can add/change ScriptAliases to use webdav.pl or a webdavwrapper from your installation src, e.g.

       ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper
       RewriteRule ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl]
       <Location /webdavcgi>
       	AuthType Basic
       	AuthUserFile /etc/apache2/webabusers
       	AuthName "WebDAV/CalDAV/CardDAV space"
       	Require valid-user
       </Location>

2. AFS backend:
   - Speedy support for AFS was added and a mod_auth_kerberos free installation is now possible:
     - a new setuid/setgid wrapper was added: helper/webdavwrapper-afs.c (mod_waklog isn't required if you use webdavwrapper-afs.c)
     - a PAG script was added: cgi-bin/afswrapper
     - visit AFS section for details
   - mod_waklog is no longer required for AFS
3. SMB backend:
   - a wrapper for mod_auth_kerberos free installation was added
   - username/password/workgroup authentication support was added

### Upgrading from 0.8.2 to 0.8.3

1. changed `@UNSELECTABLE_FOLDERS` default to `()` (relevant for AFS backend users)
2. 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

1. see Speedy support section to improve the WebDAV CGI performance

### Upgrading from 0.8.0 to 0.8.1

1. `%AUTOREFRESH` was added for the new auto-refresh feature

### Upgrading from 0.7.x to ≥0.8.0

1. a new Perl module is needed: `Module::Load` (Ubuntu/Debian package: libmodule-load-perl)
2. `OSSP::uuid` Perl module was replaced by `UUID::Tiny` (Ubuntu/Debian package: libuuid-tiny-perl)
3. 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`
4. `$IGNOREFILEPERMISSIONS` config variable was removed
5. `$BACKEND` variable was added and is required (allowed values: 'FS', 'AFS', 'GFS', 'SMB', 'DBB')
6. `$SHOW_MIME` and `$SHOW_PERM` were removed: use the new options `@ALLOWED_TABLE_COLUMNS` and `@VISIBLE_TABLE_COLUMNS` instead
7. `%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
8. `@EXTENSIONS` parameter was added: contains a list of extensions
9. `$ENABLE_SYSINFO` was removed: add `'SysInfo'` to the `@EXTENSIONS` list
10. `$ENABLE_PROPERTIES_VIEWER` was removed: add `'PropertiesViewer'` to the `@EXTENSIONS` list
11. `$ENABLE_SIDEBAR` was removed: use `@SUPPORTED_VIEWS` instead
12. `$MAXLASTMODIFIEDSIZE` was removed
13. `$MAXNAVPATHSIZE` was added

### Upgrading from ≤0.6.x to ≥0.7.x

1. two new Perl modules are used by WebDAV CGI: `IO::Compress::Gzip` and `IO::Compress::Deflate` (both are integraded in most Linux dists)
2. WebDAV CGI is no longer a single file distribution therefore:
   1. unpack the new installation package in your preferred installlation path, e.g. `cd /etc; unzip webdavcgi-0.7.?.zip`
   2. link the path for easier upgrades, e.g. `ln -s /etc/webdavcgi-0.7.? /etc/webdavcgi`
   3. 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

   4. add the `$INSTALL_BASE` variable to your existing `/etc/webdav.conf`, e.g.

          echo "\$INSTALL_BASE='/etc/webdavcgi/';" >> /etc/webdav.conf

   5. check your config file and modules, e.g.

          #> perl -c /etc/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 required modules for RCS backend:
            Rcs installed
          ++++ Checking optional binaries:
            smbclient /usr/bin/smbclient
          #### Summary:
          All modules found.
          All binaries found.

3. 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 of `webdav.pl`.

1. Create a `/etc/webdav.conf` with a minimal setup and don't forget to fix file permissions:
   `chmod a+r /etc/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, RCS):
       $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';

2. Please take a look at backend specific configuration sections AFS, GFS, SMB/CIFS, DBB, RCS
3. If you need to change other options simply copy the parameter from the `webdav.pl` setup section into your config file.
4. Don't forget to check the config file syntax: `perl -c /etc/webdav.conf`
5. 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.

Graphics::Magick does not compile:

- 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

1. Install the necessary Perl DBI driver (Debian/Ubuntu package: libdbd-...-perl)
2. Create the database and the schema
3. 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`, `webdavwrapper-krb.c`, `webdavwrapper-afs.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 cgi-bin/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 cgi-bin/webdavwrapper*

Attention: for AFS and/or Kerberos support you need `webdavwrapper-afs.c` or `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):

1. 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;`
   Attention: You need a single database for all users to share WebDAV locks and properties. If you use a file based database like SQLite you have to use a singe file writeable for all users.
2. 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

AFS note: If you use AFS you have to use AFS groups and AFS ACLs to share folders instead of folder permissions because AFS ignores all Linux/UNIX permissions:

1. Create a AFS group and add AFS users to the group.
2. Set lookup, read, write, delete, insert, and lock rights for that group to the shared folder.
3. 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 the `lib/` 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.

1. put your error documents to the `$INSTALL_BASE/htdocs` folder or wherever you want (should be readable by your users)
2. 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™:

1. Download and install CKEditor™ (e.g. into the `/srv` folder - or use another server)
2. Configure the web server to access all CKEditor™ files, e.g. `RewriteRule /ckeditor /srv/ckeditor [PT,L]`
3. 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>
       	@;
       }

Consider this if you integrate a WYSIWYG editor:

1. Allow only HTML files to edit with a WYSIWYG editor.
2. Disable 'save' button or reconfigure it to submit 'savetextdata'.
3. Use the id 'textdata' for the editor replacement.
4. Disable the WebDAV CGI integrated resizer if the editor comes with its own (set display to none for style .textdataresizer).
5. Enable full page editing to allow changing complete HTML pages.
6. 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 (see `cgi-bin/logout-dist` in your WebDAV CGI source base). It's quiet easy to integrate a logout button:

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

2. Add a rewrite rule to your Apache configuration, e.g: `RewriteRule /logout /usr/lib/cgi-bin/logout [PT,L,E=REALM:WebDAV-CGI,E=HOMEURL:/,E=TIMEOUT:0]`
   Note: this rule should precede the webdavwrapper rule
3. 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:

1. WebDAV CGI script must handle the root context of your Web server (see CardDAV section how to do that).
2. 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>

After that you have to configure WebDAV CGI, e.g:

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

### ... without mod_auth_kerberos

Requirements:

1. OpenAFS client installed on your server (Debian/Ubuntu package: openafs-client) and configured with a default realm: `/etc/krb5.conf`: `default_realm = MY.DOMAIN.NAME` (`kinit <uid_without_domain> ; aklog` should work)
2. Kerberos client tool kinit (Debian/Ubuntu package: krb5-user)
3. All users should be visible for the system and have the same password for AFS and your authentication facility like LDAP, RADIUS,... to authenticate your users with kinit and to allow setuid/setgid: `getent passwd <uid>` should work
4. The `AUTHHEADER` environment variable with the HTTP Authorization header value has to be passed to the wrapper: see RewriteRule of the Apache config example.
5. The `TICKET_LIFETIME` environment variable value should be a little bit smaller than your Kerberos ticket lifetime.
6. `cgi-bin/webdavwrapper-afs` (call `bash install.sh` from your installation directory to compile helper/webdavwrapper-afs.c)

Apache example:

    <Location /webdavcgi>
    	AuthName "WebAFS"
    	AuthType Basic
    	Require valid-user
    </Location>

    ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper-afs
    # ScriptAlias /logout /etc/webdavcgi/cgi-bin/logout
    RewriteEngine on
    # RewriteRule ^/logout - [L]
    RewriteRule ^/ /webdavcgi \
                   [PT,L,E=WEBDAVCONF:/etc/webdav.conf,\
    	             E=PERLLIB:/etc/webdavcgi/lib/perl,\
    		     E=AUTHHEADER:%{HTTP:Authorization}, \
                         E=TICKET_LIFETIME:82800]

`/etc/webdav.conf` example: see next section

### ... with mod_auth_kerberos

Requirements:

1. mod_auth_kerberos installed (Debian/Ubuntu package: libapache2-mod-auth-kerb)
2. 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)
3. OpenAFS client installed on your server (Debian/Ubuntu package: openafs-client) and configured (`kinit ...; aklog` should work)
4. The `TICKET_LIFETIME` environment variable value should be a little bit smaller than your Kerberos ticket lifetime.
5. `cgi-bin/webdavwrapper-afs` (call `bash install.sh` from your installation directory to compile helper/webdavwrapper-afs.c)

Apache example:

    KrbMethodNegotiate off
    KrbMethodK5Passwd on
    KrbSaveCredentials on
    Krb5Keytab /etc/webafs.keytab

    <Location /webdavcgi>
    	AuthName "WebAFS"
    	AuthType Kerberos
    	Require valid-user
    </Location>

    ScriptAlias /webdavcgi /etc/webdavcgi/webdavwrapper-afs
    RewriteEngine on
    RewriteRule  ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf, \
                                     E=PERLLIB:/etc/webdavcgi/lib/perl, \
                                     E=TICKET_LIFETIME:82800]

`/etc/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:

1. a mounted GFS filesystem
2. `gfs_quota` command executable by a user

`/etc/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

The SMB backend supports Kerberos and username/password/workgroup authenticated file share access.

### ... with mod_auth_kerberos

Requirements:

1. a Active Directory integrated Windows or Samba file server
2. mod_auth_kerberos installed (Debian/Ubuntu: libapache2-mod-auth-kerb)
3. a keytab file for the kerberos module:
   1. create a Windows/ADS user account with a good password (e.g. `exampleuser`)
   2. disable password change requirements (policies) for your Windows/ADS user account
   3. 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

   4. copy the keytab file `keytab.HTTP` to a Web server path, e.g. `/etc/keytab.HTTP`
4. `Filesys::SmbClient` perl module installed (Debian/Ubuntu package: libfilesys-smbclient-perl)
5. optional the `/usr/bin/smbclient` binary for quota information (Debian/Ubuntu package: smbclient)
6. 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.
7. You need a wrapper if you use Speedy (see Speed Support section) because the SMB backend needs a fresh Kerberos ticket.
8. unough temporary file space for thumbnails and ZIP upload/download

Apache example:

    ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdav.pl

    KrbVerifyKDC off
    KrbMethodNegotiate on
    KrbMethodK5Passwd on
    KrbAuthoritative on
    KrbServiceName HTTP
    Krb5Keytab /etc/keytab.HTTP
    # required:
    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  ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf,E=PERLLIB:/etc/webdavcgi/lib/perl]

`/etc/webdav.conf` example: see next section

### ... without mod_auth_kerberos but with Kerberos authentication

Requirements:

1. a Active Directory integrated Windows or Samba file server
2. a Apache authentication provider like auth_n_file, mod_authnz_ldap, ... with the same users and synchronized passwords
3. a Kerberos configuration file (/etc/krb5.conf) with a default_realm
4. `Filesys::SmbClient` perl module installed (Debian/Ubuntu package: libfilesys-smbclient-perl)
5. optional the `/usr/bin/smbclient` binary for quota information (Debian/Ubuntu package: smbclient)
6. Kerberos client tool kinit (Debian/Ubuntu package: krb5-user)
7. the `cgi-bin/smbwrapper` script (Speedy compatible): the `TICKET_LIFETIME` (in seconds) should be a little bit smaller than your Kerberos ticket lifetime
8. unough temporary file space for thumbnails and ZIP upload/download

Kerberos configuration example: `/etc/krb5.conf`:

    [libdefaults]
            dns_lookup_realm = true
            dns_lookup_kds = true
            default_realm = MY.EXAMPLE.DOMAIN.ORG
            clockskew = 900
            forwardable = true
            proxiable = true
            allow_weak_crypto = yes
    [domain_realms]
    	my.example.domain.org = MY.EXAMPLE.DOMAIN.ORG
    	.my.example.domain.org = MY.EXAMPLE.DOMAIN.ORG

Apache example:

    ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/smbwrapper

    AuthType Basic
    AuthName "MY.EXAMPLE.DOMAIN.ORG Account"
    Require valid-user

    RewriteEngine on
    RewriteRule ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf, \
                                    E=PERLLIB:/etc/webdavcgi/lib/perl, \
                                    E=AUTHHEADER:%{HTTP:Authorization}, \
                                    E=TICKET_LIFETIME:21600]

`/etc/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/)',
              },
            },
          },
        },
      },
    );

### ... with username/password/workgroup authentication

Requirements:

1. a Windows or Samba file server
2. a Apache authentication provider like auth_n_file, mod_authnz_ldap, ... with the same users and synchronized passwords
3. optional the `/usr/bin/smbclient` binary for quota information (Debian/Ubuntu package: smbclient)
4. the `cgi-bin/smbwrapper` script (Speedy compatible)
5. unough temporary file space for thumbnails and ZIP upload/download

Apache example:

    ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/smbwrapper

    AuthType Basic
    AuthName "Workgroup Account"
    Require valid-user

    RewriteEngine on
    RewriteRule ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf, \
                                    E=PERLLIB:/etc/webdavcgi/lib/perl, \
                                    E=AUTHHEADER:%{HTTP:Authorization}, \
                                    E=SMBWORKGROUP:Workgroup]

`/etc/webdav.conf` example: see previous section

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

Requirements:

- a database driver (DBD perl module; by default SQLite; Ubuntu/Debian package: libdbd-sqlite3-perl)

`/etc/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:

- 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/`)

Known issues:

- 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

Requirements:

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

`/etc/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. 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.
Setup:

1. Install Speedy (Debian/Ubuntu: `apt-get install speedy-cgi-perl`)
2. Change the shebang of webdav.pl:

       OLD: #!/usr/bin/perl
       NEW: #!/usr/bin/speedy -- -r50 -M10 -t3600

   The `-r50` 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 `-M10` limits the count of Speedy processes (see `man speedy`). If you do not use a setuid/setgid wrapper (e.g. if you use the SMB backend) you should remove the `-M10` or set it higher because all your clients using the same Speedy processes and you need one Speedy process per request. The `-t3600` sets the timeout for a idle Speedy process to one hour.
3. Only for the SMB backend:
   1. Add `E=TICKET_LIFETIME:28800` to your RewriteRule:

          RewriteRule ^/ /webdavcgi [PT,L,E=WEBDAVCONF:/etc/webdav.conf, \
                                          E=PERLLIB:/etc/webdavcgi/lib/perl, \
                                          E=TICKET_LIFETIME:21600]

   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

4. Change the Apache script aliases:

       OLD: ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdav.pl
       NEW (with mod_auth_kerberos): ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/webdavwrapper-smb
       NEW (without mod_auth_kerberos): ScriptAlias /webdavcgi /etc/webdavcgi/cgi-bin/smbwrapper

5. 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 to reduce the temporary file space consumption

- That's all and don't forget to check the notes below.
Notes:

- If you change your `/etc/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 `/etc/webdav.conf`: `$DBI_PERSISTENT = 1;`

## Troubleshooting

### Timeout

Maybe it helps to increase the `Timeout` 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.log

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

### 404 File Not Found / 500 Internal Server Error / 'Premature end of script headers'

Please check the following:

1. Apache error log - Apache writes sometimes helpful things into logs
2. read and execute file permissions of `webdavwrapper` and `webdav.pl` and fix it if necessary (owner/group too):

       chmod a+rx webdav.pl
       chmod a+rx,ug+s webdavwrapper
       chown root:root webdavwrapper

3. shebang of `webdav.pl`: path to the Perl interpreter have to be correct
4. `/etc/webdav.conf` syntax (maybe a broken config):

       #> perl -c /etc/webdav.conf
       webdav.conf syntax OK

5. check your /etc/webdav.conf: wrong `$VIRTUAL_BASE` or `$DOCUMENT_ROOT` values are cause for a 404 File Not Found
6. `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 required modules for RCS backend:
         Rcs installed
       ++++ Checking optional binaries:
         smbclient /usr/bin/smbclient
       #### Summary:
       All modules found.
       All binaries found.

7. Check your database setup (`$DBI_SRC`, `$DBI_USER`, `$DBI_PASS`).
8. 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

9. Call webdavwrapper from a shell:

       #> ./webdavwrapper
       Status: 404 Not Found
       Content-Type: text/plain

       404 Not Found - your wrapper

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

1. install UUID::Tiny: `perl -MCPAN -e 'install UUID::Tiny'`
2. replace `use OSSP:uuid;` with `use UUID::Tiny;`:

       sed -i -e 's@use OSSP::uuid;@use UUID::Tiny;@g' webdav.pl

3. replace `sub getuuid {` with `sub _unused_getuuid {`:

       sed -i -e 's@^sub getuuid@sub _unused_getuuid@g' webdav.pl

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

1. Check your `$INSTALL_BASE` variable in your `/etc/webdav.conf` (maybe you forget the trailing slash?)
2. Check /etc/webdav.conf syntax: `perl -c /etc/webdav.conf`
3. Check your Apache rewrite rule: the path to your webdav.conf must be correct: `E=WEBDAVCONF:/etc/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.utf8

and 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

see http://support.microsoft.com/kb/2445570
OR: see http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol

### RedHat/Fedora/CentOS: Graphics::Magick does not compile

see https://bugzilla.redhat.com/show_bug.cgi?id=527143#c2

### Apache error log: Permission denied: exec of '.../webdavwrapper' failed

- Check all file and folder permissions (Apache runs with user permissions)
- SELinux users should define a policy to allow the execution of webdavwrapper.

© ZE CMS, Humboldt-Universität zu Berlin | Written 2011-2012 by Daniel Rohde