Postfix version 19991231 patchlevel 03 fixes low-priority defects
and provides workarounds for unusual conditions.
- Workaround to prevent one site with a huge backlog from blocking
all other deliveries. This is controlled by a new configuration
parameter qmgr_site_hog_factor (default: 90 percent) that limits
how much in-memory queue manager resources a site can claim.
- Workarounds for the most likely problems that will happen when
running the Postfix queue on top of NFS.
- The SMTP server did not look in the relocated table and would
report "User unknown" rather than letting the mail bounce the
way it is supposed to be.
- When requested to extract recipients from message headers, Postfix
now insists that no message header exceeds the header size limit.
This prevents Postfix from inadvertently disclosing Bcc: addresses.
postfix-19991231-patch03 is about 1500 lines. This is too large
for distribution via mail. The patch and a fully-patched version
of the source code are being made available via the usual FTP
servers, primary site:
ftp://ftp.porcupine.org/mirrors/postfix-release/official/
Or, if you use a web browser,
ftp://ftp.porcupine.org/mirrors/postfix-release/index.html
Wietse
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/global/mail_version.h ./global/mail_version.h
*** ../postfix-19991231-pl02/global/mail_version.h Tue Jan 4 08:12:42 2000
--- ./global/mail_version.h Thu Jan 6 11:10:10 2000
***************
*** 15,21 ****
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
! #define DEF_MAIL_VERSION "Postfix-19991231-pl02"
extern char *var_mail_version;
/* LICENSE
--- 15,21 ----
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
! #define DEF_MAIL_VERSION "Postfix-19991231-pl03"
extern char *var_mail_version;
/* LICENSE
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/HISTORY ./HISTORY
*** ../postfix-19991231-pl02/HISTORY Tue Jan 4 08:30:35 2000
--- ./HISTORY Thu Jan 27 21:13:39 2000
***************
*** 3528,3536 ****
for this common error and logs a warning instead of refusing
the mail. File: smtpd/smtpd_check.c.
! 20000103
Bugfix: a case sensitivity bug had slipped through in the
anti-relaying code, causing mail for USER@VIRTUAL.DOMAIN
to be rejected with "relay access denied". This was found
by Jim Maenpaa @ jmm.com.
--- 3528,3603 ----
for this common error and logs a warning instead of refusing
the mail. File: smtpd/smtpd_check.c.
! 20000104
Bugfix: a case sensitivity bug had slipped through in the
anti-relaying code, causing mail for USER@VIRTUAL.DOMAIN
to be rejected with "relay access denied". This was found
by Jim Maenpaa @ jmm.com.
+
+ Portability: Ultrix patch from Simon Burge @ thistledown.com.au.
+
+ Portability: Siemens Pyramid (dcosx) patch by Thomas D.
+ Knox @ vushta.com.
+
+ 20000105
+
+ Cleanup: the INSTALL.sh script now updates the sample files
+ in /etc/postfix even when main.cf exists.
+
+ 20000106
+
+ Bugfix: the SMTP server should consult the relocated map
+ for virtual destinations (Denis Shaposhnikov). Files:
+ smtpd/smtpd.c smtpd/smtpd_check.c.
+
+ 20000108
+
+ Workaround: rename() over NFS can fail with ENOENT even
+ when the operation succeeds (Graham Orndorff @ WebTV). This
+ is not news. Any non-idempotent operation can fail over
+ NFS when the NFS server's acknowledgement is lost and the
+ NFS client code retries the operation (other examples are:
+ create, symlink, link, unlink, mkdir, rmdir). Postfix has
+ workarounds for the cases where this is most likely to
+ cause trouble. Files: util/sane_{rename,link}.[hc]. If
+ you want reliable mail system, do not use NFS.
+
+ 20000115
+
+ Workaround: better detection of bad hardware. Added SIGBUS
+ to the list of signals that the master will log before
+ exiting.
+
+ 20000122
+
+ Portability: preliminary SCO5 port Christopher Wong @
+ csports.com. This still needs to a workaround for "find"
+ not supporting "-type s" (actually, UNIX-domain sockets
+ have no unique representation in the file system and show
+ up as FIFOs).
+
+ 20000115-22
+
+ Bugfix: in case of a too long message header, don't extract
+ recipients from message headers. With the previous behavior,
+ Bcc information could be left in the message body, as one
+ person found out the hard way. Files: cleanup/cleanup.c,
+ cleanup/cleanup_extracted.c, global/cleanup_user.h.
+
+ 20000124
+
+ Whatever: RFC 1869 amends RFC 821 and specifies that code
+ 555 is to be used when a MAIL FROM or RCPT TO parameter is
+ not implemented or not recognized. Russ Allbery @stanford.edu.
+ This reply code is added to the list of reply codes that
+ cause the Postfix SMTP client to mail a transcript to the
+ postmaster. File: smtp/smtp_trouble.c.
+
+ 20000126
+
+ Emergency feature: qmgr_site_hog_factor (default: 90
+ percent) limits the amount of resources that Postfix will
+ devote to a single site. With less than 100, Postfix will
+ defer the excess mail so that one site with a large backlog
+ does not block other deliveries.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/INSTALL.sh ./INSTALL.sh
*** ../postfix-19991231-pl02/INSTALL.sh Fri Dec 31 10:47:21 1999
--- ./INSTALL.sh Thu Jan 27 21:12:59 2000
***************
*** 255,263 ****
compare_or_symlink $SENDMAIL_PATH $MAILQ_PATH
}
! compare_or_replace a+r,go-w conf/LICENSE $CONFIG_DIRECTORY/LICENSE || exit 1
!
! test -f $CONFIG_DIRECTORY/main.cf || {
cp conf/* $CONFIG_DIRECTORY || exit 1
chmod a+r,go-w $CONFIG_DIRECTORY/* || exit 1
--- 255,267 ----
compare_or_symlink $SENDMAIL_PATH $MAILQ_PATH
}
! if [ -f $CONFIG_DIRECTORY/main.cf ]
! then
! for file in LICENSE `cd conf; echo sample*` main.cf.default
! do
! compare_or_replace a+r,go-w conf/$file $CONFIG_DIRECTORY/$file || exit 1
! done
! else
cp conf/* $CONFIG_DIRECTORY || exit 1
chmod a+r,go-w $CONFIG_DIRECTORY/* || exit 1
***************
*** 269,275 ****
echo "BTW: Edit your alias database and be sure to set up aliases" 1>&2
echo "for root and postmaster, then run $NEWALIASES_PATH." 1>&2
}
! }
# Save settings.
--- 273,279 ----
echo "BTW: Edit your alias database and be sure to set up aliases" 1>&2
echo "for root and postmaster, then run $NEWALIASES_PATH." 1>&2
}
! fi
# Save settings.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/RELEASE_NOTES ./RELEASE_NOTES
*** ../postfix-19991231-pl02/RELEASE_NOTES Sun Jan 2 12:41:54 2000
--- ./RELEASE_NOTES Thu Jan 6 09:52:40 2000
***************
*** 77,85 ****
domains that are defined by Postfix virtual maps.
- The SMTP server can reject mail for unknown local users. Specify
! "local_recipient_maps = $relocated_maps, $alias_maps, unix:passwd.byname"
! if your local mail is delivered by a UNIX-style local delivery
! agent. See example in conf/main.cf.
- Use "disable_vrfy_command = yes" to disable the SMTP VRFY command.
This prevents some forms of address harvesting.
--- 77,85 ----
domains that are defined by Postfix virtual maps.
- The SMTP server can reject mail for unknown local users. Specify
! "local_recipient_maps = $alias_maps, unix:passwd.byname" if your
! local mail is delivered by a UNIX-style local delivery agent. See
! example in conf/main.cf.
- Use "disable_vrfy_command = yes" to disable the SMTP VRFY command.
This prevents some forms of address harvesting.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/cleanup/cleanup.c ./cleanup/cleanup.c
*** ../postfix-19991231-pl02/cleanup/cleanup.c Fri Aug 13 10:16:22 1999
--- ./cleanup/cleanup.c Thu Jan 27 20:17:48 2000
***************
*** 267,280 ****
* 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;
}
/*
--- 267,281 ----
* 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,
! * discard input after any lethal 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 = CLEANUP_STAT_LETHAL;
}
/*
***************
*** 321,338 ****
* 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) {
--- 322,348 ----
* file in the first place).
*
* Do not log the arrival of a message that will be bounced by the client.
+ *
+ * XXX CLEANUP_STAT_LETHAL masks errors that are not directly fatal (e.g.,
+ * header buffer overflow is normally allowed to happen), but that can
+ * indirectly become a problem (e.g., no recipients were extracted from
+ * message headers because we could not process all the message headers).
+ * However, cleanup_strerror() prioritizes errors so that it can report
+ * the cause (e.g., header buffer overflow), which is more useful.
+ * Amazing.
*/
#define CAN_BOUNCE() \
((cleanup_errs & (CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE)) == 0 \
&& cleanup_sender != 0 \
&& (cleanup_flags & CLEANUP_FLAG_BOUNCE) != 0)
! if (cleanup_errs & CLEANUP_STAT_LETHAL) {
if (CAN_BOUNCE()) {
if (bounce_append(BOUNCE_FLAG_CLEAN,
cleanup_queue_id, cleanup_recip ?
cleanup_recip : "", "cleanup", cleanup_time,
! "Message rejected: %s",
! cleanup_strerror(cleanup_errs)) == 0
&& bounce_flush(BOUNCE_FLAG_CLEAN,
MAIL_QUEUE_INCOMING,
cleanup_queue_id, cleanup_sender) == 0) {
***************
*** 354,360 ****
*/
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);
--- 364,371 ----
*/
junk = cleanup_path;
cleanup_path = 0; /* don't delete upon error */
! mail_print(cleanup_src, "%d", /* we're committed now */
! cleanup_errs & CLEANUP_STAT_LETHAL);
if (msg_verbose)
msg_info("cleanup_service: status %d", cleanup_errs);
myfree(junk);
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/cleanup/cleanup_extracted.c ./cleanup/cleanup_extracted.c
*** ../postfix-19991231-pl02/cleanup/cleanup_extracted.c Wed Aug 18 19:39:26 1999
--- ./cleanup/cleanup_extracted.c Sat Jan 22 15:08:51 2000
***************
*** 119,128 ****
/*
* Optionally account for missing recipient envelope records.
*
* XXX Code duplication from cleanup_envelope.c. This should be in one
* place.
*/
! if (cleanup_recip == 0) {
rcpt = (cleanup_resent[0] ? cleanup_resent_recip : cleanup_recipients);
if (*var_always_bcc && rcpt->argv[0]) {
clean_addr = vstring_alloc(100);
--- 119,131 ----
/*
* Optionally account for missing recipient envelope records.
*
+ * Don't extract recipients when some header was too long. We have
+ * incomplete information.
+ *
* XXX Code duplication from cleanup_envelope.c. This should be in one
* place.
*/
! if (cleanup_recip == 0 && (cleanup_errs & CLEANUP_STAT_HOVFL) == 0) {
rcpt = (cleanup_resent[0] ? cleanup_resent_recip : cleanup_recipients);
if (*var_always_bcc && rcpt->argv[0]) {
clean_addr = vstring_alloc(100);
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/cleanup/cleanup_message.c ./cleanup/cleanup_message.c
*** ../postfix-19991231-pl02/cleanup/cleanup_message.c Wed Nov 3 20:09:45 1999
--- ./cleanup/cleanup_message.c Thu Jan 27 20:27:59 2000
***************
*** 408,415 ****
* 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;
--- 408,417 ----
* 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)) {
! cleanup_errs |= CLEANUP_STAT_HOVFL;
! } else if (ISSPACE(*start)) {
VSTRING_ADDCH(cleanup_header_buf, '\n');
vstring_strcat(cleanup_header_buf, start);
continue;
***************
*** 431,438 ****
* 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();
--- 433,439 ----
* immediately followed by a non-empty message body.
*/
if (in_header
! && ((cleanup_errs & CLEANUP_STAT_HOVFL)
|| !is_header(start))) {
in_header = 0;
cleanup_missing_headers();
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/conf/main.cf ./conf/main.cf
*** ../postfix-19991231-pl02/conf/main.cf Sun Jan 2 14:19:11 2000
--- ./conf/main.cf Thu Jan 6 09:52:45 2000
***************
*** 128,134 ****
# FOR THIS TO WORK, DO NOT SPECIFY VIRTUAL DOMAINS IN MYDESTINATION.
# MYDESTINATION MUST LIST NON-VIRTUAL DOMAINS ONLY.
#
! #local_recipient_maps = $relocated_maps $alias_maps unix:passwd.byname
# ADDRESS REWRITING
#
--- 128,134 ----
# FOR THIS TO WORK, DO NOT SPECIFY VIRTUAL DOMAINS IN MYDESTINATION.
# MYDESTINATION MUST LIST NON-VIRTUAL DOMAINS ONLY.
#
! #local_recipient_maps = $alias_maps unix:passwd.byname
# ADDRESS REWRITING
#
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/global/cleanup_strerror.c ./global/cleanup_strerror.c
*** ../postfix-19991231-pl02/global/cleanup_strerror.c Fri Dec 11 13:55:23 1998
--- ./global/cleanup_strerror.c Sat Jan 22 15:15:52 2000
***************
*** 39,45 ****
/*
* 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;
--- 39,46 ----
/*
* 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,
! * or to list the cause (header overflow) before the effect (no recipients),
! * because cleanup_strerror() can report only one error.
*/
struct cleanup_stat_map {
unsigned status;
***************
*** 48,53 ****
--- 49,55 ----
static struct cleanup_stat_map cleanup_stat_map[] = {
CLEANUP_STAT_BAD, "Internal protocol error",
+ CLEANUP_STAT_HOVFL, "Message header too long",
CLEANUP_STAT_RCPT, "No recipients specified",
CLEANUP_STAT_HOPS, "Too many hops",
CLEANUP_STAT_SIZE, "Message file too big",
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/global/cleanup_user.h ./global/cleanup_user.h
*** ../postfix-19991231-pl02/global/cleanup_user.h Fri Dec 11 13:55:24 1998
--- ./global/cleanup_user.h Mon Jan 24 12:32:01 2000
***************
*** 31,36 ****
--- 31,39 ----
#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 */
+ #define CLEANUP_STAT_HOVFL (1<<7) /* Header overflow */
+
+ #define CLEANUP_STAT_LETHAL (~CLEANUP_STAT_HOVFL) /* lethal errors */
extern const char *cleanup_strerror(unsigned);
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/global/mail_params.h ./global/mail_params.h
*** ../postfix-19991231-pl02/global/mail_params.h Mon Dec 27 14:17:32 1999
--- ./global/mail_params.h Thu Jan 27 21:05:29 2000
***************
*** 420,425 ****
--- 420,426 ----
#define VAR_QMGR_ACT_LIMIT "qmgr_message_active_limit"
#define DEF_QMGR_ACT_LIMIT 1000
+ extern int var_qmgr_active_limit;
#define VAR_QMGR_RCPT_LIMIT "qmgr_message_recipient_limit"
#define DEF_QMGR_RCPT_LIMIT 10000
***************
*** 429,434 ****
--- 430,439 ----
#define DEF_QMGR_FUDGE 100
extern int var_qmgr_fudge;
+ #define VAR_QMGR_HOG "qmgr_site_hog_factor"
+ #define DEF_QMGR_HOG 90
+ extern int var_qmgr_hog;
+
/*
* Queue manager: default destination concurrency levels.
*/
***************
*** 437,442 ****
--- 442,448 ----
extern int var_init_dest_concurrency;
#define VAR_DEST_CON_LIMIT "default_destination_concurrency_limit"
+ #define _DEST_CON_LIMIT "_destination_concurrency_limit"
#define DEF_DEST_CON_LIMIT 10
extern int var_dest_con_limit;
***************
*** 444,451 ****
--- 450,461 ----
* Queue manager: default number of recipients per transaction.
*/
#define VAR_DEST_RCPT_LIMIT "default_destination_recipient_limit"
+ #define _DEST_RCPT_LIMIT "_destination_recipient_limit"
#define DEF_DEST_RCPT_LIMIT 50
extern int var_dest_rcpt_limit;
+
+ #define VAR_LOCAL_RCPT_LIMIT "local" _DEST_RCPT_LIMIT /* XXX */
+ #define DEF_LOCAL_RCPT_LIMIT 1 /* XXX */
/*
* Queue manager: default delay before retrying a dead transport.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/global/mail_queue.c ./global/mail_queue.c
*** ../postfix-19991231-pl02/global/mail_queue.c Tue Feb 16 11:25:22 1999
--- ./global/mail_queue.c Thu Jan 27 20:35:57 2000
***************
*** 299,304 ****
--- 299,305 ----
int fd;
const char *file_id;
VSTREAM *stream;
+ int count;
/*
* Initialize.
***************
*** 349,358 ****
file_id = get_file_id(fd);
GETTIMEOFDAY(&tv);
! for (;;) {
vstring_sprintf(id_buf, "%05X%s", (int) tv.tv_usec, file_id);
mail_queue_path(path_buf, queue_name, STR(id_buf));
! if (rename(STR(temp_path), STR(path_buf)) == 0) /* success */
break;
if (errno == EPERM || errno == EISDIR) {/* collision. weird. */
if ((int) ++tv.tv_usec < 0)
--- 350,359 ----
file_id = get_file_id(fd);
GETTIMEOFDAY(&tv);
! for (count = 0;; count++) {
vstring_sprintf(id_buf, "%05X%s", (int) tv.tv_usec, file_id);
mail_queue_path(path_buf, queue_name, STR(id_buf));
! if (sane_rename(STR(temp_path), STR(path_buf)) == 0) /* success */
break;
if (errno == EPERM || errno == EISDIR) {/* collision. weird. */
if ((int) ++tv.tv_usec < 0)
***************
*** 362,369 ****
if (errno != ENOENT || mail_queue_mkdirs(STR(path_buf)) < 0) {
msg_warn("%s: rename %s to %s: %m", myname,
STR(temp_path), STR(path_buf));
- sleep(10);
}
}
stream = vstream_fdopen(fd, O_RDWR);
--- 363,372 ----
if (errno != ENOENT || mail_queue_mkdirs(STR(path_buf)) < 0) {
msg_warn("%s: rename %s to %s: %m", myname,
STR(temp_path), STR(path_buf));
}
+ if (count > 1000) /* XXX whatever */
+ msg_fatal("%s: rename %s to %s: giving up", myname,
+ STR(temp_path), STR(path_buf));
}
stream = vstream_fdopen(fd, O_RDWR);
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/html/faq.html ./html/faq.html
*** ../postfix-19991231-pl02/html/faq.html Sun Jan 2 17:24:04 2000
--- ./html/faq.html Sat Jan 22 15:59:30 2000
***************
*** 87,92 ****
--- 87,94 ----
Postfix breaks the majordomo "approve" command
+ Postfix accepts MAIL FROM/RCPT TO "|command"
+
Mail relaying
***************
*** 1157,1163 ****
/etc/postfix/main.cf:
! local_recipient_maps = $relocated_maps $alias_maps, unix:passwd.byname
--- 1159,1165 ----
/etc/postfix/main.cf:
! local_recipient_maps = $alias_maps, unix:passwd.byname
***************
*** 1446,1451 ****
--- 1448,1496 ----
when delivering to commands such as majordomo. See the FAQ entry
titled "Getting rid of the ugly Delivered-To:
header".
+
+
+
+ Postfix accepts MAIL FROM and RCPT TO "|command"
+
+ With Postfix, | or / has special meaning only when it appears in
+ aliases, .forward files or in :include: files. It has no special
+ meaning in mail addresses.
+
+
+
+ If you must receive mail for systems with 10-year old vulnerabilities,
+ it is prudent to set up a regexp filter that rejects potentially
+ harmful MAIL FROM or RCPT TO commands.
+
+
+
+
+ /etc/postfix/main.cf:
+ smtpd_sender_restrictions =
+ regexp:/etc/postfix/envelope-regexp
+ reject_unknown_sender_domain
+ smtpd_recipient_restrictions =
+ regexp:/etc/postfix/envelope-regexp
+ permit_mynetworks
+ check_relay_domains
+
+ /etc/postfix/envelope-regexp:
+ /[/|]/ REJECT
+
+
+
+
+ However, rejecting all envelope addresses with / causes trouble
+ with simple-minded X.400 to Internet address mappings that leave
+ the X.400 address structure exposed.
+
+
+
+ See also the documentation on header
+ checks restrictions for message header contents. These restrictions
+ can be used to protect against attacks with command/file destinations
+ in, for example, Errors-To: or Return-Receipt_To: message headers.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/html/qmgr.8.html ./html/qmgr.8.html
*** ../postfix-19991231-pl02/html/qmgr.8.html Mon Dec 20 21:00:57 1999
--- ./html/qmgr.8.html Thu Jan 27 19:16:12 2000
***************
*** 289,328 ****
list receive that same burst of messages a whole
day later.
initial_destination_concurrency
! Initial per-destination concurrency level for par-
allel delivery to the same destination.
default_destination_concurrency_limit
! Default limit on the number of parallel deliveries
to the same destination.
transport_destination_concurrency_limit
! Limit on the number of parallel deliveries to the
! same destination, for delivery via the named mes-
sage transport.
Recipient controls
default_destination_recipient_limit
! Default limit on the number of recipients per mes-
sage transfer.
transport_destination_recipient_limit
! Limit on the number of recipients per message
transfer, for the named message transport.
- SEE ALSO
- master(8), process manager
- relocated(5), format of the "user has moved" table
- syslogd(8) system logging
- trivial-rewrite(8), address routing
-
- LICENSE
- The Secure Mailer license must be distributed with this
- software.
-
- AUTHOR(S)
- Wietse Venema
--- 289,328 ----
list receive that same burst of messages a whole
day later.
+ qmgr_site_hog_factor (valid range: 10..100)
+ The percentage of delivery resources that a busy
+ mail system will use up for delivery to a single
+ site. With 100%, mail is delivered in first-in,
+ first-out order, so that a burst of mail for one
+ site can block mail for other destinations. With
+ less than 100%, the excess mail is deferred. The
+ deferred mail is delivered in little bursts, the
+ remainder of the backlog being deferred again, with
+ a lot of I/O activity happening as Postfix searches
+ the deferred queue for deliverable mail.
+
initial_destination_concurrency
! Initial per-destination concurrency level for par-
allel delivery to the same destination.
default_destination_concurrency_limit
! Default limit on the number of parallel deliveries
to the same destination.
transport_destination_concurrency_limit
! Limit on the number of parallel deliveries to the
! same destination, for delivery via the named mes-
sage transport.
Recipient controls
default_destination_recipient_limit
! Default limit on the number of recipients per mes-
sage transfer.
transport_destination_recipient_limit
! Limit on the number of recipients per message
transfer, for the named message transport.
***************
*** 335,355 ****
QMGR(8) QMGR(8)
IBM T.J. Watson Research
P.O. Box 704
Yorktown Heights, NY 10598, USA
-
-
-
-
-
-
-
-
-
-
-
-
--- 335,355 ----
QMGR(8) QMGR(8)
+ SEE ALSO
+ master(8), process manager
+ relocated(5), format of the "user has moved" table
+ syslogd(8) system logging
+ trivial-rewrite(8), address routing
+
+ LICENSE
+ 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
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/local/maildir.c ./local/maildir.c
*** ../postfix-19991231-pl02/local/maildir.c Sun Jun 27 17:14:47 1999
--- ./local/maildir.c Sat Jan 22 16:35:41 2000
***************
*** 53,58 ****
--- 53,59 ----
#include
#include
#include
+ #include
/* Global library. */
***************
*** 136,145 ****
vstring_sprintf(why, "create %s: %m", tmpfile);
} else {
if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, why) == 0) {
! if (link(tmpfile, newfile) < 0
&& (errno != ENOENT
|| (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0
! || link(tmpfile, newfile) < 0)) {
vstring_sprintf(why, "link to %s: %m", newfile);
} else {
if (unlink(tmpfile) < 0)
--- 137,146 ----
vstring_sprintf(why, "create %s: %m", tmpfile);
} else {
if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, why) == 0) {
! if (sane_link(tmpfile, newfile) < 0
&& (errno != ENOENT
|| (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0
! || sane_link(tmpfile, newfile) < 0)) {
vstring_sprintf(why, "link to %s: %m", newfile);
} else {
if (unlink(tmpfile) < 0)
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/makedefs ./makedefs
*** ../postfix-19991231-pl02/makedefs Fri Dec 17 22:57:53 1999
--- ./makedefs Sat Jan 22 14:04:27 2000
***************
*** 51,67 ****
SYSTEM=`(uname -s) 2>/dev/null`
RELEASE=`(uname -r) 2>/dev/null`
case "$SYSTEM.$RELEASE" in
UnixWare.5*) SYSTYPE=UW7
! CC=cc
! DEBUG=
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl"
;;
UNIX_SV.4.2*) case "`uname -v`" in
2.1*) SYSTYPE=UW21
! CC=/usr/bin/cc
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl -lc -L/usr/ucblib -lucb"
;;
--- 51,81 ----
SYSTEM=`(uname -s) 2>/dev/null`
RELEASE=`(uname -r) 2>/dev/null`
+ VERSION=`(uname -v) 2>/dev/null`
+
+ case "$VERSION" in
+ dcosx*) SYSTEM=$VERSION;;
+ esac
case "$SYSTEM.$RELEASE" in
+ SCO_SV.3.2) SYSTYPE=SCO5
+ # Use the native compiler by default
+ : ${CC="/usr/bin/cc -b elf"}
+ : ${DEBUG=}
+ SYSLIBS="-lsocket -ldbm"
+ RANLIB=echo
+ ;;
UnixWare.5*) SYSTYPE=UW7
! # Use the native compiler by default
! : ${CC=/usr/bin/cc}
! : ${DEBUG=}
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl"
;;
UNIX_SV.4.2*) case "`uname -v`" in
2.1*) SYSTYPE=UW21
! # Use the native compiler by default
! : ${CC=/usr/bin/cc}
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl -lc -L/usr/ucblib -lucb"
;;
***************
*** 195,200 ****
--- 209,219 ----
: ${CC=cc}
AWK=gawk
;;
+ dcosx.1*) SYSTYPE=DCOSX1
+ RANLIB=echo
+ SYSLIBS="-lresolv -lsocket -lnsl -lc -lrpcsvc -L/usr/ucblib -lucb"
+ ;;
+
".") if [ -d /NextApps ]; then
SYSTYPE=`hostinfo | sed -n \
's/^.*NeXT Mach 3.*$/NEXTSTEP3/;/NEXTSTEP3/{p;q;}'`
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/man/man8/qmgr.8 ./man/man8/qmgr.8
*** ../postfix-19991231-pl02/man/man8/qmgr.8 Mon Dec 20 21:00:51 1999
--- ./man/man8/qmgr.8 Thu Jan 27 19:16:03 2000
***************
*** 223,228 ****
--- 223,237 ----
case, recipients near the beginning of a large list receive a burst
of messages immediately, while recipients near the end of that list
receive that same burst of messages a whole day later.
+ .IP "\fBqmgr_site_hog_factor\fR (valid range: 10..100)"
+ The percentage of delivery resources that a busy mail system will
+ use up for delivery to a single site.
+ With 100%, mail is delivered in first-in, first-out order, so that
+ a burst of mail for one site can block mail for other destinations.
+ With less than 100%, the excess mail is deferred. The deferred mail
+ is delivered in little bursts, the remainder of the backlog being
+ deferred again, with a lot of I/O activity happening as Postfix
+ searches the deferred queue for deliverable mail.
.IP \fBinitial_destination_concurrency\fR
Initial per-destination concurrency level for parallel delivery
to the same destination.
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/master/master_sig.c ./master/master_sig.c
*** ../postfix-19991231-pl02/master/master_sig.c Thu Feb 4 20:07:40 1999
--- ./master/master_sig.c Sat Jan 15 16:15:03 2000
***************
*** 159,165 ****
char *myname = "master_sigsetup";
struct sigaction action;
static int sigs[] = {
! SIGINT, SIGQUIT, SIGSEGV, SIGILL, SIGTERM,
};
unsigned i;
--- 159,165 ----
char *myname = "master_sigsetup";
struct sigaction action;
static int sigs[] = {
! SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSEGV, SIGTERM,
};
unsigned i;
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/postconf/local_table.h ./postconf/local_table.h
*** ../postfix-19991231-pl02/postconf/local_table.h Mon Dec 7 19:36:05 1998
--- ./postconf/local_table.h Thu Jan 27 20:42:24 2000
***************
*** 1,2 ****
"local_destination_concurrency_limit", "$default_destination_concurrency_limit", &var_local_destination_concurrency_limit, 0, 0,
- "local_destination_recipient_limit", "$default_destination_recipient_limit", &var_local_destination_recipient_limit, 0, 0,
--- 1 ----
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/postconf/local_vars.h ./postconf/local_vars.h
*** ../postfix-19991231-pl02/postconf/local_vars.h Mon Dec 7 19:35:08 1998
--- ./postconf/local_vars.h Thu Jan 27 20:42:36 2000
***************
*** 1,2 ****
char *var_local_destination_concurrency_limit;
- char *var_local_destination_recipient_limit;
--- 1 ----
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/qmgr/qmgr.c ./qmgr/qmgr.c
*** ../postfix-19991231-pl02/qmgr/qmgr.c Sat Dec 11 18:20:08 1999
--- ./qmgr/qmgr.c Thu Jan 27 20:47:53 2000
***************
*** 193,204 ****
/* use up for delivery of a large mailing list message.
/* With 100%, delivery of one message does not begin before the previous
/* message has been delivered. This results in good performance for large
! /* mailing lists, but results in poor response time for one-to-one mail.
/* With less than 100%, response time for one-to-one mail improves,
/* but large mailing list delivery performance suffers. In the worst
/* case, recipients near the beginning of a large list receive a burst
/* of messages immediately, while recipients near the end of that list
/* receive that same burst of messages a whole day later.
/* .IP \fBinitial_destination_concurrency\fR
/* Initial per-destination concurrency level for parallel delivery
/* to the same destination.
--- 193,213 ----
/* use up for delivery of a large mailing list message.
/* With 100%, delivery of one message does not begin before the previous
/* message has been delivered. This results in good performance for large
! /* mailing lists, but results in poor response time for one-to-one mail.
/* With less than 100%, response time for one-to-one mail improves,
/* but large mailing list delivery performance suffers. In the worst
/* case, recipients near the beginning of a large list receive a burst
/* of messages immediately, while recipients near the end of that list
/* receive that same burst of messages a whole day later.
+ /* .IP "\fBqmgr_site_hog_factor\fR (valid range: 10..100)"
+ /* The percentage of delivery resources that a busy mail system will
+ /* use up for delivery to a single site.
+ /* With 100%, mail is delivered in first-in, first-out order, so that
+ /* a burst of mail for one site can block mail for other destinations.
+ /* With less than 100%, the excess mail is deferred. The deferred mail
+ /* is delivered in little bursts, the remainder of the backlog being
+ /* deferred again, with a lot of I/O activity happening as Postfix
+ /* searches the deferred queue for deliverable mail.
/* .IP \fBinitial_destination_concurrency\fR
/* Initial per-destination concurrency level for parallel delivery
/* to the same destination.
***************
*** 280,286 ****
char *var_virtual_maps;
char *var_defer_xports;
bool var_allow_min_user;
! bool var_qmgr_fudge;
static QMGR_SCAN *qmgr_incoming;
static QMGR_SCAN *qmgr_deferred;
--- 289,297 ----
char *var_virtual_maps;
char *var_defer_xports;
bool var_allow_min_user;
! int var_qmgr_fudge;
! int var_qmgr_hog;
! int var_local_rcpt_lim; /* XXX */
static QMGR_SCAN *qmgr_incoming;
static QMGR_SCAN *qmgr_deferred;
***************
*** 474,479 ****
--- 485,492 ----
VAR_DEST_CON_LIMIT, DEF_DEST_CON_LIMIT, &var_dest_con_limit, 0, 0,
VAR_DEST_RCPT_LIMIT, DEF_DEST_RCPT_LIMIT, &var_dest_rcpt_limit, 0, 0,
VAR_QMGR_FUDGE, DEF_QMGR_FUDGE, &var_qmgr_fudge, 10, 100,
+ VAR_QMGR_HOG, DEF_QMGR_HOG, &var_qmgr_hog, 10, 100,
+ VAR_LOCAL_RCPT_LIMIT, DEF_LOCAL_RCPT_LIMIT, &var_local_rcpt_lim, 0, 0,
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/qmgr/qmgr_message.c ./qmgr/qmgr_message.c
*** ../postfix-19991231-pl02/qmgr/qmgr_message.c Thu Dec 23 20:04:42 1999
--- ./qmgr/qmgr_message.c Thu Jan 27 19:14:29 2000
***************
*** 528,535 ****
--- 528,537 ----
*/
if ((at = strrchr(STR(reply.recipient), '@')) == 0
|| resolve_local(at + 1)) {
+ #if 0
vstring_strcpy(reply.nexthop, STR(reply.recipient));
(void) split_at_right(STR(reply.nexthop), '@');
+ #endif
#if 0
if (*var_rcpt_delim)
(void) split_addr(STR(reply.nexthop), *var_rcpt_delim);
***************
*** 541,547 ****
* have to configure something for mail directed to the local
* postmaster, though, but that is an RFC requirement anyway.
*/
! if (strcasecmp(STR(reply.nexthop), var_double_bounce_sender) == 0) {
sent(message->queue_id, recipient->address,
"none", message->arrival_time, "discarded");
deliver_completed(message->fp, recipient->offset);
--- 543,551 ----
* have to configure something for mail directed to the local
* postmaster, though, but that is an RFC requirement anyway.
*/
! if (strncasecmp(STR(reply.recipient), var_double_bounce_sender,
! at - STR(reply.recipient)) == 0
! && !var_double_bounce_sender[at - STR(reply.recipient)]) {
sent(message->queue_id, recipient->address,
"none", message->arrival_time, "discarded");
deliver_completed(message->fp, recipient->offset);
***************
*** 609,614 ****
--- 613,635 ----
if (queue->window == 0) {
qmgr_defer_recipient(message, recipient->address, queue->reason);
continue;
+ }
+
+ /*
+ * This queue is a hog. Defer this recipient until the queue drains.
+ * When a site accumulates a large backlog, Postfix will deliver a
+ * little chunk and hammer the disk as it defers the remainder of the
+ * backlog and searches the deferred queue for deliverable mail.
+ */
+ if (var_qmgr_hog < 100) {
+ if (queue->todo_refcount + queue->busy_refcount
+ > (var_qmgr_hog / 100.0)
+ * (qmgr_recipient_count > 0.8 * var_qmgr_rcpt_limit ?
+ qmgr_message_count : var_qmgr_active_limit)) {
+ qmgr_defer_recipient(message, recipient->address,
+ "site destination queue overflow");
+ continue;
+ }
}
/*
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/smtp/smtp_trouble.c ./smtp/smtp_trouble.c
*** ../postfix-19991231-pl02/smtp/smtp_trouble.c Wed Jun 23 21:14:24 1999
--- ./smtp/smtp_trouble.c Mon Jan 24 12:22:46 2000
***************
*** 134,139 ****
--- 134,140 ----
* anti-UCE systems, by people who aren't aware of RFC details.
*/
if ((!SMTP_SOFT(code) && !SMTP_HARD(code))
+ || code == 555 /* RFC 1869, section 6.1. */
|| (code >= 500 && code < 510))
state->error_mask |= MAIL_ERROR_PROTOCOL;
}
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/smtpd/smtpd.c ./smtpd/smtpd.c
*** ../postfix-19991231-pl02/smtpd/smtpd.c Mon Dec 27 14:19:41 1999
--- ./smtpd/smtpd.c Thu Jan 6 09:55:48 2000
***************
*** 302,307 ****
--- 302,308 ----
char *var_canonical_maps;
char *var_rcpt_canon_maps;
char *var_virtual_maps;
+ char *var_relocated_maps;
char *var_alias_maps;
char *var_local_rcpt_maps;
bool var_allow_untrust_route;
***************
*** 1347,1352 ****
--- 1348,1354 ----
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_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_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
0,
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/smtpd/smtpd_check.c ./smtpd/smtpd_check.c
*** ../postfix-19991231-pl02/smtpd/smtpd_check.c Tue Jan 4 08:11:52 2000
--- ./smtpd/smtpd_check.c Thu Jan 6 09:56:16 2000
***************
*** 312,317 ****
--- 312,318 ----
static MAPS *rcpt_canon_maps;
static MAPS *canonical_maps;
static MAPS *virtual_maps;
+ static MAPS *relocated_maps;
/*
* Pre-opened access control lists.
***************
*** 455,460 ****
--- 456,463 ----
DICT_FLAG_LOCK);
virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps,
DICT_FLAG_LOCK);
+ relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
+ DICT_FLAG_LOCK);
/*
* Reply is used as a cache for resolved addresses, and error_text is
***************
*** 1969,1974 ****
--- 1972,1978 ----
if (*var_local_rcpt_maps
&& !mail_addr_find(rcpt_canon_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(canonical_maps, STR(reply.recipient), NOP)
+ && !mail_addr_find(relocated_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(local_rcpt_maps, STR(reply.recipient), NOP)) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"550 <%s>: User unknown", recipient);
***************
*** 1978,1983 ****
--- 1982,1988 ----
if (*var_virtual_maps
&& !mail_addr_find(rcpt_canon_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(canonical_maps, STR(reply.recipient), NOP)
+ && !mail_addr_find(relocated_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(virtual_maps, STR(reply.recipient), NOP)
&& maps_find(virtual_maps, domain, 0)) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
***************
*** 2064,2069 ****
--- 2069,2075 ----
char *var_rcpt_canon_maps;
char *var_canonical_maps;
char *var_virtual_maps;
+ char *var_relocated_maps;
char *var_local_rcpt_maps;
typedef struct {
***************
*** 2081,2086 ****
--- 2087,2093 ----
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps,
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps,
VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps,
+ VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps,
0,
};
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/Makefile.in ./util/Makefile.in
*** ../postfix-19991231-pl02/util/Makefile.in Thu Dec 30 16:54:00 1999
--- ./util/Makefile.in Mon Jan 24 12:32:49 2000
***************
*** 20,26 ****
vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \
write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
! clean_env.c watchdog.c spawn_command.c
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
--- 20,26 ----
vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \
write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
! clean_env.c watchdog.c spawn_command.c sane_rename.c sane_link.c
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
***************
*** 42,48 ****
vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \
write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
! clean_env.o watchdog.o spawn_command.o
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
--- 42,48 ----
vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \
write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
! clean_env.o watchdog.o spawn_command.o sane_rename.o sane_link.o
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
***************
*** 57,63 ****
timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
! watchdog.h spawn_command.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
--- 57,63 ----
timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
! watchdog.h spawn_command.h sane_fsops.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
***************
*** 716,721 ****
--- 716,729 ----
sane_accept.o: sane_accept.c
sane_accept.o: sys_defs.h
sane_accept.o: sane_accept.h
+ sane_link.o: sane_link.c
+ sane_link.o: sys_defs.h
+ sane_link.o: msg.h
+ sane_link.o: sane_fsops.h
+ sane_rename.o: sane_rename.c
+ sane_rename.o: sys_defs.h
+ sane_rename.o: msg.h
+ sane_rename.o: sane_fsops.h
scan_dir.o: scan_dir.c
scan_dir.o: sys_defs.h
scan_dir.o: msg.h
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/make_dirs.c ./util/make_dirs.c
*** ../postfix-19991231-pl02/util/make_dirs.c Fri Dec 11 13:55:38 1998
--- ./util/make_dirs.c Sat Jan 15 22:02:04 2000
***************
*** 72,80 ****
SKIP_WHILE(*cp != '/', cp);
if ((saved_ch = *cp) != 0)
*cp = 0;
! if ((ret = stat(saved_path, &st)) < 0)
! if (errno != ENOENT || (ret = mkdir(saved_path, perms)) < 0)
break;
if (saved_ch != 0)
*cp = saved_ch;
SKIP_WHILE(*cp == '/', cp);
--- 72,85 ----
SKIP_WHILE(*cp != '/', cp);
if ((saved_ch = *cp) != 0)
*cp = 0;
! if ((ret = stat(saved_path, &st)) >= 0) {
! if (!S_ISDIR(st.st_mode)) {
! errno = ENOTDIR;
! ret = -1;
break;
+ }
+ } else if (errno != ENOENT || (ret = mkdir(saved_path, perms)) < 0)
+ break;
if (saved_ch != 0)
*cp = saved_ch;
SKIP_WHILE(*cp == '/', cp);
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/sane_fsops.h ./util/sane_fsops.h
*** ../postfix-19991231-pl02/util/sane_fsops.h Wed Dec 31 19:00:00 1969
--- ./util/sane_fsops.h Thu Jan 27 20:57:35 2000
***************
*** 0 ****
--- 1,30 ----
+ #ifndef _SANE_FSOPS_H_
+ #define _SANE_FSOPS_H_
+
+ /*++
+ /* NAME
+ /* sane_rename 3h
+ /* SUMMARY
+ /* sanitize rename() error returns
+ /* SYNOPSIS
+ /* #include
+ /* DESCRIPTION
+ /* .nf
+
+ /* External interface. */
+
+ extern int sane_rename(const char *, const char *);
+ extern int sane_link(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
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/sane_link.c ./util/sane_link.c
*** ../postfix-19991231-pl02/util/sane_link.c Wed Dec 31 19:00:00 1969
--- ./util/sane_link.c Thu Jan 27 19:39:55 2000
***************
*** 0 ****
--- 1,71 ----
+ /*++
+ /* NAME
+ /* sane_link 3
+ /* SUMMARY
+ /* sanitize link() error returns
+ /* SYNOPSIS
+ /* #include
+ /*
+ /* int sane_link(old, new)
+ /* const char *from;
+ /* const char *to;
+ /* DESCRIPTION
+ /* sane_link() implements the link(2) system call, and works
+ /* around some errors that are possible with NFS file systems.
+ /* 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
+ #include
+ #include
+
+ /* Utility library. */
+
+ #include "msg.h"
+ #include "sane_fsops.h"
+
+ /* sane_link - sanitize link() error returns */
+
+ int sane_link(const char *from, const char *to)
+ {
+ char *myname = "sane_link";
+ int saved_errno;
+ struct stat from_st;
+ struct stat to_st;
+
+ /*
+ * Normal case: link() succeeds.
+ */
+ if (link(from, to) >= 0)
+ return (0);
+
+ /*
+ * Woops. Save errno, and see if the error is an NFS artefact. If it is,
+ * pretend the error never happened.
+ */
+ saved_errno = errno;
+ if (stat(from, &from_st) >= 0 && stat(to, &to_st) >= 0
+ && from_st.st_dev == to_st.st_dev
+ && from_st.st_ino == to_st.st_ino) {
+ msg_info("%s(%s,%s): worked around spurious NFS error",
+ myname, from, to);
+ return (0);
+ }
+
+ /*
+ * Nope, it didn't. Restore errno and report the error.
+ */
+ errno = saved_errno;
+ return (-1);
+ }
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/sane_rename.c ./util/sane_rename.c
*** ../postfix-19991231-pl02/util/sane_rename.c Wed Dec 31 19:00:00 1969
--- ./util/sane_rename.c Thu Jan 27 19:40:59 2000
***************
*** 0 ****
--- 1,68 ----
+ /*++
+ /* NAME
+ /* sane_rename 3
+ /* SUMMARY
+ /* sanitize rename() error returns
+ /* SYNOPSIS
+ /* #include
+ /*
+ /* int sane_rename(old, new)
+ /* const char *from;
+ /* const char *to;
+ /* DESCRIPTION
+ /* sane_rename() implements the rename(2) system call, and works
+ /* around some errors that are possible with NFS file systems.
+ /* 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
+ #include
+ #include /* rename(2) syscall in stdio.h? */
+
+ /* Utility library. */
+
+ #include "msg.h"
+ #include "sane_fsops.h"
+
+ /* sane_rename - sanitize rename() error returns */
+
+ int sane_rename(const char *from, const char *to)
+ {
+ char *myname = "sane_rename";
+ int saved_errno;
+ struct stat st;
+
+ /*
+ * Normal case: rename() succeeds.
+ */
+ if (rename(from, to) >= 0)
+ return (0);
+
+ /*
+ * Woops. Save errno, and see if the error is an NFS artefact. If it is,
+ * pretend the error never happened.
+ */
+ saved_errno = errno;
+ if (stat(from, &st) < 0 && stat(to, &st) >= 0) {
+ msg_info("%s(%s,%s): worked around spurious NFS error",
+ myname, from, to);
+ return (0);
+ }
+
+ /*
+ * Nope, it didn't. Restore errno and report the error.
+ */
+ errno = saved_errno;
+ return (-1);
+ }
diff -cr --exclude-from=/tmp/ignore --new-file ../postfix-19991231-pl02/util/sys_defs.h ./util/sys_defs.h
*** ../postfix-19991231-pl02/util/sys_defs.h Wed Nov 17 21:33:35 1999
--- ./util/sys_defs.h Sat Jan 22 16:03:31 2000
***************
*** 62,69 ****
#define UNSAFE_CTYPE /* XXX verify */
#define _PATH_MAILDIR "/var/spool/mail"
#define _PATH_BSHELL "/bin/sh"
! #define _PATH_DEFPATH "/usr/bin:/usr/ucb"
! #define _PATH_STDPATH "/usr/bin:/usr/etc:/usr/ucb"
#define USE_FLOCK_LOCK
#define USE_DOT_LOCK
#define HAS_FSYNC
--- 62,69 ----
#define UNSAFE_CTYPE /* XXX verify */
#define _PATH_MAILDIR "/var/spool/mail"
#define _PATH_BSHELL "/bin/sh"
! #define _PATH_DEFPATH "/bin:/usr/bin:/usr/ucb"
! #define _PATH_STDPATH "/bin:/usr/bin:/usr/etc:/usr/ucb"
#define USE_FLOCK_LOCK
#define USE_DOT_LOCK
#define HAS_FSYNC
***************
*** 79,84 ****
--- 79,85 ----
extern int optind;
extern char *optarg;
extern int opterr;
+ extern int h_errno;
#define MISSING_STRFTIME_E
#define HAS_NIS
***************
*** 554,559 ****
--- 555,618 ----
#define USE_STATVFS
#define STATVFS_IN_SYS_STATVFS_H
#define MISSING_USLEEP
+ #endif
+
+ #ifdef DCOSX1 /* Siemens Pyramid */
+ #define SUPPORTED
+ #include
+ #define _PATH_MAILDIR "/var/mail"
+ #define _PATH_BSHELL "/bin/sh"
+ #define _PATH_DEFPATH "/usr/bin:/usr/ucb"
+ #define _PATH_STDPATH "/usr/bin:/usr/sbin:/usr/ucb"
+ #define MISSING_SETENV
+ #define USE_FCNTL_LOCK
+ #define USE_DOT_LOCK
+ #define HAS_FSYNC
+ #define DEF_DB_TYPE "hash"
+ #define ALIAS_DB_MAP "hash:/etc/aliases"
+ /* Uncomment the following line if you have NIS package installed */
+ /* #define HAS_NIS */
+ #define USE_SYS_SOCKIO_H
+ #define GETTIMEOFDAY(t) gettimeofday(t,NULL)
+ #define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb"
+ #define FIONREAD_IN_SYS_FILIO_H
+ #define DBM_NO_TRAILING_NULL
+ #define USE_STATVFS
+ #define STATVFS_IN_SYS_STATVFS_H
+ #define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT
+ #ifndef S_ISSOCK
+ #define S_ISSOCK(mode) ((mode&0xF000) == 0xC000)
+ #endif
+ #endif
+
+ #ifdef SCO5
+ #define SUPPORTED
+ #include
+ #include
+ extern int h_errno;
+ #define _PATH_MAILDIR "/usr/spool/mail"
+ #define _PATH_BSHELL "/bin/sh"
+ #define _PATH_DEFPATH "/bin:/usr/bin"
+ #define USE_PATHS_H
+ #define USE_FCNTL_LOCK
+ #define USE_DOT_LOCK
+ #define HAS_FSYNC
+ #define HAS_DBM
+ #define DEF_DB_TYPE "dbm"
+ #define ALIAS_DB_MAP "dbm:/etc/mail/aliases"
+ #define DBM_NO_TRAILING_NULL
+ #define HAS_NIS
+ #define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
+ #define ROOT_PATH "/bin:/etc:/usr/bin:/tcb/bin"
+ #define USE_STATVFS
+ #define STATVFS_IN_SYS_STATVFS_H
+ #define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT
+ #define MISSING_SETENV
+ /* SCO5 misses just S_ISSOCK, the others are there
+ * Use C_ISSOCK definition from cpio.h.
+ */
+ #include
+ #define S_ISSOCK(mode) (((mode) & (S_IFMT)) == (C_ISSOCK))
#endif
/*