# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
- STATUS=$EX_TEMPFAIL
# Clean up when done or when aborting.
- trap "rm -f in.$$; exit $STATUS" 0 1 2 3 15
-
- quit() { STATUS=${1-$?}; exit; }
+ trap "rm -f in.$$" 0 1 2 3 15
# Start processing.
- cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; quit $EX_TEMPFAIL; }
+ cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
- cat >in.$$ || { echo Cannot save mail to file; quit $EX_TEMPFAIL; }
+ cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
- # filter <in.$$ || { echo Message content rejected; quit $EX_UNAVAILABLE; }
+ # filter <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
$SENDMAIL "$@" <in.$$
- STATUS=$?
+ exit $?
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
core instead if issuing an error message. This is what I
get for accepting code that I cannot test myself.
-20001220
-
- Feature: merged in Andrew McNamara's virtual delivery agent
- (a table-driven agent that does not require recipients to
- have UNIX accounts, and that implements a safe subset of
- the default local delivery agent). Files: virtual/*.
-
20001221
Code cleanup: configuration parameters that are $name
Bugfix: soft errors in client hostname lookups would be
treated as hard errors. Fix by Michael Herrmann
(informatik.tu-muenchen.de). File: smtpd/smtpd_peer.c.
+
+20010110
+
+ Bugfix: the mkdir() EEXIST race condition workaround was
+ not complete. Matthias Andree, Daniel Roesen. Files:
+ global/mail_queue.c, util/make_dirs.c.
+
+20010111
+
+ Portability: IRIX 6.5.10 defines sa_len as a macro, causing
+ a name collision with a variable used by Postfix. Roberto
+ Totaro, enigma.ethz.ch. File: smtpstone/smtp-source.c.
+
+20010116
+
+ Bugfix: REJECT by header/body_checks was flagged in smtpd
+ as a bounce, should be policy, in order to make postmaster
+ notifications more consistent. File: smtpd/smtpd.c.
+
+ Merged updated chroot setup procedure by Matthias Andree.
+ Files: examples/chroot-setup/LINUX2.
+
+20010117
+
+ Formatting: changed the seconds and days formats in the
+ "your mail is delayed" text so that it does not switch to
+ scientific notation. File: bounce/bounce_notify_util.c.
+
+20010119
+
+ Feature: SASL support for the LMTP client. Recent CYRUS
+ software requires this for Postfix over TCP sockets.
+ This was just a cloning operation.
+
+20010120
+
+ Bugfix: the 20001005 revised fallback_relay support caused
+ Postfix to send mail to the fallback even when the local
+ machine was an MX host for the final destination. Result:
+ mailer loop. Found by Laurent Wacrenier (teaser.fr). Files:
+ smtp/smtp_connect.c, smtp/smtp_addr.c.
+
+20010121
+
+ Workaround: Lotus Domino 5.0.4 violates RFC 2554 and replies
+ to EHLO with AUTH=LOGIN. File: smtp/smtp_proto.c.
-BEGIN WARNING
-=============
+[Based on information that was provided by Amous Gouaux]
-The information in this file is outdated. The Postfix LMTP server
-can now make connections over UNIX-domain sockets.
+Postfix LMTP support
+====================
+
+LMTP stands for Local Mail Transfer Protocol, and is detailed in
+RFC2033. This protocol is used to communicate with the final
+delivery agent, which may be on the local host or a remote host.
+
+This protocol opens up interesting possibilities: one Postfix front
+end system can drive multiple mailbox back end systems over LMTP.
+As the mail load increases you add Postfix front end systems and
+LMTP mailbox back end systems. You can use LDAP or mysql to share
+the user database among the front end and back end systems.
+
+Postfix LMTP support is based on a modified version of the Postfix
+SMTP client. The initial version was by Philip A. Prindeville of
+Mirapoint, Inc., USA. This code was modified further by Amos Gouaux
+of University of Texas at Dallas, Richardson, USA. Wietse Venema
+reduced the code to its present shape.
+
+
+Overview
+========
+
+Most of the examples in this document involve the CMU Cyrus IMAP/POP
+server, available from:
+
+ http://asg.web.cmu.edu/cyrus/
-With connections over TCP sockets, some Cyrus implementations insist
-on SASL-style authentication, which is not supported by the Postfix
-LMTP client. In that case, use UNIX-domain sockets instead.
+While certainly not the only application that could make use of LMTP,
+it tends to be the most discussed. These examples are based on the
+forthcoming Cyrus 2.0.10, at least at the time of writing. The 2.x
+branch of Cyrus places greater emphasis on LMTP delivery than the
+previous releases. Those using older releases of Cyrus can find a
+discussion in the appendix of this document.
+
+There are a variety of ways LMTP delivery can be configured in
+Postfix. The two basic flavors are delivery over UNIX-domain sockets
+and delivery over TCP sockets. Both flavors can be specified in
+either the Postfix main.cf or in a transport map. The best approach
+to use depends upon the arrangement of your servers and the desired
+level of parallelization. Please be sure to study this entire
+document as there are trade-offs in convenience and performance with
+these different approaches.
The precise syntax for UNIX-domain and TCP connection endpoints is
given in the lmtp(8) manual page.
+
+Using main.cf configuration
+===========================
+
+This is the simplest LMTP configuration. The settings
+local_transport, mailbox_transport, and fallback_transport can
+support the following connections:
+
+1. LMTP over TCP sockets.
+
+ mailbox_transport = lmtp
+
+ Instead of delivering local mail to a mail box such as
+ /var/mail/$user, a connection will be made over TCP to an LMTP
+ server. Currently the default port for this connection is 24,
+ but this can be customized in the "/etc/services" file.
+
+ NOTE:
+
+ With connections over TCP sockets, some Cyrus implementations
+ insist on SASL-style authentication, which is not currently
+ supported by the Postfix LMTP client. See the examples below
+ for additional details.
+
+
+2. LMTP over UNIX-domain sockets.
+
+ mailbox_transport = lmtp:unix:/path/name
+
+ In this case the LMTP connection will be made over a UNIX-domain
+ socket. This "/path/name" should be the socket created by the
+ LMTP server on the local machine.
+
+ NOTE 1:
+
+ If you configured Cyrus using the "--with-libwrap" option, be
+ sure to allow access to the "lmtpd" service from "0.0.0.0".
+ Otherwise LMTP deliveries over UNIX-domain sockets will be
+ blocked. See the examples below for more on using libwrap.
+
+ NOTE 2:
+
+ If you run the lmtp client chrooted, the interpretation of
+ the /path/name is relative to the Postfix queue directory
+ (typically, /var/spool/postfix).
+
+ NOTE 3:
+
+ By default, the Postfix LMTP client does not run chrooted.
+ With LMTP delivery to the local machine there is no good
+ reason to run the Postfix LMTP client chrooted.
+
+
Examples:
+1. LMTP over UNIX-domain sockets.
+
+ To utilize UNIX-domain sockets for the communication between
+ Postfix and Cyrus, the corresponding configuration files should
+ look something like this:
+
+ /etc/cyrus.conf:
+
+ SERVICES {
+ ...
+ lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
+ ...
+ }
+
+ /etc/postfix/main.cf:
+
+ mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
+
+ In this case, mail that is resolved to be local will be delivered
+ to the Cyrus lmtpd server via the socket "/var/imap/socket/lmtp".
+
+ If you configured Cyrus using the "--with-libwrap" option, you
+ will need the following:
+
+ /etc/hosts.allow:
+
+ lmtpd : 0.0.0.0
+
+2. LMTP over TCP sockets.
+
+ For this example, suppose the following files are configured
+ thusly:
+
+ /etc/cyrus.conf:
+
+ SERVICES {
+ ...
+ lmtp cmd="lmtpd -a" listen="127.0.0.1:lmtp" prefork=0
+ ...
+ }
+
+XXX does this mean that connections will be accepted only on 127.0.0.1?
+
+ /etc/services:
+
+ lmtp 2003/tcp
+
+ /etc/postfix/main.cf:
+
+ mailbox_transport = lmtp
+
+ /etc/postfix/master.cf:
+
+ lmtp unix - - n - - lmtp
+
+ Mail that Postfix resolves to be local will be delivered via TCP
+ to the Cyrus LMTP server. Postfix will make a connection to port
+ 2003 on the local host, subsequently transmitting the message to
+ the lmtpd server managed by the Cyrus master process. Since
+ Postfix does not currently support LMTP-AUTH, the "-a" lmtpd
+ option is required.
+
+ CAUTION:
+
+ If you run lmtpd with the "-a" option, be certain that you
+ restrict what systems can connect to this service. This can
+ be done in either one of two ways:
+
+ a. Compile Cyrus with libwrap support, configuring
+ "/etc/hosts.allow" to restrict access to this service to
+ only your mail server.
+
+ b. In the cyrus.conf file, for the "listen" argument to the
+ "lmtp" service, specify the address (in this case
+ localhost), that the service should bind to. This can
+ also be convenient if you have a private network between
+ your Postfix server and your Cyrus server.
+
+ If neither of these actions are taken, anybody will be able
+ to drop junk into your Cyrus message store!
+
+
+3. LMTP over TCP sockets, using hosts.allow.
+
+ While similar to the previous example, this one varies in how the
+ lmtpd service is protected from unauthorized use. Instead of
+ binding the lmtpd service to a specific Internet address, access
+ will be controlled using the "/etc/hosts.allow" tcp_wrappers
+ configuration file. The tcp_wrappers package is available from:
+
+ ftp://ftp.porcupine.org/pub/security/index.html
+
+ To take advantage of tcp_wrappers, Cyrus will need to be
+ configured using the "--with-libwrap" option. See the Cyrus
+ documentation for more details.
+
+ Here are excerpts of the pertinent files:
+
+ /etc/hosts.allow:
+
+ lmtpd : localhost : ALLOW
+ lmtpd : ALL@ALL : DENY
+
+ /etc/cyrus.conf:
+
+ SERVICES {
+ ...
+ lmtp cmd="lmtpd -a" listen="lmtp" prefork=0
+ ...
+ }
+
+ /etc/services:
+
+ lmtp 2003/tcp
+
+ /etc/postfix/main.cf:
+
+ mailbox_transport = lmtp
+
+ The syntax shown in the hosts.allow excerpt above is valid if
+ tcp_wrappers is compiled using a "make" argument of:
+
+ STYLE=-DPROCESS_OPTIONS
+
+ See the tcp_wrappers hosts_options(5) man page for more details.
+
+
+Using transport map configuration
+=================================
+
+This approach is quite similar to specifying the LMTP service in the
+Postfix main.cf configuration file. However, now we will use a
+transport map to route mail to the appropriate LMTP server. Why
+might this approach be useful? This could be handy if you wish to
+route mail for multiple domains to their respective mail retrieval
+(IMAP/POP) server. Example:
+
/etc/postfix/transport:
+
domain1.name lmtp1:unix:/path/name
domain2.name lmtp2:lmtp2host
/etc/postfix/master.cf:
+
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
-The first example (domain1) uses UNIX-domain connections, the second
-example (domain2) uses TCP.
+ /etc/postfix/main.cf:
-For optimal use of connection caching, specify separate mail delivery
-transports for each domain that receives mail via LMTP:
+ transport_maps = hash:/etc/postfix/transport
-END WARNING
-===========
+Instead of "hash", use the map type of your choice. Some systems use
+"dbm" instead. Use "postconf -m" to find out what map types are
+supported.
-Postfix LMTP support
-====================
-Postfix LMTP support is based on a modified version of the Postfix
-SMTP client. The initial version was by Philip A. Prindeville of
-Mirapoint, Inc., USA. This code was modified further by Amos Gouaux
-of University of Texas at Dallas, Richardson, USA. Wietse Venema
-reduced the code to its present shape.
+Performance considerations
+==========================
-Postfix can be configured to talk to a local or remote LMTP server.
-Most people will run the LMTP server on the same machine that runs
-Postfix. However, a remote LMTP server can be useful if Postfix
-runs on mail relay server(s) that feed incoming mail directly to
-the appropriate mailbox server(s). This way, mailbox servers do
-not need to run an SMTP server at all. Tidy all the way around.
+Hopefully the preceding discussion has seemed pretty straight
+forward. Now things get interesting. After reading the following
+you will see that there are more factors to consider when setting up
+LMTP services.
-Configuring the mailbox server (local or remote)
-================================================
-On the mailbox server, in this case a CMU Cyrus imapd/popd server,
-add the following to /etc/services:
+Single instance message store
+=============================
- pop3 110/tcp # Cyrus POP3
- imap 143/tcp # Cyrus IMAP4
- lmtp 24/tcp
+Presently this topic is more pertinent to sites running Cyrus, but
+may be a factor with other applications as well.
-Next, put the following in /etc/inetd.conf:
+Since 1.6.22, Cyrus has had the feature that if a message containing
+multiple recipients is received via the LMTP protocol, and all these
+recipients were on the same Cyrus partition, only one instance of
+this message would be written to the file system. The other
+recipients would then see a hard link of this single instance.
+Depending on your user base, this can be considerable motivation to
+using LMTP.
- lmtp stream tcp nowait cyrus /usr/sbin/tcpd /usr/local/cyrus/bin/deliver -e -l
+However, there is a catch: currently the Postfix local delivery
+mechanisms are only designed to handle one recipient at a time, which
+in most cases is more than adequate. So, if you wish to support
+single instance message store delivery, you will have to use a
+transport table to map these users to the appropriate LMTP
+destination.
-/usr/sbin/tcpd is from the tcp_wrappers package. You want this to
-make sure only your mail relay(s) can talk to the LMTP server.
-Postfix by default does multiple deliveries per LMTP session
-(connection caching), so do not worry about the overhead of
-tcp_wrapping the LMTP port.
+While the simplest thing to do would be to list the entire domain in
+the transport map for LMTP delivery, this by-passes alias expansion
+for otherwise local addresses. If the site is to run software via
+aliases, like most Mailing List Management (MLM) software, a more
+complex solution is required. Fortunately, a virtual table should do
+the trick.
-On some systems, tcpd is built into inetd, so you do not have to
-specify tcpd in the inetd.conf file. Instead of tcpd/inetd, xinetd
-can do a similar job of logging and access control.
+As an example, suppose we wanted to support single instance message
+store delivery for the domain "example.org". The configuration files
+for this domain could look something like this:
+
+ /etc/postfix/virtual:
+
+ mlist@example.org mlist@localhost
+
+ /etc/postfix/transport:
+
+ example.org lmtp:unix:/var/imap/socket/lmtp
-Configuring Postfix
-===================
+ /etc/postfix/aliases:
-Similar changes to /etc/services:
+ mlist: "|/path/to/mlm/software"
- lmtp 24/tcp
+ /etc/postfix/master.cf:
-You may have to add the following entry to /etc/postfix/master.cf:
+ lmtp unix - - n - - lmtp
- lmtp unix - - n - - lmtp
+ /etc/postfix/main.cf:
-NOTE: Root privileges are not necessary!
+ mydestination = localhost, $myhostname, $mydomain
+ virtual_maps = hash:/etc/postfix/virtual
+ transport_maps = hash:/etc/postfix/transport
+ alias_maps = hash:/etc/postfix/aliases
+ alias_database = hash:/etc/postfix/aliases
-Put this in /etc/postfix/transport:
+ /etc/cyrus.conf:
- inbox.domain.org lmtp:inbox.domain.org
+ SERVICES {
+ ...
+ lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
+ ...
+ }
-Naturally, this means we also need in /etc/postfix/main.cf:
+Breaking things down, we begin with the address "mlist@example.org",
+which represents a mailing list. By placing an entry in the virtual
+map to direct this mail to "mlist@localhost", we can override the
+transport map that would by default route all "@example.org" mail to
+a LMTP server via a UNIX-domain socket.
- transport_maps = hash:/etc/postfix/transport
+To summarize, all mail that is to be processed by an alias entry must
+first be diverted with a virtual table entry so that it does not fall
+into the more general routing established by the transport table.
-Instead of "hash", use the map type of your choice. Some systems
-use "dbm" instead. Use "postconf -m" to find out what map types
-are supported.
Improving connection caching performance
========================================
configuring a separate mail delivery transport for each LMTP server:
/etc/postfix/master.cf:
+
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
. . . . . . . .
mail lmtp2 transport for the LMTP server #2, and so on.
/etc/postfix/transport:
+
foo.com lmtp1:lmtp1host
bar.com lmtp2:lmtp2host
+
+
+Appendix: Older Cyrus versions
+==============================
+
+First of all, if you are using a Cyrus 2.x version prior to 2.0.10,
+it would be good to upgrade. The previous 2.x releases were beta
+releases, and numerous bug fixes and enhancements have been
+incorporated into the 2.0.10 release.
+
+Further back, 1.6.24 was the last pre-2.x production release.
+(Actually, there was a 1.6.25-BETA, but it is uncertain whether this
+will be released officially as CMU is now focusing support on the 2.x
+branch.) The following discussion touches on how to configure the
+Postfix LMTP facilities with Cyrus 1.6.24.
+
+One of the significant differences between Cyrus 1.x and 2.x is the
+inclusion of the "master" process in 2.x. This "master" process is
+responsible for running the various components of Cyrus, such as
+imapd, pop3d, and lmtpd. Prior to 2.x, these services were managed
+by inetd, the Internet services daemon.
+
+To utilize LMTP delivery with Cyrus 1.6.24, the first thing to do is
+configure inetd. This involves the following file edits:
+
+ /etc/services:
+
+ lmtp 2003/tcp
+
+ /etc/inetd.conf:
+
+ lmtp stream tcp nowait cyrus /usr/sbin/tcpd /usr/cyrus/bin/deliver -e -l
+
+ /etc/hosts.allow:
+
+ deliver : localhost : ALLOW
+ deliver : ALL@ALL : DENY
+
+The "/usr/sbin/tcpd" is from the tcp_wrappers package, which is
+discussed in the example "LMTP over TCP sockets, using hosts.allow."
+It is important that you wrap this LMTP port to protect it from
+unauthorized access.
+
+On some systems, tcpd is built into inetd, so you do not have to
+specify tcpd in the inetd.conf file. Instead of tcpd/inetd, xinetd
+can do a similar job of logging and access control.
+
+Now comes the Postfix configuration. Basically, the Cyrus 2.x
+discussions regarding LMTP delivery over TCP are also applicable to
+Cyrus 1.x, with the exception of the "/etc/cyrus.conf" file. A
+typical Postfix configuration might look like this:
+
+ /etc/postfix/master.cf:
+
+ lmtp unix - - n - - lmtp
+
+ /etc/postfix/main.cf:
+
+ mailbox_transport = lmtp
+
+It is also possible to use the transport map to route mail to your
+Cyrus 1.6.24 LMTP server:
+
+ /etc/postfix/transport:
+
+ domain1.name lmtp1:lmtp1host
+ domain2.name lmtp2:lmtp2host
+
+ /etc/postfix/master.cf:
+
+ lmtp1 unix - - n - - lmtp
+ lmtp2 unix - - n - - lmtp
+
+ /etc/postfix/main.cf:
+
+ transport_maps = hash:/etc/postfix/transport
+
+If you have read the discussion covering the Cyrus 2.x installation,
+you will notice the one significant difference with the Postfix
+configuration is the lack of mention of the UNIX-domain sockets.
+That is because delivery over UNIX-domain sockets is new with Cyrus
+2.x, yet another reason to upgrade. :-)
+
+
+
+# Local Variables:
+# mode: text
+# mode: flyspell
+# fill-column: 69
+# End:
+
+
+
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/virtual # src/base64 proto man html
+ src/nqmgr src/spawn src/flush # proto man html
default: update
+REJECT by header/body_checks are now flagged as policy violations
+rather than bounces, for consistency in postmaster notifications.
+
Major changes with snapshot-20001217
====================================
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
===============================================================
-Do not use this code. The Postfix SASL support is based on the
-Cyrus SASL library, which has not enough documentation about how
-the software is supposed to work. It is not clear if the code is
-safe enough for security-critical applications.
+This code is not blessed by Wietse.
+
+People who go to the trouble of installing Postfix may have the
+expectation that Postfix is more secure than some other mailers.
+
+With SASL authentication enabled in the Postfix SMTP client and
+SMTP server, Postfix becomes no more secure than other mail systems
+that use the Cyrus SASL library.
+
+The Cyrus SASL library has too little documentation about how the
+software is supposed to work; and it is too much code to be used
+in a security-sensitive program such as an SMTP client or server.
+
+However, you are pretty much required to build with SASL support
+if you are going to use the LMTP interface of the Cyrus delivery
+agent. This interface is much faster than forking a new process
+for every message delivery.
Postfix+SASL 1.5.5 appears to work on RedHat 6.1 (pwcheck_method
set to shadow or sasldb), Solaris 2.7 (pwcheck_method set to shadow
SASL. Note also that the Cyrus SASL documentation says that it is
pointless to enable that if you use "sasldb" for "pwcheck_method".
-SASL is a lot of complex code. In a future version the Postfix SASL
-code is likely to be put outside the SMTP server.
-
Introduction
============
non-standard SASL LOGIN authentication method. To enable this
authentication method, specify ``./configure --enable-login''.
+Reportedly, older Microsoft software mis-implements the AUTH
+protocol, and requires that the server replies to EHLO with
+"250-AUTH=stuff..." instead of "250-AUTH stuff...". To accomodate
+such clients, set "allow_broken_auth_clients = yes" in the main.cf
+file.
+
Building Postfix with SASL authentication support
=================================================
+++ /dev/null
-[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:
---/---
-
-
--- /dev/null
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
+# This file contains example settings of Postfix configuration
+# parameters that control compatibility with broken software.
+
+# The ignore_mx_lookup_error parameter controls what happens when a
+# name server fails to respond to an MX lookup request. By default,
+# Postfix defers delivery and tries again after some delay. Specify
+# "ignore_mx_lookup_error = yes" to force an A record lookup instead.
+#
+ignore_mx_lookup_error = no
+
+# The smtp_always_send_ehlo parameter specifies that the SMTP client
+# should always send EHLO at the start of an SMTP session.
+#
+# By default, Postfix sends EHLO only when the word "ESMTP" appears
+# in the server greeting banner (example: 220 spike.porcupine.org
+# ESMTP Postfix).
+#
+smtp_always_send_ehlo = no
+
+# The smtp_never_send_ehlo parameter specifies that the SMTP client
+# should never send EHLO at the start of an SMTP session.
+#
+# By default, Postfix sends EHLO whenever the word "ESMTP" appears
+# in the server greeting banner (example: 220 spike.porcupine.org
+# ESMTP Postfix).
+#
+smtp_never_send_ehlo = no
+
+# The smtp_skip_4xx_greeting parameter controls what happens when
+# an SMTP server greets us with a 4XX status code (go away, try
+# again later).
+#
+# By default, Postfix moves on the the next mail exchanger. Specify
+# "smtp_skip_4xx_greeting = no" if Postfix should defer delivery
+# immediately.
+#
+smtp_skip_4xx_greeting = yes
+
+# The smtp_skip_5xx_greeting parameter controls what happens when
+# an SMTP server greets us with a 5XX status code (go away, do not
+# try again later).
+#
+# By default, Postfix moves on the the next mail exchanger. Specify
+# "smtp_skip_5xx_greeting = no" if Postfix should bounce the mail
+# immediately.
+#
+smtp_skip_5xx_greeting = yes
+
+# The smtp_skip_quit_response parameter controls whether the SMTP
+# client waits for the response to the QUIT command. The default is
+# to not wait.
+#
+smtp_skip_quit_response = yes
+
+# The strict_rfc821_envelopes configuration parameter controls whether
+# the Postfix SMTP server requires that MAIL FROM and RCPT TO addresses
+# are specified within <>, and that MAIL FROM and RCPT TO addresses
+# do not contain RFC822-style comments or phrases. It's great to
+# stop SPAM mailers. But it also trips up broken peecee clients.
+#
+# By default, Postfix SMTPD allows RFC822 syntax in MAIL FROM and RCPT TO.
+#
+strict_rfc821_envelopes = no
#smtp_bind_address=111.222.333.444
# The smtp_skip_4xx_greeting parameter controls what happens when
-# an SMTP server greets us with a 4XX status code. By default, Postfix
-# backs off. Specify "smtp_skip_4xx_greeting = yes" to move on the
-# the next mail exchanger.
-#
-smtp_skip_4xx_greeting = no
+# an SMTP server greets us with a 4XX status code (go away, try
+# again later).
+#
+# By default, Postfix moves on the the next mail exchanger. Specify
+# "smtp_skip_4xx_greeting = no" if Postfix should defer delivery
+# immediately.
+#
+smtp_skip_4xx_greeting = yes
+
+# The smtp_skip_5xx_greeting parameter controls what happens when
+# an SMTP server greets us with a 5XX status code (go away, do not
+# try again later).
+#
+# By default, Postfix moves on the the next mail exchanger. Specify
+# "smtp_skip_5xx_greeting = no" if Postfix should bounce the mail
+# immediately.
+#
+smtp_skip_5xx_greeting = yes
# The smtp_skip_quit_response parameter controls whether the SMTP
# client waits for the response to the QUIT command. The default is
#
smtpd_timeout = 300s
+# The strict_rfc821_envelopes configuration parameter controls whether
+# the Postfix SMTP server requires that MAIL FROM and RCPT TO addresses
+# are specified within <>, and that MAIL FROM and RCPT TO addresses
+# do not contain RFC822-style comments or phrases. It's great to
+# stop SPAM mailers. But it also trips up broken peecee clients.
+#
+# By default, Postfix SMTPD allows RFC822 syntax in MAIL FROM and RCPT TO.
+#
+strict_rfc821_envelopes = no
+
#
# TARPIT CONTROLS
#
#! /bin/sh
# LINUX2 - shell script to set up a Postfix chroot jail for Linux
-# Tested on SuSE Linux 5.3 (libc5) and 6.4 (glibc2.1)
+# Tested on SuSE Linux 5.3 (libc5) and 7.0 (glibc2.1)
-# Copyright (c) 2000 by Matthias Andree
+# Other testers reported as working:
+#
+# 2001-01-15 Debian sid (unstable)
+# Christian Kurz <shorty@getuid.de>
+
+# Copyright (c) 2000 - 2001 by Matthias Andree
# Redistributable unter the MIT-style license that follows:
# Abstract: "do whatever you want except hold somebody liable or change
# the copyright information".
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+# 2000-09-29
+# v0.1: initial release
+
+# 2000-12-05
+# v0.2: copy libdb.* for libnss_db.so
+# remove /etc/localtime in case it's a broken symlink
+# restrict find to maxdepth 1 (faster)
+
+# $Log: LINUX2,v $
+# Revision 1.4 2001/01/15 09:36:35 emma
+# add note it was successfully tested on Debian sid
+#
+
+CP="cp -p"
+
cond_copy() {
# find files as per pattern in $1
# if any, copy to directory $2
dir=`dirname "$1"`
pat=`basename "$1"`
- lr=`find "$dir" -name "$pat"`
+ lr=`find "$dir" -maxdepth 1 -name "$pat"`
if test ! -d "$2" ; then exit 1 ; fi
- if test "x$lr" != "x" ; then cp -p $1 "$2" ; fi
+ if test "x$lr" != "x" ; then $CP $1 "$2" ; fi
}
set -e
# find localtime (SuSE 5.3 does not have /etc/localtime)
lt=/etc/localtime
if test ! -f $lt ; then lt=/usr/lib/zoneinfo/localtime ; fi
+if test ! -f $lt ; then lt=/usr/share/zoneinfo/localtime ; fi
if test ! -f $lt ; then echo "cannot find localtime" ; exit 1 ; fi
-cp -p -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
-cp -p -f /etc/host.conf /etc/hosts /etc/passwd etc
+rm -f etc/localtime
+
+# copy localtime and some other system files into the chroot's etc
+$CP -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
+$CP -f /etc/host.conf /etc/hosts /etc/passwd etc
ln -s -f /etc/localtime usr/lib/zoneinfo
-cond_copy '/lib/libnss_*' lib
-cond_copy '/lib/libresolv*' lib
\ No newline at end of file
+# copy required libraries into the chroot
+cond_copy '/lib/libnss_*.so*' lib
+cond_copy '/lib/libresolv.so*' lib
+cond_copy '/lib/libdb.so*' lib
+
+postfix reload
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 virtual.8.html
+ nqmgr.8.html spawn.8.html flush.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 \
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 >$@
<a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
<a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
+ <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Cor-
server. Used as backup if the <b>lmtp</b> service is not
found in <b>services</b>(4).
-<b>Resource</b> <b>controls</b>
- <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
- Should we cache the connection to the LMTP server?
- The effectiveness of cached connections will be
- determined by the number of LMTP servers in use,
- and the concurrency limit specified for the LMTP
+<b>Authentication</b> <b>controls</b>
+ <b>lmtp</b><i>_</i><b>enable</b><i>_</i><b>sasl</b><i>_</i><b>auth</b>
+ Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
+ (SASL). By default, Postfix is built without SASL
+ support.
LMTP(8) LMTP(8)
+ <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b>
+ Lookup tables with per-host or domain <i>name</i>:<i>password</i>
+ entries. No entry for a host means no attempt to
+ authenticate.
+
+ <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
+ Zero or more of the following.
+
+ <b>noplaintext</b>
+ Disallow authentication methods that use
+ plaintext passwords.
+
+ <b>noactive</b>
+ Disallow authentication methods that are
+ vulnerable to non-dictionary active attacks.
+
+ <b>nodictionary</b>
+ Disallow authentication methods that are
+ vulnerable to passive dictionary attack.
+
+ <b>noanonymous</b>
+ Disallow anonymous logins.
+
+<b>Resource</b> <b>controls</b>
+ <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
+ Should we cache the connection to the LMTP server?
+ The effectiveness of cached connections will be
+ determined by the number of LMTP servers in use,
+ and the concurrency limit specified for the LMTP
client. Cached connections are closed under any of
the following conditions:
destination via this mail delivery transport.
<i>transport</i> is the name of the service as specified
in the <b>master.cf</b> file. The default limit is taken
+
+
+
+ 3
+
+
+
+
+
+LMTP(8) LMTP(8)
+
+
from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
parameter.
value: s (seconds), m (minutes), h (hours), d (days) or w
(weeks).
-
-
- 3
-
-
-
-
-
-LMTP(8) LMTP(8)
-
-
<b>lmtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
Timeout for opening a connection to the LMTP
server. If no connection can be made within the
<b>lmtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
Timeout for sending the message content.
+
+
+
+ 4
+
+
+
+
+
+LMTP(8) LMTP(8)
+
+
<b>lmtp</b><i>_</i><b>data</b><i>_</i><b>done</b><i>_</i><b>timeout</b>
Timeout for sending the "<b>.</b>" command, and for
receiving the server response. When no response is
<b>AUTHOR(S)</b>
Wietse Venema
IBM T.J. Watson Research
-
-
-
- 4
-
-
-
-
-
-LMTP(8) LMTP(8)
-
-
P.O. Box 704
Yorktown Heights, NY 10598, USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
For example, allow <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a>-style address forms with
comments, like Sendmail does.
+ <b>allow</b><i>_</i><b>broken</b><i>_</i><b>auth</b><i>_</i><b>clients</b>
+ Support older Microsoft clients that mis-implement
+ the AUTH protocol, and that expect an EHLO response
+ of "250 AUTH=list" instead of "250 AUTH list".
+
<b>Content</b> <b>inspection</b> <b>controls</b>
<b>content</b><i>_</i><b>filter</b>
The name of a mail delivery transport that filters
Location of Postfix support commands (default:
<b>$program</b><i>_</i><b>directory</b>).
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
- Increment in verbose logging level when a remote
- host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
- parameter.
-
SMTPD(8) SMTPD(8)
+ <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+ Increment in verbose logging level when a remote
+ host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+ parameter.
+
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log-
reject responses. This can be useful for testing
purposes.
-<b>Resource</b> <b>controls</b>
- <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
- Limit the amount of memory in bytes used for the
- handling of partial input lines.
-
SMTPD(8) SMTPD(8)
+<b>Resource</b> <b>controls</b>
+ <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
+ Limit the amount of memory in bytes used for the
+ handling of partial input lines.
+
<b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
Limit the total size in bytes of a message, includ-
ing on-disk storage for envelope information.
Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
- <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
- Restrict what domain names can be used in <b>ETRN</b> com-
- mands, and what clients may issue <b>ETRN</b> commands.
-
-
4
SMTPD(8) SMTPD(8)
+ <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
+ Restrict what domain names can be used in <b>ETRN</b> com-
+ mands, and what clients may issue <b>ETRN</b> commands.
+
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
Allow untrusted clients to specify addresses with
sender-specified routing. Enabling this opens up
name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
restriction.
- <b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
- <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
-
SMTPD(8) SMTPD(8)
+ <b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
+ Server response when a client violates the
+ <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
+
<b>SEE</b> <b>ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> message canonicalization
<a href="master.8.html">master(8)</a> process manager
-
-
-
-
+++ /dev/null
-<html> <head> </head> <body> <pre>
-
-
-
-VIRTUAL(8) VIRTUAL(8)
-
-
-<b>NAME</b>
- virtual - Postfix virtual domain mail delivery agent
-
-<b>SYNOPSIS</b>
- <b>virtual</b> [generic Postfix daemon options]
-
-<b>DESCRIPTION</b>
- 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 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.
-
- 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 <b>virtual</b> delivery agent can deliver to UNIX-style mail-
- box file or to qmail-style maildir files. The pathname and
- delivery mailbox style are controlled by the <b>virtual</b><i>_</i><b>mail-</b>
- <b>box</b><i>_</i><b>base</b> and <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>maps</b> configuration parameters
- (see below).
-
- 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 > 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 are made with the user and group privileges
- that are listed in the tables specified with the <b>vir-</b>
- <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> and <b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b>, respectively.
-
- The <b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b> parameter specifies a lower bound
-
-
-
- 1
-
-
-
-
-
-VIRTUAL(8) VIRTUAL(8)
-
-
- on user ID values that may be specified in <b>vir-</b>
- <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>. Mail will not be delivered when a too low
- UID value is found.
-
-<b>STANDARDS</b>
- <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
-
-<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
- or maildir paths. This is a safety measure to
- ensure that an out of control map in <b>virtual</b><i>_</i><b>mail-</b>
- <b>box</b><i>_</i><b>maps</b> doesn't litter the filesystem with mail-
- boxes. While it could be set to "/", this setting
- 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 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 <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
-
-
-
- 2
-
-
-
-
-
-VIRTUAL(8) VIRTUAL(8)
-
-
- 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>.
-
- Use the command <b>postconf</b> <b>-m</b> to find out what lock-
- ing methods are available on your system.
-
- <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
- Limit the number of attempts to acquire an exclu-
- sive lock on a mailbox file.
-
- <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
- Time (default: 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.
-
-
-
- 3
-
-
-
-
-
-VIRTUAL(8) VIRTUAL(8)
-
-
-<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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-</pre> </body> </html>
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/virtual.8
+ man8/nqmgr.8 man8/spawn.8 man8/flush.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 \
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 $? >$@
RFC 1870 (Message Size Declaration)
RFC 2033 (LMTP protocol)
RFC 2197 (Pipelining)
+RFC 2554 (AUTH command)
.SH DIAGNOSTICS
.ad
.fi
.IP \fBlmtp_tcp_port\fR
The TCP port to be used when connecting to a LMTP server. Used as
backup if the \fBlmtp\fR service is not found in \fBservices\fR(4).
+.SH "Authentication controls"
+.IP \fBlmtp_enable_sasl_auth\fR
+Enable per-session authentication as per RFC 2554 (SASL).
+By default, Postfix is built without SASL support.
+.IP \fBlmtp_sasl_password_maps\fR
+Lookup tables with per-host or domain \fIname\fR:\fIpassword\fR entries.
+No entry for a host means no attempt to authenticate.
+.IP \fBlmtp_sasl_security_options\fR
+Zero or more of the following.
+.RS
+.IP \fBnoplaintext\fR
+Disallow authentication methods that use plaintext passwords.
+.IP \fBnoactive\fR
+Disallow authentication methods that are vulnerable to non-dictionary
+active attacks.
+.IP \fBnodictionary\fR
+Disallow authentication methods that are vulnerable to passive
+dictionary attack.
+.IP \fBnoanonymous\fR
+Disallow anonymous logins.
+.RE
.SH "Resource controls"
.ad
.fi
.IP \fBstrict_rfc821_envelopes\fR
Disallow non-RFC 821 style addresses in envelopes. For example,
allow RFC822-style address forms with comments, like Sendmail does.
+.IP \fBallow_broken_auth_clients\fR
+Support older Microsoft clients that mis-implement the AUTH
+protocol, and that expect an EHLO response of "250 AUTH=list"
+instead of "250 AUTH list".
.SH "Content inspection controls"
.IP \fBcontent_filter\fR
The name of a mail delivery transport that filters mail and that
+++ /dev/null
-.TH VIRTUAL 8
-.ad
-.fi
-.SH NAME
-virtual
-\-
-Postfix virtual domain mail delivery agent
-.SH SYNOPSIS
-.na
-.nf
-\fBvirtual\fR [generic Postfix daemon options]
-.SH DESCRIPTION
-.ad
-.fi
-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.
-.SH MAILBOX DELIVERY
-.na
-.nf
-.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 \fBvirtual_mailbox_maps\fR configuration 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.
-.SH DELIVERY RIGHTS
-.na
-.nf
-.ad
-.fi
-Deliveries are made with the user and group privileges that are
-listed in the tables specified with the \fBvirtual_uid_maps\fR
-and \fBvirtual_gid_maps\fR, respectively.
-
-The \fBvirtual_minimum_uid\fR parameter specifies a lower bound on
-user ID values that may be specified in \fBvirtual_uid_maps\fR. Mail
-will not be delivered when a too low UID value is found.
-.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 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.
-
-Use the command \fBpostconf -m\fR to find out what locking methods
-are available on your system.
-.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 (default: 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
+++ /dev/null
-../../.indent.pro
\ No newline at end of file
+++ /dev/null
-SHELL = /bin/sh
-SRCS = base64encode.c base64decode.c
-OBJS = base64encode.o base64decode.o
-HDRS =
-TESTSRC =
-WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
- -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
- -Wunused
-DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
-CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG=
-INC_DIR = ../../include
-PROG = base64encode base64decode
-LIBS = ../../lib/libglobal.a ../../lib/libutil.a
-
-.c.o:; $(CC) $(CFLAGS) -c $*.c
-
-all: $(PROG)
-
-Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
-
-base64decode: base64decode.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ base64decode.o $(LIBS) $(SYSLIBS)
-
-base64encode: base64encode.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ base64encode.o $(LIBS) $(SYSLIBS)
-
-test: $(TESTPROG)
-
-update: ../../bin/base64encode ../../bin/base64decode
-
-../../bin/base64encode: base64encode
- cp $? $@
-
-../../bin/base64decode: base64decode
- cp $? $@
-
-printfck: $(OBJS) $(PROG)
- rm -rf printfck
- mkdir 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
- @$(EXPORT) make -f Makefile.in Makefile 1>&2
-
-# do not edit below this line - it is generated by 'make depend'
-base64decode.o: base64decode.c
-base64decode.o: ../../include/sys_defs.h
-base64decode.o: ../../include/vstring.h
-base64decode.o: ../../include/vbuf.h
-base64decode.o: ../../include/vstream.h
-base64decode.o: ../../include/vstring_vstream.h
-base64decode.o: ../../include/msg.h
-base64decode.o: ../../include/msg_vstream.h
-base64encode.o: base64encode.c
-base64encode.o: ../../include/sys_defs.h
-base64encode.o: ../../include/vstring.h
-base64encode.o: ../../include/vbuf.h
-base64encode.o: ../../include/vstream.h
-base64encode.o: ../../include/vstring_vstream.h
-base64encode.o: ../../include/msg.h
-base64encode.o: ../../include/msg_vstream.h
+++ /dev/null
-/* base64decode - transform base 64 data to printable form */
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <ctype.h>
-
-/* SASL library. */
-
-#include <sasl.h>
-#include <saslutil.h>
-
-/* Utility library. */
-
-#include <vstring.h>
-#include <vstream.h>
-#include <vstring_vstream.h>
-#include <msg.h>
-#include <msg_vstream.h>
-
-/* Application-specific. */
-
-#define STR(x) vstring_str(x)
-#define LEN(x) VSTRING_LEN(x)
-
-#define UCHAR(x) ((unsigned char *) (x))
-
-static VSTRING *escape(VSTRING *escaped, char *input, int len)
-{
- char *cp;
- unsigned ch;
-
- VSTRING_RESET(escaped);
- for (cp = input; cp < input + len; cp++) {
- ch = *UCHAR(cp);
- if (ISASCII(ch) && ISPRINT(ch))
- VSTRING_ADDCH(escaped, ch);
- else
- vstring_sprintf_append(escaped, "\\%03o", ch);
- }
- VSTRING_TERMINATE(escaped);
- return (escaped);
-}
-
-int main(int unused_argc, char **argv)
-{
- VSTRING *input = vstring_alloc(100);
- VSTRING *escaped = vstring_alloc(100);
- VSTRING *result = vstring_alloc(100);
- int len;
-
- msg_vstream_init(argv[0], VSTREAM_ERR);
-
- while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) {
- VSTRING_SPACE(result, LEN(input));
- if (sasl_decode64(STR(input), LEN(input),
- STR(result), &len) != SASL_OK)
- msg_fatal("malformed input");
- vstream_printf("%s\n", STR(escape(escaped, STR(result), len)));
- vstream_fflush(VSTREAM_OUT);
- }
- return (0);
-}
+++ /dev/null
-/* base64encode - transform printable form to base 64 data */
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <ctype.h>
-
-/* SASL library. */
-
-#include <sasl.h>
-#include <saslutil.h>
-
-/* Utility library. */
-
-#include <vstring.h>
-#include <vstream.h>
-#include <vstring_vstream.h>
-#include <msg.h>
-#include <msg_vstream.h>
-
-/* Application-specific. */
-
-#define STR(x) vstring_str(x)
-#define LEN(x) VSTRING_LEN(x)
-
-#define UCHAR(x) ((unsigned char *) (x))
-
-static VSTRING *unescape(VSTRING *unescaped, VSTRING *input)
-{
- char *cp = STR(input);
- int ch;
- int oval;
- int i;
-
- VSTRING_RESET(unescaped);
- while ((ch = *UCHAR(cp++)) != 0) {
- switch (ch) {
- case '\\':
- for (oval = 0, i = 0; i < 3 && (ch = *UCHAR(cp)) != 0; i++) {
- if (!ISDIGIT(ch) || ch == '8' || ch == '9')
- break;
- oval = (oval << 3) | (ch - '0');
- cp++;
- }
- VSTRING_ADDCH(unescaped, oval);
- break;
- default:
- VSTRING_ADDCH(unescaped, ch);
- break;
- }
- }
- VSTRING_TERMINATE(unescaped);
- return (unescaped);
-}
-
-int main(int unused_argc, char **argv)
-{
- VSTRING *input = vstring_alloc(100);
- VSTRING *unescaped = vstring_alloc(100);
- VSTRING *result = vstring_alloc(100);
- int result_len;
- int len;
-
- msg_vstream_init(argv[0], VSTREAM_ERR);
-
- while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) {
- unescape(unescaped, input);
- result_len = ((LEN(unescaped) + 2) / 3) * 4 + 1;
- VSTRING_SPACE(result, result_len);
- if (sasl_encode64(STR(unescaped), LEN(unescaped), STR(result),
- result_len, &len) != SASL_OK)
- msg_panic("sasl_encode64 botch");
- vstream_printf("%.*s\n", len, STR(result));
- vstream_fflush(VSTREAM_OUT);
- }
- return (0);
-}
"####################################################################");
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce,
- "Your message could not be delivered for %.1g hours.",
+ "Your message could not be delivered for %.1f hours.",
var_delay_warn_time / 3600.0);
post_mail_fprintf(bounce,
- "It will be retried until it is %.1g days old.",
+ "It will be retried until it is %.1f days old.",
var_max_queue_time / 86400.0);
}
is_header.o: is_header.c
is_header.o: ../../include/sys_defs.h
is_header.o: is_header.h
-local_transport.o: local_transport.c
-local_transport.o: ../../include/sys_defs.h
-local_transport.o: ../../include/msg.h
-local_transport.o: ../../include/mymalloc.h
-local_transport.o: string_list.h
-local_transport.o: mail_params.h
-local_transport.o: local_transport.h
mail_addr.o: mail_addr.c
mail_addr.o: ../../include/sys_defs.h
mail_addr.o: ../../include/stringops.h
#define DEF_STRICT_RFC821_ENV 0
extern bool var_strict_rfc821_env;
+ /*
+ * Standards violation: send "250 AUTH=list" in order to accomodate broken
+ * Microsoft clients.
+ */
+#define VAR_BROKEN_AUTH_CLNTS "allow_broken_auth_clients"
+#define DEF_BROKEN_AUTH_CLNTS 0
+extern bool var_broken_auth_clients;
+
/*
* Standards violation: disable VRFY.
*/
extern int var_smtpd_junk_cmd_limit;
/*
- * SASL authentication support, server side.
+ * SASL authentication support, SMTP server side.
*/
#define VAR_SMTPD_SASL_ENABLE "smtpd_sasl_auth_enable"
#define DEF_SMTPD_SASL_ENABLE 0
extern char *var_smtpd_sasl_realm;
/*
- * SASL authentication support, client side.
+ * SASL authentication support, SMTP client side.
*/
#define VAR_SMTP_SASL_ENABLE "smtp_sasl_auth_enable"
#define DEF_SMTP_SASL_ENABLE 0
#define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_smtp_sasl_opts;
+ /*
+ * SASL authentication support, LMTP client side.
+ */
+#define VAR_LMTP_SASL_ENABLE "lmtp_sasl_auth_enable"
+#define DEF_LMTP_SASL_ENABLE 0
+extern bool var_lmtp_sasl_enable;
+
+#define VAR_LMTP_SASL_PASSWD "lmtp_sasl_password_maps"
+#define DEF_LMTP_SASL_PASSWD ""
+extern char *var_lmtp_sasl_passwd;
+
+#define VAR_LMTP_SASL_OPTS "lmtp_sasl_security_options"
+#define DEF_LMTP_SASL_OPTS "noplaintext, noanonymous"
+extern char *var_lmtp_sasl_opts;
+
+ /*
+ * SASL-based relay etc. control.
+ */
#define PERMIT_SASL_AUTH "permit_sasl_authenticated"
/*
* When locking a mailbox, how often to try and how long to wait.
*/
#define VAR_FLOCK_TRIES "deliver_lock_attempts"
-#define DEF_FLOCK_TRIES 5
+#define DEF_FLOCK_TRIES 10
extern int var_flock_tries;
#define VAR_FLOCK_DELAY "deliver_lock_delay"
#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;
+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;
* missing subdirectory.
*/
if ((fp = vstream_fopen(path, flags, mode)) == 0)
- if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0)
- fp = vstream_fopen(path, flags, mode);
+ if (errno == ENOENT)
+ if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0)
+ fp = vstream_fopen(path, flags, mode);
return (fp);
}
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20010105"
+#define DEF_MAIL_VERSION "Snapshot-20010122"
extern char *var_mail_version;
/* LICENSE
SHELL = /bin/sh
SRCS = lmtp.c lmtp_connect.c lmtp_proto.c lmtp_chat.c lmtp_session.c \
- lmtp_addr.c lmtp_trouble.c lmtp_state.c
+ lmtp_addr.c lmtp_trouble.c lmtp_state.c lmtp_sasl_glue.c \
+ lmtp_sasl_proto.c
OBJS = lmtp.o lmtp_connect.o lmtp_proto.o lmtp_chat.o lmtp_session.o \
- lmtp_addr.o lmtp_trouble.o lmtp_state.o
+ lmtp_addr.o lmtp_trouble.o lmtp_state.o lmtp_sasl_glue.o \
+ lmtp_sasl_proto.o
HDRS = lmtp.h
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
lmtp.o: ../../include/mail_error.h
lmtp.o: ../../include/mail_server.h
lmtp.o: lmtp.h
+lmtp.o: lmtp_sasl.h
lmtp_addr.o: lmtp_addr.c
lmtp_addr.o: ../../include/sys_defs.h
lmtp_addr.o: ../../include/msg.h
lmtp_chat.o: ../../include/mail_addr.h
lmtp_chat.o: ../../include/post_mail.h
lmtp_chat.o: ../../include/cleanup_user.h
+lmtp_chat.o: ../../include/mail_error.h
+lmtp_chat.o: ../../include/name_mask.h
lmtp_chat.o: lmtp.h
lmtp_connect.o: lmtp_connect.c
lmtp_connect.o: ../../include/sys_defs.h
lmtp_proto.o: ../../include/rec_type.h
lmtp_proto.o: ../../include/off_cvt.h
lmtp_proto.o: ../../include/mark_corrupt.h
+lmtp_proto.o: ../../include/quote_821_local.h
lmtp_proto.o: lmtp.h
lmtp_proto.o: ../../include/argv.h
-lmtp_proto.o: ../../include/quote_821_local.h
+lmtp_proto.o: lmtp_sasl.h
+lmtp_sasl_glue.o: lmtp_sasl_glue.c
+lmtp_sasl_glue.o: ../../include/sys_defs.h
+lmtp_sasl_glue.o: ../../include/msg.h
+lmtp_sasl_glue.o: ../../include/mymalloc.h
+lmtp_sasl_glue.o: ../../include/stringops.h
+lmtp_sasl_glue.o: ../../include/vstring.h
+lmtp_sasl_glue.o: ../../include/vbuf.h
+lmtp_sasl_glue.o: ../../include/split_at.h
+lmtp_sasl_glue.o: ../../include/name_mask.h
+lmtp_sasl_glue.o: ../../include/mail_params.h
+lmtp_sasl_glue.o: ../../include/string_list.h
+lmtp_sasl_glue.o: ../../include/maps.h
+lmtp_sasl_glue.o: ../../include/dict.h
+lmtp_sasl_glue.o: ../../include/vstream.h
+lmtp_sasl_glue.o: ../../include/argv.h
+lmtp_sasl_glue.o: lmtp.h
+lmtp_sasl_glue.o: ../../include/deliver_request.h
+lmtp_sasl_glue.o: ../../include/recipient_list.h
+lmtp_sasl_glue.o: lmtp_sasl.h
+lmtp_sasl_proto.o: lmtp_sasl_proto.c
+lmtp_sasl_proto.o: ../../include/sys_defs.h
+lmtp_sasl_proto.o: ../../include/msg.h
+lmtp_sasl_proto.o: ../../include/mymalloc.h
+lmtp_sasl_proto.o: ../../include/mail_params.h
+lmtp_sasl_proto.o: lmtp.h
+lmtp_sasl_proto.o: ../../include/vstream.h
+lmtp_sasl_proto.o: ../../include/vbuf.h
+lmtp_sasl_proto.o: ../../include/vstring.h
+lmtp_sasl_proto.o: ../../include/argv.h
+lmtp_sasl_proto.o: ../../include/deliver_request.h
+lmtp_sasl_proto.o: ../../include/recipient_list.h
+lmtp_sasl_proto.o: lmtp_sasl.h
lmtp_session.o: lmtp_session.c
lmtp_session.o: ../../include/sys_defs.h
lmtp_session.o: ../../include/mymalloc.h
lmtp_state.o: ../../include/vstring.h
lmtp_state.o: ../../include/vbuf.h
lmtp_state.o: ../../include/vstream.h
-lmtp_state.o: ../../include/config.h
lmtp_state.o: ../../include/mail_conf.h
lmtp_state.o: lmtp.h
lmtp_state.o: ../../include/argv.h
lmtp_state.o: ../../include/deliver_request.h
lmtp_state.o: ../../include/recipient_list.h
+lmtp_state.o: lmtp_sasl.h
lmtp_trouble.o: lmtp_trouble.c
lmtp_trouble.o: ../../include/sys_defs.h
lmtp_trouble.o: ../../include/msg.h
/* RFC 1870 (Message Size Declaration)
/* RFC 2033 (LMTP protocol)
/* RFC 2197 (Pipelining)
+/* RFC 2554 (AUTH command)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* Corrupted message files are marked so that the queue manager can
/* .IP \fBlmtp_tcp_port\fR
/* The TCP port to be used when connecting to a LMTP server. Used as
/* backup if the \fBlmtp\fR service is not found in \fBservices\fR(4).
+/* .SH "Authentication controls"
+/* .IP \fBlmtp_enable_sasl_auth\fR
+/* Enable per-session authentication as per RFC 2554 (SASL).
+/* By default, Postfix is built without SASL support.
+/* .IP \fBlmtp_sasl_password_maps\fR
+/* Lookup tables with per-host or domain \fIname\fR:\fIpassword\fR entries.
+/* No entry for a host means no attempt to authenticate.
+/* .IP \fBlmtp_sasl_security_options\fR
+/* Zero or more of the following.
+/* .RS
+/* .IP \fBnoplaintext\fR
+/* Disallow authentication methods that use plaintext passwords.
+/* .IP \fBnoactive\fR
+/* Disallow authentication methods that are vulnerable to non-dictionary
+/* active attacks.
+/* .IP \fBnodictionary\fR
+/* Disallow authentication methods that are vulnerable to passive
+/* dictionary attack.
+/* .IP \fBnoanonymous\fR
+/* Disallow anonymous logins.
+/* .RE
/* .SH "Resource controls"
/* .ad
/* .fi
/* Application-specific. */
#include "lmtp.h"
+#include "lmtp_sasl.h"
/*
* Tunable parameters. These have compiled-in defaults that can be overruled
int var_lmtp_skip_quit_resp;
char *var_notify_classes;
char *var_error_rcpt;
+char *var_lmtp_sasl_opts;
+char *var_lmtp_sasl_passwd;
+bool var_lmtp_sasl_enable;
/*
* Global variables.
static void pre_init(char *unused_name, char **unused_argv)
{
debug_peer_init();
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable)
+ lmtp_sasl_initialize();
+#endif
}
/* cleanup - close any open connections, etc. */
msg_info("cleanup: just closed down session");
}
lmtp_state_free(state);
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable)
+ sasl_done();
+#endif
}
/* pre_accept - see if tables have changed */
VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
+ VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_lmtp_sasl_passwd, 0, 0,
+ VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_lmtp_sasl_opts, 0, 0,
0,
};
static CONFIG_INT_TABLE int_table[] = {
/* DESCRIPTION
/* .nf
+ /*
+ * SASL library.
+ */
+#ifdef USE_SASL_AUTH
+#include <sasl.h>
+#include <saslutil.h>
+#endif
+
/*
* Utility library.
*/
int features; /* server features */
ARGV *history; /* transaction log */
int error_mask; /* error classes */
+#ifdef USE_SASL_AUTH
+ char *sasl_mechanism_list; /* server mechanism list */
+ char *sasl_username; /* client username */
+ char *sasl_passwd; /* client password */
+ sasl_conn_t *sasl_conn; /* SASL internal state */
+ VSTRING *sasl_encoded; /* encoding buffer */
+ VSTRING *sasl_decoded; /* decoding buffer */
+ sasl_callback_t *sasl_callbacks; /* stateful callbacks */
+#endif
int sndbufsize; /* total window size */
int sndbuffree; /* remaining window */
int reuse; /* connection being reused */
#define LMTP_FEATURE_8BITMIME (1<<1)
#define LMTP_FEATURE_PIPELINING (1<<2)
#define LMTP_FEATURE_SIZE (1<<3)
+#define SMTP_FEATURE_AUTH (1<<5)
/*
* lmtp.c
#include <mail_params.h>
#include <mail_addr.h>
#include <post_mail.h>
+#include <mail_error.h>
/* Application-specific. */
{
LMTP_SESSION *session = state->session;
static LMTP_RESP rdata;
- int more;
char *cp;
int last_char;
VSTRING_RESET(rdata.buf);
for (;;) {
last_char = smtp_get(state->buffer, session->stream, var_line_limit);
- cp = printable(STR(state->buffer), '?');
+ printable(STR(state->buffer), '?');
if (last_char != '\n')
msg_warn("%s: response longer than %d: %.30s...",
- session->namaddr, var_line_limit, cp);
+ session->namaddr, var_line_limit, STR(state->buffer));
if (msg_verbose)
- msg_info("< %s: %s", session->namaddr, cp);
- while (ISDIGIT(*cp))
- cp++;
- rdata.code = (cp - STR(state->buffer) == 3 ?
- atoi(STR(state->buffer)) : 0);
- more = (*cp == '-');
+ msg_info("< %s: %s", session->namaddr, STR(state->buffer));
/*
* Defend against a denial of service attack by limiting the amount
vstring_strcat(rdata.buf, STR(state->buffer));
lmtp_chat_append(state, "In: ", STR(state->buffer));
}
- if (VSTRING_LEN(state->buffer) == 0) /* XXX remote brain damage */
- continue;
- if (!ISDIGIT(STR(state->buffer)[0])) /* XXX remote brain damage */
- continue;
- if (more == 0)
- break;
+
+ /*
+ * Parse into code and text. Ignore unrecognized garbage. This means
+ * that any character except space (or end of line) will have the
+ * same effect as the '-' line continuation character.
+ */
+ for (cp = STR(state->buffer); *cp && ISDIGIT(*cp); cp++)
+ /* void */ ;
+ if (cp - STR(state->buffer) == 3) {
+ if (*cp == '-')
+ continue;
+ if (*cp == ' ' || *cp == 0)
+ break;
+ }
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
}
+ rdata.code = atoi(STR(state->buffer));
VSTRING_TERMINATE(rdata.buf);
rdata.str = STR(rdata.buf);
return (&rdata);
#include <rec_type.h>
#include <off_cvt.h>
#include <mark_corrupt.h>
+#include <quote_821_local.h>
/* Application-specific. */
#include "lmtp.h"
-#include "quote_821_local.h"
+#include "lmtp_sasl.h"
/*
* Sender and receiver state. A session does not necessarily go through a
*/
if (((resp = lmtp_chat_resp(state))->code / 100) != 2)
return (lmtp_site_fail(state, resp->code,
- "%s refused to talk to me: %s",
+ "host %s refused to talk to me: %s",
session->namaddr, translit(resp->str, "\n", " ")));
/*
lmtp_chat_cmd(state, "LHLO %s", var_myhostname);
if ((resp = lmtp_chat_resp(state))->code / 100 != 2)
return (lmtp_site_fail(state, resp->code,
- "%s refused to talk to me: %s",
+ "host %s refused to talk to me: %s",
session->namaddr,
translit(resp->str, "\n", " ")));
state->features |= LMTP_FEATURE_PIPELINING;
else if (strcasecmp(word, "SIZE") == 0)
state->features |= LMTP_FEATURE_SIZE;
+#ifdef USE_SASL_AUTH
+ else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
+ lmtp_sasl_helo_auth(state, words);
+#endif
}
}
if (msg_verbose)
msg_info("server features: 0x%x", state->features);
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH))
+ return (lmtp_sasl_helo_login(state));
+#endif
+
/*
* We use LMTP command pipelining if the server said it supported it.
* Since we use blocking I/O, RFC 2197 says that we should inspect the
case LMTP_STATE_MAIL:
if (resp->code / 100 != 2) {
lmtp_mesg_fail(state, resp->code,
- "%s said: %s", session->namaddr,
+ "host %s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
mail_from_rejected = 1;
}
survivors[nrcpt++] = recv_rcpt;
} else {
lmtp_rcpt_fail(state, resp->code, rcpt,
- "%s said: %s", session->namaddr,
+ "host %s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
rcpt->offset = 0; /* in case deferred */
}
if (resp->code / 100 != 3) {
if (nrcpt > 0)
lmtp_mesg_fail(state, resp->code,
- "%s said: %s", session->namaddr,
+ "host %s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
nrcpt = -1;
}
}
} else {
lmtp_rcpt_fail(state, resp->code, rcpt,
- "%s said: %s", session->namaddr,
+ "host %s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
rcpt->offset = 0; /* in case deferred */
}
--- /dev/null
+/*++
+/* NAME
+/* lmtp_sasl 3h
+/* SUMMARY
+/* Postfix SASL interface for LMTP client
+/* SYNOPSIS
+/* #include "lmtp_sasl.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * SASL protocol functions
+ */
+extern void lmtp_sasl_initialize(void);
+extern void lmtp_sasl_connect(LMTP_STATE *);
+extern int lmtp_sasl_passwd_lookup(LMTP_STATE *);
+extern void lmtp_sasl_start(LMTP_STATE *);
+extern int lmtp_sasl_authenticate(LMTP_STATE *, VSTRING *);
+extern void lmtp_sasl_cleanup(LMTP_STATE *);
+
+extern void lmtp_sasl_helo_auth(LMTP_STATE *, const char *);
+extern int lmtp_sasl_helo_login(LMTP_STATE *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
--- /dev/null
+/*++
+/* NAME
+/* lmtp_sasl 3
+/* SUMMARY
+/* Postfix SASL interface for LMTP client
+/* SYNOPSIS
+/* #include lmtp_sasl.h
+/*
+/* void lmtp_sasl_initialize()
+/*
+/* void lmtp_sasl_connect(state)
+/* LMTP_STATE *state;
+/*
+/* void lmtp_sasl_start(state)
+/* LMTP_STATE *state;
+/*
+/* int lmtp_sasl_passwd_lookup(state)
+/* LMTP_STATE *state;
+/*
+/* int lmtp_sasl_authenticate(state, why)
+/* LMTP_STATE *state;
+/* VSTRING *why;
+/*
+/* void lmtp_sasl_cleanup(state)
+/* LMTP_STATE *state;
+/* DESCRIPTION
+/* lmtp_sasl_initialize() initializes the SASL library. This
+/* routine must be called once at process startup, before any
+/* chroot operations.
+/*
+/* lmtp_sasl_connect() performs per-session initialization. This
+/* routine must be called once at the start of each connection.
+/*
+/* lmtp_sasl_start() performs per-session initialization. This
+/* routine must be called once per session before doing any SASL
+/* authentication.
+/*
+/* lmtp_sasl_passwd_lookup() looks up the username/password
+/* for the current SMTP server. The result is zero in case
+/* of failure.
+/*
+/* lmtp_sasl_authenticate() implements the SASL authentication
+/* dialog. The result is < 0 in case of protocol failure, zero in
+/* case of unsuccessful authentication, > 0 in case of success.
+/* The why argument is updated with a reason for failure.
+/* This routine must be called only when lmtp_sasl_passwd_lookup()
+/* suceeds.
+/*
+/* lmtp_sasl_cleanup() cleans up. It must be called at the
+/* end of every SMTP session that uses SASL authentication.
+/* This routine is a noop for non-SASL sessions.
+/*
+/* Arguments:
+/* .IP state
+/* Session context.
+/* .IP mech_list
+/* String of SASL mechanisms (separated by blanks)
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Original author:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+ /*
+ * Utility library
+ */
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <split_at.h>
+#include <name_mask.h>
+
+ /*
+ * Global library
+ */
+#include <mail_params.h>
+#include <string_list.h>
+#include <maps.h>
+
+ /*
+ * Application-specific
+ */
+#include "lmtp.h"
+#include "lmtp_sasl.h"
+
+#ifdef USE_SASL_AUTH
+
+ /*
+ * Authentication security options.
+ */
+static NAME_MASK lmtp_sasl_sec_mask[] = {
+ "noplaintext", SASL_SEC_NOPLAINTEXT,
+ "noactive", SASL_SEC_NOACTIVE,
+ "nodictionary", SASL_SEC_NODICTIONARY,
+ "noanonymous", SASL_SEC_NOANONYMOUS,
+ 0,
+};
+
+static int lmtp_sasl_sec_opts;
+
+ /*
+ * Silly little macros.
+ */
+#define STR(x) vstring_str(x)
+
+ /*
+ * Per-host login/password information.
+ */
+static MAPS *lmtp_sasl_passwd_map;
+
+/* lmtp_sasl_log - logging call-back routine */
+
+static int lmtp_sasl_log(void *unused_context, int priority,
+ const char *message)
+{
+ switch (priority) {
+ case SASL_LOG_ERR:
+ case SASL_LOG_WARNING:
+ msg_warn("%s", message);
+ break;
+ case SASL_LOG_INFO:
+ if (msg_verbose)
+ msg_info("%s", message);
+ break;
+ }
+ return (SASL_OK);
+}
+
+/* lmtp_sasl_get_user - username lookup call-back routine */
+
+static int lmtp_sasl_get_user(void *context, int unused_id, const char **result,
+ unsigned *len)
+{
+ char *myname = "lmtp_sasl_get_user";
+ LMTP_STATE *state = (LMTP_STATE *) context;
+
+ if (msg_verbose)
+ msg_info("%s: %s", myname, state->sasl_username);
+
+ /*
+ * Sanity check.
+ */
+ if (state->sasl_passwd == 0)
+ msg_panic("%s: no username looked up", myname);
+
+ *result = state->sasl_username;
+ if (len)
+ *len = strlen(state->sasl_username);
+ return (SASL_OK);
+}
+
+/* lmtp_sasl_get_passwd - password lookup call-back routine */
+
+static int lmtp_sasl_get_passwd(sasl_conn_t *conn, void *context,
+ int id, sasl_secret_t **psecret)
+{
+ char *myname = "lmtp_sasl_get_passwd";
+ LMTP_STATE *state = (LMTP_STATE *) context;
+ int len;
+
+ if (msg_verbose)
+ msg_info("%s: %s", myname, state->sasl_passwd);
+
+ /*
+ * Sanity check.
+ */
+ if (!conn || !psecret || id != SASL_CB_PASS)
+ return (SASL_BADPARAM);
+ if (state->sasl_passwd == 0)
+ msg_panic("%s: no password looked up", myname);
+
+ /*
+ * Convert the password into a counted string.
+ */
+ len = strlen(state->sasl_passwd);
+ if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0)
+ return (SASL_NOMEM);
+ (*psecret)->len = len;
+ memcpy((*psecret)->data, state->sasl_passwd, len + 1);
+
+ return (SASL_OK);
+}
+
+/* lmtp_sasl_passwd_lookup - password lookup routine */
+
+int lmtp_sasl_passwd_lookup(LMTP_STATE *state)
+{
+ char *myname = "lmtp_sasl_passwd_lookup";
+ const char *value;
+ char *passwd;
+
+ /*
+ * Sanity check.
+ */
+ if (lmtp_sasl_passwd_map == 0)
+ msg_panic("%s: passwd map not initialized", myname);
+
+ /*
+ * Look up the per-server password information. Try the hostname first,
+ * then try the destination.
+ */
+ if ((value = maps_find(lmtp_sasl_passwd_map, state->session->host, 0)) != 0
+ || (value = maps_find(lmtp_sasl_passwd_map, state->request->nexthop, 0)) != 0) {
+ state->sasl_username = mystrdup(value);
+ passwd = split_at(state->sasl_username, ':');
+ state->sasl_passwd = mystrdup(passwd ? passwd : "");
+ if (msg_verbose)
+ msg_info("%s: host `%s' user `%s' pass `%s'",
+ myname, state->session->host,
+ state->sasl_username, state->sasl_passwd);
+ return (1);
+ } else {
+ if (msg_verbose)
+ msg_info("%s: host `%s' no auth info found",
+ myname, state->session->host);
+ return (0);
+ }
+}
+
+/* lmtp_sasl_initialize - per-process initialization (pre jail) */
+
+void lmtp_sasl_initialize(void)
+{
+
+ /*
+ * Global callbacks. These have no per-session context.
+ */
+ static sasl_callback_t callbacks[] = {
+ {SASL_CB_LOG, &lmtp_sasl_log, 0},
+ {SASL_CB_LIST_END, 0, 0}
+ };
+
+ /*
+ * Sanity check.
+ */
+ if (lmtp_sasl_passwd_map)
+ msg_panic("lmtp_sasl_initialize: repeated call");
+ if (*var_lmtp_sasl_passwd == 0)
+ msg_fatal("specify a password table via the `%s' configuration parameter",
+ VAR_LMTP_SASL_PASSWD);
+
+ /*
+ * Open the per-host password table and initialize the SASL library. Use
+ * shared locks for reading, just in case someone updates the table.
+ */
+ lmtp_sasl_passwd_map = maps_create("lmtp_sasl_passwd",
+ var_lmtp_sasl_passwd, DICT_FLAG_LOCK);
+ if (sasl_client_init(callbacks) != SASL_OK)
+ msg_fatal("SASL library initialization");
+
+ /*
+ * Configuration parameters.
+ */
+ lmtp_sasl_sec_opts = name_mask(VAR_LMTP_SASL_OPTS, lmtp_sasl_sec_mask,
+ var_lmtp_sasl_opts);
+}
+
+/* lmtp_sasl_connect - per-session client initialization */
+
+void lmtp_sasl_connect(LMTP_STATE *state)
+{
+ state->sasl_mechanism_list = 0;
+ state->sasl_username = 0;
+ state->sasl_passwd = 0;
+ state->sasl_conn = 0;
+ state->sasl_encoded = 0;
+ state->sasl_decoded = 0;
+ state->sasl_callbacks = 0;
+}
+
+/* lmtp_sasl_start - per-session SASL initialization */
+
+void lmtp_sasl_start(LMTP_STATE *state)
+{
+ static sasl_callback_t callbacks[] = {
+ {SASL_CB_USER, &lmtp_sasl_get_user, 0},
+ {SASL_CB_AUTHNAME, &lmtp_sasl_get_user, 0},
+ {SASL_CB_PASS, &lmtp_sasl_get_passwd, 0},
+ {SASL_CB_LIST_END, 0, 0}
+ };
+ sasl_callback_t *cp;
+ sasl_security_properties_t sec_props;
+
+ if (msg_verbose)
+ msg_info("starting new SASL client");
+
+ /*
+ * Per-session initialization. Provide each session with its own callback
+ * context.
+ */
+#define NULL_SECFLAGS 0
+
+ state->sasl_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks));
+ memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
+ for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
+ cp->context = (void *) state;
+ if (sasl_client_new("smtp", state->session->host,
+ state->sasl_callbacks, NULL_SECFLAGS,
+ (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
+ msg_fatal("per-session SASL client initialization");
+
+ /*
+ * Per-session security properties. XXX This routine is not sufficiently
+ * documented. What is the purpose of all this?
+ */
+ memset(&sec_props, 0L, sizeof(sec_props));
+ sec_props.min_ssf = 0;
+ sec_props.max_ssf = 1; /* don't allow real SASL
+ * security layer */
+ sec_props.security_flags = lmtp_sasl_sec_opts;
+ sec_props.maxbufsize = 0;
+ sec_props.property_names = 0;
+ sec_props.property_values = 0;
+ if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS,
+ &sec_props) != SASL_OK)
+ msg_fatal("set per-session SASL security properties");
+
+ /*
+ * We use long-lived conversion buffers rather than local variables in
+ * order to avoid memory leaks in case of read/write timeout or I/O
+ * error.
+ */
+ state->sasl_encoded = vstring_alloc(10);
+ state->sasl_decoded = vstring_alloc(10);
+}
+
+/* lmtp_sasl_authenticate - run authentication protocol */
+
+int lmtp_sasl_authenticate(LMTP_STATE *state, VSTRING *why)
+{
+ char *myname = "lmtp_sasl_authenticate";
+ unsigned enc_length;
+ unsigned enc_length_out;
+ char *clientout;
+ unsigned clientoutlen;
+ unsigned serverinlen;
+ LMTP_RESP *resp;
+ const char *mechanism;
+ int result;
+ char *line;
+
+#define NO_SASL_SECRET 0
+#define NO_SASL_INTERACTION 0
+#define NO_SASL_LANGLIST ((const char *) 0)
+#define NO_SASL_OUTLANG ((const char **) 0)
+
+ if (msg_verbose)
+ msg_info("%s: %s: SASL mechanisms %s",
+ myname, state->session->namaddr, state->sasl_mechanism_list);
+
+ /*
+ * Start the client side authentication protocol.
+ */
+ result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
+ state->sasl_mechanism_list,
+ NO_SASL_SECRET, NO_SASL_INTERACTION,
+ &clientout, &clientoutlen, &mechanism);
+ if (result != SASL_OK && result != SASL_CONTINUE) {
+ vstring_sprintf(why, "cannot SASL authenticate to server %s: %s",
+ state->session->namaddr,
+ sasl_errstring(result, NO_SASL_LANGLIST,
+ NO_SASL_OUTLANG));
+ return (-1);
+ }
+
+ /*
+ * Send the AUTH command and the optional initial client response.
+ * sasl_encode64() produces four bytes for each complete or incomplete
+ * triple of input bytes. Allocate an extra byte for string termination.
+ */
+#define ENCODE64_LENGTH(n) ((((n) + 2) / 3) * 4)
+
+ if (clientoutlen > 0) {
+ if (msg_verbose)
+ msg_info("%s: %s: uncoded initial reply: %.*s",
+ myname, state->session->namaddr,
+ (int) clientoutlen, clientout);
+ enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+ VSTRING_SPACE(state->sasl_encoded, enc_length);
+ if (sasl_encode64(clientout, clientoutlen,
+ STR(state->sasl_encoded), enc_length,
+ &enc_length_out) != SASL_OK)
+ msg_panic("%s: sasl_encode64 botch", myname);
+ free(clientout);
+ lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
+ } else {
+ lmtp_chat_cmd(state, "AUTH %s", mechanism);
+ }
+
+ /*
+ * Step through the authentication protocol until the server tells us
+ * that we are done.
+ */
+ while ((resp = lmtp_chat_resp(state))->code / 100 == 3) {
+
+ /*
+ * Process a server challenge.
+ */
+ line = resp->str;
+ (void) mystrtok(&line, "- \t\n"); /* skip over result code */
+ serverinlen = strlen(line);
+ VSTRING_SPACE(state->sasl_decoded, serverinlen);
+ if (sasl_decode64(line, serverinlen,
+ STR(state->sasl_decoded), &enc_length) != SASL_OK) {
+ vstring_sprintf(why, "malformed SASL challenge from server %s",
+ state->session->namaddr);
+ return (-1);
+ }
+ if (msg_verbose)
+ msg_info("%s: %s: decoded challenge: %.*s",
+ myname, state->session->namaddr,
+ (int) enc_length, STR(state->sasl_decoded));
+ result = sasl_client_step((sasl_conn_t *) state->sasl_conn,
+ STR(state->sasl_decoded), enc_length,
+ NO_SASL_INTERACTION, &clientout, &clientoutlen);
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ msg_warn("SASL authentication failed to server %s: %s",
+ state->session->namaddr,
+ sasl_errstring(result, NO_SASL_LANGLIST,
+ NO_SASL_OUTLANG));
+
+ /*
+ * Send a client response.
+ */
+ if (clientoutlen > 0) {
+ if (msg_verbose)
+ msg_info("%s: %s: uncoded client response %.*s",
+ myname, state->session->namaddr,
+ (int) clientoutlen, clientout);
+ enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+ VSTRING_SPACE(state->sasl_encoded, enc_length);
+ if (sasl_encode64(clientout, clientoutlen,
+ STR(state->sasl_encoded), enc_length,
+ &enc_length_out) != SASL_OK)
+ msg_panic("%s: sasl_encode64 botch", myname);
+ free(clientout);
+ } else {
+ vstring_strcat(state->sasl_encoded, "");
+ }
+ lmtp_chat_cmd(state, "%s", STR(state->sasl_encoded));
+ }
+
+ /*
+ * We completed the authentication protocol.
+ */
+ if (resp->code / 100 != 2) {
+ vstring_sprintf(why, "SASL authentication failed; server %s said: %s",
+ state->session->namaddr, resp->str);
+ return (0);
+ }
+ return (1);
+}
+
+/* lmtp_sasl_cleanup - per-session cleanup */
+
+void lmtp_sasl_cleanup(LMTP_STATE *state)
+{
+ if (state->sasl_username) {
+ myfree(state->sasl_username);
+ state->sasl_username = 0;
+ }
+ if (state->sasl_passwd) {
+ myfree(state->sasl_passwd);
+ state->sasl_passwd = 0;
+ }
+ if (state->sasl_mechanism_list) {
+ myfree(state->sasl_mechanism_list); /* allocated in lmtp_helo */
+ state->sasl_mechanism_list = 0;
+ }
+ if (state->sasl_conn) {
+ if (msg_verbose)
+ msg_info("disposing SASL state information");
+ sasl_dispose(&state->sasl_conn);
+ }
+ if (state->sasl_callbacks) {
+ myfree((char *) state->sasl_callbacks);
+ state->sasl_callbacks = 0;
+ }
+ if (state->sasl_encoded) {
+ vstring_free(state->sasl_encoded);
+ state->sasl_encoded = 0;
+ }
+ if (state->sasl_decoded) {
+ vstring_free(state->sasl_decoded);
+ state->sasl_decoded = 0;
+ }
+}
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* lmtp_sasl_proto 3
+/* SUMMARY
+/* Postfix SASL interface for LMTP client
+/* SYNOPSIS
+/* #include lmtp_sasl.h
+/*
+/* void lmtp_sasl_helo_auth(state, words)
+/* LMTP_STATE *state;
+/* const char *words;
+/*
+/* int lmtp_sasl_helo_login(state)
+/* LMTP_STATE *state;
+/* DESCRIPTION
+/* This module contains random chunks of code that implement
+/* the SMTP protocol interface for SASL negotiation. The goal
+/* is to reduce clutter in the main LMTP client source code.
+/*
+/* lmtp_sasl_helo_auth() processes the AUTH option in the
+/* SMTP server's EHLO response.
+/*
+/* lmtp_sasl_helo_login() authenticates the LMTP client to the
+/* SMTP server, using the authentication mechanism information
+/* given by the server. The result is a Postfix delivery status
+/* code in case of trouble.
+/*
+/* Arguments:
+/* .IP state
+/* Session context.
+/* .IP words
+/* List of SASL authentication mechanisms (separated by blanks)
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Original author:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* 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>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* Application-specific. */
+
+#include "lmtp.h"
+#include "lmtp_sasl.h"
+
+#ifdef USE_SASL_AUTH
+
+/* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */
+
+void lmtp_sasl_helo_auth(LMTP_STATE *state, const char *words)
+{
+
+ /*
+ * XXX If the server offers a null list of authentication mechanisms,
+ * then pretend that the server doesn't support SASL authentication.
+ */
+ if (state->sasl_mechanism_list) {
+ myfree(state->sasl_mechanism_list);
+ msg_warn("%s offered AUTH option multiple times",
+ state->session->namaddr);
+ state->sasl_mechanism_list = 0;
+ state->features &= ~SMTP_FEATURE_AUTH;
+ }
+ if (strlen(words) > 0) {
+ state->sasl_mechanism_list = mystrdup(words);
+ state->features |= SMTP_FEATURE_AUTH;
+ } else {
+ msg_warn("%s offered null AUTH mechanism list",
+ state->session->namaddr);
+ }
+}
+
+/* lmtp_sasl_helo_login - perform SASL login */
+
+int lmtp_sasl_helo_login(LMTP_STATE *state)
+{
+ VSTRING *why = vstring_alloc(10);
+ int ret = 0;
+
+ /*
+ * Skip authentication when no authentication info exists for this
+ * server, so that we talk to each other like strangers. Otherwise, if
+ * authentication information exists, assume that authentication is
+ * required, and assume that an authentication error is recoverable.
+ */
+ if (lmtp_sasl_passwd_lookup(state) != 0) {
+ lmtp_sasl_start(state);
+ if (lmtp_sasl_authenticate(state, why) <= 0)
+ ret = lmtp_site_fail(state, 450, "Authentication failed: %s",
+ vstring_str(why));
+ }
+ vstring_free(why);
+ return (ret);
+}
+
+#endif
/* Global library. */
-#include <config.h>
+#include <mail_conf.h>
/* Application-specific. */
#include "lmtp.h"
+#include "lmtp_sasl.h"
/* lmtp_state_alloc - initialize */
state->features = 0;
state->history = 0;
state->error_mask = 0;
+#ifdef USE_SASL_AUTH
+ lmtp_sasl_connect(state);
+#endif
state->sndbufsize = 0;
state->sndbuffree = 0;
state->reuse = 0;
vstring_free(state->buffer);
vstring_free(state->scratch);
vstring_free(state->scratch2);
+#ifdef USE_SASL_AUTH
+ lmtp_sasl_cleanup(state);
+#endif
myfree((char *) state);
}
postconf.o: bool_vars.h
postconf.o: int_vars.h
postconf.o: str_vars.h
+postconf.o: raw_vars.h
postconf.o: local_vars.h
postconf.o: smtp_vars.h
postconf.o: time_table.h
postconf.o: str_table.h
postconf.o: local_table.h
postconf.o: smtp_table.h
+postconf.o: raw_table.h
* 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
+ * main.cf, without doing $name expansions. This includes converting
* default values from numeric/boolean internal forms to external string
* form.
*
case 'd':
mode |= SHOW_DEFS;
break;
- case 'E':
- mode |= SHOW_EVAL;
- break;
case 'e':
mode |= EDIT_MAIN;
break;
smtp_proto.o: ../../include/rec_type.h
smtp_proto.o: ../../include/off_cvt.h
smtp_proto.o: ../../include/mark_corrupt.h
+smtp_proto.o: ../../include/quote_821_local.h
smtp_proto.o: smtp.h
smtp_proto.o: ../../include/argv.h
-smtp_proto.o: ../../include/quote_821_local.h
smtp_proto.o: smtp_sasl.h
smtp_sasl_glue.o: smtp_sasl_glue.c
smtp_sasl_glue.o: ../../include/sys_defs.h
*/
extern SMTP_SESSION *smtp_connect(char *, VSTRING *);
extern SMTP_SESSION *smtp_connect_host(char *, unsigned, VSTRING *);
-extern SMTP_SESSION *smtp_connect_domain(char *, unsigned, VSTRING *);
+extern SMTP_SESSION *smtp_connect_domain(char *, unsigned, VSTRING *, int *);
/*
* smtp_proto.c
/* SYNOPSIS
/* #include "smtp_addr.h"
/*
-/* DNS_RR *smtp_domain_addr(name, why)
+/* DNS_RR *smtp_domain_addr(name, why, found_myself)
/* char *name;
/* VSTRING *why;
+/* int *found_myself;
/*
/* DNS_RR *smtp_host_addr(name, why)
/* char *name;
/* smtp_domain_addr - mail exchanger address lookup */
-DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
+DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
{
DNS_RR *mx_names;
DNS_RR *addr_list = 0;
- DNS_RR *self;
+ DNS_RR *self = 0;
unsigned best_pref;
unsigned best_found;
/*
* Clean up.
*/
+ *found_myself = (self != 0);
return (addr_list);
}
* Internal interfaces.
*/
extern DNS_RR *smtp_host_addr(char *, VSTRING *);
-extern DNS_RR *smtp_domain_addr(char *, VSTRING *);
+extern DNS_RR *smtp_domain_addr(char *, VSTRING *, int *);
/* LICENSE
/* .ad
/* smtp_connect_domain - connect to smtp server for domain */
-SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why)
+SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why,
+ int *found_myself)
{
SMTP_SESSION *session = 0;
DNS_RR *addr_list;
* the primary MX host is reachable but does not want to receive our
* mail, there is no point in trying the backup hosts.
*/
- addr_list = smtp_domain_addr(name, why);
+ addr_list = smtp_domain_addr(name, why, found_myself);
for (addr = addr_list; addr; addr = addr->next) {
if ((session = smtp_connect_addr(addr, port, why)) != 0) {
session->best = (addr->pref == addr_list->pref);
char *save;
char *dest;
char *cp;
+ int found_myself;
/*
* First try to deliver to the indicated destination, then try to deliver
if (var_disable_dns || *dest == '[') {
session = smtp_connect_host(host, port, why);
} else {
- session = smtp_connect_domain(host, port, why);
+ session = smtp_connect_domain(host, port, why, &found_myself);
}
myfree(dest_buf);
* is the best MX relay for the destination. Agreed, an errno of OK
* after failure is a weird way to reporting progress.
*/
- if (session != 0 || smtp_errno == SMTP_OK)
+ if (session != 0 || smtp_errno == SMTP_OK || found_myself)
break;
}
#include <rec_type.h>
#include <off_cvt.h>
#include <mark_corrupt.h>
+#include <quote_821_local.h>
/* Application-specific. */
#include "smtp.h"
-#include "quote_821_local.h"
#include "smtp_sasl.h"
/*
#ifdef USE_SASL_AUTH
else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
smtp_sasl_helo_auth(state, words);
+ else if (var_smtp_sasl_enable && strncasecmp(word, "AUTH=", 5) == 0)
+ smtp_sasl_helo_auth(state, word + 5);
#endif
else if (strcasecmp(word, var_myhostname) == 0) {
msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
* anti-UCE systems, by people who aren't aware of RFC details.
*/
if ((!SMTP_SOFT(code) && !SMTP_HARD(code))
- || code == 555 /* RFC 1869, section 6.1. */
+ || code == 555 /* RFC 1869, section 6.1. */
|| (code >= 500 && code < 510))
state->error_mask |= MAIL_ERROR_PROTOCOL;
}
/* .IP \fBstrict_rfc821_envelopes\fR
/* Disallow non-RFC 821 style addresses in envelopes. For example,
/* allow RFC822-style address forms with comments, like Sendmail does.
+/* .IP \fBallow_broken_auth_clients\fR
+/* Support older Microsoft clients that mis-implement the AUTH
+/* protocol, and that expect an EHLO response of "250 AUTH=list"
+/* instead of "250 AUTH list".
/* .SH "Content inspection controls"
/* .IP \fBcontent_filter\fR
/* The name of a mail delivery transport that filters mail and that
char *var_smtpd_sasl_opts;
char *var_smtpd_sasl_realm;
char *var_filter_xport;
+bool var_broken_auth_clients;
/*
* Global state, for stand-alone mode queue file cleanup. When this is
smtpd_chat_reply(state, "250-SIZE");
smtpd_chat_reply(state, "250-ETRN");
#ifdef USE_SASL_AUTH
- if (var_smtpd_sasl_enable)
+ if (var_smtpd_sasl_enable) {
smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
+ if (var_broken_auth_clients)
+ smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list);
+ }
#endif
smtpd_chat_reply(state, "250 8BITMIME");
return (0);
state->error_mask |= MAIL_ERROR_BOUNCE;
smtpd_chat_reply(state, "554 Error: too many hops");
} else if ((state->err & CLEANUP_STAT_CONT) != 0) {
- state->error_mask |= MAIL_ERROR_BOUNCE;
+ state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "552 Error: content rejected");
} else if ((state->err & CLEANUP_STAT_WRITE) != 0) {
state->error_mask |= MAIL_ERROR_RESOURCE;
VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route,
VAR_SMTPD_SASL_ENABLE, DEF_SMTPD_SASL_ENABLE, &var_smtpd_sasl_enable,
+ VAR_BROKEN_AUTH_CLNTS, DEF_BROKEN_AUTH_CLNTS, &var_broken_auth_clients,
0,
};
static CONFIG_STR_TABLE str_table[] = {
static void connect_event(int unused_event, char *context)
{
int sock = CAST_CHAR_PTR_TO_INT(context);
+ struct sockaddr sa;
+ SOCKADDR_SIZE len = sizeof(sa);
SINK_STATE *state;
int fd;
- if ((fd = accept(sock, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) >= 0) {
+ if ((fd = accept(sock, &sa, &len)) >= 0) {
if (msg_verbose)
- msg_info("connect");
+ msg_info("connect (%s)", sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
+#ifdef AF_INET6
+ sa.sa_family == AF_INET6 ? "AF_INET6" :
+#endif
+ sa.sa_family == AF_INET ? "AF_INET" :
+ "unknown protocol family");
non_blocking(fd, NON_BLOCKING);
state = (SINK_STATE *) mymalloc(sizeof(*state));
state->stream = vstream_fdopen(fd, O_RDWR);
static int session_count;
static int message_count = 1;
static struct sockaddr_in sin;
+
#undef sun
static struct sockaddr_un sun;
static struct sockaddr *sa;
-static int sa_len;
+static int sa_length;
static int recipients = 1;
static char *defaddr;
static char *recipient;
session->stream = vstream_fdopen(fd, O_RDWR);
event_enable_write(fd, connect_done, (char *) session);
smtp_timeout_setup(session->stream, var_timeout);
- if (connect(fd, sa, sa_len) < 0 && errno != EINPROGRESS)
+ if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
fail_connect(session);
}
#endif
memcpy(sun.sun_path, path, path_len);
sa = (struct sockaddr *) & sun;
- sa_len = sizeof(sun);
+ sa_length = sizeof(sun);
} else {
if (strncmp(argv[optind], "inet:", 5) == 0)
argv[optind] += 5;
sin.sin_addr.s_addr = find_inet_addr(host);
sin.sin_port = find_inet_port(port, "tcp");
sa = (struct sockaddr *) & sin;
- sa_len = sizeof(sin);
+ sa_length = sizeof(sin);
}
/*
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
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
} else {
if (errno != ENOENT)
break;
- if ((ret = mkdir(saved_path, perms)) < 0 && errno != EEXIST)
- break;
+ if ((ret = mkdir(saved_path, perms)) < 0) {
+ if (errno != EEXIST)
+ break;
+ /* Race condition? */
+ if ((ret = stat(saved_path, &st)) < 0)
+ break;
+ if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ ret = -1;
+ break;
+ }
+ }
}
if (saved_ch != 0)
*cp = saved_ch;
+++ /dev/null
-../../.indent.pro
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-/*++
-/* 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");
-}
+++ /dev/null
-/*++
-/* 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);
-}
+++ /dev/null
-/*++
-/* 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);
-}
+++ /dev/null
-/*++
-/* 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);
-}
+++ /dev/null
-/*++
-/* 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));
-
-}
+++ /dev/null
-/*++
-/* NAME
-/* virtual 8
-/* SUMMARY
-/* Postfix virtual domain mail delivery agent
-/* SYNOPSIS
-/* \fBvirtual\fR [generic Postfix daemon options]
-/* DESCRIPTION
-/* The \fBvirtual\fR delivery agent is designed for virtual mail
-/* hosting services. Originally based on the Postfix local delivery
-/* agent, this agent looks up recipients with map lookups of their
-/* full recipient address, instead of using hard-coded unix password
-/* file lookups of the address local part only.
-/*
-/* This delivery agent only delivers mail. Other features such as
-/* mail forwarding, out-of-office notifications, etc., must be
-/* configured via virtual maps or via similar lookup mechanisms.
-/* MAILBOX LOCATION
-/* .ad
-/* .fi
-/* The mailbox location is controlled by the \fBvirtual_mailbox_base\fR
-/* and \fBvirtual_mailbox_maps\fR configuration parameters (see below).
-/* The pathname is constructed as follows:
-/*
-/* .ti +2
-/* \fB$virtual_mailbox_base/$virtual_mailbox_maps(\fIrecipient\fB)\fR
-/*
-/* where \fIrecipient\fR is the full recipient address.
-/* UNIX MAILBOX FORMAT
-/* .ad
-/* .fi
-/* When the mailbox location does not end in \fB/\fR, the message
-/* is delivered in UNIX mailbox format. This format stores multiple
-/* messages in one textfile.
-/*
-/* The \fBvirtual\fR delivery agent prepends a "\fBFrom \fIsender
-/* time_stamp\fR" envelope header to each message, prepends a
-/* \fBDelivered-To:\fR message header with the envelope recipient
-/* address, prepends a \fBReturn-Path:\fR message 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.
-/* QMAIL MAILDIR FORMAT
-/* .ad
-/* .fi
-/* When the mailbox location ends in \fB/\fR, the message is delivered
-/* in qmail \fBmaildir\fR format. This format stores one message per file.
-/*
-/* The \fBvirtual\fR delivery agent daemon prepends a \fBDelivered-To:\fR
-/* message header with the envelope recipient address and prepends a
-/* \fBReturn-Path:\fR message header with the envelope sender address.
-/*
-/* By definition, \fBmaildir\fR format does not require file locking
-/* during mail delivery or retrieval.
-/* MAILBOX OWNERSHIP
-/* .ad
-/* .fi
-/* Mailbox ownership is controlled by the \fBvirtual_owner_maps\fR
-/* lookup tables. These tables can perform the following mappings:
-/* .IP "recipient username"
-/* The mailbox is owned by the specified UNIX user.
-/* .IP "recipient uid:gid"
-/* The mailbox is owned by the specified numerical user and group ID.
-/* BACKWARDS COMPATIBILITY
-/* .ad
-/* .fi
-/* For backwards compatibility, mailbox ownership can also be specified
-/* through separate \fBvirtual_uid_maps\fR and \fBvirtual_gid_maps\fR
-/* tables.
-/* SAFETY
-/* .ad
-/* .fi
-/* The \fBvirtual_minimum_uid\fR parameter imposes a lower bound on
-/* numerical user ID values that may be specified in any
-/* \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR.
-/* STANDARDS
-/* RFC 822 (ARPA Internet Text Messages)
-/* DIAGNOSTICS
-/* Mail bounces when the recipient has no mailbox or when the
-/* recipient is over disk quota. In all other cases, mail for
-/* an existing recipient is deferred and a warning is logged.
-/*
-/* 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.
-/* BUGS
-/* This delivery agent silently ignores address extensions.
-/* 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 these maps 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_owner_maps\fR or \fBvirtual_uid_maps\fR lookup.
-/* Returned values less than this will be rejected, and the message
-/* will be deferred.
-/* .IP \fBvirtual_owner_maps\fR
-/* Recipients are looked up in these maps to determine the UNIX user
-/* name of the mailbox owner, or the numerical user and group ID
-/* in numerical \fIuid:gid\fR format.
-/* .IP \fBvirtual_uid_maps\fR
-/* Recipients are looked up in these maps to determine the user ID to be
-/* used when writing to the target mailbox.
-/* .sp
-/* This feature exists for backwards compatibility; it will go away.
-/* .IP \fBvirtual_gid_maps\fR
-/* Recipients are looked up in these maps to determine the group ID to be
-/* used when writing to the target mailbox.
-/* .sp
-/* This feature exists for backwards compatibility; it will go away.
-/* .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.
-/*
-/* Use the command \fBpostconf -m\fR to find out what locking methods
-/* are available on your system.
-/* .IP \fBdeliver_lock_attempts\fR
-/* Limit the number of attempts to acquire an exclusive lock
-/* on a UNIX-style mailbox file.
-/* .IP \fBdeliver_lock_delay\fR
-/* Time (default: seconds) between successive attempts to acquire
-/* an exclusive lock on a UNIX-style mailbox file.
-/* .IP \fBstale_lock_time\fR
-/* Limit the time after which a stale lockfile is removed (applicable
-/* to UNIX-style mailboxes only).
-/* .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 Postfix local delivery
-/* agent. Modifications mainly consisted of removing code that either
-/* was not applicable or that was not safe in this context: aliases,
-/* ~user/.forward files, delivery to "|command" or to /file/name.
-/*
-/* 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);
-}
+++ /dev/null
-/*++
-/* 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
-/*--*/