<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<book>
  <title>Helios qmail manual</title>

  <bookinfo>
    <author>
      <firstname>Pawel</firstname>

      <surname>Foremski</surname>

      <email>pjf@gna.org</email>
    </author>

    <author>
      <firstname>Christian</firstname>

      <surname>Löschenkohl</surname>

      <email>christian.loeschenkohl@linea7.com</email>
    </author>

    <copyright>
      <year>2004</year>

      <holder>Pawel Foremski and Christian Löschenkohl</holder>
    </copyright>

    <legalnotice>
      <para>This file is free documentation.</para>
    </legalnotice>

    <abstract>
      <para>Describes design, configuration and every-day usage of Helios
      qmail.</para>
    </abstract>

    <pubdate>23-10-2004</pubdate>
  </bookinfo>

  <preface>
    <title>Preface</title>

    <abstract>
      <simpara>Helios qmail is an advanced, top integrated and feature rich
      distribution of qmail based on qmail-sql project. It is mostly written
      in PHP to make it`s adaption easy. Helios qmail has most of the features
      that modern MTA should have.</simpara>
    </abstract>

    <para>This manual describes Helios qmail in detail - it`s <link
    linkend="chap1">design</link>, <link linkend="conf">configuration</link>,
    <link linkend="usersmgm">users managment</link> and <link
    linkend="extending">extending</link>. Note that you will not find here
    installation instructions - you can find them in document called
    <citetitle pubwork="article">Helios qmail installation guide</citetitle>,
    which is bundled with Helios qmail package and available for download in
    several formats from <ulink
    url="http://helios-qmail.sourceforge.net/#DOCS">http://helios-qmail.sourceforge.net/#DOCS</ulink>.
    This document is also distributed in the same way.</para>
  </preface>

  <chapter id="chap1">
    <title>Getting started</title>

    <sect1>
      <title>Introduction</title>

      <para>Helios qmail is an advanced, top integrated and feature rich
      distribution of qmail based on qmail-sql project. It has been created
      because stock qmail is quite useless these days - this project collects
      many popular patches, tools and extensions and links them using
      easy-to-adapt scripts and <acronym>API</acronym>s. Helios qmail can be
      treated as an <acronym>MTA</acronym> which combines security, stability
      and reliability of qmail with flexibility, modern functionality and ease
      of use.</para>
    </sect1>

    <sect1>
      <title>Features</title>

      <para>As of 0.9.0 release, Helios qmail supports:</para>

      <itemizedlist>
        <listitem>
          <para>MySQL database</para>
        </listitem>

        <listitem>
          <para>SMTP service:</para>

          <itemizedlist>
            <listitem>
              <para>SSL/TLS</para>
            </listitem>

            <listitem>
              <para>SMTP authorization</para>
            </listitem>

            <listitem>
              <para>SMTP-after-POP/IMAP</para>
            </listitem>

            <listitem>
              <para>ESMTP SIZE support</para>
            </listitem>

            <listitem>
              <para>antispam protections like:</para>

              <itemizedlist>
                <listitem>
                  <para>SPF (Sender Policy Framework)</para>
                </listitem>

                <listitem>
                  <para>antispoof</para>
                </listitem>

                <listitem>
                  <para>RBL checks</para>
                </listitem>

                <listitem>
                  <para>wildcards support in badhelo, badmailfrom and
                  badrcptto files</para>
                </listitem>

                <listitem>
                  <para>envelope sender and HELO/EHLO domains DNS
                  checks</para>
                </listitem>

                <listitem>
                  <para>tarpitting</para>
                </listitem>
              </itemizedlist>
            </listitem>

            <listitem>
              <para>advanced queue filtering - supports several content
              scanners, such as:</para>

              <itemizedlist>
                <listitem>
                  <para>SpamAssassin</para>
                </listitem>

                <listitem>
                  <para>Bogofilter</para>
                </listitem>

                <listitem>
                  <para>Clam AntiVirus</para>
                </listitem>

                <listitem>
                  <para>Mks_Vir</para>
                </listitem>
              </itemizedlist>
            </listitem>

            <listitem>
              <para>extensive logging</para>
            </listitem>

            <listitem>
              <para>SPP (SMTP plugin patch) support</para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>POP3 service:</para>

          <itemizedlist>
            <listitem>
              <para>SSL/TLS</para>
            </listitem>

            <listitem>
              <para>PLAIN and APOP authorization</para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>IMAP service - BINC IMAP</para>

          <itemizedlist>
            <listitem>
              <para>SSL/TLS</para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>integrated and centralized configuration in
          /var/qmail/control</para>
        </listitem>

        <listitem>
          <para>PHP5 libraries providing nice API for shell scripts and/or web
          applications</para>
        </listitem>

        <listitem>
          <para>single-uid delivery</para>
        </listitem>

        <listitem>
          <para>new mail notification support (through Jabber)</para>
        </listitem>

        <listitem>
          <para>many PHP scripts to help managing the system
          (add/delete/modify/show users/domains/aliases/etc settings)</para>
        </listitem>

        <listitem>
          <para>Maildir++ support</para>
        </listitem>

        <listitem>
          <para>and more...</para>
        </listitem>
      </itemizedlist>
    </sect1>

    <sect1>
      <title>Design notes</title>

      <para>If you are wondering why script language has been chosen to extend
      qmail, the answer is simple - to ease adaption of the system and to make
      it flexible. PHP has been chosen for such function because it is one of
      the most advanced and top-level script languages and to make Helios
      qmail easy to integrate with web applications.</para>

      <para>Helios qmail has been designed also to make it`s extending easy.
      Want an example? Here is a short PHP code (a <link linkend="spp">spp
      module</link>) which implements checking for maximal number of
      recipients:</para>

      <example>
        <title>A PHP implementation of a module checking for maximal number of
        recipients</title>

        <programlisting>#!/usr/local/bin/php
&lt;!php

if( $_ENV['SMTPRCPTCOUNT'] &gt;= $_ENV['MAXRECIPIENTS'] ) {
    echo("550 sorry, too many recipients (#5.7.1)\r\n");
    exit(1);
}
exit(0);

?&gt;</programlisting>
      </example>

      <para>You do not know PHP? No problem, here is a bash
      implementation:</para>

      <example>
        <title>A bash implementation of a module checking for maximal number
        of recipients</title>

        <programlisting>#!/bin/bash

if [ $SMTPRCPTCOUNT -ge $MAXRECIPIENTS ]; then
  echo "550 sorry, too many recipients (#5.7.1)"
  exit 1
fi

exit 0</programlisting>
      </example>

      <para>Such module can be written also in any other language. Helios
      qmail supports extending many of it`s elements in such (easy)
      way.</para>
    </sect1>

    <sect1>
      <title>Who is Helios qmail for?</title>

      <para>Helios qmail is intended to be used by users who have already
      successfuly installed qmail and have been using it for some time. In
      other words, it is not recommended for qmail beginners, because of one
      reason - they probably will not benefit of most of it`s features. If you
      are a beginner, try stock qmail first and read some more documentation
      about it, like <ulink url="http://www.lifewithqmail.org/">Life with
      qmail</ulink>.</para>

      <para>If you are an advanced user you will gain from it`s flexibility
      and many integrated features. Probably the most important advantage of
      Helios qmail is that it is database driven - it causes speed improvement
      and easier managment of users and domains.</para>

      <para>If you are a power user, almost a "qmail hacker", you will
      probably love it`s extensibility - API, spp plugins, advanced content
      scanning, etc... It`s just made for buliding big mail systems,
      integrating it with other applications and making any adaptions.</para>
    </sect1>

    <sect1>
      <title>Installation</title>

      <para>You will not find installation instructions here - you can find
      them in document called <citetitle pubwork="article">Helios qmail
      installation guide</citetitle>, which is bundled with Helios qmail
      package and available for download in several formats from <ulink
      url="http://helios-qmail.sourceforge.net/#DOCS">http://helios-qmail.sourceforge.net/#DOCS</ulink>.</para>
    </sect1>
  </chapter>

  <chapter id="conf">
    <title>System configuration</title>

    <sect1>
      <title>Main configuration file</title>

      <para>The main configuration file is located in
      <filename>/var/qmail/control/qmailconfig</filename> (it is a symbolic
      link to <filename>sqlserver</filename> file for compatibility with
      qmail-sql). It is divided into three parts: "System configuration",
      "Database configuration" and "Advanced options".</para>

      <note>
        <para>Be sure to restart daemontools after changing this file.</para>
      </note>

      <sect2>
        <title>System configuration</title>

        <para>This part contains several global options.</para>

        <itemizedlist>
          <listitem>
            <para>mail_root <emphasis>directory</emphasis></para>

            <para>Main directory for mail (without trailing slash); "domain/"
            and "domain/login" directories will be created there.</para>
          </listitem>

          <listitem>
            <para>default_user <emphasis>username</emphasis></para>

            <para>Contains real username to be assigned to new Helios qmail
            user.</para>
          </listitem>

          <listitem>
            <para>default_group <emphasis>group</emphasis></para>

            <para>Contains real group to be assigned to new Helios qmail
            user.</para>
          </listitem>

          <listitem>
            <para>rcpthosts_from_db { <emphasis>yes</emphasis>,
            <emphasis>no</emphasis> }</para>

            <para>Should Helios qmail read rcpthosts from the database if the
            rcpthosts file is missing.</para>

            <caution>
              <para>If it is turned off, and rcpthosts is missing, your
              mailserver will act as an open-relay.</para>
            </caution>
          </listitem>

          <listitem>
            <para>allowed_recipients_from_db { <emphasis>yes</emphasis>,
            <emphasis>no</emphasis> }</para>

            <para>Verify or not whether local envelope recipients exists
            during SMTP session.</para>
          </listitem>

          <listitem>
            <para>localpop <emphasis>domain</emphasis></para>

            <para>A domain to add to login during authorization if it is
            missing.</para>
          </listitem>

          <listitem>
            <para>domain_separators <emphasis>chars</emphasis></para>

            <para>A list of chars that can be used during authorization by
            clients to separate login from domain name.</para>
          </listitem>

          <listitem>
            <para>check_host { <emphasis>yes</emphasis>,
            <emphasis>no</emphasis> }</para>

            <para>Set it to no if you do not want SQL queries to contain
            virtual host name (not recommended).</para>
          </listitem>

          <listitem>
            <para>globaldomain <emphasis>domain</emphasis></para>

            <para>If set, system searches for login@globaldomain user if it do
            not find it in requested domain.</para>
          </listitem>

          <listitem id="host_postmaster">
            <para>host_postmaster <emphasis>email</emphasis></para>

            <para>Default postmaster`s email for new domains.</para>
          </listitem>

          <listitem>
            <para>autohomedir<emphasis> path</emphasis></para>

            <para>Path to program creating user`s home directory on
            demand.</para>
          </listitem>
        </itemizedlist>
      </sect2>

      <sect2>
        <title>Database configuration</title>

        <para>Be sure to correct this options after first installation.</para>

        <itemizedlist>
          <listitem id="connectionstring">
            <para>connectionstring <emphasis>txt</emphasis></para>

            <para>Configures connection to the database. These options are in
            the format required by PostgreSQL (PQconnectdb). For compatibility
            reasons this field is parsed to get the parameters for connecting
            with a MySQL server.</para>

            <para>An example: connectionstring user=userconsult
            password=readonly dbname=userdb host=localhost</para>

            <note>
              <para>Other MySQL options (eg. port number) are not
              recognized.</para>
            </note>
          </listitem>

          <listitem>
            <para>popconnectionstring <emphasis>txt</emphasis></para>

            <para>The same as <link
            linkend="connectionstring">connectionstring</link>, but this field
            contains data used for writing to the database (for example by
            POP3).</para>
          </listitem>

          <listitem>
            <para>connection_timeout <emphasis>secs</emphasis></para>

            <para>How long (in seconds) should Helios qmail try to connect to
            the database before returning an error. "0" means no limit.</para>
          </listitem>

          <listitem>
            <para>query_timeout <emphasis>secs</emphasis></para>

            <para>How long (in seconds) should Helios qmail wait for an answer
            from the database before returning an error. "0" means no
            limit.</para>
          </listitem>
        </itemizedlist>

        <para>There are several next directives after these options letting
        you to change the database structure (such as table and field
        names).</para>
      </sect2>
    </sect1>

    <sect1>
      <title>System services</title>

      <sect2>
        <title>SMTP</title>

        <para>This section contains information regarding configuration of
        SMTP service. Some qmail options (not Helios qmail specific) are not
        mentioned here - for more information see qmail documentation or
        <ulink url="http://lifewithqmail.org/lwq.html#configuration">Life with
        qmail</ulink>.</para>

        <sect3 id="smtpconffile">
          <title>Configuration file</title>

          <para>SMTP service can be easily configured using
          <filename>/var/qmail/smtpconfig</filename> file. It is a shell
          script, so you can also add here some start instructions if you want
          - this file is reloaded each time daemontools is started.</para>

          <note>
            <para>Be sure to restart daemontools after changing this
            file.</para>
          </note>

          <para>This file is well commented, you should not have problems
          modifying it. However, below are some notes regarding it.</para>

          <sect4>
            <title>SMTP-after-POP and SMTP-after-IMAP</title>

            <para>If you want Helios qmail to automatically authorize users
            basing on POP3 or IMAP authorization which took place some time
            before, enable SMTP-after-POP3/IMAP. Simply set
            <varname>AUTHEXPIRE</varname> environment variable to number of
            minutes that POP3/IMAP authorization should be valid for SMTP too
            and export it. You can also do it using <link
            linkend="smtptcprules">SMTP TCP rules</link> if you want
            host-specific configuration.</para>
          </sect4>

          <sect4>
            <title>Memory limit</title>

            <para>It is highly recommended to set memory limit on qmail SMTP
            service to prevent it from DoS attacks. Required amount of memory
            can vary on several systems, so if you see errors in your logs
            saying that it cannot allocate memory, increase it. You should
            also do it if you are going to use a <link
            linkend="cscanning">content scanner</link> which needs a lot of
            memory - remember that it is executed within SMTP session.</para>
          </sect4>
        </sect3>

        <sect3>
          <title>SSL/TLS</title>

          <para>If you have chosen to enable SSL/TLS support in Helios qmail,
          you can also configure some of stunnel options in
          <filename>/var/qmail/smtpconfig-stunnel</filename> file.</para>
        </sect3>

        <sect3 id="smtptcprules">
          <title>TCP rules</title>

          <para>You can set rules for tcpserver using
          <filename>/var/qmail/control/smtp-tcprules</filename> file. See
          <ulink
          url="http://cr.yp.to/ucspi-tcp/tcprules.html">http://cr.yp.to/ucspi-tcp/tcprules.html</ulink>
          for more information on TCP rules and it`s usage.</para>

          <note>
            <para>Always use <command>/var/qmail/helios/qmailctl.sh
            cdb</command> to reload TCP rules after changing it.</para>
          </note>
        </sect3>
      </sect2>

      <sect2>
        <title>POP3</title>

        <para>Configuration of POP3 service is similar to SMTP configuration -
        you can do this by editing
        <filename>/var/qmail/control/pop3config</filename> and (if you have
        enabled SSL/TLS support)
        <filename>/var/qmail/control/pop3config-stunnel</filename>
        files.</para>

        <note>
          <para>Be sure to restart daemontools after changing these
          files.</para>
        </note>
      </sect2>

      <sect2>
        <title>IMAP</title>

        <para>Helios qmail supports IMAP using BINC IMAP - it is an
        independent project, so it`s configuration is beyond this document.
        For such information consult document called <ulink
        url="http://www.lifewithbincimap.org/"><citetitle>Life With BINC
        IMAP</citetitle></ulink>.</para>

        <para>However, you can configure some elements of BINC IMAP related to
        Helios qmail in similar to SMTP and POP3 configuration way, using
        <filename>/var/qmail/control/imapconfig</filename>,
        <filename>/var/qmail/control/imapconfig-stunnel</filename> and
        <filename>/var/qmail/control/imapconfig-binc,</filename> which is the
        main configuration file of BINC IMAP.</para>

        <note>
          <para>Be sure to restart daemontools after changing these
          files.</para>
        </note>
      </sect2>
    </sect1>

    <sect1 id="cscanning">
      <title>Content scanning</title>

      <para>Helios qmail has an advanced content scanner (a qmail-qfilter
      filter) which scans mail message before it is accepted for delivery. It
      delays SMTP session, but queue scanner has many advantages - eg. it
      allows you to deny mail without bouncing it (for example if it is a
      virus message). Helios qmail once has delivery time scanners, but it was
      a waste of system resources to eg. scan mail to x recipients x
      times.</para>

      <sect2>
        <title>Queue filtering</title>

        <para>You can add several queue filters (executed by qmail-qfilter) to
        <filename>/var/qmail/queue</filename> file. Consult<ulink
        url="http://untroubled.org/qmail-qfilter/"> qmail-qfilter
        documentation</ulink> for more information on writing such
        programs.</para>
      </sect2>

      <sect2 id="helios-scanner">
        <title>Helios scanner</title>

        <para>Helios qmail contains one big qmail-qfilter filter called
        <filename>helios-scanner.php</filename>. It allows you to create your
        own filtering rules (eg. matching a regexps, passing to an external
        scanner) and to define custom actions (like adding a header, denying
        mail with special error codes, eg. virus warning).</para>

        <para>Helios scanner can be configured using
        <filename>/var/qmail/control/scanner</filename> file. It`s syntax is
        quite intuitive and it is well commented - you should not have
        problems editing it. Each scanner section starts with it`s name put
        between square brackets ('[' and ']') - eg. [section], than you can
        define some options (currently only <varname>max_size</varname> which
        contains maximal size of mail message to run checks included in this
        section), checks (scanners) to execute and actions to take if scanners
        detect something. If you are defining some texts, remember that you
        only need to escape (using '\') characters that you are using as
        opening and closing char (like " and ').</para>

        <note>
          <para>Be sure to enable Helios scanner in
          <filename>/var/qmail/control/queue</filename> before trying to use
          it</para>
        </note>
      </sect2>

      <sect2>
        <title>Scanners</title>

        <para>Scanners are defined between &lt;scanners&gt; and
        &lt;/scanners&gt; tags. Each section should have defined scanners, if
        not, it is assumed that actions should be taken without checking for
        message content. However, if &lt;scanners&gt; are empty (but there are
        opening and closing tags), section is skipped. Below is the list of
        commands that can be included in scanners definitions.</para>

        <itemizedlist>
          <listitem id="match_txt">
            <para>match_txt <emphasis>txt</emphasis></para>

            <para>Searches for <emphasis>txt</emphasis> in whole
            message.</para>
          </listitem>

          <listitem>
            <para>match_txti <emphasis>txt</emphasis></para>

            <para>Case insensitive version of <link
            linkend="match_txt">match_txt</link>.</para>
          </listitem>

          <listitem>
            <para>match_regexp <emphasis>txt</emphasis></para>

            <para>Searches for a regular expression (POSIX Extended) defined
            in <emphasis>txt</emphasis> in whole message.</para>
          </listitem>

          <listitem>
            <para>match_pcre <emphasis>txt</emphasis></para>

            <para>Searches for a regular expression (Perl-Compatible) defined
            in <emphasis>txt</emphasis> in whole message. Consult <ulink
            url="http://www.php.net/manual/en/pcre.pattern.syntax.php">PHP
            documentation</ulink> for documentation of
            <emphasis>txt</emphasis>`s syntax.</para>
          </listitem>

          <listitem id="match_header_txt">
            <para>match_header_*</para>

            <para>The same as match_*, but it searches only in message
            headers.</para>
          </listitem>

          <listitem>
            <para>match_body_*</para>

            <para>The same as match_*, but it searches only in message body,
            without it`s headers.</para>
          </listitem>

          <listitem>
            <para>scan_spamc <emphasis>"/path/to/spamc"
            "spamc-options"</emphasis> and scan_spamassassin
            <emphasis>"/path/to/spamassassin"
            "spamassassin-options"</emphasis></para>

            <para>Pass the message to SpamAssassin (using spamc or
            spamassassin programs) and check if it is a spam. If is, execute
            actions.</para>

            <note>
              <para>It is recommended to use SpamAssassin in daemon mode,
              because otherwise you will have to increase SMTP memory limit
              even to about 50 megabytes (!).</para>
            </note>
          </listitem>

          <listitem>
            <para>scan_clamdscan <emphasis>"/path/to/clamdscan"
            "clamdscan-options"</emphasis> and scan_clamscan
            <emphasis>"/path/to/clamscan" "clamscan-options"</emphasis></para>

            <para>Pass the message to Clam AntiVirus (using clamdscan or
            clamscan programs) and check it for viruses. If the message is a
            virus, execute actions.</para>

            <note>
              <para>It is recommended to use Clam AntiVirus in daemon
              mode.</para>
            </note>
          </listitem>

          <listitem>
            <para>scan_bogofilter
            <emphasis>"/path/to/bogofilter"</emphasis></para>

            <para>Pass the message to Bogofilter and check if it is a
            spam.</para>
          </listitem>
        </itemizedlist>
      </sect2>

      <sect2>
        <title>Actions</title>

        <para>Actions are defined in the same way as scanners are - between
        &lt;actions&gt; and &lt;/actions&gt; tags. Here is a list of supported
        actions.</para>

        <itemizedlist>
          <listitem id="del_header">
            <para>del_header <emphasis>header-name</emphasis></para>

            <para>Deletes header which name is
            <emphasis>header-name</emphasis>.</para>
          </listitem>

          <listitem>
            <para>del_header_pcre <emphasis>header-name</emphasis></para>

            <para>Version of <link linkend="del_header">del_header</link>
            which supports Perl-compatible regular expressions in
            <emphasis>header-name</emphasis>.</para>
          </listitem>

          <listitem>
            <para>add_body_top <emphasis>txt</emphasis> and add_body_end
            <emphasis>txt</emphasis></para>

            <para>Adds <emphasis>txt</emphasis> to the beginning or end of
            message body.</para>
          </listitem>

          <listitem>
            <para>add_header <emphasis>name</emphasis>
            <emphasis>contents</emphasis></para>

            <para>Adds header "<emphasis>name</emphasis>:
            <emphasis>contents</emphasis>".</para>
          </listitem>

          <listitem>
            <para>add_header_safe <emphasis>name</emphasis>
            <emphasis>contents</emphasis> [ <emphasis>suffix</emphasis> =
            'Old' ]</para>

            <para>Like above, but if <emphasis>name</emphasis> header already
            exists, it is moved to
            <emphasis>name</emphasis>-<emphasis>suffix</emphasis>
            first.</para>
          </listitem>

          <listitem>
            <para>mod_header <emphasis>name</emphasis>
            <emphasis>content</emphasis> [ <emphasis>new-name</emphasis> =
            <emphasis>name</emphasis> ]</para>

            <para>Changes header <emphasis>content</emphasis> and
            <emphasis>name</emphasis> (if <emphasis>new-name</emphasis> is
            specified).</para>
          </listitem>

          <listitem>
            <para>add_subject <emphasis>txt</emphasis></para>

            <para>Add <emphasis>txt</emphasis> at the beginning of 'Subject'
            header.</para>
          </listitem>

          <listitem>
            <para>add_subject_end <emphasis>txt</emphasis></para>

            <para>Add <emphasis>txt</emphasis> at the end of 'Subject'
            header.</para>
          </listitem>

          <listitem>
            <para>exec_filter <emphasis>filter</emphasis></para>

            <para>Pass mail through <emphasis>filter</emphasis>
            program.</para>
          </listitem>

          <listitem>
            <para>drop</para>

            <para>Silently drops the message.</para>
          </listitem>

          <listitem>
            <para>exit_virus</para>

            <para>Exits with error code 121, which means that mail will be
            denied and following text will be displayed: "554 YOUR MESSAGE
            CONTAINS A VIRUS! (#5.6.0)".</para>
          </listitem>

          <listitem>
            <para>exit_spam</para>

            <para>Exits with error code 122, which means that mail will be
            denied and following text will be displayed: "554 we do not accept
            SPAM (#5.6.0)".</para>
          </listitem>

          <listitem>
            <para>exit_error</para>

            <para>Exits with error code 31, which means that mail will be
            denied and following text will be displayed: "554 mail server
            permanently rejected message (#5.3.0)".</para>
          </listitem>

          <listitem>
            <para>exit_temp_error</para>

            <para>Exits with error code 71, which means that mail will be
            temporarily denied and following text will be displayed: "451 mail
            server temporarily rejected message (#4.3.0)".</para>
          </listitem>

          <listitem>
            <para>exit <emphasis>error-code</emphasis></para>

            <para>Exits with <emphasis>error-code</emphasis>.</para>
          </listitem>

          <listitem>
            <para>exit_ok</para>

            <para>Immediately accepts mail for delivery (skips remaining
            scanners).</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>

    <sect1>
      <title>Spam prevention</title>

      <para>Helios qmail has support for most of modern spam prevention
      techniques - eg. RBL, SPF, content scanning, tarpitting. This section
      describes how to enable and use some of them. Also the <link
      linkend="spp">next section</link> (regarding spp plugins) and the <link
      linkend="cscanning">previous section</link> (regarding content scanning)
      contain some information about Helios qmail features that can be used to
      prevent spam.</para>

      <sect2>
        <title>RBL</title>

        <para>RBL (Realtime Blackhole List) is a system which lists IP
        addresses of hosts whose owners refuse to stop the proliferation of
        spam. Each time some host connects to your SMTP service, you can check
        whether it is listed in specified RBL list and block connection if it
        is. To enable RBL checks edit <varname>SMTPRBLS</varname> variable in
        <filename>/var/qmail/control/smtpconfig</filename> file and restart
        daemontools.</para>
      </sect2>

      <sect2 id="spf">
        <title>SPF</title>

        <para>SPF (Sender Policy Framework) is a system which protects the
        envelope return-path. It means that you can check if remote host has
        rights to send mail from specified address. See <ulink
        url="http://spf.pobox.com/">http://spf.pobox.com/</ulink> for
        details.</para>

        <para>SPF is implemented as a <link linkend="spp">spp</link> plugin,
        so you can enable it by editing
        <filename>/var/qmail/control/smtpplugins</filename> file (you do not
        need to restart anything) if you have enabled it during installation.
        Apart of that you also need to set up an environmental variable called
        <varname>SPF</varname> (either using <link linkend="smtptcprules">TCP
        rules</link> or <link linkend="smtpconffile">SMTP configure
        file</link>) to one of the following values:</para>

        <itemizedlist>
          <listitem>
            <para>0 - never do SPF lookups</para>
          </listitem>

          <listitem>
            <para>1 - reject mails when SPF resolves to fail (deny) -
            recommended setting</para>
          </listitem>

          <listitem>
            <para>2 - reject mails when SPF resolves to softfail</para>
          </listitem>

          <listitem>
            <para>3 - reject mails when SPF resolves to neutral</para>
          </listitem>

          <listitem>
            <para>4 - reject mails when SPF resolves to none</para>
          </listitem>

          <listitem>
            <para>5 - reject mails when SPF resolves to error</para>
          </listitem>

          <listitem>
            <para>6 - reject mails when SPF resolves to unknown</para>
          </listitem>
        </itemizedlist>
      </sect2>

      <sect2 id="badfiles">
        <title>badmailfrom, badrcptto and badhelo files</title>

        <para>These files allows you to deny several strings in SMTP
        commands.</para>

        <itemizedlist>
          <listitem>
            <para>/var/qmail/control/badmailfrom</para>

            <para>You can put here mail addresses that will not be accepted as
            argument of SMTP 'MAIL FROM:' command.</para>
          </listitem>

          <listitem>
            <para>/var/qmail/control/badrcptto</para>

            <para>You can put here mail addresses that will not be accepted as
            argument of SMTP 'RCPT TO:' command.</para>
          </listitem>

          <listitem>
            <para>/var/qmail/control/badhelo</para>

            <para>You can put here host names that will not be accepted as
            argument of SMTP 'HELO' and 'EHLO' commands. Note that you need to
            enable <link linkend="spp">spp plugin</link> called badhelo.php
            first.</para>
          </listitem>
        </itemizedlist>
      </sect2>

      <sect2 id="tarpit">
        <title>Tarpitting</title>

        <para>Tarpitting allows you to delay SMTP session if the message that
        remote host is currently sending to you has too many recipients. To
        turn it on, enable tarpit.php plugin in
        <filename>/var/qmail/control/smtpplugin</filename> file, set
        <varname>TARPITCOUNT</varname> variable to number of recipients after
        which tarpitting should be started and <varname>TARPITDELAY</varname>
        to number of seconds to sleep after 'RCPT TO'. You can also set
        <varname>TARPITDELAY</varname> to one the following values:</para>

        <itemizedlist>
          <listitem>
            <para>NORMAL - sleep <emphasis>(number of recipients -
            <varname>TARPITCOUNT</varname> + 1) x 2</emphasis> seconds</para>
          </listitem>

          <listitem>
            <para>MEDIUM - sleep <emphasis>(number of recipients -
            <varname>TARPITCOUNT</varname> + 1) x 5</emphasis> seconds</para>
          </listitem>

          <listitem>
            <para>HARD - sleep <emphasis>(number of recipients -
            <varname>TARPITCOUNT</varname> +
            1)<superscript>2</superscript></emphasis> seconds</para>
          </listitem>

          <listitem>
            <para>RAND - sleep for random number of seconds (between 1 and
            50)</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>

    <sect1 id="spp">
      <title>Qmail-spp plugins</title>

      <para>qmail-spp (see <ulink
      url="http://qmail-spp.sourceforge.net/">http://qmail-spp.sourceforge.net/</ulink>
      for more iformation) is a small patch for qmail which allows you to
      enhance it`s functionality using external modules (written
      independently, in any programming language) without necessity of
      recompiling it or even restarting. Helios qmail comes with it and lets
      you for easy enabling and disabling several spp plugins by editing
      <filename>/var/qmail/control/smtpplugins</filename> file. Here is a list
      of modules bundled with Helios qmail with short description. If you want
      to write your own module, see section called <link
      linkend="spp-writing">"spp plugins" in chapter 4</link>.</para>

      <itemizedlist>
        <listitem>
          <para>antispoof.php - enables address spoofing prevention. See <link
          linkend="antispoof">"Antispoof"</link> section in next chapter for
          details. Needs <varname>ANTISPOOF</varname> variable to be set to
          run.</para>
        </listitem>

        <listitem>
          <para>badhelo.php - enables support for denying bad host names in
          HELO/EHLO SMTP commands. See <link linkend="badfiles">section
          4.3</link> for details. Needs <varname>BADHELO</varname> variable to
          be set to run.</para>
        </listitem>

        <listitem>
          <para>badmailfrom.php -</para>
        </listitem>

        <listitem>
          <para>badrcptto.php -</para>
        </listitem>

        <listitem>
          <para>helodnscheck.php -</para>
        </listitem>

        <listitem>
          <para>maxbouncercpts.php - allows for setting maximal number of
          envelope recipients for a bounce message in
          <varname>MAXBOUNCERECIPIENTS</varname> variable ("" and "0" means
          <emphasis role="bold">no recipients</emphasis>). Recommended
          setting: "1".</para>
        </listitem>

        <listitem>
          <para>maxrcpts.php - allows for setting maximal number of envelope
          recipients in <varname>MAXRECIPIENTS</varname> variable ("" and "0"
          means <emphasis role="bold">no recipients</emphasis>).</para>
        </listitem>

        <listitem>
          <para>mfdnscheck.php - checks if envelope sender domain exists.
          Needs <varname>MFDNSCHECK</varname> variable to be set to run
          check.</para>
        </listitem>

        <listitem>
          <para>rcptexists.php -</para>
        </listitem>

        <listitem>
          <para>spf - enables support for SPF. See <link linkend="spf">section
          4.2</link> for details.</para>
        </listitem>

        <listitem>
          <para>tarpit.php - implements tarpitting. See <link
          linkend="tarpit">section 4.4</link> for details.</para>
        </listitem>
      </itemizedlist>
    </sect1>

    <sect1>
      <title>Miscellaneous</title>

      <para>There are also more things that can be configured. Here is a short
      list of <filename>/var/qmail/control/</filename> files that can be used
      to change these settings. For more information consult documentation of
      qmail.</para>

      <itemizedlist>
        <listitem>
          <para><filename>bouncemaxbytes</filename> - sets maximal size of a
          bounce message (in bytes) that can be sent back to the sender. If
          the message is over that limit, it is truncated.</para>
        </listitem>

        <listitem>
          <para><filename>bouncemessage</filename> - custom text of a bounce
          message</para>
        </listitem>

        <listitem>
          <para><filename>bouncesubject</filename> - custom subject of a
          bounce message</para>
        </listitem>

        <listitem>
          <para><filename>doublebouncemessage</filename> - custom text of a
          double bounce message</para>
        </listitem>

        <listitem>
          <para><filename>doublebouncesubject</filename> - custom subject of a
          double bounce message</para>
        </listitem>

        <listitem>
          <para><filename>defaultdelivery</filename> - sets default .qmail
          file</para>
        </listitem>
      </itemizedlist>
    </sect1>
  </chapter>

  <chapter id="usersmgm">
    <title>Users managment</title>

    <para>This chapter describes users managment using scripts bundled with
    Helios qmail package which are located in
    <filename>/var/qmail/helios/</filename> directory (if you have not chosen
    to change default home dir of qmail). However, it is also possible to do
    that using only SQL queries (for advanced control) or a web interface,
    which is very easy to write using Helios qmail API. If you want to write
    your own administering interface, see <link linkend="api">section 1</link>
    in the next chapter.</para>

    <note>
      <para>Be sure to run these scripts as root user or any other user which
      has permissions to read
      <filename>/var/qmail/control/qmailconfig</filename> file.</para>
    </note>

    <sect1>
      <title>Adding and deleting domains, users and aliases</title>

      <para>Helios qmail comes with simple scripts for adding and deleting
      domains, users and aliases. They are located in
      <filename>/var/qmail/helios/</filename> directory and called
      <filename>helios-(add|del)(domain|user|alias).php</filename>, eg.
      <filename>helios-adddomain.php</filename>,
      <filename>helios-deluser.php</filename>,
      <filename>helios-delalias.php</filename> and so on. Their usage is very
      intuitive, so they will not be described extensively here - simply
      execute such script with <emphasis>--help</emphasis> option to print
      short information on using it.</para>

      <note>
        <para>Always run <command>/var/qmail/helios/qmailctl.sh hup</command>
        after adding or deleting a domain to let qmail know about it.</para>
      </note>

      <para>There is only one important thing - when you are adding a domain
      (using <filename>helios-adddomain.php</filename> script) be sure that
      you will not create a loop postmaster alias - such situation can be
      caused by adding your main domain (usually this from
      <filename>/var/qmail/control/me</filename> file) without
      <emphasis>-p</emphasis> option. This will cause that a
      <emphasis>postmaster@YOUR-MAIN-DOMAIN</emphasis> alias pointing to host
      postmaster, which is set to
      <emphasis>postmaster@YOUR-MAIN-DOMAIN</emphasis> by default, will be
      created, which will lead to mail loops.</para>

      <note>
        <para>Always use <emphasis>-p</emphasis> option with
        <filename>helios-adddomain.php</filename> script when adding the
        domain of host postmaster`s email address (see <link
        linkend="host_postmaster">information on host_postmaster option</link>
        in main configuration file).</para>
      </note>
    </sect1>

    <sect1>
      <title>Changing user password</title>

      <para>You can change user password using
      <filename>/var/qmail/helios/helios-passwd.php</filename> script. Execute
      it with <emphasis>--help</emphasis> option for usage information. For
      example type <command>/var/qmail/helios/helios-passwd.php login domain
      foo</command> to set login@domain`s password to "foo". You can also type
      only <command>/var/qmail/helios/helios-passwd.php login domain</command>
      to read user`s password from the keyboard.</para>
    </sect1>

    <sect1>
      <title>Editing user`s .qmail file.</title>

      <para>To set user`s .qmail file use
      <filename>/var/qmail/helios/helios-setdotqmail.php</filename> script.
      Simply pass it`s contents on standard input (eg. using redirection of
      <command>echo</command> command output) and give login, domain and
      optional extension as script arguments. For example type <command>echo
      "./Maildir/" | /var/qmail/helios/helios-passwd.php johny domain.org
      ext</command> to set johny-ext@domain.org`s .qmail to
      "./Maildir/".</para>

      <para>If you want to delete user`s .qmail file use
      <filename>/var/qmail/helios/helios-deldotqmail.php</filename>
      script.</para>

      <note>
        <para>".qmail file" is not a file - in fact it is saved in the
        database.</para>
      </note>
    </sect1>

    <sect1 id="antispoof">
      <title>Antispoof</title>

      <para>One of the most unique features of Helios qmail is it`s support
      for prevention of e-mail addresses spoofing. It is similar to SPF, but
      it deal only with local domains, which allows for more precise
      controlling of rights to specified local e-mail address. It is basing on
      SMTP authorization and allows you to specify which SMTP user is allowed
      to mail from given e-mail address. Antispoof in conjunction with SPF
      creates a complete system for stopping envelope sender forgeries.</para>

      <para>Helios qmail comes with antispoof disabled by default, because it
      is important to know how to use it before enabling it. You can turn it
      on by editing <filename>/var/qmail/control/smtpplugins</filename> file
      (see <link linkend="spp">section 5</link> in previous chapter for
      details).</para>

      <para>You can edit each user`s list of permitted addresses by using
      <filename>/var/qmail/helios/helios-antispoofadmin.php</filename> script
      (execute it with <emphasis>--help</emphasis> option for usage
      information). You can also edit following virtual wildcard users for
      matching a wider group of users:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>[:all:]@[:all:]</emphasis> - matches any authorized
          user</para>
        </listitem>

        <listitem>
          <para><emphasis>[:all:]@domain</emphasis> - matches any user in
          specified <emphasis>domain</emphasis></para>
        </listitem>

        <listitem>
          <para><emphasis>user@[:all:]</emphasis> - matches specified
          <emphasis>user</emphasis> in any domain</para>
        </listitem>

        <listitem>
          <para><emphasis>[:none:]@[:none:]</emphasis> - matches not
          authorized user</para>
        </listitem>
      </itemizedlist>

      <para>Such list should contain e-mail addresses (one per line) which
      user can use as envelope sender address. But there are also some useful
      strings which you can use as login and/or domain name. Below are the
      lists of such special strings.</para>

      <para>List of strings which can be used as e-mail address:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>[:any:]</emphasis> - allow user to mail from any
          e-mail address</para>
        </listitem>

        <listitem>
          <para><emphasis>[:none:]</emphasis> - do not allow user to send
          mails from any e-mail address</para>
        </listitem>

        <listitem>
          <para><emphasis>[:aliases:]</emphasis> - allow user to mail from any
          of his aliases</para>
        </listitem>

        <listitem>
          <para><emphasis>[:valid user:]</emphasis> - allow user to mail from
          e-mail address of any valid user (which exists in the system)</para>
        </listitem>
      </itemizedlist>

      <para>List of strings which can be used as login:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>[:any:]</emphasis> - matches any login name</para>
        </listitem>

        <listitem>
          <para><emphasis>[:none:]</emphasis> - disallows mailing from any
          login in specified domain, eg. <emphasis>[:none:]@foo.com</emphasis>
          disallows user to mail from <emphasis>*@foo.com</emphasis></para>
        </listitem>

        <listitem>
          <para><emphasis>[:login:]</emphasis> - matches login of authorized
          user, eg. <emphasis>[:login:]@foo.com</emphasis> in
          <emphasis>joe@domain.org</emphasis>`s list allows him to mail from
          <emphasis>joe@foo.com</emphasis>. Useful with wildcards.</para>
        </listitem>

        <listitem>
          <para><emphasis>[:my users:]</emphasis> - matches any valid login
          name (which exists in the system)</para>
        </listitem>
      </itemizedlist>

      <para>List of strings which can be used as domain name:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>[:any:]</emphasis> - matches any domain name</para>
        </listitem>

        <listitem>
          <para><emphasis>[:none:]</emphasis> - disallows mailing from
          specified login at any domain, eg.
          <emphasis>admin@[:none:]</emphasis> disallows user to mail from
          <emphasis>admin@*</emphasis></para>
        </listitem>

        <listitem>
          <para><emphasis>[:domain:]</emphasis> - matches domain name of
          authorized user, eg. <emphasis>webmaster@[:domain:]</emphasis> in
          <emphasis>tom@domain.org</emphasis>`s list allows him to mail from
          <emphasis>webmaster@domain.org</emphasis>. Useful with
          wildcards.</para>
        </listitem>

        <listitem>
          <para><emphasis>[:my domains:]</emphasis> - matches any valid domain
          name (which exists in the system)</para>
        </listitem>
      </itemizedlist>

      <para>You can also use exclamation mark as first character to negate
      matching, eg. "<emphasis>! [:any:]@[:my domains:]</emphasis>" allows
      mailing from any foreign address.</para>

      <para>Helios qmail comes with following antispoof settings by
      default:</para>

      <table>
        <title>Default settings of antispoof</title>

        <tgroup cols="3">
          <tbody>
            <row>
              <entry>User</entry>

              <entry>Permissions list</entry>

              <entry>Explanation</entry>
            </row>

            <row>
              <entry>[:none:]@[:none:]</entry>

              <entry>! [:any:]@[:my domains:]</entry>

              <entry>This setting is required to allow remote hosts (which do
              not authorize on your server) to send mail to you (from foreign
              addresses).</entry>
            </row>

            <row>
              <entry>[:any:]@[:any:]</entry>

              <entry>[:login:]@[:domain:]</entry>

              <entry>Allows any authorized user to use his mail
              address.</entry>
            </row>

            <row>
              <entry></entry>

              <entry>[:aliases:]</entry>

              <entry>Allows any authorized user to use his aliases as envelope
              sender address.</entry>
            </row>

            <row>
              <entry></entry>

              <entry>! [:any:]@[:my domains:]</entry>

              <entry>Allows any authorized user to mail from any foreign
              address.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>If the user is not allowed to mail from given e-mail address (but
      he tries to do this), and he is not authorized, he gets "530
      authentication required (#4.7.1)" error, but if he has already
      authorized, he gets "550 permission denied (#5.7.0)" error. All such
      tries are logged.</para>
    </sect1>

    <sect1>
      <title>New mail notification</title>

      <para>Helios qmail supports notifying about new mails through <ulink
      url="http://www.jabber.org/">Jabber</ulink> protocol. This allows you to
      send notifications to your mobile phone, other instant messaging
      communicators, etc. using Jabber transports, so it can be really useful
      (for example when you are waiting for an important e-mail).</para>

      <para>New mail notification works as follows: when new mail arrives, it
      is passed to <filename>/var/qmail/helios/helios-notify.php</filename>
      script (see default .qmail file in
      <filename>/var/qmail/control/defaultdelivery</filename>). Then, it reads
      the message and creates a notify message containing some information
      about mail, like sender, subject and beginning of text of the message.
      Next, it logs on a Jabber server using user`s JID and password (there is
      no system-wide account for sending Jabber notifications) and sends
      notify message to the given Jabber address (called "send-to").</para>

      <para>To set up a new mail notification for specified user (or a group
      of users - wildcard string "[:all:]" can be used as login and/or domain
      name) use <filename>/var/qmail/helios/helios-notifyadmin.php</filename>
      script (execute it with <emphasis>--help</emphasis> option for usage
      information).</para>
    </sect1>

    <sect1>
      <title>Getting user information</title>

      <para>There are two scripts for getting information about users in your
      Helios qmail system. It`s usage is trivial, so they will not be
      described much here. For more information, execute them with
      <emphasis>--help</emphasis> option.</para>

      <itemizedlist>
        <listitem>
          <para><filename>/var/qmail/helios/helios-finger.php</filename> -
          shows complete information about given user(s)</para>
        </listitem>

        <listitem>
          <para><filename>/var/qmail/helios/helios-listdomain.php</filename> -
          shows all users in given domain</para>
        </listitem>
      </itemizedlist>
    </sect1>
  </chapter>

  <chapter id="extending">
    <title>Extending Helios qmail</title>

    <para>This chapter contains only some notes on extending Helios qmail,
    please do not treat it as a "HOW-TO".</para>

    <sect1 id="api">
      <title>Helios qmail API</title>

      <para>If you want to use Helios qmail API you should be an experienced
      PHP programmer. There is no extensive documentation of it, because it is
      no problem for such person to look at the source code and just use it.
      However, such documentation may be written some day, but now there are
      only few notes about it.</para>

      <para>First of all, main Helios qmail API consist of four libraries:
      low-level - QmailSql.php and QmailSqlUser.php and high-level -
      QmailHelios.php and QmailHeliosUser.php. It can also be divided in
      another way: system-oriented - QmailSql.php and QmailHelios.php and
      user-oriented - QmailSqlUser.php and QmailHeliosUser.php. All libraries
      are located in <filename>/var/qmail/helios/lib</filename>
      directory.</para>

      <note>
        <para>QmailSql.php and QmailSqlUser.php are 100% compatible with stock
        qmail-sql, so you can use them for writing tools for it.</para>
      </note>

      <para>If you will have problems with using the API look at the
      <filename>/var/qmail/helios/helios-*.php</filename> scripts and
      user-oriented classes - they are all like a one big example.</para>
    </sect1>

    <sect1 id="spp-writing">
      <title>Qmail-spp plugins</title>

      <para>Please take a look at <ulink
      url="http://qmail-spp.sourceforge.net/">qmail-spp documentation</ulink>
      for more information.</para>
    </sect1>
  </chapter>
</book>