2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-20010122

This commit is contained in:
Wietse Venema
2001-01-22 00:00:00 -05:00
committed by Viktor Dukhovni
parent 0f4cca51f3
commit 19ca5e1319
60 changed files with 1639 additions and 2696 deletions

View File

@@ -60,23 +60,20 @@ The filter program can start out as a simple shell script like this:
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
STATUS=$EX_TEMPFAIL
# 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

View File

@@ -4672,13 +4672,6 @@ Apologies for any names omitted.
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
@@ -4708,3 +4701,49 @@ Apologies for any names omitted.
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.

View File

@@ -1,99 +1,346 @@
BEGIN WARNING
=============
The information in this file is outdated. The Postfix LMTP server
can now make connections over UNIX-domain sockets.
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.
The precise syntax for UNIX-domain and TCP connection endpoints is
given in the lmtp(8) manual page.
Examples:
/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.
For optimal use of connection caching, specify separate mail delivery
transports for each domain that receives mail via LMTP:
END WARNING
===========
[Based on information that was provided by Amous Gouaux]
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.
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.
Configuring the mailbox server (local or remote)
================================================
Overview
========
On the mailbox server, in this case a CMU Cyrus imapd/popd server,
add the following to /etc/services:
Most of the examples in this document involve the CMU Cyrus IMAP/POP
server, available from:
pop3 110/tcp # Cyrus POP3
imap 143/tcp # Cyrus IMAP4
lmtp 24/tcp
http://asg.web.cmu.edu/cyrus/
Next, put the following in /etc/inetd.conf:
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.
lmtp stream tcp nowait cyrus /usr/sbin/tcpd /usr/local/cyrus/bin/deliver -e -l
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.
/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.
The precise syntax for UNIX-domain and TCP connection endpoints is
given in the lmtp(8) manual page.
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.
Configuring Postfix
===================
Using main.cf configuration
===========================
Similar changes to /etc/services:
This is the simplest LMTP configuration. The settings
local_transport, mailbox_transport, and fallback_transport can
support the following connections:
lmtp 24/tcp
1. LMTP over TCP sockets.
You may have to add the following entry to /etc/postfix/master.cf:
mailbox_transport = lmtp
lmtp unix - - n - - 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: Root privileges are not necessary!
NOTE:
Put this in /etc/postfix/transport:
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.
inbox.domain.org lmtp:inbox.domain.org
Naturally, this means we also need in /etc/postfix/main.cf:
2. LMTP over UNIX-domain sockets.
transport_maps = hash:/etc/postfix/transport
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
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
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.
Performance considerations
==========================
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.
Single instance message store
=============================
Presently this topic is more pertinent to sites running Cyrus, but
may be a factor with other applications as well.
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.
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.
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.
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
/etc/postfix/aliases:
mlist: "|/path/to/mlm/software"
/etc/postfix/master.cf:
lmtp unix - - n - - lmtp
/etc/postfix/main.cf:
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
/etc/cyrus.conf:
SERVICES {
...
lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
...
}
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.
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
========================================
@@ -112,6 +359,7 @@ You can prevent the LMTP client from switching between servers by
configuring a separate mail delivery transport for each LMTP server:
/etc/postfix/master.cf:
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
. . . . . . . .
@@ -121,5 +369,99 @@ transport is used for all deliveries to the LMTP server #1, the
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:

View File

@@ -6,7 +6,7 @@ DIRS = src/util src/global src/dns src/master src/postfix src/smtpstone \
src/lmtp src/trivial-rewrite src/qmgr src/smtp src/bounce src/pipe \
src/showq src/postalias src/postcat src/postconf src/postdrop \
src/postkick src/postlock src/postlog src/postmap src/postsuper \
src/nqmgr src/spawn src/flush src/virtual # src/base64 proto man html
src/nqmgr src/spawn src/flush # proto man html
default: update

View File

@@ -1,3 +1,6 @@
REJECT by header/body_checks are now flagged as policy violations
rather than bounces, for consistency in postmaster notifications.
Major changes with snapshot-20001217
====================================

View File

@@ -1,10 +1,23 @@
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
@@ -14,9 +27,6 @@ Note that this seems to be related to the auto_transition switch in
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
============
@@ -52,6 +62,12 @@ Reportedly, Microsoft Internet Explorer version 5 requires the
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
=================================================

View File

@@ -1,154 +0,0 @@
[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:
--/---

View File

@@ -0,0 +1,66 @@
# 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

View File

@@ -66,11 +66,24 @@ smtp_never_send_ehlo = 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

View File

@@ -63,6 +63,16 @@ smtpd_recipient_limit = 1000
#
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
#

View File

@@ -1,9 +1,14 @@
#! /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".
@@ -26,14 +31,29 @@
# 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
@@ -47,10 +67,18 @@ mkdir -p etc lib usr/lib/zoneinfo
# 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
# 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

View File

@@ -5,7 +5,7 @@ SHELL = /bin/sh
DAEMONS = bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html \
nqmgr.8.html spawn.8.html flush.8.html 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 \
@@ -81,9 +81,6 @@ smtpd.8.html: ../src/smtpd/smtpd.c
trivial-rewrite.8.html: ../src/trivial-rewrite/trivial-rewrite.c
srctoman $? | nroff -man | man2html | postlink >$@
virtual.8.html: ../src/virtual/virtual.c
srctoman $? | nroff -man | man2html | postlink >$@
postalias.1.html: ../src/postalias/postalias.c
srctoman $? | nroff -man | man2html | postlink >$@

View File

@@ -73,6 +73,7 @@ LMTP(8) LMTP(8)
<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-
@@ -119,12 +120,11 @@ LMTP(8) LMTP(8)
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.
@@ -137,6 +137,35 @@ LMTP(8) LMTP(8)
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:
@@ -162,6 +191,18 @@ LMTP(8) LMTP(8)
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.
@@ -192,17 +233,6 @@ LMTP(8) LMTP(8)
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
@@ -227,6 +257,18 @@ LMTP(8) LMTP(8)
<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
@@ -257,18 +299,6 @@ LMTP(8) LMTP(8)
<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
@@ -296,36 +326,6 @@ LMTP(8) LMTP(8)
5

View File

@@ -77,6 +77,11 @@ SMTPD(8) SMTPD(8)
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
@@ -119,11 +124,6 @@ SMTPD(8) SMTPD(8)
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.
@@ -137,6 +137,11 @@ SMTPD(8) SMTPD(8)
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-
@@ -186,11 +191,6 @@ SMTPD(8) SMTPD(8)
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.
@@ -203,6 +203,11 @@ SMTPD(8) SMTPD(8)
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.
@@ -253,11 +258,6 @@ SMTPD(8) SMTPD(8)
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
@@ -269,6 +269,10 @@ SMTPD(8) SMTPD(8)
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
@@ -319,10 +323,6 @@ SMTPD(8) SMTPD(8)
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.
@@ -335,6 +335,10 @@ SMTPD(8) SMTPD(8)
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
@@ -383,10 +387,6 @@ SMTPD(8) SMTPD(8)

View File

@@ -1,266 +0,0 @@
<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 &gt; character
to lines beginning with "<b>From</b> ", and appends an empty
line. The mailbox is locked for exclusive access while
delivery is in progress. In case of problems, an attempt
is made to truncate the mailbox to its original length.
In the case of <b>maildir</b> delivery, the local daemon prepends
a <b>Delivered-To:</b> header with the envelope recipient address
and prepends a <b>Return-Path:</b> header with the envelope
sender address.
<b>DELIVERY</b> <b>RIGHTS</b>
Deliveries 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>

View File

@@ -5,7 +5,7 @@ SHELL = /bin/sh
DAEMONS = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 \
man8/nqmgr.8 man8/spawn.8 man8/flush.8 man8/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 \
@@ -80,9 +80,6 @@ man8/smtpd.8: ../src/smtpd/smtpd.c
man8/trivial-rewrite.8: ../src/trivial-rewrite/trivial-rewrite.c
../mantools/srctoman $? >$@
man8/virtual.8: ../src/virtual/virtual.c
../mantools/srctoman $? >$@
man1/postalias.1: ../src/postalias/postalias.c
../mantools/srctoman $? >$@

View File

@@ -59,6 +59,7 @@ RFC 1651 (SMTP service extensions)
RFC 1870 (Message Size Declaration)
RFC 2033 (LMTP protocol)
RFC 2197 (Pipelining)
RFC 2554 (AUTH command)
.SH DIAGNOSTICS
.ad
.fi
@@ -101,6 +102,27 @@ Do not wait for the server response after sending QUIT.
.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

View File

@@ -71,6 +71,10 @@ a configuration change.
.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

View File

@@ -1,183 +0,0 @@
.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

View File

@@ -1 +0,0 @@
../../.indent.pro

View File

@@ -1,79 +0,0 @@
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

View File

@@ -1,63 +0,0 @@
/* 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);
}

View File

@@ -1,77 +0,0 @@
/* 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);
}

View File

@@ -339,10 +339,10 @@ int bounce_boilerplate(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
"####################################################################");
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);
}

View File

@@ -428,13 +428,6 @@ header_opts.o: header_opts.h
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

View File

@@ -237,6 +237,14 @@ extern char *var_rcpt_witheld;
#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.
*/
@@ -712,7 +720,7 @@ extern int var_smtpd_err_sleep;
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
@@ -727,7 +735,7 @@ extern char *var_smtpd_sasl_opts;
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
@@ -741,6 +749,24 @@ extern char *var_smtp_sasl_passwd;
#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"
/*
@@ -862,7 +888,7 @@ extern int var_fork_delay;
* 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"
@@ -1110,18 +1136,23 @@ extern char *var_export_environ;
#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;

View File

@@ -415,7 +415,8 @@ VSTREAM *mail_queue_open(const char *queue_name, const char *queue_id,
* 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);
}

View File

@@ -15,7 +15,7 @@
* 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

View File

@@ -1,8 +1,10 @@
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 \
@@ -79,6 +81,7 @@ lmtp.o: ../../include/debug_peer.h
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
@@ -113,6 +116,8 @@ lmtp_chat.o: ../../include/mail_params.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
@@ -155,9 +160,42 @@ lmtp_proto.o: ../../include/record.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
@@ -176,12 +214,12 @@ lmtp_state.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

View File

@@ -49,6 +49,7 @@
/* 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
@@ -85,6 +86,27 @@
/* .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
@@ -231,6 +253,7 @@
/* Application-specific. */
#include "lmtp.h"
#include "lmtp_sasl.h"
/*
* Tunable parameters. These have compiled-in defaults that can be overruled
@@ -252,6 +275,9 @@ int var_lmtp_cache_conn;
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.
@@ -432,6 +458,10 @@ static void post_init(char *unused_name, char **unused_argv)
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. */
@@ -446,6 +476,10 @@ static void cleanup(void)
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 */
@@ -467,6 +501,8 @@ int main(int argc, char **argv)
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[] = {

View File

@@ -8,6 +8,14 @@
/* DESCRIPTION
/* .nf
/*
* SASL library.
*/
#ifdef USE_SASL_AUTH
#include <sasl.h>
#include <saslutil.h>
#endif
/*
* Utility library.
*/
@@ -35,6 +43,15 @@ typedef struct LMTP_STATE {
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 */
@@ -44,6 +61,7 @@ typedef struct LMTP_STATE {
#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

View File

@@ -104,6 +104,7 @@
#include <mail_params.h>
#include <mail_addr.h>
#include <post_mail.h>
#include <mail_error.h>
/* Application-specific. */
@@ -172,7 +173,6 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
{
LMTP_SESSION *session = state->session;
static LMTP_RESP rdata;
int more;
char *cp;
int last_char;
@@ -190,17 +190,12 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
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
@@ -212,13 +207,23 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
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);

View File

@@ -116,11 +116,12 @@
#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
@@ -193,7 +194,7 @@ int lmtp_lhlo(LMTP_STATE *state)
*/
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", " ")));
/*
@@ -202,7 +203,7 @@ int lmtp_lhlo(LMTP_STATE *state)
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", " ")));
@@ -223,11 +224,20 @@ int lmtp_lhlo(LMTP_STATE *state)
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
@@ -463,7 +473,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
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;
}
@@ -487,7 +497,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
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 */
}
@@ -505,7 +515,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
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;
}
@@ -535,7 +545,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
}
} 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 */
}

View File

@@ -0,0 +1,39 @@
/*++
/* 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
/*--*/

View File

@@ -0,0 +1,512 @@
/*++
/* 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

View File

@@ -0,0 +1,120 @@
/*++
/* 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

View File

@@ -53,11 +53,12 @@
/* Global library. */
#include <config.h>
#include <mail_conf.h>
/* Application-specific. */
#include "lmtp.h"
#include "lmtp_sasl.h"
/* lmtp_state_alloc - initialize */
@@ -75,6 +76,9 @@ LMTP_STATE *lmtp_state_alloc(void)
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;
@@ -88,5 +92,8 @@ void lmtp_state_free(LMTP_STATE *state)
vstring_free(state->buffer);
vstring_free(state->scratch);
vstring_free(state->scratch2);
#ifdef USE_SASL_AUTH
lmtp_sasl_cleanup(state);
#endif
myfree((char *) state);
}

View File

@@ -93,6 +93,7 @@ postconf.o: time_vars.h
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
@@ -101,3 +102,4 @@ postconf.o: int_table.h
postconf.o: str_table.h
postconf.o: local_table.h
postconf.o: smtp_table.h
postconf.o: raw_table.h

View File

@@ -420,7 +420,7 @@ static void set_parameters(void)
* 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.
*
@@ -790,9 +790,6 @@ int main(int argc, char **argv)
case 'd':
mode |= SHOW_DEFS;
break;
case 'E':
mode |= SHOW_EVAL;
break;
case 'e':
mode |= EDIT_MAIN;
break;

View File

@@ -162,9 +162,9 @@ smtp_proto.o: ../../include/record.h
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

View File

@@ -85,7 +85,7 @@ extern void smtp_session_free(SMTP_SESSION *);
*/
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

View File

@@ -6,9 +6,10 @@
/* 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;
@@ -279,11 +280,11 @@ static int smtp_compare_mx(DNS_RR *a, DNS_RR *b)
/* 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;
@@ -363,6 +364,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
/*
* Clean up.
*/
*found_myself = (self != 0);
return (addr_list);
}

View File

@@ -17,7 +17,7 @@
* 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

View File

@@ -292,7 +292,8 @@ SMTP_SESSION *smtp_connect_host(char *host, unsigned port, VSTRING *why)
/* 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;
@@ -306,7 +307,7 @@ SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why)
* 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);
@@ -393,6 +394,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why)
char *save;
char *dest;
char *cp;
int found_myself;
/*
* First try to deliver to the indicated destination, then try to deliver
@@ -417,7 +419,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why)
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);
@@ -426,7 +428,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why)
* 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;
}

View File

@@ -98,11 +98,11 @@
#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"
/*
@@ -226,6 +226,8 @@ int smtp_helo(SMTP_STATE *state)
#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",

View File

@@ -133,7 +133,7 @@ static void smtp_check_code(SMTP_STATE *state, int code)
* 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;
}

View File

@@ -57,6 +57,10 @@
/* .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
@@ -343,6 +347,7 @@ bool var_smtpd_sasl_enable;
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
@@ -439,8 +444,11 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
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);
@@ -949,7 +957,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
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;
@@ -1447,6 +1455,7 @@ int main(int argc, char **argv)
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[] = {

View File

@@ -329,12 +329,19 @@ static void disconnect(SINK_STATE *state)
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);

View File

@@ -136,10 +136,11 @@ static const char *var_myhostname;
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;
@@ -398,7 +399,7 @@ static void start_connect(SESSION *session)
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);
}
@@ -842,7 +843,7 @@ int main(int argc, char **argv)
#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;
@@ -853,7 +854,7 @@ int main(int argc, char **argv)
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);
}
/*

View File

@@ -383,18 +383,6 @@ dict_db.o: argv.h
dict_db.o: dict_db.h
dict_dbm.o: dict_dbm.c
dict_dbm.o: sys_defs.h
dict_dbm.o: msg.h
dict_dbm.o: mymalloc.h
dict_dbm.o: htable.h
dict_dbm.o: iostuff.h
dict_dbm.o: vstring.h
dict_dbm.o: vbuf.h
dict_dbm.o: myflock.h
dict_dbm.o: stringops.h
dict_dbm.o: dict.h
dict_dbm.o: vstream.h
dict_dbm.o: argv.h
dict_dbm.o: dict_dbm.h
dict_env.o: dict_env.c
dict_env.o: sys_defs.h
dict_env.o: mymalloc.h
@@ -418,14 +406,6 @@ dict_ldap.o: dict_ldap.c
dict_ldap.o: sys_defs.h
dict_mysql.o: dict_mysql.c
dict_mysql.o: sys_defs.h
dict_mysql.o: dict.h
dict_mysql.o: vstream.h
dict_mysql.o: vbuf.h
dict_mysql.o: argv.h
dict_mysql.o: msg.h
dict_mysql.o: mymalloc.h
dict_mysql.o: dict_mysql.h
dict_mysql.o: vstring.h
dict_ni.o: dict_ni.c
dict_ni.o: sys_defs.h
dict_nis.o: dict_nis.c

View File

@@ -81,8 +81,18 @@ int make_dirs(const char *path, int perms)
} 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;

View File

@@ -1 +0,0 @@
../../.indent.pro

View File

@@ -1,441 +0,0 @@
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

View File

@@ -1,74 +0,0 @@
/*++
/* 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");
}

View File

@@ -1,232 +0,0 @@
/*++
/* 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);
}

View File

@@ -1,159 +0,0 @@
/*++
/* 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);
}

View File

@@ -1,93 +0,0 @@
/*++
/* 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);
}

View File

@@ -1,64 +0,0 @@
/*++
/* 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));
}

View File

@@ -1,392 +0,0 @@
/*++
/* 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);
}

View File

@@ -1,134 +0,0 @@
/*++
/* 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
/*--*/