]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20001221
authorWietse Venema <wietse@porcupine.org>
Thu, 21 Dec 2000 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:03 +0000 (06:27 +0000)
30 files changed:
postfix/FILTER_README
postfix/HISTORY
postfix/Makefile.in
postfix/VIRTUAL_README [new file with mode: 0644]
postfix/html/Makefile.in
postfix/html/virtual.8.html [new file with mode: 0644]
postfix/man/Makefile.in
postfix/man/man8/virtual.8 [new file with mode: 0644]
postfix/src/global/mail_conf.h
postfix/src/global/mail_conf_raw.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/local/local.c
postfix/src/master/multi_server.c
postfix/src/master/single_server.c
postfix/src/master/trigger_server.c
postfix/src/postconf/Makefile.in
postfix/src/postconf/extract.awk
postfix/src/postconf/postconf.c
postfix/src/util/Makefile.in
postfix/src/util/dict_mysql.c
postfix/src/virtual/.indent.pro [new symlink]
postfix/src/virtual/Makefile.in [new file with mode: 0644]
postfix/src/virtual/deliver_attr.c [new file with mode: 0644]
postfix/src/virtual/mailbox.c [new file with mode: 0644]
postfix/src/virtual/maildir.c [new file with mode: 0644]
postfix/src/virtual/recipient.c [new file with mode: 0644]
postfix/src/virtual/unknown.c [new file with mode: 0644]
postfix/src/virtual/virtual.c [new file with mode: 0644]
postfix/src/virtual/virtual.h [new file with mode: 0644]

index 7c1ebfc61c5157678b5b34b281b10f0cdf57a6c5..6823d0be7e26a7adbe4848c670d11e53fd0eb5f2 100644 (file)
@@ -60,11 +60,12 @@ The filter program can start out as a simple shell script like this:
     # Exit codes from <sysexits.h>
     EX_TEMPFAIL=75
     EX_UNAVAILABLE=69
+    STATUS=$EX_TEMPFAIL
 
     cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
 
     # Clean up when done or when aborting.
-    trap "rm -f in.$$; exit" 0 1 2 3 15
+    trap "rm -f in.$$; exit $STATUS" 0 1 2 3 15
 
     cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
 
@@ -72,7 +73,7 @@ The filter program can start out as a simple shell script like this:
 
     $SENDMAIL "$@" <in.$$
 
-    exit $?
+    STATUS=$?
 
 The idea is to first capture the message to file and then run the
 content through run a third-party content filter program.  If the
index 77218e7cefaa782dbd2e2051edf06a4d9f7bf547..2cf223746e56884efcba1f9915dba66939a9d77b 100644 (file)
@@ -4664,3 +4664,10 @@ Apologies for any names omitted.
        Bugfix: reorganized some code in the MYSQL client to end
        a number of memory allocation/deallocation problems.
        This code needs more work. File: dict_mysql.c.
+
+20001218
+
+       Bugfix: the MYSQL client did not provide function pointers
+       for unimplemented operations, causing "postmap -d" to dump
+       core instead if issuing an error message. This is what I
+       get for accepting code that I cannot test myself.
index 2603ce0d0a55e05904624759b27220a8961b63b0..edbf1a070e1dc0ed2a31254db540eb3d2fdc3148 100644 (file)
@@ -6,7 +6,7 @@ DIRS    = src/util src/global src/dns src/master src/postfix src/smtpstone \
        src/lmtp src/trivial-rewrite src/qmgr src/smtp src/bounce src/pipe \
        src/showq src/postalias src/postcat src/postconf src/postdrop \
        src/postkick src/postlock src/postlog src/postmap src/postsuper \
-       src/nqmgr src/spawn src/flush # src/base64 proto man html
+       src/nqmgr src/spawn src/flush src/virtual # src/base64 proto man html
 
 default: update
 
diff --git a/postfix/VIRTUAL_README b/postfix/VIRTUAL_README
new file mode 100644 (file)
index 0000000..2553125
--- /dev/null
@@ -0,0 +1,154 @@
+[Code contribued by Andrew McNamara ]
+
+Code created by Andrew McNamara <andrew@connect.com.au> and adapted to
+snapshot 20001121 by Xavier Beaudouin.
+
+Code is maintened now by Xavier Beaudouin <kiwi@oav.net>
+
+[Original Message]
+I've run out of time to fiddle further at the moment, so I've decided to
+post my virtual local delivery agent. Note that this is still a work in
+progress, so don't bet your business on it.
+
+I'll repeat what I said last time:
+
+   This code is designed for ISP's who offer virtual mail hosting.  It
+   looks up the location, uid and gid of user mailboxes via separate maps,
+   and the mailbox location map can specify either mailbox or maildir
+   delivery (controlled by trailing slash on mailbox name).
+
+   The agent does not support aliases or .forwards (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.
+
+Some other notes:
+
+- It's still called "virtual" - I had some concerns that this would
+  confuse people, but I'll leave that call up to Wietse - if he wants
+  to integrate it, he can specify the name.
+
+- I've retained the three separate map lookups at this time. When
+  postfix supports maps that return multiple values, we can consider
+  changing it then.
+
+- Specify "virtual:" as the target in the transport table for domains
+  for which you want this agent used.
+
+- The attached file is a gzipped tar that should be unpacked in the
+  base postfix directory (where the INSTALL and HISTORY files live) -
+  it adds a "virtual" subdirectory, and a "virtual.patch" file. The
+  patch updates the top level Makefile.in to build the new agent, and
+  global/mail_params.h to add the new config parameters.
+
+New config options are:
+
+virtual_mailbox_base
+
+    Specifies a path that is prepended to all mailbox paths. This is
+    a safety measure to ensure an 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_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. Note that virtual_mailbox_base is unconditionally
+    prepended to this path.
+
+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 to be
+    used when writing to the target mailbox.
+
+virtual_gid_maps
+
+    Recipients are looked up in this map to determine the GID to be
+    used when writing to the target mailbox.
+
+virtual_usedotlock
+
+    Use dot-locking when writing to mailboxes - defaults to off.
+
+[ - Exemple configuration - ]
+
+In main.cf file :
+--/---
+ virtual_mailbox_base = /var/mail/vhosts
+ virtual_mailbox_maps = dbm:/etc/postfix/vmailbox
+ virtual_minimum_uid = 100
+ virtual_uid_maps = dbm:/etc/postfix/vuid
+ virtual_gid_maps = dbm:/etc/postfix/vgid
+ virtual_usedotlock = no
+--/---
+
+In vmailbox file :
+
+--/---
+testuser@fakedom.com testuser/
+--/---
+
+In vuid file :
+
+--/---
+testuser@fakedom.com 5000
+--/---
+
+In vgid file :
+
+--/---
+testuser@fakedom.com 5000
+--/---
+
+Don't forget to add in master.cf the entry for the agent, that should be
+like :
+
+--/---
+virtual     unix  -       n       n       -       -       virtual
+--/---
+
+NOTES :
+-------
+
+1- Don't forget to add dbm:/etc/posfix/vmailbox into your 
+local_recipent_maps in main.cf like :
+
+--/---
+local_recipient_maps = $alias_maps dbm:/etc/posfix/vmailbox unix:passwd.byname
+--/---
+
+2- If you use only the virtual localdelivery you can add the following line
+into main.cf
+
+--/---
+mailbox_transport = virtual
+--/---
+
+Otherwise you can use transport_maps :
+
+In main.cf file :
+
+--/---
+transport_maps=dbm:/etc/postfix/transport
+--/---
+
+In transport file :
+
+--/---
+fakedom.com    virtual:
+--/---
+
+
index 8a342e1fc09bf57990f7a85554f42971aaa09edf..c15b21a1f2a97e681f25eb4d13dbf75c81cf8f91 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        =  bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
        lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
        showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html \
-       nqmgr.8.html spawn.8.html flush.8.html
+       nqmgr.8.html spawn.8.html flush.8.html virtual.8.html
 COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
        postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
        postlog.1.html postdrop.1.html postmap.1.html sendmail.1.html \
@@ -81,6 +81,9 @@ smtpd.8.html: ../src/smtpd/smtpd.c
 trivial-rewrite.8.html: ../src/trivial-rewrite/trivial-rewrite.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
+virtual.8.html: ../src/virtual/virtual.c
+       srctoman $? | nroff -man | man2html | postlink >$@
+
 postalias.1.html: ../src/postalias/postalias.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
diff --git a/postfix/html/virtual.8.html b/postfix/html/virtual.8.html
new file mode 100644 (file)
index 0000000..4babb8c
--- /dev/null
@@ -0,0 +1,200 @@
+<html> <head> </head> <body> <pre>
+
+
+
+VIRTUAL(8)                                             VIRTUAL(8)
+
+
+<b>NAME</b>
+       virtual - Postfix virtual mail delivery
+
+<b>SYNOPSIS</b>
+       <b>virtual</b> [generic Postfix daemon options]
+
+<b>DESCRIPTION</b>
+       The  <b>virtual</b>  daemon  processes delivery requests from the
+       Postfix queue manager to deliver  mail  to  virtual  local
+       recipients.  Each delivery request specifies a queue file,
+       a sender address, a domain or host to deliver to, and  one
+       or  more  recipients.  This program expects to be run from
+       the <a href="master.8.html"><b>master</b>(8)</a> process manager.
+
+       This daemon is designed for ISP's  offering  virtual  mail
+       hosting  services.  Originally based on the local delivery
+       agent, this agent locates user mailboxes via  map  lookups
+       of the full recipient address, rather than hard-coded unix
+       password file searches of the local part only.
+
+       The <b>virtual</b> daemon updates queue files and  marks  recipi-
+       ents  as  finished,  or  it informs the queue manager that
+       delivery should be tried again at a later  time.  Delivery
+       problem reports are sent to the <a href="bounce.8.html"><b>bounce</b>(8)</a> or <a href="defer.8.html"><b>defer</b>(8)</a> dae-
+       mon as appropriate.
+
+<b>MAILBOX</b> <b>DELIVERY</b>
+       The default per-user mailbox is a file in  the  UNIX  mail
+       spool  directory (<b>/var/mail/</b><i>user</i> or <b>/var/spool/mail/</b><i>user</i>);
+       the location can be specified with  the  <b>mail</b><i>_</i><b>spool</b><i>_</i><b>direc-</b>
+       <b>tory</b> configuration parameter.
+
+       In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
+       mon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope header to
+       each  message,  prepends  a  <b>Delivered-To:</b> header with the
+       envelope recipient address, prepends a <b>Return-Path:</b> header
+       with  the  envelope sender address, prepends a &gt; character
+       to lines beginning with "<b>From</b>  ",  and  appends  an  empty
+       line.   The  mailbox  is locked for exclusive access while
+       delivery is in progress. In case of problems,  an  attempt
+       is made to truncate the mailbox to its original length.
+
+       In the case of <b>maildir</b> delivery, the local daemon prepends
+       a <b>Delivered-To:</b> header with the envelope recipient address
+       and  prepends  a  <b>Return-Path:</b>  header  with  the envelope
+       sender address.
+
+<b>DELIVERY</b> <b>RIGHTS</b>
+       Deliveries to mailboxes are made with the  rights  of  the
+       receiving user on whose behalf the delivery is made.
+
+<b>STANDARDS</b>
+       <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
+
+
+
+
+                                                                1
+
+
+
+
+
+VIRTUAL(8)                                             VIRTUAL(8)
+
+
+<b>DIAGNOSTICS</b>
+       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
+       rupted message files are marked so that the queue  manager
+       can move them to the <b>corrupt</b> queue afterwards.
+
+       Depending  on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
+       the postmaster is notified of bounces and of  other  trou-
+       ble.
+
+<b>CONFIGURATION</b> <b>PARAMETERS</b>
+       The  following  <b>main.cf</b> parameters are especially relevant
+       to this program. See the Postfix <b>main.cf</b> file  for  syntax
+       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
+       command after a configuration change.
+
+<b>Mailbox</b> <b>delivery</b>
+       <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b>
+              Specifies a path that is prepended to  all  mailbox
+              paths. This is a safety measure to ensure an out of
+              control map  doesn't  litter  the  filesystem  with
+              mailboxes. While it could be set to "/", this isn't
+              recommended.
+
+       <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>maps</b>
+              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 spec-
+              ify a mailbox file. Note that  <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b>
+              is unconditionally prepended to this path.
+
+       <b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b>
+              Specifies  a minimum uid that will be accepted as a
+              return from  a  <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>  lookup.  Returned
+              values  less  than  this  will be rejected, and the
+              message will be deferred.
+
+       <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>
+              Recipients are looked up in this map  to  determine
+              the UID to be used when writing to the target mail-
+              box.
+
+       <b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b>
+              Recipients are looked up in this map  to  determine
+              the GID to be used when writing to the target mail-
+              box.
+
+<b>Locking</b> <b>controls</b>
+       <b>mailbox</b><i>_</i><b>delivery</b><i>_</i><b>lock</b>
+              How to lock UNIX-style mailboxes: one  or  more  of
+              <b>flock</b>, <b>fcntl</b> or <b>dotlock</b>.
+
+       <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
+              Limit   the   number  of  attempts  to  acquire  an
+
+
+
+                                                                2
+
+
+
+
+
+VIRTUAL(8)                                             VIRTUAL(8)
+
+
+              exclusive lock on a mailbox file.
+
+       <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
+              Time in  seconds  between  successive  attempts  to
+              acquire an exclusive lock on a mailbox file.
+
+       <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
+              Limit  the  time  after  which  a stale lockfile is
+              removed.
+
+<b>Resource</b> <b>controls</b>
+       <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+              Limit the number of parallel deliveries to the same
+              domain.   The  default  limit  is  taken  from  the
+              <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
+
+       <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+              Limit the number of recipients per  message  deliv-
+              ery.    The   default   limit  is  taken  from  the
+              <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+
+<b>HISTORY</b>
+       This agent was originally  based  on  the  local  delivery
+       agent.  Modifications  mainly  consisted  of removing code
+       that wasn't applicable or  wasn't  safe  in  this  context
+       (aliases, .forwards, program aliases).
+
+       The  <b>Delivered-To:</b>  header  appears in the <b>qmail</b> system by
+       Daniel Bernstein.
+
+       The <i>maildir</i> structure  appears  in  the  <b>qmail</b>  system  by
+       Daniel Bernstein.
+
+<b>SEE</b> <b>ALSO</b>
+       <a href="bounce.8.html">bounce(8)</a> non-delivery status reports
+       syslogd(8) system logging
+       <a href="qmgr.8.html">qmgr(8)</a> queue manager
+
+<b>LICENSE</b>
+       The  Secure  Mailer  license must be distributed with this
+       software.
+
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       IBM T.J. Watson Research
+       P.O. Box 704
+       Yorktown Heights, NY 10598, USA
+
+       Andrew McNamara
+       andrewm@connect.com.au
+       connect.com.au Pty. Ltd.
+       Level 3, 213 Miller St
+       North Sydney 2060, NSW, Australia
+
+
+
+
+                                                                3
+
+
+</pre> </body> </html>
index 8e258047de1645f1487b15e8d2585d71405dbd0c..8ea0fe0fd76d8713d294da761e25d88423c35f2b 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
        man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
        man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 \
-       man8/nqmgr.8 man8/spawn.8 man8/flush.8
+       man8/nqmgr.8 man8/spawn.8 man8/flush.8 man8/virtual.8
 COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
        man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
        man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
@@ -80,6 +80,9 @@ man8/smtpd.8: ../src/smtpd/smtpd.c
 man8/trivial-rewrite.8: ../src/trivial-rewrite/trivial-rewrite.c
        ../mantools/srctoman $? >$@
 
+man8/virtual.8: ../src/virtual/virtual.c
+       ../mantools/srctoman $? >$@
+
 man1/postalias.1: ../src/postalias/postalias.c
        ../mantools/srctoman $? >$@
 
diff --git a/postfix/man/man8/virtual.8 b/postfix/man/man8/virtual.8
new file mode 100644 (file)
index 0000000..42ab48e
--- /dev/null
@@ -0,0 +1,174 @@
+.TH VIRTUAL 8 
+.ad
+.fi
+.SH NAME
+virtual
+\-
+Postfix virtual mail delivery
+.SH SYNOPSIS
+.na
+.nf
+\fBvirtual\fR [generic Postfix daemon options]
+.SH DESCRIPTION
+.ad
+.fi
+The \fBvirtual\fR daemon processes delivery requests from the
+Postfix queue manager to deliver mail to virtual local recipients.
+Each delivery request specifies a queue file, a sender address,
+a domain or host to deliver to, and one or more recipients.
+This program expects to be run from the \fBmaster\fR(8) process
+manager.
+
+This daemon is designed for ISP's offering virtual mail hosting
+services. Originally based on the local delivery agent, this agent
+locates user mailboxes via map lookups of the full recipient
+address, rather than hard-coded unix password file searches of
+the local part only.
+
+The \fBvirtual\fR daemon updates queue files and marks recipients
+as finished, or it informs the queue manager that delivery should
+be tried again at a later time. Delivery problem reports are sent
+to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
+.SH MAILBOX DELIVERY
+.na
+.nf
+.ad
+.fi
+The default per-user mailbox is a file in the UNIX mail spool
+directory (\fB/var/mail/\fIuser\fR or \fB/var/spool/mail/\fIuser\fR);
+the location can be specified with the \fBmail_spool_directory\fR
+configuration parameter.
+
+In the case of UNIX-style mailbox delivery,
+the \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR"
+envelope header to each message, prepends a \fBDelivered-To:\fR header
+with the envelope recipient address, prepends a \fBReturn-Path:\fR
+header with the envelope sender address, prepends a \fB>\fR character
+to lines beginning with "\fBFrom \fR", and appends an empty line.
+The mailbox is locked for exclusive access while delivery is in
+progress. In case of problems, an attempt is made to truncate the
+mailbox to its original length.
+
+In the case of \fBmaildir\fR delivery, the local daemon prepends
+a \fBDelivered-To:\fR header with the envelope recipient address
+and prepends a \fBReturn-Path:\fR header with the envelope sender
+address.
+.SH DELIVERY RIGHTS
+.na
+.nf
+.ad
+.fi
+Deliveries to mailboxes are made with the rights of the receiving
+user on whose behalf the delivery is made.
+.SH STANDARDS
+.na
+.nf
+RFC 822 (ARPA Internet Text Messages)
+.SH DIAGNOSTICS
+.ad
+.fi
+Problems and transactions are logged to \fBsyslogd\fR(8).
+Corrupted message files are marked so that the queue
+manager can move them to the \fBcorrupt\fR queue afterwards.
+
+Depending on the setting of the \fBnotify_classes\fR parameter,
+the postmaster is notified of bounces and of other trouble.
+.SH CONFIGURATION PARAMETERS
+.na
+.nf
+.ad
+.fi
+The following \fBmain.cf\fR parameters are especially relevant to
+this program. See the Postfix \fBmain.cf\fR file for syntax details
+and for default values. Use the \fBpostfix reload\fR command after
+a configuration change.
+.SH Mailbox delivery
+.ad
+.fi
+.IP \fBvirtual_mailbox_base\fR
+Specifies a path that is prepended to all mailbox paths. This is
+a safety measure to ensure an out of control map doesn't litter
+the filesystem with mailboxes. While it could be set to "/",
+this isn't recommended.
+.IP \fBvirtual_mailbox_maps\fR
+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. Note that
+\fBvirtual_mailbox_base\fR is unconditionally prepended to
+this path.
+.IP \fBvirtual_minimum_uid\fR
+Specifies a minimum uid that will be accepted as a return from
+a \fBvirtual_uid_maps\fR lookup. Returned values less than this
+will be rejected, and the message will be deferred.
+.IP \fBvirtual_uid_maps\fR
+Recipients are looked up in this map to determine the UID to be
+used when writing to the target mailbox.
+.IP \fBvirtual_gid_maps\fR
+Recipients are looked up in this map to determine the GID to be
+used when writing to the target mailbox.
+.SH "Locking controls"
+.ad
+.fi
+.IP \fBmailbox_delivery_lock\fR
+How to lock UNIX-style mailboxes: one or more of \fBflock\fR,
+\fBfcntl\fR or \fBdotlock\fR.
+.IP \fBdeliver_lock_attempts\fR
+Limit the number of attempts to acquire an exclusive lock
+on a mailbox file.
+.IP \fBdeliver_lock_delay\fR
+Time in seconds between successive attempts to acquire
+an exclusive lock on a mailbox file.
+.IP \fBstale_lock_time\fR
+Limit the time after which a stale lockfile is removed.
+.SH "Resource controls"
+.ad
+.fi
+.IP \fBvirtual_destination_concurrency_limit\fR
+Limit the number of parallel deliveries to the same domain.
+The default limit is taken from the
+\fBdefault_destination_concurrency_limit\fR parameter.
+.IP \fBvirtual_destination_recipient_limit\fR
+Limit the number of recipients per message delivery.
+The default limit is taken from the
+\fBdefault_destination_recipient_limit\fR parameter.
+.SH HISTORY
+.na
+.nf
+.ad
+.fi
+This agent was originally based on the local delivery
+agent. Modifications mainly consisted of removing code that wasn't
+applicable or wasn't safe in this context (aliases, .forwards,
+program aliases).
+
+The \fBDelivered-To:\fR header appears in the \fBqmail\fR system
+by Daniel Bernstein.
+
+The \fImaildir\fR structure appears in the \fBqmail\fR system
+by Daniel Bernstein.
+.SH SEE ALSO
+.na
+.nf
+bounce(8) non-delivery status reports
+syslogd(8) system logging
+qmgr(8) queue manager
+.SH LICENSE
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH AUTHOR(S)
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
+
+Andrew McNamara
+andrewm@connect.com.au
+connect.com.au Pty. Ltd.
+Level 3, 213 Miller St
+North Sydney 2060, NSW, Australia
index 1a1ae3e3f73085bdf453feca3a38bb6fa25e4233..ffa1341d7ca3ccf90eb452f6c68a434b8a742859 100644 (file)
@@ -81,6 +81,14 @@ typedef struct {
     int     max;                       /* max length or zero */
 } CONFIG_STR_TABLE;
 
+typedef struct {
+    const char *name;                  /* config variable name */
+    const char *defval;                        /* default value or null */
+    char  **target;                    /* pointer to global variable */
+    int     min;                       /* min length or zero */
+    int     max;                       /* max length or zero */
+} CONFIG_RAW_TABLE;
+
 typedef struct {
     const char *name;                  /* config variable name */
     int     defval;                    /* default value */
@@ -107,7 +115,7 @@ extern void get_mail_conf_str_table(CONFIG_STR_TABLE *);
 extern void get_mail_conf_int_table(CONFIG_INT_TABLE *);
 extern void get_mail_conf_bool_table(CONFIG_BOOL_TABLE *);
 extern void get_mail_conf_time_table(CONFIG_TIME_TABLE *);
-extern void get_mail_conf_raw_table(CONFIG_STR_TABLE *);
+extern void get_mail_conf_raw_table(CONFIG_RAW_TABLE *);
 
  /*
   * Tables to initialize parameters from the global configuration file or
@@ -121,6 +129,14 @@ typedef struct {
     int     max;                       /* upper bound or zero */
 } CONFIG_STR_FN_TABLE;
 
+typedef struct {
+    const char *name;                  /* config variable name */
+    const char *(*defval) (void);      /* default value provider */
+    char  **target;                    /* pointer to global variable */
+    int     min;                       /* lower bound or zero */
+    int     max;                       /* upper bound or zero */
+} CONFIG_RAW_FN_TABLE;
+
 typedef struct {
     const char *name;                  /* config variable name */
     int     (*defval) (void);          /* default value provider */
@@ -138,7 +154,7 @@ typedef struct {
 extern void get_mail_conf_str_fn_table(CONFIG_STR_FN_TABLE *);
 extern void get_mail_conf_int_fn_table(CONFIG_INT_FN_TABLE *);
 extern void get_mail_conf_bool_fn_table(CONFIG_BOOL_FN_TABLE *);
-extern void get_mail_conf_raw_fn_table(CONFIG_STR_FN_TABLE *);
+extern void get_mail_conf_raw_fn_table(CONFIG_RAW_FN_TABLE *);
 
 /* LICENSE
 /* .ad
index 21eda4aea6a9b7a44f3db0a4de4c49f559632e62..4c7927d5ab07d7a8c6d0341e7fd0a73bd8c9f6cd 100644 (file)
 /*     int     max;
 /*
 /*     void    get_mail_conf_raw_table(table)
-/*     CONFIG_STR_TABLE *table;
+/*     CONFIG_RAW_TABLE *table;
 /*
 /*     void    get_mail_conf_raw_fn_table(table)
-/*     CONFIG_STR_TABLE *table;
+/*     CONFIG_RAW_TABLE *table;
 /* DESCRIPTION
 /*     This module implements support for string-valued global
 /*     configuration parameters that are loaded without $name expansion.
@@ -120,7 +120,7 @@ char   *get_mail_conf_raw_fn(const char *name, stupid_indent_str defval,
 
 /* get_mail_conf_raw_table - look up table of strings */
 
-void    get_mail_conf_raw_table(CONFIG_STR_TABLE *table)
+void    get_mail_conf_raw_table(CONFIG_RAW_TABLE *table)
 {
     while (table->name) {
        if (table->target[0])
@@ -133,7 +133,7 @@ void    get_mail_conf_raw_table(CONFIG_STR_TABLE *table)
 
 /* get_mail_conf_raw_fn_table - look up strings, defaults are functions */
 
-void    get_mail_conf_raw_fn_table(CONFIG_STR_FN_TABLE *table)
+void    get_mail_conf_raw_fn_table(CONFIG_RAW_FN_TABLE *table)
 {
     while (table->name) {
        if (table->target[0])
index eb177e4e4b3895b276b388b61eb428f81afb2e84..cc4c75a1f15dbe4219511e8a65e09a95792eb41b 100644 (file)
@@ -1104,6 +1104,28 @@ extern char *var_import_environ;
 #define DEF_EXPORT_ENVIRON             "TZ"
 extern char *var_export_environ;
 
+ /*
+  * Tunables for the "virtual" local delivery agent
+  */
+#define VAR_VIRT_MAILBOX_MAPS  "virtual_mailbox_maps"
+#define DEF_VIRT_MAILBOX_MAPS  ""
+extern char *var_mailbox_maps;
+#define VAR_VIRT_UID_MAPS      "virtual_uid_maps"
+#define DEF_VIRT_UID_MAPS      ""
+extern char *var_uid_maps;
+#define VAR_VIRT_GID_MAPS      "virtual_gid_maps"
+#define DEF_VIRT_GID_MAPS      ""
+extern char *var_gid_maps;
+#define VAR_VIRT_USEDOTLOCK    "virtual_usedotlock"
+#define DEF_VIRT_USEDOTLOCK    0
+extern bool var_virt_usedotlock;
+#define VAR_VIRT_MINUID                "virtual_minimum_uid"
+#define DEF_VIRT_MINUID                100
+extern int  var_virt_minimum_uid;
+#define VAR_VIRT_MAILBOX_BASE  "virtual_mailbox_base"
+#define DEF_VIRT_MAILBOX_BASE  ""
+extern char *var_virt_mailbox_base;
+
 /* LICENSE
 /* .ad
 /* .fi
index b5a18b66b253c9374e0812ba9ca07c1437c7b668..72c9a739854f110372a928fff7ded36e45c0a967 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20001217"
+#define DEF_MAIL_VERSION       "Snapshot-20001221"
 extern char *var_mail_version;
 
 /* LICENSE
index 8bb502c0fd61898ab4c4c9e7f6c629f9850d531d..3a1cb5fc856905835b18cc51b2257d14e4134a6e 100644 (file)
@@ -658,7 +658,7 @@ int     main(int argc, char **argv)
     };
 
     /* Suppress $name expansion upon loading. */
-    static CONFIG_STR_TABLE raw_table[] = {
+    static CONFIG_RAW_TABLE raw_table[] = {
        VAR_FORWARD_PATH, DEF_FORWARD_PATH, &var_forward_path, 0, 0,
        VAR_MAILBOX_COMMAND, DEF_MAILBOX_COMMAND, &var_mailbox_command, 0, 0,
        VAR_LUSER_RELAY, DEF_LUSER_RELAY, &var_luser_relay, 0, 0,
index 7ee9520cd30e99e039f2165e19185fa0f9131c55..c9df296f4f957b5b361049a0c45479ef9397e3ce 100644 (file)
@@ -61,7 +61,7 @@
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
 /*     are allowed.
-/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
+/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_RAW_TABLE *)"
 /*     A table with configurable parameters, to be loaded from the
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
@@ -481,7 +481,7 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
            get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
            break;
        case MAIL_SERVER_RAW_TABLE:
-           get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
+           get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
            break;
        case MAIL_SERVER_PRE_INIT:
            pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
index 78d868c2c24e450aed1d2a4f870abeadffbfad80..9c6920a7d73320f50a5b9d9da4a87ac0e4c5f138 100644 (file)
@@ -56,7 +56,7 @@
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
 /*     are allowed.
-/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
+/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_RAW_TABLE *)"
 /*     A table with configurable parameters, to be loaded from the
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
@@ -452,7 +452,7 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
            get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
            break;
        case MAIL_SERVER_RAW_TABLE:
-           get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
+           get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
            break;
        case MAIL_SERVER_PRE_INIT:
            pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
index 92fdd27af1bd643b750912ed95eb2cccf1c932aa..7edd05ff6d6f2bde2d46759eb667c1869a6bd454 100644 (file)
@@ -63,7 +63,7 @@
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
 /*     are allowed.
-/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_STR_TABLE *)"
+/* .IP "MAIL_SERVER_RAW_TABLE (CONFIG_RAW_TABLE *)"
 /*     A table with configurable parameters, to be loaded from the
 /*     global Postfix configuration file. Tables are loaded in the
 /*     order as specified, and multiple instances of the same type
@@ -452,7 +452,7 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
            get_mail_conf_time_table(va_arg(ap, CONFIG_TIME_TABLE *));
            break;
        case MAIL_SERVER_RAW_TABLE:
-           get_mail_conf_raw_table(va_arg(ap, CONFIG_STR_TABLE *));
+           get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
            break;
        case MAIL_SERVER_PRE_INIT:
            pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
index edeca6216af42e566dc0b69831f5d9b3d32bac67..af5f001c1ee374d6c31a1596901418e9029b0264 100644 (file)
@@ -10,7 +10,7 @@ DEFS  = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
 TESTPROG= 
 MAKES  = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
-       str_vars.h time_table.h time_vars.h
+       str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h
 PROG   = postconf
 SAMPLES        = ../../conf/main.cf.default
 INC_DIR        = ../../include
index 3e0663982215c994a062d1ab9e5f16ca83d5b2c7..cdf25b91b2f042932950b8df695ec021e3aa8678 100644 (file)
        print | "sed 's/[       ][      ]*/ /g' | sort -u >str_table.h" 
     }
 }
+/^(static| )*CONFIG_RAW_TABLE .*\{/,/\};/ { 
+    if ($1 ~ /VAR/) {
+       print "char *" substr($3,2,length($3)-2) ";" > "raw_vars.h"
+       print | "sed 's/[       ][      ]*/ /g' | sort -u >raw_table.h" 
+    }
+}
 /^(static| )*CONFIG_BOOL_TABLE .*\{/,/\};/ { 
     if ($1 ~ /VAR/) {
        print "int " substr($3,2,length($3)-2) ";" > "bool_vars.h"
index 10bb928d9064a36dcac9c2089e844a40084a07a7..80b1c2126f16726aa0f9da7cc69c024029e60af6 100644 (file)
 /* .IP \fB-h\fR
 /*     Show parameter values only, not the ``name = '' label
 /*     that normally precedes the value.
-/* .IP \fB-m\fR
-/*     List the names of all supported lookup table types.
 /* .IP \fB-l\fR
 /*     List the names of all supported mailbox locking methods.
+/* .IP \fB-m\fR
+/*     List the names of all supported lookup table types.
 /* .IP \fB-n\fR
 /*     Print non-default parameter settings only.
 /* .IP \fB-v\fR
 #define SHOW_MAPS      (1<<3)          /* show map types */
 #define EDIT_MAIN      (1<<4)          /* edit main.cf */
 #define SHOW_LOCKS     (1<<5)          /* show mailbox lock methods */
+#define SHOW_EVAL      (1<<6)          /* expand right-hand sides */
 
  /*
   * Lookup table for in-core parameter info.
@@ -124,6 +125,7 @@ DICT   *text_table;
 #include "bool_vars.h"
 #include "int_vars.h"
 #include "str_vars.h"
+#include "raw_vars.h"
 
  /*
   * Manually extracted.
@@ -156,6 +158,11 @@ static CONFIG_STR_TABLE str_table[] = {
     0,
 };
 
+static CONFIG_RAW_TABLE raw_table[] = {
+#include "raw_table.h"
+    0,
+};
+
  /*
   * Parameters with default values obtained via function calls.
   */
@@ -400,6 +407,30 @@ static void read_parameters(void)
     myfree(path);
 }
 
+/* set_parameters - set parameter values from default or explicit setting */
+
+static void set_parameters(void)
+{
+
+    /*
+     * Populate the configuration parameter dictionary with default settings
+     * or with actual settings.
+     * 
+     * Iterate over each entry in str_fn_table, str_fn_table_2, time_table,
+     * bool_table, int_table, str_table, and raw_table. Look up each
+     * parameter name in the configuration parameter dictionary. If the
+     * parameter is not set, take the default value, or take the value from
+     * in main.c, without doing $name expansions. This includes converting
+     * default values from numeric/boolean internal forms to external string
+     * form.
+     * 
+     * Once the configuration parameter dictionary is populated, printing a
+     * parameter setting is a matter of querying the configuration parameter
+     * dictionary, optionally expanding of $name values, and printing the
+     * result.
+     */
+}
+
 /* hash_parameters - hash all parameter names so we can find and sort them */
 
 static void hash_parameters(void)
@@ -409,6 +440,7 @@ static void hash_parameters(void)
     CONFIG_INT_TABLE *cit;
     CONFIG_STR_TABLE *cst;
     CONFIG_STR_FN_TABLE *csft;
+    CONFIG_RAW_TABLE *rst;
 
     param_table = htable_create(100);
 
@@ -424,12 +456,17 @@ static void hash_parameters(void)
        htable_enter(param_table, csft->name, (char *) csft);
     for (csft = str_fn_table_2; csft->name; csft++)
        htable_enter(param_table, csft->name, (char *) csft);
+    for (rst = raw_table; rst->name; rst++)
+       htable_enter(param_table, rst->name, (char *) rst);
 }
 
 /* show_strval - show string-valued parameter */
 
 static void show_strval(int mode, const char *name, const char *value)
 {
+    if (mode & SHOW_EVAL)
+       value = mail_conf_eval(value);
+
     if (mode & SHOW_NAME) {
        vstream_printf("%s = %s\n", name, value);
     } else {
@@ -586,6 +623,33 @@ static void print_str_fn_2(int mode, CONFIG_STR_FN_TABLE *csft)
     }
 }
 
+/* print_raw - print raw string parameter */
+
+static void print_raw(int mode, CONFIG_RAW_TABLE * rst)
+{
+    const char *value;
+
+    if (mode & SHOW_EVAL)
+       msg_warn("parameter %s expands at run-time", rst->name);
+    mode &= ~SHOW_EVAL;
+
+    if (mode & SHOW_DEFS) {
+       show_strval(mode, rst->name, rst->defval);
+    } else {
+       value = dict_lookup(CONFIG_DICT, rst->name);
+       if ((mode & SHOW_NONDEF) == 0) {
+           if (value == 0) {
+               show_strval(mode, rst->name, rst->defval);
+           } else {
+               show_strval(mode, rst->name, value);
+           }
+       } else {
+           if (value != 0)
+               show_strval(mode, rst->name, value);
+       }
+    }
+}
+
 /* print_parameter - show specific parameter */
 
 static void print_parameter(int mode, char *ptr)
@@ -594,7 +658,9 @@ static void print_parameter(int mode, char *ptr)
 #define INSIDE(p,t) (ptr >= (char *) t && ptr < ((char *) t) + sizeof(t))
 
     /*
-     * This is gross, but the best we can do on short notice.
+     * This is gross, but the best we can do on short notice. Instead of
+     * guessing we should use a tagged union. This is what code looks like
+     * when written under the pressure of a first public release.
      */
     if (INSIDE(ptr, time_table))
        print_time(mode, (CONFIG_TIME_TABLE *) ptr);
@@ -608,6 +674,8 @@ static void print_parameter(int mode, char *ptr)
        print_str_fn(mode, (CONFIG_STR_FN_TABLE *) ptr);
     if (INSIDE(ptr, str_fn_table_2))
        print_str_fn_2(mode, (CONFIG_STR_FN_TABLE *) ptr);
+    if (INSIDE(ptr, raw_table))
+       print_raw(mode, (CONFIG_RAW_TABLE *) ptr);
     if (msg_verbose)
        vstream_fflush(VSTREAM_OUT);
 }
@@ -722,6 +790,9 @@ int     main(int argc, char **argv)
        case 'd':
            mode |= SHOW_DEFS;
            break;
+       case 'E':
+           mode |= SHOW_EVAL;
+           break;
        case 'e':
            mode |= EDIT_MAIN;
            break;
@@ -778,8 +849,10 @@ int     main(int argc, char **argv)
      * If showing non-default values, read main.cf.
      */
     else {
-       if ((mode & SHOW_DEFS) == 0)
+       if ((mode & SHOW_DEFS) == 0) {
            read_parameters();
+           set_parameters();
+       }
 
        /*
         * Throw together all parameters and show the asked values.
index 8d8c53b631f2a079db714a09441bfde349092b57..35ac25f540ccf7fc13e3cf11e4370bcbc9e68a34 100644 (file)
@@ -383,6 +383,18 @@ dict_db.o: argv.h
 dict_db.o: dict_db.h
 dict_dbm.o: dict_dbm.c
 dict_dbm.o: sys_defs.h
+dict_dbm.o: msg.h
+dict_dbm.o: mymalloc.h
+dict_dbm.o: htable.h
+dict_dbm.o: iostuff.h
+dict_dbm.o: vstring.h
+dict_dbm.o: vbuf.h
+dict_dbm.o: myflock.h
+dict_dbm.o: stringops.h
+dict_dbm.o: dict.h
+dict_dbm.o: vstream.h
+dict_dbm.o: argv.h
+dict_dbm.o: dict_dbm.h
 dict_env.o: dict_env.c
 dict_env.o: sys_defs.h
 dict_env.o: mymalloc.h
@@ -406,6 +418,14 @@ dict_ldap.o: dict_ldap.c
 dict_ldap.o: sys_defs.h
 dict_mysql.o: dict_mysql.c
 dict_mysql.o: sys_defs.h
+dict_mysql.o: dict.h
+dict_mysql.o: vstream.h
+dict_mysql.o: vbuf.h
+dict_mysql.o: argv.h
+dict_mysql.o: msg.h
+dict_mysql.o: mymalloc.h
+dict_mysql.o: dict_mysql.h
+dict_mysql.o: vstring.h
 dict_ni.o: dict_ni.c
 dict_ni.o: sys_defs.h
 dict_nis.o: dict_nis.c
index 5f40644b0bf338d1c265ca3d742619a4264e49a8..26498f4847963c41e45b67bc837ad7da291b09b2 100644 (file)
@@ -128,6 +128,8 @@ static void plmysql_down_host(HOST *);
 static void plmysql_connect_single(HOST *, char *, char *, char *);
 static int plmysql_ready_reconn(HOST *);
 static void dict_mysql_update(DICT *, const char *, const char *);
+static void dict_mysql_delete(struct DICT *, const char *);
+static void dict_mysql_sequence(struct DICT *, const int, const char **, const char **);
 static const char *dict_mysql_lookup(DICT *, const char *);
 DICT   *dict_mysql_open(const char *, int, int);
 static void dict_mysql_close(DICT *);
@@ -350,6 +352,8 @@ DICT   *dict_mysql_open(const char *name, int unused_flags, int unused_dict_flag
     dict_mysql = (DICT_MYSQL *) mymalloc(sizeof(DICT_MYSQL));
     dict_mysql->dict.lookup = dict_mysql_lookup;
     dict_mysql->dict.update = dict_mysql_update;
+    dict_mysql->dict.delete = dict_mysql_delete;
+    dict_mysql->dict.sequence = dict_mysql_sequence;
     dict_mysql->dict.close = dict_mysql_close;
     dict_mysql->dict.fd = -1;                  /* there's no file descriptor
                                                 * for locking */
@@ -554,4 +558,15 @@ static void dict_mysql_update(DICT *dict, const char *unused_name, const char *u
     msg_fatal("dict_mysql_update: attempt to update mysql database");
 }
 
+static void dict_mysql_delete(DICT *unused_dict, const char *unused_name)
+{
+    msg_fatal("dict_mysql_delete: attempt to delete mysql database entry");
+}
+
+static void dict_mysql_sequence(DICT *unused_dict, const int unused_function,
+                        const char **unused_key, const char **unused_value)
+{
+    msg_fatal("dict_mysql_sequence: attempt to iterate over mysql database");
+}
+
 #endif
diff --git a/postfix/src/virtual/.indent.pro b/postfix/src/virtual/.indent.pro
new file mode 120000 (symlink)
index 0000000..5c837ec
--- /dev/null
@@ -0,0 +1 @@
+../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/virtual/Makefile.in b/postfix/src/virtual/Makefile.in
new file mode 100644 (file)
index 0000000..9517501
--- /dev/null
@@ -0,0 +1,441 @@
+SHELL  = /bin/sh
+SRCS   = virtual.c mailbox.c recipient.c deliver_attr.c maildir.c unknown.c
+OBJS   = virtual.o mailbox.o recipient.o deliver_attr.o maildir.o unknown.o
+HDRS   = virtual.h
+TESTSRC        =
+WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
+       -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
+       -Wunused
+DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE) -I..
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+PROG   = virtual
+TESTPROG= 
+INC_DIR        = ../../include
+LIBS   = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a $(AUXLIBS)
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+$(PROG):       $(OBJS) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
+
+Makefile: Makefile.in
+       (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs; cat $?) >$@
+
+test:  $(TESTPROG)
+
+update: ../../libexec/$(PROG)
+
+../../libexec/$(PROG): $(PROG)
+       cp $(PROG) ../../libexec
+
+printfck: $(OBJS) $(PROG)
+       rm -rf printfck
+       mkdir printfck
+       cp *.h printfck
+       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+       cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
+
+lint:
+       lint $(DEFS) $(SRCS) $(LINTFIX)
+
+clean:
+       rm -f *.o *core $(PROG) $(TESTPROG) junk 
+       rm -rf printfck
+
+tidy:  clean
+
+depend: $(MAKES)
+       (sed '1,/^# do not edit/!d' Makefile.in; \
+       set -e; for i in [a-z][a-z0-9]*.c; do \
+           $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
+       done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+       @make -f Makefile.in Makefile
+deliver_attr.o: deliver_attr.c
+deliver_attr.o: ../../include/sys_defs.h
+deliver_attr.o: ../../include/msg.h
+deliver_attr.o: ../../include/vstream.h
+deliver_attr.o: ../../include/vbuf.h
+deliver_attr.o: virtual.h
+deliver_attr.o: ../../include/htable.h
+deliver_attr.o: ../../include/vstring.h
+deliver_attr.o: ../../include/been_here.h
+deliver_attr.o: ../../include/tok822.h
+deliver_attr.o: ../../include/resolve_clnt.h
+deliver_attr.o: ../../include/deliver_request.h
+deliver_attr.o: ../../include/recipient_list.h
+deliver_attr.o: ../../include/maps.h
+deliver_attr.o: ../../include/dict.h
+deliver_attr.o: ../../include/argv.h
+mailbox.o: mailbox.c
+mailbox.o: ../../include/sys_defs.h
+mailbox.o: ../../include/msg.h
+mailbox.o: ../../include/htable.h
+mailbox.o: ../../include/vstring.h
+mailbox.o: ../../include/vbuf.h
+mailbox.o: ../../include/vstream.h
+mailbox.o: ../../include/mymalloc.h
+mailbox.o: ../../include/stringops.h
+mailbox.o: ../../include/set_eugid.h
+mailbox.o: ../../include/mail_copy.h
+mailbox.o: ../../include/safe_open.h
+mailbox.o: ../../include/deliver_flock.h
+mailbox.o: ../../include/dot_lockfile.h
+mailbox.o: ../../include/defer.h
+mailbox.o: ../../include/bounce.h
+mailbox.o: ../../include/sent.h
+mailbox.o: ../../include/mypwd.h
+mailbox.o: ../../include/mail_params.h
+mailbox.o: ../../include/deliver_pass.h
+mailbox.o: ../../include/deliver_request.h
+mailbox.o: ../../include/recipient_list.h
+mailbox.o: ../../include/mail_proto.h
+mailbox.o: ../../include/iostuff.h
+mailbox.o: virtual.h
+mailbox.o: ../../include/been_here.h
+mailbox.o: ../../include/tok822.h
+mailbox.o: ../../include/resolve_clnt.h
+mailbox.o: ../../include/maps.h
+mailbox.o: ../../include/dict.h
+mailbox.o: ../../include/argv.h
+maildir.o: maildir.c
+maildir.o: ../../include/sys_defs.h
+maildir.o: ../../include/msg.h
+maildir.o: ../../include/mymalloc.h
+maildir.o: ../../include/stringops.h
+maildir.o: ../../include/vstring.h
+maildir.o: ../../include/vbuf.h
+maildir.o: ../../include/vstream.h
+maildir.o: ../../include/make_dirs.h
+maildir.o: ../../include/set_eugid.h
+maildir.o: ../../include/get_hostname.h
+maildir.o: ../../include/mail_copy.h
+maildir.o: ../../include/bounce.h
+maildir.o: ../../include/sent.h
+maildir.o: ../../include/mail_params.h
+maildir.o: virtual.h
+maildir.o: ../../include/htable.h
+maildir.o: ../../include/been_here.h
+maildir.o: ../../include/tok822.h
+maildir.o: ../../include/resolve_clnt.h
+maildir.o: ../../include/deliver_request.h
+maildir.o: ../../include/recipient_list.h
+maildir.o: ../../include/maps.h
+maildir.o: ../../include/dict.h
+maildir.o: ../../include/argv.h
+recipient.o: recipient.c
+recipient.o: ../../include/sys_defs.h
+recipient.o: ../../include/msg.h
+recipient.o: ../../include/mymalloc.h
+recipient.o: ../../include/htable.h
+recipient.o: ../../include/split_at.h
+recipient.o: ../../include/stringops.h
+recipient.o: ../../include/vstring.h
+recipient.o: ../../include/vbuf.h
+recipient.o: ../../include/dict.h
+recipient.o: ../../include/vstream.h
+recipient.o: ../../include/argv.h
+recipient.o: ../../include/bounce.h
+recipient.o: ../../include/mail_params.h
+recipient.o: ../../include/split_addr.h
+recipient.o: ../../include/ext_prop.h
+recipient.o: virtual.h
+recipient.o: ../../include/been_here.h
+recipient.o: ../../include/tok822.h
+recipient.o: ../../include/resolve_clnt.h
+recipient.o: ../../include/deliver_request.h
+recipient.o: ../../include/recipient_list.h
+recipient.o: ../../include/maps.h
+unknown.o: unknown.c
+unknown.o: ../../include/sys_defs.h
+unknown.o: ../../include/msg.h
+unknown.o: ../../include/stringops.h
+unknown.o: ../../include/vstring.h
+unknown.o: ../../include/vbuf.h
+unknown.o: ../../include/mymalloc.h
+unknown.o: ../../include/mail_params.h
+unknown.o: ../../include/mail_proto.h
+unknown.o: ../../include/vstream.h
+unknown.o: ../../include/iostuff.h
+unknown.o: ../../include/bounce.h
+unknown.o: virtual.h
+unknown.o: ../../include/htable.h
+unknown.o: ../../include/been_here.h
+unknown.o: ../../include/tok822.h
+unknown.o: ../../include/resolve_clnt.h
+unknown.o: ../../include/deliver_request.h
+unknown.o: ../../include/recipient_list.h
+unknown.o: ../../include/maps.h
+unknown.o: ../../include/dict.h
+unknown.o: ../../include/argv.h
+virtual.o: virtual.c
+virtual.o: ../../include/sys_defs.h
+virtual.o: ../../include/msg.h
+virtual.o: ../../include/mymalloc.h
+virtual.o: ../../include/htable.h
+virtual.o: ../../include/vstring.h
+virtual.o: ../../include/vbuf.h
+virtual.o: ../../include/vstream.h
+virtual.o: ../../include/iostuff.h
+virtual.o: ../../include/name_mask.h
+virtual.o: ../../include/set_eugid.h
+virtual.o: ../../include/dict.h
+virtual.o: ../../include/argv.h
+virtual.o: ../../include/mail_queue.h
+virtual.o: ../../include/recipient_list.h
+virtual.o: ../../include/deliver_request.h
+virtual.o: ../../include/deliver_completed.h
+virtual.o: ../../include/mail_params.h
+virtual.o: ../../include/mail_addr.h
+virtual.o: ../../include/mail_conf.h
+virtual.o: ../../include/ext_prop.h
+virtual.o: ../../include/mail_server.h
+virtual.o: virtual.h
+virtual.o: ../../include/been_here.h
+virtual.o: ../../include/tok822.h
+virtual.o: ../../include/resolve_clnt.h
+virtual.o: ../../include/maps.h
+deliver_attr.o: deliver_attr.c
+deliver_attr.o: ../../include/sys_defs.h
+deliver_attr.o: ../../include/msg.h
+deliver_attr.o: ../../include/vstream.h
+deliver_attr.o: ../../include/vbuf.h
+deliver_attr.o: virtual.h
+deliver_attr.o: ../../include/vstring.h
+deliver_attr.o: ../../include/deliver_request.h
+deliver_attr.o: ../../include/recipient_list.h
+deliver_attr.o: ../../include/maps.h
+deliver_attr.o: ../../include/dict.h
+deliver_attr.o: ../../include/argv.h
+deliver_attr.o: ../../include/mbox_conf.h
+mailbox.o: mailbox.c
+mailbox.o: ../../include/sys_defs.h
+mailbox.o: ../../include/msg.h
+mailbox.o: ../../include/vstring.h
+mailbox.o: ../../include/vbuf.h
+mailbox.o: ../../include/vstream.h
+mailbox.o: ../../include/mymalloc.h
+mailbox.o: ../../include/stringops.h
+mailbox.o: ../../include/set_eugid.h
+mailbox.o: ../../include/mail_copy.h
+mailbox.o: ../../include/mbox_open.h
+mailbox.o: ../../include/safe_open.h
+mailbox.o: ../../include/defer.h
+mailbox.o: ../../include/bounce.h
+mailbox.o: ../../include/sent.h
+mailbox.o: ../../include/mypwd.h
+mailbox.o: ../../include/mail_params.h
+mailbox.o: virtual.h
+mailbox.o: ../../include/deliver_request.h
+mailbox.o: ../../include/recipient_list.h
+mailbox.o: ../../include/maps.h
+mailbox.o: ../../include/dict.h
+mailbox.o: ../../include/argv.h
+mailbox.o: ../../include/mbox_conf.h
+maildir.o: maildir.c
+maildir.o: ../../include/sys_defs.h
+maildir.o: ../../include/msg.h
+maildir.o: ../../include/mymalloc.h
+maildir.o: ../../include/stringops.h
+maildir.o: ../../include/vstring.h
+maildir.o: ../../include/vbuf.h
+maildir.o: ../../include/vstream.h
+maildir.o: ../../include/make_dirs.h
+maildir.o: ../../include/set_eugid.h
+maildir.o: ../../include/get_hostname.h
+maildir.o: ../../include/sane_fsops.h
+maildir.o: ../../include/mail_copy.h
+maildir.o: ../../include/bounce.h
+maildir.o: ../../include/sent.h
+maildir.o: ../../include/mail_params.h
+maildir.o: virtual.h
+maildir.o: ../../include/deliver_request.h
+maildir.o: ../../include/recipient_list.h
+maildir.o: ../../include/maps.h
+maildir.o: ../../include/dict.h
+maildir.o: ../../include/argv.h
+maildir.o: ../../include/mbox_conf.h
+recipient.o: recipient.c
+recipient.o: ../../include/sys_defs.h
+recipient.o: ../../include/msg.h
+recipient.o: ../../include/mymalloc.h
+recipient.o: ../../include/htable.h
+recipient.o: ../../include/split_at.h
+recipient.o: ../../include/stringops.h
+recipient.o: ../../include/vstring.h
+recipient.o: ../../include/vbuf.h
+recipient.o: ../../include/dict.h
+recipient.o: ../../include/vstream.h
+recipient.o: ../../include/argv.h
+recipient.o: ../../include/bounce.h
+recipient.o: ../../include/mail_params.h
+recipient.o: ../../include/split_addr.h
+recipient.o: ../../include/ext_prop.h
+recipient.o: virtual.h
+recipient.o: ../../include/deliver_request.h
+recipient.o: ../../include/recipient_list.h
+recipient.o: ../../include/maps.h
+recipient.o: ../../include/mbox_conf.h
+unknown.o: unknown.c
+unknown.o: ../../include/sys_defs.h
+unknown.o: ../../include/msg.h
+unknown.o: ../../include/stringops.h
+unknown.o: ../../include/vstring.h
+unknown.o: ../../include/vbuf.h
+unknown.o: ../../include/mymalloc.h
+unknown.o: ../../include/mail_params.h
+unknown.o: ../../include/mail_proto.h
+unknown.o: ../../include/vstream.h
+unknown.o: ../../include/iostuff.h
+unknown.o: ../../include/bounce.h
+unknown.o: virtual.h
+unknown.o: ../../include/deliver_request.h
+unknown.o: ../../include/recipient_list.h
+unknown.o: ../../include/maps.h
+unknown.o: ../../include/dict.h
+unknown.o: ../../include/argv.h
+unknown.o: ../../include/mbox_conf.h
+virtual.o: virtual.c
+virtual.o: ../../include/sys_defs.h
+virtual.o: ../../include/msg.h
+virtual.o: ../../include/mymalloc.h
+virtual.o: ../../include/htable.h
+virtual.o: ../../include/vstring.h
+virtual.o: ../../include/vbuf.h
+virtual.o: ../../include/vstream.h
+virtual.o: ../../include/iostuff.h
+virtual.o: ../../include/name_mask.h
+virtual.o: ../../include/set_eugid.h
+virtual.o: ../../include/dict.h
+virtual.o: ../../include/argv.h
+virtual.o: ../../include/mail_queue.h
+virtual.o: ../../include/recipient_list.h
+virtual.o: ../../include/deliver_request.h
+virtual.o: ../../include/deliver_completed.h
+virtual.o: ../../include/mail_params.h
+virtual.o: ../../include/mail_addr.h
+virtual.o: ../../include/mail_conf.h
+virtual.o: ../../include/mail_server.h
+virtual.o: virtual.h
+virtual.o: ../../include/maps.h
+virtual.o: ../../include/mbox_conf.h
+deliver_attr.o: deliver_attr.c
+deliver_attr.o: ../../include/sys_defs.h
+deliver_attr.o: ../../include/msg.h
+deliver_attr.o: ../../include/vstream.h
+deliver_attr.o: ../../include/vbuf.h
+deliver_attr.o: virtual.h
+deliver_attr.o: ../../include/vstring.h
+deliver_attr.o: ../../include/deliver_request.h
+deliver_attr.o: ../../include/recipient_list.h
+deliver_attr.o: ../../include/maps.h
+deliver_attr.o: ../../include/dict.h
+deliver_attr.o: ../../include/argv.h
+deliver_attr.o: ../../include/mbox_conf.h
+mailbox.o: mailbox.c
+mailbox.o: ../../include/sys_defs.h
+mailbox.o: ../../include/msg.h
+mailbox.o: ../../include/vstring.h
+mailbox.o: ../../include/vbuf.h
+mailbox.o: ../../include/vstream.h
+mailbox.o: ../../include/mymalloc.h
+mailbox.o: ../../include/stringops.h
+mailbox.o: ../../include/set_eugid.h
+mailbox.o: ../../include/mail_copy.h
+mailbox.o: ../../include/mbox_open.h
+mailbox.o: ../../include/safe_open.h
+mailbox.o: ../../include/defer.h
+mailbox.o: ../../include/bounce.h
+mailbox.o: ../../include/sent.h
+mailbox.o: ../../include/mypwd.h
+mailbox.o: ../../include/mail_params.h
+mailbox.o: virtual.h
+mailbox.o: ../../include/deliver_request.h
+mailbox.o: ../../include/recipient_list.h
+mailbox.o: ../../include/maps.h
+mailbox.o: ../../include/dict.h
+mailbox.o: ../../include/argv.h
+mailbox.o: ../../include/mbox_conf.h
+maildir.o: maildir.c
+maildir.o: ../../include/sys_defs.h
+maildir.o: ../../include/msg.h
+maildir.o: ../../include/mymalloc.h
+maildir.o: ../../include/stringops.h
+maildir.o: ../../include/vstring.h
+maildir.o: ../../include/vbuf.h
+maildir.o: ../../include/vstream.h
+maildir.o: ../../include/make_dirs.h
+maildir.o: ../../include/set_eugid.h
+maildir.o: ../../include/get_hostname.h
+maildir.o: ../../include/sane_fsops.h
+maildir.o: ../../include/mail_copy.h
+maildir.o: ../../include/bounce.h
+maildir.o: ../../include/sent.h
+maildir.o: ../../include/mail_params.h
+maildir.o: virtual.h
+maildir.o: ../../include/deliver_request.h
+maildir.o: ../../include/recipient_list.h
+maildir.o: ../../include/maps.h
+maildir.o: ../../include/dict.h
+maildir.o: ../../include/argv.h
+maildir.o: ../../include/mbox_conf.h
+recipient.o: recipient.c
+recipient.o: ../../include/sys_defs.h
+recipient.o: ../../include/msg.h
+recipient.o: ../../include/mymalloc.h
+recipient.o: ../../include/stringops.h
+recipient.o: ../../include/vstring.h
+recipient.o: ../../include/vbuf.h
+recipient.o: ../../include/bounce.h
+recipient.o: virtual.h
+recipient.o: ../../include/vstream.h
+recipient.o: ../../include/deliver_request.h
+recipient.o: ../../include/recipient_list.h
+recipient.o: ../../include/maps.h
+recipient.o: ../../include/dict.h
+recipient.o: ../../include/argv.h
+recipient.o: ../../include/mbox_conf.h
+unknown.o: unknown.c
+unknown.o: ../../include/sys_defs.h
+unknown.o: ../../include/msg.h
+unknown.o: ../../include/stringops.h
+unknown.o: ../../include/vstring.h
+unknown.o: ../../include/vbuf.h
+unknown.o: ../../include/mymalloc.h
+unknown.o: ../../include/mail_params.h
+unknown.o: ../../include/mail_proto.h
+unknown.o: ../../include/vstream.h
+unknown.o: ../../include/iostuff.h
+unknown.o: ../../include/bounce.h
+unknown.o: virtual.h
+unknown.o: ../../include/deliver_request.h
+unknown.o: ../../include/recipient_list.h
+unknown.o: ../../include/maps.h
+unknown.o: ../../include/dict.h
+unknown.o: ../../include/argv.h
+unknown.o: ../../include/mbox_conf.h
+virtual.o: virtual.c
+virtual.o: ../../include/sys_defs.h
+virtual.o: ../../include/msg.h
+virtual.o: ../../include/mymalloc.h
+virtual.o: ../../include/htable.h
+virtual.o: ../../include/vstring.h
+virtual.o: ../../include/vbuf.h
+virtual.o: ../../include/vstream.h
+virtual.o: ../../include/iostuff.h
+virtual.o: ../../include/name_mask.h
+virtual.o: ../../include/set_eugid.h
+virtual.o: ../../include/dict.h
+virtual.o: ../../include/argv.h
+virtual.o: ../../include/mail_queue.h
+virtual.o: ../../include/recipient_list.h
+virtual.o: ../../include/deliver_request.h
+virtual.o: ../../include/deliver_completed.h
+virtual.o: ../../include/mail_params.h
+virtual.o: ../../include/mail_addr.h
+virtual.o: ../../include/mail_conf.h
+virtual.o: ../../include/mail_server.h
+virtual.o: virtual.h
+virtual.o: ../../include/maps.h
+virtual.o: ../../include/mbox_conf.h
diff --git a/postfix/src/virtual/deliver_attr.c b/postfix/src/virtual/deliver_attr.c
new file mode 100644 (file)
index 0000000..63b1558
--- /dev/null
@@ -0,0 +1,74 @@
+/*++
+/* NAME
+/*     deliver_attr 3
+/* SUMMARY
+/*     initialize message delivery attributes
+/* SYNOPSIS
+/*     #include "virtual.h"
+/*
+/*     void    deliver_attr_init(attrp)
+/*     DELIVER_ATTR *attrp;
+/*
+/*     void    deliver_attr_dump(attrp)
+/*     DELIVER_ATTR *attrp;
+/* DESCRIPTION
+/*     deliver_attr_init() initializes a structure with message delivery
+/*     attributes to a known initial state (all zeros).
+/*
+/*     deliver_attr_dump() logs the contents of the given attribute list.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstream.h>
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+/* deliver_attr_init - set message delivery attributes to all-zero state */
+
+void    deliver_attr_init(DELIVER_ATTR *attrp)
+{
+    attrp->level = 0;
+    attrp->fp = 0;
+    attrp->queue_name = 0;
+    attrp->queue_id = 0;
+    attrp->offset = 0;
+    attrp->sender = 0;
+    attrp->recipient = 0;
+    attrp->user = 0;
+    attrp->delivered = 0;
+    attrp->relay = 0;
+}
+
+/* deliver_attr_dump - log message delivery attributes */
+
+void    deliver_attr_dump(DELIVER_ATTR *attrp)
+{
+    msg_info("level: %d", attrp->level);
+    msg_info("path: %s", VSTREAM_PATH(attrp->fp));
+    msg_info("fp: 0x%lx", (long) attrp->fp);
+    msg_info("queue_name: %s", attrp->queue_name ? attrp->queue_name : "null");
+    msg_info("queue_id: %s", attrp->queue_id ? attrp->queue_id : "null");
+    msg_info("offset: %ld", attrp->offset);
+    msg_info("sender: %s", attrp->sender ? attrp->sender : "null");
+    msg_info("recipient: %s", attrp->recipient ? attrp->recipient : "null");
+    msg_info("user: %s", attrp->user ? attrp->user : "null");
+    msg_info("delivered: %s", attrp->delivered ? attrp->delivered : "null");
+    msg_info("relay: %s", attrp->relay ? attrp->relay : "null");
+}
diff --git a/postfix/src/virtual/mailbox.c b/postfix/src/virtual/mailbox.c
new file mode 100644 (file)
index 0000000..9dfca28
--- /dev/null
@@ -0,0 +1,232 @@
+/*++
+/* NAME
+/*     mailbox 3
+/* SUMMARY
+/*     mailbox delivery
+/* SYNOPSIS
+/*     #include "virtual.h"
+/*
+/*     int     deliver_mailbox(state, usr_attr, statusp)
+/*     LOCAL_STATE state;
+/*     USER_ATTR usr_attr;
+/*     int     *statusp;
+/* DESCRIPTION
+/*     deliver_mailbox() delivers to UNIX-style mailbox or to maildir.
+/*
+/*     A zero result means that the named user was not found.
+/*
+/*     Arguments:
+/* .IP state
+/*     The attributes that specify the message, recipient and more.
+/* .IP usr_attr
+/*     Attributes describing user rights and mailbox location.
+/* .IP statusp
+/*     Delivery status: see below.
+/* DIAGNOSTICS
+/*     The message delivery status is non-zero when delivery should be tried
+/*     again.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <set_eugid.h>
+
+/* Global library. */
+
+#include <mail_copy.h>
+#include <mbox_open.h>
+#include <defer.h>
+#include <sent.h>
+#include <mail_params.h>
+
+#ifndef EDQUOT
+#define EDQUOT EFBIG
+#endif
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+#define YES    1
+#define NO     0
+
+/* deliver_mailbox_file - deliver to recipient mailbox */
+
+static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
+{
+    char   *myname = "deliver_mailbox_file";
+    VSTRING *why;
+    MBOX   *mp;
+    int     status;
+    int     copy_flags;
+    long    end;
+    struct stat st;
+
+    /*
+     * Make verbose logging easier to understand.
+     */
+    state.level++;
+    if (msg_verbose)
+       MSG_LOG_STATE(myname, state);
+
+    /*
+     * Initialize. Assume the operation will fail. Set the delivered
+     * attribute to reflect the final recipient.
+     */
+    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
+       msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
+    state.msg_attr.delivered = state.msg_attr.recipient;
+    status = -1;
+    why = vstring_alloc(100);
+
+    /*
+     * Lock the mailbox and open/create the mailbox file.
+     * 
+     * Write the file as the recipient, so that file quota work.
+     */
+    copy_flags = MAIL_COPY_MBOX;
+
+    set_eugid(usr_attr.uid, usr_attr.gid);
+    mp = mbox_open(usr_attr.mailbox, O_APPEND | O_WRONLY | O_CREAT,
+                  S_IRUSR | S_IWUSR, &st, -1, -1,
+                  virtual_mbox_lock_mask, why);
+    if (mp != 0) {
+       if (S_ISREG(st.st_mode) == 0) {
+           vstream_fclose(mp->fp);
+           vstring_sprintf(why, "destination is not a regular file");
+           errno = 0;
+       } else {
+           end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END);
+           status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp,
+                              copy_flags, "\n", why);
+       }
+       mbox_release(mp);
+    }
+    set_eugid(var_owner_uid, var_owner_gid);
+
+    /*
+     * As the mail system, bounce, defer delivery, or report success.
+     */
+    if (status != 0)
+       status = (errno == EDQUOT ? bounce_append : defer_append)
+           (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+            "cannot access mailbox for %s. %s",
+            usr_attr.mailbox, state.msg_attr.recipient, vstring_str(why));
+    else
+       sent(SENT_ATTR(state.msg_attr), "mailbox");
+
+    vstring_free(why);
+    return (status);
+}
+
+/* deliver_mailbox - deliver to recipient mailbox */
+
+int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
+{
+    char   *myname = "deliver_mailbox";
+    const char *result;
+    long    n;
+
+    /*
+     * Make verbose logging easier to understand.
+     */
+    state.level++;
+    if (msg_verbose)
+       MSG_LOG_STATE(myname, state);
+
+    /*
+     * Sanity check.
+     */
+    if (*var_virt_mailbox_base != '/')
+       msg_fatal("do not specify relative pathname: %s = %s",
+                 VAR_VIRT_MAILBOX_BASE, var_virt_mailbox_base);
+
+    /*
+     * Look up the mailbox location and rights of the recipient user.
+     */
+    result = maps_find(virtual_mailbox_maps, state.msg_attr.user, 0);
+    if (result == 0) {
+       if (dict_errno == 0)
+           return (NO);
+
+       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                               "%s: lookup %s: %m",
+                         virtual_mailbox_maps->title, state.msg_attr.user);
+       return (YES);
+    }
+    usr_attr.mailbox = concatenate(var_virt_mailbox_base, "/", result, (char *) 0);
+
+    if ((result = maps_find(virtual_uid_maps, state.msg_attr.user, 0)) == 0) {
+       myfree(usr_attr.mailbox);
+       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                               "recipient %s: uid not found in %s",
+                             state.msg_attr.user, virtual_uid_maps->title);
+       return (YES);
+    }
+    if ((n = atol(result)) < var_virt_minimum_uid) {
+       myfree(usr_attr.mailbox);
+       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                               "recipient %s: bad uid %s in %s",
+                     state.msg_attr.user, result, virtual_uid_maps->title);
+       return (YES);
+    }
+    usr_attr.uid = (uid_t) n;
+
+    if ((result = maps_find(virtual_gid_maps, state.msg_attr.user, 0)) == 0) {
+       myfree(usr_attr.mailbox);
+       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                               "recipient %s: gid not found in %s",
+                             state.msg_attr.user, virtual_gid_maps->title);
+       return (YES);
+    }
+    if ((n = atol(result)) <= 0) {
+       myfree(usr_attr.mailbox);
+       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                               "recipient %s: bad gid %s in %s",
+                     state.msg_attr.user, result, virtual_gid_maps->title);
+       return (YES);
+    }
+    usr_attr.gid = (gid_t) n;
+
+    if (msg_verbose)
+       msg_info("%s[%d]: set user_attr: %s, uid = %d, gid = %d",
+                myname, state.level,
+                usr_attr.mailbox, usr_attr.uid, usr_attr.gid);
+
+    /*
+     * Deliver to mailbox or to external command.
+     */
+#define LAST_CHAR(s) (s[strlen(s) - 1])
+
+    if (LAST_CHAR(usr_attr.mailbox) == '/')
+       *statusp = deliver_maildir(state, usr_attr);
+    else
+       *statusp = deliver_mailbox_file(state, usr_attr);
+
+    /*
+     * Cleanup.
+     */
+    myfree(usr_attr.mailbox);
+    return (YES);
+}
diff --git a/postfix/src/virtual/maildir.c b/postfix/src/virtual/maildir.c
new file mode 100644 (file)
index 0000000..4aa0c67
--- /dev/null
@@ -0,0 +1,159 @@
+/*++
+/* NAME
+/*     maildir 3
+/* SUMMARY
+/*     delivery to maildir
+/* SYNOPSIS
+/*     #include "virtual.h"
+/*
+/*     int     deliver_maildir(state, usr_attr)
+/*     LOCAL_STATE state;
+/*     USER_ATTR usr_attr;
+/* DESCRIPTION
+/*     deliver_maildir() delivers a message to a qmail-style maildir.
+/*
+/*     Arguments:
+/* .IP state
+/*     The attributes that specify the message, recipient and more.
+/* .IP usr_attr
+/*     Attributes describing user rights and environment information.
+/* DIAGNOSTICS
+/*     deliver_maildir() always succeeds or it bounces the message.
+/* SEE ALSO
+/*     bounce(3)
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include "sys_defs.h"
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <make_dirs.h>
+#include <set_eugid.h>
+#include <get_hostname.h>
+#include <sane_fsops.h>
+
+/* Global library. */
+
+#include <mail_copy.h>
+#include <bounce.h>
+#include <sent.h>
+#include <mail_params.h>
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+/* deliver_maildir - delivery to maildir-style mailbox */
+
+int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr)
+{
+    char   *myname = "deliver_maildir";
+    char   *newdir;
+    char   *tmpdir;
+    char   *curdir;
+    char   *tmpfile;
+    char   *newfile;
+    VSTRING *why;
+    VSTRING *buf;
+    VSTREAM *dst;
+    int     status;
+    int     copy_flags;
+    static int count;
+
+    /*
+     * Make verbose logging easier to understand.
+     */
+    state.level++;
+    if (msg_verbose)
+       MSG_LOG_STATE(myname, state);
+
+    /*
+     * Initialize. Assume the operation will fail. Set the delivered
+     * attribute to reflect the final recipient.
+     */
+    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
+       msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
+    state.msg_attr.delivered = state.msg_attr.recipient;
+    status = -1;
+    buf = vstring_alloc(100);
+    why = vstring_alloc(100);
+
+    copy_flags = MAIL_COPY_TOFILE | MAIL_COPY_RETURN_PATH | MAIL_COPY_DELIVERED;
+
+    newdir = concatenate(usr_attr.mailbox, "new/", (char *) 0);
+    tmpdir = concatenate(usr_attr.mailbox, "tmp/", (char *) 0);
+    curdir = concatenate(usr_attr.mailbox, "cur/", (char *) 0);
+
+    /*
+     * Create and write the file as the recipient, so that file quota work.
+     * Create any missing directories on the fly. The file name is chosen
+     * according to ftp://koobera.math.uic.edu/www/proto/maildir.html:
+     * 
+     * "A unique name has three pieces, separated by dots. On the left is the
+     * result of time(). On the right is the result of gethostname(). In the
+     * middle is something that doesn't repeat within one second on a single
+     * host. I fork a new process for each delivery, so I just use the
+     * process ID. If you're delivering several messages from one process,
+     * use starttime.pid_count.host, where starttime is the time that your
+     * process started, and count is the number of messages you've
+     * delivered."
+     */
+#define STR vstring_str
+
+    set_eugid(usr_attr.uid, usr_attr.gid);
+    vstring_sprintf(buf, "%ld.%d_%d.%s", (long) var_starttime,
+                   var_pid, count++, get_hostname());
+    tmpfile = concatenate(tmpdir, STR(buf), (char *) 0);
+    newfile = concatenate(newdir, STR(buf), (char *) 0);
+    if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0
+       && (errno != ENOENT
+           || make_dirs(tmpdir, 0700) < 0
+           || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) {
+       vstring_sprintf(why, "create %s: %m", tmpfile);
+    } else {
+       if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why) == 0) {
+           if (sane_link(tmpfile, newfile) < 0
+               && (errno != ENOENT
+                   || (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0
+                   || sane_link(tmpfile, newfile) < 0)) {
+               vstring_sprintf(why, "link to %s: %m", newfile);
+           } else {
+               status = 0;
+           }
+       }
+       if (unlink(tmpfile) < 0)
+           msg_warn("remove %s: %m", tmpfile);
+    }
+    set_eugid(var_owner_uid, var_owner_gid);
+
+    if (status)
+       bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                     "maildir delivery failed: %s", vstring_str(why));
+    else
+       sent(SENT_ATTR(state.msg_attr), "maildir");
+    vstring_free(buf);
+    vstring_free(why);
+    myfree(newdir);
+    myfree(tmpdir);
+    myfree(curdir);
+    myfree(tmpfile);
+    myfree(newfile);
+    return (0);
+}
diff --git a/postfix/src/virtual/recipient.c b/postfix/src/virtual/recipient.c
new file mode 100644 (file)
index 0000000..725108f
--- /dev/null
@@ -0,0 +1,93 @@
+/*++
+/* NAME
+/*     recipient 3
+/* SUMMARY
+/*     deliver to one local recipient
+/* SYNOPSIS
+/*     #include "virtual.h"
+/*
+/*     int     deliver_recipient(state, usr_attr)
+/*     LOCAL_STATE state;
+/*     USER_ATTR *usr_attr;
+/* DESCRIPTION
+/*     deliver_recipient() delivers a message to a local recipient.
+/*
+/*     Arguments:
+/* .IP state
+/*     The attributes that specify the message, sender, and more.
+/* .IP usr_attr
+/*     Attributes describing user rights and mailbox location.
+/* DIAGNOSTICS
+/*     deliver_recipient() returns non-zero when delivery should be
+/*     tried again.
+/* SEE ALSO
+/*     mailbox(3) delivery to UNIX-style mailbox
+/*     maildir(3) delivery to qmail-style maildir
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <bounce.h>
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+/* deliver_recipient - deliver one local recipient */
+
+int     deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
+{
+    char   *myname = "deliver_recipient";
+    int     rcpt_stat;
+
+    /*
+     * Make verbose logging easier to understand.
+     */
+    state.level++;
+    if (msg_verbose)
+       MSG_LOG_STATE(myname, state);
+
+    /*
+     * Set up the recipient-specific attributes. The recipient's lookup
+     * handle is the full address.
+     */
+    if (state.msg_attr.delivered == 0)
+       state.msg_attr.delivered = state.msg_attr.recipient;
+    state.msg_attr.user = mystrdup(state.msg_attr.recipient);
+    lowercase(state.msg_attr.user);
+
+    /*
+     * Deliver
+     */
+    if (msg_verbose)
+       deliver_attr_dump(&state.msg_attr);
+
+    if (deliver_mailbox(state, usr_attr, &rcpt_stat) == 0)
+       rcpt_stat = deliver_unknown(state);
+
+    /*
+     * Cleanup.
+     */
+    myfree(state.msg_attr.user);
+
+    return (rcpt_stat);
+}
diff --git a/postfix/src/virtual/unknown.c b/postfix/src/virtual/unknown.c
new file mode 100644 (file)
index 0000000..8989046
--- /dev/null
@@ -0,0 +1,64 @@
+/*++
+/* NAME
+/*     unknown 3
+/* SUMMARY
+/*     delivery of unknown recipients
+/* SYNOPSIS
+/*     #include "virtual.h"
+/*
+/*     int     deliver_unknown(state)
+/*     LOCAL_STATE state;
+/* DESCRIPTION
+/*     deliver_unknown() delivers a message for unknown recipients.
+/* .PP
+/*     Arguments:
+/* .IP state
+/*     Message delivery attributes (sender, recipient etc.).
+/* .IP usr_attr
+/*     Attributes describing user rights and mailbox location.
+/* DIAGNOSTICS
+/*     The result status is non-zero when delivery should be tried again.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+
+/* Global library. */
+
+#include <bounce.h>
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+/* deliver_unknown - delivery for unknown recipients */
+
+int     deliver_unknown(LOCAL_STATE state)
+{
+    char   *myname = "deliver_unknown";
+
+    /*
+     * Make verbose logging easier to understand.
+     */
+    state.level++;
+    if (msg_verbose)
+       MSG_LOG_STATE(myname, state);
+
+    return (bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+                         "unknown user: \"%s\"", state.msg_attr.user));
+
+}
diff --git a/postfix/src/virtual/virtual.c b/postfix/src/virtual/virtual.c
new file mode 100644 (file)
index 0000000..665cbe7
--- /dev/null
@@ -0,0 +1,352 @@
+/*++
+/* NAME
+/*     virtual 8
+/* SUMMARY
+/*     Postfix virtual domain mail delivery agent
+/* SYNOPSIS
+/*     \fBvirtual\fR [generic Postfix daemon options]
+/* DESCRIPTION
+/*     This daemon is designed for ISP's offering virtual mail hosting
+/*     services. Originally based on the local delivery agent, this agent
+/*     locates user mailboxes via map lookups of the full recipient
+/*     address, rather than hard-coded unix password file searches of
+/*     the local part only.
+/*
+/*     The \fBvirtual\fR daemon processes delivery requests from the
+/*     Postfix queue manager to deliver mail to virtual local recipients.
+/*     Each delivery request specifies a queue file, a sender address,
+/*     a domain or host to deliver to, and one or more recipients.
+/*     This program expects to be run from the \fBmaster\fR(8) process
+/*     manager.
+/*
+/*     The \fBvirtual\fR daemon updates queue files and marks recipients
+/*     as finished, or it informs the queue manager that delivery should
+/*     be tried again at a later time. Delivery problem reports are sent
+/*     to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
+/* MAILBOX DELIVERY
+/* .ad
+/* .fi
+/*     The \fBvirtual\fR delivery agent can deliver to UNIX-style mailbox
+/*     file or to qmail-style maildir files. The pathname and delivery
+/*     mailbox style are controlled by the $\fBvirtual_mailbox_base\fR
+/*     and \fB$virtual_mailbox_maps\fR parameters (see below).
+/*
+/*     In the case of UNIX-style mailbox delivery,
+/*     the \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR"
+/*     envelope header to each message, prepends a \fBDelivered-To:\fR header
+/*     with the envelope recipient address, prepends a \fBReturn-Path:\fR
+/*     header with the envelope sender address, prepends a \fB>\fR character
+/*     to lines beginning with "\fBFrom \fR", and appends an empty line.
+/*     The mailbox is locked for exclusive access while delivery is in
+/*     progress. In case of problems, an attempt is made to truncate the
+/*     mailbox to its original length.
+/*
+/*     In the case of \fBmaildir\fR delivery, the local daemon prepends
+/*     a \fBDelivered-To:\fR header with the envelope recipient address
+/*     and prepends a \fBReturn-Path:\fR header with the envelope sender
+/*     address.
+/* DELIVERY RIGHTS
+/* .ad
+/* .fi
+/*     Deliveries to mailboxes are made with the UID and GID that are listed
+/*     for the recipient in the tables listed in the \fB$virtual_uid_maps\fR
+/*     and \fB$virtual_gid_maps\fR, respectively.
+/*
+/*     The \fBvirtual_minimum_uid\fR parameter specifies a lower bound on
+/*     UID values that may be specified in \fB$virtual_uid_maps\fR. Mail
+/*     will not be delivered when an invalid UID is found.
+/* STANDARDS
+/*     RFC 822 (ARPA Internet Text Messages)
+/* DIAGNOSTICS
+/*     Problems and transactions are logged to \fBsyslogd\fR(8).
+/*     Corrupted message files are marked so that the queue
+/*     manager can move them to the \fBcorrupt\fR queue afterwards.
+/*
+/*     Depending on the setting of the \fBnotify_classes\fR parameter,
+/*     the postmaster is notified of bounces and of other trouble.
+/* CONFIGURATION PARAMETERS
+/* .ad
+/* .fi
+/*     The following \fBmain.cf\fR parameters are especially relevant to
+/*     this program. See the Postfix \fBmain.cf\fR file for syntax details
+/*     and for default values. Use the \fBpostfix reload\fR command after
+/*     a configuration change.
+/* .SH Mailbox delivery
+/* .ad
+/* .fi
+/* .IP \fBvirtual_mailbox_base\fR
+/*     Specifies a path that is prepended to all mailbox or maildir paths.
+/*     This is a safety measure to ensure that an out of control map in
+/*     \fBvirtual_mailbox_maps\fR doesn't litter the filesystem with mailboxes.
+/*     While it could be set to "/", this setting isn't recommended.
+/* .IP \fBvirtual_mailbox_maps\fR
+/*     Recipients are looked up in this map to determine the path to
+/*     their mailbox or maildir. If the returned path ends in a slash
+/*     ("/"), maildir-style delivery is carried out, otherwise the
+/*     path is assumed to specify a mailbox file.
+/*
+/*     Note that \fBvirtual_mailbox_base\fR is unconditionally prepended
+/*     to this path.
+/* .IP \fBvirtual_minimum_uid\fR
+/*     Specifies a minimum uid that will be accepted as a return from
+/*     a \fBvirtual_uid_maps\fR lookup. Returned values less than this
+/*     will be rejected, and the message will be deferred.
+/* .IP \fBvirtual_uid_maps\fR
+/*     Recipients are looked up in this map to determine the UID to be
+/*     used when writing to the target mailbox.
+/* .IP \fBvirtual_gid_maps\fR
+/*     Recipients are looked up in this map to determine the GID to be
+/*     used when writing to the target mailbox.
+/* .SH "Locking controls"
+/* .ad
+/* .fi
+/* .IP \fBmailbox_delivery_lock\fR
+/*     How to lock UNIX-style mailboxes: one or more of \fBflock\fR,
+/*     \fBfcntl\fR or \fBdotlock\fR.
+/* .IP \fBdeliver_lock_attempts\fR
+/*     Limit the number of attempts to acquire an exclusive lock
+/*     on a mailbox file.
+/* .IP \fBdeliver_lock_delay\fR
+/*     Time in seconds between successive attempts to acquire
+/*     an exclusive lock on a mailbox file.
+/* .IP \fBstale_lock_time\fR
+/*     Limit the time after which a stale lockfile is removed.
+/* .SH "Resource controls"
+/* .ad
+/* .fi
+/* .IP \fBvirtual_destination_concurrency_limit\fR
+/*     Limit the number of parallel deliveries to the same domain.
+/*     The default limit is taken from the
+/*     \fBdefault_destination_concurrency_limit\fR parameter.
+/* .IP \fBvirtual_destination_recipient_limit\fR
+/*     Limit the number of recipients per message delivery.
+/*     The default limit is taken from the
+/*     \fBdefault_destination_recipient_limit\fR parameter.
+/* HISTORY
+/* .ad
+/* .fi
+/*     This agent was originally based on the local delivery
+/*     agent. Modifications mainly consisted of removing code that wasn't
+/*     applicable or wasn't safe in this context (aliases, .forwards,
+/*     program aliases).
+/*
+/*     The \fBDelivered-To:\fR header appears in the \fBqmail\fR system
+/*     by Daniel Bernstein.
+/*
+/*     The \fImaildir\fR structure appears in the \fBqmail\fR system
+/*     by Daniel Bernstein.
+/* SEE ALSO
+/*     bounce(8) non-delivery status reports
+/*     syslogd(8) system logging
+/*     qmgr(8) queue manager
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Andrew McNamara
+/*     andrewm@connect.com.au
+/*     connect.com.au Pty. Ltd.
+/*     Level 3, 213 Miller St
+/*     North Sydney 2060, NSW, Australia
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <iostuff.h>
+#include <set_eugid.h>
+#include <dict.h>
+
+/* Global library. */
+
+#include <mail_queue.h>
+#include <recipient_list.h>
+#include <deliver_request.h>
+#include <deliver_completed.h>
+#include <mail_params.h>
+#include <mail_conf.h>
+#include <mail_params.h>
+
+/* Single server skeleton. */
+
+#include <mail_server.h>
+
+/* Application-specific. */
+
+#include "virtual.h"
+
+ /*
+  * Tunable parameters.
+  */
+char   *var_mailbox_maps;
+char   *var_uid_maps;
+char   *var_gid_maps;
+int     var_virt_minimum_uid;
+char   *var_virt_mailbox_base;
+char   *var_mailbox_lock;
+
+ /*
+  * Mappings.
+  */
+MAPS   *virtual_mailbox_maps;
+MAPS   *virtual_uid_maps;
+MAPS   *virtual_gid_maps;
+
+ /*
+  * Bit masks.
+  */
+int     virtual_mbox_lock_mask;
+
+/* local_deliver - deliver message with extreme prejudice */
+
+static int local_deliver(DELIVER_REQUEST *rqst, char *service)
+{
+    char   *myname = "local_deliver";
+    RECIPIENT *rcpt_end = rqst->rcpt_list.info + rqst->rcpt_list.len;
+    RECIPIENT *rcpt;
+    int     rcpt_stat;
+    int     msg_stat;
+    LOCAL_STATE state;
+    USER_ATTR usr_attr;
+
+    if (msg_verbose)
+       msg_info("local_deliver: %s from %s", rqst->queue_id, rqst->sender);
+
+    /*
+     * Initialize the delivery attributes that are not recipient specific.
+     * While messages are being delivered and while aliases or forward files
+     * are being expanded, this attribute list is being changed constantly.
+     * For this reason, the list is passed on by value (except when it is
+     * being initialized :-), so that there is no need to undo attribute
+     * changes made by lower-level routines. The alias/include/forward
+     * expansion attribute list is part of a tree with self and parent
+     * references (see the EXPAND_ATTR definitions). The user-specific
+     * attributes are security sensitive, and are therefore kept separate.
+     * All this results in a noticeable level of clumsiness, but passing
+     * things around by value gives good protection against accidental change
+     * by subroutines.
+     */
+    state.level = 0;
+    deliver_attr_init(&state.msg_attr);
+    state.msg_attr.queue_name = rqst->queue_name;
+    state.msg_attr.queue_id = rqst->queue_id;
+    state.msg_attr.fp = rqst->fp;
+    state.msg_attr.offset = rqst->data_offset;
+    state.msg_attr.sender = rqst->sender;
+    state.msg_attr.relay = service;
+    state.msg_attr.arrival_time = rqst->arrival_time;
+    RESET_USER_ATTR(usr_attr, state.level);
+    state.request = rqst;
+
+    /*
+     * Iterate over each recipient named in the delivery request. When the
+     * mail delivery status for a given recipient is definite (i.e. bounced
+     * or delivered), update the message queue file and cross off the
+     * recipient. Update the per-message delivery status.
+     */
+    for (msg_stat = 0, rcpt = rqst->rcpt_list.info; rcpt < rcpt_end; rcpt++) {
+       state.msg_attr.recipient = rcpt->address;
+       rcpt_stat = deliver_recipient(state, usr_attr);
+       if (rcpt_stat == 0)
+           deliver_completed(state.msg_attr.fp, rcpt->offset);
+       msg_stat |= rcpt_stat;
+    }
+
+    return (msg_stat);
+}
+
+/* local_service - perform service for client */
+
+static void local_service(VSTREAM *stream, char *service, char **argv)
+{
+    DELIVER_REQUEST *request;
+    int     status;
+
+    /*
+     * Sanity check. This service takes no command-line arguments.
+     */
+    if (argv[0])
+       msg_fatal("unexpected command-line argument: %s", argv[0]);
+
+    /*
+     * This routine runs whenever a client connects to the UNIX-domain socket
+     * that is dedicated to local mail delivery service. What we see below is
+     * a little protocol to (1) tell the client that we are ready, (2) read a
+     * delivery request from the client, and (3) report the completion status
+     * of that request.
+     */
+    if ((request = deliver_request_read(stream)) != 0) {
+       status = local_deliver(request, service);
+       deliver_request_done(stream, request, status);
+    }
+}
+
+/* pre_accept - see if tables have changed */
+
+static void pre_accept(char *unused_name, char **unused_argv)
+{
+    if (dict_changed()) {
+       msg_info("table has changed -- exiting");
+       exit(0);
+    }
+}
+
+/* post_init - post-jail initialization */
+
+static void post_init(char *unused_name, char **unused_argv)
+{
+
+    /*
+     * Drop privileges most of the time.
+     */
+    set_eugid(var_owner_uid, var_owner_gid);
+
+    virtual_mailbox_maps =
+       maps_create(VAR_VIRT_MAILBOX_MAPS, var_mailbox_maps,
+                   DICT_FLAG_LOCK);
+
+    virtual_uid_maps =
+       maps_create(VAR_VIRT_UID_MAPS, var_uid_maps, DICT_FLAG_LOCK);
+
+    virtual_gid_maps =
+       maps_create(VAR_VIRT_UID_MAPS, var_gid_maps, DICT_FLAG_LOCK);
+
+    virtual_mbox_lock_mask = mbox_lock_mask(var_mailbox_lock);
+}
+
+/* main - pass control to the single-threaded skeleton */
+
+int     main(int argc, char **argv)
+{
+    static CONFIG_INT_TABLE int_table[] = {
+       VAR_VIRT_MINUID, DEF_VIRT_MINUID, &var_virt_minimum_uid, 1, 0,
+       0,
+    };
+    static CONFIG_STR_TABLE str_table[] = {
+       VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_mailbox_maps, 0, 0,
+       VAR_VIRT_UID_MAPS, DEF_VIRT_UID_MAPS, &var_uid_maps, 0, 0,
+       VAR_VIRT_GID_MAPS, DEF_VIRT_GID_MAPS, &var_gid_maps, 0, 0,
+       VAR_VIRT_MAILBOX_BASE, DEF_VIRT_MAILBOX_BASE, &var_virt_mailbox_base, 0, 0,
+       VAR_MAILBOX_LOCK, DEF_MAILBOX_LOCK, &var_mailbox_lock, 1, 0,
+       0,
+    };
+
+    single_server_main(argc, argv, local_service,
+                      MAIL_SERVER_INT_TABLE, int_table,
+                      MAIL_SERVER_STR_TABLE, str_table,
+                      MAIL_SERVER_POST_INIT, post_init,
+                      MAIL_SERVER_PRE_ACCEPT, pre_accept,
+                      0);
+}
diff --git a/postfix/src/virtual/virtual.h b/postfix/src/virtual/virtual.h
new file mode 100644 (file)
index 0000000..1443bc8
--- /dev/null
@@ -0,0 +1,134 @@
+/*++
+/* NAME
+/*     virtual 3h
+/* SUMMARY
+/*     virtual mail delivery
+/* SYNOPSIS
+/*     #include "virtual.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <unistd.h>
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <deliver_request.h>
+#include <maps.h>
+#include <mbox_conf.h>
+
+ /*
+  * Mappings.
+  */
+extern MAPS *virtual_mailbox_maps;
+extern MAPS *virtual_uid_maps;
+extern MAPS *virtual_gid_maps;
+
+ /*
+  * User attributes: these control the privileges for delivery to external
+  * commands, external files, or mailboxes, and the initial environment of
+  * external commands.
+  */
+typedef struct USER_ATTR {
+    uid_t   uid;                       /* file/command access */
+    gid_t   gid;                       /* file/command access */
+    char   *mailbox;                   /* mailbox file or directory */
+} USER_ATTR;
+
+ /*
+  * Critical macros. Not for obscurity, but to ensure consistency.
+  */
+#define RESET_USER_ATTR(usr_attr, level) { \
+       usr_attr.uid = 0; usr_attr.gid = 0; usr_attr.mailbox = 0; \
+       if (msg_verbose) \
+           msg_info("%s[%d]: reset user_attr", myname, level); \
+    }
+
+ /*
+  * The delivery attributes are inherited from files, from aliases, and from
+  * whatnot. Some of the information is changed on the fly. DELIVER_ATTR
+  * structres are therefore passed by value, so there is no need to undo
+  * changes.
+  */
+typedef struct DELIVER_ATTR {
+    int     level;                     /* recursion level */
+    VSTREAM *fp;                       /* open queue file */
+    char   *queue_name;                        /* mail queue id */
+    char   *queue_id;                  /* mail queue id */
+    long    offset;                    /* data offset */
+    char   *sender;                    /* taken from envelope */
+    char   *recipient;                 /* taken from resolver */
+    char   *user;                      /* recipient lookup handle */
+    char   *delivered;                 /* for loop detection */
+    char   *relay;                     /* relay host */
+    long    arrival_time;              /* arrival time */
+} DELIVER_ATTR;
+
+extern void deliver_attr_init(DELIVER_ATTR *);
+extern void deliver_attr_dump(DELIVER_ATTR *);
+
+#define FEATURE_NODELIVERED    (1<<0)  /* no delivered-to */
+
+ /*
+  * Rather than schlepping around dozens of arguments, here is one that has
+  * all. Well, almost. The user attributes are just a bit too sensitive, so
+  * they are passed around separately.
+  */
+typedef struct LOCAL_STATE {
+    int     level;                     /* nesting level, for logging */
+    DELIVER_ATTR msg_attr;             /* message attributes */
+    DELIVER_REQUEST *request;          /* as from queue manager */
+} LOCAL_STATE;
+
+ /*
+  * Bundle up some often-user attributes.
+  */
+#define BOUNCE_ATTR(attr)      attr.queue_id, attr.recipient, attr.relay, \
+                                       attr.arrival_time
+#define SENT_ATTR(attr)                attr.queue_id, attr.recipient, attr.relay, \
+                                       attr.arrival_time
+#define COPY_ATTR(attr)                attr.sender, attr.delivered, attr.fp
+
+#define MSG_LOG_STATE(m, p) \
+       msg_info("%s[%d]: recip %s deliver %s", m, \
+                p.level, \
+               p.msg_attr.recipient ? p.msg_attr.recipient : "", \
+               p.msg_attr.delivered ? p.msg_attr.delivered : "")
+
+ /*
+  * "inner" nodes of the delivery graph.
+  */
+extern int deliver_recipient(LOCAL_STATE, USER_ATTR);
+
+ /*
+  * "leaf" nodes of the delivery graph.
+  */
+extern int deliver_mailbox(LOCAL_STATE, USER_ATTR, int *);
+extern int deliver_file(LOCAL_STATE, USER_ATTR, char *);
+extern int deliver_maildir(LOCAL_STATE, USER_ATTR);
+extern int deliver_unknown(LOCAL_STATE);
+
+ /*
+  * Mailbox lock protocol.
+  */
+extern int virtual_mbox_lock_mask;
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/