not part of release 1.1.2
This commit is contained in:
parent
1f31e11b0f
commit
5cf194aa6d
|
@ -1,68 +0,0 @@
|
|||
Purpose of this document
|
||||
========================
|
||||
|
||||
This document describes how to build Postfix with third-party
|
||||
Berkeley DB from www.sleepycat.com, or how to choose a specific
|
||||
Berkeley DB version when your system provides multiple implementations.
|
||||
|
||||
Building Postfix with Sleepycat Berkeley DB
|
||||
===========================================
|
||||
|
||||
Many commercial UNIXes ship without Berkeley DB support. Examples
|
||||
are Solaris, HP-UX, IRIX, UNIXWARE. In order to build Postfix with
|
||||
Berkeley DB support you need to download and install the source
|
||||
code from www.sleepycat.com.
|
||||
|
||||
To build Postfix after you installed the Berkeley DB from Sleepycat,
|
||||
use something like:
|
||||
|
||||
% make tidy
|
||||
% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB.3.1/include" \
|
||||
AUXLIBS="-L/usr/local/BerkeleyDB.3.1/lib -ldb"
|
||||
% make
|
||||
|
||||
The exact pathnames depend on the DB version that you installed.
|
||||
For example, Berkeley DB version 2 installs in /usr/local/BerkeleyDB.
|
||||
|
||||
Beware, the file format produced by Berkeley DB version 1 is not
|
||||
compatible with that of versions 2 and 3 (versions 2 and 3 have
|
||||
the same format). If you switch between DB versions, then you may
|
||||
have to rebuild all your Postfix DB files.
|
||||
|
||||
Building Postfix on BSD systems with a specific Berkeley DB version
|
||||
===================================================================
|
||||
|
||||
Some BSD systems ship with multiple Berkeley DB implementations.
|
||||
Normally, Postfix builds with the default DB version that ships
|
||||
with the system.
|
||||
|
||||
To build Postfix on BSD systems with a specific DB version, use a
|
||||
variant of the following commands:
|
||||
|
||||
% make tidy
|
||||
% make makefiles CCARGS=-I/usr/include/db2 AUXLIBS=-ldb2
|
||||
% make
|
||||
|
||||
Beware, the file format produced by Berkeley DB version 1 is not
|
||||
compatible with that of versions 2 and 3 (versions 2 and 3 have
|
||||
the same format). If you switch between DB versions, then you may
|
||||
have to rebuild all your Postfix DB files.
|
||||
|
||||
Building Postfix on Linux with a specific Berkeley DB version
|
||||
=============================================================
|
||||
|
||||
Some Linux systems systems ship with multiple Berkeley DB
|
||||
implementations. Normally, Postfix builds with the default DB
|
||||
version that ships with the system.
|
||||
|
||||
On Linux, you need to edit the makedefs script in order to specify
|
||||
a non-default DB library.
|
||||
|
||||
The reason is that the location of the default db.h include file
|
||||
changes randomly between vendors and between versions, so that
|
||||
Postfix has to choose the file for you.
|
||||
|
||||
Beware, the file format produced by Berkeley DB version 1 is not
|
||||
compatible with that of versions 2 and 3 (versions 2 and 3 have
|
||||
the same format). If you switch between DB versions, then you may
|
||||
have to rebuild all your Postfix DB files.
|
|
@ -1,153 +0,0 @@
|
|||
1 - Purpose of this document
|
||||
============================
|
||||
|
||||
This document describes how to debug parts of the Postfix mail
|
||||
system, either by making the software log a lot of detail to the
|
||||
syslog daemon, or by running some daemon processes under control
|
||||
of an interactive debugger.
|
||||
|
||||
2 - Verbose logging for specific SMTP connections
|
||||
=================================================
|
||||
|
||||
In /etc/postfix/main.cf, list the remote site name or address in
|
||||
the "debug_peer_list" parameter. For example, in order to make the
|
||||
software log a lot of information to the syslog daemon for connections
|
||||
from or to the loopback interface:
|
||||
|
||||
debug_peer_list = 127.0.0.1
|
||||
|
||||
You can specify one or more hosts, domains, addresses or net/masks.
|
||||
|
||||
2b - Record the SMTP connection with a sniffer
|
||||
==============================================
|
||||
|
||||
This example uses tcpdump. In order to record a conversation you
|
||||
need to specify a large enough buffer or else you will miss some
|
||||
or all of the packet payload.
|
||||
|
||||
tcpdump -w /file/name -s 2000 host hostname and port 25
|
||||
|
||||
Run this for a while, stop with Ctrl-C when done. To view the data
|
||||
use a binary viewer, or use my tcpdumpx utility that is available
|
||||
from ftp://ftp.porcupine.org/pub/debugging.
|
||||
|
||||
3 - Making Postfix daemon programs more verbose
|
||||
===============================================
|
||||
|
||||
Append one or more -v options to selected daemon definitions in
|
||||
/etc/postfix/master.cf and type "postfix reload". This will cause
|
||||
a lot of activity to be logged to the syslog daemon.
|
||||
|
||||
4 - Manually tracing a Postfix daemon process
|
||||
=============================================
|
||||
|
||||
Some systems allow you to inspect a running process with a system
|
||||
call tracer. For example:
|
||||
|
||||
# trace -p process-id
|
||||
# strace -p process-id
|
||||
# truss -p process-id
|
||||
# ktrace -p process-id
|
||||
|
||||
See your system documentation for details.
|
||||
|
||||
Tracing a running process can give valuable information about what
|
||||
a process is attempting to do. This is as much information as you
|
||||
can get without running an interactive debugger program, as described
|
||||
in a later section.
|
||||
|
||||
5 - Automatically tracing a Postfix daemon process
|
||||
==================================================
|
||||
|
||||
Postfix can attach a call tracer whenever a daemon process starts.
|
||||
|
||||
Append a -D option to the suspect command in /etc/postfix/master.cf,
|
||||
for example:
|
||||
|
||||
smtp inet n - n - - smtpd -D
|
||||
|
||||
Edit the debugger_command definition in /etc/postfix/main.cf so
|
||||
that it invokes the call tracer of your choice, for example:
|
||||
|
||||
debugger_command =
|
||||
PATH=/bin:/usr/bin:/usr/local/bin
|
||||
(truss -p $process_id 2>&1 | logger -p mail.info) & sleep 5
|
||||
|
||||
Instead of truss use trace or strace.
|
||||
|
||||
Type "postfix reload" and watch the logfile.
|
||||
|
||||
6 - Running daemon programs under an interactive debugger
|
||||
=========================================================
|
||||
|
||||
Append a -D option to the suspect command in /etc/postfix/master.cf,
|
||||
for example:
|
||||
|
||||
smtp inet n - n - - smtpd -D
|
||||
|
||||
Edit the debugger_command definition in /etc/postfix/main.cf so
|
||||
that it invokes the debugger of your choice, for example:
|
||||
|
||||
debugger_command =
|
||||
PATH=/usr/bin:/usr/X11R6/bin
|
||||
xxgdb $daemon_directory/$process_name $process_id & sleep 5
|
||||
|
||||
If you use xxgdb, be sure that gdb is in the command search path.
|
||||
|
||||
Export XAUTHORITY so that X access control works, for example:
|
||||
|
||||
% setenv XAUTHORITY ~/.Xauthority
|
||||
|
||||
Stop and start the Postfix system.
|
||||
|
||||
Whenever the suspect daemon process is started, a debugger window
|
||||
pops up and you can watch in detail what happens.
|
||||
|
||||
7 - Unreasonable behavior
|
||||
=========================
|
||||
|
||||
Sometimes the behavior exhibit by Postfix just does not match the
|
||||
source code. Why can a program deviate from the instructions given
|
||||
by its author? There are two possibilities.
|
||||
|
||||
1 - The compiler has messed up.
|
||||
|
||||
2 - The hardware has messed up.
|
||||
|
||||
In both cases, the program being executed is not the program that
|
||||
was supposed to be executed, so anything can happen.
|
||||
|
||||
There is a third possibility:
|
||||
|
||||
3 - Bugs in system software (kernel or libraries).
|
||||
|
||||
Hardware-related failures happen erratically, and they usually do
|
||||
not reproduce after power cycling and rebooting the system. There's
|
||||
little I can do about bad hardware. Be sure to use hardware that
|
||||
at the very least can detect memory errors. Otherwise, Postfix will
|
||||
just be a sitting duck waiting to be hit by a bit error. Critical
|
||||
systems deserve real hardware.
|
||||
|
||||
When a compiler messes up, the problem can be reproduced whenever
|
||||
the resulting program is run. Compiler errors are most likely to
|
||||
happen in the code optimizer. If a problem is reproducible across
|
||||
power cycles and system reboots, it can be worthwhile to rebuild
|
||||
Postfix with optimization disabled, and to see if optimization
|
||||
makes a difference.
|
||||
|
||||
In order to compile Postfix with optimizations turned off:
|
||||
|
||||
% make tidy
|
||||
% make makefiles OPT=
|
||||
|
||||
This produces a set of Makefiles that do not request compiler
|
||||
optimization.
|
||||
|
||||
Once the makefiles are set up, build the software:
|
||||
|
||||
% make
|
||||
% su
|
||||
# make install
|
||||
|
||||
And see if the problem reproduces. If the problem goes away, talk
|
||||
to your vendor.
|
|
@ -1,117 +0,0 @@
|
|||
Purpose of this document
|
||||
========================
|
||||
|
||||
This document describes the purpose of the Postfix fast ETRN service,
|
||||
how the service works, and how it can be tested.
|
||||
|
||||
Other documents with information on this subject:
|
||||
|
||||
- conf/sample-flush.cf, sample configuration file
|
||||
- conf/main.cf, sample configuration file
|
||||
- flush(8), flush service implementation
|
||||
|
||||
The Postfix fast ETRN service
|
||||
=============================
|
||||
|
||||
The SMTP ETRN command was designed for sites that have intermittent
|
||||
Internet connectivity. With ETRN, a site can tell the mail server
|
||||
of its provider to "Please deliver all my mail now".
|
||||
|
||||
Postfix versions before 20001005 implemented the ETRN command in
|
||||
a lame manner: they simply attempted to deliver all queued mail.
|
||||
This is slow on mail servers that queue mail for many customers.
|
||||
|
||||
As of version 20001005, Postfix has a fast ETRN implementation that
|
||||
does not require Postfix to examine every queue file. The command
|
||||
"sendmail -qR" is now implemented by sending an ETRN command to
|
||||
the local SMTP server.
|
||||
|
||||
Postfix "fast ETRN/sendmail -qR" speeds up deliveries by attempting
|
||||
to deliver only mail that is queued for a given destination site.
|
||||
The old Postfix "slow ETRN" is still used as a fall-back method.
|
||||
|
||||
How Postfix fast ETRN works
|
||||
===========================
|
||||
|
||||
The "fast ETRN" service uses the new "flush" daemon which maintains
|
||||
per-destination logfiles of queued mail. These logfiles are kept
|
||||
below /var/spool/postfix/flush. Each logfile is named after its
|
||||
destination domain name. Only destinations with syntactically valid
|
||||
domain names can have per-destination logfiles.
|
||||
|
||||
The behavior of the new "flush" daemon is controlled by parameters
|
||||
in the main.cf configuration file.
|
||||
|
||||
By default, Postfix "fast ETRN/sendmail -qR" service is available
|
||||
only for destinations that Postfix is willing to relay mail to:
|
||||
|
||||
fast_flush_domains = $relay_domains
|
||||
|
||||
The "relay_domains" parameter specifies what destinations Postfix
|
||||
will relay to.
|
||||
|
||||
For destinations that are not eligible for the new "fast ETRN/sendmail
|
||||
-qR" service, Postfix falls back to the old "slow ETRN" method
|
||||
which attempts to deliver all queued mail.
|
||||
|
||||
To enable "fast ETRN/sendmail -qR" for some other destination, specify:
|
||||
|
||||
fast_flush_domains = $relay_domains, some.other.domain
|
||||
|
||||
To disable "fast ETRN/sendmail -qR", so that Postfix always uses
|
||||
the old "slow ETRN" which delivers all queued mail, specify:
|
||||
|
||||
fast_flush_domains =
|
||||
|
||||
Testing the fast ETRN service
|
||||
=============================
|
||||
|
||||
If you run Postfix with "fast ETRN" service for the very first
|
||||
time, you need to run "sendmail -q" to populate the per-site deferred
|
||||
mail logfiles. If you omit this step, the logfiles will eventually
|
||||
become populated as Postfix routinely attempts to deliver delayed
|
||||
mail, but that will take a couple hours.
|
||||
|
||||
After the "sendmail -q" has completed all delivery attempts (that
|
||||
can take a while), you're ready to test the "fast ETRN" service.
|
||||
Telnet to the Postfix SMTP server from a client that is allowed to
|
||||
execute ETRN commands (by default, that's every client), and type:
|
||||
|
||||
helo my.client.name
|
||||
etrn some.customer.domain
|
||||
|
||||
where "some.customer.domain" is the name of a domain that has a
|
||||
non-empty logfile somewhere under /var/spool/postfix/flush.
|
||||
|
||||
In the maillog file, you should immediately see a couple of logfile
|
||||
records, as evidence that the queue manager has opened queue files:
|
||||
|
||||
Oct 2 10:51:19 localhost postfix/qmgr[51999]: 682E8440A4:
|
||||
from=<whatever>, size=12345, nrcpt=1 (queue active)
|
||||
Oct 2 10:51:19 localhost postfix/qmgr[51999]: 02249440B7:
|
||||
from=<whatever>, size=4711, nrcpt=1 (queue active)
|
||||
|
||||
What happens next depends on whether the destination is reachable.
|
||||
If it's not reachable, the mail queue IDs will be added back to
|
||||
the some.customer.domain logfile under /var/spool/postfix/flush.
|
||||
|
||||
Repeat the exercise with another domain that your server is willing
|
||||
to relay to (domain listed in "relay_domains"), but that has no mail
|
||||
queued.
|
||||
|
||||
helo my.client.name
|
||||
etrn some.other.customer.domain
|
||||
|
||||
This time, the "etrn" command should trigger NO mail deliveries at
|
||||
all. If this triggers delivery of all mail, then you used the wrong
|
||||
domain name, or "fast ETRN" service is turned off.
|
||||
|
||||
Finally, repeat the exercise with a destination that your mail
|
||||
server is not willing to relay to. It does not matter if your
|
||||
server has mail queued for that destination.
|
||||
|
||||
helo my.client.name
|
||||
etrn not.a.customer.domain
|
||||
|
||||
If your "fast ETRN" caching policy is left at its default setting,
|
||||
then the "etrn" command should trigger delivery of all queued mail.
|
|
@ -1,216 +0,0 @@
|
|||
This is a very first implementation of Postfix content filtering.
|
||||
A Postfix content filter receives unfiltered mail from Postfix and
|
||||
either bounces the mail or re-injects filtered mail back into Postfix.
|
||||
|
||||
It involves an incompatible change to queue file formats. Older
|
||||
Postfix versions will reject mail that needs to be content filtered,
|
||||
and will move the queue file to the "corrupt" mail queue subdirectory.
|
||||
|
||||
This document describes two approaches to content filtering.
|
||||
|
||||
Simple content filtering example
|
||||
================================
|
||||
|
||||
The first example is simpler to set up, but is also more resource
|
||||
intensive. With the shell script as shown you will lose a factor
|
||||
of four in Postfix performance for transit mail that arrives and
|
||||
leaves via SMTP. You will lose another factor in transit performance
|
||||
for each additional temporary file that is created and deleted in
|
||||
the process of content filtering. The performance impact is less
|
||||
for mail that is submitted or delivered locally, because such
|
||||
deliveries are not as fast as SMTP transit mail.
|
||||
|
||||
The example assumes that only mail arriving via SMTP needs to be
|
||||
content filtered.
|
||||
|
||||
..................................
|
||||
: Postfix :
|
||||
----->smtpd \ /local---->
|
||||
: -cleanup->queue- :
|
||||
---->pickup / \smtp----->
|
||||
^ : | :
|
||||
| : \pipe-----+
|
||||
| .................................. |
|
||||
| |
|
||||
| |
|
||||
+------sendmail<-------filter<---------+
|
||||
|
||||
1 - Create a dedicated local user account called "filter". The
|
||||
user will never log in, and can be given a "*" password and
|
||||
non-existent shell and home directory. This user handles all
|
||||
potentially dangerous mail content - that is why it should be
|
||||
a separate account.
|
||||
|
||||
2 - Create a directory /var/spool/filter that is accessible only
|
||||
to the "filter" user. This is where the content filtering will
|
||||
store its temporary files.
|
||||
|
||||
3 - Define a content filtering entry in the Postfix master file:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
filter unix - n n - - pipe
|
||||
flags=R user=filter argv=/some/where/filter -f ${sender} -- ${recipient}
|
||||
|
||||
The /some/where/filter program can be a simple shell script like this:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
# Localize these
|
||||
INSPECT_DIR=/var/spool/filter
|
||||
SENDMAIL="/usr/sbin/sendmail -i"
|
||||
|
||||
# Exit codes from <sysexits.h>
|
||||
EX_TEMPFAIL=75
|
||||
EX_UNAVAILABLE=69
|
||||
|
||||
# Clean up when done or when aborting.
|
||||
trap "rm -f in.$$" 0 1 2 3 15
|
||||
|
||||
# Start processing.
|
||||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
|
||||
|
||||
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
|
||||
|
||||
# filter <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
|
||||
|
||||
$SENDMAIL "$@" <in.$$
|
||||
|
||||
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
|
||||
mail cannot be captured to file, mail delivery is deferred by
|
||||
terminating with exit status 75 (EX_TEMPFAIL). If the content
|
||||
filter program finds a problem, the mail is bounced by terminating
|
||||
the shell script with exit status 69 (EX_UNAVAILABLE). If the
|
||||
content is OK, it is given as input to Postfix sendmail, and the
|
||||
exit status of the filter command is whatever exit status Postfix
|
||||
sendmail produces.
|
||||
|
||||
I suggest that you play with this script for a while until you are
|
||||
satisfied with the results. Run it as the filter user, with a real
|
||||
message (headers+body) as input:
|
||||
|
||||
% /some/where/filter -f sender recipient... <message-file
|
||||
|
||||
Turn on content filtering for mail arriving via SMTP only, by
|
||||
appending "-o content_filter=filter:dummy" to the master.cf
|
||||
entry that defines the Postfix SMTP server:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
smtp inet ...stuff... smtpd
|
||||
-o content_filter=filter:dummy
|
||||
|
||||
The content_filter configuration parameter accepts the same
|
||||
syntax as the right-hand side in a Postfix transport table.
|
||||
|
||||
Simple content filter limitations
|
||||
=================================
|
||||
|
||||
The problem with content filters like the one above is that they
|
||||
are not very robust, because the software does not talk a well-defined
|
||||
protocol with Postfix. If the filter shell script aborts because
|
||||
the shell runs into some memory allocation problem, the script will
|
||||
not produce a nice exit status as per /usr/include/sysexits.h and
|
||||
mail will probably bounce. The same lack of robustness is possible
|
||||
when the content filtering software itself runs into a resource
|
||||
problem.
|
||||
|
||||
Advanced content filtering example
|
||||
===================================
|
||||
|
||||
The second example is considerably more complex, but can give much
|
||||
better performance, and is less likely to bounce mail when the
|
||||
machine runs into a resource problem. This approach uses content
|
||||
filtering software that can receive and deliver mail via SMTP.
|
||||
You can expect to lose about a factor of two in Postfix performance
|
||||
for transit mail that arrives and leaves via SMTP, provided that
|
||||
you create no temporary files. Each temporary file adds another
|
||||
factor to the performance loss.
|
||||
|
||||
We will set up a content filtering program that receives SMTP mail
|
||||
via localhost port 10025, and that submits SMTP mail back into
|
||||
Postfix via localhost port 10026.
|
||||
|
||||
..................................
|
||||
: Postfix :
|
||||
----->smtpd \ /local---->
|
||||
: -cleanup->queue- :
|
||||
---->pickup / ^ | \smtp----->
|
||||
: | v :
|
||||
: smtpd smtp :
|
||||
: 10026 | :
|
||||
......................|...........
|
||||
^ |
|
||||
| v
|
||||
....|............
|
||||
: | 10025 :
|
||||
: filter :
|
||||
: :
|
||||
.................
|
||||
|
||||
To enable content filtering in this manner, specify in main.cf a
|
||||
new parameter:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
content_filter = smtp:localhost:10025
|
||||
|
||||
This causes Postfix to add one extra content filtering record to
|
||||
each incoming mail message, with content smtp:localhost:10025.
|
||||
You can use the same syntax as in the right-hand side of a Postfix
|
||||
transport table. The content filtering records are added by the
|
||||
smtpd and pickup servers.
|
||||
|
||||
When a queue file has content filtering information, the queue
|
||||
manager will deliver the mail to the specified content filter
|
||||
regardless of its final destination.
|
||||
|
||||
The content filter can be set up with the Postfix spawn service,
|
||||
which is the Postfix equivalent of inetd. For example, to instantiate
|
||||
up to 10 content filtering processes on demand:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
localhost:10025 inet n n n - 10 spawn
|
||||
user=filter argv=/some/where/filter localhost 10026
|
||||
|
||||
"filter" is a dedicated local user account. The user will never
|
||||
log in, and can be given a "*" password and non-existent shell and
|
||||
home directory. This user handles all potentially dangerous mail
|
||||
content - that is why it should be a separate account.
|
||||
|
||||
In the above example, Postfix listens on port localhost:10025. If
|
||||
you want to have your filter listening on port localhost:10025
|
||||
instead of Postfix, then you must run your filter as a stand-alone
|
||||
program.
|
||||
|
||||
Note: the localhost port 10025 SMTP server filter should announce
|
||||
itself as "220 localhost...", to silence warnings in the log.
|
||||
|
||||
The /some/where/filter command is most likely a PERL script. PERL
|
||||
has modules that make talking SMTP easy. The command-line specifies
|
||||
that mail should be sent back into Postfix via localhost port 10026.
|
||||
|
||||
For now, it is left up to the Postfix users to come up with a
|
||||
PERL/SMTP framework for Postfix content filtering. If done well,
|
||||
it can be used with other mailers too, which is a nice spin-off.
|
||||
|
||||
The simplest content filter just copies SMTP commands and data
|
||||
between its inputs and outputs. If it has a problem, all it has to
|
||||
do is to reply to an input of `.' with `550 content rejected', and
|
||||
to disconnect without sending `.' on the connection that injects
|
||||
mail back into Postfix.
|
||||
|
||||
The job of the content filter is to either bounce mail with a
|
||||
suitable diagnostic, or to feed the mail back into Postfix through
|
||||
a dedicated listener on port localhost 10026:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
localhost:10026 inet n - n - 10 smtpd
|
||||
-o content_filter= -o myhostname=localhost.domain.name
|
||||
|
||||
This is just another SMTP server. It is configured NOT to request
|
||||
content filtering for incoming mail, has the same process limit
|
||||
as the filter master.cf entry, and is configured to use a different
|
||||
hostname in the greeting message (this is necessary for testing
|
||||
when I simply use no filtering program and let the SMTP content
|
||||
filtering interfaces talk directly to each other).
|
|
@ -1,373 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Sample Postfix installation script. Run this from the top-level
|
||||
# Postfix source directory.
|
||||
|
||||
PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc
|
||||
umask 022
|
||||
|
||||
test -t 0 &&
|
||||
cat <<EOF
|
||||
|
||||
Warning: this script replaces existing sendmail or Postfix programs.
|
||||
Make backups if you want to be able to recover.
|
||||
|
||||
In addition to doing a fresh install, this script can change an
|
||||
existing installation from using a world-writable maildrop to a
|
||||
group-writable one. It cannot be used to change Postfix queue
|
||||
file/directory ownership.
|
||||
|
||||
Before installing files, this script prompts you for some definitions.
|
||||
Most definitions will be remembered, so you have to specify them
|
||||
only once. All definitions have a reasonable default value.
|
||||
|
||||
install_root - prefix for installed file names (for package building)
|
||||
|
||||
tempdir - where to write scratch files
|
||||
|
||||
config_directory - directory with Postfix configuration files.
|
||||
daemon_directory - directory with Postfix daemon programs.
|
||||
command_directory - directory with Postfix administrative commands.
|
||||
queue_directory - directory with Postfix queues.
|
||||
|
||||
sendmail_path - full pathname of the Postfix sendmail command.
|
||||
newaliases_path - full pathname of the Postfix newaliases command.
|
||||
mailq_path - full pathname of the Postfix mailq command.
|
||||
|
||||
mail_owner - owner of Postfix queue files.
|
||||
|
||||
setgid - groupname, e.g., postdrop (default: no). See INSTALL section 12.
|
||||
manpages - "no" or path to man tree. Example: /usr/local/man.
|
||||
|
||||
EOF
|
||||
|
||||
# By now, shells must have functions. Ultrix users must use sh5 or lose.
|
||||
# The following shell functions replace files/symlinks while minimizing
|
||||
# the time that a file does not exist, and avoid copying over programs
|
||||
# in order to not disturb running programs.
|
||||
|
||||
censored_ls() {
|
||||
ls "$@" | egrep -v '^\.|/\.|CVS|RCS|SCCS'
|
||||
}
|
||||
|
||||
compare_or_replace() {
|
||||
(cmp $2 $3 >/dev/null 2>&1 && echo Skipping $3...) || {
|
||||
echo Updating $3...
|
||||
rm -f $tempdir/junk || exit 1
|
||||
cp $2 $tempdir/junk || exit 1
|
||||
chmod $1 $tempdir/junk || exit 1
|
||||
mv -f $tempdir/junk $3 || exit 1
|
||||
chmod $1 $3 || exit 1
|
||||
}
|
||||
}
|
||||
|
||||
compare_or_symlink() {
|
||||
(cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
|
||||
echo Updating $2...
|
||||
rm -f $tempdir/junk || exit 1
|
||||
dest=`echo $1 | sed '
|
||||
s;^'$install_root';;
|
||||
s;/\./;/;g
|
||||
s;//*;/;g
|
||||
s;^/;;
|
||||
'`
|
||||
link=`echo $2 | sed '
|
||||
s;^'$install_root';;
|
||||
s;/\./;/;g
|
||||
s;//*;/;g
|
||||
s;^/;;
|
||||
s;/[^/]*$;/;
|
||||
s;[^/]*/;../;g
|
||||
s;$;'$dest';
|
||||
'`
|
||||
ln -s $link $tempdir/junk || exit 1
|
||||
mv -f $tempdir/junk $2 || {
|
||||
echo Error: your mv command is unable to rename symlinks. 1>&2
|
||||
echo If you run Linux, upgrade to GNU fileutils-4.0 or better, 1>&2
|
||||
echo or choose a tempdir that is in the same file system as $2. 1>&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compare_or_move() {
|
||||
(cmp $2 $3 >/dev/null 2>&1 && echo Skipping $3...) || {
|
||||
echo Updating $3...
|
||||
mv -f $2 $3 || exit 1
|
||||
chmod $1 $3 || exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# How to supress newlines in echo
|
||||
|
||||
case `echo -n` in
|
||||
"") n=-n; c=;;
|
||||
*) n=; c='\c';;
|
||||
esac
|
||||
|
||||
# Default settings. Most are clobbered by remembered settings.
|
||||
|
||||
: ${install_root=/}
|
||||
: ${tempdir=`pwd`}
|
||||
: ${config_directory=/etc/postfix}
|
||||
: ${daemon_directory=/usr/libexec/postfix}
|
||||
: ${command_directory=/usr/sbin}
|
||||
: ${queue_directory=/var/spool/postfix}
|
||||
if [ -f /usr/lib/sendmail ]
|
||||
then : ${sendmail_path=/usr/lib/sendmail}
|
||||
else : ${sendmail_path=/usr/sbin/sendmail}
|
||||
fi
|
||||
: ${newaliases_path=/usr/bin/newaliases}
|
||||
: ${mailq_path=/usr/bin/mailq}
|
||||
: ${mail_owner=postfix}
|
||||
: ${setgid=no}
|
||||
: ${manpages=/usr/local/man}
|
||||
|
||||
# Find out the location of configuration files.
|
||||
|
||||
test -t 0 &&
|
||||
for name in install_root tempdir config_directory
|
||||
do
|
||||
while :
|
||||
do
|
||||
eval echo \$n "$name: [\$$name]\ \$c"
|
||||
read ans
|
||||
case $ans in
|
||||
"") break;;
|
||||
*) eval $name=\$ans; break;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
# Sanity checks
|
||||
|
||||
for path in $tempdir $install_root $config_directory
|
||||
do
|
||||
case $path in
|
||||
/*) ;;
|
||||
*) echo Error: $path should be an absolute path name. 1>&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# In case some systems special-case pathnames beginning with //.
|
||||
|
||||
case $install_root in
|
||||
/) install_root=
|
||||
esac
|
||||
|
||||
# Load defaults from existing installation.
|
||||
|
||||
CONFIG_DIRECTORY=$install_root$config_directory
|
||||
|
||||
test -f $CONFIG_DIRECTORY/main.cf && {
|
||||
for name in daemon_directory command_directory queue_directory mail_owner
|
||||
do
|
||||
eval $name='"`bin/postconf -c $CONFIG_DIRECTORY -h $name`"' || kill $$
|
||||
done
|
||||
}
|
||||
|
||||
if [ -f $CONFIG_DIRECTORY/install.cf ]
|
||||
then
|
||||
. $CONFIG_DIRECTORY/install.cf
|
||||
elif [ ! -t 0 -a -z "$install_root" ]
|
||||
then
|
||||
echo Non-interactive install needs the $CONFIG_DIRECTORY/install.cf 1>&2
|
||||
echo file from a previous Postfix installation. 1>&2
|
||||
echo 1>&2
|
||||
echo Use interactive installation instead. 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Override default settings.
|
||||
|
||||
test -t 0 &&
|
||||
for name in daemon_directory command_directory \
|
||||
queue_directory sendmail_path newaliases_path mailq_path mail_owner\
|
||||
setgid manpages
|
||||
do
|
||||
while :
|
||||
do
|
||||
eval echo \$n "$name: [\$$name]\ \$c"
|
||||
read ans
|
||||
case $ans in
|
||||
"") break;;
|
||||
*) eval $name=\$ans; break;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
# Sanity checks
|
||||
|
||||
for path in $daemon_directory $command_directory \
|
||||
$queue_directory $sendmail_path $newaliases_path $mailq_path $manpages
|
||||
do
|
||||
case $path in
|
||||
/*) ;;
|
||||
no) ;;
|
||||
*) echo Error: $path should be an absolute path name. 1>&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -d $tempdir || mkdir -p $tempdir || exit 1
|
||||
|
||||
( rm -f $tempdir/junk && touch $tempdir/junk ) || {
|
||||
echo Error: you have no write permission to $tempdir. 1>&2
|
||||
echo Specify an alternative directory for scratch files. 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
chown root $tempdir/junk >/dev/null 2>&1 || {
|
||||
echo Error: you have no permission to change file ownership. 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
chown "$mail_owner" $tempdir/junk >/dev/null 2>&1 || {
|
||||
echo Error: $mail_owner needs an entry in the passwd file. 1>&2
|
||||
echo Remember, $mail_owner must have a dedicated user id and group id. 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case $setgid in
|
||||
no) ;;
|
||||
*) chgrp "$setgid" $tempdir/junk >/dev/null 2>&1 || {
|
||||
echo Error: $setgid needs an entry in the group file. 1>&2
|
||||
echo Remember, $setgid must have a dedicated group id. 1>&2
|
||||
exit 1
|
||||
}
|
||||
esac
|
||||
|
||||
rm -f $tempdir/junk
|
||||
|
||||
# Avoid clumsiness.
|
||||
|
||||
DAEMON_DIRECTORY=$install_root$daemon_directory
|
||||
COMMAND_DIRECTORY=$install_root$command_directory
|
||||
QUEUE_DIRECTORY=$install_root$queue_directory
|
||||
SENDMAIL_PATH=$install_root$sendmail_path
|
||||
NEWALIASES_PATH=$install_root$newaliases_path
|
||||
MAILQ_PATH=$install_root$mailq_path
|
||||
MANPAGES=$install_root$manpages
|
||||
|
||||
# Create any missing directories.
|
||||
|
||||
test -d $CONFIG_DIRECTORY || mkdir -p $CONFIG_DIRECTORY || exit 1
|
||||
test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
|
||||
test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
|
||||
test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
|
||||
for path in $SENDMAIL_PATH $NEWALIASES_PATH $MAILQ_PATH
|
||||
do
|
||||
dir=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
|
||||
test -d $dir || mkdir -p $dir || exit 1
|
||||
done
|
||||
|
||||
# Install files. Be careful to not copy over running programs.
|
||||
|
||||
for file in `censored_ls libexec`
|
||||
do
|
||||
compare_or_replace a+x,go-w libexec/$file $DAEMON_DIRECTORY/$file || exit 1
|
||||
done
|
||||
|
||||
for file in `censored_ls bin | grep '^post'`
|
||||
do
|
||||
compare_or_replace a+x,go-w bin/$file $COMMAND_DIRECTORY/$file || exit 1
|
||||
done
|
||||
|
||||
test -f bin/sendmail && {
|
||||
compare_or_replace a+x,go-w bin/sendmail $SENDMAIL_PATH || exit 1
|
||||
compare_or_symlink $SENDMAIL_PATH $NEWALIASES_PATH
|
||||
compare_or_symlink $SENDMAIL_PATH $MAILQ_PATH
|
||||
}
|
||||
|
||||
if [ -f $CONFIG_DIRECTORY/main.cf ]
|
||||
then
|
||||
for file in LICENSE `cd conf; censored_ls sample*` main.cf.default
|
||||
do
|
||||
compare_or_replace a+r,go-w conf/$file $CONFIG_DIRECTORY/$file || exit 1
|
||||
done
|
||||
else
|
||||
cp `censored_ls conf/*` $CONFIG_DIRECTORY || exit 1
|
||||
chmod a+r,go-w $CONFIG_DIRECTORY/* || exit 1
|
||||
|
||||
test -z "$install_root" && need_config=1
|
||||
fi
|
||||
|
||||
# Save settings.
|
||||
|
||||
bin/postconf -c $CONFIG_DIRECTORY -e \
|
||||
"daemon_directory = $daemon_directory" \
|
||||
"command_directory = $command_directory" \
|
||||
"queue_directory = $queue_directory" \
|
||||
"mail_owner = $mail_owner" \
|
||||
|| exit 1
|
||||
|
||||
(echo "# This file was generated by $0"
|
||||
for name in sendmail_path newaliases_path mailq_path setgid manpages
|
||||
do
|
||||
eval echo $name=\$$name
|
||||
done) >$tempdir/junk || exit 1
|
||||
compare_or_move a+x,go-w $tempdir/junk $CONFIG_DIRECTORY/install.cf || exit 1
|
||||
rm -f $tempdir/junk
|
||||
|
||||
# Use set-gid privileges instead of writable maildrop (optional).
|
||||
|
||||
test -d $QUEUE_DIRECTORY/maildrop || {
|
||||
mkdir -p $QUEUE_DIRECTORY/maildrop || exit 1
|
||||
chown $mail_owner $QUEUE_DIRECTORY/maildrop || exit 1
|
||||
}
|
||||
|
||||
case $setgid in
|
||||
no)
|
||||
chmod 1733 $QUEUE_DIRECTORY/maildrop || exit 1
|
||||
chmod g-s $COMMAND_DIRECTORY/postdrop || exit 1
|
||||
postfix_script=conf/postfix-script-nosgid
|
||||
;;
|
||||
*)
|
||||
chgrp $setgid $COMMAND_DIRECTORY/postdrop || exit 1
|
||||
chmod g+s $COMMAND_DIRECTORY/postdrop || exit 1
|
||||
chgrp $setgid $QUEUE_DIRECTORY/maildrop || exit 1
|
||||
chmod 1730 $QUEUE_DIRECTORY/maildrop || exit 1
|
||||
postfix_script=conf/postfix-script-sgid
|
||||
;;
|
||||
esac
|
||||
|
||||
compare_or_replace a+x,go-w $postfix_script $CONFIG_DIRECTORY/postfix-script ||
|
||||
exit 1
|
||||
|
||||
# Install manual pages (optional).
|
||||
|
||||
case $manpages in
|
||||
no) ;;
|
||||
*) (
|
||||
cd man || exit 1
|
||||
for dir in man?
|
||||
do test -d $MANPAGES/$dir || mkdir -p $MANPAGES/$dir || exit 1
|
||||
done
|
||||
for file in `censored_ls man?/*`
|
||||
do
|
||||
(test -f $MANPAGES/$file && cmp -s $file $MANPAGES/$file &&
|
||||
echo Skipping $MANPAGES/$file...) || {
|
||||
echo Updating $MANPAGES/$file...
|
||||
rm -f $MANPAGES/$file
|
||||
cp $file $MANPAGES/$file || exit 1
|
||||
chmod 644 $MANPAGES/$file || exit 1
|
||||
}
|
||||
done
|
||||
)
|
||||
esac
|
||||
|
||||
test "$need_config" = 1 || exit 0
|
||||
|
||||
ALIASES=`bin/postconf -h alias_database | sed 's/^[^:]*://'`
|
||||
cat <<EOF 1>&2
|
||||
|
||||
Warning: you still need to edit myorigin/mydestination/mynetworks
|
||||
in $CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup
|
||||
sites or for sites inside a firewalled network.
|
||||
|
||||
BTW: Check your $ALIASES file and be sure to set up aliases
|
||||
for root and postmaster that direct mail to a real person, then
|
||||
run $NEWALIASES_PATH.
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
|
@ -1,328 +0,0 @@
|
|||
LDAP SUPPORT IN POSTFIX
|
||||
=======================
|
||||
|
||||
Postfix can use an LDAP directory as a source for any of its lookups:
|
||||
aliases, virtual, canonical, etc. This allows you to keep information
|
||||
for your mail service in a replicated network database with fine-grained
|
||||
access controls. By not storing it locally on the mail server, the
|
||||
administrators can maintain it from anywhere, and the users can control
|
||||
whatever bits of it you think appropriate. You can have multiple mail
|
||||
servers using the same information, without the hassle and delay of
|
||||
having to copy it to each.
|
||||
|
||||
BUILDING WITH LDAP SUPPORT
|
||||
==========================
|
||||
|
||||
You need to have LDAP libraries and include files installed somewhere on
|
||||
your system, and you need to configure the Postfix Makefiles
|
||||
accordingly.
|
||||
|
||||
If you're using the libraries from the UM distribution
|
||||
(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP
|
||||
(http://www.openldap.org), something like this in the top level of your
|
||||
Postfix source tree should work:
|
||||
|
||||
% make tidy
|
||||
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
|
||||
AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber"
|
||||
|
||||
On Solaris 2.x you may have to specify run-time link information,
|
||||
otherwise ld.so will not find some of the shared libraries:
|
||||
|
||||
% make tidy
|
||||
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
|
||||
AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lldap \
|
||||
-L/usr/local/lib -R/usr/local/lib -llber"
|
||||
|
||||
The 'make tidy' command is needed only if you have previously built
|
||||
Postfix without LDAP support.
|
||||
|
||||
Instead of '/usr/local' specify the actual locations of your LDAP
|
||||
include files and libraries. Be sure to not mix LDAP include files
|
||||
and LDAP libraries of different versions!!
|
||||
|
||||
If your LDAP libraries were built with Kerberos support, you'll also
|
||||
need to include your Kerberos libraries in this line. Note that the KTH
|
||||
Kerberos IV libraries might conflict with Postfix's lib/libdns.a, which
|
||||
defines dns_lookup. If that happens, you'll probably want to link with
|
||||
LDAP libraries that lack Kerberos support just to build Postfix, as it
|
||||
doesn't support Kerberos binds to the LDAP server anyway. Sorry about
|
||||
the bother.
|
||||
|
||||
If you're using one of the Netscape LDAP SDKs, you'll need to change the
|
||||
AUXLIBS line to point to libldap10.so or libldapssl30.so or whatever you
|
||||
have, and you may need to use the appropriate linker option (e.g. '-R')
|
||||
so the executables can find it at runtime.
|
||||
|
||||
CONFIGURING LDAP LOOKUPS
|
||||
========================
|
||||
|
||||
In order to use LDAP lookups, define at least one LDAP source as a table
|
||||
lookup in main.cf, for example:
|
||||
|
||||
alias_maps = hash:/etc/aliases, ldap:ldapsource
|
||||
|
||||
Each LDAP source can have the following parameters, which should be
|
||||
prefixed in main.cf with the name you've given the source in its
|
||||
definition and an underscore. To continue the example, the first
|
||||
parameter below, "server_host", would be defined in main.cf as
|
||||
"ldapsource_server_host". Defaults are given in parentheses:
|
||||
|
||||
server_host (localhost)
|
||||
The name of the host running the LDAP server, e.g.
|
||||
ldapsource_server_host = ldap.your.com
|
||||
It should be possible with all the libraries mentioned above to
|
||||
specify multiple servers separated by spaces, with the libraries
|
||||
trying them in order should the first one fail. It should also
|
||||
be possible to give each server in the list a different port, by
|
||||
naming them like "ldap.your.com:1444".
|
||||
|
||||
server_port (389)
|
||||
The port the LDAP server listens on, e.g.
|
||||
ldapsource_server_port = 778
|
||||
|
||||
search_base (No default; you must configure this.)
|
||||
The base at which to conduct the search, e.g.
|
||||
ldapsource_search_base = dc=your, dc=com
|
||||
|
||||
timeout (10 seconds)
|
||||
The number of seconds a search can take before timing out, e.g.
|
||||
ldapsource_timeout = 5
|
||||
|
||||
query_filter (mailacceptinggeneralid=%s)
|
||||
The RFC2254 filter used to search the directory, where %s is a
|
||||
substitute for the address Postfix is trying to resolve, e.g.
|
||||
ldapsource_query_filter = (&(mail=%s)(paid_up=true))
|
||||
|
||||
domain (Default is to ignore this.)
|
||||
This is a list of domain names, paths to files, or dictionaries.
|
||||
If specified, only lookups for the domains on this list will be
|
||||
performed. This means that the LDAP map won't get searched for
|
||||
'user', nor will it get searched for any domain not listed. This
|
||||
can significantly reduce the query load on the LDAP server.
|
||||
ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains
|
||||
|
||||
result_attribute (maildrop)
|
||||
The attribute(s) Postfix will read from any directory entries
|
||||
returned by the lookup, to be resolved to an email address.
|
||||
ldapsource_result_attribute = mailbox,maildrop
|
||||
|
||||
special_result_attribute (No default)
|
||||
The attribute(s) of directory entries that can contain DNs or URLs.
|
||||
If found, a recursive subsequent search is done using their values.
|
||||
ldapsource_special_result_attribute = member
|
||||
|
||||
scope (sub)
|
||||
The LDAP search scope: sub, base, or one. These translate into
|
||||
LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE, and LDAP_SCOPE_ONELEVEL.
|
||||
|
||||
bind (yes)
|
||||
Whether or not to bind to the LDAP server. Newer LDAP
|
||||
implementations don't require clients to bind, which saves
|
||||
time. Example:
|
||||
ldapsource_bind = no
|
||||
|
||||
If you do need to bind, you might consider configuring Postfix
|
||||
to connect to the local machine on a port that's an SSL tunnel
|
||||
to your LDAP server. If your LDAP server doesn't natively
|
||||
support SSL, put a tunnel (wrapper, proxy, whatever you want to
|
||||
call it) on that system too. This should prevent the password
|
||||
from traversing the network in the clear.
|
||||
|
||||
bind_dn ("")
|
||||
If you do have to bind, do it with this distinguished name.
|
||||
Example:
|
||||
ldapsource_bind_dn = uid=postfix, dc=your, dc=com
|
||||
|
||||
bind_pw ("")
|
||||
The password for the distinguished name above. If you have to
|
||||
use this, you probably want to make main.cf readable only by
|
||||
the Postfix user. Example:
|
||||
ldapsource_bind_pw = postfixpw
|
||||
|
||||
cache (no)
|
||||
Whether to use a client-side cache for the LDAP connection. See
|
||||
ldap_enable_cache(3). It's off by default.
|
||||
|
||||
cache_expiry (30 seconds)
|
||||
If the client-side cache is enabled, cached results will expire
|
||||
after this many seconds.
|
||||
|
||||
cache_size (32768 bytes)
|
||||
If the client-side cache is enabled, this is its size in bytes.
|
||||
|
||||
dereference (0)
|
||||
When to dereference LDAP aliases. (Note that this has nothing
|
||||
do with Postfix aliases.) The permitted values are those
|
||||
legal for the OpenLDAP/UM LDAP implementations:
|
||||
|
||||
0 never
|
||||
1 when searching
|
||||
2 when locating the base object for the search
|
||||
3 always
|
||||
|
||||
See ldap.h or the ldap_open(3) or ldapsearch(1) man pages for
|
||||
more information. And if you're using an LDAP package that has
|
||||
other possible values, please bring it to the attention of the
|
||||
postfix-users@postfix.org mailing list.
|
||||
|
||||
Don't use quotes in these variables; at least, not until the Postfix
|
||||
configuration routines understand how to deal with quoted strings.
|
||||
|
||||
EXAMPLES
|
||||
========
|
||||
|
||||
ALIASES
|
||||
-------
|
||||
|
||||
Here's a basic example for using LDAP to look up aliases. Assume that in
|
||||
main.cf, you have these configuration parameters defined:
|
||||
|
||||
alias_maps = hash:/etc/aliases, ldap:ldapsource
|
||||
ldapsource_server_host = ldap.my.com
|
||||
ldapsource_search_base = dc=my, dc=com
|
||||
|
||||
Upon receiving mail for a local address "ldapuser" that isn't found in
|
||||
the /etc/aliases database, Postfix will search the LDAP server listening
|
||||
at port 389 on ldap.my.com. It will bind anonymously, search for any
|
||||
directory entries whose mailacceptinggeneralid attribute is "ldapuser",
|
||||
read the "maildrop" attributes of those found, and build a list of their
|
||||
maildrops, which will be treated as RFC822 addresses to which the
|
||||
message will be delivered.
|
||||
|
||||
VIRTUAL DOMAINS/ADDRESSES
|
||||
-------------------------
|
||||
|
||||
If you want to keep information for virtual lookups in your directory,
|
||||
it's only a little more complicated. First you need to make sure Postfix
|
||||
knows about the virtual domain. An easy way to do that is to add the
|
||||
domain to the mailacceptinggeneralid attribute of some entry in the
|
||||
directory. Next you'll want to make sure all of your virtual recipients'
|
||||
mailacceptinggeneralid attributes are fully qualified with their virtual
|
||||
domains. Finally, if you want to designate a directory entry as the
|
||||
default user for a virtual domain, just give it an additional
|
||||
mailacceptinggeneralid (or the equivalent in your directory) of
|
||||
"@virtual.dom". That's right, no user part. If you don't want a catchall
|
||||
user, omit this step and mail to unknown users in the domain will simply
|
||||
bounce.
|
||||
|
||||
If you're using a version of Postfix newer than 19991226, that should do
|
||||
it. If not, you also need to add your virtual domains to relay_domains.
|
||||
Simply add "$virtual_maps" to your relay_domains line. Then you can use
|
||||
the same map you use to find virtual recipients to determine if a domain
|
||||
is a valid virtual domain and should be allowed to relay.
|
||||
|
||||
In summary, you might have a catchall user for a virtual domain that
|
||||
looks like this:
|
||||
|
||||
dn: cn=defaultrecipient, dc=fake, dc=dom
|
||||
objectclass: top
|
||||
objectclass: virtualaccount
|
||||
cn: defaultrecipient
|
||||
owner: uid=root, dc=someserver, dc=isp, dc=dom
|
||||
1 -> mailacceptinggeneralid: fake.dom
|
||||
2 -> mailacceptinggeneralid: @fake.dom
|
||||
3 -> maildrop: realuser@real.dom
|
||||
|
||||
1: Postfix knows fake.dom is a valid virtual domain when it looks for
|
||||
this and gets something (the maildrop) back.
|
||||
|
||||
2: This causes any mail for unknown users in fake.dom to go to this entry ...
|
||||
|
||||
3: ... and then to its maildrop.
|
||||
|
||||
Normal users might simply have one mailacceptinggeneralid and maildrop,
|
||||
e.g. "normaluser@fake.dom" and "normaluser@real.dom".
|
||||
|
||||
OTHER USES
|
||||
----------
|
||||
|
||||
Other common uses for LDAP lookups include rewriting senders and
|
||||
recipients with Postfix' canonical lookups, for example in order to make
|
||||
mail leaving your site appear to be coming from "First.Last@site.dom"
|
||||
instead of "userid@site.dom".
|
||||
|
||||
NOTES AND THINGS TO THINK ABOUT
|
||||
===============================
|
||||
|
||||
- The bits of schema and attribute names used in this document are just
|
||||
examples. There's nothing special about them, other than that some are
|
||||
the defaults in the LDAP configuration parameters. You can use
|
||||
whatever schema you like, and configure Postfix accordingly.
|
||||
|
||||
- You probably want to make sure that mailacceptinggeneralids are
|
||||
unique, and that not just anyone can specify theirs as postmaster or
|
||||
root, say.
|
||||
|
||||
- An entry can have an arbitrary number of mailacceptinggeneralids or
|
||||
maildrops. Maildrops can also be comma-separated lists of addresses.
|
||||
They will all be found and returned by the lookups. For example, you
|
||||
could define an entry intended for use as a mailing list that looks
|
||||
like this (Warning! Schema made up just for this example):
|
||||
|
||||
dn: cn=Accounting Staff List, dc=my, dc=com
|
||||
cn: Accounting Staff List
|
||||
o: my.com
|
||||
objectclass: maillist
|
||||
mailacceptinggeneralid: accountingstaff
|
||||
mailacceptinggeneralid: accounting-staff
|
||||
maildrop: mylist-owner
|
||||
maildrop: an-accountant
|
||||
maildrop: some-other-accountant
|
||||
maildrop: this, that, theother
|
||||
|
||||
- If you use an LDAP map for lookups other than aliases, you may have to
|
||||
make sure the lookup makes sense. In the case of virtual lookups,
|
||||
maildrops other than mail addresses are pretty useless, because
|
||||
Postfix can't know how to set the ownership for program or file
|
||||
delivery. Your query_filter should probably look something like this:
|
||||
|
||||
virtual_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
|
||||
|
||||
- And for that matter, even for aliases, you may not want users able to
|
||||
specify their maildrops as programs, includes, etc. This might be
|
||||
particularly pertinent on a "sealed" server where they don't have
|
||||
local UNIX accounts, but exist only in LDAP and Cyrus. You might allow
|
||||
the fun stuff only for directory entries owned by an administrative
|
||||
account:
|
||||
|
||||
local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
|
||||
|
||||
So that if the object had a program as its maildrop and weren't owned
|
||||
by "cn=root" it wouldn't be returned as a valid local user. This will
|
||||
require some thought on your part to implement safely, considering the
|
||||
ramifications of this type of delivery. You may decide it's not worth
|
||||
the bother to allow any of that nonsense in LDAP lookups, ban it in
|
||||
the query_filter, and keep things like majordomo lists in local alias
|
||||
databases.
|
||||
|
||||
- LDAP lookups are slower than local DB or DBM lookups. For most sites
|
||||
they won't be a bottleneck, but it's a good idea to know how to tune
|
||||
your directory service.
|
||||
|
||||
FEEDBACK
|
||||
========
|
||||
|
||||
If you have questions, send them to postfix-users@postfix.org. Please
|
||||
include relevant information about your Postfix setup: LDAP-related
|
||||
output from postconf, which LDAP libraries you built with, and which
|
||||
directory server you're using. If your question involves your directory
|
||||
contents, please include the applicable bits of some directory entries.
|
||||
|
||||
CREDITS
|
||||
=======
|
||||
|
||||
Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
|
||||
John Hensley: Multiple LDAP sources with more configurable attributes.
|
||||
Carsten Hoeger: Search scope handling.
|
||||
LaMont Jones: Domain restriction, URL and DN searches, multiple result
|
||||
attributes.
|
||||
Mike Mattice: Alias dereferencing control.
|
||||
Hery Rakotoarisoa: Patches for LDAPv3 updating.
|
||||
Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
|
||||
Keith Stevenson: RFC 2254 escaping in queries.
|
||||
Samuel Tardieu: Noticed that searches could include wildcards, prompting
|
||||
the work on RFC 2254 escaping in queries. Spotted a bug
|
||||
in binding.
|
||||
|
||||
And of course Wietse.
|
|
@ -1,17 +0,0 @@
|
|||
LINUX PORTABILITY
|
||||
=================
|
||||
|
||||
On RedHat Linux 7.0, you must install the db3-devel RPM before you
|
||||
can compile the Postfix source code.
|
||||
|
||||
LINUX SYSLOGD PERFORMANCE
|
||||
=========================
|
||||
|
||||
LINUX syslogd uses synchronous writes by default, which is very
|
||||
expensive. For services such as mail it is recommended that you
|
||||
disable synchronous logfile writes by editing /etc/syslog.conf and
|
||||
by prepending a - to the logfile name:
|
||||
|
||||
mail.* -/var/log/mail.log
|
||||
|
||||
Send a "kill -HUP" to the syslogd to make the change effective.
|
|
@ -1,466 +0,0 @@
|
|||
[This file still needs to be updated - some information is obsolete]
|
||||
|
||||
1 - Postfix LMTP support
|
||||
========================
|
||||
|
||||
LMTP stands for Local Mail Transfer Protocol, and is detailed in
|
||||
RFC2033. Postfix uses this protocol to communicate with the final
|
||||
delivery agent, which may run on the local host or a remote host.
|
||||
|
||||
This protocol opens up interesting possibilities: one Postfix front
|
||||
end machine can drive multiple mailbox back end machines over LMTP.
|
||||
As the mail load increases, you add more Postfix front end systems
|
||||
and more LMTP mailbox back end systems. This is the model that I
|
||||
had in mind when I began drafting the design for Postfix - a scalable
|
||||
architecture that allows you to keep adding SMTP servers and mailbox
|
||||
servers painlessly.
|
||||
|
||||
Such a distributed architecture needs glue to keep things together.
|
||||
You can use a networked database LDAP or mysql to share the user
|
||||
database among the front end and back end systems. Use a replicated
|
||||
database so that no machine becomes a single point of failure for
|
||||
the entire mail infrastructure.
|
||||
|
||||
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, who also revised
|
||||
much of the documentation. Wietse Venema reduced the code to its
|
||||
present shape.
|
||||
|
||||
|
||||
2 - Overview
|
||||
============
|
||||
|
||||
Most of the examples in this document involve the CMU Cyrus IMAP/POP
|
||||
server, available from:
|
||||
|
||||
http://asg.web.cmu.edu/cyrus/
|
||||
|
||||
While certainly not the only application that could make use of
|
||||
LMTP, it tends to be the most discussed. These examples are based
|
||||
on the forthcoming Cyrus 2.0.10, at least at the time of writing.
|
||||
The 2.x branch of Cyrus places greater emphasis on LMTP delivery
|
||||
than the previous releases. Those using older releases of Cyrus
|
||||
can find a discussion in the appendix of this document.
|
||||
|
||||
There are a variety of ways LMTP delivery can be configured in
|
||||
Postfix. The two basic flavors are delivery over UNIX-domain
|
||||
sockets and delivery over TCP sockets.
|
||||
|
||||
o Connections over UNIX-domain sockets limit delivery to LMTP
|
||||
servers running on the same machine.
|
||||
|
||||
o Connections over TCP sockets allow you to deliver to LMTP
|
||||
servers across a local network.
|
||||
|
||||
The precise syntax for UNIX-domain and TCP connection endpoints is
|
||||
given in the lmtp(8) manual page. Examples are also given in the
|
||||
text below.
|
||||
|
||||
Both socket flavors can be specified in either the Postfix main.cf
|
||||
file (see section 5) or in a Postfix transport map (section 6).
|
||||
What is the best approach for you 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 in performance with these different approaches.
|
||||
|
||||
3 - LMTP over UNIX-domain sockets
|
||||
=================================
|
||||
|
||||
A UNIX-domain socket is specified as the socket type ("unix") and
|
||||
a name in the local file system:
|
||||
|
||||
unix:/path/name
|
||||
|
||||
The "/path/name" part should be the name of a socket created by
|
||||
the LMTP server on the local machine. See the specific examples
|
||||
later in this document.
|
||||
|
||||
NOTE:
|
||||
|
||||
If you run the lmtp client chrooted, the interpretation of the
|
||||
/path/name is relative to the Postfix queue directory (typically,
|
||||
/var/spool/postfix).
|
||||
|
||||
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.
|
||||
|
||||
4 - LMTP over TCP sockets
|
||||
=========================
|
||||
|
||||
A TCP destination is specified as the socket type ("inet"), the
|
||||
destination hostname and the TCP port:
|
||||
|
||||
inet:hostname:port
|
||||
|
||||
The "inet:" part can be omitted, as it is the default socket type.
|
||||
|
||||
The destination port can be omitted as well. Currently the default
|
||||
TCP port number for this type of connection is 24, but this can be
|
||||
customized in the "/etc/services" file. Specific examples are
|
||||
given later in this document.
|
||||
|
||||
NOTE:
|
||||
|
||||
With connections over TCP sockets, later Cyrus LMTP server
|
||||
implementations insist on SASL-style authentication. This means
|
||||
that Postfix must be built with SASL support (see SASL_README).
|
||||
The examples below show how to enable this in the Postfix LMTP
|
||||
client.
|
||||
|
||||
Some Cyrus LMTP server implementations do not allow SASL-style
|
||||
authentication via plaintext passwords. You will have to jump
|
||||
some extra hoops in order to enable MD5 password support, or
|
||||
you will have to wait until this restriction is relaxed.
|
||||
|
||||
|
||||
5 - Configuring LMTP using main.cf configuration
|
||||
================================================
|
||||
|
||||
This is the simplest LMTP configuration.
|
||||
|
||||
5.1 - Delivery mechanisms
|
||||
-------------------------
|
||||
|
||||
Postfix main.cf supports three mechanisms to deliver mail over
|
||||
LMTP. Each method can use UNIX-domain or TCP sockets as described
|
||||
in a later section.
|
||||
|
||||
main.cf mechanism 1
|
||||
-------------------
|
||||
|
||||
mailbox_transport = lmtp:unix:/path/name (UNIX-domain socket example)
|
||||
mailbox_transport = lmtp:hostname:port (TCP socket example)
|
||||
|
||||
Mail that resolves as local (domain is listed in $mydestination)
|
||||
is given to the Postfix local delivery agent. The Postfix local
|
||||
delivery agent expands aliases and .forward files, and delegates
|
||||
mailbox delivery to the LMTP server.
|
||||
|
||||
main.cf mechanism 2
|
||||
-------------------
|
||||
|
||||
local_transport = lmtp:unix:/path/name (UNIX-domain socket example)
|
||||
local_transport = lmtp:hostname:port (TCP socket example)
|
||||
|
||||
Mail that resolves as local (domain is listed in $mydestination)
|
||||
is directly given to the LMTP server. The mail is not processed
|
||||
by the Postfix local delivery agent; therefore aliases and .forward
|
||||
files are not processed.
|
||||
|
||||
main.cf mechanism 3
|
||||
-------------------
|
||||
|
||||
fallback_transport = lmtp:unix:/path/name (UNIX-domain socket example)
|
||||
fallback_transport = lmtp:hostname:port (TCP socket example)
|
||||
|
||||
Mail that resolves as local (domain is listed in $mydestination)
|
||||
is given to the Postfix local delivery agent. The Postfix local
|
||||
delivery agent processes aliases and .forward files, and delivers
|
||||
to /var[/spool]/mail/$user for users that have a UNIX account.
|
||||
Mail for other local users is delegated to the LMTP server.
|
||||
|
||||
5.2 - Examples
|
||||
--------------
|
||||
|
||||
5.2.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, the Postfix local delivery agent expands aliases
|
||||
and .forward files, and delegates mailbox delivery to the Cyrus
|
||||
lmtpd server via the socket "/var/imap/socket/lmtp".
|
||||
|
||||
5.2.2 - LMTP over TCP sockets
|
||||
-----------------------------
|
||||
|
||||
For this example, suppose the following files are configured
|
||||
thusly:
|
||||
|
||||
/etc/cyrus.conf:
|
||||
|
||||
SERVICES {
|
||||
...
|
||||
lmtp cmd="lmtpd" listen="127.0.0.1:lmtp" prefork=0
|
||||
...
|
||||
}
|
||||
|
||||
/etc/services:
|
||||
|
||||
lmtp 24/tcp
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
|
||||
mailbox_transport = lmtp:localhost
|
||||
lmtp_sasl_auth_enable = yes
|
||||
lmtp_sasl_password_maps = hash:/etc/postfix/lmtp_sasl_pass
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
|
||||
lmtp unix - - n - - lmtp
|
||||
|
||||
/etc/postfix/lmtp_sasl_pass:
|
||||
localhost.my.domain username:password
|
||||
|
||||
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.
|
||||
|
||||
With the above settings, the Postfix local delivery agent expands
|
||||
aliases and .forward files, and delegates mailbox delivery to the
|
||||
the Cyrus LMTP server. Postfix makes a connection to port 24 on
|
||||
the local host, subsequently transmitting the message to the lmtpd
|
||||
server managed by the Cyrus master process.
|
||||
|
||||
|
||||
6 - Configuring LMTP 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,
|
||||
instead of depending on delegation by the Postfix local delivery
|
||||
agent.
|
||||
|
||||
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
|
||||
|
||||
For details of the Cyrus LMTP server configuration, see section 5.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
7 - 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.
|
||||
|
||||
|
||||
8 - 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: the Postfix local delivery agent is
|
||||
designed to deliver 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 virtual table to
|
||||
map these users to the appropriate LMTP destination (at the time
|
||||
of writing, the Postfix transport table supports only per-domain
|
||||
routing, and not per-recipient routing).
|
||||
|
||||
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 (see section 5.1, delivery
|
||||
mechanism 2). If the site is to run software via aliases, like
|
||||
most Mailing List Management (MLM) software, a more complex solution
|
||||
is required. A virtual table should do the trick.
|
||||
|
||||
As an example, suppose we wanted to support single instance message
|
||||
store delivery for the hosted (not local) 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.
|
||||
|
||||
|
||||
9 - Improving connection caching performance
|
||||
============================================
|
||||
|
||||
After delivering a message via LMTP, Postfix will keep the connection
|
||||
open for a while, so that it can be reused for a subsequent delivery.
|
||||
This reduces overhead of LMTP servers that create one process per
|
||||
connection.
|
||||
|
||||
For LMTP connection caching to work, the Postfix LMTP client should
|
||||
not switch destination hosts. This is no problem when you run only
|
||||
one LMTP server. However, if you run multiple LMTP servers, this
|
||||
can be an issue.
|
||||
|
||||
You can prevent the LMTP client from switching between servers by
|
||||
configuring a separate LMTP delivery transport for each LMTP server:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
|
||||
lmtp1 unix - - n - - lmtp
|
||||
lmtp2 unix - - n - - lmtp
|
||||
. . . . . . . .
|
||||
|
||||
Configure transport table entries such that the lmtp1 mail delivery
|
||||
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
|
||||
|
||||
|
||||
10 - 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 24/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. :-)
|
|
@ -1,2 +0,0 @@
|
|||
See the files in auxiliary/MacOSX for hints and tips to set up
|
||||
Postfix.
|
|
@ -1,92 +0,0 @@
|
|||
[Code contributed by Scott Cotton and Joshua Marcus, IC Group, Inc.]
|
||||
|
||||
We've written code to add a mysql map type. It utilizes the mysql
|
||||
client library, which can be obtained from:
|
||||
|
||||
http://www.mysql.com/downloads/
|
||||
http://sourceforge.net/projects/mysql/
|
||||
|
||||
In order to build postfix with mysql map support, you will need to add
|
||||
-DHAS_MYSQL and -I for the directory containing the mysql headers, and
|
||||
the mysqlclient library (and libm) to AUXLIBS, for example:
|
||||
|
||||
make -f Makefile.init makefiles \
|
||||
'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \
|
||||
'AUXLIBS=-L/usr/local/mysql/lib -lmysqlclient -lz -lm'
|
||||
|
||||
then, just run 'make'. This requires libz, the compression library.
|
||||
Older mysql implementations build without libz.
|
||||
|
||||
Postfix installations which may benefit from using mysql map types
|
||||
include sites that have a need for instantaneous updates of
|
||||
forwarding, and sites that may benefit from having mail exchangers
|
||||
reference a networked database, possibly working in conjunction with a
|
||||
customer database of sorts.
|
||||
|
||||
Once postfix is built with mysql support, you can specify a map type
|
||||
in main.cf like this:
|
||||
|
||||
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
|
||||
|
||||
The file /etc/postfix/mysql-aliases.cf specifies lots of information
|
||||
telling postfix how to reference the mysql database. An example mysql
|
||||
map config file follows:
|
||||
|
||||
#
|
||||
# mysql config file for alias lookups on postfix
|
||||
# comments are ok.
|
||||
#
|
||||
|
||||
# the user name and password to log into the mysql server
|
||||
user = someone
|
||||
password = some_password
|
||||
|
||||
# the database name on the servers
|
||||
dbname = customer_database
|
||||
|
||||
# the table name
|
||||
table = mxaliases
|
||||
|
||||
#
|
||||
select_field = forw_addr
|
||||
where_field = alias
|
||||
|
||||
# you may specify additional_conditions here
|
||||
additional_conditions = and status = 'paid'
|
||||
|
||||
# the above variables will result in a query of
|
||||
# the form:
|
||||
# select forw_addr from mxaliases where alias = '$lookup' and status = 'paid'
|
||||
# ($lookup is escaped so if it contains single quotes or other odd
|
||||
# characters, it will not cause a parse error in the sql).
|
||||
#
|
||||
# the hosts that postfix will try to connect to
|
||||
# and query from (in the order listed)
|
||||
# specify unix: for unix-domain sockets, inet: for TCP connections (default)
|
||||
hosts = host1.some.domain host2.some.domain unix:/file/name
|
||||
|
||||
# end mysql config file
|
||||
|
||||
Some notes:
|
||||
|
||||
This configuration interface setup allows for multiple mysql
|
||||
databases: you can use one for a virtual table, one for an access
|
||||
table, and one for an aliases table if you want.
|
||||
|
||||
Since sites that have a need for multiple mail exchangers may enjoy
|
||||
the convenience of using a networked mailer database, but do not want
|
||||
to introduce a single point of failure to their system, we've included
|
||||
the ability to have postfix reference multiple hosts for access to a
|
||||
single mysql map. This will work if sites set up mirrored mysql
|
||||
databases on two or more hosts. Whenever queries fail with an error
|
||||
at one host, the rest of the hosts will be tried in order. Each host
|
||||
that is in an error state will undergo a reconnection attempt every so
|
||||
often, and if no mysql server hosts are reachable, then mail will be
|
||||
deferred until at least one of those hosts is reachable.
|
||||
|
||||
Performance of postfix with mysql has not been thoroughly tested,
|
||||
however, we have found it to be stable. Busy mail servers using mysql
|
||||
maps will generate lots of concurrent mysql clients, so the mysql
|
||||
server(s) should be run with this fact in mind. Any further
|
||||
performance information, in addition to any feedback is most welcome.
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
To: wietse@porcupine.org (Wietse Venema)
|
||||
Cc: postfix-users@postfix.org (Postfix users)
|
||||
Subject: regexp map patch
|
||||
In-reply-to: Your message of "Thu, 25 Feb 1999 19:51:25 CDT."
|
||||
<19990226005125.69B3C4596E@spike.porcupine.org>
|
||||
Date: Tue, 02 Mar 1999 11:04:02 +1100
|
||||
From: Andrew McNamara <andrewm@connect.com.au>
|
||||
Message-Id: <19990302000403.074C7ED7D@melang.off.connect.com.au>
|
||||
Sender: owner-postfix-users@postfix.org
|
||||
Precedence: bulk
|
||||
Return-Path: <owner-postfix-users@postfix.org>
|
||||
|
||||
I've written [code] to add a regexp map type. It utilises the PCRE
|
||||
library (Perl Compatible Regular Expressions), which can be obtained
|
||||
from:
|
||||
|
||||
ftp://ftp.cus.cam.ac.uk/pub/software/programs/pcre/
|
||||
|
||||
You will need to add -DHAS_PCRE and a -I for the PCRE header to CCARGS,
|
||||
and add the path to the PCRE library to AUXLIBS, for example:
|
||||
|
||||
make -f Makefile.init makefiles 'CCARGS=-DHAS_PCRE -I../../../pcre-2.08' \
|
||||
'AUXLIBS=../../../pcre-2.08/libpcre.a'
|
||||
|
||||
[note: pcre versions before 2.06 are no longer compatible -- Wietse]
|
||||
|
||||
One possible use is to add a line to main.cf:
|
||||
|
||||
smtpd_recipient_restrictions = pcre:/opt/postfix/etc/smtprecipient
|
||||
|
||||
The regular expressions are read from the file specified and compiled -
|
||||
a sample regexp file for this usage is included in the patch.
|
||||
|
||||
Any feedback is appreciated (from Wietse in particular :-). Have
|
||||
fun.
|
||||
|
||||
[I've changed the code so that it can be used for other Postfix
|
||||
table lookups, not just for junk mail control. In particular,
|
||||
regular expressions in canonical tables could be very useful.
|
||||
|
||||
For the sake of robustness, I have disabled the matching of partial
|
||||
addresses (user@, domain, user, @domain) that is normally done with
|
||||
Postfix access control tables, canonical maps and virtual maps.
|
||||
|
||||
As a side effect, pcre maps can only match user@domain strings, so
|
||||
that regexps cannot be used for local alias database lookups. That
|
||||
would be a security exposure anyway -- Wietse.]
|
|
@ -1,24 +0,0 @@
|
|||
Per client/helo/sender/recipient UCE restrictions
|
||||
=================================================
|
||||
|
||||
The Postfix SMTP server allows you to specify UCE restrictions on
|
||||
the right-hand side of SMTPD access tables, so that you can have
|
||||
different UCE restrictions for different clients or users.
|
||||
|
||||
The only anomalies in this scheme are that (1) message header_checks
|
||||
and body_checks are still the same for every message, and (2) you
|
||||
must use a restriction class name (see below) if you want to specify
|
||||
a lookup table on the right-hand side of an access table (this is
|
||||
because Postfix needs to open those tables ahead of time).
|
||||
|
||||
Restriction classes allow you to give easy-to-remember names to
|
||||
groups of UCE restrictions (such as permissive, restrictive, and
|
||||
so on). For example in main.cf:
|
||||
|
||||
smtpd_restriction_classes = restrictive, permissive
|
||||
restrictive = reject_unknown_sender reject_unknown_client ...
|
||||
permissive = permit
|
||||
|
||||
With this in place, you can use "restrictive" or "permissive" on
|
||||
the right-hand side of your per-client/helo/sender/recipient SMTPD
|
||||
access tables.
|
|
@ -1,206 +0,0 @@
|
|||
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
===============================================================
|
||||
|
||||
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
|
||||
or sasldb), and FreeBSD 3.4 (pwcheck_method set to sasldb). On
|
||||
RedHat 6.1, SASL 1.5.5 insisted on write access to /etc/sasldb.
|
||||
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".
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The Postfix SASL support (RFC 2554) was originally implemented by
|
||||
Till Franke of SuSE Rhein/Main AG. The present code is a trimmed-down
|
||||
version with only the bare necessities.
|
||||
|
||||
When receiving mail, Postfix logs the client-provided username,
|
||||
authentication method, and sender address to the maillog file, and
|
||||
optionally grants mail access via the permit_sasl_authenticated
|
||||
UCE restriction. SASL authentication information is not passed on
|
||||
via message headers or via SMTP. It is no-one's business what
|
||||
username and authentication method the poster was using in order
|
||||
to access the mail server.
|
||||
|
||||
When sending mail, Postfix looks up the server hostname or destination
|
||||
domain (the address remote part) in a table, and if a username/password
|
||||
is found, it will use that username and password to authenticate
|
||||
to the server.
|
||||
|
||||
Building the SASL library
|
||||
=========================
|
||||
|
||||
Postfix appears to work with cyrus-sasl-1.5.5, which is available
|
||||
from:
|
||||
|
||||
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
|
||||
|
||||
IMPORTANT: if you install the Cyrus SASL libraries as per the default,
|
||||
you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
|
||||
|
||||
Reportedly, Microsoft Internet Explorer version 5 requires the
|
||||
non-standard SASL LOGIN authentication method. To enable this
|
||||
authentication method, specify ``./configure --enable-login''.
|
||||
|
||||
If you install the Cyrus SASL libraries as per the default, you
|
||||
will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
|
||||
|
||||
Building Postfix with SASL authentication support
|
||||
=================================================
|
||||
|
||||
To build Postfix with SASL authentication support, the following
|
||||
assumes that the Cyrus SASL include files are in /usr/local/include,
|
||||
and that the Cyrus SASL libraries are in /usr/local/lib.
|
||||
|
||||
On some systems this generates the necessary Makefile definitions:
|
||||
|
||||
% make tidy # if you have left-over files from a previous build
|
||||
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
|
||||
AUXLIBS="-L/usr/local/lib -lsasl"
|
||||
|
||||
On Solaris 2.x you need to specify run-time link information,
|
||||
otherwise ld.so will not find the SASL shared library:
|
||||
|
||||
% make tidy # if you have left-over files from a previous build
|
||||
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
|
||||
AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
|
||||
|
||||
Enabling SASL authentication in the Postfix SMTP server
|
||||
=======================================================
|
||||
|
||||
See conf/sample-auth.cf for examples.
|
||||
|
||||
In order to enable SASL support in the SMTP server:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_sasl_auth_enable = yes
|
||||
|
||||
In order to allow mail relaying by authenticated clients:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks permit_sasl_authenticated ...
|
||||
|
||||
In /usr/local/lib/sasl/smtpd.conf you need to specify how the server
|
||||
should validate client passwords.
|
||||
|
||||
In order to authenticate against the UNIX password database, try:
|
||||
|
||||
/usr/local/lib/sasl/smtpd.conf:
|
||||
pwcheck_method: pwcheck
|
||||
|
||||
The pwcheck daemon is contained in the cyrus-sasl source tarball.
|
||||
|
||||
In order to authenticate against SASL's own password database:
|
||||
|
||||
/usr/local/lib/sasl/smtpd.conf:
|
||||
pwcheck_method: sasldb
|
||||
|
||||
This will use the SASL password file (default: /etc/sasldb), which
|
||||
is maintained with the saslpasswd command (part of the Cyrus SASL
|
||||
software). On some poorly-supported systems the saslpasswd command
|
||||
needs to be run multiple times before it stops complaining. The
|
||||
Postfix SMTP server needs read access to the sasldb file - you may
|
||||
have to play games with group access permissions. On RedHat 6.1,
|
||||
SASL 1.5.5 insists on write access to /etc/sasldb.
|
||||
|
||||
IMPORTANT: To get sasldb running, make sure that you set the SASL domain
|
||||
(realm) to a fully qualified domain name.
|
||||
|
||||
EXAMPLE: saslpasswd -c -u `postconf -h myhostname` exampleuser
|
||||
|
||||
To run software chrooted with SASL support is an interesting
|
||||
exercise. It probably is not worth the trouble.
|
||||
|
||||
Older Microsoft SMTP client software implements a non-standard
|
||||
version of the AUTH protocol syntax, and expects that the SMTP
|
||||
server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH
|
||||
stuff". To accomodate such clients in addition to conformant
|
||||
clients, set "broken_sasl_auth_clients = yes" in the main.cf file.
|
||||
|
||||
Testing SASL authentication in the Postfix SMTP server
|
||||
======================================================
|
||||
|
||||
To test the whole mess, connect to the SMTP server, and you should
|
||||
be able to have a conversation like this:
|
||||
|
||||
220 server.host.name ESMTP Postfix
|
||||
EHLO client.host.name
|
||||
250-server.host.name
|
||||
250-PIPELINING
|
||||
250-SIZE 10240000
|
||||
250-ETRN
|
||||
250-AUTH DIGEST-MD5 PLAIN CRAM-MD5
|
||||
250 8BITMIME
|
||||
AUTH PLAIN dGVzdAB0ZXN0AHRlc3RwYXNz
|
||||
235 Authentication successful
|
||||
|
||||
Instead of dGVzdAB0ZXN0AHRlc3RwYXNz, specify the base64 encoded
|
||||
form of username\0username\0password (the \0 is a null byte). The
|
||||
example above is for a user named `test' with password `testpass'.
|
||||
|
||||
In order to generate base64 encoded authentication information you
|
||||
can use one of the following commands:
|
||||
|
||||
% printf 'username\0username\0password' | mmencode
|
||||
|
||||
% perl -MMIME::Base64 -e \
|
||||
'print encode_base64("username\0username\0password");'
|
||||
|
||||
MIME::Base64 is available from www.cpan.org.
|
||||
|
||||
Enabling SASL authentication in the Postfix SMTP client
|
||||
=======================================================
|
||||
|
||||
Turn on client-side SASL authentication, and specify a table with
|
||||
per-host or per-destination username and password information.
|
||||
Postfix first looks up the server hostname; if no entry is found,
|
||||
then Postfix looks up the destination domain name (usually, the
|
||||
remote part of an email address).
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtp_sasl_auth_enable = yes
|
||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||
|
||||
/etc/postfix/sasl_passwd:
|
||||
foo.com username:password
|
||||
bar.com username
|
||||
|
||||
Note: some SMTP servers support PLAIN or LOGIN authentication only.
|
||||
By default, the Postfix SMTP client does not use authentication
|
||||
methods that send plaintext passwords, and defers delivery with
|
||||
the following error message: "Authentication failed: cannot SASL
|
||||
authenticate to server". To enable plaintext authentication specify,
|
||||
for example:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtp_sasl_security_options =
|
||||
|
||||
The SASL client password file is opened before the SMTP server
|
||||
enters the optional chroot jail, so you can keep the file in
|
||||
/etc/postfix.
|
||||
|
||||
The Postfix SMTP client is backwards compatible with SMTP servers
|
||||
that use the non-standard AUTH=stuff... syntax in response to the
|
||||
EHLO command.
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
|
||||
one queue per rcpt hurts when delivering to agents that don't
|
||||
get stuck on shell commands or mailbox locks
|
||||
|
||||
xxx: bounced as yyy (bounced mail); xxx forwarded as zzz (mail
|
||||
expanded via :include:).
|
||||
|
||||
postconf -f filename
|
||||
|
||||
get rid of the relocated feature - perhaps better to bounce recipients
|
||||
at the SMTP port.
|
||||
|
||||
make sendmail/smtpd/cleanup output directory/fifo configurable
|
||||
|
||||
if postdrop scrutinizes input, skip the overhead in the pickup
|
||||
daemon.
|
||||
|
||||
add a threshold to sendmail etc. stderr logging, so that class
|
||||
"info" messages don't go to stderr.
|
||||
|
||||
implement an UCE control to accept mail if the sender domain sender
|
||||
lists us as MX host (rafal wiosna). By the same token, implement
|
||||
a control to accept mail when the client hostname/parent domain
|
||||
lists us as their MX host.
|
||||
|
||||
received: headers should be generated by the cleanup daemon, and
|
||||
client attributes ("with", "from", etc.) should be passed along
|
||||
with the message. This guarantees that forwarded/aliased mail gets
|
||||
stamped with the queue ID.
|
||||
|
||||
toss double-bounce mail even when mail for the local machine is
|
||||
redirected to another box. See mail_addr_double_bounce().
|
||||
|
||||
remote showq access (cookie in maildrop or print some text to inform
|
||||
the user)
|
||||
|
||||
defer: explain mail was bounced after N days
|
||||
|
||||
multiple rewrite processes?
|
||||
|
||||
gethostbyaddr() uses native name services, which can be slow.
|
||||
|
||||
can we detect a client that ignores error responses?
|
||||
|
||||
way to block inbound mail based on recipient suffix?
|
||||
|
||||
can Postfix implement one switchboard instead of having all these
|
||||
little lookup tables?
|
||||
|
||||
make canonical/virtual/etc. table lookup order configurable
|
||||
|
||||
pass on client etc/ attributes along with message to delivery agent
|
||||
|
||||
scrutinize file opens in delivery agents just like in qmgr (better:
|
||||
open the file and see if someone compromised the vmailer account
|
||||
and is racing against us).
|
||||
|
||||
suspend/resume signals + master status (suspended/running) in PID
|
||||
file. Maybe use FIFO instead. But, that means requests do not
|
||||
arrive when the master is stuck.
|
||||
|
||||
postedit queue-id command...
|
||||
|
||||
more flexible mail queue list command
|
||||
|
||||
multiple queues may make ETRN processing less painful because there
|
||||
is less delayed mail to plow through.
|
||||
|
||||
qmgr: configurable incoming/deferred mixing ratio so we can prioritize
|
||||
new mail over old mail
|
||||
|
||||
Replace [my.own.ip.addr] by domain name so that delivered-to has
|
||||
the desired effect.
|
||||
|
||||
Received: header and bounce text will be configurable with ${name}
|
||||
macros. This requires that everything must cope with newlines in
|
||||
config parameters (including the SMTP greeting bannner, yuck).
|
||||
|
||||
Pass along the client hostname/posting user with queue files, to
|
||||
be logged by the queue manager.
|
||||
|
||||
showq: don't use mail_open_ok() - it assumes coordinated queue
|
||||
access.
|
||||
|
||||
trivial-rewrite: optionally, use DNS to fully qualify hostnames.
|
||||
|
||||
pickup/cleanup/qmgr/local: add options record to control internal
|
||||
features such as canonical/virtual mapping, VERPs etcetera.
|
||||
|
||||
Add hook for (domain, user database) support. This is needed if
|
||||
you have lots of real domains and can't afford a separate master.cf
|
||||
delivery agent entry for each domain.
|
||||
|
||||
Add support for DBZ databases, using the code from INN. Reportedly,
|
||||
GDB handles large numbers of keys poorly.
|
||||
|
||||
Change the front-end to cleanup protocol so that the front-end
|
||||
sends the expected message size, and so that the cleanup service
|
||||
can report if there is enough space. This is useful only for the
|
||||
SMTP server, because pickup can't produce bounce requests: the
|
||||
bounce service can't read the maildrop file.
|
||||
|
||||
On systems with functional UNIX-domain sockets, use that instead
|
||||
of FIFOs to trigger the pickup and qmgr services. This allows for
|
||||
some coupling between front-end programs and queue manager, so that
|
||||
a burst of inbound mail does not lock out the queue manager from
|
||||
accessing the queue, causing outbound delivery to stop.
|
||||
|
||||
There is a need to run `master' services outside the "master"
|
||||
environment, either for testing (new config files) or for production.
|
||||
For consistency reasons, programs file names should be taken from
|
||||
the master.cf file.
|
||||
|
||||
- The showq service. Used by the super user when the mail system
|
||||
is down.
|
||||
|
||||
- The smtpd service for "sendmail -bs" emulation. Used by some
|
||||
mail posting agents. Output to the maildrop, so that messages
|
||||
can be posted even when the mail system is down.
|
||||
|
||||
- The rewrite engine for "sendmail -bt" emulation, for off-line
|
||||
testing of configuration files. Requires a method to override
|
||||
the location of the rewriting rules file. Or, perhaps there
|
||||
should be an official place (/etc/vmailer/testbed?) for playing
|
||||
with config files.
|
||||
|
||||
postfix-script: detect and/or build missing alias database. In
|
||||
order to do this we must extract the alias_maps parameter from the
|
||||
main.cf file, and create any missing files with the right ownerships.
|
||||
|
||||
implement the return-receipt-to notification service.
|
||||
|
||||
bounce/defer: provide attribute-value interface, for better logging
|
||||
(expanded-from etc.) and non-delivery reports.
|
||||
|
||||
Maintain per-client short-term host status, so we can slow down
|
||||
unreasonable clients
|
||||
|
||||
Make archiving delivered mail a REAL option (queue manager). What
|
||||
about one archive per day. The magic could be put into the mail
|
||||
queue name routines. Just make it aware of the date.
|
||||
|
||||
Will the mail system be faster when we avoid moving new messages
|
||||
incoming->active? How would one detect the arrival of new files?
|
||||
|
||||
pickup: pass file descriptor to cleanup instead of copying data.
|
||||
This violates the principle that all front-end programs protect
|
||||
the mail system against unreasonably-long inputs.
|
||||
|
||||
True ETRN means kick the host out of the queue manager's "dead
|
||||
hosts" table & move mail from the "hold" queue for that site to
|
||||
the incoming queue.
|
||||
|
||||
postfix-script: make sure that each queue file matches its file id
|
||||
or we might lose mail.
|
||||
|
||||
postfix-script: do database fixups as the unprivileged user
|
||||
|
||||
Maintain a pool of pre-allocated queue files, to eliminate file
|
||||
creation and deletion overhead.
|
|
@ -1,34 +0,0 @@
|
|||
To: wietse@porcupine.org (Wietse Venema)
|
||||
Subject: postfix-19990317-pl05 on Ultrix4.3a
|
||||
From: Christian von Roques <roques@pond.sub.org>
|
||||
Date: 02 Jun 1999 18:44:34 +0200
|
||||
Message-ID: <87iu96wo0d.fsf_-_@scalar.pond.sub.org>
|
||||
|
||||
I've upgraded the MTA of our DECstation-3100 running Ultrix4.3a to
|
||||
postfix-19990317-pl05 and am sending you the patches I needed to get
|
||||
it running under Ultrix.
|
||||
|
||||
...
|
||||
|
||||
o One of the bugs of Ultrix's /bin/sh is that shell-variables set in
|
||||
arguments of `:' expand to garbage if expanded in here-documents.
|
||||
Using a different shell helps. I needed to replace all calls of
|
||||
``sh .../makedefs'' by ``$(SHELL) .../makedefs'' in all the
|
||||
Makefile.in and am now able to use
|
||||
|
||||
make SHELL=/bin/sh5 or zsh.
|
||||
|
||||
...
|
||||
|
||||
o Ultrix's FD_SET_SIZE is 4096, but getdtablesize() returns 64 by
|
||||
default, if not increased when building a new kernel. getrlimit()
|
||||
doesn't know RLIMIT_NOFILE. This makes event_init() always log
|
||||
the warning: `could allocate space for only 64 open files'.
|
||||
|
||||
I just reduced the threshold from 256 to 64, but this is not good.
|
||||
The initial problem still remains: How to disable this warning on
|
||||
Ultrix without making the source ugly?
|
||||
|
||||
[I have updated util/sys_defs.h, and by default set FD_SETSIZE to
|
||||
100. This should be sufficient for a workstation. No-one would
|
||||
run a major mail hub on Ultrix 4. -- Wietse]
|
|
@ -1,6 +0,0 @@
|
|||
In order to receive mail via UUCP, your system needs to have an
|
||||
rmail command installed. A minimal rmail command can be found in
|
||||
the "auxiliary/rmail" directory. Install the command, mode 755, in
|
||||
a place that can be found by the UUCP "uuxqt" command.
|
||||
|
||||
In order to send mail via UUCP, see html/faq.html.
|
|
@ -1,31 +0,0 @@
|
|||
Before you do the build, make sure you run niscript (as root) to properly
|
||||
create a postfix user, and postfix & maildrop groups.
|
||||
|
||||
DO NOT USE THE MULTIPLE USERS APPLICATION TO CREATE THE POSTFIX USER!
|
||||
|
||||
1) su
|
||||
|
||||
2) ./niscript
|
||||
|
||||
this creates the necessary users & groups for proper operation
|
||||
of postfix
|
||||
|
||||
3) ./stash-sendmail
|
||||
|
||||
move your existing sendmail binaries somewhere safe
|
||||
|
||||
4) make install
|
||||
|
||||
When the script asks you for setgid (the default will be no) tell it
|
||||
maildrop
|
||||
|
||||
5) edit /etc/postfix/main.cf to suit your requirements
|
||||
|
||||
6) postfix start
|
||||
|
||||
7) Test. Read INSTALL for a series of suggested tests.
|
||||
|
||||
8) cp -R darwin-Postfix /System/Library/StartupItems/Postfix
|
||||
|
||||
9) edit /System/Library/StartupItems/Sendmail. add "exit 0" as the
|
||||
first line
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. /etc/rc.common
|
||||
|
||||
##
|
||||
# Start mail server
|
||||
##
|
||||
|
||||
if [ "${MAILSERVER:=-NO-}" = "-YES-" ]; then
|
||||
|
||||
ConsoleMessage "Starting Postfix mail services"
|
||||
/usr/sbin/postfix start
|
||||
fi
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
Description = "Postfix mail server";
|
||||
Provides = ("SMTP");
|
||||
Requires = ("Resolver");
|
||||
Uses = ("Network Time", "NFS");
|
||||
Preference = "None";
|
||||
Messages =
|
||||
{
|
||||
start = "Starting Postfix";
|
||||
stop = "Stopping Postfix";
|
||||
};
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF
|
||||
mv /usr/bin/newaliases /usr/bin/newaliases.OFF
|
||||
mv /usr/bin/mailq /usr/bin/mailq.OFF
|
||||
chmod 755 /usr/sbin/sendmail.OFF /usr/bin/newaliases.OFF /usr/bin/mailq.OFF
|
|
@ -1,22 +0,0 @@
|
|||
*** postfix-script-nosgid Wed Mar 24 11:20:49 1999
|
||||
--- postfix-script-sgid Wed Mar 24 11:20:53 1999
|
||||
***************
|
||||
*** 174,181 ****
|
||||
test -d maildrop || {
|
||||
$WARN creating missing Postfix maildrop directory
|
||||
mkdir maildrop || exit 1
|
||||
! chmod 1733 maildrop
|
||||
chown $mail_owner maildrop
|
||||
}
|
||||
test -d pid || {
|
||||
$WARN creating missing Postfix pid directory
|
||||
--- 174,182 ----
|
||||
test -d maildrop || {
|
||||
$WARN creating missing Postfix maildrop directory
|
||||
mkdir maildrop || exit 1
|
||||
! chmod 1730 maildrop
|
||||
chown $mail_owner maildrop
|
||||
+ chgrp maildrop maildrop
|
||||
}
|
||||
test -d pid || {
|
||||
$WARN creating missing Postfix pid directory
|
|
@ -1,273 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
#++
|
||||
# NAME
|
||||
# postfix-script 1
|
||||
# SUMMARY
|
||||
# execute Postfix administrative commands
|
||||
# SYNOPSIS
|
||||
# \fBpostfix-script\fR \fIcommand\fR
|
||||
# DESCRIPTION
|
||||
# The \fBfBpostfix-script\fR script executes Postfix administrative
|
||||
# commands in an environtment that is set up by the \fBpostfix\fR(1)
|
||||
# command.
|
||||
# SEE ALSO
|
||||
# master(8) Postfix master program
|
||||
# postfix(1) Postfix administrative interface
|
||||
# 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
|
||||
#--
|
||||
|
||||
# Avoid POSIX death due to SIGHUP when some parent process exits.
|
||||
|
||||
trap '' 1
|
||||
|
||||
case $daemon_directory in
|
||||
"") echo This script must be run by the postfix command. 1>&2
|
||||
echo Do not run directly. 1>&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
LOGGER="$command_directory/postlog -t postfix-script"
|
||||
INFO="$LOGGER -p info"
|
||||
WARN="$LOGGER -p warn"
|
||||
ERROR="$LOGGER -p error"
|
||||
FATAL="$LOGGER -p fatal"
|
||||
PANIC="$LOGGER -p panic"
|
||||
|
||||
umask 022
|
||||
|
||||
#
|
||||
# LINUX by default does not synchronously update directories -
|
||||
# that's dangerous for mail.
|
||||
#
|
||||
if [ -f /usr/bin/chattr ]
|
||||
then
|
||||
CHATTR="/usr/bin/chattr +S"
|
||||
else
|
||||
CHATTR=:
|
||||
fi
|
||||
|
||||
#
|
||||
# Can't do much without these in place.
|
||||
#
|
||||
cd $command_directory || {
|
||||
$FATAL no Postfix command directory $command_directory!
|
||||
exit 1
|
||||
}
|
||||
cd $daemon_directory || {
|
||||
$FATAL no Postfix daemon directory $daemon_directory!
|
||||
exit 1
|
||||
}
|
||||
test -f master || {
|
||||
$FATAL no Postfix master program $daemon_directory/master!
|
||||
exit 1
|
||||
}
|
||||
cd $config_directory || {
|
||||
$FATAL no Postfix configuration directory $config_directory!
|
||||
exit 1
|
||||
}
|
||||
cd $queue_directory || {
|
||||
$FATAL no Postfix queue directory $queue_directory!
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Parse JCL
|
||||
#
|
||||
case $1 in
|
||||
|
||||
start_msg)
|
||||
|
||||
echo "Start postfix"
|
||||
;;
|
||||
|
||||
stop_msg)
|
||||
|
||||
echo "Stop postfix"
|
||||
;;
|
||||
|
||||
start)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null || {
|
||||
$FATAL the Postfix mail system is already running
|
||||
exit 1
|
||||
}
|
||||
$config_directory/postfix-script check || {
|
||||
$FATAL Postfix integrity check failed!
|
||||
exit 1
|
||||
}
|
||||
$INFO starting the Postfix mail system
|
||||
$daemon_directory/master &
|
||||
;;
|
||||
|
||||
drain)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO stopping the Postfix mail system
|
||||
kill -9 `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO stopping the Postfix mail system
|
||||
kill `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
abort)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO aborting the Postfix mail system
|
||||
kill `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
reload)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO refreshing the Postfix mail system
|
||||
$command_directory/postsuper active || exit 1
|
||||
kill -HUP `sed 1q pid/master.pid`
|
||||
$command_directory/postsuper &
|
||||
;;
|
||||
|
||||
flush)
|
||||
|
||||
cd $queue_directory || {
|
||||
$FATAL no Postfix queue directory $queue_directory!
|
||||
exit 1
|
||||
}
|
||||
$command_directory/postkick public qmgr IDFA
|
||||
;;
|
||||
|
||||
check)
|
||||
|
||||
for dir in $daemon_directory $config_directory $queue_directory
|
||||
do
|
||||
ls -lLd $dir | (grep " root " >/dev/null ||
|
||||
$WARN not owned by root: $dir)
|
||||
done
|
||||
|
||||
find $daemon_directory/* $config_directory/* ! -user root \
|
||||
-exec $WARN not owned by root: {} \;
|
||||
|
||||
find $daemon_directory/. $config_directory/. \
|
||||
\( -perm -020 -o -perm -002 \) \
|
||||
-exec $WARN group or other writable: {} \;
|
||||
|
||||
find $queue_directory/* $config_directory/* -name '*core' \
|
||||
-exec $WARN core file: {} \; 2>/dev/null
|
||||
|
||||
test -d maildrop || {
|
||||
$WARN creating missing Postfix maildrop directory
|
||||
mkdir maildrop || exit 1
|
||||
chmod 1733 maildrop
|
||||
chown $mail_owner maildrop
|
||||
}
|
||||
test -d pid || {
|
||||
$WARN creating missing Postfix pid directory
|
||||
mkdir pid || exit 1
|
||||
chmod 755 pid
|
||||
chown $mail_owner pid
|
||||
}
|
||||
for dir in incoming active bounce defer deferred flush saved corrupt; do
|
||||
test -d $dir || {
|
||||
$WARN creating missing Postfix $dir directory
|
||||
mkdir $dir || exit 1
|
||||
chmod 700 $dir; $CHATTR $dir 2>/dev/null
|
||||
chown $mail_owner $dir
|
||||
}
|
||||
done
|
||||
test -d public || {
|
||||
$WARN creating missing Postfix public directory
|
||||
mkdir public || exit 1
|
||||
chmod 755 public
|
||||
chown $mail_owner public
|
||||
}
|
||||
test -d private || {
|
||||
$WARN creating missing Postfix private directory
|
||||
mkdir private || exit 1
|
||||
chmod 700 private
|
||||
chown $mail_owner private
|
||||
}
|
||||
find `ls -d $queue_directory/* | \
|
||||
egrep '/(incoming|active|defer|deferred|bounce|saved|corrupt|public|private)$'` \
|
||||
! \( -type p -o -type s \) ! -user $mail_owner \
|
||||
-exec $WARN not owned by $mail_owner: {} \;
|
||||
|
||||
for dir in $queue_directory/maildrop
|
||||
do
|
||||
ls -lLd $dir | (grep " $mail_owner " >/dev/null ||
|
||||
$WARN not owned by $mail_owner: $dir)
|
||||
done
|
||||
|
||||
for dir in bin etc lib sbin usr
|
||||
do
|
||||
test -d $dir && find $dir -type f -print | while read path
|
||||
do
|
||||
cmp -s $path /$path ||
|
||||
$WARN $queue_directory/$path and /$path differ
|
||||
done
|
||||
done
|
||||
|
||||
# Look for incomplete upgrades.
|
||||
|
||||
test -f $config_directory/master.cf || {
|
||||
$FATAL no $config_directory/master.cf file found
|
||||
exit 1
|
||||
}
|
||||
grep 'flush.*flush' $config_directory/master.cf >/dev/null || {
|
||||
$WARN adding missing entry for flush service to master.cf
|
||||
cat >>$config_directory/master.cf <<EOF
|
||||
flush unix - - n 1000? 0 flush
|
||||
EOF
|
||||
}
|
||||
found=`$command_directory/postconf -h hash_queue_names`
|
||||
missing=
|
||||
(echo "$found" | grep active >/dev/null) || missing="$missing active"
|
||||
(echo "$found" | grep bounce >/dev/null) || missing="$missing bounce"
|
||||
(echo "$found" | grep defer >/dev/null) || missing="$missing defer"
|
||||
(echo "$found" | grep flush >/dev/null) || missing="$missing flush"
|
||||
(echo "$found" | grep incoming>/dev/null)|| missing="$missing incoming"
|
||||
(echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
|
||||
test -n "$missing" && {
|
||||
$WARN fixing main.cf hash_queue_names for missing $missing
|
||||
$command_directory/postconf -e hash_queue_names="$found$missing"
|
||||
}
|
||||
|
||||
# See if all queue files are in the right place.
|
||||
|
||||
$command_directory/postsuper active
|
||||
$command_directory/postsuper &
|
||||
|
||||
find corrupt -type f -exec $WARN damaged message: {} \;
|
||||
|
||||
# XXX also: look for weird stuff, weird permissions, etc.
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
$FATAL "usage: postfix start (or stop, reload, abort, flush, or check)"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
|
@ -1,274 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
#++
|
||||
# NAME
|
||||
# postfix-script 1
|
||||
# SUMMARY
|
||||
# execute Postfix administrative commands
|
||||
# SYNOPSIS
|
||||
# \fBpostfix-script\fR \fIcommand\fR
|
||||
# DESCRIPTION
|
||||
# The \fBfBpostfix-script\fR script executes Postfix administrative
|
||||
# commands in an environtment that is set up by the \fBpostfix\fR(1)
|
||||
# command.
|
||||
# SEE ALSO
|
||||
# master(8) Postfix master program
|
||||
# postfix(1) Postfix administrative interface
|
||||
# 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
|
||||
#--
|
||||
|
||||
# Avoid POSIX death due to SIGHUP when some parent process exits.
|
||||
|
||||
trap '' 1
|
||||
|
||||
case $daemon_directory in
|
||||
"") echo This script must be run by the postfix command. 1>&2
|
||||
echo Do not run directly. 1>&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
LOGGER="$command_directory/postlog -t postfix-script"
|
||||
INFO="$LOGGER -p info"
|
||||
WARN="$LOGGER -p warn"
|
||||
ERROR="$LOGGER -p error"
|
||||
FATAL="$LOGGER -p fatal"
|
||||
PANIC="$LOGGER -p panic"
|
||||
|
||||
umask 022
|
||||
|
||||
#
|
||||
# LINUX by default does not synchronously update directories -
|
||||
# that's dangerous for mail.
|
||||
#
|
||||
if [ -f /usr/bin/chattr ]
|
||||
then
|
||||
CHATTR="/usr/bin/chattr +S"
|
||||
else
|
||||
CHATTR=:
|
||||
fi
|
||||
|
||||
#
|
||||
# Can't do much without these in place.
|
||||
#
|
||||
cd $command_directory || {
|
||||
$FATAL no Postfix command directory $command_directory!
|
||||
exit 1
|
||||
}
|
||||
cd $daemon_directory || {
|
||||
$FATAL no Postfix daemon directory $daemon_directory!
|
||||
exit 1
|
||||
}
|
||||
test -f master || {
|
||||
$FATAL no Postfix master program $daemon_directory/master!
|
||||
exit 1
|
||||
}
|
||||
cd $config_directory || {
|
||||
$FATAL no Postfix configuration directory $config_directory!
|
||||
exit 1
|
||||
}
|
||||
cd $queue_directory || {
|
||||
$FATAL no Postfix queue directory $queue_directory!
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Parse JCL
|
||||
#
|
||||
case $1 in
|
||||
|
||||
start_msg)
|
||||
|
||||
echo "Start postfix"
|
||||
;;
|
||||
|
||||
stop_msg)
|
||||
|
||||
echo "Stop postfix"
|
||||
;;
|
||||
|
||||
start)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null || {
|
||||
$FATAL the Postfix mail system is already running
|
||||
exit 1
|
||||
}
|
||||
$config_directory/postfix-script check || {
|
||||
$FATAL Postfix integrity check failed!
|
||||
exit 1
|
||||
}
|
||||
$INFO starting the Postfix mail system
|
||||
$daemon_directory/master &
|
||||
;;
|
||||
|
||||
drain)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO stopping the Postfix mail system
|
||||
kill -9 `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO stopping the Postfix mail system
|
||||
kill `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
abort)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO aborting the Postfix mail system
|
||||
kill `sed 1q pid/master.pid`
|
||||
;;
|
||||
|
||||
reload)
|
||||
|
||||
$daemon_directory/master -t 2>/dev/null && {
|
||||
$FATAL the Postfix mail system is not running
|
||||
exit 1
|
||||
}
|
||||
$INFO refreshing the Postfix mail system
|
||||
$command_directory/postsuper active || exit 1
|
||||
kill -HUP `sed 1q pid/master.pid`
|
||||
$command_directory/postsuper &
|
||||
;;
|
||||
|
||||
flush)
|
||||
|
||||
cd $queue_directory || {
|
||||
$FATAL no Postfix queue directory $queue_directory!
|
||||
exit 1
|
||||
}
|
||||
$command_directory/postkick public qmgr IDFA
|
||||
;;
|
||||
|
||||
check)
|
||||
|
||||
for dir in $daemon_directory $config_directory $queue_directory
|
||||
do
|
||||
ls -lLd $dir | (grep " root " >/dev/null ||
|
||||
$WARN not owned by root: $dir)
|
||||
done
|
||||
|
||||
find $daemon_directory/* $config_directory/* ! -user root \
|
||||
-exec $WARN not owned by root: {} \;
|
||||
|
||||
find $daemon_directory/. $config_directory/. \
|
||||
\( -perm -020 -o -perm -002 \) \
|
||||
-exec $WARN group or other writable: {} \;
|
||||
|
||||
find $queue_directory/* $config_directory/* -name '*core' \
|
||||
-exec $WARN core file: {} \; 2>/dev/null
|
||||
|
||||
test -d maildrop || {
|
||||
$WARN creating missing Postfix maildrop directory
|
||||
mkdir maildrop || exit 1
|
||||
chmod 1730 maildrop
|
||||
chown $mail_owner maildrop
|
||||
chgrp maildrop maildrop
|
||||
}
|
||||
test -d pid || {
|
||||
$WARN creating missing Postfix pid directory
|
||||
mkdir pid || exit 1
|
||||
chmod 755 pid
|
||||
chown $mail_owner pid
|
||||
}
|
||||
for dir in incoming active bounce defer deferred flush saved corrupt; do
|
||||
test -d $dir || {
|
||||
$WARN creating missing Postfix $dir directory
|
||||
mkdir $dir || exit 1
|
||||
chmod 700 $dir; $CHATTR $dir 2>/dev/null
|
||||
chown $mail_owner $dir
|
||||
}
|
||||
done
|
||||
test -d public || {
|
||||
$WARN creating missing Postfix public directory
|
||||
mkdir public || exit 1
|
||||
chmod 755 public
|
||||
chown $mail_owner public
|
||||
}
|
||||
test -d private || {
|
||||
$WARN creating missing Postfix private directory
|
||||
mkdir private || exit 1
|
||||
chmod 700 private
|
||||
chown $mail_owner private
|
||||
}
|
||||
find `ls -d $queue_directory/* | \
|
||||
egrep '/(incoming|active|defer|deferred|bounce|saved|corrupt|public|private)$'` \
|
||||
! \( -type p -o -type s \) ! -user $mail_owner \
|
||||
-exec $WARN not owned by $mail_owner: {} \;
|
||||
|
||||
for dir in $queue_directory/maildrop
|
||||
do
|
||||
ls -lLd $dir | (grep " $mail_owner " >/dev/null ||
|
||||
$WARN not owned by $mail_owner: $dir)
|
||||
done
|
||||
|
||||
for dir in bin etc lib sbin usr
|
||||
do
|
||||
test -d $dir && find $dir -type f -print | while read path
|
||||
do
|
||||
cmp -s $path /$path ||
|
||||
$WARN $queue_directory/$path and /$path differ
|
||||
done
|
||||
done
|
||||
|
||||
# Look for incomplete upgrades.
|
||||
|
||||
test -f $config_directory/master.cf || {
|
||||
$FATAL no $config_directory/master.cf file found
|
||||
exit 1
|
||||
}
|
||||
grep 'flush.*flush' $config_directory/master.cf >/dev/null || {
|
||||
$WARN adding missing entry for flush service to master.cf
|
||||
cat >>$config_directory/master.cf <<EOF
|
||||
flush unix - - n 1000? 0 flush
|
||||
EOF
|
||||
}
|
||||
found=`$command_directory/postconf -h hash_queue_names`
|
||||
missing=
|
||||
(echo "$found" | grep active >/dev/null) || missing="$missing active"
|
||||
(echo "$found" | grep bounce >/dev/null) || missing="$missing bounce"
|
||||
(echo "$found" | grep defer >/dev/null) || missing="$missing defer"
|
||||
(echo "$found" | grep flush >/dev/null) || missing="$missing flush"
|
||||
(echo "$found" | grep incoming>/dev/null)|| missing="$missing incoming"
|
||||
(echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
|
||||
test -n "$missing" && {
|
||||
$WARN fixing main.cf hash_queue_names for missing $missing
|
||||
$command_directory/postconf -e hash_queue_names="$found$missing"
|
||||
}
|
||||
|
||||
# See if all queue files are in the right place.
|
||||
|
||||
$command_directory/postsuper active
|
||||
$command_directory/postsuper &
|
||||
|
||||
find corrupt -type f -exec $WARN damaged message: {} \;
|
||||
|
||||
# XXX also: look for weird stuff, weird permissions, etc.
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
$FATAL "usage: postfix start (or stop, reload, abort, flush, or check)"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
|
@ -1,52 +0,0 @@
|
|||
#
|
||||
# Sample pcre (PERL-compatible regular expression) map file
|
||||
#
|
||||
# The first field is a perl-like regular expression. The expression
|
||||
# delimiter can be any character except whitespace, or characters
|
||||
# that have special meaning to the regexp library (traditionally
|
||||
# the forward slash is used). The regular expression can contain
|
||||
# whitespace.
|
||||
#
|
||||
# By default, matching is case-INsensitive, although following
|
||||
# the second slash with an 'i' will reverse this. Other flags are
|
||||
# supported, but the only other useful one is 'U', which makes
|
||||
# matching ungreedy (see PCRE documentation and source for more
|
||||
# info).
|
||||
#
|
||||
# The second field is the "replacement" string - the text
|
||||
# returned by the match. When used for smtpd checks, this would
|
||||
# be a helpful message to misguided users (or an offensive
|
||||
# message to spammers), although it could also be a domain name
|
||||
# or other data for use as a transport, virtual, or other map.
|
||||
#
|
||||
# Substitution of sub-strings from the matched expression is
|
||||
# possible using the conventional perl syntax. The macros in the
|
||||
# replacement string may need to be protected with curly braces
|
||||
# if they aren't followed by whitespace (see the examples
|
||||
# below).
|
||||
#
|
||||
# Lines starting with whitespace are continuation lines - they are
|
||||
# appended to the previous line (there should be no whitespace
|
||||
# before your regular expression!)
|
||||
#
|
||||
# This code was originally developed for SPAM control. However
|
||||
# it seems that it can be used equally well for address rewriting
|
||||
# by virtual or canonical lookups. Using this for aliases might
|
||||
# be stretching things, though.
|
||||
#
|
||||
|
||||
# Protect your outgoing majordomo exploders
|
||||
#
|
||||
/^(?!owner-)(.*)-outgoing@(connect.com.au)$/ 550 Use ${1}@${2} instead
|
||||
|
||||
|
||||
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||
# be better just bouncing all friend@ mail - this is just an example).
|
||||
#
|
||||
/^friend@(?!connect.com.au).*$/ 550 Stick this in your pipe $0
|
||||
|
||||
# A multi-line response
|
||||
#
|
||||
/^noddy@connect.com.au$/
|
||||
550 This user is a funny one. You really don't want to send mail to them
|
||||
as it only makes their head spin.
|
|
@ -1,21 +0,0 @@
|
|||
# Sample regexp lookup "table".
|
||||
#
|
||||
# Format is /regexp/flags or /regexp/flags!/regexp/flags
|
||||
# where regexp is a regular expression as found in regexp(5), and flags are
|
||||
# i: toggle ignore case (REG_ICASE - default is to ignore case)
|
||||
# x: toggle extended expression (REG_EXTENDED - default is extended)
|
||||
# m: toggle multiline mode (REG_NEWLINE - default is non-multiline mode)
|
||||
#
|
||||
# In order for a line to match, the first regexp must match, and the
|
||||
# second (if present) must not match. The first matching line wins,
|
||||
# terminating processing of the ruleset.
|
||||
|
||||
# Disallow sender-specified routing. This is a must if you relay mail
|
||||
#for other domains.
|
||||
/[%!@].*@/ 550 Sender-specified routing rejected
|
||||
|
||||
# Postmaster is OK, that way they can talk to us about how to fix their problem.
|
||||
/^postmaster@.*$/ OK
|
||||
|
||||
# Protect your outgoing majordomo exploders
|
||||
/^(.*)-outgoing@(.*)$/!/^owner-.*/ 550 Use ${1}@${2} instead
|
|
@ -1,69 +0,0 @@
|
|||
/*++
|
||||
/* NAME
|
||||
/* mail_command_read 3
|
||||
/* SUMMARY
|
||||
/* single-command server
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/*
|
||||
/* int mail_command_read(stream, format, ...)
|
||||
/* VSTREAM *stream;
|
||||
/* char *format;
|
||||
/* DESCRIPTION
|
||||
/* This module implements the server interface for single-command
|
||||
/* requests: a clients sends a single command and expects a single
|
||||
/* completion status code.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP stream
|
||||
/* Server endpoint.
|
||||
/* .IP format
|
||||
/* Format string understood by mail_print(3) and mail_scan(3).
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* SEE ALSO
|
||||
/* mail_scan(3)
|
||||
/* mail_command_write(3) client interface
|
||||
/* 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 <stdlib.h> /* 44BSD stdarg.h uses abort() */
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <vstring.h>
|
||||
#include <vstream.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include "mail_proto.h"
|
||||
|
||||
/* mail_command_read - read single-command request */
|
||||
|
||||
int mail_command_read(VSTREAM *stream, char *fmt,...)
|
||||
{
|
||||
VSTRING *eof = vstring_alloc(10);
|
||||
va_list ap;
|
||||
int count;
|
||||
|
||||
va_start(ap, fmt);
|
||||
count = mail_vscan(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
if (mail_scan(stream, "%s", eof) != 1 || strcmp(vstring_str(eof), MAIL_EOF))
|
||||
count = -1;
|
||||
vstring_free(eof);
|
||||
return (count);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*++
|
||||
/* NAME
|
||||
/* mail_command_write 3
|
||||
/* SUMMARY
|
||||
/* single-command client
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/*
|
||||
/* int mail_command_write(class, name, format, ...)
|
||||
/* const char *class;
|
||||
/* const char *name;
|
||||
/* const char *format;
|
||||
/* DESCRIPTION
|
||||
/* This module implements a client interface for single-command
|
||||
/* clients: a client that sends a single command and expects
|
||||
/* a single completion status code.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP class
|
||||
/* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
|
||||
/* .IP name
|
||||
/* Service name (master.cf).
|
||||
/* .IP format
|
||||
/* Format string understood by mail_print(3).
|
||||
/* DIAGNOSTICS
|
||||
/* The result is -1 if the request could not be sent, otherwise
|
||||
/* the result is the status reported by the server.
|
||||
/* Warnings: problems connecting to the requested service.
|
||||
/* Fatal: out of memory.
|
||||
/* SEE ALSO
|
||||
/* mail_command_read(3), server interface
|
||||
/* mail_proto(5h), client-server protocol
|
||||
/* 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 <stdlib.h> /* 44BSD stdarg.h uses abort() */
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <vstream.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include "mail_proto.h"
|
||||
|
||||
/* mail_command_write - single-command transaction with completion status */
|
||||
|
||||
int mail_command_write(const char *class, const char *name,
|
||||
const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
VSTREAM *stream;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Talk a little protocol with the specified service.
|
||||
*/
|
||||
if ((stream = mail_connect(class, name, BLOCKING)) == 0)
|
||||
return (-1);
|
||||
va_start(ap, fmt);
|
||||
status = mail_vprint(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
if (status != 0
|
||||
|| mail_print(stream, "%s", MAIL_EOF) != 0
|
||||
|| vstream_fflush(stream) != 0
|
||||
|| mail_scan(stream, "%d", &status) != 1)
|
||||
status = -1;
|
||||
(void) vstream_fclose(stream);
|
||||
return (status);
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
/*++
|
||||
/* NAME
|
||||
/* mail_print 3
|
||||
/* SUMMARY
|
||||
/* intra-mail system write routine
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/*
|
||||
/* int mail_print(stream, format, ...)
|
||||
/* VSTREAM *stream;
|
||||
/* const char *format;
|
||||
/*
|
||||
/* int mail_vprint(stream, format, ap)
|
||||
/* VSTREAM *stream;
|
||||
/* const char *format;
|
||||
/* va_list ap;
|
||||
/*
|
||||
/* void mail_print_register(letter, name, print_fn)
|
||||
/* int letter;
|
||||
/* const char *name;
|
||||
/* void (*print_fn)(VSTREAM *stream, const char *data);
|
||||
/* DESCRIPTION
|
||||
/* mail_print() prints one or more null-delimited strings to
|
||||
/* the named stream, each string being converted according to the
|
||||
/* contents of the \fIformat\fR argument.
|
||||
/*
|
||||
/* mail_vprint() provides an alternative interface.
|
||||
/*
|
||||
/* mail_print_register() registers the named print function for
|
||||
/* the specified letter, for the named type.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP stream
|
||||
/* The stream to print to.
|
||||
/* .IP format
|
||||
/* Format string, which is interpreted as follows:
|
||||
/* .RS
|
||||
/* .IP "white space"
|
||||
/* White space in the format string is ignored.
|
||||
/* .IP %s
|
||||
/* The corresponding argument has type (char *).
|
||||
/* .IP %d
|
||||
/* The corresponding argument has type (int).
|
||||
/* .IP %ld
|
||||
/* The corresponding argument has type (long).
|
||||
/* .IP %letter
|
||||
/* Call the print routine that was registered for the specified letter.
|
||||
/* .PP
|
||||
/* Anything else in a format string is a fatal error.
|
||||
/* .RE
|
||||
/* .IP letter
|
||||
/* Format letter that is bound to the \fIprint_fn\fR print function.
|
||||
/* .IP name
|
||||
/* Descriptive string for verbose logging.
|
||||
/* .IP print_fn
|
||||
/* A print function. It takes as arguments:
|
||||
/* .RS
|
||||
/* .IP stream
|
||||
/* The stream to print to.
|
||||
/* .IP data
|
||||
/* A generic data pointer. It is up to the function
|
||||
/* to do any necessary casts to the data-specific type.
|
||||
/* .RE
|
||||
/* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <mymalloc.h>
|
||||
#include <vstream.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include "mail_proto.h"
|
||||
|
||||
/*
|
||||
* Provision for the user to register type-specific scanners for
|
||||
* applications with unusual requirements.
|
||||
*/
|
||||
typedef struct {
|
||||
int letter;
|
||||
char *name;
|
||||
MAIL_PRINT_FN print_fn;
|
||||
} MAIL_PRINT;
|
||||
|
||||
MAIL_PRINT *mail_print_tab = 0;
|
||||
int mail_print_tablen = 0;
|
||||
|
||||
/* mail_print_register - register printer function */
|
||||
|
||||
void mail_print_register(int letter, const char *name, MAIL_PRINT_FN print_fn)
|
||||
{
|
||||
MAIL_PRINT *tp;
|
||||
|
||||
for (tp = 0; tp < mail_print_tab + mail_print_tablen; tp++)
|
||||
if (tp->letter == letter)
|
||||
msg_panic("mail_print_register: redefined letter: %c", letter);
|
||||
|
||||
/*
|
||||
* Tight fit allocation. We're not registering lots of characters.
|
||||
*/
|
||||
if (mail_print_tab == 0) {
|
||||
mail_print_tablen = 1;
|
||||
mail_print_tab = (MAIL_PRINT *)
|
||||
mymalloc(sizeof(*mail_print_tab) * mail_print_tablen);
|
||||
} else {
|
||||
mail_print_tablen++;
|
||||
mail_print_tab = (MAIL_PRINT *)
|
||||
myrealloc((char *) mail_print_tab,
|
||||
sizeof(*mail_print_tab) * mail_print_tablen);
|
||||
}
|
||||
tp = mail_print_tab + mail_print_tablen - 1;
|
||||
tp->letter = letter;
|
||||
tp->name = mystrdup(name);
|
||||
tp->print_fn = print_fn;
|
||||
}
|
||||
|
||||
/* mail_vprint - print null-delimited data to stream */
|
||||
|
||||
int mail_vprint(VSTREAM *stream, const char *fmt, va_list ap)
|
||||
{
|
||||
const char *cp;
|
||||
int lflag;
|
||||
char *sval;
|
||||
int ival;
|
||||
long lval;
|
||||
int error;
|
||||
MAIL_PRINT *tp;
|
||||
|
||||
for (cp = fmt; (error = vstream_ferror(stream)) == 0 && *cp != 0; cp++) {
|
||||
if (ISSPACE(*cp))
|
||||
continue;
|
||||
if (*cp != '%')
|
||||
msg_fatal("mail_vprint: bad format: %.*s>%c<%s",
|
||||
(int) (cp - fmt), fmt, *cp, cp + 1);
|
||||
if ((lflag = (*++cp == 'l')) != 0)
|
||||
cp++;
|
||||
|
||||
switch (*cp) {
|
||||
case 's':
|
||||
sval = va_arg(ap, char *);
|
||||
if (msg_verbose)
|
||||
msg_info("print string: %s", sval);
|
||||
vstream_fputs(sval, stream);
|
||||
VSTREAM_PUTC(0, stream);
|
||||
break;
|
||||
case 'd':
|
||||
if (lflag) {
|
||||
lval = va_arg(ap, long);
|
||||
if (msg_verbose)
|
||||
msg_info("print long: %ld", lval);
|
||||
vstream_fprintf(stream, "%ld", lval);
|
||||
} else {
|
||||
ival = va_arg(ap, int);
|
||||
if (msg_verbose)
|
||||
msg_info("print int: %d", ival);
|
||||
vstream_fprintf(stream, "%d", ival);
|
||||
}
|
||||
VSTREAM_PUTC(0, stream);
|
||||
break;
|
||||
default:
|
||||
for (tp = mail_print_tab; tp < mail_print_tab + mail_print_tablen; tp++)
|
||||
if (tp->letter == *cp) {
|
||||
if (msg_verbose)
|
||||
msg_info("print %s", tp->name);
|
||||
tp->print_fn(stream, va_arg(ap, char *));
|
||||
break;
|
||||
}
|
||||
if (tp >= mail_print_tab + mail_print_tablen)
|
||||
msg_fatal("mail_vprint: bad format: %.*s>%c<%s",
|
||||
(int) (cp - fmt), fmt, *cp, cp + 1);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* mail_print - print null-delimited data to stream */
|
||||
|
||||
int mail_print(VSTREAM *stream, const char *fmt,...)
|
||||
{
|
||||
int status;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
status = mail_vprint(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
return (status);
|
||||
}
|
|
@ -1,272 +0,0 @@
|
|||
/*++
|
||||
/* NAME
|
||||
/* mail_scan 3
|
||||
/* SUMMARY
|
||||
/* intra-mail read routine
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/*
|
||||
/* int mail_scan(stream, format, ...)
|
||||
/* VSTREAM *stream;
|
||||
/* const char *format;
|
||||
/*
|
||||
/* void mail_scan_register(letter, name, scan_fn)
|
||||
/* int letter;
|
||||
/* const char *name;
|
||||
/* int (*scan_fn)(const char *string, char *result);
|
||||
/* DESCRIPTION
|
||||
/* mail_scan() reads one or more null-delimited strings from
|
||||
/* the named stream, each string being converted according to the
|
||||
/* contents of the \fIformat\fR argument.
|
||||
/* The result value is the number of successful conversions.
|
||||
/*
|
||||
/* mail_scan_register() registers an input conversion function
|
||||
/* for the specified letter.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP stream
|
||||
/* Stream to read from.
|
||||
/* .IP format
|
||||
/* Format string, which is interpreted as follows:
|
||||
/* .RS
|
||||
/* .IP "white space"
|
||||
/* White space in the format string is ignored.
|
||||
/* .IP %s
|
||||
/* The corresponding argument has type (VSTRING *).
|
||||
/* .IP %d
|
||||
/* The corresponding argument has type (int *).
|
||||
/* .IP %ld
|
||||
/* The corresponding argument has type (long *).
|
||||
/* .IP %letter
|
||||
/* Call the input conversion routine that was registered for
|
||||
/* the specified letter.
|
||||
/* .PP
|
||||
/* Anything else in a format string is a fatal error.
|
||||
/* .RE
|
||||
/* .IP letter
|
||||
/* Format letter that is bound to the \fIscan_fn\fR input
|
||||
/* conversion function.
|
||||
/* .IP name
|
||||
/* Descriptive string for verbose logging.
|
||||
/* .IP scan_fn
|
||||
/* An input conversion function. It takes as arguments:
|
||||
/* .RS
|
||||
/* .IP string
|
||||
/* The null-terminated string to be converted.
|
||||
/* .IP result
|
||||
/* A character pointer to the result. It is up to the function
|
||||
/* to do any necessary casts to the data-specific type.
|
||||
/* .RE
|
||||
/* .PP
|
||||
/* The function result values are as follows:
|
||||
/* .RS
|
||||
/* .IP MAIL_SCAN_ERROR
|
||||
/* The expected input could not be read.
|
||||
/* .IP MAIL_SCAN_DONE
|
||||
/* The operation completed successfully.
|
||||
/* .IP MAIL_SCAN_MORE
|
||||
/* More input is expected.
|
||||
/* .RE
|
||||
/* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <vstring.h>
|
||||
#include <vstream.h>
|
||||
#include <vstring_vstream.h>
|
||||
#include <mymalloc.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include "mail_proto.h"
|
||||
|
||||
/*
|
||||
* Provision for the user to register type-specific input conversion
|
||||
* routines for applications with unusual requirements.
|
||||
*/
|
||||
typedef struct {
|
||||
int letter;
|
||||
char *name;
|
||||
MAIL_SCAN_FN scanner;
|
||||
} MAIL_SCAN;
|
||||
|
||||
MAIL_SCAN *mail_scan_tab = 0;
|
||||
int mail_scan_tablen = 0;
|
||||
|
||||
/* mail_scan_register - register scanner function */
|
||||
|
||||
void mail_scan_register(int letter, const char *name, MAIL_SCAN_FN scanner)
|
||||
{
|
||||
MAIL_SCAN *tp;
|
||||
|
||||
for (tp = 0; tp < mail_scan_tab + mail_scan_tablen; tp++)
|
||||
if (tp->letter == letter)
|
||||
msg_panic("mail_scan_register: redefined letter: %c", letter);
|
||||
|
||||
/*
|
||||
* Tight fit allocation (as in: Robin Hood and the men that wear tights).
|
||||
*/
|
||||
if (mail_scan_tab == 0) {
|
||||
mail_scan_tablen = 1;
|
||||
mail_scan_tab = (MAIL_SCAN *)
|
||||
mymalloc(sizeof(*mail_scan_tab) * mail_scan_tablen);
|
||||
} else {
|
||||
mail_scan_tablen++;
|
||||
mail_scan_tab = (MAIL_SCAN *)
|
||||
myrealloc((char *) mail_scan_tab,
|
||||
sizeof(*mail_scan_tab) * mail_scan_tablen);
|
||||
}
|
||||
tp = mail_scan_tab + mail_scan_tablen - 1;
|
||||
tp->letter = letter;
|
||||
tp->name = mystrdup(name);
|
||||
tp->scanner = scanner;
|
||||
}
|
||||
|
||||
/* mail_scan_any - read one null-delimited string from stream */
|
||||
|
||||
static int mail_scan_any(VSTREAM *stream, VSTRING *vp, char *what)
|
||||
{
|
||||
if (vstring_fgets_null(vp, stream) == 0) {
|
||||
msg_warn("end of input while receiving %s data from service %s",
|
||||
what, VSTREAM_PATH(stream));
|
||||
return (-1);
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("mail_scan_any: read %s: %s", what, vstring_str(vp));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* mail_scan_other - read user-defined type from stream */
|
||||
|
||||
static int mail_scan_other(VSTREAM *stream, VSTRING *vp,
|
||||
MAIL_SCAN *tp, char *result)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while ((ret = mail_scan_any(stream, vp, tp->name)) == 0) {
|
||||
switch (tp->scanner(vstring_str(vp), result)) {
|
||||
case MAIL_SCAN_MORE:
|
||||
break;
|
||||
case MAIL_SCAN_DONE:
|
||||
return (0);
|
||||
case MAIL_SCAN_ERROR:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* mail_scan_long - read long integer from stream */
|
||||
|
||||
static int mail_scan_long(VSTREAM *stream, VSTRING *vp, long *lp)
|
||||
{
|
||||
int ret;
|
||||
char junk;
|
||||
|
||||
if ((ret = mail_scan_any(stream, vp, "long integer")) == 0) {
|
||||
if (sscanf(vstring_str(vp), "%ld%c", lp, &junk) != 1) {
|
||||
msg_warn("mail_scan_long: bad long long: %s", vstring_str(vp));
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* mail_scan_int - read integer from stream */
|
||||
|
||||
static int mail_scan_int(VSTREAM *stream, VSTRING *vp, int *lp)
|
||||
{
|
||||
int ret;
|
||||
char junk;
|
||||
|
||||
if ((ret = mail_scan_any(stream, vp, "integer")) == 0) {
|
||||
if (sscanf(vstring_str(vp), "%d%c", lp, &junk) != 1) {
|
||||
msg_warn("mail_scan_int: bad integer: %s", vstring_str(vp));
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* mail_scan - read null-delimited data from stream */
|
||||
|
||||
int mail_scan(VSTREAM *stream, const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
int count;
|
||||
|
||||
va_start(ap, fmt);
|
||||
count = mail_vscan(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* mail_vscan - read null-delimited data from stream */
|
||||
|
||||
int mail_vscan(VSTREAM *stream, const char *fmt, va_list ap)
|
||||
{
|
||||
const char *cp;
|
||||
int lflag;
|
||||
int count;
|
||||
int error;
|
||||
static VSTRING *tmp;
|
||||
MAIL_SCAN *tp;
|
||||
|
||||
if (tmp == 0)
|
||||
tmp = vstring_alloc(100);
|
||||
|
||||
for (count = 0, error = 0, cp = fmt; error == 0 && *cp != 0; cp++) {
|
||||
if (ISSPACE(*cp))
|
||||
continue;
|
||||
if (*cp != '%')
|
||||
msg_fatal("mail_scan: bad format: %.*s>%c<%s",
|
||||
(int) (cp - fmt), fmt, *cp, cp + 1);
|
||||
if ((lflag = (*++cp == 'l')) != 0)
|
||||
cp++;
|
||||
|
||||
switch (*cp) {
|
||||
case 's':
|
||||
error = mail_scan_any(stream, va_arg(ap, VSTRING *), "string");
|
||||
break;
|
||||
case 'd':
|
||||
if (lflag)
|
||||
error = mail_scan_long(stream, tmp, va_arg(ap, long *));
|
||||
else
|
||||
error = mail_scan_int(stream, tmp, va_arg(ap, int *));
|
||||
break;
|
||||
default:
|
||||
for (tp = mail_scan_tab; tp < mail_scan_tab + mail_scan_tablen; tp++)
|
||||
if (tp->letter == *cp) {
|
||||
if (msg_verbose)
|
||||
msg_info("mail_scan: %s", tp->name);
|
||||
error = mail_scan_other(stream, tmp, tp, va_arg(ap, char *));
|
||||
break;
|
||||
}
|
||||
if (tp >= mail_scan_tab + mail_scan_tablen)
|
||||
msg_fatal("mail_scan: bad format: %.*s>%c<%s",
|
||||
(int) (cp - fmt), fmt, *cp, cp + 1);
|
||||
}
|
||||
if (error == 0)
|
||||
count++;
|
||||
}
|
||||
return (count);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*++
|
||||
/* NAME
|
||||
/* attr 3
|
||||
/* SUMMARY
|
||||
/* attribute list manager
|
||||
/* SYNOPSIS
|
||||
/* #include <htable.h>
|
||||
/* #include <attr.h>
|
||||
/*
|
||||
/* void attr_enter(attr, name, value)
|
||||
/* HTABLE *attr;
|
||||
/* const char *name;
|
||||
/* const char *value;
|
||||
/*
|
||||
/* const char *attr_find(attr, name)
|
||||
/* HTABLE *attr;
|
||||
/* const char *name;
|
||||
/*
|
||||
/* void attr_free(attr)
|
||||
/* HTABLE *attr;
|
||||
/* DESCRIPTION
|
||||
/* This module maintains open attribute lists of string-valued
|
||||
/* names and values. The module is built on top of the generic
|
||||
/* htable(3) hash table manager.
|
||||
/*
|
||||
/* attr_enter() adds a new attribute or updates an existing one.
|
||||
/* Both the name and the value are copied.
|
||||
/*
|
||||
/* attr_find() looks up the named attribute. It returns the
|
||||
/* corresponding value if one is found, a null pointer otherwise.
|
||||
/*
|
||||
/* attr_free() destroys the named attribute list and makes its
|
||||
/* memory available for reuse.
|
||||
/* BUGS
|
||||
/* This module cannot store null pointer values. If that is a
|
||||
/* problem, use the raw hash table management routines instead.
|
||||
/* 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 "mymalloc.h"
|
||||
#include "htable.h"
|
||||
#include "attr.h"
|
||||
|
||||
/* attr_enter - add or replace attribute */
|
||||
|
||||
void attr_enter(HTABLE *attr, const char *name, const char *value)
|
||||
{
|
||||
HTABLE_INFO *ht;
|
||||
|
||||
if ((ht = htable_locate(attr, name)) != 0) {/* replace attribute */
|
||||
myfree(ht->value);
|
||||
ht->value = mystrdup(value);
|
||||
} else { /* add attribute */
|
||||
(void) htable_enter(attr, name, mystrdup(value));
|
||||
}
|
||||
}
|
||||
|
||||
/* attr_free - destroy attribute list */
|
||||
|
||||
void attr_free(HTABLE *attr)
|
||||
{
|
||||
htable_free(attr, myfree);
|
||||
}
|
||||
|
Loading…
Reference in New Issue