mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-28 12:48:01 +00:00
snapshot-20000918
This commit is contained in:
parent
77741d9964
commit
5a94b2d36d
@ -1,7 +1,6 @@
|
||||
This is a very first implementation of Postfix content filtering.
|
||||
A Postfix content filter re-injects filtered mail back into Postfix.
|
||||
If all you want is content _inspection_, see the INSPECT_README
|
||||
file instead.
|
||||
A Postfix content filter receives unfiltered mail from Postfix and
|
||||
re-injects filtered mail back into Postfix.
|
||||
|
||||
It involves an incompatible change to queue file formats. Older
|
||||
Postfix versions will reject mail that needs to be content filtered,
|
||||
|
@ -4055,12 +4055,6 @@ Apologies for any names omitted.
|
||||
lying around after unsuccessful delivery (problem reported
|
||||
by Brian Laughton @ Corp.Axxent.Ca).
|
||||
|
||||
20000619
|
||||
|
||||
Workaround: if append_dot_mydomain=no, turn on parent domain
|
||||
search in the Postfix SMTP client, so that mail does not
|
||||
bounce. Files: smtp/smtp.c, smtp/smtp_unalias.c.
|
||||
|
||||
20000621
|
||||
|
||||
AIX 4.x had POSIX regular expression support all the time
|
||||
@ -4127,7 +4121,7 @@ Apologies for any names omitted.
|
||||
not exist, defer mail instead of bouncing it (which would
|
||||
lose the mail if the bounce would have to be delivered to
|
||||
that same non-existent relayhost). Problem reported by
|
||||
Chris Cooper @ maths.ox.ac.uk.
|
||||
Chris Cooper @ maths.ox.ac.uk. File: smtp/smtp_connect.c.
|
||||
|
||||
20000821
|
||||
|
||||
@ -4136,6 +4130,7 @@ Apologies for any names omitted.
|
||||
Cleanup: smtpd now replies with 555 when the client sends
|
||||
unrecognized RCPT TO parameters, as required by RFC 1869
|
||||
(problem report by Robert Norris @ its.monash.edu.au).
|
||||
File: smtpd/smtpd.c.
|
||||
|
||||
20000822
|
||||
|
||||
@ -4156,3 +4151,58 @@ Apologies for any names omitted.
|
||||
access controls, for example, hold off mail from an unknown
|
||||
client or sender until we have completed some investigation,
|
||||
after which we will either reject or accept.
|
||||
|
||||
20000905
|
||||
|
||||
Robustness: the dns client now rejects malformed domain
|
||||
names rather than depending on the DNS to report that the
|
||||
name does not exist. Linux returns a rather misleading
|
||||
server failure code as found out by Patrik Rak. File:
|
||||
dns/dns_lookup.c.
|
||||
|
||||
20000911
|
||||
|
||||
Feature: added IGNORE keyword to header_checks and body_checks
|
||||
to pretend that certain data does not exist. File:
|
||||
cleanup/cleanup_message.c.
|
||||
|
||||
20000911
|
||||
|
||||
Bugfix: the SASL code did not allow MAIL FROM... AUTH=sender
|
||||
without prior authentication. The RFC allows this, although
|
||||
one wonders what the reasoning behind this is. File:
|
||||
smtpd/smtpd_sasl_proto.c.
|
||||
|
||||
20000913
|
||||
|
||||
Bugfix: the rmail script did not handle remote UUCP systems
|
||||
that send a from_ line with unqualified envelope sender.
|
||||
Reported by Luciano Mannucci.
|
||||
|
||||
Compatibility: don't insert Sender: header lines. Sendmail
|
||||
has not done so for at least 10 years, if it ever did.
|
||||
Problem reported by Brad Knowles. File: cleanup/cleanup_message.c.
|
||||
|
||||
20000916
|
||||
|
||||
Bugfix: when propagating an address extension in a virtual
|
||||
or canonical mapping, cleanup accesses memory that is no
|
||||
longer allocated. This can happen when the result address
|
||||
length is more than 100 characters. Problem reported by
|
||||
Adi Prasaja @ satunet.com. File: global/mail_addr_crunch.c.
|
||||
|
||||
Bugfix: fixed a misleading error message when the cleanup
|
||||
server reaches the queue file size limit. Fix by Robby
|
||||
Griffin @ MIT.EDU. File: cleanup/cleanup_extracted.c.
|
||||
|
||||
20000917
|
||||
|
||||
Bugfix: postalias -i would complain about duplicate entries
|
||||
for the Sendmail-compatible @ entry and for the NIS-compatible
|
||||
YP_LAST_MODIFIED and YP_MASTER_NAME entries.
|
||||
|
||||
20000918
|
||||
|
||||
Gross hack: prevent looping a bad recipient by always
|
||||
forwarding recipients in :include: files, even when
|
||||
owner-listname is not set. File: local/recipient.c.
|
||||
|
@ -1,181 +0,0 @@
|
||||
This is a very first implementation of Postfix content inspection.
|
||||
A Postfix content inspector causes "bad" mail to be bounced. All
|
||||
other mail is delivered normally. If you want content _inspection_,
|
||||
which allows you to modify mail content or destination, see the
|
||||
FILTER_README file instead.
|
||||
|
||||
Content inspection involves an incompatible change to queue file
|
||||
formats. Older Postfix versions will reject mail that needs to be
|
||||
content inspected, and will move the queue file to the "corrupt"
|
||||
mail queue subdirectory.
|
||||
|
||||
This document describes two approaches to content inspection.
|
||||
|
||||
Simple content inspection example
|
||||
=================================
|
||||
|
||||
The example is relatively simple to set up, but is resource intensive
|
||||
because it runs a shell script for each message.
|
||||
|
||||
With the shell script as shown you can lose a factor in Postfix
|
||||
performance for each temporary file that is created and deleted in
|
||||
the process of content inspection. The performance impact is less
|
||||
for mail that is submitted or delivered locally, because such
|
||||
deliveries are not as fast as SMTP transit mail.
|
||||
|
||||
The example assumes that only mail received via SMTP needs to be
|
||||
content inspected.
|
||||
|
||||
..................................
|
||||
. Postfix .
|
||||
------smtpd \ /local-----
|
||||
. -cleanup->queue- .
|
||||
-----pickup / \smtp------
|
||||
. | .
|
||||
. \pipe------>inspector
|
||||
..................................
|
||||
|
||||
Create a dedicated local user account called "inspect". The user
|
||||
will never log in, and can be given a "*" password and non-existent
|
||||
shell and home.
|
||||
|
||||
Create a directory /var/spool/inspect that is accessible only to
|
||||
the "inspect" user. This is where the content inspection software
|
||||
will store any temporary files.
|
||||
|
||||
Define a content inspection entry in the Postfix master file:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
inspect unix - n n - - pipe
|
||||
user=inspect argv=/some/where/inspect ${sender} ${recipient}
|
||||
|
||||
The filter program can start out as a simple shell script like this:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
# Localize this
|
||||
INSPECT_DIR=/var/spool/inspect
|
||||
|
||||
# Exit codes from <sysexits.h>
|
||||
EX_TEMPFAIL=75
|
||||
EX_UNAVAILABLE=69
|
||||
|
||||
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
|
||||
|
||||
# Clean up when done or when aborting.
|
||||
trap "rm -f in.$$; exit" 0 1 2 3 15
|
||||
|
||||
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
|
||||
|
||||
# inspect <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
|
||||
|
||||
exit 0
|
||||
|
||||
The idea is to first capture the message to file and then run the
|
||||
content through run a third-party content inspection program. If
|
||||
the mail cannot be captured to file, mail delivery is deferred by
|
||||
terminating with exit status 75 (EX_TEMPFAIL). If the content
|
||||
inspection program finds a problem, the mail is bounced by terminating
|
||||
the shell script with exit status 69 (EX_UNAVAILABLE). An exit
|
||||
status of zero means everything is hunky-dory and the mail can
|
||||
be delivered to its recipients.
|
||||
|
||||
If mail is rejected, another possible action is to mail a copy to
|
||||
the local postmaster. If you do that, be sure not to enable content
|
||||
inspection for locally-posted mail or else rejected mail will loop.
|
||||
|
||||
The problem with content inspection sotware like this is that it is
|
||||
not very robust, because the software does not talk a well-defined
|
||||
protocol with Postfix. If the shell scripts aborts because the
|
||||
shell runs into some memory allocation problem, the script will
|
||||
not produce a nice exit status as per /usr/include/sysexits.h and
|
||||
mail will probably bounce. The same lack of robustness is possible
|
||||
when the content inspection software itself runs into a resource
|
||||
problem.
|
||||
|
||||
I suggest that you play with this script for a while until you are
|
||||
satisfied with the results. Run it as root or as the filter user,
|
||||
with a real message (headers+body) as input:
|
||||
|
||||
# /some/where/inspect sender recipient... <message-file
|
||||
|
||||
Turn on content inspection for mail arriving via SMTP only, by
|
||||
appending "-o content_inspector=inspect:dummy" to the master.cf
|
||||
entry that defines the Postfix SMTP server:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
smtp inet ...stuff... smtpd
|
||||
-o content_inspector=inspect:dummy
|
||||
|
||||
The content_inspector configuration parameter accepts the same
|
||||
syntax as the right-hand side in a Postfix transport table.
|
||||
|
||||
Advanced content inspection example
|
||||
===================================
|
||||
|
||||
The second example is more complex, but can give better performance,
|
||||
and is less likely to bounce mail when the machine runs into a
|
||||
resource problem. This approach uses content inspection software
|
||||
that can receive mail via SMTP, and that can run as a resident
|
||||
server. You can expect to lose about a factor in Postfix performance
|
||||
for every temporary file created.
|
||||
|
||||
We will set up a content inspection program listening on localhost
|
||||
port 10025 that receives mail via the SMTP protocol.
|
||||
|
||||
..................................
|
||||
. Postfix .
|
||||
------smtpd \ /local-----
|
||||
. -cleanup->queue- .
|
||||
-----pickup / | \smtp------
|
||||
. v .
|
||||
. smtp .
|
||||
. | .
|
||||
......................|...........
|
||||
|
|
||||
v
|
||||
.................
|
||||
. 10025 .
|
||||
. inspection .
|
||||
. .
|
||||
.................
|
||||
|
||||
To enable content inspection in this manner, specify in main.cf a
|
||||
new parameter:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
content_filter = smtp:localhost:10025
|
||||
|
||||
This causes Postfix to add one extra content inspection record to
|
||||
each incoming mail message, with content smtp:localhost:10025.
|
||||
You can use the same syntax as in the right-hand side of a Postfix
|
||||
transport table. The content inspection records are added by the
|
||||
smtpd and pickup servers.
|
||||
|
||||
When a queue file has content inspection information, the queue
|
||||
manager will deliver the mail to the specified content inspector
|
||||
before attempting final delivery.
|
||||
|
||||
The content filter can be set up with the Postfix spawn service,
|
||||
which is the Postfix equivalent of inetd. For example, to instantiate
|
||||
up to 10 content inspection processes on demand:
|
||||
|
||||
/etc/postfix/master.cf:
|
||||
localhost:10025 inet n n n - 10 spawn
|
||||
user=inspect argv=/some/where/inspect
|
||||
|
||||
"inspect" is a dedicated local user account. The user will never
|
||||
log in, and can be given a "*" password and non-existent shell and
|
||||
home.
|
||||
|
||||
The spawn server is part of Postfix but is not installed by default.
|
||||
Edit the top-level Makefile.in file, run "make makefiles", "make",
|
||||
and "make install". The manual page isn't installed by default,
|
||||
either. See the spawn.c source file.
|
||||
|
||||
The /some/where/inspect command is most likely a PERL script. PERL
|
||||
has modules that make talking SMTP easy.
|
||||
|
||||
For now, it is left up to the Postfix users to come up with a
|
||||
PERL/SMTP framework for Postfix content inspection. If done well,
|
||||
it can be used with other mailers too, which is a nice spin-off.
|
@ -3,6 +3,11 @@
|
||||
# Dummy UUCP rmail command for postfix/qmail systems
|
||||
|
||||
SENDMAIL="/usr/sbin/sendmail"
|
||||
IFS=" " read junk from junk
|
||||
IFS=" " read junk from junk junk junk junk junk junk junk relay
|
||||
|
||||
case "$from" in
|
||||
*[@!]*) ;;
|
||||
*) from="$from@$relay";;
|
||||
esac
|
||||
|
||||
exec $SENDMAIL -f "$from" -- "$@"
|
||||
|
@ -183,10 +183,13 @@ static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf,
|
||||
*/
|
||||
if (vstream_fflush(state->dst)) {
|
||||
msg_warn("%s: write queue file: %m", state->queue_id);
|
||||
if (errno == EFBIG)
|
||||
if (errno == EFBIG) {
|
||||
msg_warn("%s: queue file size limit exceeded", state->queue_id);
|
||||
state->errs |= CLEANUP_STAT_SIZE;
|
||||
else
|
||||
} else {
|
||||
msg_warn("%s: write queue file: %m", state->queue_id);
|
||||
state->errs |= CLEANUP_STAT_WRITE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -267,6 +267,8 @@ static void cleanup_header(CLEANUP_STATE *state)
|
||||
state->queue_id, header, state->sender,
|
||||
state->recip ? state->recip : "unknown");
|
||||
state->errs |= CLEANUP_STAT_CONT;
|
||||
} else if (strcasecmp(value, "IGNORE") == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,12 +348,8 @@ static void cleanup_missing_headers(CLEANUP_STATE *state)
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a missing (Resent-)From: header. If a (Resent-)From: header is
|
||||
* present, see if we need a (Resent-)Sender: header.
|
||||
* Add a missing (Resent-)From: header.
|
||||
*/
|
||||
#define NOT_SPECIAL_SENDER(addr) (*(addr) != 0 \
|
||||
&& strcasecmp(addr, mail_addr_double_bounce()) != 0)
|
||||
|
||||
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||
HDR_RESENT_FROM : HDR_FROM))) == 0) {
|
||||
quote_822_local(state->temp1, *state->sender ?
|
||||
@ -366,15 +364,6 @@ static void cleanup_missing_headers(CLEANUP_STATE *state)
|
||||
tok822_free_tree(token);
|
||||
}
|
||||
CLEANUP_OUT_BUF(state, REC_TYPE_NORM, state->temp2);
|
||||
} else if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||
HDR_RESENT_SENDER : HDR_SENDER))) == 0
|
||||
&& NOT_SPECIAL_SENDER(state->sender)) {
|
||||
from = (state->resent[0] ? state->resent_from : state->from);
|
||||
if (from == 0 || strcasecmp(state->sender, from) != 0) {
|
||||
quote_822_local(state->temp1, state->sender);
|
||||
cleanup_out_format(state, REC_TYPE_NORM, "%sSender: %s",
|
||||
state->resent, vstring_str(state->temp1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -508,6 +497,8 @@ static void cleanup_message_body(CLEANUP_STATE *state, int type, char *buf, int
|
||||
state->queue_id, buf, state->sender,
|
||||
state->recip ? state->recip : "unknown");
|
||||
state->errs |= CLEANUP_STAT_CONT;
|
||||
} else if (strcasecmp(value, "IGNORE") == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,7 @@
|
||||
#include <msg.h>
|
||||
#include <valid_hostname.h>
|
||||
#include <stringops.h>
|
||||
#include <valid_hostname.h>
|
||||
|
||||
/* DNS library. */
|
||||
|
||||
@ -430,6 +431,16 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
int count;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* The Linux resolver misbehaves when given an invalid domain name.
|
||||
*/
|
||||
if (!valid_hostname(name)) {
|
||||
if (why)
|
||||
vstring_sprintf(why, "Name service error for %s: invalid name",
|
||||
name);
|
||||
return (DNS_NOTFOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the lookup. Follow CNAME chains, but only up to a
|
||||
* pre-determined maximum.
|
||||
|
@ -8,11 +8,9 @@ POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
|
||||
cd ${POSTFIX_DIR}
|
||||
|
||||
mkdir etc
|
||||
cp /etc/localtime /etc/services /etc/resolv.conf etc
|
||||
cp /etc/localtime /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
|
||||
mkdir -p usr/lib/zoneinfo
|
||||
ln -s /etc/localtime usr/lib/zoneinfo
|
||||
|
||||
if [ -e /lib/libnss_dns.so.1 ]; then
|
||||
mkdir lib
|
||||
cp /lib/libnss_dns.so.1 lib
|
||||
fi
|
||||
mkdir lib
|
||||
cp /lib/libnss_* lib
|
||||
|
@ -84,10 +84,10 @@ ARGV *mail_addr_crunch(const char *string, const char *extension)
|
||||
tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL);
|
||||
canon_addr_external(canon_addr, STR(extern_addr));
|
||||
if (extension) {
|
||||
VSTRING_SPACE(canon_addr, extlen + 1);
|
||||
if ((ratsign = strrchr(STR(canon_addr), '@')) == 0) {
|
||||
vstring_strcat(canon_addr, extension);
|
||||
} else {
|
||||
VSTRING_SPACE(canon_addr, extlen + 1);
|
||||
memmove(ratsign + extlen, ratsign, strlen(ratsign) + 1);
|
||||
memcpy(ratsign, extension, extlen);
|
||||
VSTRING_SKIP(canon_addr);
|
||||
|
@ -42,8 +42,9 @@
|
||||
/* data to stable storage, and truncate the destination
|
||||
/* file to its original length in case of problems.
|
||||
/* .IP MAIL_COPY_FROM
|
||||
/* Prepend a UNIX-style From_ line to the message, and append
|
||||
/* an empty line to the end of the message.
|
||||
/* Prepend a UNIX-style From_ line to the message.
|
||||
/* .IP MAIL_COPY_BLANK
|
||||
/* Append an empty line to the end of the message.
|
||||
/* .IP MAIL_COPY_DELIVERED
|
||||
/* Prepend a Delivered-To: header with the name of the
|
||||
/* \fIdelivered\fR attribute.
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Version of this program.
|
||||
*/
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "Snapshot-20000823"
|
||||
#define DEF_MAIL_VERSION "Snapshot-20000918"
|
||||
extern char *var_mail_version;
|
||||
|
||||
/* LICENSE
|
||||
|
@ -41,9 +41,7 @@ PIPE(8) PIPE(8)
|
||||
|
||||
<b>F</b> Prepend a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope
|
||||
header to the message content. This is
|
||||
expected by, for example, <b>UUCP</b> software. The
|
||||
<b>F</b> flag also causes an empty line to be
|
||||
appended to the message.
|
||||
expected by, for example, <b>UUCP</b> software.
|
||||
|
||||
<b>R</b> Prepend a <b>Return-Path:</b> message header with
|
||||
the envelope sender address.
|
||||
@ -59,6 +57,8 @@ PIPE(8) PIPE(8)
|
||||
|
||||
<b>user</b>=<i>username</i>:<i>groupname</i>
|
||||
The external command is executed with the rights of
|
||||
the specified <i>username</i>. The software refuses to
|
||||
execute commands with root privileges, or with the
|
||||
|
||||
|
||||
|
||||
@ -71,8 +71,6 @@ PIPE(8) PIPE(8)
|
||||
PIPE(8) PIPE(8)
|
||||
|
||||
|
||||
the specified <i>username</i>. The software refuses to
|
||||
execute commands with root privileges, or with the
|
||||
privileges of the mail system owner. If <i>groupname</i>
|
||||
is specified, the corresponding group ID is used
|
||||
instead of the group ID of <i>username</i>.
|
||||
@ -125,6 +123,8 @@ PIPE(8) PIPE(8)
|
||||
tains <b>${recipient</b>} expands into as many com-
|
||||
mand-line arguments as there are recipients.
|
||||
|
||||
<b>${sender</b>}
|
||||
This macro expands to the envelope sender
|
||||
|
||||
|
||||
|
||||
@ -137,8 +137,6 @@ PIPE(8) PIPE(8)
|
||||
PIPE(8) PIPE(8)
|
||||
|
||||
|
||||
<b>${sender</b>}
|
||||
This macro expands to the envelope sender
|
||||
address.
|
||||
|
||||
<b>${size</b>}
|
||||
@ -190,7 +188,9 @@ PIPE(8) PIPE(8)
|
||||
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
||||
Limit the number of parallel deliveries to the same
|
||||
destination, for delivery via the named <i>transport</i>.
|
||||
The default limit is taken from the
|
||||
The default limit is taken from the <b>default</b><i>_</i><b>desti-</b>
|
||||
<b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter. The limit is
|
||||
enforced by the Postfix queue manager.
|
||||
|
||||
|
||||
|
||||
@ -203,21 +203,18 @@ PIPE(8) PIPE(8)
|
||||
PIPE(8) PIPE(8)
|
||||
|
||||
|
||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
|
||||
The limit is enforced by the Postfix queue manager.
|
||||
|
||||
<i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
||||
Limit the number of recipients per message deliv-
|
||||
ery, for delivery via the named <i>transport</i>. The
|
||||
default limit is taken from the <b>default</b><i>_</i><b>destina-</b>
|
||||
<b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter. The limit is
|
||||
Limit the number of recipients per message deliv-
|
||||
ery, for delivery via the named <i>transport</i>. The
|
||||
default limit is taken from the <b>default</b><i>_</i><b>destina-</b>
|
||||
<b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter. The limit is
|
||||
enforced by the Postfix queue manager.
|
||||
|
||||
<i>transport_</i><b>time</b><i>_</i><b>limit</b>
|
||||
Limit the time for delivery to external command,
|
||||
for delivery via the named <b>transport</b>. The default
|
||||
limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
|
||||
ter. The limit is enforced by the Postfix queue
|
||||
Limit the time for delivery to external command,
|
||||
for delivery via the named <b>transport</b>. The default
|
||||
limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
|
||||
ter. The limit is enforced by the Postfix queue
|
||||
manager.
|
||||
|
||||
<b>SEE</b> <b>ALSO</b>
|
||||
@ -227,7 +224,7 @@ PIPE(8) PIPE(8)
|
||||
syslogd(8) system logging
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
@ -256,6 +253,9 @@ PIPE(8) PIPE(8)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -75,9 +75,6 @@ SMTP(8) SMTP(8)
|
||||
command after a configuration change.
|
||||
|
||||
<b>Miscellaneous</b>
|
||||
<b>append</b><i>_</i><b>dot</b><i>_</i><b>mydomain</b>
|
||||
Rewrite <i>user</i>@<i>host</i> to <i>user</i>@<i>host</i>.$<b>mydomain</b>.
|
||||
|
||||
<b>best</b><i>_</i><b>mx</b><i>_</i><b>transport</b>
|
||||
Name of the delivery transport to use when the
|
||||
local machine is the most-preferred mail exchanger
|
||||
@ -126,6 +123,9 @@ SMTP(8) SMTP(8)
|
||||
<b>smtp</b><i>_</i><b>always</b><i>_</i><b>send</b><i>_</i><b>ehlo</b>
|
||||
Always send EHLO at the start of a connection.
|
||||
|
||||
<b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
|
||||
Skip servers that greet us with a 4xx status code.
|
||||
|
||||
|
||||
|
||||
2
|
||||
@ -137,9 +137,6 @@ SMTP(8) SMTP(8)
|
||||
SMTP(8) SMTP(8)
|
||||
|
||||
|
||||
<b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
|
||||
Skip servers that greet us with a 4xx status code.
|
||||
|
||||
<b>smtp</b><i>_</i><b>skip</b><i>_</i><b>5xx</b><i>_</i><b>greeting</b>
|
||||
Skip servers that greet us with a 5xx status code.
|
||||
|
||||
@ -191,6 +188,9 @@ SMTP(8) SMTP(8)
|
||||
ery. The default limit is taken from the
|
||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
|
||||
|
||||
<b>Timeout</b> <b>controls</b>
|
||||
<b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
|
||||
Timeout in seconds for completing a TCP connection.
|
||||
|
||||
|
||||
|
||||
@ -203,9 +203,6 @@ SMTP(8) SMTP(8)
|
||||
SMTP(8) SMTP(8)
|
||||
|
||||
|
||||
<b>Timeout</b> <b>controls</b>
|
||||
<b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
|
||||
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.
|
||||
@ -257,6 +254,9 @@ SMTP(8) SMTP(8)
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
|
||||
|
||||
|
||||
@ -269,9 +269,6 @@ SMTP(8) SMTP(8)
|
||||
SMTP(8) SMTP(8)
|
||||
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
@ -322,6 +319,9 @@ SMTP(8) SMTP(8)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -84,47 +84,47 @@ TRANSPORT(5) TRANSPORT(5)
|
||||
names.
|
||||
|
||||
<b>EXAMPLES</b>
|
||||
In order to send mail for <b>foo.org</b> and its subdomains
|
||||
via the <b>uucp</b> transport to the UUCP host named <b>foo</b>:
|
||||
In order to send mail for <b>foo.org</b> and its subdomains via
|
||||
the <b>uucp</b> transport to the UUCP host named <b>foo</b>:
|
||||
|
||||
<b>foo.org</b> <b>uucp:foo</b>
|
||||
<b>.foo.org</b> <b>uucp:foo</b>
|
||||
|
||||
When no <i>nexthop</i> host name is specified, the destination domain
|
||||
name is used instead. For example, the following directs mail for
|
||||
<i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a mail
|
||||
exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
|
||||
something that runs at most one delivery process at a time:
|
||||
When no <i>nexthop</i> host name is specified, the destination
|
||||
domain name is used instead. For example, the following
|
||||
directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
|
||||
mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
|
||||
something that runs at most one delivery process at a
|
||||
time:
|
||||
|
||||
<b>foo.org</b> <b>slow:</b>
|
||||
|
||||
When no <i>transport</i> is specified, the default transport is
|
||||
When no <i>transport</i> is specified, the default transport is
|
||||
used, as specified via the <b>default</b><i>_</i><b>transport</b> configuration
|
||||
parameter. The following sends all mail for <b>foo.org</b> and its
|
||||
subdomains to host <b>gateway.foo.org</b>:
|
||||
parameter. The following sends all mail for <b>foo.org</b> and
|
||||
its subdomains to host <b>gateway.foo.org</b>:
|
||||
|
||||
<b>foo.org</b> <b>:[gateway.foo.org]</b>
|
||||
<b>.foo.org</b> <b>:[gateway.foo.org]</b>
|
||||
|
||||
In the above example, the [] are used to suppress MX lookups.
|
||||
The result would likely point to your local machine.
|
||||
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
|
||||
<i>hostname</i>:<i>service</i> instead of just a host:
|
||||
In the case of delivery via SMTP, one may specify <i>host-</i>
|
||||
<i>name</i>:<i>service</i> instead of just a host:
|
||||
|
||||
<b>foo.org</b> <b>smtp:bar.org:2025</b>
|
||||
|
||||
This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b>
|
||||
port <b>2025</b>. Instead of a numerical port a symbolic name may be
|
||||
used. Specify [] around the destination in order to disable MX lookups.
|
||||
This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
|
||||
<b>2025</b>. Instead of a numerical port a symbolic name may be
|
||||
used. Specify [] around the destination in order to dis-
|
||||
able MX lookups.
|
||||
|
||||
The error mailer can be used to bounce mail:
|
||||
|
||||
<b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliverable</b>
|
||||
|
||||
This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b>
|
||||
to be bounced.
|
||||
|
||||
<b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
|
||||
<b>erable</b>
|
||||
|
||||
|
||||
|
||||
@ -137,28 +137,31 @@ TRANSPORT(5) TRANSPORT(5)
|
||||
TRANSPORT(5) TRANSPORT(5)
|
||||
|
||||
|
||||
This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
|
||||
bounced.
|
||||
|
||||
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
|
||||
This section describes how the table lookups change when
|
||||
This section describes how the table lookups change when
|
||||
the table is given in the form of regular expressions. For
|
||||
a description of regular expression lookup table syntax,
|
||||
a description of regular expression lookup table syntax,
|
||||
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
|
||||
|
||||
Each pattern is a regular expression that is applied to
|
||||
Each pattern is a regular expression that is applied to
|
||||
the entire domain being looked up. Thus, <i>some.domain.hier-</i>
|
||||
<i>archy</i> is not broken up into parent domains.
|
||||
|
||||
Patterns are applied in the order as specified in the
|
||||
table, until a pattern is found that matches the search
|
||||
Patterns are applied in the order as specified in the
|
||||
table, until a pattern is found that matches the search
|
||||
string.
|
||||
|
||||
Results are the same as with normal indexed file lookups,
|
||||
with the additional feature that parenthesized substrings
|
||||
from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
|
||||
Results are the same as with normal indexed file lookups,
|
||||
with the additional feature that parenthesized substrings
|
||||
from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
|
||||
|
||||
<b>CONFIGURATION</b> <b>PARAMETERS</b>
|
||||
The following <b>main.cf</b> parameters are especially relevant
|
||||
to this topic. See the Postfix <b>main.cf</b> file for syntax
|
||||
details and for default values. Use the <b>postfix</b> <b>reload</b>
|
||||
The following <b>main.cf</b> parameters are especially relevant
|
||||
to this topic. See the Postfix <b>main.cf</b> file for syntax
|
||||
details and for default values. Use the <b>postfix</b> <b>reload</b>
|
||||
command after a configuration change.
|
||||
|
||||
<b>transport</b><i>_</i><b>maps</b>
|
||||
@ -167,7 +170,7 @@ TRANSPORT(5) TRANSPORT(5)
|
||||
Other parameters of interest:
|
||||
|
||||
<b>default</b><i>_</i><b>transport</b>
|
||||
The transport to use when no transport is explic-
|
||||
The transport to use when no transport is explic-
|
||||
itly specified.
|
||||
|
||||
<b>relayhost</b>
|
||||
@ -181,20 +184,83 @@ TRANSPORT(5) TRANSPORT(5)
|
||||
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TRANSPORT(5) TRANSPORT(5)
|
||||
|
||||
|
||||
Yorktown Heights, NY 10598, USA
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
4
|
||||
|
||||
|
||||
</pre> </body> </html>
|
||||
|
@ -43,6 +43,7 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
lowing:
|
||||
|
||||
<i>virtual.domain</i> <i>anything</i> (right-hand content does not matter)
|
||||
<i>postmaster@virtual.domain</i> <i>postmaster</i>
|
||||
<i>user1@virtual.domain</i> <i>address1</i>
|
||||
<i>user2@virtual.domain</i> <i>address2,</i> <i>address3</i>
|
||||
|
||||
@ -57,8 +58,7 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
Blank lines are ignored, as are lines beginning
|
||||
with `#'.
|
||||
|
||||
<i>pattern</i> <i>result</i>
|
||||
When <i>pattern</i> matches a mail address, replace it by
|
||||
|
||||
|
||||
|
||||
|
||||
@ -71,6 +71,8 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
VIRTUAL(5) VIRTUAL(5)
|
||||
|
||||
|
||||
<i>pattern</i> <i>result</i>
|
||||
When <i>pattern</i> matches a mail address, replace it by
|
||||
the corresponding <i>result</i>.
|
||||
|
||||
With lookups from indexed files such as DB or DBM, or from
|
||||
@ -124,8 +126,6 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
table, until a pattern is found that matches the search
|
||||
string.
|
||||
|
||||
Results are the same as with normal indexed file lookups,
|
||||
|
||||
|
||||
|
||||
2
|
||||
@ -137,6 +137,7 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
VIRTUAL(5) VIRTUAL(5)
|
||||
|
||||
|
||||
Results are the same as with normal indexed file lookups,
|
||||
with the additional feature that parenthesized substrings
|
||||
from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
|
||||
|
||||
@ -193,7 +194,6 @@ VIRTUAL(5) VIRTUAL(5)
|
||||
|
||||
|
||||
|
||||
|
||||
3
|
||||
|
||||
|
||||
|
@ -158,6 +158,12 @@ static int deliver_switch(LOCAL_STATE state, USER_ATTR usr_attr)
|
||||
&& strcasecmp(state.msg_attr.owner, state.msg_attr.user) != 0)
|
||||
return (deliver_indirect(state));
|
||||
|
||||
/*
|
||||
* Always forward recipients in :include: files.
|
||||
*/
|
||||
if (state.msg_attr.exp_type = EXPAND_TYPE_INCL)
|
||||
return (deliver_indirect(state));
|
||||
|
||||
/*
|
||||
* Delivery to local user. First try expansion of the recipient's
|
||||
* $HOME/.forward file, then mailbox delivery.
|
||||
|
@ -70,6 +70,7 @@ can also be used with IP addresses instead of hostnames.
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
In order to send mail for \fBfoo.org\fR and its subdomains
|
||||
via the \fBuucp\fR transport to the UUCP host named \fBfoo\fR:
|
||||
|
||||
|
@ -43,6 +43,7 @@ Typical support for a virtual domain looks like the following:
|
||||
.in +4
|
||||
.nf
|
||||
\fIvirtual.domain anything\fR (right-hand content does not matter)
|
||||
\fIpostmaster@virtual.domain postmaster\fR
|
||||
\fIuser1@virtual.domain address1\fR
|
||||
\fIuser2@virtual.domain address2, address3\fR
|
||||
.fi
|
||||
|
@ -41,8 +41,7 @@ when preceded by a blank line.
|
||||
.IP \fBF\fR
|
||||
Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to
|
||||
the message content.
|
||||
This is expected by, for example, \fBUUCP\fR software. The \fBF\fR
|
||||
flag also causes an empty line to be appended to the message.
|
||||
This is expected by, for example, \fBUUCP\fR software.
|
||||
.IP \fBR\fR
|
||||
Prepend a \fBReturn-Path:\fR message header with the envelope sender
|
||||
address.
|
||||
|
@ -72,8 +72,6 @@ a configuration change.
|
||||
.SH Miscellaneous
|
||||
.ad
|
||||
.fi
|
||||
.IP \fBappend_dot_mydomain\fR
|
||||
Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
|
||||
.IP \fBbest_mx_transport\fR
|
||||
Name of the delivery transport to use when the local machine
|
||||
is the most-preferred mail exchanger (by default, a mailer
|
||||
|
@ -33,8 +33,7 @@
|
||||
/* .IP \fBF\fR
|
||||
/* Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to
|
||||
/* the message content.
|
||||
/* This is expected by, for example, \fBUUCP\fR software. The \fBF\fR
|
||||
/* flag also causes an empty line to be appended to the message.
|
||||
/* This is expected by, for example, \fBUUCP\fR software.
|
||||
/* .IP \fBR\fR
|
||||
/* Prepend a \fBReturn-Path:\fR message header with the envelope sender
|
||||
/* address.
|
||||
|
@ -263,6 +263,12 @@ static void postalias(char *map_type, char *path_name,
|
||||
mkmap_append(mkmap, STR(key_buffer), STR(value_buffer));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update or append sendmail and NIS signatures.
|
||||
*/
|
||||
if ((open_flags & O_TRUNC) == 0)
|
||||
mkmap->dict->flags |= DICT_FLAG_DUP_REPLACE;
|
||||
|
||||
/*
|
||||
* Sendmail compatibility: add the @:@ signature to indicate that the
|
||||
* database is complete. This might be needed by NIS clients running
|
||||
@ -328,7 +334,7 @@ static int postalias_delete(const char *map_type, const char *map_name,
|
||||
dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK);
|
||||
status = dict_del(dict, key);
|
||||
dict_close(dict);
|
||||
return (status);
|
||||
return (status == 0);
|
||||
}
|
||||
|
||||
/* usage - explain */
|
||||
|
@ -60,6 +60,7 @@
|
||||
# can also be used with IP addresses instead of hostnames.
|
||||
# EXAMPLES
|
||||
# .ad
|
||||
# .fi
|
||||
# In order to send mail for \fBfoo.org\fR and its subdomains
|
||||
# via the \fBuucp\fR transport to the UUCP host named \fBfoo\fR:
|
||||
#
|
||||
|
@ -35,6 +35,7 @@
|
||||
# .in +4
|
||||
# .nf
|
||||
# \fIvirtual.domain anything\fR (right-hand content does not matter)
|
||||
# \fIpostmaster@virtual.domain postmaster\fR
|
||||
# \fIuser1@virtual.domain address1\fR
|
||||
# \fIuser2@virtual.domain address2, address3\fR
|
||||
# .fi
|
||||
|
@ -56,8 +56,6 @@
|
||||
/* .SH Miscellaneous
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* .IP \fBappend_dot_mydomain\fR
|
||||
/* Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
|
||||
/* .IP \fBbest_mx_transport\fR
|
||||
/* Name of the delivery transport to use when the local machine
|
||||
/* is the most-preferred mail exchanger (by default, a mailer
|
||||
@ -241,7 +239,6 @@ char *var_smtp_sasl_opts;
|
||||
char *var_smtp_sasl_passwd;
|
||||
bool var_smtp_sasl_enable;
|
||||
char *var_smtp_bind_addr;
|
||||
bool var_append_dot_mydomain;
|
||||
|
||||
/*
|
||||
* Global variables. smtp_errno is set by the address lookup routines and by
|
||||
@ -411,7 +408,6 @@ int main(int argc, char **argv)
|
||||
VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
|
||||
VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
|
||||
VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
|
||||
VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
|
||||
0,
|
||||
};
|
||||
|
||||
|
@ -50,10 +50,6 @@
|
||||
#include <vstring.h>
|
||||
#include <msg.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_params.h>
|
||||
|
||||
/* DNS library. */
|
||||
|
||||
#include <dns.h>
|
||||
@ -77,11 +73,8 @@ const char *smtp_unalias_name(const char *name)
|
||||
* after servicing a limited number of requests, so there is no need to
|
||||
* prevent the cache from growing too large, or to expire old entries.
|
||||
*/
|
||||
if (cache == 0) {
|
||||
if (cache == 0)
|
||||
cache = htable_create(10);
|
||||
if (var_append_dot_mydomain == 0)
|
||||
smtp_unalias_flags |= RES_DNSRCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the fqdn. If none is found use the query name instead, so that
|
||||
|
@ -176,10 +176,12 @@ char *smtpd_sasl_mail_opt(SMTPD_STATE *state, const char *addr)
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
return ("503 Error: authentication disabled");
|
||||
}
|
||||
#if 0
|
||||
if (state->sasl_username == 0) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
return ("503 Error: send AUTH command first");
|
||||
}
|
||||
#endif
|
||||
if (state->sasl_sender != 0) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
return ("503 Error: multiple AUTH= options");
|
||||
|
@ -13,21 +13,21 @@
|
||||
/* DESCRIPTION
|
||||
/* dict_tcp_open() makes a TCP server accessible via the generic
|
||||
/* dictionary operations described in dict_open(3).
|
||||
/* The \fIdummy\fR argument is not used. Server access is read-only
|
||||
/* (i.e., only lookups are implemented).
|
||||
/* The \fIdummy\fR argument is not used. The only implemented
|
||||
/* operation is dictionary lookup.
|
||||
/*
|
||||
/* Map names have the form host:port.
|
||||
/*
|
||||
/* The map implements a very simple protocol: the query is sent as
|
||||
/* one line of text, and the reply is sent back in the same format.
|
||||
/* Data is sent as a newline-terminated string. % and non-printable
|
||||
/* characters are replaced by %xx, xx being the corresponding
|
||||
/* hexadecimal value.
|
||||
/* The TCP map class implements a very simple protocol: a query is sent
|
||||
/* as one line of text, and a reply is sent back in the same format.
|
||||
/* % and non-printable characters are replaced by %xx, xx being the
|
||||
/* corresponding hexadecimal value.
|
||||
/* SEE ALSO
|
||||
/* dict(3) generic dictionary manager
|
||||
/* hex_quote(3) http-style quoting
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal errors: out of memory, unknown host or service name,
|
||||
/* attempt to update map.
|
||||
/* attempt to update or iterate over map.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -63,8 +63,8 @@
|
||||
typedef struct {
|
||||
DICT dict; /* generic members */
|
||||
char *map; /* server host:port */
|
||||
VSTRING *raw_buf; /* raw buffer */
|
||||
VSTRING *hex_buf; /* hexified buffer */
|
||||
VSTRING *raw_buf; /* raw I/O buffer */
|
||||
VSTRING *hex_buf; /* quoted I/O buffer */
|
||||
VSTREAM *fp; /* I/O stream */
|
||||
} DICT_TCP;
|
||||
|
||||
@ -73,12 +73,48 @@ typedef struct {
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
/* dict_tcp_connect - connect to TCP server */
|
||||
|
||||
static int dict_tcp_connect(DICT_TCP *dict_tcp)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Connect to the server. Enforce a time limit on read/write operations
|
||||
* so that we do not get stuck.
|
||||
*/
|
||||
if ((fd = inet_connect(dict_tcp->map, BLOCKING, 0)) < 0) {
|
||||
msg_warn("connect to TCP map %s: %m", dict_tcp->map);
|
||||
return (-1);
|
||||
}
|
||||
dict_tcp->fp = vstream_fdopen(fd, O_RDWR);
|
||||
vstream_control(dict_tcp->fp,
|
||||
VSTREAM_CTL_TIMEOUT, DICT_TCP_TMOUT,
|
||||
VSTREAM_CTL_END);
|
||||
|
||||
/*
|
||||
* Allocate per-map I/O buffers on the fly.
|
||||
*/
|
||||
if (dict_tcp->raw_buf == 0) {
|
||||
dict_tcp->raw_buf = vstring_alloc(10);
|
||||
dict_tcp->hex_buf = vstring_alloc(10);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* dict_tcp_disconnect - disconnect from TCP server */
|
||||
|
||||
static void dict_tcp_disconnect(DICT_TCP *dict_tcp)
|
||||
{
|
||||
(void) vstream_fclose(dict_tcp->fp);
|
||||
dict_tcp->fp = 0;
|
||||
}
|
||||
|
||||
/* dict_tcp_lookup - query TCP server */
|
||||
|
||||
static const char *dict_tcp_lookup(DICT *dict, const char *key)
|
||||
{
|
||||
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
dict_errno = 0;
|
||||
@ -86,7 +122,7 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
|
||||
for (i = 0; /* see below */ ; i++) {
|
||||
|
||||
/*
|
||||
* Try to connect a few times before giving up.
|
||||
* Try to connect a limited number of times before giving up.
|
||||
*/
|
||||
if (i >= DICT_TCP_MAXTRY) {
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
@ -94,36 +130,22 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
|
||||
}
|
||||
|
||||
/*
|
||||
* Sleep between connection attempts.
|
||||
* Sleep between attempts, instead of hammering the server.
|
||||
*/
|
||||
if (i > 0)
|
||||
sleep(1);
|
||||
|
||||
/*
|
||||
* Try to connect to the server.
|
||||
* Connect to the server.
|
||||
*/
|
||||
if (dict_tcp->fp == 0) {
|
||||
if ((fd = inet_connect(dict_tcp->map, BLOCKING, 0)) < 0) {
|
||||
msg_warn("connect to TCP map %s: %m", dict_tcp->map);
|
||||
if (dict_tcp->fp == 0)
|
||||
if (dict_tcp_connect(dict_tcp) < 0)
|
||||
continue;
|
||||
}
|
||||
dict_tcp->fp = vstream_fdopen(fd, O_RDWR);
|
||||
vstream_control(dict_tcp->fp,
|
||||
VSTREAM_CTL_TIMEOUT, DICT_TCP_TMOUT,
|
||||
VSTREAM_CTL_END);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate per-map buffers on the fly.
|
||||
*/
|
||||
if (dict_tcp->raw_buf == 0) {
|
||||
dict_tcp->raw_buf = vstring_alloc(10);
|
||||
dict_tcp->hex_buf = vstring_alloc(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send query and receive response. Both are %XX quoted and both are
|
||||
* terminated by newline.
|
||||
* terminated by newline. This encoding is convenient for data that
|
||||
* is mostly text.
|
||||
*/
|
||||
hex_quote(dict_tcp->hex_buf, key);
|
||||
vstream_fprintf(dict_tcp->fp, "%s\n", STR(dict_tcp->hex_buf));
|
||||
@ -140,8 +162,7 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
|
||||
/*
|
||||
* That did not work. Clean up and try again.
|
||||
*/
|
||||
(void) vstream_fclose(dict_tcp->fp);
|
||||
dict_tcp->fp = 0;
|
||||
dict_tcp_disconnect(dict_tcp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,6 +175,25 @@ static void dict_tcp_update(DICT *dict, const char *unused_name, const char *unu
|
||||
msg_fatal("dict_tcp_update: attempt to update map %s", dict_tcp->map);
|
||||
}
|
||||
|
||||
/* dict_tcp_delete - remove table entry */
|
||||
|
||||
static int dict_tcp_delete(DICT *dict, const char *unused_name)
|
||||
{
|
||||
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||
|
||||
msg_fatal("dict_tcp_delete: attempt to update map %s", dict_tcp->map);
|
||||
}
|
||||
|
||||
/* dict_tcp_sequence - iterate over table */
|
||||
|
||||
static int dict_tcp_sequence(DICT *dict, int unused_func,
|
||||
const char **unused_name, const char **unused_value)
|
||||
{
|
||||
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||
|
||||
msg_fatal("dict_tcp_sequence: attempt to iterate map %s", dict_tcp->map);
|
||||
}
|
||||
|
||||
/* dict_tcp_close - close TCP map */
|
||||
|
||||
static void dict_tcp_close(DICT *dict)
|
||||
@ -183,6 +223,8 @@ DICT *dict_tcp_open(const char *map, int unused_flags, int dict_flags)
|
||||
dict_tcp->raw_buf = dict_tcp->hex_buf = 0;
|
||||
dict_tcp->dict.lookup = dict_tcp_lookup;
|
||||
dict_tcp->dict.update = dict_tcp_update;
|
||||
dict_tcp->dict.delete = dict_tcp_delete;
|
||||
dict_tcp->dict.sequence = dict_tcp_sequence;
|
||||
dict_tcp->dict.close = dict_tcp_close;
|
||||
dict_tcp->dict.fd = -1;
|
||||
dict_tcp->map = mystrdup(map);
|
||||
|
Loading…
x
Reference in New Issue
Block a user