This code was created by Andrew McNamara <andrew@connect.com.au>
and adapted to snapshot 20001121 by Xavier Beaudouin. It was merged
with mainstream Postfix for snapshot 20010128 by Wietse.

Purpose of this software
========================

You can use the virtual delivery agent for mailbox delivery of some
or all domains that are handled by a machine.

This mechanism is different from simulated virtual domains. Those
are implemented by translating every recipient address into a
different address. For that, see the virtual(5) manual page.

With the virtual delivery agent, every recipient adress can have
its own mailbox. There is no translation from recipient addresses
into different addresses.

This is what Andrew McNamara wrote when he made the virtual delivery
agent available.

"This code is designed for ISP's who offer virtual mail hosting.
It looks up the user mailbox location, uid and gid via separate
maps, and the mailbox location map can specify either mailbox or
maildir delivery (controlled by trailing slash on mailbox name).

The agent allows but ignores user+foo address extensions, does not
support aliases or .forward files (use the virtual table instead),
and therefore doesn't support file or program aliases. This choice
was made to simplify and streamline the code (it allowed me to
dispense with 70% of local's code - mostly the bits that are a
security headache) - if you need this functionality, this agent
isn't for you.

It also doesn't support writing to a common spool as root and then
chowning the mailbox to the user - I felt this functionality didn't
fit with my overall aims."

[End of Andrew McNamara's words]

The result is the most secure local delivery agent that you will
find with Postfix.

This delivery agent requires three different lookup tables in order
to define its recipients as (mailbox path, user ID, group ID). This
is because Postfix table lookups can't return multiple results.

If your virtual mailboxes are all owned by the same user/group ID,
just specify "static" maps that always return the same result. See
below for examples.

If your virtual mailboxes must be owned by different user/group
IDs, and if it is too inconvenient for you to maintain three parallel
tables, use an LDAP or MYSQL database (or generate the three parallel
tables from one common template).

Configuration parameters
========================

virtual_mailbox_base

    Specifies a path that is prepended to all mailbox paths. This
    is a safety measure to ensure an that out of control map doesn't
    litter the filesystem with mailboxes (or worse). While it could
    be set to "/", this isn't recommended.

virtual_mailbox_domains

    Specifies the list of domains that should be delivered to the
    $virtual_transport delivery agent (default: virtual). As of
    version 2.0, Postfix is smart enough that you don't have to
    list every virtual domain in a Postfix transport map.

virtual_mailbox_maps

    Recipients are looked up in this map to determine the path to
    their mailbox. If the returned path ends in a slash ("/"),
    maildir-style delivery is carried out, otherwise the path is
    assumed to specify a mailbox file. The virtual_mailbox_base
    directory is unconditionally prepended to this path. If the
    recipient is not found the mail is bounced.

    In a lookup table, specify a left-hand side of @domain.tld to
    match any user in the specified domain that does not have her
    own user@domain.tld entry. While searching a lookup table, an
    address extension (user+foo@domain.tld) is ignored.

    If a recipient is not found the mail is returned to the sender.

    Regular expression maps are allowed. For security reasons,
    regular expression substitution of $1 etc. is disallowed,
    because that would open a security hole.

    The mail administrator is expected to create and chown recipient
    mailbox files or maildir directories ahead of time.

virtual_minimum_uid

    Specifies a minimum uid that will be accepted as a return from
    a virtual_uid_maps lookup. Returned values less than this will
    be rejected, and the message will be deferred.

virtual_uid_maps

    Recipients are looked up in this map to determine the UID (owner
    privileges) to be used when writing to the target mailbox.

    In a lookup table, specify a left-hand side of @domain.tld to
    match any user in the specified domain that does not have a
    specific user@domain.tld entry. While searching a lookup table,
    an address extension (user+foo@domain.tld) is ignored.

    Regular expression maps are allowed. For security reasons,
    regular expression substitution of $1 etc. is disallowed,
    because that would open a security hole.

    Specify a static map if all mailboxes should be owned by the same
    UID. For example, to specify that all mailboxes are owned by the
    UID 5000, specify:

	virtual_uid_maps = static:5000

virtual_gid_maps

    Recipients are looked up in this map to determine the GID (group
    privileges) to be used when writing to the target mailbox.

    In a lookup table, specify a left-hand side of @domain.tld to
    match any user in the specified domain that does not have a
    specific user@domain.tld entry. While searching a lookup table,
    an address extension (user+foo@domain.tld) is ignored.

    Regular expression maps are allowed. For security reasons,
    regular expression substitution of $1 etc. is disallowed,
    because that would open a security hole.

    Specify a static map if all mailboxes should be owned by the same
    GID. For example, to specify that all mailboxes are owned by the
    GID 5000, specify:

	virtual_gid_maps = static:5000

virtual_mailbox_lock

    This setting is ignored in case of maildir delivery.

    Locking method to use when updating a mailbox. Defaults to
    fcntl or flock depending on the system. Depending on the POP
    or IMAP server you may have to specify dotlock locking, which
    requires that the recipient UID or GID has write access to the
    parent directory of the mailbox file.

    Use the "postconf -l" command to find out what locking methods
    Postfix supports on your system.

virtual_mailbox_limit

    An upper limit on the size of a mailbox file or maildir file.

Example 1: using the virtual delivery agent for all local mail
==============================================================

This example does not use the Postfix local delivery agent at all.
With this configuration Postfix does no alias expansion, no .forward
file expansion, no lookups of recipients in /etc/passwd, and allows
but ignores user+foo address extensions.

Instead of "hash" specify "dbm" or "btree", depending on your system
type.  The command "postconf -m" displays possible lookup table
types.

    /etc/postfix/main.cf:
	# Don't send mail to the local delivery agent.
	mydestination =

	# All domains that are listed in $virtual_mailbox_domains
	# are delivered via $virtual_transport, which is the virtual
	# delivery agent by default.
	virtual_mailbox_domains = 
	    $myhostname localhost.$mydomain virtual1.domain virtual2.domain

	virtual_transport = virtual
	virtual_mailbox_base = /var/mail/vhosts
	virtual_mailbox_maps = hash:/etc/postfix/vmailbox
	virtual_minimum_uid = 100
	virtual_uid_maps = hash:/etc/postfix/vuid
	virtual_gid_maps = hash:/etc/postfix/vgid

Define a virtual delivery agent if the entry doesn't already exist:

    /etc/postfix/master.cf:
	virtual     unix  -       n       n       -       -       virtual

Example recipients, one UNIX-style mailbox, one qmail-style maildir:

    /etc/postfix/vmailbox:
	test1@virtual1.domain test1
	test2@virtual2.domain test2/

    /etc/postfix/vuid:
	test1@virtual1.domain 5001
	test2@virtual2.domain 5002

    /etc/postfix/vgid:
	test1@virtual1.domain 5001
	test2@virtual2.domain 5002

Execute something like the following commands for each mailbox recipient:

    # touch /var/mail/vhosts/test1
    # chown 5001:5001 /var/mail/vhosts/test1

Execute something like the following commands for each maildir recipient:

    # mkdir /var/mail/vhosts/test2
    # chown 5002:5002 /var/mail/vhosts/test2

Be sure to make the necessary entries for root@$myhostname,
postmaster@$myhostname and for any other necessary addresses.

Example 2: co-existing with the default local delivery agent
============================================================

In this example, the default Postfix local delivery agent handles
the mail for non-virtual recipients; the virtual delivery agent
handles virtual recipients, and all virtual mailboxes are owned
by user ID 5000, group ID 5000.

Instead of "hash" specify "dbm" or "btree", depending on your system
type.  The command "postconf -m" displays possible lookup table
types.

    /etc/postfix/main.cf:
	# All domains and users delivered by the virtual local delivery agent.

	virtual_transport = virtual
	virtual_mailbox_base = /var/mail/vhosts
	virtual_mailbox_maps = hash:/etc/postfix/vmailbox
	virtual_mailbox_domains = $virtual_mailbox_maps
	virtual_minimum_uid = 100
	virtual_uid_maps = static:5000
	virtual_gid_maps = static:5000

	# All domains and users delivered by the local delivery agent.
	# local_recipient_maps is used by the SMTP server to reject mail
	# for unknown users.

	local_transport = local
	mydestination = $myhostname $localhost.$mydomain
	local_recipient_maps = unix:passwd.byname $alias_maps

Define a virtual delivery agent if the entry doesn't already exist:

    /etc/postfix/master.cf:
	virtual     unix  -       n       n       -       -       virtual

Example recipients, one UNIX-style mailbox, one qmail-style maildir:

    /etc/postfix/vmailbox:
	test1@virtual1.domain test1
	test2@virtual2.domain test2/

    /etc/postfix/vmaildomains:
	virtual1.domain		required to prevent relay access denied errors
	virtual2.domain		required to prevent relay access denied errors

Execute something like the following commands for each mailbox recipient:

    # touch /var/mail/vhosts/test1
    # chown 5000:5000 /var/mail/vhosts/test1

Execute something like the following commands for each maildir recipient:

    # mkdir /var/mail/vhosts/test2
    # chown 5000:5000 /var/mail/vhosts/test2

Remember that each domain is required to have a postmaster contact
address.

Example 3: hosting many virtual users
=====================================

Example 2 is fine if you host only a few virtual users.  With many
users you will want to separate the information that changes often
(the user addresses) from the information that changes rarely (the
names of hosted domains).

This example is the same as above, with co-existing local and
virtual domains, but it uses a separate table for specifying the
virtual domain names.

    /etc/postfix/main.cf:
	# All domains and users delivered by the virtual local delivery agent.

	virtual_transport = virtual
	virtual_mailbox_base = /var/mail/vhosts
	virtual_mailbox_maps = hash:/etc/postfix/vmailbox
	virtual_mailbox_domains = hash:/etc/postfix/vmaildomains
	virtual_minimum_uid = 100
	virtual_uid_maps = static:5000
	virtual_gid_maps = static:5000

	# All domains and users delivered by the local delivery agent.
	# local_recipient_maps is used by the SMTP server to reject mail
	# for unknown users.

	local_transport = local
	mydestination = $myhostname $localhost.$mydomain
	local_recipient_maps = unix:passwd.byname $alias_maps

Define a virtual delivery agent if the entry doesn't already exist:

    /etc/postfix/master.cf:
	virtual     unix  -       n       n       -       -       virtual

Example recipients, one UNIX-style mailbox, one qmail-style maildir:

    /etc/postfix/vmailbox:
	test1@virtual1.domain test1
	test2@virtual2.domain test2/

    /etc/postfix/vmaildomains:
	virtual1.domain		required to prevent relay access denied errors
	virtual2.domain		required to prevent relay access denied errors

Execute something like the following commands for each mailbox recipient:

    # touch /var/mail/vhosts/test1
    # chown 5000:5000 /var/mail/vhosts/test1

Execute something like the following commands for each maildir recipient:

    # mkdir /var/mail/vhosts/test2
    # chown 5000:5000 /var/mail/vhosts/test2

Remember that each domain is required to have a postmaster contact
address.

Example 4: forwarding mail for an old account to a new address
==============================================================

In order to forward mail for a user who no longer exists, one would
set up a rule in a virtual table (please ignore the text in the
virtual configuration file about virtual domains):

    /etc/postfix/main.cf:
	virtual_maps = hash:/etc/postfix/virtual

    /etc/postfix/virtual:
	old_user@old.domain	new_user@new.domain

Example 5: setting up a virtual vacation autoresponder
======================================================

In order to set up an autoreply for virtual recipients while still
delivering mail as normal, set up a rule in a virtual table (please
ignore the text in the virtual configuration file about virtual
domains):

    /etc/postfix/main.cf:
        virtual_maps = hash:/etc/postfix/virtual

    /etc/postfix/virtual:
        user@domain.tld	user@domain.tld, user@autoreply.domain.tld

This delivers mail to the recipient, and sends a copy of the mail
to the address that produces automatic replies. The address can be
serviced on a different machine, or it can be serviced locally by
setting up a transport map entry that pipes all mail for the
autoreply.domain.tld into some script that sends an automatic
reply back to the sender.
