2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-31 06:05:37 +00:00

postfix-beta-19990122

This commit is contained in:
Wietse Venema
1999-01-22 00:00:00 -05:00
parent 5cade00958
commit 01563531ac
660 changed files with 86997 additions and 0 deletions

89
postfix/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

148
postfix/0README Normal file
View File

@@ -0,0 +1,148 @@
Purpose of this document
========================
This document provides a road map of the Postfix mail system source
code distribution. I suggest that you take a few minutes to read
it, and then proceed with the installation instructions.
Introduction
============
This is the first public release of the Postfix mail system. Thank
you for your interest in this project. Send me a postcard if you
like it. My postal address is below.
You must read the LICENSE file, if you didn't do so already. A copy
of the LICENSE must be distributed with every original, modified,
complete, source, or binary copy of this software or parts thereof.
I suggest that you keep a copy of the file in /etc/postfix/LICENSE.
Purpose of the Postfix mail system
==================================
Postfix aims to be an alternative to the widely-used sendmail
program. Sendmail is responsible for 70% of all e-mail delivered
on the Internet. With an estimated 100 million users, that's an
estimated 10 billion (10^10) messages daily. A stunning number.
Although IBM supported the Postfix development, it abstains from
control over its evolution. The goal is to have Postfix installed
on as many systems as possible. To this end, the software is given
away with no strings attached to it, so that it can evolve with
input from and under control by its users.
In other words, IBM releases Postfix only once. I will be around
to guide its development for a limited time.
On-line resources devoted to the Postfix mail system
====================================================
Web sites:
http://www.ibm.com/alphaworks/ the original distribution site
http://www.postfix.org/ post-release information
Mail addresses (please do NOT send mail to my address at work):
postfix-XXX@postfix.org Postfix mailing lists
wietse@porcupine.org the original author
In order to subscribe to a mailing list, see http://www.postfix.org/.
Acknowledgements
================
This release could not have happened without the input from a team
of competent alpha testers. Their names appear in numerous places
in the HISTORY file. I appreciate the input from my colleagues at
the IBM Global Security Analysis Laboratory: Paul Karger, Dave
Safford, Douglas Schales, and Leendert van Doorn. I also appreciate
the support by Charles Palmer under whose leadership I began this
project, and who had the privilege to name the software, twice.
If you wish to express your appreciation for the Postfix software,
you are welcome to send a postcard to:
Wietse Venema
IBM T.J Watson Research Center
P.O. Box 704,
Yorktown Heights, NY 10598
USA
Roadmap of the Postfix source distribution
==========================================
Point your browser at html/index.html for Postfix documentation,
for manual pages, and for the unavoidable Postfix FAQ. Expect to
see updated versions on-line at http://www.postfix.org/
Point your MANPATH environment variable at the `man' directory (use
an absolute path) for UNIX-style on-line manual pages. These pages
are also available through the HTML interface, which allows you to
navigate faster.
The COMPATIBILITY file lists features that Postfix does or does
not yet implement, and how well it works with other software.
The HISTORY file gives a detailed log of changes to the software.
The INSTALL file provides a step-by-step guide for building and
installing Postfix on many popular UNIX platforms.
The PORTING file discusses how to go about porting Postfix to other
UNIX platforms. Some people are looking into a port to Windows NT.
We'll see. This software uses every trick in the book that I learned
about UNIX.
The TODO file lists things that still need to be done. If you want
to set your teeth into one of those problems, drop me a note at
wietse@porcupine.org to avoid duplication of effort.
Documentation:
html/ HTML format
man/ UNIX on-line manual page format
Library routines:
dns/ DNS client library
global/ Postfix-specific support routines
util/ General-purpose support routines
Command-line utilities:
postalias/ Alias database management
postcat/ List Postfix queue file
postconf/ Configuration utility
postfix/ Postfix administrative interface
postkick/ Postfix IPC for shell scripts
postlock/ Postfix locking for shell scripts
postlog/ Postfix logging for shell scripts
postmap/ Postfix lookup table management
sendmail/ Sendmail compatibility interface
Postfix daemons:
bounce/ Bounce or defer mail
cleanup/ Canonicalize and enqueue mail
local/ Local delivery
master/ Postfix resident superserver
pickup/ Local pickup
pipe/ Pipe delivery
qmgr/ Queue manager
showq/ List Postfix queue status
smtp/ SMTP client
smtpd/ SMTP server
trivial-rewrite/ Address rewriting and resolving
Test programs:
fsstone/ Measure file system overhead
smtpstone/ SMTP server torture test
Miscellaneous:
bin/ Installed programs
conf/ Sample configuration files
include/ Installed include files
lib/ Installed object libraries

55
postfix/COMPATIBILITY Normal file
View File

@@ -0,0 +1,55 @@
.forward yes (empty files; can enable/disable mail to /file or |command)
/usr/mail yes (compile time option)
/usr/spool/mail yes (compile time option)
/var/mail yes (compile time option)
/var/spool/mail yes (compile time option)
:include: yes (mail to /file and |command is off by default)
aliases yes (can enable/disable mail to /file or |command)
bare newlines yes (but will send CRLF)
blacklisting yes (client name/addr; helo hostname; mail from; rcpt to)
content filter no
db tables yes (compile time option)
dbm tables yes (compile time option)
delivered-to yes
dsn not yet
errors-to: yes
esmtp yes
etrn support yes (flushes entire queue)
fcntl locking yes (compile time)
flock locking yes (compile time)
home mailbox yes
ident lookup no
ldap tables yes (contributed)
luser relay not yet
m4 config no
mail to command yes (configurable for .forward, aliases, :include:)
mail to file yes (configurable for .forward, aliases, :include:)
maildir yes (with procmail)
mailertable yes (it's called transport)
mailq yes
majordomo yes (edit approve script to delete /delivered-to/i)
mime conversion not yet; postfix uses just-send-eight
missing <> yes (most common address forms)
netinfo tables yes (contributed)
newaliases yes (main alias database only)
nis tables yes
nis+ tables not yet
pipeline option yes (server and client)
pop/imap yes (with third-party daemons that use /var[/spool]/mail)
rbl support yes
return-receipt: not yet
sendmail -q yes
sendmail -qRxxx no
sendmail -qSxxx no
sendmail -qtime ignored
sendmail -v no
sendmail.cf no (uses table-driven address rewriting)
size option yes, server and client
smarthost yes
tcp wrapper no (use built-in blacklist facility)
user+extension yes (also: .forward+extension)
user-extension yes (also: .forward-extension)
user.lock yes (compile time)
uucp support yes (sends user@domain recipients)
virtual domains yes
year 2000 safe yes

2001
postfix/HISTORY Normal file

File diff suppressed because it is too large Load Diff

504
postfix/INSTALL Normal file
View File

@@ -0,0 +1,504 @@
Purpose of this document
========================
This document describes how to build, install and configure a
Postfix system so that it can do one of the following:
- Send mail only, without changing an existing sendmail
installation.
- Send and receive mail via a virtual host interface, still
without any change to an existing sendmail installation.
- Replace sendmail altogether.
Typographical conventions
=========================
In the instructions below, a command written as
# command
should be executed as the superuser.
A command written as
% command
should be executed as an unprivileged user.
Documentation
=============
Documentation is available as HTML web pages (point your browser
to html/index.html) and as UNIX-style manpages (point your MANPATH
environment variable to the `man' subdirectory; be sure to use an
absolute path).
The sample configuration files in the `conf' directory have extensive
comments, but they may not describe every nuance of every feature.
Many files have their own built-in manual page. Tools to extract
those embedded manual pages are available in the contributed software
from http://www.postfix.org/
Building on a supported system
==============================
If your system is supported, it is one of
AIX 4.1.x
AIX 4.2.0
BSD/OS 2.x
BSD/OS 3.x
BSD/OS 4.x
FreeBSD 2.x
FreeBSD 3.x
HP-UX 9.x
HP-UX 10.x
HP-UX 11.x
IRIX 5.x
IRIX 6.x
Linux Debian 1.3.1
Linux Debian 2.x
Linux RedHat 4.2
Linux RedHat 5.x
Linux Slackware 3.5
Linux SuSE 5.x
NEXTSTEP 3.x
NetBSD 1.x
OPENSTEP 4.x
OSF1.V4 aka Digital UNIX V4
OpenBSD 2.x
SunOS 4.1.x
SunOS 5.4..5.7 (Solaris 2.4..7)
or something closely resemblant. Some platforms such as Ultrix 4
might work, but that has not been verified. It is sufficiently
similar to SunOS 4 that my guesses should be mostly right.
Download the contributed software from http://www.postfix.org/ if
you wish to include support for LDAP (light-weight directory access
protocol) lookups, for NEXTSTEP version 3 or for OPENSTEP version 4.
If at any time in the build process you get messages like: "make:
don't know how to ..." you should be able to recover by running
the following command from the Postfix top-level directory:
% make -f Makefile.init makefiles
If you copied the Postfix source code after building it on another
machine, it is a good idea to cd into the top-level directory and
% make tidy
first. This will get rid of any system dependencies left over from
compiling the software elsewhere.
To build with GCC, or with the native compiler if people told me
that is better for your system, just cd into the top-level Postfix
directory of the source tree and type:
% make
To build with a non-default compiler, you need to specify the name
of the compiler:
% make makefiles CC=/opt/SUNWspro/bin/cc
% make
% make makefiles CC="purify cc"
% make
and so on. On some cases, optimization is turned off automatically.
In order to build with non-default settings, for example, with a
configuration directory other than /etc/postfix, use:
% make makefiles CCARGS=-DDEF_CONFIG_DIR=\\\\\\\"/some/where\\\\\\\"
% make
That's seven backslashes :-) But at least this works with sh and csh.
In any case, if the command
% make
produces compiler error messages, it may be time to examine the
FAQ document.
Porting to on an unsupported system
===================================
- Choose a SYSTEMTYPE name for the new system. Please use a name
that includes the major version of the operating system (such as
SUNOS4 or LINUX2), so that different releases of the same system
can be supported without confusion.
- Add a case statement to the "makedefs" shell script in the
top-level directory that recognizes the new system reliably, and
that emits the right system-specific information. Be sure to make
the code robust against user PATH settings; if the system offers
multiple UNIX flavors (e.g. BSD and SYSV) be sure to build for the
native flavor, not the emulated one.
- Add an #ifdef SYSTEMTYPE section to the central util/sys_defs.h
include file. You may have to invent new feature macros. Please
choose sensible feature macro names such as HAS_DBM or
FIONREAD_IN_SYS_FILIO_H. I strongly recommend against #ifdef
SYSTEMTYPE dependencies in individual source files. This may seem
to be the quickest solution, but it will create a mess that becomes
increasingly difficult to maintain over time. Moreover, with the
next port you'd have to place #ifdefs all over the source code
again.
Installing the software after successful compilation
====================================================
There is no automated installation procedure. The Postfix system
is sufficiently complex, and UNIX systems are sufficiently different,
that I feel uncomfortable providing an out-of-the-box procedure.
Installing Postfix by hand takes only a few steps.
- Configuration directory. This name is wired into the programs,
but it can be overruled by setting the MAIL_CONFIG environment
variable. This text assumes that you have chosen the default
location.
As superuser, execute the commands:
# mkdir /etc/postfix
# chmod 755 /etc/postfix
# cp /some/where/postfix/conf/* /etc/postfix
# chmod 644 /etc/postfix/*
# chmod 755 /etc/postfix/postfix-script
This also installs the LICENSE file, as required.
- Spool directory. The pathname is configurable in /etc/postfix/main.cf.
This text assumes that you have chosen the default location.
As superuser, execute the commands:
# mkdir /var/spool/postfix
# chmod 755 /var/spool/postfix
- Program directory. The pathname is configurable in /etc/postfix/main.cf.
I recommend that you install the programs in a separate directory,
not in a place that contains other software.
As superuser, execute the commands:
# mkdir /some/where/bin
# cp bin/* /some/where/bin
Alternative 1: leave the programs in the Postfix source tree.
Alternative 2: use separate program and daemon directories (again,
configurable in /etc/postfix/main.cf):
# mkdir /some/where/sbin /some/where/libexec
# cp bin/sendmail bin/post* /some/where/sbin
# cp `ls bin/*|egrep -v 'post|fsstone|smtp-|sendmail'` /some/where/libexec
- On-line manual pages:
# mkdir /some/where/man
# (cd man; tar cf - .) | (cd /some/where/man; tar xvf -)
Alternative: leave the manpages in the Postfix source tree.
You may wish to update your MANPATH so you can view the Postfix
manual pages. For example:
# export MANPATH
# MANPATH=/some/where/man:/usr/share/man:/usr/local/man
- Next, review the "To chroot or not to chroot" section, and proceed
to the section on how you wish to run Postfix on your particular
machine:
- Send mail only, without changing an existing sendmail
installation.
- Send and receive mail via a virtual host interface, still
without any change to an existing sendmail installation.
- Replace sendmail altogether.
To chroot or not to chroot
==========================
Most Postfix daemons can run in a chroot jail, that is, in a chroot
environment at fixed low privilege. This provides a significant
barrier against intrusion. The barrier is not impenetrable, but
every little bit helps.
The file /etc/postfix/master.cf by default runs no Postfix daemons
in a chroot jail. However, with the exception of the `local' and
`pipe' daemons, every Postfix daemon can run chrooted.
- The contributed source code from http://www.postfix.org/ has
scripts for setting up chroot environments for Postfix systems.
Configuring Postfix to send mail only
=====================================
If you are going to use Postfix to send mail only, there is no need
to change your sendmail setup. Instead, set up your mail user agent
so that it calls the Postfix sendmail program directly.
Follow the instructions in the "Mandatory configuration file edits"
section below.
You must comment out the smtp inet service in /etc/postfix/master.cf,
in order to avoid conflicts with the sendmail daemon.
Start the Postfix system:
# postfix start
or, if you feel nostalgic,
# /some/where/bin/sendmail -bd -qwhatever
and watch your syslog file for any error messages.
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
In order to inspect the mail queue, use
% /some/where/bin/sendmail -bp
See also the "Care and feeding" section below.
Configuring Postfix to send and receive mail (virtual interface)
================================================================
Alternatively, you can use the Postfix system to send AND receive
mail while leaving your sendmail setup intact, by running Postfix
on a virtual interface address. Simply configure your mail user
agent to directly invoke the Postfix sendmail program.
The contributed source code from http://www.postfix.org/ gives
examples for setting up virtual interfaces for a variety of UNIX
versions.
In the /etc/postfix/main.cf file, I would specify
myhostname = virtual.host.name
inet_interfaces = $myhostname
mydestination = $myhostname
You still have to do the "Mandatory configuration file edits"
described below. After those edits, start the mail system:
# /some/where/bin/postfix start
or, if you feel nostalgic,
# /some/where/bin/sendmail -bd -qwhatever
and watch your syslog file for any error messages.
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
In order to inspect the mail queue, use
% /some/where/bin/sendmail -bp
See also the "Care and feeding" section below.
Turning off sendmail forever
============================
If you are going to REPLACE sendmail by Postfix, execute the
following commands. The text assumes that your sendmail is in
/usr/sbin, and that mailq and newaliases are in /usr/bin.
First, move the existing sendmail, mailq and newaliases commands
out of the way:
# mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF
# mv /usr/bin/mailq /usr/bin/mailq.OFF
# mv /usr/bin/newaliases /usr/bin/newaliases.OFF
# chmod 555 /usr/sbin/sendmail.OFF /usr/bin/mailq.OFF \
/usr/bin/newaliases.OFF
Then, drop in the new Postfix sendmail and support programs, and
set up links for the mailq and newaliases commands:
# ln -s /some/where/bin/sendmail /some/where/bin/post* /usr/sbin
# chmod 755 /usr/sbin/sendmail /usr/sbin/post*
# ln -s /usr/sbin/sendmail /usr/bin/mailq
# ln -s /usr/sbin/sendmail /usr/bin/newaliases
Be sure to keep the old sendmail running for at least a couple
days to flush any unsent mail.
After you have visited the "Mandatory configuration file edits"
section below, you can start the Postfix system with
# postfix start
But the good old sendmail way works just as well:
# sendmail -bd -qwhatever
and watch the syslog file for any complaints from the mail system.
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
See also the "Care and feeding" section below.
Mandatory configuration file edits
==================================
By default, all Postfix configuration files are in /etc/postfix, and
must be owned by root.
Whenever you make a change to a config file, execute the following
command in order to refresh a running mail system:
# postfix reload
In /etc/postfix/main.cf you will have to set up a minimal number of
configuration parameters. Postfix configuration parameters
resemble shell variables. You specify a variable as
parameter = value
and you use it by putting a $ in front of it:
other_parameter = $parameter
You can use $parameter before it is given a value. The Postfix
configuration language uses lazy evaluation, and does not look at
a parameter value until it is needed at runtime.
First of all you have to specify the userid that owns the Postfix
queue and processes. The default setting,
mail_owner = postfix
should be appropriate for your system. I would recommend that you
create a dedicated user account "postfix", that is not in the same
group as other accounts. Make sure it is a locked account that
no-one can log into. It does not need an executable login shell,
nor does it need an existing home directory.
Secondly, you should specify what domain name will be appended to
a local address. The "myorigin" parameter defaults to the local
hostname, but that is probably OK only for very small sites.
Some examples:
myorigin = $myhostname
myorigin = $mydomain
In the first case, local mail goes out as user@$myhostname, in
the second case the sender address is user@$mydomain.
Next you nee to specify what mail addresses are local to the Postfix
system.
Some examples:
mydestination = $myhostname, localhost.$mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
mydestination = $myhostname
The first example is appropriate for a workstation, the second is
appropriate for the mailserver for an entire domain. The third
example should be used when running on a virtual host interface.
If you're behind a firewall, you should set up a relayhost. If
you can, specify the organizational domain name so that Postfix
can use DNS lookups, and so that it can fall back to a secondary
MX host when the primary MX host is down. Otherwise just specify
a hard-coded hostname.
Some examples:
relayhost = $mydomain
relayhost = mail.$mydomain
If you haven't used sendmail prior to using Postfix, you will have
to build the alias database (with: sendmail -bi, or: newaliases).
Finally, specify the program and queue directories.
program_directory = /some/where/bin
queue_directory = /var/spool/postfix
For further configuration information I suggest that you browse
the configuration documentation in the html subdirectory.
Security: writable versus protected maildrop directory
======================================================
Postfix offers a choice of submission mechanims.
1 - Postfix can use a world-writable, sticky, mode 1733 maildrop
directory where local users can submit mail. This approach
avoids the need for set-uid or set-gid software. Mail can be
posted even while the mail system is down. Queue files in the
maildrop directory have no read/write/execute permission for
other users. The maildrop directory is not used for mail
received via the network.
With directory world write permission come opportunities for
annoyance: a local user can make hard links to someone else's
maildrop files so they don't go away and may be delivered
multiple times; a local user can fill the maildrop directory
with junk and try to crash the mail system; and a local user
can hard link someone else's files into the maildrop directory
and try to have them delivered as mail. However, Postfix queue
files have a specific format; less than one in 10^12 non-Postfix
files would be recognized as a valid Postfix queue file.
In order to enable this mode, step into /etc/postfix and:
# cp postfix-script-nosgid postfix-script
2 - On systems with many users it may be desirable to revoke maildrop
directory world write permission, and to enable set-gid privileges
on a small "postdrop" command that is provided for this purpose.
In order to revoke world-write permission, create a group
"maildrop" that is unique and that does not share its group ID
with any other user, certainly not with the postfix account,
then execute the following commands to make "postdrop" set-gid,
and to make maildrop non-writable for unprivileged users:
# chgrp maildrop /var/spool/postfix/maildrop /some/where/postdrop
# chmod 730 /var/spool/postfix/maildrop
# chmod 2755 /some/where/postdrop
The sendmail posting program will automatically invoke the
postdrop command when maildrop directory write permission is
restricted.
In order to enable this mode, step into /etc/postfix and:
# cp postfix-script-sgid postfix-script
Care and feeding of the Postfix system
======================================
The Postfix programs log all problems to the syslog daemon.
Hopefully, the number of problems will be small, but it is a good
idea to run every night before the syslog files are rotated:
# postfix check
# egrep '(reject|warning|error|fatal|panic):' /some/log/file
The second line looks for problem reports from the mail software,
and reports how effective the anti-relay and anti-UCE blocks are.

59
postfix/LICENSE Normal file
View File

@@ -0,0 +1,59 @@
Please read this carefully. You must agree to the following terms and
conditions before installing the Secure Mailer or any related
documentation ("Software"). If you do not agree to these terms
and conditions, you may not install or use the Software.
Permission to reproduce and create derivative works from the Software
("Software Derivative Works") is hereby granted to you under the
copyrights of International Business Machines Corporation ("IBM"). IBM
also grants you the right to distribute the Software and Software
Derivative Works.
You grant IBM a world-wide, royalty-free right to use, copy,
distribute, sublicense and prepare derivative works based upon any
feedback, including materials, error corrections, Software Derivatives,
enhancements, suggestions and the like that you provide to IBM relating
to the Software.
IBM licenses the Software to you on an "AS IS" basis, without warranty
of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES OR
CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, NON
INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. You are solely
responsible for determining the appropriateness of using this Software
and assume all risks associated with the use and distribution of this
Software, including but not limited to the risks of program errors,
damage to or loss of data, programs or equipment, and unavailability or
interruption of operations. IBM WILL NOT BE LIABLE FOR ANY DIRECT
DAMAGES OR FOR ANY SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY
ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS),
EVEN IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IBM
will not be liable for the loss of, or damage to, your records or data,
or any damages claimed by you based on a third party claim. You may
not use the name "IBM" or any other IBM trademark without the prior
written consent of IBM.
You agree to distribute the Software and any Software Derivatives under
a license agreement that: 1) is sufficient to notify all licensees of
the Software and Software Derivatives that IBM assumes no liability for
any claim that may arise regarding the Software or Software
Derivatives, and 2) that disclaims all warranties, both express and
implied, from IBM regarding the Software and Software Derivatives. (If
you include this Agreement with any distribution of the Software or
Software Derivatives you will have met this requirement.) You agree
that you will not delete any copyright notices in the Software.
In the event an intellectual property claim is made or appears likely
to be made with respect to the Software, you agree to permit IBM to
enable you to continue to use the Software, or to modify it, or replace
it with software that is at least functionally equivalent. If IBM
determines that none of these alternatives is reasonably available, you
agree, at IBM's request, upon notice to you, to discontinue further
distribution of the Software and to delete or destroy all copies of the
Software you possess. This is IBM's entire obligation to you regarding
any claim of infringement.
This Agreement is the exclusive statement of your rights in the
Software as provided by IBM. Except for the licenses granted to you in
the second paragraph above, no other licenses are granted hereunder, by
estoppel, implication or otherwise.

18
postfix/Makefile Normal file
View File

@@ -0,0 +1,18 @@
# Usage:
# make makefiles [CC=compiler] [OPT=compiler-flags] [DEBUG=debug-flags]
#
# The defaults are: CC=gcc, OPT=-O, and DEBUG=-g. Examples:
#
# make makefiles
# make makefiles CC="purify cc"
# make makefiles CC=cc OPT=
#
SHELL = /bin/sh
default: update
update depend printfck clean tidy depend_update: Makefiles
$(MAKE) $@
makefiles Makefiles:
$(MAKE) -f Makefile.in Makefiles

42
postfix/Makefile.in Normal file
View File

@@ -0,0 +1,42 @@
SHELL = /bin/sh
WARN = -Wmissing-prototypes
OPTS = "CC=$(CC)"
DIRS = util global dns master postfix smtpstone fsstone sendmail \
pickup cleanup smtpd local trivial-rewrite qmgr smtp bounce pipe \
showq postalias postcat postconf postdrop postkick postlock postlog \
postmap # man html
default: update
makefiles Makefiles:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; rm -f Makefile; \
$(MAKE) -f Makefile.in Makefile); \
done;
rm -f Makefile; (set -e; sh makedefs; cat Makefile.in) >Makefile
update printfck:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $(OPTS) $@) || exit 1; \
done
depend clean:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $@) || exit 1; \
done
depend_update:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) depend && $(MAKE) $(OPTS) update) \
|| exit 1; \
done
tidy: clean
rm -f Makefile */Makefile
cp Makefile.init Makefile
-rm -f *core */*core .nfs* .pure bin/* lib/* include/* */.nfs* */.pure \
*.out */*.out */*.db */*.a *~ */*~ *- */*- *.orig */*.orig *.bak \
*/*.bak make.err
find . -type s -print | xargs rm -f
find . -type d -print | xargs chmod 755
find . -type f -print | xargs chmod a+r

18
postfix/Makefile.init Normal file
View File

@@ -0,0 +1,18 @@
# Usage:
# make makefiles [CC=compiler] [OPT=compiler-flags] [DEBUG=debug-flags]
#
# The defaults are: CC=gcc, OPT=-O, and DEBUG=-g. Examples:
#
# make makefiles
# make makefiles CC="purify cc"
# make makefiles CC=cc OPT=
#
SHELL = /bin/sh
default: update
update depend printfck clean tidy depend_update: Makefiles
$(MAKE) $@
makefiles Makefiles:
$(MAKE) -f Makefile.in Makefiles

23
postfix/PORTING Normal file
View File

@@ -0,0 +1,23 @@
In order to port software to a new platform:
- Choose a SYSTEMTYPE name for the new system. Please use a name
that includes the major version of the operating system (such as
SUNOS4 or LINUX2), so that different releases of the same system
can be supported without confusion.
- Add a case statement to the "makedefs" shell script in the
top-level directory that recognizes the new system reliably, and
that emits the right system-specific information. Be sure to make
the code robust against user PATH settings; if the system offers
multiple UNIX flavors (e.g. BSD and SYSV) be sure to build for the
native flavor, not the emulated one.
- Add an #ifdef SYSTEMTYPE section to the central util/sys_defs.h
include file. You may have to invent new feature macros. Please
choose sensible feature macro names such as HAS_DBM or
FIONREAD_IN_SYS_FILIO_H. I strongly recommend against #ifdef
SYSTEMTYPE dependencies in individual source files. This may seem
to be the quickest solution, but it will create a mess that becomes
increasingly difficult to maintain over time. Moreover, with the
next port you'd have to place #ifdefs all over the source code
again.

62
postfix/RELEASE_NOTES Normal file
View File

@@ -0,0 +1,62 @@
This release introduces lots of new functionality in response to feedback
from users.
Incompatible changes:
=====================
- The syntax of the transport table has changed. An entry like:
customer.org smtp:[gateway.customer.org]
no longer forwards mail for anything.customer.org. For that you
need to specify:
customer.org smtp:[gateway.customer.org]
.customer.org smtp:[gateway.customer.org]
This change makes tranport tables more compatible with
sendmail mailer tables.
- The format of syslog records has changed. A client is now always
logged as hostname[address]; the pickup daemon logs queue file uid
and sender address.
Major changes over the previous version:
========================================
- Junk mail restrictions can now be postoned to the RCPT TO command.
Specify: "smtpd_recipient_restrictions = reject_maps_rbl...".
- More flexible interface for delivery to e.g., cyrus IMAP without
need for PERL scripts to munge recipient addresses. In addition to
$sender, $nexthop and $recipient, the pipe mailer now also supports
$user, $extension and $mailbox.
- New mail now has precedence over deferred mail, plus some other
tweaks to make bulk mail go faster. But it ain't no cure for massive
network outages.
- Watchdog timer for systems that cause the Postfix queue manager
to lock up, so it recovers without human intervention.
- Delivery to qmail-style maildir files, which is good for NFS
environments. Specify "home_mailbox = Maildir/", or specify
/file/name/ in aliases or in .forward files. The trailing / is
required to turn on maildir delivery.
- Incremental updates of aliases and maps. Specify "postmap -i
mapname" and it will read new entries from stdin.
- Newaliases will now update more than one alias database.
Specify the names with the main.cf "alias_database" parameter.
- Address masquerading exceptions to prevent users from being
masqueraded. Specify "masquerade_exceptions = root".
- A pipelined SMTP client. Deliveries to Postfix, qmail, LSOFT,
zmailer, and exim (once it's fixed) speed up by some 30% for short
messages with one recipient, with more for multi-recipient mails.
- Hook for local delivery to "|command" via the smrsh restricted
shell, to restrict what commands may be used in .forward etc. files.
Specify "local_command_shell = /some/where/smrsh -c".

274
postfix/TODO Normal file
View File

@@ -0,0 +1,274 @@
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
more general relocated feature - perhaps better to bounce recipients
at the SMTP port.
use $mydomain when hostname is not FQDN.
generic daemon that listens on fifo and runs command
make sendmail/smtpd/cleanup output directory/fifo configurable
if postdrop scrutinizes input, skip the overhead in the pickup
daemon.
luser relay
add a threshold to sendmail etc. stderr logging, so that class
"info" messages don't go to stderr.
need a configurable mailbox locking method with system-specific
default, so people don't have to recompile just to turn of fcntl()
locks to work around SUN mailtool.
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.
with recipient delimiter enabled, append the unmatched recipient
of @virtual.domain patterns as extension to right-hand recipient,
for qmail-like virtual mapping.
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.
trivial-rewrite etc.: after reload, close the listen socket and
wait until all clients disconnect.
In qmgr_entry.c, turn off random walk by default.
toss double-bounce mail even when mail for the local machine is
redirected to another box. See mail_addr_double_bounce().
represent peer as object, not as name + addr arguments
ignore sender: header when different from envelope?
smtp client: optionally log every MX host contacted
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?
log relay address in addition to host.
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?
when client begins with non-SMTP data, log warning
when non-SMTP follows ".", log warning.
On linux syslogd needs -/file/name
can Postfix implement one switchboard instead of having all these
little lookup tables?
make canonical/virtual/etc. table lookup order configurable
allow /file/name or maptype_mapname in $mydestination
make protocol errors soft errore? There are a lot of broken mailers
out there that sometimes croak and sometimes work.
require @ in sender/rcpt (another restriction)
figure out a way to pump recipients into qmgr before concurrency
starts to drop.
pass on client etc/ attributes along with message to delivery agent
pass on configurable info into external process environment
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).
cleanup: don't run out of memory with large amounts of bcc addresses
cleanup: permit non-empty extra segment, so that mail posting
software can pass in bcc recipients.
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.
smtp: optionally deal with MX records containing an address instead
of a name.
pickup/cleanup/qmgr/local: add options record to control internal
features such as canonical/virtual mapping, VERPs etcetera.
smtpd: when deciding if a destination is local, also look at the
virtual map. Perhaps we should move canonical and virtual lookups
back into the rewrite service, but under a different name, so they
do not get in the way if we do not want them.
Queue manager: do not allocate queue slots when a destination
already has more than some threshold. This is to prevent a dead or
slow destination from filling up the queue manager's active queue,
preventing delivery to other destinations. However, such `fairness'
strategies should not cause Postfix to lose the benchmark race, so
we must be fair and smart at the same time :-)
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.
Make the number of time bits in the queue ID configurable, or at
least a little larger.
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.
SunOS 5.4 sendmail seems to include the null byte in alias keys
and values, like almost every UNIX system; SunOS 5.5 sendmail does
not include these nulls. Need to add support for SunOS 5.4. NIS
alias maps always include the null terminator...
implement the return-receipt-to notification service.
Implement real address rewriting.
default alias for mail to non-existent users. How useful is this
when the postmaster already gets notices of mail that could not be
delivered by the local mail system? And how do we pass around the
original envelope recipient once it has been "aliased" to the
address for non-existent users?
owner-default alias to capture all mailing list errors. Or perhaps
they should just set up the appropriate owner-foo aliases in their
alias database?
make mail_params module the main config interface; no calls from
config.c to routines in mail_params.c
resolve/rewrite clients should share connection
postfix-script: make sure permissions of queue (and anything below)
are sane.
bounce/defer: provide attribute-value interface, for better logging
(expanded-from etc.) and non-delivery reports.
Postfix-Options: header, to turn on qmail-like VERPs. But, these
must be accessible only for locally-posted mail (not mail that
arrives via UUCP).
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.
Option to make a copy of all mail passing through the mail system.
The message ID is built by concatenating the time of day in seconds
with the queue id. We must ensure that a queue id is unique for at
least one second, otherwise multiple messages will have the same
message ID. Queue ids will always collide after a while. The NFS
generation number for the queue file would be useful, but there is
no portable interface to get it, and we cannot depend on the system
having NFS support enabled. If a 1-microsecond resolution is
sufficient, we could compose the queue ID from the inode number
plus 6 decimal digits or 5 hex ones for the time in microseconds.
Or, use a smarter encoding with more bits per character.
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
Put a version file in the conf directory or add option to vmail
control command to print the version (requires vmconf tool that
can query main.cf.).
Maintain a pool of pre-allocated queue files, to eliminate file
creation and deletion overhead.

0
postfix/bin/.keep Normal file
View File

89
postfix/bounce/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/bounce/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

121
postfix/bounce/Makefile.in Normal file
View File

@@ -0,0 +1,121 @@
SHELL = /bin/sh
SRCS = bounce.c bounce_append_service.c bounce_flush_service.c \
bounce_cleanup.c
OBJS = bounce.o bounce_append_service.o bounce_flush_service.o \
bounce_cleanup.o
HDRS =
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
PROG = bounce
INC_DIR = ../include
LIBS = ../lib/libmaster.a ../lib/libglobal.a ../lib/libutil.a
.c.o:; $(CC) $(CFLAGS) -c $*.c
$(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
(set -e; echo "# DO NOT EDIT"; $(OPTS) sh ../makedefs; cat $?) >$@
test: $(TESTPROG)
update: ../bin/$(PROG)
../bin/$(PROG): $(PROG)
cp $(PROG) ../bin
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
cp *.h printfck
sed '1,/^# do not edit/!d' Makefile > printfck/Makefile
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
clean:
rm -f *.o *core $(PROG) $(TESTPROG) junk
rm -rf printfck
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
bounce.o: bounce.c
bounce.o: ../include/sys_defs.h
bounce.o: ../include/msg.h
bounce.o: ../include/vstring.h
bounce.o: ../include/vbuf.h
bounce.o: ../include/vstream.h
bounce.o: ../include/stringops.h
bounce.o: ../include/mail_proto.h
bounce.o: ../include/iostuff.h
bounce.o: ../include/mail_queue.h
bounce.o: ../include/mail_params.h
bounce.o: ../include/config.h
bounce.o: ../include/bounce.h
bounce.o: ../include/mail_server.h
bounce.o: bounce_service.h
bounce_append_service.o: bounce_append_service.c
bounce_append_service.o: ../include/sys_defs.h
bounce_append_service.o: ../include/msg.h
bounce_append_service.o: ../include/vstring.h
bounce_append_service.o: ../include/vbuf.h
bounce_append_service.o: ../include/vstream.h
bounce_append_service.o: ../include/stringops.h
bounce_append_service.o: ../include/mail_queue.h
bounce_append_service.o: ../include/quote_822_local.h
bounce_append_service.o: ../include/deliver_flock.h
bounce_append_service.o: bounce_service.h
bounce_cleanup.o: bounce_cleanup.c
bounce_cleanup.o: ../include/sys_defs.h
bounce_cleanup.o: ../include/msg.h
bounce_cleanup.o: ../include/mymalloc.h
bounce_cleanup.o: ../include/vstring.h
bounce_cleanup.o: ../include/vbuf.h
bounce_cleanup.o: ../include/mail_queue.h
bounce_cleanup.o: ../include/vstream.h
bounce_cleanup.o: bounce_service.h
bounce_flush_service.o: bounce_flush_service.c
bounce_flush_service.o: ../include/sys_defs.h
bounce_flush_service.o: ../include/msg.h
bounce_flush_service.o: ../include/vstring.h
bounce_flush_service.o: ../include/vbuf.h
bounce_flush_service.o: ../include/vstream.h
bounce_flush_service.o: ../include/vstring_vstream.h
bounce_flush_service.o: ../include/mymalloc.h
bounce_flush_service.o: ../include/stringops.h
bounce_flush_service.o: ../include/events.h
bounce_flush_service.o: ../include/line_wrap.h
bounce_flush_service.o: ../include/name_mask.h
bounce_flush_service.o: ../include/mail_queue.h
bounce_flush_service.o: ../include/mail_proto.h
bounce_flush_service.o: ../include/iostuff.h
bounce_flush_service.o: ../include/quote_822_local.h
bounce_flush_service.o: ../include/mail_params.h
bounce_flush_service.o: ../include/canon_addr.h
bounce_flush_service.o: ../include/is_header.h
bounce_flush_service.o: ../include/record.h
bounce_flush_service.o: ../include/rec_type.h
bounce_flush_service.o: ../include/config.h
bounce_flush_service.o: ../include/post_mail.h
bounce_flush_service.o: ../include/cleanup_user.h
bounce_flush_service.o: ../include/mail_addr.h
bounce_flush_service.o: ../include/mark_corrupt.h
bounce_flush_service.o: ../include/mail_error.h
bounce_flush_service.o: bounce_service.h

281
postfix/bounce/bounce.c Normal file
View File

@@ -0,0 +1,281 @@
/*++
/* NAME
/* bounce 8
/* SUMMARY
/* Postfix message bounce or defer daemon
/* SYNOPSIS
/* \fBbounce\fR [generic Postfix daemon options]
/* DESCRIPTION
/* The \fBbounce\fR daemon maintains per-message log files with
/* non-delivery status information. Each log file is named after the
/* queue file that it corresponds to, and is kept in a queue subdirectory
/* named after the service name in the \fBmaster.cf\fR file (either
/* \fBbounce\fR or \fBdefer\fR).
/* This program expects to be run from the \fBmaster\fR(8) process
/* manager.
/*
/* The \fBbounce\fR daemon processes two types of service requests:
/* .IP \(bu
/* Append a recipient status record to a per-message log file.
/* .IP \(bu
/* Post a bounce message, with a copy of a log file and of the
/* corresponding message. When the bounce is posted successfully,
/* the log file is deleted.
/* .PP
/* The software does a best effort to notify the sender that there
/* was a problem. A notification is sent even when the log file
/* or original message cannot be read.
/*
/* Optionally, a client can request that the per-message log file be
/* deleted when the requested operation fails.
/* This is used by clients that cannot retry transactions by
/* themselves, and that depend on retry logic in their own client.
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS
/* The log files use an ad-hoc, unstructured format. This will have
/* to change in order to easily support standard delivery status
/* notifications.
/* CONFIGURATION PARAMETERS
/* .ad
/* .fi
/* The following \fBmain.cf\fR parameters are especially relevant to
/* this program. See the Postfix \fBmain.cf\fR file for syntax details
/* and for default values. Use the \fBpostfix reload\fR command after
/* a configuration change.
/* .IP \fBbounce_size_limit\fR
/* Limit the amount of original message context that is sent in
/* a non-delivery notification.
/* .IP \fBmail_name\fR
/* Use this mail system name in the introductory text at the
/* start of a bounce message.
/* .IP \fBnotify_classes\fR
/* Notify the postmaster of bounced mail when this parameter
/* includes the \fBbounce\fR class. For privacy reasons, the message
/* body is not included.
/* SEE ALSO
/* master(8) process manager
/* qmgr(8) queue manager
/* syslogd(8) system logging
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <stringops.h>
/* Global library. */
#include <mail_proto.h>
#include <mail_queue.h>
#include <mail_params.h>
#include <config.h>
#include <bounce.h>
/* Single-threaded server skeleton. */
#include <mail_server.h>
/* Application-specific. */
#include "bounce_service.h"
/*
* Tunables.
*/
int var_bounce_limit;
char *var_notify_classes;
/*
* We're single threaded, so we can avoid some memory allocation overhead.
*/
static VSTRING *queue_id;
static VSTRING *queue_name;
static VSTRING *recipient;
static VSTRING *sender;
static VSTRING *why;
#define STR vstring_str
/* bounce_append_proto - bounce_append server protocol */
static int bounce_append_proto(char *service_name, VSTREAM *client)
{
int flags;
/*
* Read the and validate the client request.
*/
if (mail_command_read(client, "%d %s %s %s",
&flags, queue_id, recipient, why) != 4) {
msg_warn("malformed request");
return (-1);
}
if (mail_queue_id_ok(STR(queue_id)) == 0) {
msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
return (-1);
}
if (msg_verbose)
msg_info("bounce_append_proto: service=%s id=%s to=%s why=%s",
service_name, STR(queue_id), STR(recipient), STR(why));
/*
* On request by the client, set up a trap to delete the log file in case
* of errors.
*/
if (flags & BOUNCE_FLAG_CLEAN)
bounce_cleanup_register(service_name, STR(queue_id));
/*
* Execute the request.
*/
return (bounce_append_service(service_name, STR(queue_id),
STR(recipient), STR(why)));
}
/* bounce_flush_proto - bounce_flush server protocol */
static int bounce_flush_proto(char *service_name, VSTREAM *client)
{
int flags;
/*
* Read and validate the client request.
*/
if (mail_command_read(client, "%d %s %s %s",
&flags, queue_name, queue_id, sender) != 4) {
msg_warn("malformed request");
return (-1);
}
if (mail_queue_name_ok(STR(queue_name)) == 0) {
msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
return (-1);
}
if (mail_queue_id_ok(STR(queue_id)) == 0) {
msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
return (-1);
}
if (msg_verbose)
msg_info("bounce_flush_proto: service=%s queue=%s id=%s sender=%s",
service_name, STR(queue_name), STR(queue_id), STR(sender));
/*
* On request by the client, set up a trap to delete the log file in case
* of errors.
*/
if (flags & BOUNCE_FLAG_CLEAN)
bounce_cleanup_register(service_name, STR(queue_id));
/*
* Execute the request.
*/
return (bounce_flush_service(service_name, STR(queue_name),
STR(queue_id), STR(sender)));
}
/* bounce_service - parse bounce command type and delegate */
static void bounce_service(VSTREAM *client, char *service_name, char **argv)
{
int command;
int status;
/*
* Sanity check. This service takes no command-line arguments. The
* service name should be usable as a subdirectory name.
*/
if (argv[0])
msg_fatal("unexpected command-line argument: %s", argv[0]);
if (mail_queue_name_ok(service_name) == 0)
msg_fatal("malformed service name: %s", service_name);
/*
* Read and validate the first parameter of the client request. Let the
* request-specific protocol routines take care of the remainder.
*/
if (mail_scan(client, "%d", &command) != 1) {
msg_warn("malformed request");
status = -1;
} else if (command == BOUNCE_CMD_FLUSH) {
status = bounce_flush_proto(service_name, client);
} else if (command == BOUNCE_CMD_APPEND) {
status = bounce_append_proto(service_name, client);
} else {
msg_warn("unknown command: %d", command);
status = -1;
}
/*
* When the request has completed, send the completion status to the
* client.
*/
mail_print(client, "%d", status);
vstream_fflush(client);
/*
* When a cleanup trap was set, delete the log file in case of error.
* This includes errors while sending the completion status to the
* client.
*/
if (bounce_cleanup_path) {
if (status || vstream_ferror(client))
bounce_cleanup_log();
bounce_cleanup_unregister();
}
}
/* post_jail_init - initialize after entering chroot jail */
static void post_jail_init(void)
{
/*
* Initialize. We're single threaded so we can reuse some memory upon
* successive requests.
*/
queue_id = vstring_alloc(10);
queue_name = vstring_alloc(10);
recipient = vstring_alloc(10);
sender = vstring_alloc(10);
why = vstring_alloc(10);
}
/* main - the main program */
int main(int argc, char **argv)
{
static CONFIG_INT_TABLE int_table[] = {
VAR_BOUNCE_LIMIT, DEF_BOUNCE_LIMIT, &var_bounce_limit, 1, 0,
0,
};
static CONFIG_STR_TABLE str_table[] = {
VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
0,
};
/*
* Pass control to the single-threaded service skeleton.
*/
single_server_main(argc, argv, bounce_service,
MAIL_SERVER_INT_TABLE, int_table,
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_POST_INIT, post_jail_init,
0);
}

View File

@@ -0,0 +1,124 @@
/*++
/* NAME
/* bounce_append_service 3
/* SUMMARY
/* append record to bounce log, server side
/* SYNOPSIS
/* #include "bounce_service.h"
/*
/* int bounce_append_service(queue_id, recipient, why)
/* char *queue_id;
/* char *recipient;
/* char *why;
/* DESCRIPTION
/* This module implements the server side of the bounce_append()
/* (append bounce log) request. This routine either succeeds or
/* it raises a fatal error.
/* DIAGNOSTICS
/* Fatal errors: all file access errors; memory allocation errors.
/* BUGS
/* SEE ALSO
/* bounce(3) basic bounce service 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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <stringops.h>
/* Global library. */
#include <mail_queue.h>
#include <quote_822_local.h>
#include <deliver_flock.h>
/* Application-specific. */
#include "bounce_service.h"
/* bounce_append_service - append bounce log */
int bounce_append_service(char *service, char *queue_id,
char *recipient, char *why)
{
VSTRING *in_buf = vstring_alloc(100);
VSTRING *out_buf = vstring_alloc(100);
VSTREAM *log;
long orig_length;
/*
* This code is paranoid for a good reason. Once the bounce service takes
* responsibility, the mail system will make no further attempts to
* deliver this recipient. Whenever file access fails, assume that the
* system is under stress or that something has been mis-configured, and
* force a backoff by raising a fatal run-time error.
*/
log = mail_queue_open(service, queue_id,
O_WRONLY | O_APPEND | O_CREAT, 0600);
if (log == 0)
msg_fatal("open file %s %s: %m", service, queue_id);
/*
* Lock out other processes to avoid truncating someone else's data in
* case of trouble.
*/
if (deliver_flock(vstream_fileno(log), (VSTRING *) 0) < 0)
msg_fatal("lock file %s %s: %m", service, queue_id);
/*
* Now, go for it. Append a record. Truncate the log to the original
* length when the append operation fails. We use the plain stream-lf
* file format because we do not need anything more complicated. As a
* benefit, we can still recover some data when the file is a little
* garbled.
*/
if ((orig_length = vstream_fseek(log, 0L, SEEK_END)) < 0)
msg_fatal("seek file %s %s: %m", service, queue_id);
if (*recipient)
vstream_fprintf(log, "<%s>: ",
printable(vstring_str(quote_822_local(in_buf, recipient)), '?'));
vstream_fputs(printable(why, '?'), log);
vstream_fputs("\n\n", log);
if (vstream_fflush(log) != 0 || fsync(vstream_fileno(log)) < 0) {
#ifndef NO_TRUNCATE
if (ftruncate(vstream_fileno(log), (off_t) orig_length) < 0)
msg_fatal("truncate file %s %s: %m", service, queue_id);
#endif
msg_fatal("append file %s %s: %m", service, queue_id);
}
/*
* Darn. If closing the log detects a problem, the only way to undo the
* damage is to open the log once more, and to truncate the log to the
* original length. But, this could happen only when the log is kept on a
* remote file system, and that is not recommended practice anyway.
*/
if (vstream_fclose(log) != 0)
msg_warn("append file %s %s: %m", service, queue_id);
vstring_free(in_buf);
vstring_free(out_buf);
return (0);
}

View File

@@ -0,0 +1,177 @@
/*++
/* NAME
/* bounce_cleanup 3
/* SUMMARY
/* cleanup logfile upon error
/* SYNOPSIS
/* #include "bounce_service.h"
/*
/* int bounce_cleanup_registered()
/*
/* void bounce_cleanup_register(queue_id)
/* char *queue_id;
/*
/* void bounce_cleanup_log(void)
/*
/* void bounce_cleanup_unregister(void)
/* DESCRIPTION
/* This module implements support for deleting the current
/* bounce logfile in case of errors, and upon the arrival
/* of a SIGTERM signal (shutdown).
/*
/* bounce_cleanup_register() registers a callback routine with the
/* run-time error handler, for automatic logfile removal in case
/* of a fatal run-time error.
/*
/* bounce_cleanup_unregister() cleans up storage used by
/* bounce_cleanup_register().
/*
/* In-between bounce_cleanup_register() and bounce_cleanup_unregister()
/* calls, a call of bounce_cleanup_log() will delete the registered
/* bounce logfile.
/*
/* bounce_cleanup_registered() returns non-zero when a cleanup
/* trap has been set.
/* DIAGNOSTICS
/* Fatal error: all file access errors. Panic: nested calls of
/* bounce_cleanup_register(); any calls of bounce_cleanup_unregister()
/* or bounce_cleanup_log() without preceding bounce_cleanup_register()
/* call.
/* BUGS
/* SEE ALSO
/* master(8) process manager
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstring.h>
/* Global library. */
#include <mail_queue.h>
/* Application-specific. */
#include "bounce_service.h"
/*
* Support for removing a logfile when an update fails. In order to do this,
* we save a copy of the currently-open logfile name, and register a
* callback function pointer with the run-time error handler. The saved
* pathname is made global so that the application can see whether or not a
* trap was set up.
*/
static MSG_CLEANUP_FN bounce_cleanup_func; /* saved callback */
VSTRING *bounce_cleanup_path; /* saved path name */
/* bounce_cleanup_callback - run-time callback to cleanup logfile */
static void bounce_cleanup_callback(void)
{
/*
* Remove the logfile.
*/
if (bounce_cleanup_path)
bounce_cleanup_log();
/*
* Execute the saved cleanup action.
*/
if (bounce_cleanup_func)
bounce_cleanup_func();
}
/* bounce_cleanup_log - clean up the logfile */
void bounce_cleanup_log(void)
{
char *myname = "bounce_cleanup_log";
/*
* Sanity checks.
*/
if (bounce_cleanup_path == 0)
msg_panic("%s: no cleanup context", myname);
/*
* This function may be called before a logfile is created or after it
* has been deleted, so do not complain.
*/
(void) unlink(vstring_str(bounce_cleanup_path));
}
/* bounce_cleanup_sig - signal handler */
static void bounce_cleanup_sig(int sig)
{
/*
* Running as a signal handler - don't do complicated stuff.
*/
if (bounce_cleanup_path)
(void) unlink(vstring_str(bounce_cleanup_path));
exit(sig);
}
/* bounce_cleanup_register - register logfile to clean up */
void bounce_cleanup_register(char *service, char *queue_id)
{
char *myname = "bounce_cleanup_register";
/*
* Sanity checks.
*/
if (bounce_cleanup_path)
msg_panic("%s: nested call", myname);
/*
* Save a copy of the logfile path, and of the last callback function
* pointer registered with the run-time error handler.
*/
bounce_cleanup_path = vstring_alloc(10);
(void) mail_queue_path(bounce_cleanup_path, service, queue_id);
bounce_cleanup_func = msg_cleanup(bounce_cleanup_callback);
signal(SIGTERM, bounce_cleanup_sig);
}
/* bounce_cleanup_unregister - unregister logfile to clean up */
void bounce_cleanup_unregister(void)
{
char *myname = "bounce_cleanup_unregister";
/*
* Sanity checks.
*/
if (bounce_cleanup_path == 0)
msg_panic("%s: no cleanup context", myname);
/*
* Restore the saved callback function pointer, and release storage for
* the saved logfile pathname.
*/
signal(SIGTERM, SIG_DFL);
(void) msg_cleanup(bounce_cleanup_func);
vstring_free(bounce_cleanup_path);
bounce_cleanup_path = 0;
}

View File

@@ -0,0 +1,359 @@
/*++
/* NAME
/* bounce_flush_service 3
/* SUMMARY
/* send non-delivery report to sender, server side
/* SYNOPSIS
/* #include "bounce_service.h"
/*
/* int bounce_flush_service(queue_name, queue_id, sender)
/* char *queue_name;
/* char *queue_id;
/* char *sender;
/* DESCRIPTION
/* This module implements the server side of the bounce_flush()
/* (send bounce message) request.
/*
/* When a message bounces, a full copy is sent to the originator,
/* and a copy of the diagnostics with message headers is sent to
/* the postmaster. The result is non-zero when the operation
/* should be tried again.
/*
/* When a single bounce is sent, the sender address is the empty
/* address. When a double bounce is sent, the sender is taken
/* from the configuration parameter \fIdouble_bounce_sender\fR.
/* DIAGNOSTICS
/* Fatal error: error opening existing file. Warnings: corrupt
/* message file. A corrupt message is saved to the "corrupt"
/* queue for further inspection.
/* BUGS
/* SEE ALSO
/* bounce(3) basic bounce service 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 <fcntl.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <mymalloc.h>
#include <stringops.h>
#include <events.h>
#include <line_wrap.h>
#include <name_mask.h>
/* Global library. */
#include <mail_queue.h>
#include <mail_proto.h>
#include <quote_822_local.h>
#include <mail_params.h>
#include <canon_addr.h>
#include <is_header.h>
#include <record.h>
#include <rec_type.h>
#include <config.h>
#include <post_mail.h>
#include <mail_addr.h>
#include <mark_corrupt.h>
#include <mail_error.h>
/* Application-specific. */
#include "bounce_service.h"
#define STR vstring_str
/* bounce_header - generate bounce message header */
static int bounce_header(VSTREAM *bounce, VSTRING *buf, char *dest)
{
/*
* Print a minimal bounce header. The cleanup service will add other
* headers and will make all addresses fully qualified.
*/
post_mail_fprintf(bounce, "From: %s (Mail Delivery System)",
MAIL_ADDR_MAIL_DAEMON);
post_mail_fprintf(bounce, *dest == 0 ?
"Subject: Postmaster Copy: Undelivered Mail" :
"Subject: Undelivered Mail Returned to Sender");
quote_822_local(buf, *dest == 0 ? mail_addr_postmaster() : dest);
post_mail_fprintf(bounce, "To: %s", STR(buf));
post_mail_fputs(bounce, "");
return (vstream_ferror(bounce));
}
/* bounce_boilerplate - generate boiler-plate text */
static int bounce_boilerplate(VSTREAM *bounce, VSTRING *buf)
{
/*
* Print the message body with the problem report. XXX For now, we use a
* fixed bounce template. We could use a site-specific parametrized
* template with ${name} macros and we could do wonderful things such as
* word wrapping to make the text look nicer. No matter how hard we would
* try, receiving bounced mail will always suck.
*/
post_mail_fprintf(bounce, "This is the %s program at host %s.",
var_mail_name, var_myhostname);
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce,
"I'm sorry to have to inform you that the message returned");
post_mail_fprintf(bounce,
"below could not be delivered to one or more destinations.");
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce,
"For further assistance, please contact <%s>",
STR(canon_addr_external(buf, MAIL_ADDR_POSTMASTER)));
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce,
"If you do so, please include this problem report. You can");
post_mail_fprintf(bounce,
"delete your own text from the message returned below.");
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
return (vstream_ferror(bounce));
}
/* bounce_print - line_wrap callback */
static void bounce_print(const char *str, int len, int indent, char *context)
{
VSTREAM *bounce = (VSTREAM *) context;
post_mail_fprintf(bounce, "%*s%.*s", indent, "", len, str);
}
/* bounce_diagnostics - send bounce log report */
static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char *queue_id)
{
VSTREAM *log;
/*
* If the bounce log cannot be found, do not raise a fatal run-time
* error. There is nothing we can do about the error, and all we are
* doing is to inform the sender of a delivery problem, Bouncing a
* message does not have to be a perfect job. But if the system IS
* running out of resources, raise a fatal run-time error and force a
* backoff.
*/
if ((log = mail_queue_open(service, queue_id, O_RDONLY, 0)) == 0) {
if (errno != ENOENT)
msg_fatal("open %s %s: %m", service, queue_id);
post_mail_fputs(bounce, "");
post_mail_fputs(bounce, "\t--- Delivery error report unavailable ---");
post_mail_fputs(bounce, "");
}
/*
* Append a copy of the delivery error log. Again, we're doing a best
* effort, so there is no point raising a fatal run-time error in case of
* a logfile read error. Wrap long lines, filter non-printable
* characters, and prepend one blank, so this data can safely be piped
* into other programs.
*/
else {
#define LENGTH 79
#define INDENT 4
post_mail_fputs(bounce, "");
post_mail_fputs(bounce, "\t--- Delivery error report follows ---");
post_mail_fputs(bounce, "");
while (vstream_ferror(bounce) == 0 && vstring_fgets_nonl(buf, log)) {
printable(STR(buf), '_');
line_wrap(STR(buf), LENGTH, INDENT, bounce_print, (char *) bounce);
if (vstream_ferror(bounce) != 0)
break;
}
if (vstream_fclose(log))
msg_warn("read bounce log %s: %m", queue_id);
}
return (vstream_ferror(bounce));
}
/* bounce_original - send a copy of the original to the victim */
static int bounce_original(char *service, VSTREAM *bounce, VSTRING *buf,
char *queue_name, char *queue_id, int headers_only)
{
int status = 0;
VSTREAM *src;
int rec_type;
int bounce_length;
/*
* If the original message cannot be found, do not raise a run-time
* error. There is nothing we can do about the error, and all we are
* doing is to inform the sender of a delivery problem. Bouncing a
* message does not have to be a perfect job. But if the system IS
* running out of resources, raise a fatal run-time error and force a
* backoff.
*/
if ((src = mail_queue_open(queue_name, queue_id, O_RDONLY, 0)) == 0) {
if (errno != ENOENT)
msg_fatal("open %s %s: %m", service, queue_id);
post_mail_fputs(bounce, "\t--- Undelivered message unavailable ---");
return (vstream_ferror(bounce));
}
/*
* Append a copy of the rejected message.
*/
post_mail_fputs(bounce, "\t--- Undelivered message follows ---");
post_mail_fputs(bounce, "");
/*
* Skip over the original message envelope records. If the envelope is
* corrupted just send whatever we can (remember this is a best effort,
* it does not have to be perfect).
*/
while ((rec_type = rec_get(src, buf, 0)) > 0)
if (rec_type == REC_TYPE_MESG)
break;
/*
* Copy the original message contents. Limit the amount of bounced text
* so there is a better chance of the bounce making it back. We're doing
* raw record output here so that we don't throw away binary transparency
* yet.
*/
#define IS_HEADER(s) (ISSPACE(*(s)) || is_header(s))
bounce_length = 0;
while (status == 0 && (rec_type = rec_get(src, buf, 0)) > 0) {
if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
break;
if (headers_only && !IS_HEADER(vstring_str(buf)))
break;
if (var_bounce_limit == 0 || bounce_length < var_bounce_limit) {
bounce_length += VSTRING_LEN(buf);
status = (REC_PUT_BUF(bounce, rec_type, buf) != rec_type);
}
}
if (headers_only == 0 && rec_type != REC_TYPE_XTRA)
status |= mark_corrupt(src);
if (vstream_fclose(src))
msg_warn("read message file %s %s: %m", queue_name, queue_id);
return (status);
}
/* bounce_flush_service - send a bounce */
int bounce_flush_service(char *service, char *queue_name,
char *queue_id, char *recipient)
{
VSTRING *buf = vstring_alloc(100);
const char *double_bounce_addr;
int status = 1;
VSTREAM *bounce;
#define NULL_RECIPIENT MAIL_ADDR_EMPTY /* special address */
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define TO_POSTMASTER(addr) (*(addr) == 0)
#define NULL_CLEANUP_FLAGS 0
#define BOUNCE_HEADERS 1
#define BOUNCE_ALL 0
/*
* The choice of sender address depends on recipient address. For a
* single bounce (typically a non-delivery notification to the message
* originator), the sender address is the empty string. For a double
* bounce (typically a failed single bounce, or a postmaster notification
* that was produced by any of the mail processes) the sender address is
* defined by the var_double_bounce_sender configuration variable. When a
* double bounce cannot be delivered, the local delivery agent gives
* special treatment to the resulting bounce message.
*/
double_bounce_addr = mail_addr_double_bounce();
/*
* Connect to the cleanup service, and request that the cleanup service
* takes no special actions in case of problems.
*/
if ((bounce = post_mail_fopen_nowait(TO_POSTMASTER(recipient) ?
double_bounce_addr : NULL_SENDER,
recipient, NULL_CLEANUP_FLAGS,
"BOUNCE")) != 0) {
/*
* Send the bounce message header, some boilerplate text that
* pretends that we are a polite mail system, the text with reason
* for the bounce, and a copy of the original message.
*/
if (bounce_header(bounce, buf, recipient) == 0
&& bounce_boilerplate(bounce, buf) == 0
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
bounce_original(service, bounce, buf, queue_name, queue_id, BOUNCE_ALL);
/*
* Finish the bounce, and retrieve the completion status.
*/
status = post_mail_fclose(bounce);
}
/*
* If not sending to the postmaster or double-bounce pseudo accounts,
* send a postmaster copy as if it is a double bounce, so it will not
* bounce in case of error. This time, block while waiting for resources
* to become available. We know they were available just a split second
* ago.
*/
if (status == 0 && !TO_POSTMASTER(recipient)
&& strcasecmp(recipient, double_bounce_addr) != 0
&& (MAIL_ERROR_BOUNCE & name_mask(mail_error_masks, var_notify_classes))) {
/*
* Send the text with reason for the bounce, and the headers of the
* original message. Don't bother sending the boiler-plate text.
*/
bounce = post_mail_fopen(double_bounce_addr, NULL_RECIPIENT,
NULL_CLEANUP_FLAGS, "BOUNCE");
if (bounce_header(bounce, buf, NULL_RECIPIENT) == 0
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
bounce_original(service, bounce, buf, queue_name, queue_id, BOUNCE_HEADERS);
/*
* Finish the bounce, and update the completion status.
*/
status |= post_mail_fclose(bounce);
}
/*
* Examine the completion status. Delete the bounce log file only when
* the bounce was posted successfully.
*/
if (status == 0 && mail_queue_remove(service, queue_id) && errno != ENOENT)
msg_fatal("remove %s %s: %m", service, queue_id);
/*
* Cleanup.
*/
vstring_free(buf);
return (status);
}

View File

@@ -0,0 +1,45 @@
/*++
/* NAME
/* bounce_service 3h
/* SUMMARY
/* bounce message service
/* SYNOPSIS
/* #include <bounce_service.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <vstring.h>
/*
* bounce_append_service.c
*/
extern int bounce_append_service(char *, char *, char *, char *);
/*
* bounce_flush_service.c
*/
extern int bounce_flush_service(char *, char *, char *, char *);
/*
* bounce_cleanup.c
*/
extern VSTRING *bounce_cleanup_path;
extern void bounce_cleanup_register(char *, char *);
extern void bounce_cleanup_log(void);
extern void bounce_cleanup_unregister(void);
#define bounce_cleanup_registered() (bounce_cleanup_path != 0)
/* 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
/*--*/

89
postfix/cleanup/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/cleanup/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

273
postfix/cleanup/Makefile.in Normal file
View File

@@ -0,0 +1,273 @@
SHELL = /bin/sh
SRCS = cleanup.c cleanup_out.c cleanup_envelope.c cleanup_message.c \
cleanup_extracted.c cleanup_state.c cleanup_skip.c cleanup_rewrite.c \
cleanup_map11.c cleanup_map1n.c cleanup_masquerade.c \
cleanup_out_recipient.c
OBJS = cleanup.o cleanup_out.o cleanup_envelope.o cleanup_message.o \
cleanup_extracted.o cleanup_state.o cleanup_skip.o cleanup_rewrite.o \
cleanup_map11.o cleanup_map1n.o cleanup_masquerade.o \
cleanup_out_recipient.o
HDRS =
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
PROG = cleanup
INC_DIR = ../include
LIBS = ../lib/libmaster.a ../lib/libglobal.a ../lib/libutil.a
.c.o:; $(CC) $(CFLAGS) -c $*.c
$(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
(set -e; echo "# DO NOT EDIT"; $(OPTS) sh ../makedefs; cat $?) >$@
test: $(TESTPROG)
update: ../bin/$(PROG)
../bin/$(PROG): $(PROG)
cp $(PROG) ../bin
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
cp *.h printfck
sed '1,/^# do not edit/!d' Makefile > printfck/Makefile
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
clean:
rm -f *.o *core $(PROG) $(TESTPROG) junk
rm -rf printfck
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
cleanup.o: cleanup.c
cleanup.o: ../include/sys_defs.h
cleanup.o: ../include/msg.h
cleanup.o: ../include/vstring.h
cleanup.o: ../include/vbuf.h
cleanup.o: ../include/vstream.h
cleanup.o: ../include/mymalloc.h
cleanup.o: ../include/iostuff.h
cleanup.o: ../include/config.h
cleanup.o: ../include/cleanup_user.h
cleanup.o: ../include/mail_queue.h
cleanup.o: ../include/mail_proto.h
cleanup.o: ../include/opened.h
cleanup.o: ../include/bounce.h
cleanup.o: ../include/mail_params.h
cleanup.o: ../include/mail_stream.h
cleanup.o: ../include/mail_addr.h
cleanup.o: ../include/mail_server.h
cleanup.o: cleanup.h
cleanup.o: ../include/argv.h
cleanup.o: ../include/maps.h
cleanup.o: ../include/tok822.h
cleanup.o: ../include/resolve_clnt.h
cleanup.o: ../include/been_here.h
cleanup_envelope.o: cleanup_envelope.c
cleanup_envelope.o: ../include/sys_defs.h
cleanup_envelope.o: ../include/msg.h
cleanup_envelope.o: ../include/vstring.h
cleanup_envelope.o: ../include/vbuf.h
cleanup_envelope.o: ../include/vstream.h
cleanup_envelope.o: ../include/mymalloc.h
cleanup_envelope.o: ../include/record.h
cleanup_envelope.o: ../include/rec_type.h
cleanup_envelope.o: ../include/cleanup_user.h
cleanup_envelope.o: ../include/tok822.h
cleanup_envelope.o: ../include/resolve_clnt.h
cleanup_envelope.o: ../include/mail_params.h
cleanup_envelope.o: cleanup.h
cleanup_envelope.o: ../include/argv.h
cleanup_envelope.o: ../include/maps.h
cleanup_envelope.o: ../include/been_here.h
cleanup_envelope.o: ../include/mail_stream.h
cleanup_extracted.o: cleanup_extracted.c
cleanup_extracted.o: ../include/sys_defs.h
cleanup_extracted.o: ../include/msg.h
cleanup_extracted.o: ../include/vstring.h
cleanup_extracted.o: ../include/vbuf.h
cleanup_extracted.o: ../include/vstream.h
cleanup_extracted.o: ../include/argv.h
cleanup_extracted.o: ../include/mymalloc.h
cleanup_extracted.o: ../include/cleanup_user.h
cleanup_extracted.o: ../include/record.h
cleanup_extracted.o: ../include/rec_type.h
cleanup_extracted.o: cleanup.h
cleanup_extracted.o: ../include/maps.h
cleanup_extracted.o: ../include/tok822.h
cleanup_extracted.o: ../include/resolve_clnt.h
cleanup_extracted.o: ../include/been_here.h
cleanup_extracted.o: ../include/mail_stream.h
cleanup_map11.o: cleanup_map11.c
cleanup_map11.o: ../include/sys_defs.h
cleanup_map11.o: ../include/msg.h
cleanup_map11.o: ../include/vstring.h
cleanup_map11.o: ../include/vbuf.h
cleanup_map11.o: ../include/dict.h
cleanup_map11.o: ../include/vstream.h
cleanup_map11.o: ../include/mymalloc.h
cleanup_map11.o: ../include/cleanup_user.h
cleanup_map11.o: ../include/mail_addr_map.h
cleanup_map11.o: ../include/argv.h
cleanup_map11.o: ../include/maps.h
cleanup_map11.o: ../include/quote_822_local.h
cleanup_map11.o: cleanup.h
cleanup_map11.o: ../include/tok822.h
cleanup_map11.o: ../include/resolve_clnt.h
cleanup_map11.o: ../include/been_here.h
cleanup_map11.o: ../include/mail_stream.h
cleanup_map1n.o: cleanup_map1n.c
cleanup_map1n.o: ../include/sys_defs.h
cleanup_map1n.o: ../include/mymalloc.h
cleanup_map1n.o: ../include/msg.h
cleanup_map1n.o: ../include/argv.h
cleanup_map1n.o: ../include/vstring.h
cleanup_map1n.o: ../include/vbuf.h
cleanup_map1n.o: ../include/dict.h
cleanup_map1n.o: ../include/vstream.h
cleanup_map1n.o: ../include/mail_addr_map.h
cleanup_map1n.o: ../include/maps.h
cleanup_map1n.o: ../include/cleanup_user.h
cleanup_map1n.o: ../include/quote_822_local.h
cleanup_map1n.o: cleanup.h
cleanup_map1n.o: ../include/tok822.h
cleanup_map1n.o: ../include/resolve_clnt.h
cleanup_map1n.o: ../include/been_here.h
cleanup_map1n.o: ../include/mail_stream.h
cleanup_masquerade.o: cleanup_masquerade.c
cleanup_masquerade.o: ../include/sys_defs.h
cleanup_masquerade.o: ../include/msg.h
cleanup_masquerade.o: ../include/vstring.h
cleanup_masquerade.o: ../include/vbuf.h
cleanup_masquerade.o: ../include/argv.h
cleanup_masquerade.o: ../include/htable.h
cleanup_masquerade.o: ../include/mymalloc.h
cleanup_masquerade.o: ../include/stringops.h
cleanup_masquerade.o: ../include/mail_params.h
cleanup_masquerade.o: ../include/tok822.h
cleanup_masquerade.o: ../include/resolve_clnt.h
cleanup_masquerade.o: ../include/quote_822_local.h
cleanup_masquerade.o: cleanup.h
cleanup_masquerade.o: ../include/vstream.h
cleanup_masquerade.o: ../include/maps.h
cleanup_masquerade.o: ../include/been_here.h
cleanup_masquerade.o: ../include/mail_stream.h
cleanup_message.o: cleanup_message.c
cleanup_message.o: ../include/sys_defs.h
cleanup_message.o: ../include/msg.h
cleanup_message.o: ../include/vstring.h
cleanup_message.o: ../include/vbuf.h
cleanup_message.o: ../include/vstream.h
cleanup_message.o: ../include/argv.h
cleanup_message.o: ../include/split_at.h
cleanup_message.o: ../include/mymalloc.h
cleanup_message.o: ../include/record.h
cleanup_message.o: ../include/rec_type.h
cleanup_message.o: ../include/cleanup_user.h
cleanup_message.o: ../include/tok822.h
cleanup_message.o: ../include/resolve_clnt.h
cleanup_message.o: ../include/header_opts.h
cleanup_message.o: ../include/quote_822_local.h
cleanup_message.o: ../include/mail_params.h
cleanup_message.o: ../include/mail_date.h
cleanup_message.o: ../include/mail_addr.h
cleanup_message.o: ../include/is_header.h
cleanup_message.o: cleanup.h
cleanup_message.o: ../include/maps.h
cleanup_message.o: ../include/been_here.h
cleanup_message.o: ../include/mail_stream.h
cleanup_out.o: cleanup_out.c
cleanup_out.o: ../include/sys_defs.h
cleanup_out.o: ../include/msg.h
cleanup_out.o: ../include/vstring.h
cleanup_out.o: ../include/vbuf.h
cleanup_out.o: ../include/vstream.h
cleanup_out.o: ../include/record.h
cleanup_out.o: ../include/rec_type.h
cleanup_out.o: ../include/cleanup_user.h
cleanup_out.o: cleanup.h
cleanup_out.o: ../include/argv.h
cleanup_out.o: ../include/maps.h
cleanup_out.o: ../include/tok822.h
cleanup_out.o: ../include/resolve_clnt.h
cleanup_out.o: ../include/been_here.h
cleanup_out.o: ../include/mail_stream.h
cleanup_out_recipient.o: cleanup_out_recipient.c
cleanup_out_recipient.o: ../include/sys_defs.h
cleanup_out_recipient.o: ../include/argv.h
cleanup_out_recipient.o: ../include/been_here.h
cleanup_out_recipient.o: ../include/mail_params.h
cleanup_out_recipient.o: ../include/rec_type.h
cleanup_out_recipient.o: cleanup.h
cleanup_out_recipient.o: ../include/vstring.h
cleanup_out_recipient.o: ../include/vbuf.h
cleanup_out_recipient.o: ../include/vstream.h
cleanup_out_recipient.o: ../include/maps.h
cleanup_out_recipient.o: ../include/tok822.h
cleanup_out_recipient.o: ../include/resolve_clnt.h
cleanup_out_recipient.o: ../include/mail_stream.h
cleanup_rewrite.o: cleanup_rewrite.c
cleanup_rewrite.o: ../include/sys_defs.h
cleanup_rewrite.o: ../include/msg.h
cleanup_rewrite.o: ../include/vstring.h
cleanup_rewrite.o: ../include/vbuf.h
cleanup_rewrite.o: ../include/tok822.h
cleanup_rewrite.o: ../include/resolve_clnt.h
cleanup_rewrite.o: ../include/rewrite_clnt.h
cleanup_rewrite.o: ../include/quote_822_local.h
cleanup_rewrite.o: cleanup.h
cleanup_rewrite.o: ../include/vstream.h
cleanup_rewrite.o: ../include/argv.h
cleanup_rewrite.o: ../include/maps.h
cleanup_rewrite.o: ../include/been_here.h
cleanup_rewrite.o: ../include/mail_stream.h
cleanup_skip.o: cleanup_skip.c
cleanup_skip.o: ../include/sys_defs.h
cleanup_skip.o: ../include/msg.h
cleanup_skip.o: ../include/vstream.h
cleanup_skip.o: ../include/vbuf.h
cleanup_skip.o: ../include/record.h
cleanup_skip.o: ../include/vstring.h
cleanup_skip.o: ../include/rec_type.h
cleanup_skip.o: cleanup.h
cleanup_skip.o: ../include/argv.h
cleanup_skip.o: ../include/maps.h
cleanup_skip.o: ../include/tok822.h
cleanup_skip.o: ../include/resolve_clnt.h
cleanup_skip.o: ../include/been_here.h
cleanup_skip.o: ../include/mail_stream.h
cleanup_state.o: cleanup_state.c
cleanup_state.o: ../include/sys_defs.h
cleanup_state.o: ../include/mymalloc.h
cleanup_state.o: ../include/vstring.h
cleanup_state.o: ../include/vbuf.h
cleanup_state.o: ../include/vstream.h
cleanup_state.o: ../include/been_here.h
cleanup_state.o: ../include/mail_params.h
cleanup_state.o: cleanup.h
cleanup_state.o: ../include/argv.h
cleanup_state.o: ../include/maps.h
cleanup_state.o: ../include/tok822.h
cleanup_state.o: ../include/resolve_clnt.h
cleanup_state.o: ../include/mail_stream.h

443
postfix/cleanup/cleanup.c Normal file
View File

@@ -0,0 +1,443 @@
/*++
/* NAME
/* cleanup 8
/* SUMMARY
/* canonicalize and enqueue Postfix message
/* SYNOPSIS
/* \fBcleanup\fR [generic Postfix daemon options]
/* DESCRIPTION
/* The \fBcleanup\fR daemon processes inbound mail, inserts it
/* into the \fBincoming\fR mail queue, and informs the queue
/* manager of its arrival.
/*
/* The \fBcleanup\fR daemon always performs the following transformations:
/* .IP \(bu
/* Insert missing message headers: (\fBResent-\fR) \fBFrom:\fR,
/* \fBMessage-Id:\fR, and \fBDate:\fR.
/* .IP \(bu
/* Extract envelope recipient addresses from (\fBResent-\fR) \fBTo:\fR,
/* \fBCc:\fR and \fBBcc:\fR message headers when no recipients are
/* specified in the message envelope.
/* .IP \(bu
/* Transform envelope and header addresses to the standard
/* \fIuser@fully-qualified-domain\fR form that is expected by other
/* Postfix programs.
/* This task is delegated to the \fBtrivial-rewrite\fR(8) daemon.
/* .IP \(bu
/* Eliminate duplicate envelope recipient addresses.
/* .PP
/* The following address transformations are optional:
/* .IP \(bu
/* Optionally, rewrite all envelope and header addresses according
/* to the mappings specified in the \fBcanonical\fR(5) lookup tables.
/* .IP \(bu
/* Optionally, masquerade envelope sender addresses and message
/* header addresses (i.e. strip host or domain information below
/* all domains listed in the \fBmasquerade_domains\fR parameter,
/* except for user names listed in \fBmasquerade_exceptions\fR).
/* Address masquerading does not affect envelope recipients.
/* .IP \(bu
/* Optionally, expand envelope recipients according to information
/* found in the \fBvirtual\fR(5) lookup tables.
/* .PP
/* The \fBcleanup\fR daemon performs sanity checks on the content of
/* each message. When it finds a problem, by default it returns a
/* diagnostic status to the client, and leaves it up to the client
/* to deal with the problem. Alternatively, the client can request
/* the \fBcleanup\fR daemon to bounce the message back to the sender
/* in case of trouble.
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS
/* Table-driven rewriting rules make it hard to express \fBif then
/* else\fR and other logical relationships.
/* CONFIGURATION PARAMETERS
/* .ad
/* .fi
/* The following \fBmain.cf\fR parameters are especially relevant to
/* this program. See the Postfix \fBmain.cf\fR file for syntax details
/* and for default values. Use the \fBpostfix reload\fR command after
/* a configuration change.
/* .SH Miscellaneous
/* .ad
/* .fi
/* .IP \fBhopcount_limit\fR
/* Limit the number of \fBReceived:\fR message headers.
/* .SH "Address transformations"
/* .ad
/* .fi
/* .IP \fBempty_address_recipient\fR
/* The destination for undeliverable mail from <>. This
/* substitution is done before all other address rewriting.
/* .IP \fBcanonical_maps\fR
/* Address mapping lookup table for sender and recipient addresses
/* in envelopes and headers.
/* .IP \fBrecipient_canonical_maps\fR
/* Address mapping lookup table for envelope and header recipient
/* addresses.
/* .IP \fBsender_canonical_maps\fR
/* Address mapping lookup table for envelope and header sender
/* addresses.
/* .IP \fBmasquerade_domains\fR
/* List of domains that hide their subdomain structure.
/* .IP \fBmasquerade_exceptions\fR
/* List of user names that are not subject to address masquerading.
/* .IP \fBvirtual_maps\fR
/* Address mapping lookup table for envelope recipient addresses.
/* .SH "Resource controls"
/* .ad
/* .fi
/* .IP \fBduplicate_filter_limit\fR
/* Limit the number of envelope recipients that are remembered.
/* .IP \fBheader_size_limit\fR
/* Limit the amount of memory in bytes used to process a message header.
/* SEE ALSO
/* canonical(5) canonical address lookup table format
/* qmgr(8) queue manager daemon
/* syslogd(8) system logging
/* trivial-rewrite(8) address rewriting
/* virtual(5) virtual address lookup table format
/* FILES
/* /etc/postfix/canonical*, canonical mapping table
/* /etc/postfix/virtual*, virtual mapping table
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <mymalloc.h>
#include <iostuff.h>
/* Global library. */
#include <config.h>
#include <cleanup_user.h>
#include <mail_queue.h>
#include <mail_proto.h>
#include <opened.h>
#include <bounce.h>
#include <mail_params.h>
#include <mail_stream.h>
#include <mail_addr.h>
/* Single-threaded server skeleton. */
#include <mail_server.h>
/* Application-specific. */
#include "cleanup.h"
/*
* Global state: any queue files that we have open, so that the error
* handler can clean up in case of trouble.
*/
char *cleanup_path; /* queue file name */
/*
* Tunable parameters.
*/
int var_hopcount_limit; /* max mailer hop count */
int var_header_limit; /* max header length */
char *var_canonical_maps; /* common canonical maps */
char *var_send_canon_maps; /* sender canonical maps */
char *var_rcpt_canon_maps; /* recipient canonical maps */
char *var_virtual_maps; /* virtual maps */
char *var_masq_domains; /* masquerade domains */
char *var_masq_exceptions; /* users not masqueraded */
int var_dup_filter_limit; /* recipient dup filter */
char *var_empty_addr; /* destination of bounced bounces */
/*
* Mappings.
*/
MAPS *cleanup_comm_canon_maps;
MAPS *cleanup_send_canon_maps;
MAPS *cleanup_rcpt_canon_maps;
MAPS *cleanup_virtual_maps;
ARGV *cleanup_masq_domains;
/* cleanup_service - process one request to inject a message into the queue */
static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
{
char *junk;
static char *log_queues[] = {
MAIL_QUEUE_DEFER,
MAIL_QUEUE_BOUNCE,
0,
};
char **cpp;
/*
* Sanity check. This service takes no command-line arguments.
*/
if (argv[0])
msg_fatal("unexpected command-line argument: %s", argv[0]);
/*
* Initialize.
*/
cleanup_state_alloc();
cleanup_src = src;
/*
* Open the queue file. Send the queue ID to the client so they can use
* it for logging purposes. For example, the SMTP server sends the queue
* id to the SMTP client after completion of the DATA command; and when
* the local delivery agent forwards a message, it logs the new queue id
* together with the old one. All this is done to make it easier for mail
* admins to follow a message while it hops from machine to machine.
*
* Save the queue file name, so that the runtime error handler can clean up
* in case of problems.
*/
cleanup_handle = mail_stream_file(MAIL_QUEUE_INCOMING,
MAIL_CLASS_PUBLIC, MAIL_SERVICE_QUEUE);
cleanup_dst = cleanup_handle->stream;
cleanup_path = mystrdup(VSTREAM_PATH(cleanup_dst));
cleanup_queue_id = mystrdup(cleanup_handle->id);
if (msg_verbose)
msg_info("cleanup_service: open %s", cleanup_path);
/*
* If there is a time to get rid of spurious bounce/defer log files, this
* is it. The down side is that this costs performance for every message,
* while the probability of spurious bounce/defer log files is quite low.
* Perhaps we should put the queue file ID inside the defer and bounce
* files, so that the bounce and defer daemons can figure out if a file
* is a left-over from a previous message instance. For now, we play safe
* and check each time a new queue file is created.
*/
for (cpp = log_queues; *cpp; cpp++) {
if (mail_queue_remove(*cpp, cleanup_queue_id) == 0)
msg_warn("%s: removed spurious %s log", *cpp, cleanup_queue_id);
else if (errno != ENOENT)
msg_fatal("%s: remove %s log: %m", *cpp, cleanup_queue_id);
}
/*
* Send the queue id to the client. Read client processing options. If we
* can't read the client processing options we can pretty much forget
* about the whole operation.
*/
mail_print(cleanup_src, "%s", cleanup_queue_id);
if (mail_scan(src, "%d", &cleanup_flags) != 1) {
cleanup_errs |= CLEANUP_STAT_BAD;
cleanup_flags = 0;
}
/*
* If the client requests us to do the bouncing in case of problems,
* throw away the input only in case of real show-stopper errors, such as
* unrecognizable data (which should never happen) or insufficient space
* for the queue file (which will happen occasionally). Otherwise, throw
* away the input after any error. See the CLEANUP_OUT_OK() definition.
*/
if (cleanup_flags & CLEANUP_FLAG_BOUNCE) {
cleanup_err_mask =
(CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE | CLEANUP_STAT_SIZE);
} else {
cleanup_err_mask = ~0;
}
/*
* First, copy the envelope records to the queue file. Then, copy the
* message content (headers and body). Finally, attach any information
* extracted from message headers.
*/
cleanup_envelope();
if (CLEANUP_OUT_OK())
cleanup_message();
if (CLEANUP_OUT_OK())
cleanup_extracted();
/*
* Now that we have captured the entire message, see if there are any
* other errors. For example, if the message needs to be bounced for lack
* of recipients. We want to turn on the execute bits on a file only when
* we want the queue manager to process it.
*/
if (cleanup_recip == 0)
cleanup_errs |= CLEANUP_STAT_RCPT;
/*
* If there are no errors, be very picky about queue file write errors
* because we are about to tell the sender that it can throw away its
* copy of the message.
*/
if (cleanup_errs == 0)
cleanup_errs |= mail_stream_finish(cleanup_handle);
else
mail_stream_cleanup(cleanup_handle);
cleanup_handle = 0;
cleanup_dst = 0;
/*
* If there was an error, remove the queue file, after optionally
* bouncing it. An incomplete message should never be bounced: it was
* canceled by the client, and may not even have an address to bounce to.
* That last test is redundant but we keep it just for robustness.
*
* If we are responsible for bouncing a message, we must must report success
* to the client unless the bounce message file could not be written
* (which is just as bad as not being able to write the message queue
* file in the first place).
*
* Do not log the arrival of a message that will be bounced by the client.
*/
#define CAN_BOUNCE() \
((cleanup_errs & (CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE)) == 0 \
&& cleanup_sender != 0 \
&& (cleanup_flags & CLEANUP_FLAG_BOUNCE) != 0)
if (cleanup_errs) {
if (CAN_BOUNCE()) {
if (bounce_append(BOUNCE_FLAG_CLEAN,
cleanup_queue_id, cleanup_recip ?
cleanup_recip : "", "cleanup", cleanup_time,
"%s", cleanup_strerror(cleanup_errs)) == 0
&& bounce_flush(BOUNCE_FLAG_CLEAN,
MAIL_QUEUE_INCOMING,
cleanup_queue_id, cleanup_sender) == 0) {
cleanup_errs = 0;
} else {
msg_warn("%s: bounce message failure", cleanup_queue_id);
cleanup_errs = CLEANUP_STAT_WRITE;
}
}
if (REMOVE(cleanup_path))
msg_warn("remove %s: %m", cleanup_path);
}
/*
* Report the completion status back to the client. Order of operations
* matters very much: make sure that our queue file will not be deleted
* by the error handler AFTER we have taken responsibility for delivery.
* Better to deliver twice than to lose mail.
*/
junk = cleanup_path;
cleanup_path = 0; /* don't delete upon error */
mail_print(cleanup_src, "%d", cleanup_errs);/* we're committed now */
if (msg_verbose)
msg_info("cleanup_service: status %d", cleanup_errs);
myfree(junk);
/*
* Cleanup internal state. This is simply complementary to the
* initializations at the beginning of this routine.
*/
cleanup_state_free();
}
/* cleanup_all - callback for the runtime error handler */
static void cleanup_all(void)
{
if (cleanup_path && REMOVE(cleanup_path))
msg_warn("cleanup_all: remove %s: %m", cleanup_path);
}
/* cleanup_sig - cleanup after signal */
static void cleanup_sig(int sig)
{
cleanup_all();
exit(sig);
}
/* pre_jail_init - initialize before entering the chroot jail */
static void pre_jail_init(void)
{
if (*var_canonical_maps)
cleanup_comm_canon_maps =
maps_create(VAR_CANONICAL_MAPS, var_canonical_maps);
if (*var_send_canon_maps)
cleanup_send_canon_maps =
maps_create(VAR_SEND_CANON_MAPS, var_send_canon_maps);
if (*var_rcpt_canon_maps)
cleanup_rcpt_canon_maps =
maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps);
if (*var_virtual_maps)
cleanup_virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps);
if (*var_masq_domains)
cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n");
}
/* post_jail_init - initialize after entering the chroot jail */
static void post_jail_init(void)
{
/*
* Optionally set the file size resource limit. XXX This limits the
* message content to somewhat less than requested, because the total
* queue file size also includes envelope information. Unless people set
* really low limit, the difference is going to matter only when a queue
* file has lots of recipients.
*/
if (var_message_limit > 0)
set_file_limit((off_t) var_message_limit);
}
/* main - the main program */
int main(int argc, char **argv)
{
static CONFIG_INT_TABLE int_table[] = {
VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0,
VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
0,
};
static CONFIG_STR_TABLE str_table[] = {
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
VAR_SEND_CANON_MAPS, DEF_SEND_CANON_MAPS, &var_send_canon_maps, 0, 0,
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
VAR_MASQ_DOMAINS, DEF_MASQ_DOMAINS, &var_masq_domains, 0, 0,
VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0,
VAR_MASQ_EXCEPTIONS, DEF_MASQ_EXCEPTIONS, &var_masq_exceptions, 0, 0,
0,
};
/*
* Clean up an incomplete queue file in case of a fatal run-time error,
* or after receiving SIGTERM from the master at shutdown time.
*/
signal(SIGTERM, cleanup_sig);
msg_cleanup(cleanup_all);
/*
* Pass control to the single-threaded service skeleton.
*/
single_server_main(argc, argv, cleanup_service,
MAIL_SERVER_INT_TABLE, int_table,
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
MAIL_SERVER_POST_INIT, post_jail_init,
0);
}

160
postfix/cleanup/cleanup.h Normal file
View File

@@ -0,0 +1,160 @@
/*++
/* NAME
/* cleanup 3h
/* SUMMARY
/* canonicalize and enqueue message
/* SYNOPSIS
/* #include "cleanup.h"
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
/*
* Global library.
*/
#include <maps.h>
#include <tok822.h>
#include <been_here.h>
#include <mail_stream.h>
/*
* These state variables are accessed by many functions, and there is only
* one instance of each. Rather than passing around lots and lots of
* parameters, or passing them around as part of a huge structure, we just
* make the variables global, because that is what they are.
*/
extern VSTRING *cleanup_inbuf; /* read buffer */
extern VSTRING *cleanup_temp1; /* scratch buffer, local use only */
extern VSTRING *cleanup_temp2; /* scratch buffer, local use only */
extern VSTREAM *cleanup_src; /* current input stream */
extern VSTREAM *cleanup_dst; /* current output stream */
extern MAIL_STREAM *cleanup_handle; /* mail stream handle */
extern char *cleanup_queue_id; /* queue file basename */
extern time_t cleanup_time; /* posting time */
extern char *cleanup_fullname; /* envelope sender full name */
extern char *cleanup_sender; /* envelope sender address */
extern char *cleanup_from; /* From: address */
extern char *cleanup_resent_from; /* Resent-From: address */
extern char *cleanup_recip; /* envelope recipient address */
extern char *cleanup_return_receipt; /* return-receipt address */
extern char *cleanup_errors_to; /* errors-to address */
extern int cleanup_flags; /* processing options */
extern int cleanup_errs; /* any badness experienced */
extern int cleanup_err_mask; /* allowed badness */
extern VSTRING *cleanup_header_buf; /* multi-record header */
extern int cleanup_headers_seen; /* which headers were seen */
extern int cleanup_hop_count; /* count of received: headers */
extern ARGV *cleanup_recipients; /* recipients from regular headers */
extern ARGV *cleanup_resent_recip; /* recipients from resent headers */
extern char *cleanup_resent; /* any resent- header seen */
extern BH_TABLE *cleanup_dups; /* recipient dup filter */
/*
* Mappings.
*/
extern MAPS *cleanup_comm_canon_maps;
extern MAPS *cleanup_send_canon_maps;
extern MAPS *cleanup_rcpt_canon_maps;
extern MAPS *cleanup_virtual_maps;
extern ARGV *cleanup_masq_domains;
/*
* Saved queue file name, so the file can be removed in case of a fatal
* run-time error.
*/
extern char *cleanup_path;
/*
* Tunable parameters.
*/
extern int var_bounce_limit; /* max bounce message size */
extern int var_message_limit; /* max message size */
extern int var_hopcount_limit; /* max mailer hop count */
extern int var_header_limit; /* max header length */
/*
* cleanup_state.c
*/
extern void cleanup_state_alloc(void);
extern void cleanup_state_free(void);
/*
* cleanup_out.c
*/
extern void cleanup_out(int, char *, int);
extern void cleanup_out_string(int, char *);
extern void cleanup_out_format(int, char *,...);
#define CLEANUP_OUT_BUF(t, b) \
cleanup_out((t), vstring_str((b)), VSTRING_LEN((b)))
#define CLEANUP_OUT_OK() \
((cleanup_errs & cleanup_err_mask) == 0)
/*
* cleanup_envelope.c
*/
extern void cleanup_envelope(void);
/*
* cleanup_message.c
*/
extern void cleanup_message(void);
/*
* cleanup_extracted.c
*/
extern void cleanup_extracted(void);
/*
* cleanup_skip.o
*/
extern void cleanup_skip(void);
/*
* cleanup_rewrite.c
*/
extern void cleanup_rewrite_external(VSTRING *, const char *);
extern void cleanup_rewrite_internal(VSTRING *, const char *);
extern void cleanup_rewrite_tree(TOK822 *);
/*
* cleanup_map11.c
*/
extern void cleanup_map11_external(VSTRING *, MAPS *);
extern void cleanup_map11_internal(VSTRING *, MAPS *);
extern void cleanup_map11_tree(TOK822 *, MAPS *);
/*
* cleanup_map1n.c
*/
ARGV *cleanup_map1n_internal(char *, MAPS *);
/*
* cleanup_masquerade.c
*/
extern void cleanup_masquerade_external(VSTRING *, ARGV *);
extern void cleanup_masquerade_internal(VSTRING *, ARGV *);
extern void cleanup_masquerade_tree(TOK822 *, ARGV *);
/*
* Cleanup_recipient.c
*/
extern void cleanup_out_recipient(char *);
/* 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
/*--*/

View File

@@ -0,0 +1,132 @@
/*++
/* NAME
/* cleanup_envelope 3
/* SUMMARY
/* process envelope segment
/* SYNOPSIS
/* #include <cleanup.h>
/*
/* void cleanup_envelope()
/* DESCRIPTION
/* This module processes the envelope segment of a mail message.
/* While copying records from input to output it validates the
/* message structure, rewrites sender/recipient addresses
/* to canonical form, and expands recipients according to
/* entries in the virtual table.
/* 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 <string.h>
#include <stdlib.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <mymalloc.h>
/* Global library. */
#include <record.h>
#include <rec_type.h>
#include <cleanup_user.h>
#include <tok822.h>
#include <mail_params.h>
/* Application-specific. */
#include "cleanup.h"
#define STR vstring_str
/* cleanup_envelope - process envelope segment */
void cleanup_envelope(void)
{
VSTRING *clean_addr = vstring_alloc(100);
int type = 0;
/*
* The message content size record goes first, so it can easily be
* updated in place. This information takes precedence over any size
* estimate provided by the client. Size goes first so that it it easy to
* produce queue file reports.
*/
cleanup_out_format(REC_TYPE_SIZE, REC_TYPE_SIZE_FORMAT, 0L);
/*
* XXX Rely on the front-end programs to enforce record size limits.
*/
while (CLEANUP_OUT_OK()) {
if ((type = rec_get(cleanup_src, cleanup_inbuf, 0)) < 0) {
cleanup_errs |= CLEANUP_STAT_BAD;
break;
}
if (type == REC_TYPE_MESG) {
if (cleanup_sender == 0 || cleanup_time == 0) {
msg_warn("missing sender or time envelope record");
cleanup_errs |= CLEANUP_STAT_BAD;
}
break;
}
if (strchr(REC_TYPE_ENVELOPE, type) == 0) {
msg_warn("unexpected record type %d in envelope", type);
cleanup_errs |= CLEANUP_STAT_BAD;
break;
}
if (msg_verbose)
msg_info("envelope %c %s", type, STR(cleanup_inbuf));
if (type == REC_TYPE_TIME) {
cleanup_time = atol(STR(cleanup_inbuf));
CLEANUP_OUT_BUF(type, cleanup_inbuf);
} else if (type == REC_TYPE_FULL) {
cleanup_fullname = mystrdup(STR(cleanup_inbuf));
} else if (type == REC_TYPE_FROM) {
cleanup_rewrite_internal(clean_addr, STR(cleanup_inbuf));
if (cleanup_send_canon_maps)
cleanup_map11_internal(clean_addr, cleanup_send_canon_maps);
if (cleanup_comm_canon_maps)
cleanup_map11_internal(clean_addr, cleanup_comm_canon_maps);
if (cleanup_masq_domains)
cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
CLEANUP_OUT_BUF(type, clean_addr);
if (cleanup_sender == 0)
cleanup_sender = mystrdup(STR(clean_addr));
} else if (type == REC_TYPE_RCPT) {
cleanup_rewrite_internal(clean_addr, *STR(cleanup_inbuf) ?
STR(cleanup_inbuf) : var_empty_addr);
if (cleanup_rcpt_canon_maps)
cleanup_map11_internal(clean_addr, cleanup_rcpt_canon_maps);
if (cleanup_comm_canon_maps)
cleanup_map11_internal(clean_addr, cleanup_comm_canon_maps);
cleanup_out_recipient(STR(clean_addr));
if (cleanup_recip == 0)
cleanup_recip = mystrdup(STR(clean_addr));
} else {
CLEANUP_OUT_BUF(type, cleanup_inbuf);
}
}
/*
* XXX Keep reading in case of trouble, so that the sender is ready to
* receive our status report.
*/
if (!CLEANUP_OUT_OK())
if (type >= 0)
cleanup_skip();
vstring_free(clean_addr);
}

View File

@@ -0,0 +1,116 @@
/*++
/* NAME
/* cleanup_extracted 3
/* SUMMARY
/* process extracted segment
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_extracted(void)
/* DESCRIPTION
/* This module processes message segments for information
/* extracted from message content. It requires that the input
/* contains no extracted information, and writes extracted
/* information records to the output.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
#include <mymalloc.h>
/* Global library. */
#include <cleanup_user.h>
#include <record.h>
#include <rec_type.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_extracted - generate segment with header-extracted information */
void cleanup_extracted(void)
{
ARGV *rcpt;
char **cpp;
int type;
/*
* Do not complain in case of premature EOF - most likely the client
* aborted the operation.
*
* XXX Rely on the front-end programs to enforce record size limits.
*/
if ((type = rec_get(cleanup_src, cleanup_inbuf, 0)) < 0) {
cleanup_errs |= CLEANUP_STAT_BAD;
return;
}
/*
* Require that the client sends an empty record group. It is OUR job to
* extract information from message headers. Clients can specify options
* via special message header lines.
*
* XXX Keep reading in case of trouble, so that the sender is ready for our
* status report.
*/
if (type != REC_TYPE_END) {
msg_warn("unexpected record type %d in extracted segment", type);
cleanup_errs |= CLEANUP_STAT_BAD;
if (type >= 0)
cleanup_skip();
return;
}
/*
* Start the extracted segment.
*/
cleanup_out_string(REC_TYPE_XTRA, "");
/*
* Always emit Return-Receipt-To and Errors-To records, and always emit
* them ahead of extracted recipients, so that the queue manager does not
* waste lots of time searching through large numbers of recipient
* addresses.
*/
cleanup_out_string(REC_TYPE_RRTO, cleanup_return_receipt ?
cleanup_return_receipt : "");
cleanup_out_string(REC_TYPE_ERTO, cleanup_errors_to ?
cleanup_errors_to : cleanup_sender);
/*
* Optionally account for missing recipient envelope records.
*/
if (cleanup_recip == 0) {
rcpt = (cleanup_resent[0] ? cleanup_resent_recip : cleanup_recipients);
argv_terminate(rcpt);
for (cpp = rcpt->argv; CLEANUP_OUT_OK() && *cpp; cpp++)
cleanup_out_recipient(*cpp);
if (rcpt->argv[0])
cleanup_recip = mystrdup(rcpt->argv[0]);
}
/*
* Terminate the extracted segment.
*/
cleanup_out_string(REC_TYPE_END, "");
}

View File

@@ -0,0 +1,158 @@
/*++
/* NAME
/* cleanup_map11 3
/* SUMMARY
/* one-to-one mapping
/* SYNOPSIS
/* #include <cleanup.h>
/*
/* void cleanup_map11_external(addr, maps)
/* VSTRING *addr;
/* MAPS *maps;
/*
/* void cleanup_map11_internal(addr, maps)
/* VSTRING *addr;
/* MAPS *maps;
/*
/* void cleanup_map11_tree(tree, maps)
/* TOK822 *tree;
/* MAPS *maps;
/* DESCRIPTION
/* This module performs one-to-one map lookups.
/*
/* If an address has a mapping, the lookup result is
/* subjected to another iteration of rewriting and mapping.
/* Recursion continues until an address maps onto itself,
/* or until an unreasonable recursion level is reached.
/*
/* cleanup_map11_external() looks up the external (quoted) string
/* form of an address in the maps specified via the \fImaps\fR argument.
/*
/* cleanup_map11_internal() is a wrapper around the
/* cleanup_map11_external() routine that transforms from
/* internal (quoted) string form to external form and back.
/*
/* cleanup_map11_tree() is a wrapper around the
/* cleanup_map11_external() routine that transforms from
/* internal parse tree form to external form and back.
/* DIAGNOSTICS
/* Recoverable errors: the global \fIcleanup_errs\fR flag is updated.
/* SEE ALSO
/* mail_addr_find(3) address lookups
/* mail_addr_map(3) address mappings
/* 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 <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <dict.h>
#include <mymalloc.h>
/* Global library. */
#include <cleanup_user.h>
#include <mail_addr_map.h>
#include <quote_822_local.h>
/* Application-specific. */
#include "cleanup.h"
#define STR vstring_str
#define MAX_RECURSION 10
/* cleanup_map11_external - one-to-one table lookups */
void cleanup_map11_external(VSTRING *addr, MAPS *maps)
{
int count;
int expand_to_self;
ARGV *new_addr;
char *saved_addr;
/*
* Produce sensible output even in the face of a recoverable error. This
* simplifies error recovery considerably because we can do delayed error
* checking in one place, instead of having error handling code all over
* the place.
*/
for (count = 0; count < MAX_RECURSION; count++) {
if ((new_addr = mail_addr_map(maps, STR(addr))) != 0) {
if (new_addr->argc > 1)
msg_warn("multi-valued %s entry for %s",
maps->title, STR(addr));
saved_addr = mystrdup(STR(addr));
vstring_strcpy(addr, new_addr->argv[0]);
expand_to_self = !strcasecmp(saved_addr, STR(addr));
myfree(saved_addr);
argv_free(new_addr);
if (expand_to_self)
return;
} else if (dict_errno != 0) {
msg_warn("%s: %s map lookup problem for %s",
cleanup_queue_id, maps->title, STR(addr));
cleanup_errs |= CLEANUP_STAT_WRITE;
return;
} else {
return;
}
}
msg_warn("%s: unreasonable %s map nesting for %s",
cleanup_queue_id, maps->title, STR(addr));
}
/* cleanup_map11_tree - rewrite address node */
void cleanup_map11_tree(TOK822 *tree, MAPS *maps)
{
VSTRING *temp = vstring_alloc(100);
/*
* Produce sensible output even in the face of a recoverable error. This
* simplifies error recovery considerably because we can do delayed error
* checking in one place, instead of having error handling code all over
* the place.
*/
tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
cleanup_map11_external(temp, maps);
tok822_free_tree(tree->head);
tree->head = tok822_scan(STR(temp), &tree->tail);
vstring_free(temp);
}
/* cleanup_map11_internal - rewrite address internal form */
void cleanup_map11_internal(VSTRING *addr, MAPS *maps)
{
VSTRING *temp = vstring_alloc(100);
/*
* Produce sensible output even in the face of a recoverable error. This
* simplifies error recovery considerably because we can do delayed error
* checking in one place, instead of having error handling code all over
* the place.
*/
quote_822_local(temp, STR(addr));
cleanup_map11_external(temp, maps);
unquote_822_local(addr, STR(temp));
vstring_free(temp);
}

View File

@@ -0,0 +1,133 @@
/*++
/* NAME
/* cleanup_map1n 3
/* SUMMARY
/* one-to-many address mapping
/* SYNOPSIS
/* #include <cleanup.h>
/*
/* ARGV *cleanup_map1n_internal(addr)
/* char *addr;
/* DESCRIPTION
/* This module implements one-to-many table mapping via table lookup.
/* The process is recursive. The recursion terminates when the
/* left-hand side appears in its own expansion, or when a maximal
/* nesting level is reached.
/*
/* cleanup_map1n_internal() is the interface for addresses in
/* internal (unquoted) form.
/* DIAGNOSTICS
/* Recoverable errors: the global \fIcleanup_errs\fR flag is updated.
/* SEE ALSO
/* mail_addr_map(3) address mappings
/* mail_addr_find(3) address lookups
/* 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 <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <mymalloc.h>
#include <msg.h>
#include <argv.h>
#include <vstring.h>
#include <dict.h>
/* Global library. */
#include <mail_addr_map.h>
#include <cleanup_user.h>
#include <quote_822_local.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_map1n_internal - one-to-many table lookups */
ARGV *cleanup_map1n_internal(char *addr, MAPS *maps)
{
ARGV *argv;
ARGV *lookup;
int count;
int i;
int arg;
int expand_to_self;
char *saved_lhs;
/*
* Initialize.
*/
argv = argv_alloc(1);
argv_add(argv, addr, ARGV_END);
argv_terminate(argv);
/*
* Rewrite the address vector in place. With each map lookup result,
* split it into separate addresses, then rewrite and flatten each
* address, and repeat the process. Beware: argv is being changed, so we
* must index the array explicitly, instead of running along it with a
* pointer.
*/
#define UPDATE(ptr,new) { myfree(ptr); ptr = mystrdup(new); }
#define MAX_RECURSION 1000
#define MAX_EXPANSION 1000
#define STR vstring_str
for (expand_to_self = 0, arg = 0; arg < argv->argc; arg++) {
if (argv->argc > MAX_EXPANSION) {
msg_warn("%s: unreasonable %s map expansion size for %s",
cleanup_queue_id, maps->title, addr);
break;
}
for (count = 0; /* void */ ; count++) {
if (count >= MAX_RECURSION) {
msg_warn("%s: unreasonable %s map nesting for %s",
cleanup_queue_id, maps->title, addr);
break;
}
if ((lookup = mail_addr_map(maps, argv->argv[arg])) != 0) {
saved_lhs = mystrdup(argv->argv[arg]);
for (i = 0; i < lookup->argc; i++) {
unquote_822_local(cleanup_temp1, lookup->argv[i]);
if (strcasecmp(saved_lhs, STR(cleanup_temp1)) == 0)
expand_to_self = 1;
if (i == 0) {
UPDATE(argv->argv[arg], STR(cleanup_temp1));
} else {
argv_add(argv, STR(cleanup_temp1), ARGV_END);
argv_terminate(argv);
}
}
myfree(saved_lhs);
argv_free(lookup);
if (expand_to_self)
return (argv);
} else if (dict_errno != 0) {
msg_warn("%s: %s map lookup problem for %s",
cleanup_queue_id, maps->title, addr);
cleanup_errs |= CLEANUP_STAT_WRITE;
return (argv);
} else {
break;
}
}
}
return (argv);
}

View File

@@ -0,0 +1,173 @@
/*++
/* NAME
/* cleanup_masquerade 3
/* SUMMARY
/* address masquerading
/* SYNOPSIS
/* #include <cleanup.h>
/*
/* void cleanup_masquerade_external(addr, masq_domains)
/* VSTRING *addr;
/* ARGV *masq_domains;
/*
/* void cleanup_masquerade_internal(addr, masq_domains)
/* VSTRING *addr;
/* ARGV *masq_domains;
/*
/* void cleanup_masquerade_tree(tree, masq_domains)
/* TOK822 *tree;
/* ARGV *masq_domains;
/* DESCRIPTION
/* This module masquerades addresses, that is, it strips subdomains
/* below domain names that are listed in the masquerade_domains
/* configuration parameter, except for user names listed in the
/* masquerade_exceptions configuration parameter.
/*
/* cleanup_masquerade_external() rewrites the external (quoted) string
/* form of an address.
/*
/* cleanup_masquerade_internal() is a wrapper around the
/* cleanup_masquerade_external() routine that transforms from
/* internal (quoted) string form to external form and back.
/*
/* cleanup_masquerade_tree() is a wrapper around the
/* cleanup_masquerade_external() routine that transforms from
/* internal parse tree form to external form and back.
/* DIAGNOSTICS
/* 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 <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <argv.h>
#include <htable.h>
#include <mymalloc.h>
#include <stringops.h>
/* Global library. */
#include <mail_params.h>
#include <tok822.h>
#include <quote_822_local.h>
/* Application-specific. */
#include "cleanup.h"
#define STR vstring_str
/* cleanup_masquerade_external - masquerade address external form */
void cleanup_masquerade_external(VSTRING *addr, ARGV *masq_domains)
{
char *domain;
int domain_len;
char **masqp;
int masq_len;
char *parent;
/* Stuff for excluded names. */
static HTABLE *masq_except_table = 0;
char *saved_names;
char *name;
char *ptr;
int excluded;
/*
* First time, build a lookup table for excluded names.
*/
if (*var_masq_exceptions && masq_except_table == 0) {
masq_except_table = htable_create(5);
ptr = saved_names = mystrdup(var_masq_exceptions);
while ((name = mystrtok(&ptr, ", \t\r\n")) != 0)
htable_enter(masq_except_table, name, (char *) 0);
myfree(saved_names);
}
/*
* Find the domain part.
*/
if ((domain = strrchr(STR(addr), '@')) == 0)
return;
domain += 1;
domain_len = strlen(domain);
/*
* Don't masquerade excluded names (regardless of domain).
*/
if (masq_except_table) {
name = mystrndup(STR(addr), domain - 1 - STR(addr));
excluded = (htable_locate(masq_except_table, name) != 0);
myfree(name);
if (excluded)
return;
}
/*
* If any parent domain matches the list of masquerade domains, replace
* the domain in the address and terminate. If the domain matches a
* masquerade domain, leave it alone. Order of specification matters.
*/
for (masqp = masq_domains->argv; *masqp; masqp++) {
masq_len = strlen(*masqp);
if (masq_len == domain_len) {
if (strcasecmp(*masqp, domain) == 0)
break;
} else if (masq_len < domain_len) {
parent = domain + domain_len - masq_len;
if (parent[-1] == '.' && strcasecmp(*masqp, parent) == 0) {
if (msg_verbose)
msg_info("masquerade: %s -> %s", domain, *masqp);
vstring_truncate(addr, domain - STR(addr));
vstring_strcat(addr, *masqp);
break;
}
}
}
}
/* cleanup_masquerade_tree - masquerade address node */
void cleanup_masquerade_tree(TOK822 *tree, ARGV *masq_domains)
{
VSTRING *temp = vstring_alloc(100);
tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
cleanup_masquerade_external(temp, masq_domains);
tok822_free_tree(tree->head);
tree->head = tok822_scan(STR(temp), &tree->tail);
vstring_free(temp);
}
/* cleanup_masquerade_internal - masquerade address internal form */
void cleanup_masquerade_internal(VSTRING *addr, ARGV *masq_domains)
{
VSTRING *temp = vstring_alloc(100);
quote_822_local(temp, STR(addr));
cleanup_masquerade_external(temp, masq_domains);
unquote_822_local(addr, STR(temp));
vstring_free(temp);
}

View File

@@ -0,0 +1,491 @@
/*++
/* NAME
/* cleanup_message 3
/* SUMMARY
/* process message segment
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_message(void)
/* DESCRIPTION
/* This module processes message content segments.
/* While copying records from input to output, it validates
/* the input, rewrites sender/recipient addresses to canonical
/* form, inserts missing message headers, and extracts information
/* from message headers to be used later when generating the extracted
/* output segment.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
#include <split_at.h>
#include <mymalloc.h>
/* Global library. */
#include <record.h>
#include <rec_type.h>
#include <cleanup_user.h>
#include <tok822.h>
#include <header_opts.h>
#include <quote_822_local.h>
#include <mail_params.h>
#include <mail_date.h>
#include <mail_addr.h>
#include <is_header.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_out_header - output one header as a bunch of records */
static void cleanup_out_header(void)
{
char *start = vstring_str(cleanup_header_buf);
char *line;
char *next_line;
/*
* Prepend a tab to continued header lines that went through the address
* rewriting machinery. See cleanup_fold_header() below for the form of
* such header lines. NB: This code destroys the header. We could try to
* avoid clobbering it, but we're not going to use the data any further.
*/
for (line = start; line; line = next_line) {
next_line = split_at(line, '\n');
if (line == start || ISSPACE(*line)) {
cleanup_out_string(REC_TYPE_NORM, line);
} else {
cleanup_out_format(REC_TYPE_NORM, "\t%s", line);
}
}
}
/* cleanup_fold_header - wrap address list header */
static void cleanup_fold_header(void)
{
char *start_line = vstring_str(cleanup_header_buf);
char *end_line;
char *next_line;
char *line;
/*
* A rewritten address list contains one address per line. The code below
* replaces newlines by spaces, to fit as many addresses on a line as
* possible (without rearranging the order of addresses). Prepending
* white space to the beginning of lines is delegated to the output
* routine.
*/
for (line = start_line; line != 0; line = next_line) {
end_line = line + strcspn(line, "\n");
if (line > start_line) {
if (end_line - start_line < 70) { /* TAB counts as one */
line[-1] = ' ';
} else {
start_line = line;
}
}
next_line = *end_line ? end_line + 1 : 0;
}
cleanup_out_header();
}
/* cleanup_extract_internal - save unquoted copy of extracted address */
static char *cleanup_extract_internal(VSTRING *buffer, TOK822 *addr)
{
/*
* A little routine to stash away a copy of an address that we extracted
* from a message header line.
*/
tok822_internalize(buffer, addr->head, TOK822_STR_DEFL);
return (mystrdup(vstring_str(buffer)));
}
/* cleanup_rewrite_sender - sender address rewriting */
static void cleanup_rewrite_sender(HEADER_OPTS *hdr_opts)
{
TOK822 *tree;
TOK822 **addr_list;
TOK822 **tpp;
if (msg_verbose)
msg_info("rewrite_sender: %s", hdr_opts->name);
/*
* Parse the header line, rewrite each address found, save copies of
* sender addresses, and regenerate the header line. Finally, pipe the
* result through the header line folding routine.
*/
tree = tok822_parse(vstring_str(cleanup_header_buf)
+ strlen(hdr_opts->name) + 1);
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
if (cleanup_send_canon_maps)
cleanup_map11_tree(*tpp, cleanup_send_canon_maps);
if (cleanup_comm_canon_maps)
cleanup_map11_tree(*tpp, cleanup_comm_canon_maps);
if (cleanup_masq_domains)
cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
if (hdr_opts->type == HDR_FROM && cleanup_from == 0)
cleanup_from = cleanup_extract_internal(cleanup_header_buf, *tpp);
if (hdr_opts->type == HDR_RESENT_FROM && cleanup_resent_from == 0)
cleanup_resent_from =
cleanup_extract_internal(cleanup_header_buf, *tpp);
}
vstring_sprintf(cleanup_header_buf, "%s: ", hdr_opts->name);
tok822_externalize(cleanup_header_buf, tree, TOK822_STR_HEAD);
myfree((char *) addr_list);
tok822_free_tree(tree);
if ((hdr_opts->flags & HDR_OPT_DROP) == 0)
cleanup_fold_header();
}
/* cleanup_rewrite_recip - recipient address rewriting */
static void cleanup_rewrite_recip(HEADER_OPTS *hdr_opts)
{
TOK822 *tree;
TOK822 **addr_list;
TOK822 **tpp;
if (msg_verbose)
msg_info("rewrite_recip: %s", hdr_opts->name);
/*
* Parse the header line, rewrite each address found, save copies of
* recipient addresses, and regenerate the header line. Finally, pipe the
* result through the header line folding routine.
*/
tree = tok822_parse(vstring_str(cleanup_header_buf)
+ strlen(hdr_opts->name) + 1);
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
if (cleanup_rcpt_canon_maps)
cleanup_map11_tree(*tpp, cleanup_rcpt_canon_maps);
if (cleanup_comm_canon_maps)
cleanup_map11_tree(*tpp, cleanup_comm_canon_maps);
if (cleanup_masq_domains)
cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
if (hdr_opts->type == HDR_RETURN_RECEIPT_TO && !cleanup_return_receipt)
cleanup_return_receipt =
cleanup_extract_internal(cleanup_header_buf, *tpp);
if (hdr_opts->type == HDR_ERRORS_TO && !cleanup_errors_to)
cleanup_errors_to =
cleanup_extract_internal(cleanup_header_buf, *tpp);
tok822_internalize(cleanup_temp1, tpp[0]->head, TOK822_STR_DEFL);
if (cleanup_recip == 0 && (hdr_opts->flags & HDR_OPT_EXTRACT) != 0)
argv_add((hdr_opts->flags & HDR_OPT_RR) ?
cleanup_resent_recip : cleanup_recipients,
vstring_str(cleanup_temp1), (char *) 0);
}
vstring_sprintf(cleanup_header_buf, "%s: ", hdr_opts->name);
tok822_externalize(cleanup_header_buf, tree, TOK822_STR_HEAD);
myfree((char *) addr_list);
tok822_free_tree(tree);
if ((hdr_opts->flags & HDR_OPT_DROP) == 0)
cleanup_fold_header();
}
/* cleanup_header - process one complete header line */
static void cleanup_header(void)
{
HEADER_OPTS *hdr_opts;
/*
* If this is an "unknown" header, just copy it to the output without
* even bothering to fold long lines. XXX Should split header lines that
* do not fit a REC_TYPE_NORM record.
*/
if ((hdr_opts = header_opts_find(vstring_str(cleanup_header_buf))) == 0) {
cleanup_out_header();
}
/*
* Known header. Remember that we have seen at least one. Find out what
* we should do with this header: delete, count, rewrite. Note that we
* should examine headers even when they will be deleted from the output,
* because the addresses in those headers might be needed elsewhere.
*/
else {
cleanup_headers_seen |= (1 << hdr_opts->type);
if (hdr_opts->type == HDR_MESSAGE_ID)
msg_info("%s: message-id=%s", cleanup_queue_id,
vstring_str(cleanup_header_buf) + strlen(hdr_opts->name) + 2);
if (hdr_opts->type == HDR_RESENT_MESSAGE_ID)
msg_info("%s: resent-message-id=%s", cleanup_queue_id,
vstring_str(cleanup_header_buf) + strlen(hdr_opts->name) + 2);
if (hdr_opts->type == HDR_RECEIVED)
if (++cleanup_hop_count >= var_hopcount_limit)
cleanup_errs |= CLEANUP_STAT_HOPS;
if (CLEANUP_OUT_OK()) {
if (hdr_opts->flags & HDR_OPT_RR)
cleanup_resent = "Resent-";
if (hdr_opts->flags & HDR_OPT_SENDER) {
cleanup_rewrite_sender(hdr_opts);
} else if (hdr_opts->flags & HDR_OPT_RECIP) {
cleanup_rewrite_recip(hdr_opts);
} else if ((hdr_opts->flags & HDR_OPT_DROP) == 0) {
cleanup_out_header();
}
}
}
}
/* cleanup_missing_headers - insert missing message headers */
static void cleanup_missing_headers(void)
{
char time_stamp[1024]; /* XXX locale dependent? */
struct tm *tp;
TOK822 *token;
char *from;
/*
* Add a missing Return-Path: header when the sender address is not
* empty. XXX Shouldn't this depend on the delivery transport being used?
* But, it is very tempting to use RFC822 as the basis for our canonical
* message representation. And, it is easy to delete an unwanted header.
*/
if (*cleanup_sender != 0
&& (cleanup_headers_seen & (1 << HDR_RETURN_PATH)) == 0) {
quote_822_local(cleanup_temp1, cleanup_sender);
cleanup_out_format(REC_TYPE_NORM, "Return-Path: <%s>",
vstring_str(cleanup_temp1));
}
/*
* Add a missing (Resent-)Message-Id: header. The message ID gives the
* time in GMT units, plus the local queue ID.
*/
if ((cleanup_headers_seen & (1 << (cleanup_resent[0] ?
HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) {
tp = gmtime(&cleanup_time);
strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp);
cleanup_out_format(REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>",
cleanup_resent, time_stamp, cleanup_queue_id, var_myhostname);
msg_info("%s: %smessage-id=<%s.%s@%s>",
cleanup_queue_id, *cleanup_resent ? "resent-" : "",
time_stamp, cleanup_queue_id, var_myhostname);
}
/*
* Add a missing (Resent-)Date: header. The date is in local time units,
* with the GMT offset at the end.
*/
if ((cleanup_headers_seen & (1 << (cleanup_resent[0] ?
HDR_RESENT_DATE : HDR_DATE))) == 0) {
cleanup_out_format(REC_TYPE_NORM, "%sDate: %s",
cleanup_resent, mail_date(cleanup_time));
}
/*
* Add a missing (Resent-)From: header. If a (Resent-)From: header is
* present, see if we need a (Resent-)Sender: header.
*/
#define NOT_SPECIAL_SENDER(addr) (*(addr) != 0 \
&& strcasecmp(addr, mail_addr_double_bounce()) != 0)
if ((cleanup_headers_seen & (1 << (cleanup_resent[0] ?
HDR_RESENT_FROM : HDR_FROM))) == 0) {
quote_822_local(cleanup_temp1, cleanup_sender);
vstring_sprintf(cleanup_temp2, "%sFrom: %s",
cleanup_resent, vstring_str(cleanup_temp1));
if (cleanup_fullname && *cleanup_fullname) {
vstring_strcat(cleanup_temp2, " (");
token = tok822_alloc(TOK822_COMMENT, cleanup_fullname);
tok822_externalize(cleanup_temp2, token, TOK822_STR_NONE);
tok822_free(token);
vstring_strcat(cleanup_temp2, ")");
}
CLEANUP_OUT_BUF(REC_TYPE_NORM, cleanup_temp2);
} else if ((cleanup_headers_seen & (1 << (cleanup_resent[0] ?
HDR_RESENT_SENDER : HDR_SENDER))) == 0
&& NOT_SPECIAL_SENDER(cleanup_sender)) {
from = (cleanup_resent[0] ? cleanup_resent_from : cleanup_from);
if (from == 0 || strcasecmp(cleanup_sender, from) != 0) {
quote_822_local(cleanup_temp1, cleanup_sender);
cleanup_out_format(REC_TYPE_NORM, "%sSender: %s",
cleanup_resent, vstring_str(cleanup_temp1));
}
}
}
/* cleanup_message - process message content segment */
void cleanup_message(void)
{
char *myname = "cleanup_message";
long mesg_offset;
long data_offset;
long xtra_offset;
int in_header;
char *start;
int type = 0;
/*
* Write a dummy start-of-content segment marker. We'll update it with
* real file offset information after reaching the end of the message
* content.
*/
if ((mesg_offset = vstream_ftell(cleanup_dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
cleanup_out_format(REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, 0);
if ((data_offset = vstream_ftell(cleanup_dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
/*
* An unannounced end-of-input condition most likely means that the
* client did not want to send this message after all. Don't complain,
* just stop generating any further output.
*
* XXX Rely on the front-end programs to enforce record size limits.
*/
in_header = 1;
while (CLEANUP_OUT_OK()) {
if ((type = rec_get(cleanup_src, cleanup_inbuf, 0)) < 0) {
cleanup_errs |= CLEANUP_STAT_BAD;
break;
}
if (strchr(REC_TYPE_CONTENT, type) == 0) {
msg_warn("%s: unexpected record type %d", myname, type);
cleanup_errs |= CLEANUP_STAT_BAD;
break;
}
start = vstring_str(cleanup_inbuf);
/*
* First, deal with header information that we have accumulated from
* previous input records. A whole record that starts with whitespace
* is a continuation of previous data.
*
* XXX Silently switch to body processing when some message header
* requires an unreasonable amount of storage, or when a message
* header record does not fit in a REC_TYPE_NORM type record.
*/
if (VSTRING_LEN(cleanup_header_buf) > 0) {
if (VSTRING_LEN(cleanup_header_buf) < var_header_limit
&& type == REC_TYPE_NORM && ISSPACE(*start)) {
VSTRING_ADDCH(cleanup_header_buf, '\n');
vstring_strcat(cleanup_header_buf, start);
continue;
}
/*
* No more input to append to this saved header. Do output
* processing and reset the saved header buffer.
*/
VSTRING_TERMINATE(cleanup_header_buf);
cleanup_header();
VSTRING_RESET(cleanup_header_buf);
}
/*
* Switch to body processing if we didn't read a header or if the
* saved header requires an unreasonable amount of storage. Generate
* missing headers. Add one blank line when the message headers are
* immediately followed by a non-empty message body.
*/
if (in_header
&& (VSTRING_LEN(cleanup_header_buf) >= var_header_limit
|| type != REC_TYPE_NORM
|| !is_header(start))) {
in_header = 0;
cleanup_missing_headers();
if (type != REC_TYPE_XTRA && *start)/* output blank line */
cleanup_out_string(REC_TYPE_NORM, "");
}
/*
* If this is a header record, save it until we know that the header
* is complete. If this is a body record, copy it to the output
* immediately.
*/
if (type == REC_TYPE_NORM || type == REC_TYPE_CONT) {
if (in_header) {
vstring_strcpy(cleanup_header_buf, start);
} else {
CLEANUP_OUT_BUF(type, cleanup_inbuf);
}
}
/*
* If we have reached the end of the message content segment, update
* the start-of-content marker, now that we know how large the
* message content segment is, and update the content size indicator
* at the beginning of the message envelope segment. vstream_fseek()
* implicitly flushes the stream, which may fail for various reasons.
*/
else if (type == REC_TYPE_XTRA) {
if ((xtra_offset = vstream_ftell(cleanup_dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
if (vstream_fseek(cleanup_dst, mesg_offset, SEEK_SET) < 0) {
msg_warn("%s: write queue file: %m", cleanup_queue_id);
if (errno == EFBIG)
cleanup_errs |= CLEANUP_STAT_SIZE;
else
cleanup_errs |= CLEANUP_STAT_WRITE;
break;
}
cleanup_out_format(REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, xtra_offset);
if (vstream_fseek(cleanup_dst, 0L, SEEK_SET) < 0)
msg_fatal("%s: vstream_fseek %s: %m", myname, cleanup_path);
cleanup_out_format(REC_TYPE_SIZE, REC_TYPE_SIZE_FORMAT,
xtra_offset - data_offset);
if (vstream_fseek(cleanup_dst, xtra_offset, SEEK_SET) < 0)
msg_fatal("%s: vstream_fseek %s: %m", myname, cleanup_path);
break;
}
/*
* This should never happen.
*/
else {
msg_panic("%s: unexpected record type: %d", myname, type);
}
}
/*
* Keep reading in case of problems, so that the sender is ready to
* receive our status report.
*/
if (CLEANUP_OUT_OK() == 0)
if (type >= 0)
cleanup_skip();
}

View File

@@ -0,0 +1,117 @@
/*++
/* NAME
/* cleanup_out 3
/* SUMMARY
/* record output support
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* int CLEANUP_OUT_OK()
/*
/* void cleanup_out(type, data, len)
/* int type;
/* char *data;
/* int len;
/*
/* void cleanup_out_string(type, str)
/* int type;
/* char *str;
/*
/* void CLEANUP_OUT_BUF(type, buf)
/* int type;
/* VSTRING *buf;
/*
/* void cleanup_out_format(type, format, ...)
/* int type;
/* char *format;
/* DESCRIPTION
/* This module writes records to the output stream.
/*
/* CLEANUP_OUT_OK() is a macro that evaluates to non-zero
/* as long as it makes sense to produce output. All output
/* routines below check for this condition.
/*
/* cleanup_out() is the main record output routine. It writes
/* one record of the specified type, with the specified data
/* and length to the output stream.
/*
/* cleanup_out_string() outputs one string as a record.
/*
/* CLEANUP_OUT_BUF() is an unsafe macro that outputs
/* one string buffer as a record.
/*
/* cleanup_out_format() formats its arguments and writes
/* the result as a record.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <errno.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
/* Global library. */
#include <record.h>
#include <rec_type.h>
#include <cleanup_user.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_out - output one single record */
void cleanup_out(int type, char *string, int len)
{
if (CLEANUP_OUT_OK()) {
if (rec_put(cleanup_dst, type, string, len) < 0) {
if (errno == EFBIG) {
msg_warn("queue file size limit exceeded");
cleanup_errs |= CLEANUP_STAT_SIZE;
} else {
msg_warn("%s: write queue file: %m", cleanup_queue_id);
cleanup_errs |= CLEANUP_STAT_WRITE;
}
}
}
}
/* cleanup_out_string - output string to one single record */
void cleanup_out_string(int type, char *string)
{
cleanup_out(type, string, strlen(string));
}
/* cleanup_out_format - output one formatted record */
void cleanup_out_format(int type, char *fmt,...)
{
static VSTRING *vp;
va_list ap;
if (vp == 0)
vp = vstring_alloc(100);
va_start(ap, fmt);
vstring_vsprintf(vp, fmt, ap);
va_end(ap);
CLEANUP_OUT_BUF(type, vp);
}

View File

@@ -0,0 +1,72 @@
/*++
/* NAME
/* cleanup_out_recipient 3
/* SUMMARY
/* envelope recipient output filter
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_out_recipient(recipient)
/* char *recipient;
/* DESCRIPTION
/* This module implements an envelope recipient output filter.
/*
/* cleanup_out_recipient() performs virtual table expansion
/* and recipient duplicate filtering, and appends the
/* resulting recipients to the output stream.
/* CONFIGURATION
/* .ad
/* .fi
/* .IP local_duplicate_filter_limit
/* Upper bound to the size of the recipient duplicate filter.
/* Zero means no limit; this may cause the mail system to
/* become stuck.
/* .IP virtual_maps
/* list of virtual address lookup tables.
/* 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 <argv.h>
/* Global library. */
#include <been_here.h>
#include <mail_params.h>
#include <rec_type.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_out_recipient - envelope recipient output filter */
void cleanup_out_recipient(char *recip)
{
ARGV *argv;
char **cpp;
if (cleanup_virtual_maps == 0) {
if (been_here_fixed(cleanup_dups, recip) == 0)
cleanup_out_string(REC_TYPE_RCPT, recip);
} else {
argv = cleanup_map1n_internal(recip, cleanup_virtual_maps);
for (cpp = argv->argv; *cpp; cpp++)
if (been_here_fixed(cleanup_dups, *cpp) == 0)
cleanup_out_string(REC_TYPE_RCPT, *cpp);
argv_free(argv);
}
}

View File

@@ -0,0 +1,99 @@
/*++
/* NAME
/* cleanup_rewrite 3
/* SUMMARY
/* address canonicalization
/* SYNOPSIS
/* #include <cleanup.h>
/*
/* void cleanup_rewrite_external(result, addr)
/* VSTRING *result;
/* const char *addr;
/*
/* void cleanup_rewrite_internal(result, addr)
/* VSTRING *result;
/* const char *addr;
/*
/* void cleanup_rewrite_tree(tree)
/* TOK822 *tree;
/* DESCRIPTION
/* This module rewrites addresses to canonical form, adding missing
/* domains and stripping source routes etc., and performs
/* \fIcanonical\fR map lookups to map addresses to official form.
/*
/* cleanup_rewrite_init() performs one-time initialization.
/*
/* cleanup_rewrite_external() rewrites the external (quoted) string
/* form of an address.
/*
/* cleanup_rewrite_internal() is a wrapper around the
/* cleanup_rewrite_external() routine that transforms from
/* internal (quoted) string form to external form and back.
/*
/* cleanup_rewrite_tree() is a wrapper around the
/* cleanup_rewrite_external() routine that transforms from
/* internal parse tree form to external form and back.
/* DIAGNOSTICS
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
/* Global library. */
#include <tok822.h>
#include <rewrite_clnt.h>
#include <quote_822_local.h>
/* Application-specific. */
#include "cleanup.h"
#define STR vstring_str
/* cleanup_rewrite_external - rewrite address external form */
void cleanup_rewrite_external(VSTRING *result, const char *addr)
{
rewrite_clnt(REWRITE_CANON, addr, result);
}
/* cleanup_rewrite_tree - rewrite address node */
void cleanup_rewrite_tree(TOK822 *tree)
{
VSTRING *temp = vstring_alloc(100);
tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
cleanup_rewrite_external(temp, STR(temp));
tok822_free_tree(tree->head);
tree->head = tok822_scan(STR(temp), &tree->tail);
vstring_free(temp);
}
/* cleanup_rewrite_internal - rewrite address internal form */
void cleanup_rewrite_internal(VSTRING *result, const char *addr)
{
VSTRING *temp = vstring_alloc(100);
quote_822_local(temp, addr);
cleanup_rewrite_external(temp, STR(temp));
unquote_822_local(result, STR(temp));
vstring_free(temp);
}

View File

@@ -0,0 +1,57 @@
/*++
/* NAME
/* cleanup_skip 3
/* SUMMARY
/* skip further input
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_skip(void)
/* DESCRIPTION
/* cleanup_skip() skips client input. This function is used after
/* detecting an error. The idea is to drain input from the client
/* so the client is ready to read the cleanup service status report.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <msg.h>
#include <vstream.h>
/* Global library. */
#include <record.h>
#include <rec_type.h>
/* Application-specific. */
#include "cleanup.h"
/* cleanup_skip - skip further client input */
void cleanup_skip(void)
{
int type;
msg_warn("skipping further client input");
/*
* XXX Rely on the front-end programs to enforce record size limits.
*/
while ((type = rec_get(cleanup_src, cleanup_inbuf, 0)) > 0
&& type != REC_TYPE_END)
/* void */ ;
}

View File

@@ -0,0 +1,138 @@
/*++
/* NAME
/* cleanup_state 3
/* SUMMARY
/* per-message state variables
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_state_alloc(void)
/*
/* void cleanup_state_free(void)
/* DESCRIPTION
/* This module maintains about two dozen global (ugh) state variables
/* that are used by many routines in the course of processing one
/* message. Using globals seems to make more sense than passing around
/* large parameter lists, or passing around a structure with a large
/* number of components. We can get away with this because we need only
/* one instance at a time.
/*
/* cleanup_state_alloc() initializes the per-message state variables.
/*
/* cleanup_state_free() cleans up.
/* 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 <vstring.h>
#include <vstream.h>
/* Global library. */
#include <been_here.h>
#include <mail_params.h>
/* Application-specific. */
#include "cleanup.h"
/*
* These variables are accessed by many functions, and there is only one
* instance of each. Rather than passing around lots and lots of parameters,
* or passing them around in a structure, we just make the variables global,
* because that is what they are.
*/
VSTRING *cleanup_inbuf; /* read buffer */
VSTRING *cleanup_temp1; /* scratch buffer, local use only */
VSTRING *cleanup_temp2; /* scratch buffer, local use only */
VSTREAM *cleanup_src; /* current input stream */
VSTREAM *cleanup_dst; /* current output stream */
MAIL_STREAM *cleanup_handle; /* mail stream handle */
char *cleanup_queue_id; /* queue file basename */
time_t cleanup_time; /* posting time */
char *cleanup_fullname; /* envelope sender full name */
char *cleanup_sender; /* envelope sender address */
char *cleanup_from; /* From: address */
char *cleanup_resent_from; /* Resent-From: address */
char *cleanup_recip; /* envelope recipient address */
char *cleanup_return_receipt; /* return-receipt address */
char *cleanup_errors_to; /* errors-to address */
int cleanup_flags; /* processing options */
int cleanup_errs; /* any badness experienced */
int cleanup_err_mask; /* allowed badness */
VSTRING *cleanup_header_buf; /* multi-record header */
int cleanup_headers_seen; /* which headers were seen */
int cleanup_hop_count; /* count of received: headers */
ARGV *cleanup_recipients; /* recipients from regular headers */
ARGV *cleanup_resent_recip; /* recipients from resent headers */
char *cleanup_resent; /* any resent- header seen */
BH_TABLE *cleanup_dups; /* recipient dup filter */
/* cleanup_state_alloc - initialize global state */
void cleanup_state_alloc(void)
{
cleanup_hop_count = 0;
cleanup_headers_seen = 0;
cleanup_time = 0;
cleanup_errs = 0;
cleanup_from = 0;
cleanup_fullname = 0;
cleanup_header_buf = vstring_alloc(100);
cleanup_queue_id = 0;
cleanup_recip = 0;
cleanup_return_receipt = 0;
cleanup_errors_to = 0;
cleanup_recipients = argv_alloc(2);
cleanup_resent = "";
cleanup_resent_from = 0;
cleanup_resent_recip = argv_alloc(2);
cleanup_sender = 0;
cleanup_temp1 = vstring_alloc(10);
cleanup_temp2 = vstring_alloc(10);
cleanup_inbuf = vstring_alloc(100);
cleanup_dups = been_here_init(var_dup_filter_limit, BH_FLAG_FOLD);
}
/* cleanup_state_free - destroy global state */
void cleanup_state_free(void)
{
if (cleanup_fullname)
myfree(cleanup_fullname);
if (cleanup_sender)
myfree(cleanup_sender);
if (cleanup_from)
myfree(cleanup_from);
if (cleanup_resent_from)
myfree(cleanup_resent_from);
if (cleanup_recip)
myfree(cleanup_recip);
if (cleanup_return_receipt)
myfree(cleanup_return_receipt);
if (cleanup_errors_to)
myfree(cleanup_errors_to);
vstring_free(cleanup_header_buf);
argv_free(cleanup_recipients);
argv_free(cleanup_resent_recip);
vstring_free(cleanup_temp1);
vstring_free(cleanup_temp2);
vstring_free(cleanup_inbuf);
if (cleanup_queue_id)
myfree(cleanup_queue_id);
been_here_free(cleanup_dups);
}

59
postfix/conf/LICENSE Normal file
View File

@@ -0,0 +1,59 @@
Please read this carefully. You must agree to the following terms and
conditions before installing the Secure Mailer or any related
documentation ("Software"). If you do not agree to these terms
and conditions, you may not install or use the Software.
Permission to reproduce and create derivative works from the Software
("Software Derivative Works") is hereby granted to you under the
copyrights of International Business Machines Corporation ("IBM"). IBM
also grants you the right to distribute the Software and Software
Derivative Works.
You grant IBM a world-wide, royalty-free right to use, copy,
distribute, sublicense and prepare derivative works based upon any
feedback, including materials, error corrections, Software Derivatives,
enhancements, suggestions and the like that you provide to IBM relating
to the Software.
IBM licenses the Software to you on an "AS IS" basis, without warranty
of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES OR
CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, NON
INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. You are solely
responsible for determining the appropriateness of using this Software
and assume all risks associated with the use and distribution of this
Software, including but not limited to the risks of program errors,
damage to or loss of data, programs or equipment, and unavailability or
interruption of operations. IBM WILL NOT BE LIABLE FOR ANY DIRECT
DAMAGES OR FOR ANY SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY
ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS),
EVEN IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IBM
will not be liable for the loss of, or damage to, your records or data,
or any damages claimed by you based on a third party claim. You may
not use the name "IBM" or any other IBM trademark without the prior
written consent of IBM.
You agree to distribute the Software and any Software Derivatives under
a license agreement that: 1) is sufficient to notify all licensees of
the Software and Software Derivatives that IBM assumes no liability for
any claim that may arise regarding the Software or Software
Derivatives, and 2) that disclaims all warranties, both express and
implied, from IBM regarding the Software and Software Derivatives. (If
you include this Agreement with any distribution of the Software or
Software Derivatives you will have met this requirement.) You agree
that you will not delete any copyright notices in the Software.
In the event an intellectual property claim is made or appears likely
to be made with respect to the Software, you agree to permit IBM to
enable you to continue to use the Software, or to modify it, or replace
it with software that is at least functionally equivalent. If IBM
determines that none of these alternatives is reasonably available, you
agree, at IBM's request, upon notice to you, to discontinue further
distribution of the Software and to delete or destroy all copies of the
Software you possess. This is IBM's entire obligation to you regarding
any claim of infringement.
This Agreement is the exclusive statement of your rights in the
Software as provided by IBM. Except for the licenses granted to you in
the second paragraph above, no other licenses are granted hereunder, by
estoppel, implication or otherwise.

69
postfix/conf/access Normal file
View File

@@ -0,0 +1,69 @@
#++
# NAME
# access 5
# SUMMARY
# format of Postfix access table
# SYNOPSIS
# \fBpostmap /etc/postfix/access\fR
# DESCRIPTION
# The optional \fBaccess\fR table directs the Postfix SMTP server
# to selectively reject or accept mail from or to specific hosts,
# domains, networks, host addresses or mail addresses.
#
# The table serves as input to the \fBpostmap\fR(1) command. The
# result, an indexed file in \fBdbm\fR or \fBdb\fR format,
# is used for fast searching by the mail system. After an update
# it may take a minute or so before the change becomes visible.
# Issue a \fBpostfix reload\fR command to eliminate the delay.
#
# The format of the access table is as follows:
# .IP "blanks and comments"
# Blank lines are ignored, as are lines beginning with `#'.
# .IP "\fIpattern action\fR"
# When \fIpattern\fR matches a mail address, domain or host address,
# perform the corresponding \fIaction\fR.
# PATTERNS
# Patterns are tried in the order as listed below:
# .ad
# .fi
# .IP \fIuser\fR@\fIdomain\fR
# Matches the specified mail address.
# .IP \fIdomain.name\fR
# Matches the \fIdomain.name\fR itself and any subdomain thereof,
# either in hostnames or in mail addresses. Top-level domains will
# never be matched.
# .IP \fIuser\fR@
# Matches all mail addresses with the specified user part.
# .IP \fInet.work.addr.ess\fR
# .IP \fInet.work.addr\fR
# .IP \fInet.work\fR
# .IP \fInet\fR
# Matches any host address in the specified network. A network
# address is a sequence of one or more octets separated by ".".
# ACTIONS
# .ad
# .fi
# .IP "[\fB45\fR]\fIXX text\fR"
# Reject the address etc. that matches the pattern, and respond with
# the numerical code and text.
# .IP \fBREJECT\fR
# Reject the address etc. that matches the pattern. A generic
# error response message is generated.
# .IP \fBOK\fR
# .IP "\fIAny other text\fR"
# Accept the address etc. that matches the pattern.
# BUGS
# The table format does not understand quoting conventions.
# SEE ALSO
# postmap(1) create mapping table
# smtpd(8) smtp server
# 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
#--

115
postfix/conf/aliases Normal file
View File

@@ -0,0 +1,115 @@
#++
# NAME
# aliases 5
# SUMMARY
# format of the Postfix alias database
# SYNOPSIS
# .fi
# \fBpostalias\fR [\fB-c\fR \fIconfig_dir\fR] [\fB-v\fR]
# [\fIfile_type\fR:]\fIinput_file\fR
# DESCRIPTION
# The \fBaliases\fR file provides a system-wide mechanism to
# redirect mail for local recipients.
#
# The file serves as input to the \fBpostalias\fR(1) command. The
# result, an indexed file in \fBdbm\fR or \fBdb\fR format, is
# used for fast lookup by the mail system. After an update
# it may take a minute or so before the change becomes visible.
# Issue a \fBpostfix reload\fR command to eliminate the delay.
#
# The input and output file formats are expected to be compatible
# with Sendmail version 8, and are expected to be suitable for the
# use as NIS maps.
#
# Users can control delivery of their own mail by setting
# up \fB.forward\fR files in their home directory.
# Lines in per-user \fB.forward\fR files have the same syntax
# as the right-hand side of \fBaliases\fR entries.
#
# The format of the alias database input file is as follows:
# .IP \(bu
# An alias definition has the form
# .sp
# .ti +5
# \fIname\fR: \fIvalue1\fR, \fIvalue2\fR, \fI...\fR
# .IP \(bu
# Lines that begin with whitespace continue the previous line.
# .IP \(bu
# Blank lines are ignored, as are lines beginning with `#'.
# .PP
# The \fIname\fR is a local address (no domain part).
# Use double quotes when the name contains any special characters
# such as whitespace, `#', `:', or `@'. The \fIname\fR is folded to
# lowercase, in order to make database lookups case insensitive.
# .PP
# In addition, when an alias exists for \fBowner-\fIname\fR, delivery
# diagnostics are directed to that address, instead of to the originator.
# This is typically used to direct delivery errors to the owner of
# a mailing list, who is in a better position to deal with mailing
# list delivery problems than the originator of the undelivered mail.
# .PP
# The \fIvalue\fR contains one or more of the following:
# .IP \fIaddress\fR
# Mail is forwarded to \fIaddress\fR, which is compatible
# with the RFC 822 standard.
# .IP \fI/file/name\fR
# Mail is appended to \fI/file/name\fR. See \fBlocal\fR(8)
# for details of delivery to file.
# Delivery is not limited to regular files. For example, to dispose
# of unwanted mail, deflect it to \fB/dev/null\fR.
# .IP "|\fIcommand\fR"
# Mail is piped into \fIcommand\fR. Commands that contain special
# characters, such as whitespace, should be enclosed between double
# quotes. See \fBlocal\fR(8) for details of delivery to command.
# .sp
# When the command fails, a limited amount of command output is
# mailed back to the sender. The file \fB/usr/include/sysexits.h\fR
# defines the expected exit status codes. For example, use
# \fB|"exit 67"\fR to simulate a "user unknown" error, and
# \fB|"exit 0"\fR to implement an expensive black hole.
# .IP \fB:include:\fI/file/name\fR
# Mail is sent to the destinations listed in the named file.
# Lines in \fB:include:\fR files have the same syntax
# as the right-hand side of alias entries.
# .sp
# A destination can be any destination that is described in this
# manual page. However, delivery to "|\fIcommand\fR" and
# \fI/file/name\fR is disallowed by default. To enable, edit the
# \fBallow_mail_to_commands\fR and \fBallow_mail_to_files\fR
# configuration parameters.
# ADDRESS EXTENSION
# .ad
# .fi
# When alias database search fails, and the recipient localpart
# contains the optional recipient delimiter (e.g., \fIuser+foo\fR),
# the search is repeated for the unextended address (e.g., \fIuser\fR).
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The following \fBmain.cf\fR parameters are especially relevant to
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
# .IP \fBalias_maps\fR
# List of alias databases.
# .IP \fBallow_mail_to_commands\fR
# Restrict the usage of mail delivery to external command.
# .IP \fBallow_mail_to_files\fR
# Restrict the usage of mail delivery to external file.
# .IP \fBrecipient_delimiter\fR
# Delimiter that separates recipients from address extensions.
# STANDARDS
# RFC 822 (ARPA Internet Text Messages)
# SEE ALSO
# local(8) local delivery agent
# postalias(1) alias database management
# 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
#--

110
postfix/conf/canonical Normal file
View File

@@ -0,0 +1,110 @@
#++
# NAME
# canonical 5
# SUMMARY
# format of Postfix canonical table
# SYNOPSIS
# \fBpostmap /etc/postfix/canonical\fR
# DESCRIPTION
# The optional \fBcanonical\fR file specifies an address mapping for
# local and non-local addresses. The mapping is used by the
# \fBcleanup\fR(8) daemon. The address mapping is recursive.
#
# The file serves as input to the \fBpostmap\fR(1) command. The result,
# an indexed file in \fBdbm\fR or \fBdb\fR format, is used for
# fast searching by the mail system. After an update
# it may take a minute or so before the change becomes visible.
# Issue a \fBpostfix reload\fR command to eliminate the delay.
#
# The \fBcanonical\fR mapping affects both message header addresses
# (i.e. addresses that appear inside messages) and message envelope
# addresses (for example, the addresses that are used in SMTP protocol
# commands). Think Sendmail rule set \fBS3\fR, if you like.
#
# Typically, one would use the \fBcanonical\fR table to replace login
# names by \fIFirstname.Lastname\fR, or to clean up addresses produced
# by legacy mail systems.
#
# The \fBcanonical\fR mapping is not to be confused with \fIvirtual
# domain\fR support. Use the \fBvirtual\fR(5) map for that purpose.
#
# The \fBcanonical\fR mapping is not to be confused with local aliasing.
# Use the \fBaliases\fR(5) map for that purpose.
#
# The format of the \fBcanonical\fR table is as follows, mappings
# being tried in the order as listed in this manual page:
# .IP "blanks and comments"
# Blank lines are ignored, as are lines beginning with `#'.
# .IP "\fIuser\fR@\fIdomain address\fR"
# \fIuser\fR@\fIdomain\fR is replaced by \fIaddress\fR. This form
# has the highest precedence.
# .sp
# This form useful to clean up addresses produced by legacy mail systems.
# It can also be used to produce \fIFirstname.Lastname\fR style
# addresses, but see below for a simpler solution.
# .IP "\fIuser address\fR"
# \fIuser\fR@\fIsite\fR is replaced by \fIaddress\fR when \fIsite\fR is
# equal to $\fBmyorigin\fR, when \fIsite\fR is listed in
# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR.
# .sp
# This form is useful for replacing login names by
# \fIFirstname.Lastname\fR.
# .IP "@\fIdomain address\fR"
# Every address in \fIdomain\fR is replaced by \fIaddress\fR.
# This form has the lowest precedence.
# .PP
# In all the above forms, when \fIaddress\fR has the form
# @\fIotherdomain\fR, the result is the same user in \fIotherdomain\fR.
# ADDRESS EXTENSION
# .fi
# .ad
# When table lookup fails, and the address localpart contains the
# optional recipient delimiter (e.g., \fIuser+foo\fR@\fIdomain\fR), the
# search is repeated for the unextended address (e.g.
# \fIuser\fR@\fIdomain\fR), and the unmatched extension is propagated
# to the result of table lookup. The matching order is:
# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR,
# \fIuser+foo\fR, \fIuser\fR, and @\fIdomain\fR.
# BUGS
# The table format does not understand quoting conventions.
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The following \fBmain.cf\fR parameters are especially relevant to
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
# .IP \fBcanonical_maps\fR
# List of canonical mapping tables.
# .IP \fBrecipient_canonical_maps\fR
# Address mapping lookup table for envelope and header recipient
# addresses.
# .IP \fBsender_canonical_maps\fR
# Address mapping lookup table for envelope and header sender
# addresses.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
# The network interface addresses that this system receives mail on.
# .IP \fBmasquerade_domains\fR
# List of domains that hide their subdomain structure.
# .IP \fBmasquerade_exceptions\fR
# List of user names that are not subject to address masquerading.
# .IP \fBmydestination\fR
# List of domains that this mail system considers local.
# .IP \fBmyorigin\fR
# The domain that is appended to locally-posted mail.
# SEE ALSO
# cleanup(8) canonicalize and enqueue mail
# postmap(1) create mapping table
# virtual(5) virtual domain mapping
# 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
#--

322
postfix/conf/main.cf Normal file
View File

@@ -0,0 +1,322 @@
# Global Postfix configuration file. This file lists only a subset
# of all 100+ parameters. See the sample-xxx.cf files for a full list.
#
# The general format is lines with parameter = value pairs. Lines
# that begin with whitespace continue the previous line. A value can
# contain references to other $names or ${name}s.
# LOCAL PATHNAME INFORMATION
#
# The queue_directory specifies the location of the Postfix queue.
# This is also the root directory of Postfix daemons that run chrooted.
# The contributed source code from http://www.postfix.org/ has examples
# for setting up Postfix chroot environments on different UNIX systems.
#
queue_directory = /var/spool/postfix
# The program_directory parameter specifies the default location of
# Postfix support programs and daemons. This setting can be overruled
# with the command_directory and daemon_directory parameters.
#
program_directory = /some/where/postfix/bin
# The command_directory parameter specifies the location of all
# postXXX commands. The default value is $program_directory.
#
#command_directory = /usr/sbin
# The daemon_directory parameter specifies the location of all Postfix
# daemon programs (i.e. programs listed in the master.cf file). The
# default value is $program_directory. This directory must be owned
# by root.
#
#daemon_directory = /usr/libexec/postfix
# QUEUE AND PROCESS OWNERSHIP
#
# The mail_owner parameter specifies the owner of the Postfix queue
# and of most Postfix daemon processes. Specify the name of a user
# account THAT DOES NOT SHARE A GROUP WITH OTHER ACCOUNTS AND THAT
# OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM. In particular,
# don't specify nobody or daemon. PLEASE USE A DEDICATED USER.
#
#mail_owner = postfix
# The default_privs parameter specifies the default rights used by
# the local delivery agent for delivery to external file or command.
# These rights are used in the absence of a recipient user context.
# DO NOT SPECIFY A PRIVILEGED USER OR THE POSTFIX OWNER.
#
#default_privs = nobody
# INTERNET HOST AND DOMAIN NAMES
#
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.name
#myhostname = virtual.domain.name
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.name
# SENDING MAIL
#
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites. If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
#myorigin = $myhostname
#myorigin = $mydomain
# RECEIVING MAIL
# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on. By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
# The mydestination parameter specifies the list of domains that this
# machine considers itself the final destination for.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain. Do not specify the
# names of domains that this machine is backup MX host for. Specify
# those names via the relay_domains or permit_mx_backup settings for
# the SMTP server (see sample-smtpd.cf.
#
# The local machine is always the final destination for mail addressed
# to user@[the.net.work.address] of an interface that the mail system
# receives mail on (see the inet_interfaces parameter).
#
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
# a name matches a lookup key. Continue long lines by starting the
# next line with whitespace.
#
#mydestination = $myhostname, localhost.$mydomain
#mydestination = $myhostname, localhost.$mydomain $mydomain
#mydestination = $myhostname, localhost.$mydomain, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
# INTERNET VERSUS INTRANET
#
# The relayhost parameter specifies the default host to send mail to
# when no entry is matched in the optional transport(5) table. When
# no relayhost is given, mail is routed directly to the destination.
#
# On an intranet, specify the organizational domain name. If your
# internal DNS uses no MX records, specify the name of the intranet
# gateway host instead.
#
# Specify a domain, host, host:port, [address] or [address:port].
# Use the form [destination] to turn off MX lookups. See also the
# default_transport parameter if you're connected via UUCP.
#
#relayhost = $mydomain
#relayhost = gateway.my.domain
#relayhost = uucphost
#relayhost = [mail.$mydomain:9999]
# DEFAULT TRANSPORT
#
# The default_transport parameter specifies the default message
# delivery transport to use when no transport is explicitly given in
# the optional transport(5) table.
#
#default_transport = smtp
#default_transport = uucp
# ADDRESS REWRITING
#
# Insert text from sample-rewrite.cf if you need to do address
# masquerading.
#
# Insert text from sample-canonical.cf if you need to do address
# rewriting, or if you need username->Firstname.Lastname mapping.
# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
#
# Insert text from sample-virtual.cf if you need virtual domain support.
# "USER HAS MOVED" BOUNCE MESSAGES
#
# Insert text from sample-relocated.cf if you need "user has moved"
# style bounce messages. Alternatively, you can bounce recipients
# with an SMTP server access table. See sample-smtpd.cf.
# TRANSPORT MAP
#
# Insert text from sample-transport.cf if you need explicit routing.
# ALIAS DATABASE
#
# The alias_maps parameter specifies the list of alias databases used
# by the local delivery agent. The default list is system dependent.
# On systems with NIS, the default is to search the local alias
# database, then the NIS alias database. See aliases(5) for syntax
# details.
#
# If you change the alias database, run "postalias /etc/aliases" (or
# wherever your system stores the mail alias file), or simply run
# "newaliases" to build the necessary DBM or DB file.
#
# It will take a minute or so before changes become visible. Use
# "postfix reload" to eliminate the delay.
#
#alias_maps = dbm:/etc/aliases
#alias_maps = hash:/etc/aliases
#alias_maps = hash:/etc/aliases, nis:mail.aliases
# The alias_database parameter specifies the alias database(s) that
# are built with "newaliases" or "sendmail -bi". This is a separate
# configuration parameter, because alias_maps (see above) may specify
# tables that are not necessarily all under control by Postfix.
#
#alias_database = dbm:/etc/aliases
#alias_database = dbm:/etc/mail/aliases
#alias_database = hash:/etc/aliases
#alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases
# ADDRESS EXTENSIONS (e.g., user+foo)
#
# The recipient_delimiter parameter specifies the separator between
# user names and address extensions (user+foo). See canonical(5),
# local(8), relocated(5) and virtual(5) for the effects this has on
# aliases, canonical, virtual, relocated and .forward file lookups.
# Basically, the software tries user+foo and .forward+foo before
# trying user and .forward.
#
# recipient_delimiter = +
# DELIVERY TO MAILBOX
#
# The home_mailbox parameter specifies the optional pathname of a
# mailbox relative to a user's home directory. The default is to
# deliver to the UNIX-style /var/spool/mail/user or /var/mail/user.
# Specify "Maildir/" for qmail-style delivery (the / is required).
#
#home_mailbox = Mailbox
#home_mailbox = Maildir/
# The mailbox_command specifies the optional external command to use
# instead of mailbox delivery. The command is run with proper HOME,
# SHELL and LOGNAME settings.
#
# Avoid shell meta characters because they will force Postfix to run
# an expensive shell process. Procmail alone is expensive enough.
#
#mailbox_command = /some/where/procmail
# JUNK MAIL CONTROLS
#
# The controls listed here are only a very small subset. See the file
# sample-smtpd.cf for an elaborate list of anti-UCE controls.
# The relay_domains parameter restricts what domains (and subdomains
# thereof) this mail system will relay mail from or to. See the
# smtpd_recipient_restrictions restriction in the file sample-smtpd.cf.
#
# By default, Postfix relays mail only from or to sites in or below
# $mydestination, or in the optional virtual domain list.
#
# Specify a list of hosts or domains, /file/name patterns or type:name
# lookup tables, separated by commas and/or whitespace. Continue
# long lines by starting the next line with whitespace. A file name
# is replaced by its contents; a type:name table is matched when a
# (parent) domain appears as lookup key.
#
# NOTE: Postfix will not automatically forward mail for domains that
# list this system as their primary or backup MX host. See the
# permit_mx_backup restriction in the file sample-smtpd.cf.
#
#relay_domains = $mydestination, $virtual_domains
# The mynetworks parameter specifies the list of networks that are
# local to this machine. The list is used by the anti-UCE software
# to distinguish local clients from strangers. See permit_mynetworks
# and smtpd_recipient_restrictions in the file sample-smtpd.cf file.
#
# The default is all networks attached to the machine: a complete
# class A network, a complete class B network, and so on. If you want
# stricter control, specify a list of network/mask patterns, where
# the mask specifies the number of bits in the network part of a host
# address. You can also specify the absolute pathname of a pattern
# file instead of listing the patterns here.
#
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
# SHOW SOFTWARE VERSION OR NOT
#
# The smtpd_banner parameter specifies the text that follows the 220
# status code in the SMTP greeting banner. Some people like to see
# the mail version advertised. By default, Postfix shows no version.
#
# You MUST specify the $myhostname at the start of the text. When
# the SMTP client sees its own hostname at the start of an SMTP
# greeting banner it will report a mailer loop. That's better than
# having a machine meltdown.
#
#smtpd_banner = $myhostname ESMTP $mail_name
#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
# PARALLEL DELIVERY TO THE SAME DESTINATION
#
# How many parallel deliveries to the same user or domain? With local
# delivery, it does not make sense to do massively parallel delivery
# to the same user, because mailbox updates must happen sequentially,
# and expensive pipelines in .forward files can cause disasters when
# too many are run at the same time. With SMTP deliveries, 10
# simultaneous connections to the same domain could be sufficient to
# raise eyebrows.
#
# Each message delivery transport has its XXX_destination_concurrency_limit
# parameter. The default is $default_destination_concurrency_limit.
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10
# DEBUGGING CONTROL
#
# The debug_peer_level parameter specifies the increment in verbose
# logging level when an SMTP client or server host name or address
# matches a pattern in the debug_peer_list parameter.
#
debug_peer_level = 2
# The debug_peer_list parameter specifies an optional list of domain
# or network patterns, /file/name patterns or type:name tables. When
# an SMTP client or server host name or address matches a pattern,
# increase the verbose logging level by the amount specified in the
# debug_peer_level parameter.
#
# debug_peer_list = 127.0.0.1
# debug_peer_list = some.domain
# The debugger_command specifies the external command that is executed
# when a Postfix daemon program is run with the -D option.
#
# Use "command .. & sleep 5" so that the debugger can attach before
# the process marches on. If you use an X-based debugger, be sure to
# set up your XAUTHORITY environment variable before starting Postfix.
#
debugger_command =
PATH=/usr/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
# Other configurable parameters.

61
postfix/conf/master.cf Normal file
View File

@@ -0,0 +1,61 @@
#
# Postfix master process configuration file. Each line describes how
# a mailer component program should be run. The fields that make up
# each line are described below. A "-" field value requests that a
# default value be used for that field.
#
# Service: any name that is valid for the specified transport type
# (the next field). With INET transports, a service is specified as
# host:port. The host part (and colon) may be omitted. Either host
# or port may be given in symbolic form or in numeric form.
#
# Transport type: "inet" for Internet sockets, "unix" for UNIX-domain
# sockets, "fifo" for named pipes.
#
# Private: whether or not access is restricted to the mail system.
# Default is private service. Internet (inet) sockets can't be private.
#
# Unprivileged: whether the service runs with root privileges or as
# the owner of the Postfix system (the owner name is controlled by the
# mail_owner configuration variable in the main.cf file).
#
# Chroot: whether or not the service runs chrooted to the mail queue
# directory (pathname is controlled by the queue_directory configuration
# variable in the main.cf file). Presently, all Postfix daemons can run
# chrooted, except for the pipe and local daemons. The contributed
# source code from http://www.postfix.org/ describes how to set up
# a Postfix chroot environment for your type of machine.
#
# Wakeup time: automatically wake up the named service after the
# specified number of seconds. Specify 0 for no wakeup. Presently,
# only the local pickup and queue manager daemons need a wakeup timer.
#
# Max procs: the maximum number of processes that may execute this
# service simultaneously. Default is to use a globally configurable
# limit (the default_process_limit configuration parameter in main.cf).
#
# Command + args: the command to be executed. The command name is
# relative to the Postfix program directory (pathname is controlled by
# the program_directory configuration variable). Adding one or more
# -v options turns on verbose logging for that service; adding a -D
# option enables symbolic debugging (see the debugger_command variable
# in the main.cf configuration file).
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (50)
# ==========================================================================
smtp inet n - n - - smtpd
pickup fifo n n n 60 1 pickup
cleanup unix - - n - 0 cleanup
qmgr fifo n - n 300 1 qmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
smtp unix - - n - - smtp
showq unix n - n - - showq
local unix - n n - - local
#local unix - n n - - pipe
# user=cyrus argv=/cyrus/bin/deliver -e -q -m ${extension} ${user}
uucp unix - n n - - pipe
flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)

View File

@@ -0,0 +1,218 @@
#!/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 [ -x /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
}
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
kill -HUP `cat pid/master.pid`
;;
flush)
cd $queue_directory || {
$FATAL no Postfix queue directory $queue_directory!
exit 1
}
$command_directory/postkick public qmgr DFA
;;
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 $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 saved corrupt; do
test -d $dir || {
$WARN creating missing Postfix $dir directory
mkdir $dir || exit 1
chmod 700 $dir; $CHATTR $dir
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: {} \;
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

219
postfix/conf/postfix-script-sgid Executable file
View File

@@ -0,0 +1,219 @@
#!/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 [ -x /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
}
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
kill -HUP `cat pid/master.pid`
;;
flush)
cd $queue_directory || {
$FATAL no Postfix queue directory $queue_directory!
exit 1
}
$command_directory/postkick public qmgr DFA
;;
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 $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 730 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 saved corrupt; do
test -d $dir || {
$WARN creating missing Postfix $dir directory
mkdir $dir || exit 1
chmod 700 $dir; $CHATTR $dir
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: {} \;
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

78
postfix/conf/relocated Normal file
View File

@@ -0,0 +1,78 @@
#++
# NAME
# relocated 5
# SUMMARY
# format of Postfix relocated table
# SYNOPSIS
# \fBpostmap /etc/postfix/relocated\fR
# DESCRIPTION
# The optional \fBrelocated\fR file provides the information that is
# used in "user has moved to \fInew_location\fR" bounce messages.
#
# The file serves as input to the \fBpostmap\fR(1) command. The result,
# an indexed file in \fBdbm\fR or \fBdb\fR format, is used for
# fast searching by the mail system. After an update
# issue a \fBpostfix reload\fR command to make the change visible.
#
# Table lookups are case insensitive.
#
# The format of the table is as follows:
# .IP \(bu
# Blank lines are ignored, as are lines beginning with `#'.
# .IP \(bu
# An entry has one of the following form:
# .ti +5
# \fIkey new_location\fR
# .br
# Where \fInew_location\fR specifies contact information such as
# an email address, or perhaps a street address or telephone number.
# .PP
# The \fIkey\fR field is one of the following:
# .IP \fIuser\fR@\fIdomain\fR
# Matches \fIuser\fR@\fIdomain\fR. This form has precedence over all
# other forms.
# .IP \fIuser\fR
# Matches \fIuser\fR@\fIsite\fR when \fIsite\fR is $\fBmyorigin\fR,
# when \fIsite\fR is listed in $\fBmydestination\fR, or when \fIsite\fR
# is listed in $\fBinet_interfaces\fR.
# .IP @\fIdomain\fR
# Matches every address in \fIdomain\fR. This form has the lowest
# precedence.
# ADDRESS EXTENSION
# .fi
# .ad
# When the search fails, and the address localpart contains the
# optional recipient delimiter (e.g., \fIuser+foo\fR@\fIdomain\fR),
# the search is repeated for the unextended address (e.g.
# \fIuser\fR@\fIdomain\fR).
# BUGS
# The table format does not understand quoting conventions.
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The following \fBmain.cf\fR parameters are especially relevant to
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
# .IP \fBrelocated_maps\fR
# List of lookup tables for relocated users or sites.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
# The network interface addresses that this system receives mail on.
# .IP \fBmydestination\fR
# List of domains that this mail system considers local.
# .IP \fBmyorigin\fR
# The domain that is appended to locally-posted mail.
# SEE ALSO
# postmap(1) create lookup table
# 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
#--

View File

@@ -0,0 +1,32 @@
# This file contains example settings of Postfix configuration
# parameters that control alias database lookups.
#
# See the sample-local.cf file for examples of other parameters
# that control local delivery.
# The alias_database parameter specifies the alias database that is
# built with "newaliases" or "sendmail -bi". This is a separate
# configuration parameter, because the alias_maps parameter may
# specify multiple tables, not necessarily all under control by
# Postfix.
#
# alias_database = dbm:/etc/aliases
# alias_database = dbm:/etc/mail/aliases
alias_database = hash:/etc/aliases
# The alias_maps parameter specifies the list of alias databases used
# by the local delivery agent. The default list is system dependent.
# On systems with NIS, the default is to search the local alias
# database, then the NIS alias database. See aliases(5) for syntax
# details.
#
# If you change the alias database, run "postalias /etc/aliases" (or
# wherever your system stores the mail alias file), or simply run
# "newaliases" to build the necessary DBM or DB file.
#
# It will take a minute or so before changes become visible. Use
# "postfix reload" to eliminate the delay.
#
# alias_maps = dbm:/etc/aliases, nis:mail.aliases
# alias_maps = hash:/etc/aliases
alias_maps = hash:/etc/aliases

View File

@@ -0,0 +1,45 @@
# This file contains example settings of Postfix configuration
# parameters that control canonical address map lookups.
# The canonical_maps parameter specifies optional address mapping
# lookup tables. The mapping is applied to both sender and recipient
# addresses, in both envelopes and in headers. This is typically used
# to clean up dirty addresses from legacy mail systems, or to replace
# login names by Firstname.Lastname. See canonical(5) for details.
#
# By default, no canonical address mapping is done.
#
# If you use this feature, run "postmap /etc/postfix/canonical" to
# build the necessary DBM or DB file after every change. The changes
# will become visible after a minute or so. Use "postfix reload"
# to eliminate the delay.
#
# canonical_maps = dbm:/etc/postfix/canonical
# canonical_maps = hash:/etc/postfix/canonical
# canonical_maps = hash:/etc/postfix/canonical, nis:canonical
# canonical_maps = hash:/etc/postfix/canonical, netinfo:/canonical
canonical_maps =
# The recipient_canonical_maps parameter specifies optional address
# mapping lookup tables for envelope and header RECIPIENT addresses.
#
# By default, no recipient-only address mapping is done.
#
# $recipient_canonical_maps is used before $canonical_maps lookups.
#
# recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
recipient_canonical_maps =
# The sender_canonical_maps parameter specifies optional address
# mapping lookup tables for envelope and header SENDER addresses.
#
# For example, you want to rewrite the SENDER address user@ugly.domain
# to user@pretty.domain, while still being able to send mail to the
# RECIPIENT address user@ugly.domain.
#
# By default, no sender-only address mapping is done.
#
# $sender_canonical_maps is used before $canonical_maps lookups.
#
# sender_canonical_maps = hash:/etc/postfix/sender_canonical
sender_canonical_maps =

View File

@@ -0,0 +1,29 @@
# This file contains example settings of Postfix configuration
# parameters that control debugging features.
# The debug_peer_level parameter specifies the increment in verbose
# logging level when an SMTP client or server host name or address
# matches a pattern in the debug_peer_list parameter.
#
debug_peer_level = 2
# The debug_peer_list parameter specifies an optional list of domain
# or network patterns, /file/name patterns or type:name tables. When
# an SMTP client or server host name or address matches a pattern,
# increase the verbose logging level by the amount specified in the
# debug_peer_level parameter.
#
# debug_peer_list = 127.0.0.1
# debug_peer_list = some.domain
debug_peer_list =
# The debugger_command specifies the external command that is executed
# when a Postfix daemon program is run with the -D option.
#
# Use "command .. & sleep 5" so that the debugger can attach before
# the process marches on. If you use an X-based debugger, be sure to
# set up your XAUTHORITY environment variable before starting Postfix.
#
debugger_command =
PATH=/usr/bin:/usr/X11R6/bin
xxgdb $program_directory/$process_name $process_id & sleep 5

View File

@@ -0,0 +1,16 @@
# This file contains example settings of Postfix configuration
# parameters that control LDAP lookups. Source code for LDAP
# lookup is available separately from http://www.postfix.org/
# The ldap_lookup_timeout parameter specifies the timeout for LDAP
# database lookups.
#
ldap_lookup_timeout = 10
# The ldap_search_base parameter specifies the LDAP database to search.
#
ldap_search_base =
# The ldap_server_host parameter specifies the LDAP server hostname.
#
ldap_server_host =

View File

@@ -0,0 +1,93 @@
# This file contains example settings of Postfix configuration
# parameters that control local delivery.
#
# See the sample-aliases.cf file for parameters that are specific to
# alias database lookup.
#
# SECURITY CONTROLS
#
# The local_command_shell parameter controls what shell will be used
# for delivery to external command. By default, external commands
# are executed directly; commands are given to given to /bin/sh only
# when they contain shell meta characters or shell built-in commands.
#
# Specify a different shell when you need more control over what
# programs can be run from e.g. .forward files.
#
# "sendmail's restricted shell" (smrsh) is what most people will use
# (smrsh is part of recent sendmail distributions)
#
# Note: when a shell is specified, it is invoked even when the
# command contains no shell built-in commands or meta characters.
#
#local_command_shell = /some/where/smrsh -c
# The allow_mail_to_commands parameter restricts mail delivery to
# external commands. The default is to disallow delivery to "|command"
# in :include: files.
#
# allow_mail_to_commands = alias,forward,include
allow_mail_to_commands = alias,forward
# The allow_mail_to_files parameter restricts mail delivery to external
# file. The default is to disallow delivery to /file/name in :include:
# files.
#
# allow_mail_to_files = alias,forward,include
allow_mail_to_files = alias,forward
# The default_privs parameter specifies the default rights used by
# the local delivery agent for delivery to external file or command.
# These rights are used in the absence of a recipient user context.
# DO NOT SPECIFY A PRIVILEGED USER OR THE POSTFIX OWNER.
#
default_privs = nobody
#
# MAILBOX DELIVERY CONTROLS
#
# The home_mailbox parameter specifies the optional pathname of a
# mailbox relative to a user's home directory. The default is to
# deliver to the UNIX-style /var/spool/mail/user or /var/mail/user.
# Specify "Maildir/" for qmail-style delivery (the / is required).
#
# home_mailbox = Mailbox
# home_mailbox = Maildir/
home_mailbox =
# The mailbox_command specifies the optional external command to use
# instead of mailbox delivery. The command is run with proper HOME,
# SHELL and LOGNAME settings.
#
# Avoid shell meta characters because they will force Postfix to run
# an expensive shell process. Procmail alone is expensive enough.
#
# mailbox_command = /some/where/procmail
mailbox_command =
#
# RATE CONTROLS
#
# The local_destination_concurrency_limit parameter limits the number
# of parallel deliveries to the same local recipient.
#
# The default limit is taken from the default_destination_concurrency_limit
# parameter. I recommend a low limit of 2, just in case someone has
# an expensive shell command in a .forward file or in an alias (e.g.,
# a mailing list manager). You don't want to run lots of those.
#
local_destination_concurrency_limit = 2
# The local_destination_recipient_limit parameter limits the number
# of recipients per local message delivery. The default limit is
# taken from the default_destination_recipient_limit parameter.
#
# However, the queue manager by design limits the number of recipients
# per local delivery request to exactly 1, so this parameter has no
# effect.
#
local_destination_recipient_limit = 1

232
postfix/conf/sample-misc.cf Normal file
View File

@@ -0,0 +1,232 @@
# This file contains example settings for miscellaneous Postfix
# configuration parameters.
# The default_database_type parameter specifies the default database
# type to use in postalias(1) and postmap(1) commands. On many UNIX
# systems the default type is either `dbm' or `hash'. The default is
# determined when the Postfix system is built.
#
# default_database_type = hash
# default_database_type = dbm
# The default_transport parameter specifies the default message
# delivery transport to use when no transport is explicitly given in
# the optional transport(5) table.
#
# default_transport = uucp
default_transport = smtp
# The double_bounce_sender parameter specifies the sender address
# for mail that must be discarded when it cannot be delivered. This
# must be a unique name. All mail to this name is silently discarded,
# in order to terminate mail bounce loops.
#
double_bounce_sender = double-bounce
# The hash_queue_depth parameter specifies the number of subdirectory
# levels below the queue directories listed in the hash_queue_names
# parameter.
#
# Multiple subdirectory levels can speed up directory searches by
# reducing the number of files per directory.
#
hash_queue_depth = 2
# The hash_queue_names parameter specifies the names of queue
# directories that are split across multiple subdirectory levels.
# Currently, hashing cannot be used for the maildrop, incoming, active
# or deferred directories. Hashing MUST be used for the defer logfile
# directory, or mail system performance will suffer.
#
hash_queue_names = defer
# The hopcount_limit parameter limits the number of Received: message
# headers. A message that exceeds the limit is bounced.
#
hopcount_limit = 50
# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on. By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
inet_interfaces = all
# The ipc_idle parameter bounds the idle time in seconds after which
# an internal IPC client disconnects. The purpose is to allow servers
# to terminate voluntarily. Currently this is used by the address
# resolving and rewriting clients.
#
ipc_idle = 100
# The ipc_timeout parameter specifies a timeout in seconds for I/O
# on internal communication channels. The purpose is to break out
# of deadlock situations. If the timeout is exceeded the software
# aborts with a fatal error.
#
ipc_timeout = 3600
# The mail_name parameter specifies the mail system name that is used
# in Received: headers, in the SMTP greeting banner, and in bounced
# mail.
#
mail_name = Postfix
# The mail_owner parameter specifies the owner of the Postfix queue
# and of most Postfix daemon processes. Specify the name of a user
# account THAT DOES NOT SHARE A GROUP WITH OTHER ACCOUNTS AND THAT
# OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM. In particular,
# don't specify nobody or daemon. PLEASE USE A DEDICATED USER.
#
mail_owner = postfix
# The mail_version parameter specifies the official version of the
# mail system. The version string can be used in, for example, the
# SMTP greeting banner.
#
mail_version = 19981207
# The max_idle parameter limits the time in seconds that a Postfix
# daemon process waits for the next service request before exiting.
# This parameter is ignored by the Postfix queue manager.
#
max_idle = 100
# The max_use parameter limits the number of service requests handled
# by a Postfix daemon process before exiting. This parameter is
# ignored by the Postfix queue manager.
#
max_use = 100
# The mydestination parameter specifies the list of domains that this
# machine considers itself the final destination for.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain. Do not specify the
# names of domains that this machine is backup MX host for. Specify
# those names via the relay_domains or permit_mx_backup settings for
# the SMTP server (see sample-smtpd.cf.
#
# The local machine is always the final destination for mail addressed
# to user@[the.net.work.address] of an interface that the mail system
# receives mail on (see the inet_interfaces parameter).
#
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
# a name matches a lookup key. Continue long lines by starting the
# next line with whitespace.
#
# mydestination = $myhostname, localhost.$mydomain $mydomain
# mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain
mydestination = $myhostname, localhost.$mydomain
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.name
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.name
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites. If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
# myorigin = $mydomain
myorigin = $myhostname
# The mynetworks parameter specifies the list of networks that are
# local to this machine. The list is used by the anti-UCE software
# to distinguish local clients from strangers. See permit_mynetworks
# in the sample-smtpd.cf file.
#
# The default is all networks attached to the machine: a complete
# class A network, a complete class B network, and so on. If you want
# stricter control, specify a list of network/mask patterns, where
# the mask specifies the number of bits in the network part of a host
# address. You can also specify the absolute pathname of a pattern
# file instead of listing the patterns here.
#
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
# The notify_classes parameter specifies the list of error classes
# that are reported to the postmaster. The default is to report only
# the most serious problems. The paranoid may wish to turn on the
# policy (anti-UCE violations) and protocol error (broken mailers)
# reports.
#
# notify_classes = bounce,policy,protocol,resource,software
notify_classes = resource,software
# The process_id_directory specifies a lock file directory relative
# to the Postfix queue directory. This facility is used by the master
# daemon to lock out other master daemon instances.
#
process_id_directory = pid
# The program_directory parameter specifies the location of Postfix
# support programs and daemons. This directory must be owned by root.
#
program_directory = /usr/libexec/postfix
# The queue_directory specifies the location of the Postfix queue.
# This is also the root directory of Postfix daemons that run chrooted.
# The contributed source code from http://www.postfix.org/ has examples
# for setting up Postfix chroot environments on different UNIX systems.
#
queue_directory = /var/spool/postfix
# The recipient_delimiter parameter specifies the separator between
# user names and address extensions (user+foo). See canonical(5),
# local(8), relocated(5) and virtual(5) for the effects this has on
# aliases, canonical, virtual, relocated and .forward file lookups.
# Basically, the software tries user+foo and .forward+foo before
# trying user and .forward.
#
# recipient_delimiter = +
recipient_delimiter =
# The relayhost parameter specifies the default host to send mail to
# when no entry is matched in the optional transport(5) table. When
# no relayhost is given, mail is routed directly to the destination.
#
# On an intranet, specify the organizational domain name. If your
# internal DNS uses no MX records, specify the name of the intranet
# gateway host instead.
#
# Specify a domain, host, host:port, [address] or [address:port].
# Use the form [destination] to turn off MX lookups. See also the
# default_transport parameter if you're connected via UUCP.
#
# relayhost = $mydomain
# relayhost = gateway.my.domain
# relayhost = uucphost
relayhost =
# The relocated_maps parameter specifies optional tables with contact
# information for users, hosts or domains that no longer exist. See
# relocated(5) for details.
#
# By default, this feature is disabled.
#
# Specify the types and names of databases to use. After change,
# run "postmap /etc/postfix/relocated", then "postfix reload".
#
# relocated_maps = hash:/etc/postfix/relocated
relocated_maps =
# The trigger_timeout parameter limits the time to send a trigger to
# a Postfix daemon. This prevents programs from getting stuck when the
# mail system is under heavy load.
#
trigger_timeout = 10

View File

@@ -0,0 +1,56 @@
# This file contains example settings of Postfix parameters that
# control delivery rates.
# The default_destination_concurrency_limit parameter specifies a
# default limit on the number of parallel deliveries to the same
# destination. This is the default limit for delivery via SMTP, via
# the local delivery agent and via the pipe mailer.
#
default_destination_concurrency_limit = 10
# The default_destination_recipient_limit parameter specifies a
# default limit on the number of recipients per message delivery.
# This is the default limit for delivery via SMTP, via the local
# delivery agent and via the pipe mailer.
#
default_destination_recipient_limit = 50
# The initial_destination_concurrency parameter specifies the initial
# per-destination concurrency level for parallel delivery to the same
# destination. This limit applies to delivery via SMTP, via the local
# delivery agent and via the pipe mailer.
#
# With concurrency of 1, one bad message is enough to block all mail
# to a site. A concurrency of 2 seems a reasonable choice.
#
initial_destination_concurrency = 2
# The maximal_backoff_time parameter specifies the maximal time in
# seconds between attempts to deliver a deferred message.
#
maximal_backoff_time = 4000
# The maximal_queue_lifetime parameter specifies the maximal time in
# days a message is queued before it is sent back as undeliverable.
#
maximal_queue_lifetime = 5
# The minimal_backoff_time parameter specifies the minimal time in
# seconds between attempts to deliver a deferred message. This
# parameter also limits the time an unreachable destination is kept
# in the short-term, in-memory destination status cache.
#
minimal_backoff_time = 1000
# The queue_run_delay parameter specifies the time in seconds
# between deferred queue scans by the queue manager.
#
queue_run_delay = 1000
# The defer_transports parameter specifies the names of transports
# that should not be delivered to unless someone issues "sendmail
# -q" or equivalent. Specify zero or more names of mail delivery
# transports names that appear in the first field of master.cf).
#
#defer_transports = smtp
#defer_transports =

View File

@@ -0,0 +1,18 @@
# This file contains example settings of Postfix configuration
# parameters that control relocated database lookups.
# The relocated_maps parameter specifies optional lookup tables with
# new contact information for users or even domains that no longer
# exist.
#
# By default, this feature is disabled.
#
# If you use this feature, run "postmap /etc/postfix/relocated" to
# build the necessary DBM or DB file after change, then "postfix
# reload" to make the changes visible.
#
# relocated_maps = dbm:/etc/postfix/relocated
# relocated_maps = hash:/etc/postfix/relocated
# relocated_maps = hash:/etc/postfix/relocated, nis:virtual
# relocated_maps = hash:/etc/postfix/relocated, netinfo:/relocated
relocated_maps =

View File

@@ -0,0 +1,97 @@
# This file contains example settings of general Postfix resource
# control parameters.
#
# Controls that are specific to message delivery transports are
# described in the respective sample-transportname.cf file.
# The bounce_size_limit parameter limits the amount of original
# message context in bytes that is sent in a non-delivery notification.
#
bounce_size_limit = 50000
# The command_time_limit parameter limits the amount of time for
# delivery to external commands. This limit is used by the local
# delivery agent, and is the default time limit for delivery by the
# pipe mailer.
#
# Note: if you set this time limit to a large value you must update the
# global ipc_timeout parameter as well. See sample-misc.cf for details.
#
command_time_limit = 1000
# The default_process_limit parameter specifies the default limit
# on the number of Postfix child processes that provide a given
# service.
#
default_process_limit = 50
# The deliver_lock_attempts parameter limits the number of attempts
# to acquire an exclusive lock on a mailbox or other file.
#
deliver_lock_attempts = 5
# The deliver_lock_delay parameter limits the time in seconds between
# attempts to acquire an exclusive lock.
#
deliver_lock_delay = 1
# The duplicate_filter_limit parameter limits the number of addresses
# remembered by the duplicate filter for alias, virtual, etc.
# expansion.
#
duplicate_filter_limit = 1000
# The fork_attempts parameter limits the number of attempts to
# fork() a process.
#
fork_attempts = 5
# The fork_delay parameter specifies the delay in seconds between
# fork() attempts.
#
fork_delay = 1
# The header_size_limit parameter limits the amount of memory in
# bytes used for processing a message header. If a header is larger,
# the remainder of the entire message is treated as message body.
#
header_size_limit = 102400
# The line_length_limit parameter limits the amount of memory in
# bytes used for handling input lines. Longer lines are chopped up
# into pieces and reconstructed upon delivery.
#
line_length_limit = 2048
# The message_size_limit parameter limits the total size in bytes of
# a message, including envelope information.
#
message_size_limit = 10240000
# The qmgr_message_active_limit parameter limits the number of
# messages in the active queue.
#
qmgr_message_active_limit = 1000
# The qmgr_message_recipient_limit parameter limits the number of
# in-memory recipients. This parameter also limits the size of the
# short-term, in-memory destination status cache.
#
qmgr_message_recipient_limit = 1000
# The queue_minfree parameter specifies the minimal amount of free
# space in bytes in the queue file system. This is currently used by
# the SMTP server to decide if it will accept any mail at all.
#
queue_minfree = 0
# The stale_lock_time parameter limits the time after which a stale
# lock is removed. This is used for delivery to file or mailbox.
#
stale_lock_time = 500
# The transport_retry_time parameter specifies the time in seconds
# between attempts by the queue manager to contact a broken message
# delivery transport.
#
transport_retry_time = 60

View File

@@ -0,0 +1,48 @@
# This file contains example settings of Postfix configuration
# parameters that control address rewriting.
# The allow_percent_hack parameter controls the rewriting of the form
# "user%domain" to "user@domain". This is enabled by default.
#
# allow_percent_hack = no
allow_percent_hack = yes
# The append_at_myorigin controls the rewriting of the form "user" to
# "user@$mydomain". This should not be turned off.
#
append_at_myorigin = yes
# The append_dot_mydomain controls the rewriting of the form
# "user@host" to "user@host.$mydomain". This is enabled by default.
#
# append_dot_mydomain = no
append_dot_mydomain = yes
# The empty_address_recipient specifies the destination for mail from
# <> that is undeliverable (typically, bounce notifications and
# other notifications). By default, such mail is sent to MAILER-DAEMON.
#
empty_address_recipient = MAILER-DAEMON
# The masquerade_domains parameter gives an optional list of domains
# that must have their subdomain structure stripped off.
#
# By default, address masquerading is disabled.
#
# masquerade_domains = $mydomain
masquerade_domains =
# The masquerade_exceptions parameter gives an optional list of user
# names that are not subjected to address masquerading.
#
# By default, address masquerading makes no exceptions.
#
#masquerade_exceptions = root
masquerade_exceptions =
# The swap_bangpath parameter controls the rewriting of the form
# "site!user" to "user@site". This is necessary if your machine is
# connected to UUCP networks. It is enabled by default.
#
# swap_bangpath = no
swap_bangpath = yes

104
postfix/conf/sample-smtp.cf Normal file
View File

@@ -0,0 +1,104 @@
# This file contains example settings of Postfix configuration
# parameters that control the SMTP client program.
#
# RATE CONTROLS
#
# The smtp_destination_concurrency_limit parameter limits the number
# of parallel deliveries to the same destination via the smtp delivery
# agent.
#
# The default limit is the default_destination_concurrency_limit
# parameter. It is probably safer to limit the concurrency to 10.
#
smtp_destination_concurrency_limit = 10
# The smtp_destination_recipient_limit parameter limits the number
# of recipients per delivery via the smtp delivery agent.
#
# The default is taken from the default_destination_recipient_limit
# parameter.
#
smtp_destination_recipient_limit = $default_destination_recipient_limit
#
# TIMEOUT CONTROLS
#
# Note: if you set SMTP timeouts to large values you must update the
# global ipc_timeout parameter as well. See sample-misc.cf for details.
#
# The smtp_connect_timeout parameter specifies the SMTP client
# timeout in seconds for completing a TCP connection.
#
# When no connection can be made within the deadline, the SMTP client
# tries the next address on the mail exchanger list. Specify 0 to
# disable the timeout.
#
# smtp_connect_timeout = 30
smtp_connect_timeout = 0
# The smtp_helo_timeout parameter specifies the SMTP client timeout
# in seconds for receiving the SMTP greeting banner.
#
# When the server drops the connection without sending a greeting
# banner, or when it sends no greeting banner within the deadline,
# the SMTP client tries the next address on the mail exchanger list.
#
smtp_helo_timeout = 300
# The smtp_mail_timeout parameter specifies the SMTP client timeout
# in seconds for sending the SMTP MAIL FROM command, and for receiving
# the server response.
#
# In case of problems the client does NOT try the next address on
# the mail exchanger list.
#
smtp_mail_timeout = 300
# The smtp_rcpt_timeout parameter specifies the SMTP client timeout
# in seconds for sending the SMTP RCPT TO command, and for receiving
# the server response.
#
# In case of problems the client does NOT try the next address on
# the mail exchanger list.
#
smtp_rcpt_timeout = 300
# The smtp_data_init_timeout parameter specifies the SMTP client
# timeout in seconds for sending the SMTP DATA command, and for
# receiving the server response.
#
# In case of problems the client does NOT try the next address on
# the mail exchanger list.
#
smtp_data_init_timeout = 120
# The smtp_data_xfer_timeout parameter specifies the SMTP client
# timeout in seconds for sending the SMTP message content. When
# the connection stalls for more than $smtp_data_xfer_timeout the
# SMTP client terminates the transfer.
#
# In case of problems the client does NOT try the next address on
# the mail exchanger list.
#
smtp_data_xfer_timeout = 180
# The smtp_data_done_timeout parameter specifies the SMTP client
# timeout in seconds for sending the SMTP ".", and for receiving
# the server response.
#
# When no response is received within the deadline, a warning is
# logged that the mail may be delivered multiple times.
#
# In case of problems the client does NOT try the next address on
# the mail exchanger list.
#
smtp_data_done_timeout = 600
# The smtp_quit_timeout parameter specifies the SMTP client timeout
# in seconds for sending the SMTP QUIT command, and for receiving
# the server response.
#
smtp_quit_timeout = 300

View File

@@ -0,0 +1,272 @@
# This file contains example settings of Postfix configuration parameters
# that control the SMTP server program.
#
# MISCELLANEOUS
#
# The smtpd_banner parameter specifies the text that follows the 220
# status code in the SMTP greeting banner. Some people like to see
# the mail version advertised. By default, Postfix shows no version.
#
# You MUST specify the $myhostname at the start of the text. When
# the SMTP client sees its own hostname at the start of an SMTP
# greeting banner it will report a mailer loop. That's better than
# having a machine meltdown.
#
# smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
smtpd_banner = $myhostname ESMTP $mail_name
# The smtpd_recipient_limit parameter restricts the number of recipients
# that the SMTP server accepts per message delivery.
#
smtpd_recipient_limit = 1000
# The smtpd_timeout parameter limits the time in seconds to send an
# SMTP server response and to receive an SMTP client request.
#
# Note: if you set SMTP timeouts to large values you must update the
# global ipc_timeout parameter as well. See sample-misc.cf for details.
#
smtpd_timeout = 300
#
# TARPIT CONTROLS
#
# The smtpd_error_sleep_time parameter specifies the time in seconds
# the SMTP server waits before sending a 4xx or 5xx SMTP server error
# response. This prevents naive clients from going into an error -
# disconnect - connect - error loop.
#
smtpd_error_sleep_time = 5
# The smtpd_soft_error_limit parameter specifies an error count lower
# limit. When an SMTP client has made this number of errors within
# a session, the server waits error_count seconds before responding
# to any client request.
#
smtpd_soft_error_limit = 10
# The smtpd_hard_error_limit parameter specifies an error count upper
# limit. The SMTP server disconnects after an SMTP client makes this
# number of errors within a session.
#
smtpd_hard_error_limit = 100
#
# UCE RESTRICTIONS
#
# The smtpd_client_restrictions parameter specifies optional restrictions
# on SMTP client host names and addresses.
#
# The default is to allow connections from any host. The following
# restrictions are available:
#
# reject_unknown_client:reject the request if the client hostname is unknown.
# permit_mynetworks: permit if the client address matches $mynetworks.
# maptype:mapname: look up client name, parent domains, client address,
# or networks obtained by stripping octets.
# Reject if result is REJECT or "[45]xx text"
# Permit otherwise.
# reject_maps_rbl:reject if the client is listed under $maps_rbl_domains.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
#
# Restrictions are applied in the order as specified; the first
# restriction that matches wins.
#
# Specify a list of restrictions, separated by commas and/or whitespace.
# Continue long lines by starting the next line with whitespace.
#
smtpd_client_restrictions =
# The smtpd_helo_required parameter optionally turns on the requirement
# that SMTP clients must introduce themselves at the beginning of an
# SMTP session.
#
# smtpd_helo_required = yes
smtpd_helo_required = no
# The smtpd_helo_restrictions parameter specifies optional restrictions
# on what SMTP clients can send in SMTP HELO and EHLO commands.
#
# The default is to permit everything. The following restrictions
# are available:
#
# reject_unknown_client:reject the request if the client hostname is unknown.
# permit_mynetworks: permit if the client address matches $mynetworks.
# reject_invalid_hostname: reject HELO hostname with bad syntax.
# reject_unknown_hostname: reject HELO hostname without DNS A record.
# maptype:mapname: look up HELO hostname or parent domains.
# Reject if result is REJECT or "[45]xx text"
# Permit otherwise.
# check_client_access maptype:mapname: see smtpd_client_restrictions.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
#
# Restrictions are applied in the order as specified; the first
# restriction that matches wins.
#
# Specify a list of restrictions, separated by commas and/or whitespace.
# Continue long lines by starting the next line with whitespace.
#
# smtpd_helo_restrictions = reject_invalid_hostname
# smtpd_helo_restrictions = permit_mynetworks, reject_unknown_hostname
smtpd_helo_restrictions =
# The smtpd_sender_restrictions parameter specifies optional restrictions
# on sender addresses that SMTP clients can send in MAIL FROM commands.
#
# The default is to permit any sender address. The following
# restrictions are available:
#
# reject_unknown_client:reject the request if the client hostname is unknown.
# permit_mynetworks: permit if the client address matches $mynetworks.
# reject_unknown_address:reject if the sender domain has no A or MX record.
# maptype:mapname: look up sender address, parent domain, or localpart@.
# Reject if result is REJECT or "[45]xx text"
# Permit otherwise.
# check_client_access maptype:mapname: see smtpd_client_restrictions.
# check_helo_access maptype:mapname: see smtpd_helo_restrictions.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
#
# Restrictions are applied in the order as specified; the first
# restriction that matches wins.
#
# Specify a list of restrictions, separated by commas and/or whitespace.
# Continue long lines by starting the next line with whitespace.
#
# smtpd_sender_restrictions = reject_unknown_address
# smtpd_sender_restrictions = reject_unknown_address, hash:/etc/postfix/access
smtpd_sender_restrictions =
# The smtpd_recipient_restrictions parameter specifies restrictions on
# recipient addresses that SMTP clients can send in RCPT TO commands.
#
# The default is to permit any destination from clients that match
# $mynetworks, and to otherwise permit only mail from or to domains
# listed in $relay_domains.
#
# The following restrictions are available:
#
# reject_unknown_client:reject the request if the client hostname is unknown.
# permit_mynetworks: permit if the client address matches $mynetworks.
# check_relay_domains: permit only mail from/to domains in $relay_domains.
# permit_mx_backup: accept mail for sites that list me as MX host.
# maptype:mapname: look up recipient address, parent domain, or localpart@.
# Reject if result is REJECT or "[45]xx text"
# Permit otherwise.
# check_client_access maptype:mapname: see smtpd_client_restrictions.
# check_helo_access maptype:mapname: see smtpd_helo_restrictions.
# check_sender_access maptype:mapname: see smtpd_sender_restrictions.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
#
# Restrictions are applied in the order as specified; the first
# restriction that matches wins.
#
# Specify a list of restrictions, separated by commas and/or whitespace.
# Continue long lines by starting the next line with whitespace.
#
smtpd_recipient_restrictions = permit_mynetworks,check_relay_domains
#
# ADDITIONAL UCE CONTROLS
#
# The maps_rbl_domains parameter specifies an optional list of DNS
# domains that publish the network addresses of blacklisted hosts.
#
# By default, RBL blacklist lookups are disabled. See the
# smtpd_client_restrictions parameter.
#
# The real-time blackhole list works as follows: reverse the client
# network address, and reject service if it is listed below any of
# the following domains.
#
maps_rbl_domains = rbl.maps.vix.com
# The relay_domains parameter restricts what domains (and subdomains
# thereof) this mail system will relay mail from or to.
#
# By default, Postfix relays mail only from or to sites in or below
# $mydestination, or in the optional virtual domain list.
#
# Specify a list of hosts or domains, /file/name patterns or type:name
# lookup tables, separated by commas and/or whitespace. Continue
# long lines by starting the next line with whitespace. A file name
# is replaced by its contents; a type:name table is matched when a
# (parent) domain appears as lookup key.
#
# NOTE: Postfix will not automatically forward mail for domains that
# list this system as their primary or backup MX host. See the
# permit_mx_backup restriction, in the description of the
# smtpd_recipient_restrictions parameter.
#
relay_domains = $mydestination, $virtual_domains
#
# RESPONSE CODES
#
# The access_map_reject_code parameter specifies the SMTP server
# response code when a client violates an access map restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
access_map_reject_code = 550
# The invalid_hostname_reject_code parameter specifies the SMTP server
# response when a client violates the reject_invalid_hostname anti-UCE
# restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
invalid_hostname_reject_code = 501
# The maps_rbl_reject_code parameter specifies the SMTP server response
# when a client violates the maps_rbl_domains restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
maps_rbl_reject_code = 550
# The reject_code parameter specifies the SMTP server response code
# when an SMTP client matches a reject restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
reject_code = 550
# The relay_domains_reject_code parameter specifies the SMTP server
# response when a client attempts to violate the mail relay policy.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
relay_domains_reject_code = 550
# The unknown_address_reject_code parameter specifies the SMTP server
# response when a client violates the reject_unknown_address restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
unknown_address_reject_code = 450
# The unknown_client_reject_code parameter specifies the SMTP server
# response when a client without address to name mapping violates
# the reject_unknown_clients restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
unknown_client_reject_code = 450
# The unknown_hostname_reject_code parameter specifies the SMTP server
# response when a client violates the reject_unknown_hostname
# restriction.
#
# Do not change this unless you have a complete understanding of RFC 822.
#
unknown_hostname_reject_code = 450

View File

@@ -0,0 +1,15 @@
# This file contains example settings of Postfix configuration
# parameters that control the optional transport table lookups.
# The transport_maps parameter specifies optional tables with domain
# to (transport, nexthop) mappings. See transport(5) for syntax details.
#
# By default, this feature is disabled. Specify the types of databases
# to use. If you use this feature, run "postmap /etc/postfix/transport"
# after change, then "postfix reload".
#
# transport_maps = dbm:/etc/postfix/transport
# transport_maps = hash:/etc/postfix/transport
# transport_maps = hash:/etc/postfix/transport, nis:transport
# transport_maps = hash:/etc/postfix/transport, netinfo:/transport
transport_maps =

View File

@@ -0,0 +1,20 @@
# This file contains example settings of Postfix configuration
# parameters that control virtual database lookups.
# The virtual_maps parameter specifies optional lookup tables to
# redirect specific addresses or even complete domains to another
# address. This is typically used to implement virtual domain support.
#
# By default, no address redirection is done.
#
# If you use this feature, run "postmap /etc/postfix/virtual" to
# build the necessary DBM or DB file after change.
#
# It will take a minute or so before the change becomes visible.
# Use "postfix reload" to eliminate the delay.
#
# virtual_maps = dbm:/etc/postfix/virtual
# virtual_maps = hash:/etc/postfix/virtual
# virtual_maps = hash:/etc/postfix/virtual, nis:virtual
# virtual_maps = hash:/etc/postfix/virtual, netinfo:/virtual
virtual_maps =

101
postfix/conf/transport Normal file
View File

@@ -0,0 +1,101 @@
#++
# NAME
# transport 5
# SUMMARY
# format of Postfix transport table
# SYNOPSIS
# \fBpostmap /etc/postfix/transport\fR
# DESCRIPTION
# The optional \fBtransport\fR file specifies a mapping from domain
# hierarchies to message delivery transports and/or relay hosts. The
# mapping is used by the \fBtrivial-rewrite\fR(8) daemon.
#
# The file serves as input to the \fBpostmap\fR(1) command. The result,
# an indexed file in \fBdbm\fR or \fBdb\fR format, is used for
# fast searching by the mail system. After updating this table,
# issue the \fBpostfix reload\fR command to make the change visible.
#
# The format of the transport table is as follows:
# .IP "blanks and comments"
# Blank lines are ignored, as are lines beginning with `#'.
# .IP "\fIdomain transport\fR:\fInexthop\fR"
# Mail for \fIdomain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# .IP "\fI.domain transport\fR:\fInexthop\fR"
# Mail for any subdomain of \fIdomain\fR is delivered through
# \fItransport\fR to \fInexthop\fR.
#
# The interpretation of the \fInexthop\fR field is transport
# dependent. In the case of SMTP, specify \fIhost\fR:\fIservice\fR for a
# non-default server port, and use [\fIhost\fR] or [\fIhost\fR:\fIport\fR]
# in order to disable MX (mail exchanger) DNS lookups. The [] form
# can also be used with IP addresses instead of hostnames.
# EXAMPLES
# .ad
# In order to send mail for \fBfoo.org\fR and its subdomains
# via the \fBuucp\fR transport to the UUCP host named \fBfoo\fR:
#
# .ti +5
# \fBfoo.org uucp:foo\fR
# .ti +5
# \fB\&.foo.org uucp:foo\fR
#
# When no \fInexthop\fR host name is specified, the destination domain
# name is used instead. For example, the following directs mail for
# \fIuser\fR@\fBfoo.org\fR via the \fBslow\fR transport to a mail
# exchanger for \fBfoo.org\fR. The \fBslow\fR transport could be
# something that runs at most one delivery process at a time:
#
# .ti +5
# \fBfoo.org slow:\fR
#
# When no \fItransport\fR is specified, the default transport is
# used, as specified via the \fBdefault_transport\fR configuration
# parameter. The following sends all mail for \fBfoo.org\fR and its
# subdomains to host \fBgateway.foo.org\fR:
#
# .ti +5
# \fBfoo.org :[gateway.foo.org]\fR
# .ti +5
# \fB\&.foo.org :[gateway.foo.org]\fR
#
# In the above example, the [] are used to suppress MX lookups.
# The result would likely point to your local machine.
#
# In the case of delivery via SMTP, one may specify
# \fIhostname\fR:\fIservice\fR instead of just a host:
#
# .ti +5
# \fBfoo.org smtp:bar.org:2025\fR
#
# This directs mail for \fIuser\fR@\fBfoo.org\fR to host \fBbar.org\fR
# port \fB2025\fR. Instead of a numerical port a symbolic name may be
# used. Specify [] around the destination in order to disable MX lookups.
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The following \fBmain.cf\fR parameters are especially relevant to
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
# .IP \fBtransport_maps\fR
# List of transport lookup tables.
# .PP
# Other parameters of interest:
# .IP \fBdefault_transport\fR
# The transport to use when no transport is explicitly specified.
# .IP \fBrelayhost\fR
# The default host to send to when no transport table entry matches.
# SEE ALSO
# postmap(1) create mapping table
# trivial-rewrite(8) rewrite and resolve addresses
# 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
#--

102
postfix/conf/virtual Normal file
View File

@@ -0,0 +1,102 @@
#++
# NAME
# virtual 5
# SUMMARY
# format of Postfix virtual table
# SYNOPSIS
# \fBpostmap /etc/postfix/virtual\fR
# DESCRIPTION
# The optional \fBvirtual\fR table specifies redirections for local
# and non-local recipients or domains. The redirections are used by
# the \fBcleanup\fR(8) daemon. The redirections are recursive.
#
# The \fBvirtual\fR redirection is applied only to the recipient
# envelope address, and does not affect message headers.
# Think Sendmail rule set \fBS0\fR, if you like. Use \fBcanonical\fR(5)
# mapping to rewrite header and envelope addresses in general.
#
# The file serves as input to the \fBpostmap\fR(1) command. The
# result, an indexed file in \fBdbm\fR or \fBdb\fR format,
# is used for fast searching by the mail system. After an update
# it may take a minute or so before the change becomes visible.
# Issue a \fBpostfix reload\fR command to eliminate the delay.
#
# Typical support for a virtual domain looks like the following:
#
# .in +4
# .nf
# \fIvirtual.domain anything\fR (right-hand content does not matter)
# \fIuser1@virtual.domain address1\fR
# \fIuser2@virtual.domain address2, address3\fR
# .fi
# .in -4
#
# With this, the SMTP server accepts mail for \fIvirtual.domain\fR
# (provided that the \fBrelay_domains\fR parameter includes
# $\fBvirtual_maps\fR), and mail for \fIunknown\fR@\fIvirtual.domain\fR
# is bounced as undeliverable.
#
# The format of the virtual table is as follows, mappings being
# tried in the order as listed in this manual page:
# .IP "blanks and comments"
# Blank lines are ignored, as are lines beginning with `#'.
# .IP "\fIuser\fR@\fIdomain address, address, ...\fR"
# Mail for \fIuser\fR@\fIdomain\fR is redirected to \fIaddress\fR.
# This form has the highest precedence.
# .IP "\fIuser address, address, ...\fR"
# Mail for \fIuser\fR@\fIsite\fR is redirected to \fIaddress\fR when
# \fIsite\fR is equal to $\fBmyorigin\fR, when \fIsite\fR is listed in
# $\fRmydestination\fR, or when it is listed in $\fIinet_interfaces\fR.
# .sp
# This functionality overlaps with functionality of the local
# \fIalias\fR(5) database. The difference is that \fBvirtual\fR
# mapping can be applied to non-local addresses.
# .IP "@\fIdomain address, address, ...\fR"
# Mail for any user in \fIdomain\fR is redirected to \fIaddress\fR.
# This form has the lowest precedence.
# .PP
# In all the above forms, when \fIaddress\fR has the form
# @\fIotherdomain\fR, the result is the same user in \fIotherdomain\fR.
# This works for the first address in the expansion only.
# ADDRESS EXTENSION
# .fi
# .ad
# When the search fails, and the address localpart contains the
# optional recipient delimiter (e.g., \fIuser+foo\fR@\fIdomain\fR),
# the search is repeated for the unextended address (e.g.
# \fIuser\fR@\fIdomain\fR), and the unmatched address extension is
# propagated to the result of expansion. The matching order is:
# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR,
# \fIuser+foo\fR, \fIuser\fR, and @\fIdomain\fR.
# BUGS
# The table format does not understand quoting conventions.
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The following \fBmain.cf\fR parameters are especially relevant to
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
# .IP \fBvirtual_maps\fR
# List of virtual mapping tables.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
# The network interface addresses that this system receives mail on.
# .IP \fBmydestination\fR
# List of domains that this mail system considers local.
# .IP \fBmyorigin\fR
# The domain that is appended to locally-posted mail.
# SEE ALSO
# cleanup(8) canonicalize and enqueue mail
# postmap(1) create mapping table
# 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
#--

89
postfix/dns/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/dns/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

103
postfix/dns/Makefile.in Normal file
View File

@@ -0,0 +1,103 @@
SHELL = /bin/sh
SRCS = dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c
OBJS = dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o
HDRS = dns.h
TESTSRC = test_dns_lookup.c test_alias_token.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
INCL =
LIB = libdns.a
TESTPROG= test_dns_lookup
LIBS = ../lib/libutil.a
LIB_DIR = ../lib
INC_DIR = ../include
.c.o:; $(CC) $(CFLAGS) -c $*.c
all: $(LIB)
Makefile: Makefile.in
(set -e; echo "# DO NOT EDIT"; $(OPTS) sh ../makedefs; cat $?) >$@
test: $(TESTPROG)
$(LIB): $(OBJS)
$(AR) $(ARFL) $(LIB) $?
$(RANLIB) $(LIB)
$(LIB_DIR)/$(LIB): $(LIB)
cp $(LIB) $(LIB_DIR)
$(RANLIB) $(LIB_DIR)/$(LIB)
update: $(LIB_DIR)/$(LIB) $(HDRS)
-for i in $(HDRS); \
do \
cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
done
cd $(INC_DIR); chmod 644 $(HDRS)
test_dns_lookup: test_dns_lookup.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
cp *.h printfck
sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
clean:
rm -f *.o $(LIB) *core $(TESTPROG) junk
rm -rf printfck
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
dns_lookup.o: dns_lookup.c
dns_lookup.o: ../include/sys_defs.h
dns_lookup.o: ../include/mymalloc.h
dns_lookup.o: ../include/vstring.h
dns_lookup.o: ../include/vbuf.h
dns_lookup.o: ../include/msg.h
dns_lookup.o: ../include/valid_hostname.h
dns_lookup.o: dns.h
dns_rr.o: dns_rr.c
dns_rr.o: ../include/sys_defs.h
dns_rr.o: ../include/msg.h
dns_rr.o: ../include/mymalloc.h
dns_rr.o: dns.h
dns_rr.o: ../include/vstring.h
dns_rr.o: ../include/vbuf.h
dns_strerror.o: dns_strerror.c
dns_strerror.o: ../include/sys_defs.h
dns_strerror.o: ../include/vstring.h
dns_strerror.o: ../include/vbuf.h
dns_strerror.o: dns.h
dns_strtype.o: dns_strtype.c
dns_strtype.o: ../include/sys_defs.h
dns_strtype.o: ../include/vstring.h
dns_strtype.o: ../include/vbuf.h
dns_strtype.o: dns.h
test_dns_lookup.o: test_dns_lookup.c
test_dns_lookup.o: ../include/sys_defs.h
test_dns_lookup.o: ../include/vstring.h
test_dns_lookup.o: ../include/vbuf.h
test_dns_lookup.o: ../include/msg.h
test_dns_lookup.o: ../include/msg_vstream.h
test_dns_lookup.o: ../include/vstream.h
test_dns_lookup.o: dns.h

135
postfix/dns/dns.h Normal file
View File

@@ -0,0 +1,135 @@
#ifndef _DNS_H_INCLUDED_
#define _DNS_H_INCLUDED_
/*++
/* NAME
/* dns 3h
/* SUMMARY
/* domain name service lookup
/* SYNOPSIS
/* #include <dns.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <netinet/in.h>
#include <arpa/nameser.h>
#ifdef RESOLVE_H_NEEDS_STDIO_H
#include <stdio.h>
#endif
#include <resolv.h>
/*
* Name server compatibility. These undocumented macros appear in the file
* <arpa/nameser.h>, but since they are undocumented we should not count on
* their presence, and so they are included here just in case.
*/
#ifndef GETSHORT
#define GETSHORT(s, cp) { \
unsigned char *t_cp = (u_char *)(cp); \
(s) = ((unsigned)t_cp[0] << 8) \
| ((unsigned)t_cp[1]) \
; \
(cp) += 2; \
}
#define GETLONG(l, cp) { \
unsigned char *t_cp = (u_char *)(cp); \
(l) = ((unsigned)t_cp[0] << 24) \
| ((unsigned)t_cp[1] << 16) \
| ((unsigned)t_cp[2] << 8) \
| ((unsigned)t_cp[3]) \
; \
(cp) += 4; \
}
#endif
/*
* Utility library.
*/
#include <vstring.h>
/*
* Structure for fixed resource record data.
*/
typedef struct DNS_FIXED {
unsigned short type; /* T_A, T_CNAME, etc. */
unsigned short class; /* T_A, T_CNAME, etc. */
unsigned int ttl; /* always */
unsigned length; /* record length */
} DNS_FIXED;
/*
* Structure of a DNS resource record after expansion. The components are
* named after the things one can expect to find in a DNS resource record.
*/
typedef struct DNS_RR {
char *name; /* name, mystrdup()ed */
unsigned short type; /* T_A, T_CNAME, etc. */
unsigned short class; /* T_A, T_CNAME, etc. */
unsigned int ttl; /* always */
unsigned short pref; /* T_MX only */
struct DNS_RR *next; /* linkage */
unsigned data_len; /* actual data size */
char data[1]; /* actually a bunch of data */
} DNS_RR;
/*
* dns_strerror.c
*/
extern const char *dns_strerror(unsigned);
/*
* dns_strtype.c
*/
extern const char *dns_strtype(unsigned);
extern unsigned dns_type(const char *);
/*
* dns_rr.c
*/
extern DNS_RR *dns_rr_create(const char *, DNS_FIXED *, unsigned,
const char *, unsigned);
extern void dns_rr_free(DNS_RR *);
extern DNS_RR *dns_rr_append(DNS_RR *, DNS_RR *);
extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
/*
* dns_lookup.c
*/
extern int dns_lookup(const char *, unsigned, unsigned, DNS_RR **,
VSTRING *, VSTRING *);
extern int dns_lookup_types(const char *, unsigned, DNS_RR **,
VSTRING *, VSTRING *,...);
/*
* Status codes. Failures must have negative codes so they will not collide
* with valid counts of answer records etc.
*/
#define DNS_FAIL (-4) /* query failed, don't retry */
#define DNS_NOTFOUND (-3) /* query ok, data not found */
#define DNS_RETRY (-2) /* query failed, try again */
#define DNS_RECURSE (-1) /* recursion needed */
#define DNS_OK 0 /* query succeeded */
/*
* How long can a DNS name be?
*/
#define DNS_NAME_LEN 1024
/* 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
/*--*/
#endif

475
postfix/dns/dns_lookup.c Normal file
View File

@@ -0,0 +1,475 @@
/*++
/* NAME
/* dns_lookup 3
/* SUMMARY
/* domain name service lookup
/* SYNOPSIS
/* #include <dns.h>
/*
/* int dns_lookup(name, type, flags, list, fqdn, why)
/* const char *name;
/* unsigned type;
/* unsigned flags;
/* DNS_RR **list;
/* VSTRING *fqdn;
/* VSTRING *why;
/*
/* int dns_lookup_types(name, flags, list, fqdn, why, type, ...)
/* const char *name;
/* unsigned flags;
/* DNS_RR **list;
/* VSTRING *fqdn;
/* VSTRING *why;
/* unsigned type;
/* DESCRIPTION
/* dns_lookup() looks up DNS resource records. When requested to
/* look up data other than type CNAME, it will follow a limited
/* number of CNAME indirections. All result names (including
/* null terminator) will fit a buffer of size DNS_NAME_LEN.
/* All name results are validated by \fIvalid_hostname\fR();
/* an invalid name is reported as a transient error.
/*
/* dns_lookup_types() allows the user to specify a null-terminated
/* list of resource types. This function calls dns_lookup() for each
/* listed type in the specified order, until the list is exhausted or
/* until the search result becomes not equal to DNS_NOTFOUND.
/* INPUTS
/* .ad
/* .fi
/* .IP name
/* The name to be looked up in the domain name system.
/* .IP type
/* The resource record type to be looked up (T_A, T_MX etc.).
/* .IP flags
/* A bitwise OR of:
/* .RS
/* .IP RES_DEBUG
/* Print debugging information.
/* .IP RES_DNSRCH
/* Search local domain and parent domains.
/* .IP RES_DEFNAMES
/* Append local domain to unqualified names.
/* .RE
/* OUTPUTS
/* .ad
/* .fi
/* .IP list
/* A null pointer, or a pointer to a variable that receives a
/* list of requested resource records.
/* .IP fqdn
/* A null pointer, or storage for the fully-qualified domain
/* name found for \fIname\fR.
/* .IP why
/* A null pointer, or storage for the reason for failure.
/* DIAGNOSTICS
/* dns_lookup() returns one of the following codes and sets the
/* \fIwhy\fR argument accordingly:
/* .IP DNS_OK
/* The DNS query succeeded.
/* .IP DNS_NOTFOUND
/* The DNS query succeeded; the requested information was not found.
/* .IP DNS_RETRY
/* The query failed; the problem is transient.
/* .IP DNS_FAIL
/* The query failed.
/* BUGS
/* dns_lookup() implements a subset of all possible resource types:
/* CNAME, MX, A, and some records with similar formatting requirements.
/* It is unwise to specify the T_ANY wildcard resource type.
/*
/* It takes a surprising amount of code to accomplish what appears
/* to be a simple task. Later versions of the mail system may implement
/* their own DNS client software.
/* SEE ALSO
/* dns_rr(3) resource record memory and list management
/* 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 <netdb.h>
#include <stdlib.h> /* BSDI stdarg.h uses abort() */
#include <stdarg.h>
#include <string.h>
/* Utility library. */
#include <mymalloc.h>
#include <vstring.h>
#include <msg.h>
#include <valid_hostname.h>
/* DNS library. */
#include "dns.h"
/* Local stuff. */
/*
* Structure to keep track of things while decoding a name server reply.
*/
#define DNS_REPLY_SIZE 4096 /* in case we're using TCP */
typedef struct DNS_REPLY {
unsigned char buf[DNS_REPLY_SIZE]; /* raw reply data */
int query_count; /* number of queries */
int answer_count; /* number of answers */
unsigned char *query_start; /* start of query data */
unsigned char *answer_start; /* start of answer data */
unsigned char *end; /* first byte past reply */
} DNS_REPLY;
#define INET_ADDR_LEN 4 /* XXX */
/* dns_query - query name server and pre-parse the reply */
static int dns_query(const char *name, int type, int flags,
DNS_REPLY *reply, VSTRING *why)
{
HEADER *reply_header;
int len;
/*
* Initialize the name service.
*/
if ((_res.options & RES_INIT) == 0 && res_init() < 0) {
if (why)
vstring_strcpy(why, "Name service initialization failure");
return (DNS_FAIL);
}
/*
* Set search options: debugging, parent domain search, append local
* domain. Do not allow the user to control other features.
*/
#define USER_FLAGS (RES_DEBUG | RES_DNSRCH | RES_DEFNAMES)
if ((flags & USER_FLAGS) != flags)
msg_panic("dns_query: bad flags: %d", flags);
_res.options &= ~(USER_FLAGS);
_res.options |= flags;
/*
* Perform the lookup. Claim that the information cannot be found if and
* only if the name server told us so.
*/
len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
if (len < 0) {
if (why)
vstring_sprintf(why, "Name service error for domain %s: %s",
name, dns_strerror(h_errno));
if (msg_verbose)
msg_info("dns_query: %s (%s): %s",
name, dns_strtype(type), dns_strerror(h_errno));
switch (h_errno) {
case NO_RECOVERY:
return (DNS_FAIL);
case HOST_NOT_FOUND:
case NO_DATA:
return (DNS_NOTFOUND);
default:
return (DNS_RETRY);
}
}
if (msg_verbose)
msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
/*
* Initialize the reply structure. Some structure members are filled on
* the fly while the reply is being parsed.
*/
if ((reply->end = reply->buf + len) > reply->buf + sizeof(reply->buf))
reply->end = reply->buf + sizeof(reply->buf);
reply_header = (HEADER *) reply->buf;
reply->query_start = reply->buf + sizeof(HEADER);
reply->answer_start = 0;
reply->query_count = ntohs(reply_header->qdcount);
reply->answer_count = ntohs(reply_header->ancount);
return (DNS_OK);
}
/* dns_skip_query - skip query data in name server reply */
static int dns_skip_query(DNS_REPLY *reply)
{
int query_count = reply->query_count;
unsigned char *pos = reply->query_start;
char temp[DNS_NAME_LEN];
int len;
/*
* For each query, skip over the domain name and over the fixed query
* data.
*/
while (query_count-- > 0) {
if (pos >= reply->end)
return DNS_RETRY;
len = dn_expand(reply->buf, reply->end, pos, temp, DNS_NAME_LEN);
if (len < 0)
return (DNS_RETRY);
pos += len + QFIXEDSZ;
}
reply->answer_start = pos;
return (DNS_OK);
}
/* dns_get_fixed - extract fixed data from resource record */
static int dns_get_fixed(unsigned char *pos, DNS_FIXED *fixed)
{
GETSHORT(fixed->type, pos);
GETSHORT(fixed->class, pos);
GETLONG(fixed->ttl, pos);
GETSHORT(fixed->length, pos);
if (fixed->class != C_IN) {
msg_warn("dns_get_fixed: bad class: %u", fixed->class);
return (DNS_RETRY);
}
return (DNS_OK);
}
/* dns_get_rr - extract resource record from name server reply */
static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
char *rr_name, DNS_FIXED *fixed)
{
char temp[DNS_NAME_LEN];
int data_len = fixed->length;
unsigned pref = 0;
if (pos + fixed->length > reply->end)
return (0);
switch (fixed->type) {
default:
msg_panic("dns_get_rr: don't know how to extract resource type %s",
dns_strtype(fixed->type));
case T_CNAME:
case T_MB:
case T_MG:
case T_MR:
case T_NS:
case T_PTR:
if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
return (0);
if (!valid_hostname(temp))
return (0);
data_len = strlen(temp) + 1;
break;
case T_MX:
GETSHORT(pref, pos);
if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
return (0);
if (!valid_hostname(temp))
return (0);
data_len = strlen(temp) + 1;
break;
case T_A:
if (fixed->length != INET_ADDR_LEN) {
msg_warn("extract_answer: bad address length: %d", fixed->length);
return (0);
}
if (fixed->length > sizeof(temp))
msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
fixed->length);
memcpy(temp, pos, fixed->length);
data_len = fixed->length;
break;
}
return (dns_rr_create(rr_name, fixed, pref, temp, data_len));
}
/* dns_get_alias - extract CNAME from name server reply */
static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
DNS_FIXED *fixed, char *cname, int c_len)
{
if (fixed->type != T_CNAME)
msg_panic("dns_get_alias: bad type %s", dns_strtype(fixed->type));
if (dn_expand(reply->buf, reply->end, pos, cname, c_len) < 0)
return (DNS_RETRY);
if (!valid_hostname(cname))
return (DNS_RETRY);
return (DNS_OK);
}
/* dns_get_answer - extract answers from name server reply */
static int dns_get_answer(DNS_REPLY *reply, int type,
DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len)
{
char rr_name[DNS_NAME_LEN];
unsigned char *pos;
int answer_count = reply->answer_count;
int len;
DNS_FIXED fixed;
DNS_RR *rr;
int resource_found = 0;
int cname_found = 0;
/*
* Initialize. Skip over the name server query if we haven't yet.
*/
if (reply->answer_start == 0)
if (dns_skip_query(reply) < 0)
return (DNS_RETRY);
pos = reply->answer_start;
if (rrlist)
*rrlist = 0;
/*
* Either this, or use a GOTO for emergency exits. The purpose is to
* prevent incomplete answers from being passed back to the caller.
*/
#define CORRUPT { \
if (rrlist && *rrlist) { \
dns_rr_free(*rrlist); \
*rrlist = 0; \
} \
return (DNS_RETRY); \
}
/*
* Iterate over all answers.
*/
while (answer_count-- > 0) {
/*
* Optionally extract the fully-qualified domain name.
*/
if (pos >= reply->end)
CORRUPT;
len = dn_expand(reply->buf, reply->end, pos, rr_name, DNS_NAME_LEN);
if (len < 0)
CORRUPT;
if (!valid_hostname(rr_name))
CORRUPT;
if (fqdn)
vstring_strcpy(fqdn, rr_name);
pos += len;
/*
* Extract the fixed reply data: type, class, ttl, length.
*/
if (pos + RRFIXEDSZ > reply->end)
CORRUPT;
if (dns_get_fixed(pos, &fixed) != DNS_OK)
CORRUPT;
if (msg_verbose)
msg_info("dns_get_answer: type %s for %s",
dns_strtype(fixed.type), rr_name);
pos += RRFIXEDSZ;
/*
* Optionally extract the requested resource or CNAME data.
*/
if (pos + fixed.length > reply->end)
CORRUPT;
if (type == fixed.type || type == T_ANY) { /* requested type */
resource_found++;
if (rrlist) {
if ((rr = dns_get_rr(reply, pos, rr_name, &fixed)) == 0)
CORRUPT;
*rrlist = dns_rr_append(*rrlist, rr);
}
} else if (fixed.type == T_CNAME) { /* cname resource */
cname_found++;
if (cname && c_len > 0)
if (dns_get_alias(reply, pos, &fixed, cname, c_len) != DNS_OK)
CORRUPT;
}
pos += fixed.length;
}
/*
* See what answer we came up with. Report success when the requested
* information was found. Otherwise, when a CNAME was found, report that
* more recursion is needed. Otherwise report failure.
*/
if (resource_found)
return (DNS_OK);
if (cname_found)
return (DNS_RECURSE);
return (DNS_NOTFOUND);
}
/* dns_lookup - DNS lookup user interface */
int dns_lookup(const char *name, unsigned type, unsigned flags,
DNS_RR **rrlist, VSTRING *fqdn, VSTRING *why)
{
char cname[DNS_NAME_LEN];
int c_len = sizeof(cname);
DNS_REPLY reply;
int count;
int status;
/*
* Perform the lookup. Follow CNAME chains, but only up to a
* pre-determined maximum.
*/
for (count = 0; count < 10; count++) {
/*
* Perform the DNS lookup, and pre-parse the name server reply.
*/
if ((status = dns_query(name, type, flags, &reply, why)) != DNS_OK)
return (status);
/*
* Extract resource records of the requested type. Pick up CNAME
* information just in case the requested data is not found.
*/
status = dns_get_answer(&reply, type, rrlist, fqdn, cname, c_len);
switch (status) {
default:
if (why)
vstring_sprintf(why, "%s: Malformed name server reply", name);
case DNS_NOTFOUND:
case DNS_OK:
return (status);
case DNS_RECURSE:
if (msg_verbose)
msg_info("dns_lookup: %s aliased to %s", name, cname);
name = cname;
}
}
if (why)
vstring_sprintf(why, "Name server loop for %s", name);
msg_warn("dns_lookup: Name server loop for %s", name);
return (DNS_NOTFOUND);
}
/* dns_lookup_types - DNS lookup interface with multiple types */
int dns_lookup_types(const char *name, unsigned flags, DNS_RR **rrlist,
VSTRING *fqdn, VSTRING *why,...)
{
va_list ap;
unsigned type;
int status = DNS_NOTFOUND;
int soft_err = 0;
va_start(ap, why);
while ((type = va_arg(ap, unsigned)) != 0) {
if (msg_verbose)
msg_info("lookup %s type %d flags %d", name, type, flags);
status = dns_lookup(name, type, flags, rrlist, fqdn, why);
if (status == DNS_OK)
break;
if (status == DNS_RETRY)
soft_err = 1;
}
va_end(ap);
return ((status == DNS_OK || soft_err == 0) ? status : DNS_RETRY);
}

173
postfix/dns/dns_rr.c Normal file
View File

@@ -0,0 +1,173 @@
/*++
/* NAME
/* dns_rr 3
/* SUMMARY
/* resource record memory and list management
/* SYNOPSIS
/* #include <dns.h>
/*
/* DNS_RR *dns_rr_create(name, fixed, preference, data, data_len)
/* const char *name;
/* DNS_FIXED *fixed;
/* unsigned preference;
/* const char *data;
/* unsigned len;
/*
/* void dns_rr_free(list)
/* DNS_RR *list;
/*
/* DNS_RR *dns_rr_append(list, record)
/* DNS_RR *list;
/* DNS_RR *record;
/*
/* DNS_RR *dns_rr_sort(list, compar)
/* DNS_RR *list
/* int (*compar)(DNS_RR *, DNS_RR *);
/* DESCRIPTION
/* The routines in this module maintain memory for DNS resource record
/* information, and maintain lists of DNS resource records.
/*
/* dns_rr_create() creates and initializes one resource record.
/* The \fIname\fR record specifies the record name.
/* The \fIfixed\fR argument specifies generic resource record
/* information such as resource type and time to live;
/* \fIpreference\fR is used for MX records; \fIdata\fR is a null
/* pointer or specifies optional resource-specific data;
/* \fIdata_len\fR is the amount of resource-specific data.
/*
/* dns_rr_free() releases the resource used by of zero or more
/* resource records.
/*
/* dns_rr_append() appends a resource record to a (list of) resource
/* record(s).
/*
/* dns_rr_sort() sorts a list of resource records into ascending
/* order according to a user-specified criterion. The result is the
/* sorted list.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <string.h>
#include <stdlib.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
/* DNS library. */
#include "dns.h"
/* dns_rr_create - fill in resource record structure */
DNS_RR *dns_rr_create(const char *name, DNS_FIXED *fixed, unsigned pref,
const char *data, unsigned data_len)
{
DNS_RR *rr;
rr = (DNS_RR *) mymalloc(sizeof(*rr) + data_len - 1);
rr->name = mystrdup(name);
rr->type = fixed->type;
rr->class = fixed->class;
rr->ttl = fixed->ttl;
rr->pref = pref;
if (data && data_len > 0)
memcpy(rr->data, data, data_len);
rr->data_len = data_len;
rr->next = 0;
return (rr);
}
/* dns_rr_free - destroy resource record structure */
void dns_rr_free(DNS_RR *rr)
{
if (rr) {
if (rr->next)
dns_rr_free(rr->next);
myfree(rr->name);
myfree((char *) rr);
}
}
/* dns_rr_append - append resource record to list */
DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr)
{
if (list == 0) {
list = rr;
} else {
list->next = dns_rr_append(list->next, rr);
}
return (list);
}
/* dns_rr_sort_callback - glue function */
static int (*dns_rr_sort_user) (DNS_RR *, DNS_RR *);
static int dns_rr_sort_callback(const void *a, const void *b)
{
DNS_RR *aa = *(DNS_RR **) a;
DNS_RR *bb = *(DNS_RR **) b;
return (dns_rr_sort_user(aa, bb));
}
/* dns_rr_sort - sort resource record list */
DNS_RR *dns_rr_sort(DNS_RR *list, int (*compar) (DNS_RR *, DNS_RR *))
{
int (*saved_user) (DNS_RR *, DNS_RR *);
DNS_RR **rr_array;
DNS_RR *rr;
int len;
int i;
/*
* Save state and initialize.
*/
saved_user = dns_rr_sort_user;
dns_rr_sort_user = compar;
/*
* Build linear array with pointers to each list element.
*/
for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
/* void */ ;
rr_array = (DNS_RR **) mymalloc(len * sizeof(*rr_array));
for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
rr_array[len] = rr;
/*
* Sort by user-specified criterion.
*/
qsort((char *) rr_array, len, sizeof(*rr_array), dns_rr_sort_callback);
/*
* Fix the links.
*/
for (i = 0; i < len - 1; i++)
rr_array[i]->next = rr_array[i + 1];
rr_array[i]->next = 0;
list = rr_array[0];
/*
* Cleanup.
*/
myfree((char *) rr_array);
dns_rr_sort_user = saved_user;
return (list);
}

View File

@@ -0,0 +1,69 @@
/*++
/* NAME
/* dns_strerror 3
/* SUMMARY
/* name service lookup error code to string
/* SYNOPSIS
/* #include <dhs.h>
/*
/* const char *dns_strerror(code)
/* int code;
/* DESCRIPTION
/* dns_strerror() maps a name service lookup error to printable string.
/* The result is for read-only purposes, and unknown codes share a
/* common string buffer.
/* 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 <netdb.h>
/* Utility library. */
#include <vstring.h>
/* DNS library. */
#include "dns.h"
/*
* Mapping from error code to printable string. The herror() routine does
* something similar, but has output only to the stderr stream.
*/
struct dns_error_map {
unsigned error;
const char *text;
};
static struct dns_error_map dns_error_map[] = {
HOST_NOT_FOUND, "Host not found",
TRY_AGAIN, "Host not found, try again",
NO_RECOVERY, "Non-recoverable error",
NO_DATA, "Host found but no data record of requested type",
};
/* dns_strerror - map resolver error code to printable string */
const char *dns_strerror(unsigned error)
{
static VSTRING *unknown = 0;
unsigned i;
for (i = 0; i < sizeof(dns_error_map) / sizeof(dns_error_map[0]); i++)
if (dns_error_map[i].error == error)
return (dns_error_map[i].text);
if (unknown == 0)
unknown = vstring_alloc(sizeof("Unknown error XXXXXX"));
vstring_sprintf(unknown, "Unknown error %u", error);
return (vstring_str(unknown));
}

200
postfix/dns/dns_strtype.c Normal file
View File

@@ -0,0 +1,200 @@
/*++
/* NAME
/* dns_strtype 3
/* SUMMARY
/* name service lookup type codes and printable forms
/* SYNOPSIS
/* #include <dns.h>
/*
/* const char *dns_strtype(code)
/* int code;
/*
/* int dns_type(strval)
/* const char *strval;
/* DESCRIPTION
/* dns_strtype() maps a name service lookup type to printable string.
/* The result is for read-only purposes, and unknown codes share a
/* common string buffer.
/*
/* dns_type() converts a name service lookup string value to a numeric
/* code. A null result means the code was not found. The input can be
/* in lower case, upper case or mixed case.
/* 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 <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <vstring.h>
/* DNS library. */
#include "dns.h"
/*
* Mapping from type code to printable string. Some names are possibly not
* defined on every platform, so I have #ifdef-ed them all just to be safe.
*/
struct dns_type_map {
unsigned type;
const char *text;
};
static struct dns_type_map dns_type_map[] = {
#ifdef T_A
T_A, "A",
#endif
#ifdef T_NS
T_NS, "NS",
#endif
#ifdef T_MD
T_MD, "MD",
#endif
#ifdef T_MF
T_MF, "MF",
#endif
#ifdef T_CNAME
T_CNAME, "CNAME",
#endif
#ifdef T_SOA
T_SOA, "SOA",
#endif
#ifdef T_MB
T_MB, "MB",
#endif
#ifdef T_MG
T_MG, "MG",
#endif
#ifdef T_MR
T_MR, "MR",
#endif
#ifdef T_NULL
T_NULL, "NULL",
#endif
#ifdef T_WKS
T_WKS, "WKS",
#endif
#ifdef T_PTR
T_PTR, "PTR",
#endif
#ifdef T_HINFO
T_HINFO, "HINFO",
#endif
#ifdef T_MINFO
T_MINFO, "MINFO",
#endif
#ifdef T_MX
T_MX, "MX",
#endif
#ifdef T_TXT
T_TXT, "TXT",
#endif
#ifdef T_RP
T_RP, "RP",
#endif
#ifdef T_AFSDB
T_AFSDB, "AFSDB",
#endif
#ifdef T_X25
T_X25, "X25",
#endif
#ifdef T_ISDN
T_ISDN, "ISDN",
#endif
#ifdef T_RT
T_RT, "RT",
#endif
#ifdef T_NSAP
T_NSAP, "NSAP",
#endif
#ifdef T_NSAP_PTR
T_NSAP_PTR, "NSAP_PTR",
#endif
#ifdef T_SIG
T_SIG, "SIG",
#endif
#ifdef T_KEY
T_KEY, "KEY",
#endif
#ifdef T_PX
T_PX, "PX",
#endif
#ifdef T_GPOS
T_GPOS, "GPOS",
#endif
#ifdef T_AAAA
T_AAAA, "AAAA",
#endif
#ifdef T_LOC
T_LOC, "LOC",
#endif
#ifdef T_UINFO
T_UINFO, "UINFO",
#endif
#ifdef T_UID
T_UID, "UID",
#endif
#ifdef T_GID
T_GID, "GID",
#endif
#ifdef T_UNSPEC
T_UNSPEC, "UNSPEC",
#endif
#ifdef T_AXFR
T_AXFR, "AXFR",
#endif
#ifdef T_MAILB
T_MAILB, "MAILB",
#endif
#ifdef T_MAILA
T_MAILA, "MAILA",
#endif
#ifdef T_ANY
T_ANY, "ANY",
#endif
};
/* dns_strtype - translate DNS query type to string */
const char *dns_strtype(unsigned type)
{
static VSTRING *unknown = 0;
unsigned i;
for (i = 0; i < sizeof(dns_type_map) / sizeof(dns_type_map[0]); i++)
if (dns_type_map[i].type == type)
return (dns_type_map[i].text);
if (unknown == 0)
unknown = vstring_alloc(sizeof("Unknown type XXXXXX"));
vstring_sprintf(unknown, "Unknown type %u", type);
return (vstring_str(unknown));
}
/* dns_type - translate string to DNS query type */
unsigned dns_type(const char *text)
{
unsigned i;
for (i = 0; i < sizeof(dns_type_map) / sizeof(dns_type_map[0]); i++)
if (strcasecmp(dns_type_map[i].text, text) == 0)
return (dns_type_map[i].type);
return (0);
}

View File

@@ -0,0 +1,95 @@
/*++
/* NAME
/* test_dns_lookup 1
/* SUMMARY
/* DNS lookup test program
/* SYNOPSIS
/* test_dns_lookup query-type domain-name
/* DESCRIPTION
/* test_dns_lookup performs a DNS query of the specified resource
/* type for the specified resource name.
/* DIAGNOSTICS
/* Problems are reported to the standard error stream.
/* 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 <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
/* Utility library. */
#include <vstring.h>
#include <msg.h>
#include <msg_vstream.h>
/* Application-specific. */
#include "dns.h"
static void print_rr(DNS_RR *rr)
{
struct in_addr addr;
while (rr) {
printf("%s: ttl: %9d ", rr->name, rr->ttl);
switch (rr->type) {
case T_A:
memcpy((char *) &addr.s_addr, rr->data, sizeof(addr.s_addr));
printf("%s: %s\n", dns_strtype(rr->type), inet_ntoa(addr));
break;
case T_CNAME:
case T_MB:
case T_MG:
case T_MR:
case T_NS:
case T_PTR:
printf("%s: %s\n", dns_strtype(rr->type), rr->data);
break;
case T_MX:
printf("pref: %d %s: %s\n",
rr->pref, dns_strtype(rr->type), rr->data);
break;
default:
msg_fatal("print_rr: don't know how to print type %s",
dns_strtype(rr->type));
}
rr = rr->next;
}
}
int main(int argc, char **argv)
{
int type;
char *name;
VSTRING *fqdn = vstring_alloc(100);
VSTRING *why = vstring_alloc(100);
DNS_RR *rr;
msg_vstream_init(argv[0], VSTREAM_ERR);
if (argc != 3)
msg_fatal("usage: %s type name", argv[0]);
if ((type = dns_type(argv[1])) == 0)
msg_fatal("invalid query type: %s", argv[1]);
name = argv[2];
msg_verbose = 1;
switch (dns_lookup_types(name, RES_DEFNAMES | RES_DEBUG, &rr, fqdn, why, type, 0)) {
default:
msg_fatal("%s", vstring_str(why));
case DNS_OK:
printf("%s: fqdn: %s\n", name, vstring_str(fqdn));
print_rr(rr);
}
exit(0);
}

89
postfix/fsstone/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/fsstone/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

View File

@@ -0,0 +1,62 @@
SHELL = /bin/sh
SRCS = fsstone.c
OBJS = fsstone.o
HDRS =
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
PROG = fsstone
INC_DIR = ../include
LIBS = ../lib/libglobal.a ../lib/libutil.a
.c.o:; $(CC) $(CFLAGS) -c $*.c
all: $(PROG)
Makefile: Makefile.in
(set -e; echo "# DO NOT EDIT"; $(OPTS) sh ../makedefs; cat $?) >$@
fsstone: fsstone.o $(LIBS)
$(CC) $(CFLAGS) -o $@ fsstone.o $(LIBS) $(SYSLIBS)
test: $(TESTPROG)
update: ../bin/fsstone
../bin/fsstone: fsstone
cp $? $@
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
clean:
rm -f *.o *core $(PROG) $(TESTPROG) junk
rm -rf printfck
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
fsstone.o: fsstone.c
fsstone.o: ../include/sys_defs.h
fsstone.o: ../include/msg.h
fsstone.o: ../include/msg_vstream.h
fsstone.o: ../include/vstream.h
fsstone.o: ../include/vbuf.h

211
postfix/fsstone/fsstone.c Normal file
View File

@@ -0,0 +1,211 @@
/*++
/* NAME
/* fsstone 1
/* SUMMARY
/* measure directory operation overhead
/* SYNOPSIS
/* \fBfsstone\fR [\fB-c\fR] [\fB-r\fR] \fImsg_count files_per_dir\fR
/* DESCRIPTION
/* The \fBfsstone\fR command measures the cost of creating, renaming
/* and deleting queue files versus appending messages to existing
/* files and truncating them after use.
/*
/* The program simulates the arrival of \fImsg_count\fR short messages,
/* and arranges for at most \fIfiles_per_dir\fR simultaneous files
/* in the same directory.
/*
/* Options:
/* .IP \fB-c\fR
/* Create and delete files.
/* .IP \fB-r\fR
/* Rename files twice (requires \fB-c\fR).
/* DIAGNOSTICS
/* Problems are reported to the standard error stream.
/* BUGS
/* The \fB-r\fR option renames files within the same directory.
/* For a more realistic simulation, the program should rename files
/* <i>between</i> directories, and should also have an option to use
/* <i>hashed</i> directories as implemented with, for example, the
/* \fBdir_forest\fR(3) module.
/* 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 <stdlib.h>
#include <unistd.h>
#include <time.h>
/* Utility library. */
#include <msg.h>
#include <msg_vstream.h>
/* rename_file - rename a file */
static void rename_file(int old, int new)
{
char new_path[BUFSIZ];
char old_path[BUFSIZ];
sprintf(new_path, "%06d", new);
sprintf(old_path, "%06d", old);
if (rename(old_path, new_path))
msg_fatal("rename %s to %s: %m", old_path, new_path);
}
/* make_file - create a little file and use it */
static void make_file(int seqno)
{
char path[BUFSIZ];
FILE *fp;
int i;
sprintf(path, "%06d", seqno);
if ((fp = fopen(path, "w")) == 0)
msg_fatal("open %s: %m", path);
for (i = 0; i < 400; i++)
fprintf(fp, "hello");
if (fsync(fileno(fp)))
msg_fatal("fsync: %m");
if (fclose(fp))
msg_fatal("fclose: %m");
if ((fp = fopen(path, "r")) == 0)
msg_fatal("open %s: %m", path);
while (fgets(path, sizeof(path), fp))
/* void */ ;
if (fclose(fp))
msg_fatal("fclose: %m");
}
/* use_file - use existing file */
static void use_file(int seqno)
{
char path[BUFSIZ];
FILE *fp;
int i;
sprintf(path, "%06d", seqno);
if ((fp = fopen(path, "w")) == 0)
msg_fatal("open %s: %m", path);
for (i = 0; i < 400; i++)
fprintf(fp, "hello");
if (fsync(fileno(fp)))
msg_fatal("fsync: %m");
if (fclose(fp))
msg_fatal("fclose: %m");
if ((fp = fopen(path, "r+")) == 0)
msg_fatal("open %s: %m", path);
while (fgets(path, sizeof(path), fp))
/* void */ ;
if (ftruncate(fileno(fp), (off_t) 0))
msg_fatal("ftruncate: %m");;
if (fclose(fp))
msg_fatal("fclose: %m");
}
/* remove_file - delete specified file */
static void remove_file(int seq)
{
char path[BUFSIZ];
sprintf(path, "%06d", seq);
if (remove(path))
msg_fatal("remove %s: %m", path);
}
/* remove_silent - delete specified file, silently */
static void remove_silent(int seq)
{
char path[BUFSIZ];
sprintf(path, "%06d", seq);
(void) remove(path);
}
/* usage - explain */
static void usage(char *myname)
{
msg_fatal("usage: %s [-c [-r]] messages directory_entries", myname);
}
int main(int argc, char **argv)
{
int op_count;
int max_file;
time_t start;
int do_rename = 0;
int do_create = 0;
int seq;
int ch;
msg_vstream_init(argv[0], VSTREAM_ERR);
while ((ch = GETOPT(argc, argv, "cr")) != EOF) {
switch (ch) {
case 'c':
do_create++;
break;
case 'r':
do_rename++;
break;
default:
usage(argv[0]);
}
}
if (argc - optind != 2 || (do_rename && !do_create))
usage(argv[0]);
if ((op_count = atoi(argv[optind])) <= 0)
usage(argv[0]);
if ((max_file = atoi(argv[optind + 1])) <= 0)
usage(argv[0]);
/*
* Populate the directory with little files.
*/
for (seq = 0; seq < max_file; seq++)
make_file(seq);
/*
* Simulate arrival and delivery of mail messages.
*/
start = time((time_t *) 0);
while (op_count > 0) {
seq %= max_file;
if (do_create) {
remove_file(seq);
make_file(seq);
if (do_rename) {
rename_file(seq, seq + max_file);
rename_file(seq + max_file, seq);
}
} else {
use_file(seq);
}
seq++;
op_count--;
}
printf("elapsed time: %ld\n", (long) time((time_t *) 0) - start);
/*
* Clean up directory fillers.
*/
for (seq = 0; seq < max_file; seq++)
remove_silent(seq);
return (0);
}

89
postfix/global/.indent.pro vendored Normal file
View File

@@ -0,0 +1,89 @@
-TALIAS_TOKEN
-TARGV
-TBH_TABLE
-TBINHASH
-TBINHASH_INFO
-TBOUNCE_STAT
-TCLEANUP_STATE
-TCLIENT_LIST
-TCONFIG_BOOL_FN_TABLE
-TCONFIG_BOOL_TABLE
-TCONFIG_INT_FN_TABLE
-TCONFIG_INT_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDICT
-TDICT_DB
-TDICT_DBM
-TDICT_ENV
-TDICT_HT
-TDICT_LDAP
-TDICT_NI
-TDICT_NIS
-TDICT_NISPLUS
-TDICT_NODE
-TDICT_OPEN_INFO
-TDNS_FIXED
-TDNS_REPLY
-TDNS_RR
-TDOMAIN_LIST
-TEXPAND_ATTR
-TFILE
-TFORWARD_INFO
-THEADER_OPTS
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TINT_TABLE
-TLOCAL_STATE
-TMAC_HEAD
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TMASTER_STATUS
-TMBLOCK
-TMKMAP
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TQMGR_ENTRY
-TQMGR_MESSAGE
-TQMGR_QUEUE
-TQMGR_RCPT_LIST
-TQMGR_RECIPIENT
-TQMGR_SCAN
-TQMGR_TRANSPORT
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TSCAN_DIR
-TSINGLE_SERVER
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
-TSMTP_SESSION
-TSMTP_STATE
-TSOCKADDR_SIZE
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
-TTRIGGER_SERVER
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TVSTRING
-TWAIT_STATUS_T

24
postfix/global/.printfck Normal file
View File

@@ -0,0 +1,24 @@
been_here_xt 2 0
bounce_append 5 0
cleanup_out_format 1 0
defer_append 5 0
mail_command 1 0
mail_print 1 0
msg_error 0 0
msg_fatal 0 0
msg_info 0 0
msg_panic 0 0
msg_warn 0 0
opened 3 0
qmgr_message_bounce 2 0
rec_fprintf 2 0
sent 4 0
smtp_cmd 1 0
smtp_mesg_fail 2 0
smtp_printf 1 0
smtp_rcpt_fail 3 0
smtp_site_fail 2 0
udp_syslog 1 0
vstream_fprintf 1 0
vstream_printf 0 0
vstring_sprintf 1 0

842
postfix/global/Makefile.in Normal file
View File

@@ -0,0 +1,842 @@
SHELL = /bin/sh
SRCS = been_here.c bounce.c canon_addr.c clean_env.c cleanup_strerror.c \
config.c config_bool.c config_int.c config_str.c debug_peer.c \
debug_process.c defer.c deliver_completed.c deliver_flock.c \
deliver_request.c domain_list.c dot_lockfile.c file_id.c \
header_opts.c is_header.c mail_addr.c mail_addr_crunch.c \
mail_addr_find.c mail_addr_map.c mail_command_read.c \
mail_command_write.c mail_connect.c mail_copy.c mail_date.c \
mail_error.c mail_flush.c mail_open_ok.c mail_params.c \
mail_pathname.c mail_print.c mail_queue.c mail_run.c mail_scan.c \
mail_task.c mail_trigger.c maps.c mark_corrupt.c mkmap_db.c \
mkmap_dbm.c mkmap_open.c mynetworks.c mypwd.c namadr_list.c \
off_cvt.c opened.c own_inet_addr.c pipe_command.c post_mail.c \
quote_822_local.c rec_streamlf.c rec_type.c recipient_list.c \
record.c remove.c resolve_clnt.c resolve_local.c rewrite_clnt.c \
sent.c smtp_stream.c split_addr.c string_list.c sys_exits.c \
timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c mail_stream.c
OBJS = been_here.o bounce.o canon_addr.o clean_env.o cleanup_strerror.o \
config.o config_bool.o config_int.o config_str.o debug_peer.o \
debug_process.o defer.o deliver_completed.o deliver_flock.o \
deliver_request.o domain_list.o dot_lockfile.o file_id.o \
header_opts.o is_header.o mail_addr.o mail_addr_crunch.o \
mail_addr_find.o mail_addr_map.o mail_command_read.o \
mail_command_write.o mail_connect.o mail_copy.o mail_date.o \
mail_error.o mail_flush.o mail_open_ok.o mail_params.o \
mail_pathname.o mail_print.o mail_queue.o mail_run.o mail_scan.o \
mail_task.o mail_trigger.o maps.o mark_corrupt.o mkmap_db.o \
mkmap_dbm.o mkmap_open.o mynetworks.o mypwd.o namadr_list.o \
off_cvt.o opened.o own_inet_addr.o pipe_command.o post_mail.o \
quote_822_local.o rec_streamlf.o rec_type.o recipient_list.o \
record.o remove.o resolve_clnt.o resolve_local.o rewrite_clnt.o \
sent.o smtp_stream.o split_addr.o string_list.o sys_exits.o \
timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o mail_stream.o
HDRS = been_here.h bounce.h canon_addr.h clean_env.h cleanup_user.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_request.h domain_list.h dot_lockfile.h \
file_id.h header_opts.h is_header.h mail_addr.h mail_addr_crunch.h \
mail_addr_find.h mail_addr_map.h mail_copy.h mail_date.h \
mail_error.h mail_flush.h mail_open_ok.h mail_params.h \
mail_proto.h mail_queue.h mail_run.h mail_task.h mail_version.h \
maps.h mark_corrupt.h mkmap.h mynetworks.h mypwd.h namadr_list.h \
off_cvt.h opened.h own_inet_addr.h pipe_command.h post_mail.h \
quote_822_local.h rec_streamlf.h rec_type.h recipient_list.h \
record.h resolve_clnt.h resolve_local.h rewrite_clnt.h sent.h \
smtp_stream.h split_addr.h string_list.h sys_exits.h timed_ipc.h \
tok822.h mail_stream.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
INCL =
LIB = libglobal.a
TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
mail_addr_map mail_date maps mynetworks mypwd namadr_list \
off_cvt quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse
LIBS = ../lib/libutil.a
LIB_DIR = ../lib
INC_DIR = ../include
MAKES =
.c.o:; $(CC) $(CFLAGS) -c $*.c
all: $(LIB)
Makefile: Makefile.in
(set -e; echo "# DO NOT EDIT"; $(OPTS) sh ../makedefs; cat $?) >$@
test: $(TESTPROG)
$(LIB): $(OBJS)
$(AR) $(ARFL) $(LIB) $?
$(RANLIB) $(LIB)
$(LIB_DIR)/$(LIB): $(LIB)
cp $(LIB) $(LIB_DIR)
$(RANLIB) $(LIB_DIR)/$(LIB)
update: $(LIB_DIR)/$(LIB) $(HDRS)
-for i in $(HDRS); \
do \
cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
done
cd $(INC_DIR); chmod 644 $(HDRS)
dot_lockfile: $(LIB) $(LIBS)
mv $@.o junk
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
tok822_parse: $(LIB) $(LIBS)
mv $@.o junk
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
rec2stream: rec2stream.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
stream2rec: stream2rec.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
recdump: recdump.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
namadr_list: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
domain_list: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mynetworks: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
resolve_clnt: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
rewrite_clnt: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
quote_822_local: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
off_cvt: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mail_addr_map: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mail_addr_find: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
maps: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mypwd: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mail_date: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
resolve_local: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
mail_addr_crunch: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
string_list: $(LIB) $(LIBS)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
cp *.h printfck
sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
clean:
rm -f *.o $(LIB) *core $(TESTPROG) junk
rm -rf printfck
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
been_here.o: been_here.c
been_here.o: ../include/sys_defs.h
been_here.o: ../include/msg.h
been_here.o: ../include/mymalloc.h
been_here.o: ../include/htable.h
been_here.o: ../include/vstring.h
been_here.o: ../include/vbuf.h
been_here.o: ../include/stringops.h
been_here.o: been_here.h
bounce.o: bounce.c
bounce.o: ../include/sys_defs.h
bounce.o: ../include/msg.h
bounce.o: ../include/vstring.h
bounce.o: ../include/vbuf.h
bounce.o: mail_proto.h
bounce.o: ../include/vstream.h
bounce.o: ../include/iostuff.h
bounce.o: defer.h
bounce.o: bounce.h
canon_addr.o: canon_addr.c
canon_addr.o: ../include/sys_defs.h
canon_addr.o: ../include/vstring.h
canon_addr.o: ../include/vbuf.h
canon_addr.o: ../include/mymalloc.h
canon_addr.o: rewrite_clnt.h
canon_addr.o: canon_addr.h
clean_env.o: clean_env.c
clean_env.o: ../include/sys_defs.h
clean_env.o: ../include/msg.h
clean_env.o: clean_env.h
cleanup_strerror.o: cleanup_strerror.c
cleanup_strerror.o: ../include/sys_defs.h
cleanup_strerror.o: ../include/vstring.h
cleanup_strerror.o: ../include/vbuf.h
cleanup_strerror.o: cleanup_user.h
config.o: config.c
config.o: ../include/sys_defs.h
config.o: ../include/msg.h
config.o: ../include/mymalloc.h
config.o: ../include/vstream.h
config.o: ../include/vbuf.h
config.o: ../include/vstring.h
config.o: ../include/dict.h
config.o: ../include/safe.h
config.o: ../include/stringops.h
config.o: mail_params.h
config.o: config.h
config_bool.o: config_bool.c
config_bool.o: ../include/sys_defs.h
config_bool.o: ../include/msg.h
config_bool.o: ../include/dict.h
config_bool.o: ../include/vstream.h
config_bool.o: ../include/vbuf.h
config_bool.o: config.h
config_int.o: config_int.c
config_int.o: ../include/sys_defs.h
config_int.o: ../include/msg.h
config_int.o: ../include/mymalloc.h
config_int.o: ../include/dict.h
config_int.o: ../include/vstream.h
config_int.o: ../include/vbuf.h
config_int.o: ../include/stringops.h
config_int.o: config.h
config_str.o: config_str.c
config_str.o: ../include/sys_defs.h
config_str.o: ../include/msg.h
config_str.o: ../include/mymalloc.h
config_str.o: config.h
debug_peer.o: debug_peer.c
debug_peer.o: ../include/sys_defs.h
debug_peer.o: ../include/msg.h
debug_peer.o: mail_params.h
debug_peer.o: namadr_list.h
debug_peer.o: debug_peer.h
debug_process.o: debug_process.c
debug_process.o: ../include/sys_defs.h
debug_process.o: ../include/msg.h
debug_process.o: mail_params.h
debug_process.o: config.h
debug_process.o: debug_process.h
defer.o: defer.c
defer.o: ../include/sys_defs.h
defer.o: ../include/msg.h
defer.o: ../include/vstring.h
defer.o: ../include/vbuf.h
defer.o: mail_queue.h
defer.o: ../include/vstream.h
defer.o: mail_proto.h
defer.o: ../include/iostuff.h
defer.o: bounce.h
defer.o: defer.h
deliver_completed.o: deliver_completed.c
deliver_completed.o: ../include/sys_defs.h
deliver_completed.o: ../include/msg.h
deliver_completed.o: ../include/vstream.h
deliver_completed.o: ../include/vbuf.h
deliver_completed.o: record.h
deliver_completed.o: ../include/vstring.h
deliver_completed.o: rec_type.h
deliver_completed.o: deliver_completed.h
deliver_flock.o: deliver_flock.c
deliver_flock.o: ../include/sys_defs.h
deliver_flock.o: ../include/vstring.h
deliver_flock.o: ../include/vbuf.h
deliver_flock.o: ../include/myflock.h
deliver_flock.o: mail_params.h
deliver_flock.o: deliver_flock.h
deliver_request.o: deliver_request.c
deliver_request.o: ../include/sys_defs.h
deliver_request.o: ../include/msg.h
deliver_request.o: ../include/vstream.h
deliver_request.o: ../include/vbuf.h
deliver_request.o: ../include/vstring.h
deliver_request.o: ../include/mymalloc.h
deliver_request.o: ../include/iostuff.h
deliver_request.o: mail_queue.h
deliver_request.o: mail_proto.h
deliver_request.o: mail_open_ok.h
deliver_request.o: recipient_list.h
deliver_request.o: deliver_request.h
domain_list.o: domain_list.c
domain_list.o: ../include/sys_defs.h
domain_list.o: ../include/match_list.h
domain_list.o: ../include/match_ops.h
domain_list.o: domain_list.h
dot_lockfile.o: dot_lockfile.c
dot_lockfile.o: ../include/sys_defs.h
dot_lockfile.o: ../include/vstring.h
dot_lockfile.o: ../include/vbuf.h
dot_lockfile.o: ../include/stringops.h
dot_lockfile.o: ../include/mymalloc.h
dot_lockfile.o: mail_params.h
dot_lockfile.o: dot_lockfile.h
file_id.o: file_id.c
file_id.o: ../include/sys_defs.h
file_id.o: ../include/msg.h
file_id.o: ../include/vstring.h
file_id.o: ../include/vbuf.h
file_id.o: file_id.h
header_opts.o: header_opts.c
header_opts.o: ../include/sys_defs.h
header_opts.o: ../include/msg.h
header_opts.o: ../include/htable.h
header_opts.o: ../include/vstring.h
header_opts.o: ../include/vbuf.h
header_opts.o: header_opts.h
is_header.o: is_header.c
is_header.o: ../include/sys_defs.h
is_header.o: is_header.h
mail_addr.o: mail_addr.c
mail_addr.o: ../include/sys_defs.h
mail_addr.o: ../include/stringops.h
mail_addr.o: mail_params.h
mail_addr.o: mail_addr.h
mail_addr_crunch.o: mail_addr_crunch.c
mail_addr_crunch.o: ../include/sys_defs.h
mail_addr_crunch.o: ../include/mymalloc.h
mail_addr_crunch.o: ../include/argv.h
mail_addr_crunch.o: ../include/vstring.h
mail_addr_crunch.o: ../include/vbuf.h
mail_addr_crunch.o: tok822.h
mail_addr_crunch.o: resolve_clnt.h
mail_addr_crunch.o: canon_addr.h
mail_addr_crunch.o: mail_addr_crunch.h
mail_addr_find.o: mail_addr_find.c
mail_addr_find.o: ../include/sys_defs.h
mail_addr_find.o: ../include/msg.h
mail_addr_find.o: ../include/dict.h
mail_addr_find.o: ../include/vstream.h
mail_addr_find.o: ../include/vbuf.h
mail_addr_find.o: ../include/stringops.h
mail_addr_find.o: ../include/mymalloc.h
mail_addr_find.o: ../include/vstring.h
mail_addr_find.o: mail_params.h
mail_addr_find.o: split_addr.h
mail_addr_find.o: mail_addr_find.h
mail_addr_find.o: maps.h
mail_addr_find.o: resolve_local.h
mail_addr_map.o: mail_addr_map.c
mail_addr_map.o: ../include/sys_defs.h
mail_addr_map.o: ../include/msg.h
mail_addr_map.o: ../include/vstring.h
mail_addr_map.o: ../include/vbuf.h
mail_addr_map.o: ../include/dict.h
mail_addr_map.o: ../include/vstream.h
mail_addr_map.o: ../include/argv.h
mail_addr_map.o: ../include/mymalloc.h
mail_addr_map.o: mail_addr_find.h
mail_addr_map.o: maps.h
mail_addr_map.o: mail_addr_crunch.h
mail_addr_map.o: mail_addr_map.h
mail_command_read.o: mail_command_read.c
mail_command_read.o: ../include/sys_defs.h
mail_command_read.o: ../include/vstring.h
mail_command_read.o: ../include/vbuf.h
mail_command_read.o: ../include/vstream.h
mail_command_read.o: mail_proto.h
mail_command_read.o: ../include/iostuff.h
mail_command_write.o: mail_command_write.c
mail_command_write.o: ../include/sys_defs.h
mail_command_write.o: ../include/vstream.h
mail_command_write.o: ../include/vbuf.h
mail_command_write.o: mail_proto.h
mail_command_write.o: ../include/iostuff.h
mail_connect.o: mail_connect.c
mail_connect.o: ../include/sys_defs.h
mail_connect.o: ../include/msg.h
mail_connect.o: ../include/vstream.h
mail_connect.o: ../include/vbuf.h
mail_connect.o: ../include/connect.h
mail_connect.o: ../include/iostuff.h
mail_connect.o: ../include/mymalloc.h
mail_connect.o: timed_ipc.h
mail_connect.o: mail_proto.h
mail_copy.o: mail_copy.c
mail_copy.o: ../include/sys_defs.h
mail_copy.o: ../include/msg.h
mail_copy.o: ../include/htable.h
mail_copy.o: ../include/vstream.h
mail_copy.o: ../include/vbuf.h
mail_copy.o: ../include/vstring.h
mail_copy.o: ../include/vstring_vstream.h
mail_copy.o: ../include/stringops.h
mail_copy.o: quote_822_local.h
mail_copy.o: record.h
mail_copy.o: rec_type.h
mail_copy.o: mail_queue.h
mail_copy.o: mail_addr.h
mail_copy.o: mail_copy.h
mail_copy.o: mark_corrupt.h
mail_date.o: mail_date.c
mail_date.o: ../include/sys_defs.h
mail_date.o: ../include/msg.h
mail_date.o: ../include/vstring.h
mail_date.o: ../include/vbuf.h
mail_date.o: mail_date.h
mail_error.o: mail_error.c
mail_error.o: ../include/sys_defs.h
mail_error.o: mail_error.h
mail_error.o: ../include/name_mask.h
mail_flush.o: mail_flush.c
mail_flush.o: ../include/sys_defs.h
mail_flush.o: mail_proto.h
mail_flush.o: ../include/vstream.h
mail_flush.o: ../include/vbuf.h
mail_flush.o: ../include/iostuff.h
mail_flush.o: mail_flush.h
mail_open_ok.o: mail_open_ok.c
mail_open_ok.o: ../include/sys_defs.h
mail_open_ok.o: ../include/msg.h
mail_open_ok.o: mail_queue.h
mail_open_ok.o: ../include/vstring.h
mail_open_ok.o: ../include/vbuf.h
mail_open_ok.o: ../include/vstream.h
mail_open_ok.o: mail_open_ok.h
mail_params.o: mail_params.c
mail_params.o: ../include/sys_defs.h
mail_params.o: ../include/msg.h
mail_params.o: ../include/get_hostname.h
mail_params.o: ../include/valid_hostname.h
mail_params.o: mynetworks.h
mail_params.o: config.h
mail_params.o: mail_version.h
mail_params.o: mail_params.h
mail_pathname.o: mail_pathname.c
mail_pathname.o: ../include/sys_defs.h
mail_pathname.o: ../include/stringops.h
mail_pathname.o: mail_proto.h
mail_pathname.o: ../include/vstream.h
mail_pathname.o: ../include/vbuf.h
mail_pathname.o: ../include/iostuff.h
mail_print.o: mail_print.c
mail_print.o: ../include/sys_defs.h
mail_print.o: ../include/msg.h
mail_print.o: ../include/mymalloc.h
mail_print.o: ../include/vstream.h
mail_print.o: ../include/vbuf.h
mail_print.o: mail_proto.h
mail_print.o: ../include/iostuff.h
mail_queue.o: mail_queue.c
mail_queue.o: ../include/sys_defs.h
mail_queue.o: ../include/msg.h
mail_queue.o: ../include/vstring.h
mail_queue.o: ../include/vbuf.h
mail_queue.o: ../include/vstream.h
mail_queue.o: ../include/mymalloc.h
mail_queue.o: ../include/argv.h
mail_queue.o: ../include/dir_forest.h
mail_queue.o: ../include/make_dirs.h
mail_queue.o: ../include/split_at.h
mail_queue.o: file_id.h
mail_queue.o: mail_params.h
mail_queue.o: mail_queue.h
mail_run.o: mail_run.c
mail_run.o: ../include/sys_defs.h
mail_run.o: ../include/msg.h
mail_run.o: ../include/stringops.h
mail_run.o: ../include/mymalloc.h
mail_run.o: mail_params.h
mail_run.o: mail_run.h
mail_scan.o: mail_scan.c
mail_scan.o: ../include/sys_defs.h
mail_scan.o: ../include/msg.h
mail_scan.o: ../include/vstring.h
mail_scan.o: ../include/vbuf.h
mail_scan.o: ../include/vstream.h
mail_scan.o: ../include/vstring_vstream.h
mail_scan.o: ../include/mymalloc.h
mail_scan.o: mail_proto.h
mail_scan.o: ../include/iostuff.h
mail_stream.o: mail_stream.c
mail_stream.o: ../include/sys_defs.h
mail_stream.o: ../include/msg.h
mail_stream.o: ../include/mymalloc.h
mail_stream.o: ../include/vstring.h
mail_stream.o: ../include/vbuf.h
mail_stream.o: ../include/vstream.h
mail_stream.o: ../include/stringops.h
mail_stream.o: cleanup_user.h
mail_stream.o: mail_proto.h
mail_stream.o: ../include/iostuff.h
mail_stream.o: mail_queue.h
mail_stream.o: opened.h
mail_stream.o: mail_stream.h
mail_task.o: mail_task.c
mail_task.o: ../include/sys_defs.h
mail_task.o: ../include/vstring.h
mail_task.o: ../include/vbuf.h
mail_task.o: mail_params.h
mail_task.o: mail_task.h
mail_trigger.o: mail_trigger.c
mail_trigger.o: ../include/sys_defs.h
mail_trigger.o: ../include/msg.h
mail_trigger.o: ../include/mymalloc.h
mail_trigger.o: ../include/iostuff.h
mail_trigger.o: ../include/trigger.h
mail_trigger.o: mail_params.h
mail_trigger.o: mail_proto.h
mail_trigger.o: ../include/vstream.h
mail_trigger.o: ../include/vbuf.h
maps.o: maps.c
maps.o: ../include/sys_defs.h
maps.o: ../include/argv.h
maps.o: ../include/mymalloc.h
maps.o: ../include/msg.h
maps.o: ../include/dict.h
maps.o: ../include/vstream.h
maps.o: ../include/vbuf.h
maps.o: ../include/stringops.h
maps.o: ../include/split_at.h
maps.o: config.h
maps.o: maps.h
mark_corrupt.o: mark_corrupt.c
mark_corrupt.o: ../include/sys_defs.h
mark_corrupt.o: ../include/msg.h
mark_corrupt.o: ../include/vstream.h
mark_corrupt.o: ../include/vbuf.h
mark_corrupt.o: mail_queue.h
mark_corrupt.o: ../include/vstring.h
mark_corrupt.o: mark_corrupt.h
mkmap_db.o: mkmap_db.c
mkmap_db.o: ../include/sys_defs.h
mkmap_db.o: ../include/msg.h
mkmap_db.o: ../include/mymalloc.h
mkmap_db.o: ../include/stringops.h
mkmap_db.o: ../include/dict.h
mkmap_db.o: ../include/vstream.h
mkmap_db.o: ../include/vbuf.h
mkmap_db.o: ../include/dict_db.h
mkmap_db.o: mkmap.h
mkmap_dbm.o: mkmap_dbm.c
mkmap_dbm.o: ../include/sys_defs.h
mkmap_dbm.o: ../include/msg.h
mkmap_dbm.o: ../include/mymalloc.h
mkmap_dbm.o: ../include/stringops.h
mkmap_dbm.o: ../include/dict.h
mkmap_dbm.o: ../include/vstream.h
mkmap_dbm.o: ../include/vbuf.h
mkmap_dbm.o: ../include/dict_dbm.h
mkmap_dbm.o: mkmap.h
mkmap_open.o: mkmap_open.c
mkmap_open.o: ../include/sys_defs.h
mkmap_open.o: ../include/msg.h
mkmap_open.o: ../include/dict.h
mkmap_open.o: ../include/vstream.h
mkmap_open.o: ../include/vbuf.h
mkmap_open.o: ../include/sigdelay.h
mkmap_open.o: ../include/mymalloc.h
mkmap_open.o: ../include/myflock.h
mkmap_open.o: mkmap.h
mynetworks.o: mynetworks.c
mynetworks.o: ../include/sys_defs.h
mynetworks.o: ../include/msg.h
mynetworks.o: ../include/vstring.h
mynetworks.o: ../include/vbuf.h
mynetworks.o: ../include/inet_addr_list.h
mynetworks.o: own_inet_addr.h
mynetworks.o: mynetworks.h
mypwd.o: mypwd.c
mypwd.o: ../include/sys_defs.h
mypwd.o: ../include/mymalloc.h
mypwd.o: ../include/htable.h
mypwd.o: ../include/binhash.h
mypwd.o: ../include/msg.h
mypwd.o: mypwd.h
namadr_list.o: namadr_list.c
namadr_list.o: ../include/sys_defs.h
namadr_list.o: ../include/match_list.h
namadr_list.o: ../include/match_ops.h
namadr_list.o: namadr_list.h
off_cvt.o: off_cvt.c
off_cvt.o: ../include/sys_defs.h
off_cvt.o: ../include/msg.h
off_cvt.o: ../include/vstring.h
off_cvt.o: ../include/vbuf.h
off_cvt.o: off_cvt.h
opened.o: opened.c
opened.o: ../include/sys_defs.h
opened.o: ../include/msg.h
opened.o: ../include/vstring.h
opened.o: ../include/vbuf.h
opened.o: opened.h
own_inet_addr.o: own_inet_addr.c
own_inet_addr.o: ../include/sys_defs.h
own_inet_addr.o: ../include/msg.h
own_inet_addr.o: ../include/mymalloc.h
own_inet_addr.o: ../include/inet_addr_list.h
own_inet_addr.o: ../include/inet_addr_local.h
own_inet_addr.o: ../include/inet_addr_host.h
own_inet_addr.o: ../include/stringops.h
own_inet_addr.o: mail_params.h
own_inet_addr.o: own_inet_addr.h
pipe_command.o: pipe_command.c
pipe_command.o: ../include/sys_defs.h
pipe_command.o: ../include/msg.h
pipe_command.o: ../include/vstream.h
pipe_command.o: ../include/vbuf.h
pipe_command.o: ../include/vstring.h
pipe_command.o: ../include/stringops.h
pipe_command.o: ../include/iostuff.h
pipe_command.o: ../include/timed_wait.h
pipe_command.o: ../include/set_ugid.h
pipe_command.o: ../include/argv.h
pipe_command.o: mail_params.h
pipe_command.o: mail_copy.h
pipe_command.o: clean_env.h
pipe_command.o: pipe_command.h
pipe_command.o: ../include/exec_command.h
pipe_command.o: sys_exits.h
post_mail.o: post_mail.c
post_mail.o: ../include/sys_defs.h
post_mail.o: ../include/msg.h
post_mail.o: ../include/vstream.h
post_mail.o: ../include/vbuf.h
post_mail.o: ../include/vstring.h
post_mail.o: mail_params.h
post_mail.o: record.h
post_mail.o: rec_type.h
post_mail.o: mail_proto.h
post_mail.o: ../include/iostuff.h
post_mail.o: cleanup_user.h
post_mail.o: post_mail.h
post_mail.o: mail_date.h
quote_822_local.o: quote_822_local.c
quote_822_local.o: ../include/sys_defs.h
quote_822_local.o: ../include/vstring.h
quote_822_local.o: ../include/vbuf.h
quote_822_local.o: quote_822_local.h
rec2stream.o: rec2stream.c
rec2stream.o: ../include/sys_defs.h
rec2stream.o: ../include/vstring.h
rec2stream.o: ../include/vbuf.h
rec2stream.o: ../include/vstream.h
rec2stream.o: record.h
rec2stream.o: rec_streamlf.h
rec2stream.o: rec_type.h
rec_streamlf.o: rec_streamlf.c
rec_streamlf.o: ../include/sys_defs.h
rec_streamlf.o: ../include/vstring.h
rec_streamlf.o: ../include/vbuf.h
rec_streamlf.o: ../include/vstream.h
rec_streamlf.o: record.h
rec_streamlf.o: rec_type.h
rec_streamlf.o: rec_streamlf.h
rec_type.o: rec_type.c
rec_type.o: rec_type.h
recdump.o: recdump.c
recdump.o: ../include/sys_defs.h
recdump.o: ../include/msg_vstream.h
recdump.o: ../include/vstream.h
recdump.o: ../include/vbuf.h
recdump.o: record.h
recdump.o: ../include/vstring.h
recdump.o: rec_streamlf.h
recdump.o: rec_type.h
recipient_list.o: recipient_list.c
recipient_list.o: ../include/mymalloc.h
recipient_list.o: recipient_list.h
record.o: record.c
record.o: ../include/sys_defs.h
record.o: ../include/msg.h
record.o: ../include/mymalloc.h
record.o: ../include/vstream.h
record.o: ../include/vbuf.h
record.o: ../include/vstring.h
record.o: record.h
remove.o: remove.c
remove.o: ../include/sys_defs.h
remove.o: ../include/vstring.h
remove.o: ../include/vbuf.h
remove.o: mail_params.h
resolve_clnt.o: resolve_clnt.c
resolve_clnt.o: ../include/sys_defs.h
resolve_clnt.o: ../include/msg.h
resolve_clnt.o: ../include/vstream.h
resolve_clnt.o: ../include/vbuf.h
resolve_clnt.o: ../include/vstring.h
resolve_clnt.o: ../include/vstring_vstream.h
resolve_clnt.o: ../include/events.h
resolve_clnt.o: ../include/iostuff.h
resolve_clnt.o: mail_proto.h
resolve_clnt.o: mail_params.h
resolve_clnt.o: resolve_clnt.h
resolve_local.o: resolve_local.c
resolve_local.o: ../include/sys_defs.h
resolve_local.o: ../include/msg.h
resolve_local.o: ../include/mymalloc.h
resolve_local.o: string_list.h
resolve_local.o: mail_params.h
resolve_local.o: own_inet_addr.h
resolve_local.o: resolve_local.h
rewrite_clnt.o: rewrite_clnt.c
rewrite_clnt.o: ../include/sys_defs.h
rewrite_clnt.o: ../include/msg.h
rewrite_clnt.o: ../include/vstring.h
rewrite_clnt.o: ../include/vbuf.h
rewrite_clnt.o: ../include/vstream.h
rewrite_clnt.o: ../include/vstring_vstream.h
rewrite_clnt.o: ../include/events.h
rewrite_clnt.o: ../include/iostuff.h
rewrite_clnt.o: quote_822_local.h
rewrite_clnt.o: mail_proto.h
rewrite_clnt.o: mail_params.h
rewrite_clnt.o: rewrite_clnt.h
sent.o: sent.c
sent.o: ../include/sys_defs.h
sent.o: ../include/msg.h
sent.o: ../include/vstring.h
sent.o: ../include/vbuf.h
sent.o: sent.h
smtp_stream.o: smtp_stream.c
smtp_stream.o: ../include/sys_defs.h
smtp_stream.o: ../include/vstring.h
smtp_stream.o: ../include/vbuf.h
smtp_stream.o: ../include/vstream.h
smtp_stream.o: ../include/vstring_vstream.h
smtp_stream.o: ../include/msg.h
smtp_stream.o: ../include/iostuff.h
smtp_stream.o: smtp_stream.h
split_addr.o: split_addr.c
split_addr.o: ../include/sys_defs.h
split_addr.o: ../include/split_at.h
split_addr.o: mail_params.h
split_addr.o: mail_addr.h
split_addr.o: split_addr.h
stream2rec.o: stream2rec.c
stream2rec.o: ../include/sys_defs.h
stream2rec.o: ../include/vstream.h
stream2rec.o: ../include/vbuf.h
stream2rec.o: ../include/vstring.h
stream2rec.o: record.h
stream2rec.o: rec_streamlf.h
stream2rec.o: rec_type.h
string_list.o: string_list.c
string_list.o: ../include/sys_defs.h
string_list.o: ../include/match_list.h
string_list.o: ../include/match_ops.h
string_list.o: string_list.h
sys_exits.o: sys_exits.c
sys_exits.o: ../include/sys_defs.h
sys_exits.o: ../include/msg.h
sys_exits.o: sys_exits.h
timed_ipc.o: timed_ipc.c
timed_ipc.o: ../include/sys_defs.h
timed_ipc.o: ../include/msg.h
timed_ipc.o: ../include/vstream.h
timed_ipc.o: ../include/vbuf.h
timed_ipc.o: ../include/iostuff.h
timed_ipc.o: mail_params.h
timed_ipc.o: timed_ipc.h
tok822_find.o: tok822_find.c
tok822_find.o: ../include/sys_defs.h
tok822_find.o: ../include/vstring.h
tok822_find.o: ../include/vbuf.h
tok822_find.o: tok822.h
tok822_find.o: resolve_clnt.h
tok822_node.o: tok822_node.c
tok822_node.o: ../include/sys_defs.h
tok822_node.o: ../include/mymalloc.h
tok822_node.o: ../include/vstring.h
tok822_node.o: ../include/vbuf.h
tok822_node.o: tok822.h
tok822_node.o: resolve_clnt.h
tok822_parse.o: tok822_parse.c
tok822_parse.o: ../include/sys_defs.h
tok822_parse.o: ../include/vstring.h
tok822_parse.o: ../include/vbuf.h
tok822_parse.o: ../include/msg.h
tok822_parse.o: tok822.h
tok822_parse.o: resolve_clnt.h
tok822_resolve.o: tok822_resolve.c
tok822_resolve.o: ../include/sys_defs.h
tok822_resolve.o: ../include/vstring.h
tok822_resolve.o: ../include/vbuf.h
tok822_resolve.o: ../include/msg.h
tok822_resolve.o: resolve_clnt.h
tok822_resolve.o: tok822.h
tok822_rewrite.o: tok822_rewrite.c
tok822_rewrite.o: ../include/sys_defs.h
tok822_rewrite.o: ../include/vstring.h
tok822_rewrite.o: ../include/vbuf.h
tok822_rewrite.o: ../include/msg.h
tok822_rewrite.o: rewrite_clnt.h
tok822_rewrite.o: tok822.h
tok822_rewrite.o: resolve_clnt.h
tok822_tree.o: tok822_tree.c
tok822_tree.o: ../include/sys_defs.h
tok822_tree.o: ../include/mymalloc.h
tok822_tree.o: ../include/vstring.h
tok822_tree.o: ../include/vbuf.h
tok822_tree.o: tok822.h
tok822_tree.o: resolve_clnt.h

175
postfix/global/been_here.c Normal file
View File

@@ -0,0 +1,175 @@
/*++
/* NAME
/* been_here 3
/* SUMMARY
/* detect repeated occurrence of string
/* SYNOPSIS
/* #include <been_here.h>
/*
/* BH_TABLE *been_here_init(size)
/* int size;
/*
/* int been_here_fixed(dup_filter, string)
/* BH_TABLE *dup_filter;
/* char *string;
/*
/* int been_here(dup_filter, format, ...)
/* BH_TABLE *dup_filter;
/* char *format;
/*
/* void been_here_free(dup_filter)
/* BH_TABLE *dup_filter;
/* DESCRIPTION
/* This module implements a simple filter to detect repeated
/* occurrences of character strings.
/*
/* been_here_init() creates an empty duplicate filter.
/*
/* been_here_fixed() looks up a fixed string in the given table, and
/* makes an entry in the table if the string was not found. The result
/* is non-zero (true) if the string was found, zero (false) otherwise.
/*
/* been_here() formats its arguments, looks up the result in the
/* given table, and makes an entry in the table if the string was
/* not found. The result is non-zero (true) if the formatted result was
/* found, zero (false) otherwise.
/*
/* been_here_free() releases storage for a duplicate filter.
/*
/* Arguments:
/* .IP size
/* Upper bound on the table size; at most \fIsize\fR strings will
/* be remembered. Specify a value <= 0 to disable the upper bound.
/* .IP flags
/* Requests for special processing. Specify the bitwise OR of zero
/* or more flags:
/* .RS
/* .IP BH_FLAG_FOLD
/* Enable case-insensitive lookup.
/* .IP BH_FLAG_NONE
/* A manifest constant that requests no special processing.
/* .RE
/* .IP dup_filter
/* The table with remembered names
/* .IP string
/* Fixed search string.
/* .IP format
/* Format for building the search string.
/* 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 <msg.h>
#include <mymalloc.h>
#include <htable.h>
#include <vstring.h>
#include <stringops.h>
/* Global library. */
#include "been_here.h"
/* been_here_init - initialize duplicate filter */
BH_TABLE *been_here_init(int limit, int flags)
{
BH_TABLE *dup_filter;
dup_filter = (BH_TABLE *) mymalloc(sizeof(*dup_filter));
dup_filter->limit = limit;
dup_filter->flags = flags;
dup_filter->table = htable_create(0);
return (dup_filter);
}
/* been_here_free - destroy duplicate filter */
void been_here_free(BH_TABLE *dup_filter)
{
htable_free(dup_filter->table, (void (*) (char *)) 0);
myfree((char *) dup_filter);
}
/* been_here - duplicate detector with finer control */
int been_here(BH_TABLE *dup_filter, const char *fmt,...)
{
VSTRING *buf = vstring_alloc(100);
int status;
va_list ap;
/*
* Construct the string to be checked.
*/
va_start(ap, fmt);
vstring_vsprintf(buf, fmt, ap);
va_end(ap);
/*
* Do the duplicate check.
*/
status = been_here_fixed(dup_filter, vstring_str(buf));
/*
* Cleanup.
*/
vstring_free(buf);
return (status);
}
/* been_here_fixed - duplicate detector */
int been_here_fixed(BH_TABLE *dup_filter, const char *string)
{
char *folded_string;
const char *lookup_key;
int status;
/*
* Special processing: case insensitive lookup.
*/
if (dup_filter->flags & BH_FLAG_FOLD) {
folded_string = mystrdup(string);
lookup_key = lowercase(folded_string);
} else {
folded_string = 0;
lookup_key = string;
}
/*
* Do the duplicate check.
*/
if (htable_locate(dup_filter->table, lookup_key) != 0) {
status = 1;
} else {
if (dup_filter->limit > 0
&& dup_filter->limit > dup_filter->table->used)
htable_enter(dup_filter->table, lookup_key, (char *) 0);
status = 0;
}
if (msg_verbose)
msg_info("been_here: %s: %d", string, status);
/*
* Cleanup.
*/
if (folded_string)
myfree(folded_string);
return (status);
}

View File

@@ -0,0 +1,47 @@
#ifndef _BEEN_HERE_H_INCLUDED_
#define _BEEN_HERE_H_INCLUDED_
/*++
/* NAME
/* been_here 3h
/* SUMMARY
/* detect repeated occurrence of string
/* SYNOPSIS
/* #include <been_here.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <stdarg.h>
/*
* External interface.
*/
typedef struct {
int limit; /* ceiling, zero for none */
int flags; /* see below */
struct HTABLE *table;
} BH_TABLE;
#define BH_FLAG_NONE 0 /* no special processing */
#define BH_FLAG_FOLD (1<<0) /* fold case */
extern BH_TABLE *been_here_init(int, int);
extern void been_here_free(BH_TABLE *);
extern int been_here_fixed(BH_TABLE *, const char *);
extern int been_here(BH_TABLE *, const char *,...);
/* 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
/*--*/
#endif

167
postfix/global/bounce.c Normal file
View File

@@ -0,0 +1,167 @@
/*++
/* NAME
/* bounce 3
/* SUMMARY
/* bounce service client
/* SYNOPSIS
/* #include <bounce.h>
/*
/* int bounce_append(flags, id, recipient, relay, entry, format, ...)
/* int flags;
/* const char *id;
/* const char *recipient;
/* const char *relay;
/* time_t entry;
/* const char *format;
/*
/* int vbounce_append(flags, id, recipient, relay, entry, format, ap)
/* int flags;
/* const char *id;
/* const char *recipient;
/* const char *relay;
/* time_t entry;
/* const char *format;
/* va_list ap;
/*
/* int bounce_flush(flags, queue, id, sender)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *sender;
/* DESCRIPTION
/* This module implements the client interface to the message
/* bounce service, which maintains a per-message log of status
/* records with recipients that were bounced, and the reason why.
/*
/* bounce_append() appends a reason for non-delivery to the
/* bounce log for the named recipient.
/*
/* vbounce_append() implements an alternative interface.
/*
/* bounce_flush() actually bounces the specified message to
/* the specified sender, including the bounce log that was
/* built with bounce_append().
/*
/* Arguments:
/* .IP flags
/* The bitwise OR of zero or mor of the following (specify
/* BOUNCE_FLAG_NONE to request no special processing):
/* .RS
/* .IP BOUNCE_FLAG_CLEAN
/* Delete the bounce log in case of an error (as in: pretend
/* that we never even tried to bounce this message).
/* .IP BOUNCE_FLAG_COPY
/* Request that a postmaster copy is sent (bounce_flush() only).
/* .RE
/* .IP queue
/* The message queue name of the original message file.
/* .IP id
/* The message queue id if the original message file. The bounce log
/* file has the same name as the original message file.
/* .IP sender
/* The sender envelope address.
/* .IP relay
/* Name of the host that the message could not be delivered to.
/* This information is used for syslogging only.
/* .IP entry
/* Message arrival time.
/* .IP recipient
/* Recipient address that the message could not be delivered to.
/* This information is used for syslogging only.
/* .IP format
/* The reason for non-delivery.
/* .IP ap
/* Variable-length argument list.
/* DIAGNOSTICS
/* In case of success, these functions log the action, and return a
/* zero value. Otherwise, the functions return a non-zero result,
/* and when BOUNCE_FLAG_CLEAN is disabled, log that message
/* delivery is deferred.
/* BUGS
/* Should be replaced by routines with an attribute-value based
/* interface instead of an interface that uses a rigid argument list.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <time.h>
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
/* Global library. */
#include "mail_proto.h"
#include "defer.h"
#include "bounce.h"
/* bounce_append - append reason to per-message bounce log */
int bounce_append(int flags, const char *id, const char *recipient,
const char *relay, time_t entry, const char *fmt,...)
{
va_list ap;
int status;
va_start(ap, fmt);
status = vbounce_append(flags, id, recipient, relay, entry, fmt, ap);
va_end(ap);
return (status);
}
/* vbounce_append - append bounce reason to per-message log */
int vbounce_append(int flags, const char *id, const char *recipient,
const char *relay, time_t entry, const char *fmt, va_list ap)
{
VSTRING *why = vstring_alloc(100);
int status;
int delay = time((time_t *) 0) - entry;
vstring_vsprintf(why, fmt, ap);
if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE,
"%d %d %s %s %s", BOUNCE_CMD_APPEND,
flags, id, recipient, vstring_str(why)) == 0) {
msg_info("%s: to=<%s>, relay=%s, delay=%d, status=bounced (%s)",
id, recipient, relay, delay, vstring_str(why));
status = 0;
} else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
status = defer_append(flags, id, recipient, "bounce", delay,
"bounce failed");
} else {
status = -1;
}
vstring_free(why);
return (status);
}
/* bounce_flush - flush the bounce log and deliver to the sender */
int bounce_flush(int flags, const char *queue, const char *id,
const char *sender)
{
if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE,
"%d %d %s %s %s", BOUNCE_CMD_FLUSH,
flags, queue, id, sender) == 0) {
return (0);
} else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
msg_info("%s: status=deferred (bounce failed)", id);
return (-1);
} else {
return (-1);
}
}

58
postfix/global/bounce.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef _BOUNCE_H_INCLUDED_
#define _BOUNCE_H_INCLUDED_
/*++
/* NAME
/* bounce 3h
/* SUMMARY
/* bounce service client
/* SYNOPSIS
/* #include <bounce.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <time.h>
#include <stdarg.h>
/*
* Client interface.
*/
extern int bounce_append(int, const char *, const char *, const char *,
time_t, const char *,...);
extern int vbounce_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int bounce_flush(int, const char *, const char *, const char *);
/*
* Bounce/defer protocol commands.
*/
#define BOUNCE_CMD_APPEND 0 /* append log */
#define BOUNCE_CMD_FLUSH 1 /* send log */
/*
* Flags.
*/
#define BOUNCE_FLAG_NONE 0 /* no flags up */
#define BOUNCE_FLAG_CLEAN (1<<0) /* remove log on error */
#define BOUNCE_FLAG_COPY (1<<1) /* postmaster notice */
/*
* Backwards compatibility.
*/
#define BOUNCE_FLAG_KEEP BOUNCE_FLAG_NONE
/* 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
/*--*/
#endif

View File

@@ -0,0 +1,67 @@
/*++
/* NAME
/* canon_addr 3
/* SUMMARY
/* simple address canonicalization
/* SYNOPSIS
/* #include <canon_addr.h>
/*
/* VSTRING *canon_addr_external(result, address)
/* VSTRING *result;
/* const char *address;
/*
/* VSTRING *canon_addr_internal(result, address)
/* VSTRING *result;
/* const char *address;
/* DESCRIPTION
/* This module provides a simple interface to the address
/* canonicalization service that is provided by the address
/* rewriting service.
/*
/* canon_addr_external() transforms an address in external (i.e.
/* quoted) RFC822 form to a fully-qualified address (user@domain).
/*
/* canon_addr_internal() transforms an address in internal (i.e.
/* unquoted) RFC822 form to a fully-qualified address (user@domain).
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages).
/* SEE ALSO
/* rewrite_clnt(3) address rewriting 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>
/* Utility library. */
#include <vstring.h>
#include <mymalloc.h>
/* Global library. */
#include "rewrite_clnt.h"
#include "canon_addr.h"
/* canon_addr_external - make address fully qualified, external form */
VSTRING *canon_addr_external(VSTRING *result, const char *addr)
{
return (rewrite_clnt(REWRITE_CANON, addr, result));
}
/* canon_addr_internal - make address fully qualified, internal form */
VSTRING *canon_addr_internal(VSTRING *result, const char *addr)
{
return (rewrite_clnt_internal(REWRITE_CANON, addr, result));
}

View File

@@ -0,0 +1,36 @@
#ifndef _CANON_ADDR_H_INCLUDED_
#define _CANON_ADDR_H_INCLUDED_
/*++
/* NAME
/* canon_addr 3h
/* SUMMARY
/* simple address canonicalization
/* SYNOPSIS
/* #include <canon_addr.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <vstring.h>
/*
* External interface.
*/
extern VSTRING *canon_addr_external(VSTRING *, const char *);
extern VSTRING *canon_addr_internal(VSTRING *, const char *);
/* 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
/*--*/
#endif

View File

@@ -0,0 +1,68 @@
/*++
/* NAME
/* clean_env 3
/* SUMMARY
/* clean up the environment
/* SYNOPSIS
/* #include <clean_env.h>
/*
/* void clean_env()
/* DESCRIPTION
/* clean_env() reduces the process environment to the bare minimum.
/* In the initial version, rules are hard-coded. This will be
/* made configurable.
/* 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>
#include <unistd.h>
/* Utility library. */
#include <msg.h>
/* Global library. */
#include "clean_env.h"
/* clean_env - clean up the environment */
void clean_env(void)
{
char *TZ;
extern char **environ;
/*
* Preserve selected environment variables. This list will be
* configurable.
*/
TZ = getenv("TZ");
/*
* Truncate the process environment, if available. On some systems
* (Ultrix!), environ can be a null pointer.
*/
if (environ)
environ[0] = 0;
/*
* Restore preserved environment variables.
*/
if (TZ && setenv("TZ", TZ, 1))
msg_fatal("setenv: %m");
/*
* Update the process environment with configurable initial values.
*/
}

View File

@@ -0,0 +1,30 @@
#ifndef _CLEAN_ENV_H_INCLUDED_
#define _CLEAN_ENV_H_INCLUDED_
/*++
/* NAME
/* clean_env 3h
/* SUMMARY
/* clean up the environment
/* SYNOPSIS
/* #include <clean_env.h>
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
extern void clean_env(void);
/* 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
/*--*/
#endif

View File

@@ -0,0 +1,76 @@
/*++
/* NAME
/* cleanup_strerror 3
/* SUMMARY
/* cleanup status code to string
/* SYNOPSIS
/* #include <cleanup_user.h>
/*
/* const char *cleanup_strerror(code)
/* int code;
/* DESCRIPTION
/* cleanup_strerror() maps a status code returned by the \fIcleanup\fR
/* service to printable string.
/* The result is for read purposes only. Unknown status codes share
/* a common result buffer.
/* 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 <vstring.h>
/* Global library. */
#include "cleanup_user.h"
/*
* Mapping from status code to printable string. One message may suffer from
* multiple errors, to it is important to list the most severe errors first,
* because the result of lookup can be only one string.
*/
struct cleanup_stat_map {
unsigned status;
const char *text;
};
static struct cleanup_stat_map cleanup_stat_map[] = {
CLEANUP_STAT_BAD, "Internal protocol error",
CLEANUP_STAT_RCPT, "No recipients specified",
CLEANUP_STAT_HOPS, "Too many hops",
CLEANUP_STAT_SIZE, "Message file too big",
CLEANUP_STAT_CONT, "Message content rejected",
CLEANUP_STAT_WRITE, "Error writing message file",
};
/* cleanup_strerror - map status code to printable string */
const char *cleanup_strerror(unsigned status)
{
static VSTRING *unknown;
unsigned i;
if (status == 0)
return ("Success");
for (i = 0; i < sizeof(cleanup_stat_map) / sizeof(cleanup_stat_map[0]); i++)
if (cleanup_stat_map[i].status & status)
return (cleanup_stat_map[i].text);
if (unknown == 0)
unknown = vstring_alloc(20);
vstring_sprintf(unknown, "Unknown status %u", status);
return (vstring_str(unknown));
}

View File

@@ -0,0 +1,48 @@
#ifndef _CLEANUP_USER_H_INCLUDED_
#define _CLEANUP_USER_H_INCLUDED_
/*++
/* NAME
/* cleanup_user 3h
/* SUMMARY
/* cleanup user interface codes
/* SYNOPSIS
/* #include <cleanup_user.h>
/* DESCRIPTION
/* .nf
/*
* Options.
*/
#define CLEANUP_FLAG_NONE 0 /* No special features */
#define CLEANUP_FLAG_BOUNCE (1<<0) /* Bounce bad messages */
#define CLEANUP_FLAG_FILTER (2<<0) /* Enable content filter */
/*
* Diagnostics.
*/
#define CLEANUP_STAT_OK 0 /* Success. */
#define CLEANUP_STAT_BAD (1<<0) /* Internal protocol error */
#define CLEANUP_STAT_WRITE (1<<1) /* Error writing message file */
#define CLEANUP_STAT_SIZE (1<<2) /* Message file too big */
#define CLEANUP_STAT_CONT (1<<3) /* Message content rejected */
#define CLEANUP_STAT_HOPS (1<<4) /* Too many hops */
#define CLEANUP_STAT_SYN (1<<5) /* Bad address syntax */
#define CLEANUP_STAT_RCPT (1<<6) /* No recipients found */
extern const char *cleanup_strerror(unsigned);
/* 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
/*--*/
#endif

147
postfix/global/config.c Normal file
View File

@@ -0,0 +1,147 @@
/*++
/* NAME
/* config 3
/* SUMMARY
/* global configuration parameter management
/* SYNOPSIS
/* #include <config.h>
/*
/* void read_config()
/*
/* void config_update(name, value)
/* const char *name;
/* const char *value;
/*
/* const char *config_lookup(name)
/* const char *name;
/*
/* const char *config_eval(string)
/* const char *string;
/*
/* const char *config_lookup_eval(name)
/* const char *name;
/* DESCRIPTION
/* read_config() reads the global Postfix configuration file, and
/* stores its values into a global configuration dictionary.
/*
/* The following routines are wrappers around the generic dictionary
/* access routines.
/*
/* config_update() updates the named global parameter. This has
/* no effect on parameters whose value has already been looked up.
/* The update succeeds or the program terminates with fatal error.
/*
/* config_lookup() looks up the value of the named parameter.
/* A null pointer result means the parameter was not found.
/* The result is volatile and should be copied if it is to be
/* used for any appreciable amount of time.
/*
/* config_eval() recursively expands any $parameters in the
/* string argument. The result is volatile and should be copied
/* if it is to be used for any appreciable amount of time.
/*
/* config_lookup_eval() looks up the named parameter, and expands any
/* $parameters in the result. The result is volatile and should be
/* copied if it is to be used for any appreciable amount of time.
/* DIAGNOSTICS
/* Fatal errors: malformed numerical value.
/* FILES
/* /etc/postfix: default Postfix configuration directory.
/* ENVIRONMENT
/* MAIL_CONFIG, non-default configuration database
/* MAIL_VERBOSE, enable verbose mode
/* SEE ALSO
/* dict(3) generic dictionary manager
/* config_int(3) integer-valued parameters
/* config_str(3) string-valued parameters
/* 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>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstream.h>
#include <vstring.h>
#include <dict.h>
#include <safe.h>
#include <stringops.h>
/* Global library. */
#include "mail_params.h"
#include "config.h"
/* read_config - read global configuration file */
void read_config(void)
{
char *config_dir;
char *path;
/*
* Permit references to unknown configuration variable names. We rely on
* a separate configuration checking tool to spot misspelled names and
* other kinds of trouble. Enter the configuration directory into the
* default dictionary.
*/
dict_unknown_allowed = 1;
if (var_config_dir)
myfree(var_config_dir);
var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ?
config_dir : DEF_CONFIG_DIR); /* XXX */
set_config_str(VAR_CONFIG_DIR, var_config_dir);
path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
dict_load_file(CONFIG_DICT, path);
myfree(path);
mail_params_init();
}
/* config_eval - expand macros in string */
const char *config_eval(const char *string)
{
#define RECURSIVE 1
return (dict_eval(CONFIG_DICT, string, RECURSIVE));
}
/* config_lookup - lookup named variable */
const char *config_lookup(const char *name)
{
return (dict_lookup(CONFIG_DICT, name));
}
/* config_lookup_eval - expand named variable */
const char *config_lookup_eval(const char *name)
{
const char *value;
#define RECURSIVE 1
if ((value = dict_lookup(CONFIG_DICT, name)) != 0)
value = dict_eval(CONFIG_DICT, value, RECURSIVE);
return (value);
}
/* config_update - update parameter */
void config_update(const char *key, const char *value)
{
dict_update(CONFIG_DICT, key, value);
}

136
postfix/global/config.h Normal file
View File

@@ -0,0 +1,136 @@
#ifndef _CONFIG_H_INCLUDED_
#define _CONFIG_H_INCLUDED_
/*++
/* NAME
/* config 3h
/* SUMMARY
/* global configuration parameter management
/* SYNOPSIS
/* #include <config.h>
/* DESCRIPTION
/* .nf
/*
* Well known names. These are not configurable. One has to start somewhere.
*/
#define CONFIG_DICT "mail_dict" /* global Postfix dictionary */
/*
* Environment variables.
*/
#define CONF_ENV_PATH "MAIL_CONFIG" /* config database */
#define CONF_ENV_VERB "MAIL_VERBOSE" /* verbose mode on */
#define CONF_ENV_DEBUG "MAIL_DEBUG" /* verbose mode on */
/*
* External representation for booleans.
*/
#define CONFIG_BOOL_YES "yes"
#define CONFIG_BOOL_NO "no"
/*
* Basic configuration management.
*/
extern void read_config(void);
extern void config_update(const char *, const char *);
extern const char *config_lookup(const char *);
extern const char *config_eval(const char *);
extern const char *config_lookup_eval(const char *);
/*
* Specific parameter lookup routines.
*/
extern char *get_config_str(const char *, const char *, int, int);
extern int get_config_int(const char *, int, int, int);
extern int get_config_bool(const char *, int);
extern int get_config_int2(const char *, const char *, int, int, int);
/*
* Lookup with function-call defaults.
*/
extern char *get_config_str_fn(const char *, const char *(*) (void), int, int);
extern int get_config_int_fn(const char *, int (*) (void), int, int);
extern int get_config_bool_fn(const char *, int (*) (void));
/*
* Update dictionary.
*/
extern void set_config_str(const char *, const char *);
extern void set_config_int(const char *, int);
extern void set_config_bool(const char *, int);
/*
* Tables that allow us to selectively copy values from the global
* configuration file to global variables.
*/
typedef struct {
const char *name; /* config variable name */
const char *defval; /* default value or null */
char **target; /* pointer to global variable */
int min; /* min length or zero */
int max; /* max length or zero */
} CONFIG_STR_TABLE;
typedef struct {
const char *name; /* config variable name */
int defval; /* default value */
int *target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
} CONFIG_INT_TABLE;
typedef struct {
const char *name; /* config variable name */
int defval; /* default value */
int *target; /* pointer to global variable */
} CONFIG_BOOL_TABLE;
extern void get_config_str_table(CONFIG_STR_TABLE *);
extern void get_config_int_table(CONFIG_INT_TABLE *);
extern void get_config_bool_table(CONFIG_BOOL_TABLE *);
/*
* Tables to initialize parameters from the global configuration file or
* from function calls.
*/
typedef struct {
const char *name; /* config variable name */
const char *(*defval) (void); /* default value provider */
char **target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
} CONFIG_STR_FN_TABLE;
typedef struct {
const char *name; /* config variable name */
int (*defval) (void); /* default value provider */
int *target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
} CONFIG_INT_FN_TABLE;
typedef struct {
const char *name; /* config variable name */
int (*defval) (void); /* default value provider */
int *target; /* pointer to global variable */
} CONFIG_BOOL_FN_TABLE;
extern void get_config_str_fn_table(CONFIG_STR_FN_TABLE *);
extern void get_config_int_fn_table(CONFIG_INT_FN_TABLE *);
extern void get_config_bool_fn_table(CONFIG_BOOL_FN_TABLE *);
/* 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
/*--*/
#endif

View File

@@ -0,0 +1,155 @@
/*++
/* NAME
/* config_bool 3
/* SUMMARY
/* boolean-valued configuration parameter support
/* SYNOPSIS
/* #include <config.h>
/*
/* int get_config_bool(name, defval)
/* const char *path;
/* const char *name;
/* int defval;
/*
/* int get_config_bool_fn(name, defval)
/* const char *path;
/* const char *name;
/* int (*defval)();
/*
/* void set_config_bool(name, value)
/* const char *name;
/* int value;
/*
/* void get_config_bool_table(table)
/* CONFIG_BOOL_TABLE *table;
/*
/* void get_config_bool_fn_table(table)
/* CONFIG_BOOL_TABLE *table;
/* DESCRIPTION
/* This module implements configuration parameter support for
/* boolean values. The internal representation is zero (false)
/* and non-zero (true). The external representation is "no"
/* (false) and "yes" (true). The conversion from external
/* representation is case insensitive.
/*
/* get_config_bool() looks up the named entry in the global
/* configuration dictionary. The specified default value is
/* returned when no value was found.
/*
/* get_config_bool_fn() is similar but specifies a function that
/* provides the default value. The function is called only
/* when the default value is needed.
/*
/* set_config_bool() updates the named entry in the global
/* configuration dictionary. This has no effect on values that
/* have been looked up earlier via the get_config_XXX() routines.
/*
/* get_config_bool_table() and get_config_int_fn_table() initialize
/* lists of variables, as directed by their table arguments. A table
/* must be terminated by a null entry.
/* DIAGNOSTICS
/* Fatal errors: malformed boolean value.
/* SEE ALSO
/* config(3) general configuration
/* config_str(3) string-valued configuration parameters
/* config_int(3) integer-valued configuration parameters
/* 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>
#include <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/* Utility library. */
#include <msg.h>
#include <dict.h>
/* Global library. */
#include "config.h"
/* convert_config_bool - look up and convert boolean parameter value */
static int convert_config_bool(const char *name, int *intval)
{
const char *strval;
if ((strval = config_lookup_eval(name)) == 0) {
return (0);
} else {
if (strcasecmp(strval, CONFIG_BOOL_YES) == 0) {
*intval = 1;
} else if (strcasecmp(strval, CONFIG_BOOL_NO) == 0) {
*intval = 0;
} else {
msg_fatal("bad boolean configuration: %s = %s", name, strval);
}
return (1);
}
}
/* get_config_bool - evaluate boolean-valued configuration variable */
int get_config_bool(const char *name, int defval)
{
int intval;
if (convert_config_bool(name, &intval) == 0)
set_config_bool(name, intval = defval);
return (intval);
}
/* get_config_bool_fn - evaluate boolean-valued configuration variable */
typedef int (*stupid_indent_int) (void);
int get_config_bool_fn(const char *name, stupid_indent_int defval)
{
int intval;
if (convert_config_bool(name, &intval) == 0)
set_config_bool(name, intval = defval());
return (intval);
}
/* set_config_bool - update boolean-valued configuration dictionary entry */
void set_config_bool(const char *name, int value)
{
config_update(name, value ? CONFIG_BOOL_YES : CONFIG_BOOL_NO);
}
/* get_config_bool_table - look up table of booleans */
void get_config_bool_table(CONFIG_BOOL_TABLE *table)
{
while (table->name) {
table->target[0] = get_config_bool(table->name, table->defval);
table++;
}
}
/* get_config_bool_fn_table - look up booleans, defaults are functions */
void get_config_bool_fn_table(CONFIG_BOOL_FN_TABLE *table)
{
while (table->name) {
table->target[0] = get_config_bool_fn(table->name, table->defval);
table++;
}
}

193
postfix/global/config_int.c Normal file
View File

@@ -0,0 +1,193 @@
/*++
/* NAME
/* config_int 3
/* SUMMARY
/* integer-valued configuration parameter support
/* SYNOPSIS
/* #include <config.h>
/*
/* int get_config_int(name, defval, min, max);
/* const char *name;
/* int defval;
/* int min;
/* int max;
/*
/* int get_config_int_fn(name, defval, min, max);
/* const char *name;
/* int (*defval)();
/* int min;
/* int max;
/*
/* void set_config_int(name, value)
/* const char *name;
/* int value;
/*
/* void get_config_int_table(table)
/* CONFIG_INT_TABLE *table;
/*
/* void get_config_int_fn_table(table)
/* CONFIG_INT_TABLE *table;
/* AUXILIARY FUNCTIONS
/* int get_config_int2(name1, name2, defval, min, max);
/* const char *name1;
/* const char *name2;
/* int defval;
/* int min;
/* int max;
/* DESCRIPTION
/* This module implements configuration parameter support
/* for integer values.
/*
/* get_config_int() looks up the named entry in the global
/* configuration dictionary. The default value is returned
/* when no value was found.
/* \fImin\fR is zero or specifies a lower limit on the integer
/* value or string length; \fImax\fR is zero or specifies an
/* upper limit on the integer value or string length.
/*
/* get_config_int_fn() is similar but specifies a function that
/* provides the default value. The function is called only
/* when the default value is needed.
/*
/* set_config_int() updates the named entry in the global
/* configuration dictionary. This has no effect on values that
/* have been looked up earlier via the get_config_XXX() routines.
/*
/* get_config_int_table() and get_config_int_fn_table() initialize
/* lists of variables, as directed by their table arguments. A table
/* must be terminated by a null entry.
/*
/* get_config_int2() concatenates the two names and is otherwise
/* identical to get_config_int().
/* DIAGNOSTICS
/* Fatal errors: malformed numerical value.
/* SEE ALSO
/* config(3) general configuration
/* config_str(3) string-valued configuration parameters
/* 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>
#include <stdio.h> /* sscanf() */
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <dict.h>
#include <stringops.h>
/* Global library. */
#include "config.h"
/* convert_config_int - look up and convert integer parameter value */
static int convert_config_int(const char *name, int *intval)
{
const char *strval;
char junk;
if ((strval = config_lookup_eval(name)) != 0) {
if (sscanf(strval, "%d%c", intval, &junk) != 1)
msg_fatal("bad numerical configuration: %s = %s", name, strval);
return (1);
}
return (0);
}
/* check_config_int - validate integer value */
static void check_config_int(const char *name, int intval, int min, int max)
{
if (min && intval < min)
msg_fatal("invalid %s: %d (min %d)", name, intval, min);
if (max && intval > max)
msg_fatal("invalid %s: %d (max %d)", name, intval, max);
}
/* get_config_int - evaluate integer-valued configuration variable */
int get_config_int(const char *name, int defval, int min, int max)
{
int intval;
if (convert_config_int(name, &intval) == 0)
set_config_int(name, intval = defval);
check_config_int(name, intval, min, max);
return (intval);
}
/* get_config_int2 - evaluate integer-valued configuration variable */
int get_config_int2(const char *name1, const char *name2, int defval,
int min, int max)
{
int intval;
char *name;
name = concatenate(name1, name2, (char *) 0);
if (convert_config_int(name, &intval) == 0)
set_config_int(name, intval = defval);
check_config_int(name, intval, min, max);
myfree(name);
return (intval);
}
/* get_config_int_fn - evaluate integer-valued configuration variable */
typedef int (*stupid_indent_int) (void);
int get_config_int_fn(const char *name, stupid_indent_int defval,
int min, int max)
{
int intval;
if (convert_config_int(name, &intval) == 0)
set_config_int(name, intval = defval());
check_config_int(name, intval, min, max);
return (intval);
}
/* set_config_int - update integer-valued configuration dictionary entry */
void set_config_int(const char *name, int value)
{
char buf[BUFSIZ]; /* yeah! crappy code! */
sprintf(buf, "%d", value); /* yeah! more crappy code! */
config_update(name, buf);
}
/* get_config_int_table - look up table of integers */
void get_config_int_table(CONFIG_INT_TABLE *table)
{
while (table->name) {
table->target[0] = get_config_int(table->name, table->defval,
table->min, table->max);
table++;
}
}
/* get_config_int_fn_table - look up integers, defaults are functions */
void get_config_int_fn_table(CONFIG_INT_FN_TABLE *table)
{
while (table->name) {
table->target[0] = get_config_int_fn(table->name, table->defval,
table->min, table->max);
table++;
}
}

160
postfix/global/config_str.c Normal file
View File

@@ -0,0 +1,160 @@
/*++
/* NAME
/* config_str 3
/* SUMMARY
/* string-valued global configuration parameter support
/* SYNOPSIS
/* #include <config.h>
/*
/* char *get_config_str(name, defval, min, max)
/* const char *name;
/* const char *defval;
/* int min;
/* int max;
/*
/* char *get_config_str_fn(name, defval, min, max)
/* const char *name;
/* const char *(*defval)(void);
/* int min;
/* int max;
/*
/* void set_config_str(name, value)
/* const char *name;
/* const char *value;
/*
/* void get_config_str_table(table)
/* CONFIG_STR_TABLE *table;
/*
/* void get_config_str_fn_table(table)
/* CONFIG_STR_TABLE *table;
/* DESCRIPTION
/* This module implements support for string-valued global
/* configuration parameters.
/*
/* get_config_str() looks up the named entry in the global
/* configuration dictionary. The default value is returned when
/* no value was found. String results should be passed to myfree()
/* when no longer needed. \fImin\fR is zero or specifies a lower
/* bound on the string length; \fImax\fR is zero or specifies an
/* upper limit on the string length.
/*
/* get_config_str_fn() is similar but specifies a function that
/* provides the default value. The function is called only when
/* the default value is used.
/*
/* set_config_str() updates the named entry in the global
/* configuration dictionary. This has no effect on values that
/* have been looked up earlier via the get_config_XXX() routines.
/*
/* get_config_str_table() and get_config_str_fn_table() read
/* lists of variables, as directed by their table arguments. A table
/* must be terminated by a null entry.
/* DIAGNOSTICS
/* Fatal errors: bad string length.
/* SEE ALSO
/* config(3) generic config parameter support
/* 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>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
/* Global library. */
#include "config.h"
/* check_config_str - validate string length */
static void check_config_str(const char *name, const char *strval,
int min, int max)
{
int len = strlen(strval);
if (min && len < min)
msg_fatal("bad string length (%d < %d): %s = %s",
len, min, name, strval);
if (max && len > max)
msg_fatal("bad string length (%d > %d): %s = %s",
len, max, name, strval);
}
/* get_config_str - evaluate string-valued configuration variable */
char *get_config_str(const char *name, const char *defval,
int min, int max)
{
const char *strval;
if ((strval = config_lookup_eval(name)) == 0) {
strval = config_eval(defval);
config_update(name, strval);
}
check_config_str(name, strval, min, max);
return (mystrdup(strval));
}
/* get_config_str_fn - evaluate string-valued configuration variable */
typedef const char *(*stupid_indent_str) (void);
char *get_config_str_fn(const char *name, stupid_indent_str defval,
int min, int max)
{
const char *strval;
if ((strval = config_lookup_eval(name)) == 0) {
strval = config_eval(defval());
config_update(name, strval);
}
check_config_str(name, strval, min, max);
return (mystrdup(strval));
}
/* set_config_str - update string-valued configuration dictionary entry */
void set_config_str(const char *name, const char *value)
{
config_update(name, value);
}
/* get_config_str_table - look up table of strings */
void get_config_str_table(CONFIG_STR_TABLE *table)
{
while (table->name) {
if (table->target[0])
myfree(table->target[0]);
table->target[0] = get_config_str(table->name, table->defval,
table->min, table->max);
table++;
}
}
/* get_config_str_fn_table - look up strings, defaults are functions */
void get_config_str_fn_table(CONFIG_STR_FN_TABLE *table)
{
while (table->name) {
if (table->target[0])
myfree(table->target[0]);
table->target[0] = get_config_str_fn(table->name, table->defval,
table->min, table->max);
table++;
}
}

129
postfix/global/debug_peer.c Normal file
View File

@@ -0,0 +1,129 @@
/*++
/* NAME
/* debug_peer 3
/* SUMMARY
/* increase verbose logging for specific peers
/* SYNOPSIS
/* #include <debug_peer.h>
/*
/* void debug_peer_init(void)
/*
/* int peer_debug_check(peer_name, peer_addr)
/* const char *peer_name;
/* const char *peer_addr;
/*
/* void debug_peer_restore()
/* DESCRIPTION
/* This module implements increased verbose logging for specific
/* network peers.
/*
/* The \fIdebug_peer_list\fR configuration parameter
/* specifies what peers receive this special treatment; see
/* namadr_list(3) for a description of the matching process.
/*
/* The \fIdebug_peer_level\fR configuration parameter specifies
/* by what amount the verbose logging level should increase when
/* a peer is listed in \fIdebug_peer_list\fR.
/*
/* debug_peer_init() performs initializations that must be
/* performed once at the start of the program.
/*
/* debug_peer_check() increases the verbose logging level when the
/* client name or address matches the debug_peer_list pattern.
/* The result is non-zero when the noise leven was increased.
/*
/* debug_peer_restore() restores the verbose logging level.
/* This routine has no effect when debug_peer_check() had no
/* effect; this routine can safely be called multiple times.
/* DIAGNOSTICS
/* Panic: interface violations.
/* Fatal errors: unable to access a peer_list file; invalid
/* peer_list pattern; invalid verbosity level increment.
/* SEE ALSO
/* msg(3) the msg_verbose variable
/* namadr_list(3) match host by name or by address
/* CONFIG PARAMETERS
/* debug_peer_list, patterns as described in namadr_list(3)
/* debug_peer_level, verbose logging level
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <msg.h>
/* Global library. */
#include <mail_params.h>
#include <namadr_list.h>
#include <debug_peer.h>
/* Application-specific. */
#define UNUSED_SAVED_LEVEL (-1)
static NAMADR_LIST *debug_peer_list;
static int saved_level = UNUSED_SAVED_LEVEL;
/* debug_peer_init - initialize */
void debug_peer_init(void)
{
char *myname = "debug_peer_init";
/*
* Sanity check.
*/
if (debug_peer_list)
msg_panic("%s: repeated call", myname);
if (var_debug_peer_list == 0)
msg_panic("%s: uninitialized %s", myname, VAR_DEBUG_PEER_LIST);
if (var_debug_peer_level <= 0)
msg_fatal("%s: %s <= 0", myname, VAR_DEBUG_PEER_LEVEL);
/*
* Finally.
*/
if (*var_debug_peer_list)
debug_peer_list = namadr_list_init(var_debug_peer_list);
}
/* debug_peer_check - see if this peer needs verbose logging */
int debug_peer_check(const char *name, const char *addr)
{
/*
* Crank up the noise when this peer is listed.
*/
if (debug_peer_list != 0
&& saved_level == UNUSED_SAVED_LEVEL
&& namadr_list_match(debug_peer_list, name, addr) != 0) {
saved_level = msg_verbose;
msg_verbose += var_debug_peer_level;
return (1);
}
return (0);
}
/* debug_peer_restore - restore logging level */
void debug_peer_restore(void)
{
if (saved_level != UNUSED_SAVED_LEVEL) {
msg_verbose = saved_level;
saved_level = UNUSED_SAVED_LEVEL;
}
}

View File

@@ -0,0 +1,31 @@
#ifndef _DEBUG_PEER_H_INCLUDED_
#define _DEBUG_PEER_H_INCLUDED_
/*++
/* NAME
/* debug_peer 3h
/* SUMMARY
/* increase verbose logging for specific peers
/* SYNOPSIS
/* #include <debug_peer.h>
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
extern void debug_peer_init(void);
extern int debug_peer_check(const char *, const char *);
extern void debug_peer_restore(void);
/* 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
/*--*/
#endif

View File

@@ -0,0 +1,62 @@
/*++
/* NAME
/* debug_process 3
/* SUMMARY
/* run an external debugger
/* SYNOPSIS
/* #include <debug_process.h>
/*
/* char *debug_process()
/* DESCRIPTION
/* debug_process() runs a debugger, as specified in the
/* \fIdebugger_command\fR configuration variable.
/*
/* Examples of non-interactive debuggers are call tracing tools
/* such as: trace, strace or truss.
/*
/* Examples of interactive debuggers are xxgdb, xxdbx, and so on.
/* In order to use an X-based debugger, the process must have a
/* properly set up XAUTHORITY environment variable.
/* 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 <string.h>
#include <stdlib.h>
#include <unistd.h>
/* Utility library. */
#include <msg.h>
/* Global library. */
#include "mail_params.h"
#include "config.h"
#include "debug_process.h"
/* debug_process - run a debugger on this process */
void debug_process(void)
{
const char *command;
/*
* Expand $debugger_command then run it.
*/
command = config_lookup_eval(VAR_DEBUG_COMMAND);
if (*command == 0)
msg_fatal("no %s variable set up", VAR_DEBUG_COMMAND);
msg_info("running: %s", command);
system(command);
}

View File

@@ -0,0 +1,30 @@
#ifndef _DEBUG_PROCESS_H_INCLUDED_
#define _DEBUG_PROCESS_H_INCLUDED_
/*++
/* NAME
/* debug_process 3h
/* SUMMARY
/* run an external debugger
/* SYNOPSIS
/* #include <unistd.h>
/* #include <debug_process.h>
/* DESCRIPTION
/* .nf
/* External interface. */
extern void debug_process(void);
/* 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
/*--*/
#endif

156
postfix/global/defer.c Normal file
View File

@@ -0,0 +1,156 @@
/*++
/* NAME
/* defer 3
/* SUMMARY
/* defer service client interface
/* SYNOPSIS
/* #include <defer.h>
/*
/* int defer_append(flags, id, recipient, relay, entry, format, ...)
/* int flags;
/* const char *id;
/* const char *recipient;
/* const char *relay;
/* time_t entry;
/* const char *format;
/*
/* int vdefer_append(flags, id, recipient, relay, entry, format, ap)
/* int flags;
/* const char *id;
/* const char *recipient;
/* const char *relay;
/* time_t entry;
/* const char *format;
/* va_list ap;
/*
/* int defer_flush(flags, queue, id, sender)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *sender;
/* DESCRIPTION
/* This module implements a client interface to the defer service,
/* which maintains a per-message logfile with status records for
/* each recipient whose delivery is deferred, and the reason why.
/*
/* defer_append() appends a record to the per-message defer log,
/* with the reason for delayed delivery to the named recipient.
/* The result is a convenient non-zero value.
/*
/* vdefer_append() implements an alternative client interface.
/*
/* defer_flush() bounces the specified message to the specified
/* sender, including the defer log that was built with defer_append().
/* The result is zero in case of success, non-zero otherwise.
/*
/* Arguments:
/* .IP flags
/* The bit-wise OR of zero or more of the following (specify
/* BOUNCE_FLAG_NONE to explicitly request not special processing):
/* .RS
/* .IP BOUNCE_FLAG_CLEAN
/* Delete the defer log in case of an error (as in: pretend
/* that we never even tried to defer this message).
/* .IP BOUNCE_FLAG_COPY
/* Request that postmaster a copy is sent (defer_flush() only).
/* .RE
/* .IP queue
/* The message queue name of the original message file.
/* .IP id
/* The queue id of the original message file.
/* .IP recipient
/* A recipient address that is being deferred. The domain part
/* of the address is marked dead (for a limited amount of time).
/* .IP sender
/* The sender envelope address.
/* .IP relay
/* Host we could not talk to.
/* .IP entry
/* Message arrival time.
/* .IP format
/* The reason for non-delivery.
/* .IP ap
/* Variable-length argument list.
/* .PP
/* For convenience, these functions always return a non-zero result.
/* DIAGNOSTICS
/* Warnings: problems connecting to the defer service.
/* Fatal: out of memory.
/* BUGS
/* Should be replaced by routines with an attribute-value based
/* interface instead of an interface that uses a rigid argument list.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
/* Global library. */
#include "mail_queue.h"
#include "mail_proto.h"
#include "bounce.h"
#include "defer.h"
/* defer_append - defer message delivery */
int defer_append(int flags, const char *id, const char *recipient,
const char *relay, time_t entry, const char *fmt,...)
{
va_list ap;
int status;
va_start(ap, fmt);
status = vdefer_append(flags, id, recipient, relay, entry, fmt, ap);
va_end(ap);
return (status);
}
/* vdefer_append - defer delivery of queue file */
int vdefer_append(int flags, const char *id, const char *recipient,
const char *relay, time_t entry, const char *fmt, va_list ap)
{
VSTRING *why = vstring_alloc(100);
int delay = time((time_t *) 0) - entry;
vstring_vsprintf(why, fmt, ap);
if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER,
"%d %d %s %s %s", BOUNCE_CMD_APPEND,
flags, id, recipient, vstring_str(why)) != 0)
msg_warn("%s: defer service failure", id);
msg_info("%s: to=<%s>, relay=%s, delay=%d, status=deferred (%s)",
id, recipient, relay, delay, vstring_str(why));
vstring_free(why);
return (-1);
}
/* defer_flush - flush the defer log and deliver to the sender */
int defer_flush(int flags, const char *queue, const char *id,
const char *sender)
{
if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER,
"%d %d %s %s %s", BOUNCE_CMD_FLUSH,
flags, queue, id, sender) == 0) {
return (0);
} else {
return (-1);
}
}

45
postfix/global/defer.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef _DEFER_H_INCLUDED_
#define _DEFER_H_INCLUDED_
/*++
/* NAME
/* defer 3h
/* SUMMARY
/* defer service client interface
/* SYNOPSIS
/* #include <defer.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <time.h>
#include <stdarg.h>
/*
* Global library.
*/
#include <bounce.h>
/*
* External interface.
*/
extern int defer_append(int, const char *, const char *, const char *,
time_t, const char *,...);
extern int vdefer_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int defer_flush(int, const char *, const char *, const char *);
/* 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
/*--*/
#endif

Some files were not shown because too many files have changed in this diff Show More