summaryrefslogtreecommitdiffstats
path: root/maildir/README.sharedfolders.html
diff options
context:
space:
mode:
Diffstat (limited to 'maildir/README.sharedfolders.html')
-rw-r--r--maildir/README.sharedfolders.html1060
1 files changed, 1060 insertions, 0 deletions
diff --git a/maildir/README.sharedfolders.html b/maildir/README.sharedfolders.html
new file mode 100644
index 0000000..2387b1b
--- /dev/null
+++ b/maildir/README.sharedfolders.html
@@ -0,0 +1,1060 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii" />
+
+ <title>Shared folders</title>
+ <meta name="MSSmartTagsPreventParsing" content="TRUE" />
+</head>
+<!-- Copyright 2000 Double Precision, Inc. See COPYING for -->
+<!-- distribution information. -->
+
+<body>
+ <h1>Shared folders</h1>
+
+ <p>This document describes how shared folders are implemented by
+ Courier-IMAP, and SqWebMail.</p>
+
+ <p>Courier-IMAP and SqWebMail actually have two different shared
+ folder implementations, for two situations: A) Filesystem
+ permissions-based shared folders, for systems with traditional
+ shell login accounts, and mailboxes; and B) virtual shared
+ folders, for closed systems that provide mail access only, with
+ all mailboxes using the same system userid/groupid, and no
+ end-user shell login access.</p>
+
+ <p>This documentation is also applicable to the Courier mail
+ server, which includes Courier-IMAP and SqWebMail as its
+ components. There are some minor implementation differences
+ between the standalone Courier-IMAP and SqWebMail packages, and
+ Courier; namely the different locations of several key
+ configuration files. Aside from that, both implementation are
+ equivalent.</p>
+
+ <table>
+ <tbody>
+ <tr>
+ <th align="left" colspan="2">Table Of Contents</th>
+ </tr>
+
+ <tr>
+ <td colspan="2"><a href="#newshared">Virtual shared
+ folders</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#newsharedterm">Terminology</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#newsharedtech">Technical Overview</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#newsharedfunc">Functional Overview</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#combo">Combining Courier-IMAP's and SqWebMail
+ index files</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#imapacl">IMAP Access Control List and account
+ groups</a></td>
+ </tr>
+
+ <tr>
+ <td colspan="2">&nbsp;</td>
+ </tr>
+
+ <tr>
+ <td colspan="2"><a href="#oldshared">Filesystem
+ permissions-based shared folders</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedterm">Terminology</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedtech">Technical Overview</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedfunc">Functional Overview</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedaccess">Accessing shared
+ folders</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedsub">Subscribing to a shared
+ folder</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedunsub">Unsubscribing to a shared
+ folder</a></td>
+ </tr>
+
+ <tr>
+ <td>&nbsp;</td>
+
+ <td><a href="#oldsharedopen">Opening a shared
+ folder</a></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h1><a name="newshared" id="newshared">Virtual shared
+ folders</a></h1>
+
+ <h2><a name="newsharedterm" id=
+ "newsharedterm">Terminology</a></h2>
+
+ <p>Virtual shared folders are implemented in a completely
+ different manner. In a virtual setup, all mailboxes use the same
+ system userid and groupid; there is no shell login access to the
+ mail server, and all access is managed by setting up access
+ control lists. Each individual user may voluntarily grant access
+ to a folder to another user or group of user. Access control
+ lists permit fine-grained control. It is possible to specify what
+ different users are permitted to do to the folder or its
+ contents. Since there is no shell login access, all access to
+ mail folders occurs through an IMAP connection to the server, and
+ the IMAP server observes the defined access control lists on each
+ folder.</p>
+
+ <blockquote>
+ <p><em>NOTE:</em></p>
+
+ <p>The references to IMAP in this documentation equally apply
+ to SqWebMail as well. This documentation file is included in
+ Courier-IMAP's and SqWebMail's tarballs. When reading this
+ documentation file in the SqWebMail tarball, mentally replace
+ all references to IMAP with webmail. SqWebMail does not use
+ IMAP, the server reads the maildirs directory; but it uses the
+ same shared library as Courier-IMAP, which explains the similar
+ implementation.</p>
+ </blockquote>
+
+ <p>For more information on how to set up access control lists,
+ see the <a href="maildiracl">maildiracl(1)</a> manual page.</p>
+
+ <h2><a name="newsharedtech" id="newsharedtech">Technical
+ Overview</a></h2>
+
+ <p>After logging in, the server process runs in the logged in
+ account's maildir. As the INSTALL file describes in great detail,
+ virtual mail accounts may be maintained via a wide variety of
+ back-end databases, including MySQL, PostgresSQL, or an LDAP
+ directory. If now the server needs to check the access controls
+ on another account's mail folder, to determine if the user has
+ access to it, the server needs to now locate where the other
+ account is located.</p>
+
+ <p>However, there are several reasons why the server cannot
+ directly go back to the authentication database. The first reason
+ is that after logging in the server process no longer has root
+ privileges; and database configuration files normally require
+ root privileges (since they may contain administrative
+ passwords). Although there might be ways to hack around that, the
+ second reason is the show-stopper: IMAP's design permits clients
+ to enumerate all available shared mail accounts, or arbitrary
+ subsets of them. And, in fact, many of them do just that; mainly
+ because IMAP's design leaves no other alternative, in some
+ situations.</p>
+
+ <p>Clearly, it is not feasible to have hundreds of clients
+ hammering at the database server, repeatedly downloading huge
+ lists of available shared folders (which may number in tens of
+ thousands, on a busy server). Therefore, the following approach
+ is used.</p>
+
+ <p>One or more flat text files are set up, which contain an index
+ of all virtual mail folders. The list is, essentially, downloaded
+ from the authentication database. The text file contain a subset
+ of the data in the authentication database; only the minimum
+ amount of fields necessary to specify the account's name, and
+ where the account lives. The server process quickly reads the
+ text file(s) in order to locate another account's folder, and to
+ check its access control list.</p>
+
+ <p>The system administrator will need to set up a
+ regularly-scheduled process that rebuilds the shared folder
+ index. Yes, that means that a new account's shared folders will
+ not be accessible, by other accounts, until the shared folder
+ index gets rebuilt (but the account still has immediate access to
+ its own folders, after creation). The shared folder index will be
+ updated in a manner that allows the update to occur live, without
+ requiring any system downtime.</p>
+
+ <p>On moderately-sized systems it might be feasible to invoke the
+ shared index update script as part of the process that adds or
+ removes an account; thereby the shared folder index files will
+ always be kept up to date.</p>
+
+ <p>In its most simple form, the shared index is a single file,
+ called <em>SYSCONFDIR/shared/index</em>, where "SYSCONFDIR" is
+ the server's configuration directory. The following table
+ provides the default locations of the configuration file:</p>
+
+ <table>
+ <tbody>
+ <tr>
+ <td>Courier-IMAP:</td>
+
+ <td>
+ <code>/usr/lib/courier-imap/etc/shared/index</code></td>
+ </tr>
+
+ <tr>
+ <td>Courier:</td>
+
+ <td><code>/usr/lib/courier/etc/shared/index</code></td>
+ </tr>
+
+ <tr>
+ <td>Courier (Red Hat/Fedora build):</td>
+
+ <td><code>/etc/courier/shared/index</code></td>
+ </tr>
+
+ <tr>
+ <td>SqWebMail (standalone build):</td>
+
+ <td>
+ <code>/usr/local/share/sqwebmail/shared/index</code></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <blockquote>
+ <p><em>NOTE:</em></p>
+
+ <p>If the "shared" directory doesn't exist, just create it.</p>
+ </blockquote>
+
+ <p>Blank lines in this file are ignored, as well as lines that
+ begin with a single "#" character, which are arbitrary comments.
+ Each remaining line specifies the location of an account's
+ maildir. The line contains the following fields, separated by a
+ single tab character:</p>
+
+ <ol>
+ <li>name</li>
+
+ <li>system userid</li>
+
+ <li>system groupid</li>
+
+ <li>virtual home directory</li>
+
+ <li>maildir path, relative to the virtual home directory</li>
+ </ol>
+
+ <p>"name" <em>SHOULD</em> be the account's login name (which in
+ some rare configurations may not actually match the IMAP login
+ used by the client; this is the name that's logged to syslog when
+ the account successfully logs in, which is usually the same as the
+ IMAP login id). In most situations all accounts will have the
+ same system userid and groupid. The server doesn't actually do
+ anything with these fields at this time, but may do so in the
+ future.</p>
+
+ <p>The virtual account's home directory is taken verbatim from
+ the authentication database. The maildir path field is optional.
+ If missing, it defaults to "./Maildir". Combining the home
+ directory, and the maildir path, results in the location where
+ the specified account's maildir folders may be found.</p>
+
+ <p>Inaccessible accounts are silently ignored. This allows the
+ shared folder index to be itself shared between multiple servers
+ even though that accounts themselves are not shared. Each server
+ will only see the accounts it can access.</p>
+
+ <p>As mentioned previously, IMAP clients will often want to
+ obtain a complete list of shared folders. If the mail server has
+ more than a a couple of hundred accounts, a single index file may
+ be inefficient, and the mail accounts should be segregated into
+ different groups. An account group entry in the index file looks
+ like this:</p>
+
+ <ol>
+ <li>group name</li>
+
+ <li>*</li>
+
+ <li>filename</li>
+ </ol>
+
+ <p>When the second tab-delimited field is a single asterisk, the
+ first field is taken to be a name of an account group; and
+ "filename" is the name of another, separate, index file that
+ lists all accounts that belong in this group. The second file
+ should also be installed in <code>SYSCONFDIR/shared</code>.</p>
+
+ <p>When it's time to use account groups,
+ <code><em>SYSCONFDIR/shared/index</em></code> will usually
+ contain only group entries, with the accounts themselves
+ dispersed in other files in the same directory.</p>
+
+ <p>Account names and group names use the <code>UTF-8</code>
+ character set. This is not usually an issue for account names,
+ which are almost always limited to the Latin character set. Group
+ names may be arbitrary, though, and include non-Latin characters,
+ using <code>UTF-8</code>.</p>
+
+ <p>Courier does not allow IMAP folder names to contain the "." or
+ the "/" characters. The shared index file may include those
+ characters in account or group names, and they will be
+ automatically replaced by spaces (which are allowed).</p>
+
+ <p>This is not normally an issue, unless there exists two
+ separate accounts or groups whose names are the same, except that
+ one name contains spaces, and the other name contains the
+ forbidden characters. This is obviously not something that is
+ likely to occur, but if it did the end result would be that one
+ of the names will have its punctuation characters replaced by
+ spaces, and now two virtual folders will exist with the same
+ name.</p>
+
+ <p>If this rather unlikely scenario somehow materializes the
+ solution is to enable the <code>IMAP_SHAREDMUNGENAMES</code>
+ setting in Courier-IMAP's configuration file. When enabled, this
+ setting replaces the "." and "/" with a two character sequence:
+ "\:" and "\;". Any the existing backslashes are doubled, thus
+ preserving folder name uniqueness. This is not something you'd
+ want to do unless you have no other choice.</p>
+
+ <p>The equivalent setting for SqWebMail (or Courier's webmail
+ server) is the <code>SQWEBMAIL_SHAREDMUNGENAMES</code>. When
+ using SqWebMail at the same time as Courier-IMAP, and if
+ <code>IMAP_SHAREDMUNGENAMES</code> is set, the
+ <code>SQWEBMAIL_SHAREDMUNGENAMES</code> variable must also be set
+ in order for everyone to be in sync. This can be done in one of
+ two different ways:</p>
+
+ <blockquote>
+ <ol>
+ <li>
+ <p>Set this variable before running the <code>sqwebmaild
+ start</code> command:</p>
+ <pre>
+SQWEBMAIL_SHAREDMUNGENAMES=1
+export SQWEBMAIL_SHAREDMUNGENAMES
+sqwebmaild start
+</pre>
+ </li>
+
+ <li>
+ <p>Set this environment variable in the web server's
+ configuration files. With Apache, for example:</p>
+ <pre>
+SetEnv SQWEGBMAIL_SHAREDMUNGENAMES 1
+</pre>
+ </li>
+ </ol>
+ </blockquote>
+
+ <h3>Many Shared Accounts</h3>
+
+ <p>When the number of mail accounts begins to exceed a couple of
+ thousand (or even less, depending on the mail server), even
+ account groups will not be enough. If a single mail server has
+ tens of thousands of accounts, an individual IMAP client may
+ potentially access hundreds of thousands of folders.</p>
+
+ <p>It is a sad fact of life that there are poorly-designed IMAP
+ clients that insist on searching for every accessible folder,
+ every time. They will stubornly scan the entire IMAP folder
+ namespace, recursively reading each folder hierarchy, to compile
+ a list of available folders. Even though there may only be a few
+ folders shared by their owners, the server still has to check
+ whether the IMAP client has access to each folder, in order to
+ compile the list of accessible folders. No mail server will like
+ an IMAP client that insists on reading the access control lists
+ of hundreds of thousand of folders.</p>
+
+ <p>This problem is solved by setting the
+ "<code>sharedgroup</code>" option for each account. The
+ <code>INSTALL</code> file contains a more specific description of
+ how to initialize account options. Normally, the shared folder
+ index file is "<em>SYSCONFDIR/shared/index</em>"; however, if the
+ "<code>sharedgroup</code>" option is set, the value of
+ "<code>sharedgroup</code>" is appended to the shared folder index
+ filename. So, if user1's account has the
+ "<code>sharedgroup=12</code>" option, as far as this account is
+ concerned the shared folder index file is
+ "<em>SYSCONFDIR/shared/index12</em>". Note that
+ <em>SYSCONFDIR/shared/index12</em> may still contain account
+ group entries that point to other shared index files.</p>
+
+ <p>This enables the ability to partition all accounts into
+ smaller "universes". The list of accounts is broken up into
+ individual universe. Accounts within a universe can only see
+ other accounts in the same universe. Even if a given folder's
+ access control lists permit global access, only accounts in the
+ same universe will be able to access it.</p>
+
+ <p>Also note that trans-universal wormholes are possible. Two, or
+ more, top-level index files may list the same set of account
+ groups, and those accounts will be visible from both (or more)
+ universes.</p>
+
+ <p><strong>IMPORTANT</strong>: Under no circumstances should you
+ install circular wormholes (index file A lists index file B as a
+ group, and index file B lists index file A as a group). The
+ consequences would be disastrous for both universes.</p>
+
+ <h2><a name="newsharedfunc" id="newsharedfunc">Functional
+ Overview</a></h2>
+
+ <p>As mentioned in the previous section, it is necessary to set
+ up a regularly-scheduled system process that updates the shared
+ folder index files. The procedure for doing so is site-specific.
+ Individual sites will need to put together a set of custom
+ scripts that create the shared folder index files in
+ <em>SYSCONFDIR/shared</em>. This is likely to be a highly
+ site-specific code; however Courier installs several generic
+ shell scripts that can be used as a working starting point.</p>
+
+ <p>The most important step in the process is actually the final
+ step of installing new shared folder index files in
+ <em>SYSCONFDIR/shared</em>. They must be installed in a way that
+ can be done live, without shutting down the system, and without
+ affecting any existing processes. This can be done using the
+ &ldquo;sharedindexinstall&rdquo; script, which may be found in
+ the <code>sbin</code> directory. To use
+ <code>sharedindexinstall</code>, first create the shared index
+ files in a temporary directory called
+ <em>SYSCONFDIR/shared.tmp</em>, then run the script to move all
+ the files in this directory to <em>SYSCONFDIR/shared</em>.</p>
+
+ <p>So a typical script that updates shared index files will
+ generally look like this (this example uses Courier-IMAP, for
+ SqWebMail the directory locations will be different):</p>
+
+ <blockquote>
+ <hr />
+ <pre>
+#!/bin/sh
+sysconfdir="/usr/lib/courier-imap/etc" # Or /etc/courier, or whatever...
+sbindir="/usr/lib/courier-imap/sbin" # Or, wherever it actually is...
+
+rm -rf $sysconfdir/shared.tmp
+mkdir $sysconfdir/shared.tmp || exit 1
+
+#
+# A magical process creates updated shared index files right about now...
+#
+
+$sbindir/sharedindexinstall
+</pre>
+ <hr />
+ </blockquote>
+
+ <blockquote>
+ <h4>NOTE</h4>
+
+ <p>Existing IMAP server processes may continue to use cached
+ shared folder index data for some time, after
+ <code>sharedindexinstall</code>. This will not cause any
+ problems.</p>
+ </blockquote>
+
+ <h3>Using <code>authenumerate</code></h3>
+
+ <p>In most cases, systems that use a single shared index file are
+ likely to need to only run the &ldquo;authenumerate&rdquo;
+ program in order to build the shared folder index. As long as
+ Courier's authentication modules are properly configured (and
+ <code>authdaemond</code> is running) <code>authenumerate</code>
+ will download the list of accounts from the configured
+ authentication module, and generate a suitably-formatted list on
+ standard output. So the complete shared folder index update
+ script will look like this:</p>
+
+ <blockquote>
+ <hr />
+ <pre>
+#!/bin/sh
+sysconfdir="/usr/lib/courier-imap/etc"
+sbindir="/usr/lib/courier-imap/sbin"
+
+rm -rf $sysconfdir/shared.tmp
+mkdir $sysconfdir/shared.tmp || exit 1
+
+$sbindir/authenumerate -s &gt;$sysconfdir/shared.tmp/index || exit 1
+
+$sbindir/sharedindexinstall
+</pre>
+ <hr />
+ </blockquote>
+
+ <p>The functionality to enumerate accounts is new to Courier-IMAP
+ 3.0. When upgrading from an earlier versions, systems that are
+ configured to use a custom MySQL, PostgreSQL, or LDAP queries
+ will need to enter a new configuration setting in the appropriate
+ configuration file. The update process will add a new variable to
+ the configuration file, which must be initialized to contain the
+ custom query that reads the account list accordingly. In most
+ cases the query only needs to be a slight variation on the
+ existing query that checks the password of a specific account
+ that's requesting authentication.</p>
+
+ <p>Systems that do not use the custom query option should not
+ need to make any additional setting, as the standard query
+ authentication variables contain all the information that's
+ needed to obtain a complete list of accounts.</p>
+
+ <p>If only a small proportion of your users are entitled to use
+ shared mailboxes, then it helps scalability enormously if you
+ restrict the shared index file to contain just those accounts.
+ The <b>-s</b> flag to <code>authenumerate</code> implements this,
+ by discarding all accounts which have the option
+ <code>disableshared</code> set to a non-zero value. Further
+ efficiency can be gained by customising your database query so
+ that the database itself returns only the relevant accounts. Use
+ option <code>MYSQL_ENUMERATE_CLAUSE</code>,
+ <code>PGSQL_ENUMERATE_CLAUSE</code> or
+ <code>LDAP_ENUMERATE_FILTER</code> as appropriate.</p>
+
+ <p>Note also that you can set
+ <code>DEFAULTOPTIONS="disableshared=1"</code> in
+ <code>authdaemonrc</code> to make sharing disabled for everyone,
+ and then set option <code>disableshared=0</code> only on
+ permitted accounts.</p>
+
+ <blockquote>
+ <h4>NOTE</h4>
+
+ <p><code>authenumerate</code> tries not to download the
+ complete results of each query into a memory buffer, but it may
+ be that this still happens due to circumstances out of its
+ control (e.g. older versions of MySQL or PostgreSQL client
+ libraries may force this to happen). If so, it's possible that
+ <code>authenumerate</code>'s memory requirements may be large
+ enough to affect the running system. In this case you will need
+ to come up with an alternative mechanism to obtain the list of
+ accounts, in some other way.</p>
+ </blockquote>
+
+ <blockquote>
+ <h4>NOTE</h4>
+
+ <p>The PAM library does not have a function that obtains a list
+ of available accounts. Therefore, on all systems that use the
+ <code>authpwd</code>, <code>authshadow</code>, or
+ <code>authpam</code> modules, <code>authenumerate</code> works
+ in exactly the same way: by using the <code>getpwent</code>()
+ function. Systems that use certain PAM modules, such as ones
+ that authenticate against a MySQL, a PostgreSQL, or an LDAP
+ database, will not be able to use <code>authenumerate</code>,
+ and must come up with a suitable replacement.</p>
+ </blockquote>
+
+ <h3>Using <code>sharedindexsplit</code></h3>
+
+ <p>As mentioned in the <a href="#newsharedtech">technical
+ overview</a>, a single index file may not be feasible if the
+ number of accounts is more than a thousand, or so. At that point
+ it becomes necessary to split the shared folder index into
+ multiple files.</p>
+
+ <p>The <code>sharedindexsplit</code> script reads a list of all
+ accounts, formatted as a single shared folder index (which,
+ incidentally, matches <code>authenumerate</code>'s output format
+ as well) and splits it into multiple files. The first argument to
+ <code>sharedindexsplit</code> is the name of the directory where
+ the output files are going to be created. The directory must be
+ empty.</p>
+
+ <p><code>sharedindexsplit</code> splits the index into multiple
+ files, based on either the 'sharedgroup' account option, or the
+ first character or characters of the account's name. Use the
+ optional second argument to <code>sharedindexsplit</code> to
+ specify a number, if splitting the account list based on initial
+ characters is desired. If splitting based on the 'sharedgroup'
+ account option then use the <code>-o</code> flag to
+ <code>authenumerate</code> to get it to include the account
+ options in its output.</p>
+
+ <p>Perl 5.8.0, or greater, must be installed if account names
+ include non-Latin characters. For best results, the shared folder
+ index input to <code>sharedindexsplit</code> should already be
+ sorted, but it doesn't have to be.</p>
+
+ <p>Therefore, the following scripts should produce good results
+ on a system with a large, but a moderate number of accounts.
+ Split on 'sharedgroup' if you have a number of separate
+ 'universes' where sharing is only permitted within each universe;
+ otherwise split on the account name if all users can potentially
+ access all shared mailboxes.</p>
+
+ <blockquote>
+ <hr />
+ <pre>
+#!/bin/sh
+sysconfdir="/usr/lib/courier-imap/etc"
+sbindir="/usr/lib/courier-imap/sbin"
+
+rm -rf $sysconfdir/shared.tmp
+mkdir $sysconfdir/shared.tmp || exit 1
+
+# split on the 'sharedgroup' option
+$sbindir/authenumerate -s -o &gt;$sysconfdir/shared.tmp/.tmplist || exit 1
+$sbindir/sharedindexsplit $sysconfdir/shared.tmp &lt;$sysconfdir/shared.tmp/.tmplist || exit 1
+rm -f $sysconfdir/shared.tmp/.tmplist
+$sbindir/sharedindexinstall
+</pre>
+ <hr />
+ <pre>
+#!/bin/sh
+sysconfdir="/usr/lib/courier-imap/etc"
+sbindir="/usr/lib/courier-imap/sbin"
+
+rm -rf $sysconfdir/shared.tmp
+mkdir $sysconfdir/shared.tmp || exit 1
+
+# split on the first 1 character of the username
+$sbindir/authenumerate -s &gt;$sysconfdir/shared.tmp/.tmplist || exit 1
+$sbindir/sharedindexsplit $sysconfdir/shared.tmp 1 &lt;$sysconfdir/shared.tmp/.tmplist || exit 1
+rm -f $sysconfdir/shared.tmp/.tmplist
+$sbindir/sharedindexinstall
+</pre>
+ <hr />
+ </blockquote>
+
+ <p><code>authenumerate</code> is saved to a temporary file,
+ instead of being piped directly, is so that its exit code can be
+ checked. We want to abort the entire process if
+ <code>authenumerate</code> terminates with a non-zero exit code.
+ If <code>authenumerate</code> pipes its output directly to
+ <code>sharedindexsplit</code>, and aborts with an error, then
+ <code>sharedindexsplit</code> will read an empty shared folder
+ index, consequently the output directory will be empty, and then
+ <code>sharedindexinstall</code> will obligingly install an empty
+ list of shared folders.</p>
+
+ <p>As mentioned previously, at some point
+ <code>authenumerate</code>'s memory requirements may become too
+ much to handle, and an alternative mechanism will need to be
+ improvised. <code>sharedindexsplit</code>'s memory requirements
+ are not dependent on the number of accounts, so this script can
+ still be used even with very many accounts.</p>
+
+ <p>When it's time to use account groups,
+ <em>SYSCONFDIR/shared/index</em> will usually contain only group
+ entries, with the accounts themselves dispersed in other files in
+ the same directory.</p>
+
+ <h2><a name="combo" id="combo">Combining Courier-IMAP's and
+ SqWebMail index files</a></h2>
+
+ <p>The information in this section is applicable only when
+ running both Courier-IMAP and SqWebMail packages. This is not
+ applicable when running Courier, which includes both the IMAP
+ server and the webmail server. In the Courier build, both servers
+ are set up to use the same shared index file.</p>
+
+ <p>But, if both standalone builds are installed, Courier-IMAP
+ will want to use
+ <code>/usr/lib/courier-imap/etc/shared/index</code> as its shared
+ index file, while SqWebMail will read
+ <code>/usr/local/share/sqwebmail/shared/index</code>.</p>
+
+ <p>To make both servers use the same shared folder index, create
+ a soft link:</p>
+ <pre>
+ln -s /usr/lib/courier-imap/etc/shared /usr/local/share/sqwebmail/shared
+</pre>
+
+ <p>It's important to create a soft link to the entire "shared"
+ directory, otherwise index group files will not work.</p>
+
+ <h2><a name="imapacl" id="imapacl">IMAP Access Control List and
+ account groups</a></h2>
+
+ <p>Even after setting up shared folders indexes correctly, the
+ mail client will show an empty list of shared folders. This is
+ because even though each account's folders may be shared, they
+ will not be visible to other accounts until the mail account's
+ owner explicitly grants public access to a folder. This can be
+ done using an IMAP mail client that understands access control
+ lists, using Courier's SqWebMail, or the <tt>maildiracl</tt>
+ command. The <tt>maildiracl</tt> manual page includes an overview
+ of access control lists and how to control who gets what kind of
+ rights on a folder. See the <tt>maildiracl</tt> manual page for
+ more information.</p>
+
+ <h1><a name="oldshared" id="oldshared">Filesystem
+ permissions-based shared folders</a></h1>
+
+ <h2><a name="oldsharedterm" id=
+ "oldsharedterm">Terminology</a></h2>
+
+ <ul>
+ <li>Sharable Maildir - a maildir that contains folders that can
+ be shared.</li>
+
+ <li>Sharable folder - one or more folders in a sharable Maildir
+ that can be shared.</li>
+ </ul>
+
+ <h2><a name="oldsharedtech" id="oldsharedtech">Technical
+ Overview</a></h2>
+
+ <ul>
+ <li>They are a somewhat logical extension of the base Maildir
+ format.</li>
+
+ <li>Older versions of Courier-IMAP and SqWebMail will
+ completely ignore shared folders.</li>
+
+ <li>Messages in shared folders do not count towards any
+ individual maildir quotas (see <tt><a href=
+ "README.maildirquota.html">README.maildirquota.html</a></tt>).</li>
+
+ <li>Shared folders are implemented as additional, Maildir-based
+ folders. The messages will be soft links to the messages in the
+ sharable folder. Soft links will be used instead of hard links
+ in order to be able to have a folder containing large messages,
+ and then be able to reclaim space immediately when the messages
+ are purged, instead of waiting for everyone to sync up and
+ delete their hard link. The flip side is that you can expect
+ the usual sorts of errors and increased confusion if someone
+ attempts to read a message that has just been removed, but
+ their client (Courier-IMAP or SqWebMail) doesn't know that yet.
+ That's unavoidable. You'll probably have to set some kind of a
+ policy in order to keep the expected insanity to a
+ minimum.</li>
+
+ <li>Sharable folders are subscribed to by creating a separate
+ maildir-type directory within the main Maildir. It's created in
+ a separate subdirectory that is ignored by other Maildir
+ clients.</li>
+
+ <li>The new directory will contains soft links to the messages
+ in the sharable folder. "Synchronization" code will be used to
+ synchronize the contents of the sharable folder, and the copy
+ of it in the regular Maildir. Once links to the messages are
+ created, they can be manipulated like regular messages in a
+ Maildir. This procedure will be transparently performed by
+ Courier-IMAP or SqWebMail behind the scenes.</li>
+
+ <li>Access to shared folders is controlled by a combination of
+ an explicit configuration, plus regular filesystem permissions.
+ If account owners have shell access to the server, they can
+ create shared folders, and link their mailbox to other
+ accounts' shared folders. Then, the actual access is controlled
+ by regular filesystem permissions. The owner of the shared
+ folder will use the regular filesystem permission to give read
+ and/or write access to either everyone else, or everyone else
+ who uses the same system group ID. Read access allows people to
+ read messages from a shared folder. Write access allows people
+ to add and delete messages in the shared. The owner of the
+ shared folder can remove any message, everyone else will be
+ able to remove only their own messages.</li>
+ </ul>
+
+ <h2><a name="oldsharedfunc" id="oldsharedfunc">Functional
+ Overview</a></h2>
+
+ <p>Generally speaking, shared folders are configured using a
+ feature-enhanced <tt>maildirmake</tt> command as follows:</p>
+
+ <ul>
+ <li><tt>make install</tt> will install a <tt>maildirmake</tt>
+ command that has a bunch of funny options. The modified
+ <tt>maildirmake</tt> command is installed into Courier-IMAP's
+ or SqWebMail's installation directory.</li>
+
+ <li>Somebody, maybe you, will use some of these options to
+ create a maildir with modified permissions. The same somebody
+ will run <tt>maildirmake</tt> again, with a few other options,
+ to create folders in that maildir, also with modified
+ permissions. Those permissions allows global read (and
+ optionally write) access to those folders.</li>
+
+ <li>Do NOT use this maildir as the primary mailbox, INBOX, for
+ an account. Instead, you must create this maildir separately,
+ perhaps as $HOME/Maildir-shared, then set it up as one of your
+ sharable maildirs (see below), and access it in shared mode.
+ Because you own it, you have unlimited read/write access to it.
+ The previously mentioned options will select whether or not
+ access permissions are given to everyone else, and they do not
+ apply to you.</li>
+
+ <li>Everyone else will run <tt>maildirmake</tt> with even more
+ funny options. Those options install a link from their own
+ maildir to a maildir that contains sharable folders. A given
+ maildir may contain links to more than one sharable maildir. As
+ long as their system user/group permissions allow them to
+ access messages, they can SUBSCRIBE via their IMAP client to
+ the folder, or use the SUBSCRIBE function in SqWebmail.</li>
+
+ <li>If people do not have shell access, the system
+ administrator will have to run <tt>maildirmake</tt> on their
+ behalf, in order to create the links to the sharable
+ maildirs.</li>
+
+ <li>People with write access can add messages to a sharable
+ folder. Messages from a sharable folder can be removed only by
+ the owner of the shared folder, or by the owner of each
+ message.</li>
+
+ <li>This sharable maildir implementation cannot use maildir
+ soft-quotas. There cannot be a soft-quota installed in a
+ sharable maildir. If you need quota support, you will have to
+ use filesystem-based quotas. There are some sticky issues with
+ updating quotas on a sharable maildir.</li>
+ </ul>
+
+ <p>Also, note that anyone, not just the superuser, can create a
+ sharable maildir in their account, and invite anyone else to
+ access it, as long as their system user/group permissions allow
+ them access.</p>
+
+ <p>To summarize:</p>
+
+ <ul>
+ <li>Use the -S option to <tt>maildirmake</tt> to create a
+ maildir that can contain sharable folders.</li>
+
+ <li>Use the -s and -f options to <tt>maildirmake</tt> to create
+ sharable folders. The same sharable maildir may contain
+ multiple sharable folders with different access permissions, as
+ selected by the -s option.</li>
+
+ <li>Use the <tt>--add</tt> option to install a link from a
+ regular maildir to a sharable maildir. Afterwards, IMAP clients
+ will be able to subscribe to folders in the sharable
+ maildir.</li>
+
+ <li>Use the <tt>--del</tt> option to remove a link.</li>
+ </ul>
+
+ <p>For more information on these options, see the
+ <tt>maildirmake</tt> manual page that will be installed.</p>
+
+ <h3>More on additional options for the <tt>maildirmake</tt>
+ command</h3>The '-S' option to <tt>maildirmake</tt> to create a
+ maildir that will contain shared folders. The -S option gives
+ group and world read permissions on the maildir itself (where
+ group/world permissions are normally not set for a regular
+ maildir). This allows access to any folders in the shared
+ maildir, and that's why you should not use this Maildir directly
+ as your primary mailbox.
+
+ <p>The "new" and "cur" subdirectories will not be used or shared,
+ although they will still be created. Both SqWebMail and
+ Courier-IMAP create their auxiliary files in the main Maildir
+ with the group and world permissions turned off, so this maildir
+ can, theoretically, still be used as the primary INBOX, but I
+ don't recommend that.</p>
+
+ <p>The -S option is not limited to the system administrator. In
+ fact, anyone can use the -S option, to create shared maildirs
+ that they maintain.</p>
+
+ <p>Shared folders are created like any other folder, using the
+ <tt>-f</tt> option to <tt>maildirmake</tt>. However, that
+ normally creates a folder that is not sharable, because it will
+ not have any group or world permissions. Therefore,
+ <tt>maildirmake</tt> will take the following options to create a
+ sharable folder:</p>
+
+ <ul>
+ <li><tt>-s read</tt> will create a "moderated" folder. The
+ folder will have group and world read permissions, letting
+ anyone read messages, but only the owner of the sharable
+ Maildir can add messages to the sharable folder.</li>
+
+ <li><tt>-s write</tt> will create an "unmoderated" folder. The
+ folder will have group and world read/write permissions,
+ letting anyone read and add messages to the folder. The folder
+ will be created with the sticky bit set, like the <tt>/tmp</tt>
+ directory, preventing people from removing someone else's
+ messages.</li>
+
+ <li><tt>-s read,group/-s write,group</tt> append a comma and
+ the word "group" to modify the semantics of moderated and
+ unmoderated folders only on the group level, not the group and
+ world level, as far as permissions go. This restricts sharing
+ the folder only to members of the same system group as the
+ owner of the sharable maildir.</li>
+ </ul>
+
+ <p>It's worth noting that it is perfectly permissible for folders
+ in the same sharable maildir to have different access levels.</p>
+
+ <p>Also, this is driven entirely by filesystem permissions, so
+ theoretically it's possible to create a folder that has write
+ permissions for the group, and read permissions for everyone
+ else. However, I'm too lazy to actually do it. Feel free to patch
+ <tt>maildirmake</tt> to add this functionality, then send me the
+ patch.</p>
+
+ <h2><a name="oldsharedaccess" id="oldsharedaccess">Accessing
+ shared folders</a></h2>
+
+ <p>The rest of the document consists of technical implementation
+ notes.</p>
+
+ <p>Accessing a collection of shared folders is implemented by a
+ new file that is installed in the primary maildir (usually
+ $HOME/Maildir), and a new subdirectory hierarchy underneath the
+ primary maildir, which are hereby declared.</p>
+
+ <h3><tt>shared-maildirs</tt></h3>
+
+ <p>This file must be created by the administrator or by the
+ maildir owner, manually. This file lists all available sharable
+ maildirs that this maildir can access in shared mode (confused
+ yet?). This file contains one or more lines of the following
+ format:</p>
+
+ <p><tt>name /path/to/shared/maildir</tt></p>
+
+ <p>"<em>name</em>" is an arbitrary name that's given to this
+ collection of shared folders. The name may not contain slashes,
+ periods, or spaces. This is followed by a pathname to the maildir
+ containing shared folders. Note that this is NOT the sharable
+ folder itself, but the maildir that contains one or more sharable
+ folders. The maildir client will be able to selectively subscribe
+ to any sharable folder in that maildir.</p>
+
+ <h3><tt>shared-folders</tt></h3>
+
+ <p>This subdirectory forms the root of all the shared folders
+ that are subscribed to. Let's say that <tt>shared-maildirs</tt>
+ has the following contents:</p>
+
+ <p><tt>firmwide /home/bigcheese/Maildir-shared</tt> <tt>tech
+ /home/gearhead/Maildir-shared</tt></p>
+
+ <p>Subscribing to folders 'golf' and 'boat' in bigcheese's shared
+ Maildir, and to the folder 'maintenance' in gearhead's shared
+ Maildir involves creating the following subdirectories:
+ <tt>shared-folders/firmwide/.golf</tt>,
+ <tt>shared-folders/firmwide/.boat</tt>, and
+ <tt>shared-folders/tech/.maintenance</tt>.</p>
+
+ <h3><tt>shared</tt></h3>This is a soft link that's automatically
+ created in <tt>shared-folders/<em>name</em></tt>. It is a soft
+ link that points to the sharable maildir, which contains the
+ sharable folders.
+
+ <h2><a name="oldsharedsub" id="oldsharedsub">Subscribing to a
+ shared folder</a></h2>
+
+ <ul>
+ <li>Read <tt>shared-maildirs</tt>.</li>
+
+ <li>Read the <tt>shared-folders</tt> hierarchy to determine
+ which folders are already subscribed to.</li>
+
+ <li>Read the folders in each maildir listed in
+ <tt>shared-folders</tt>, and ignore the ones that are already
+ subscribed to. Make sure to stat() each folder to make sure
+ that you can read it.</li>
+
+ <li>If necessary, create <tt>shared-folders/<em>name</em></tt>,
+ and create the <tt>shared-folders/<em>name</em>/shared</tt>
+ soft link.</li>
+
+ <li>Create <tt>shared-folders/name/.foldername</tt>, then
+ create the standard <tt>tmp</tt>, <tt>new</tt>, and
+ <tt>cur</tt> subdirectories. All the directories are created
+ without any group or world permissions.</li>
+ </ul>
+
+ <h2><a name="oldsharedunsub" id=
+ "oldsharedunsub">Unsubscribing</a></h2>
+
+ <ul>
+ <li>Delete everything in
+ <tt>shared-folders/name/<em>foldername</em></tt>.</li>
+
+ <li>If this is there are no more subscribed folders in this
+ sharable maildir, delete <tt>shared-folders/name</tt> for good
+ measure as well.</li>
+ </ul>
+
+ <h2><a name="oldsharedopen" id="oldsharedopen">Opening a shared
+ folder</a></h2>
+
+ <p>The process of "opening" a shared folder involves basically
+ "syncing" the contents of
+ <tt>shared-folders/name/.foldername</tt> with the contents of the
+ sharable folder in the original sharable maildir.</p>
+
+ <ul>
+ <li>Do the usual processing on the <tt>tmp
+ subdirectory</tt>.</li>
+
+ <li>Read the contents of
+ <tt>shared-folders/name/<em>foldername</em>/shared/new</tt>. If
+ you find <em>anything</em> in there, rename it to
+ <tt>../cur</tt>, ignoring any errors from the rename. The
+ sharable maildir owner can arrange for mail to be delivered
+ directly to this folder, and the first one to open it will put
+ the message into <tt>cur</tt>.</li>
+
+ <li>Read the contents of
+ <tt>shared-folder/name/<em>foldername</em>/shared/cur</tt>.
+ Call this directory "A", for short.</li>
+
+ <li>Read the contents of
+ <tt>shared-folder/name/<em>foldername</em>/cur</tt>. Call this
+ directory "B", for short.</li>
+
+ <li><tt>stat()</tt> A and B to see if they live on different
+ devices.</li>
+
+ <li>Remove all messages in B that do not exist in A. You want
+ to compare the filenames up to the : character.</li>
+
+ <li>Create soft links from messages that exist in A and do not
+ exist in B. The name in B should not have any flags after the
+ :, so it shows up as a new message.</li>
+
+ <li>You can now do whatever you normally do with a maildir.
+ Note that <tt>new</tt> is completely ignored, though. Moving
+ messages IN and OUT of the shared folder involves copying the
+ message as if it were a new message. Copying the message INTO
+ the shared folder means copying the message into the underlying
+ sharable folder's tmp/cur directory, and it will show up after
+ the next sync.</li>
+ </ul>
+</body>
+</html>