mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 18:07:41 +00:00
snapshot-19990909
This commit is contained in:
parent
981562b004
commit
f90b3d19a4
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -3039,3 +3039,40 @@ Apologies for any names omitted.
|
||||
and for upgrading Postfix. It replaces files instead of
|
||||
overwriting them, and leaves existing configuration and
|
||||
queue files intact.
|
||||
|
||||
19990907
|
||||
|
||||
Bugfix: reject_non_fqdn_sender used the wrong test to see
|
||||
if a sender address was given and could dump core. This
|
||||
must have been broken ever since the UCE tests were moved
|
||||
to the RCPT TO stage in 19990510.
|
||||
|
||||
Bugfix: check_sender_access was recognized as a valid
|
||||
restriction name only if a sender had been specified.
|
||||
|
||||
19990908
|
||||
|
||||
Portability: Unixware has <sysexits.h> only after sendmail
|
||||
is installed. Changed postlock.c to use global/sys_exists.h.
|
||||
|
||||
19990909
|
||||
|
||||
Performance: added one-entry cache to the address rewriting
|
||||
client and to the address resolving client. This is because
|
||||
UCE restrictions tend to produce the same query repeatedly.
|
||||
|
||||
Feature: the UCE restrictions are now fully recursive so
|
||||
you can have per-client/helo/sender/recipient restrictions.
|
||||
Instead of OK, REJECT or [45]xx, you can specify a sequence
|
||||
of restrictions on the right-hand side of an SMTPD access
|
||||
table. This means you can no longer use canonical/virtual/alias
|
||||
maps as SMTPD access tables. But the loss is compensated for.
|
||||
|
||||
Feature: restriction classes, essentially a short-hand for
|
||||
restriction lists. These short hands are useful mostly on
|
||||
the right-hand side of SMTPD access tables.
|
||||
|
||||
Feature: "permit_address_map maptype:mapname" permits a
|
||||
recipient address when it matches the specified table.
|
||||
Lookups are done just as with canonical/virtual maps. With
|
||||
this, you can also use passwd/aliases as SMTPD access maps.
|
||||
|
@ -174,7 +174,7 @@ rm -f junk
|
||||
|
||||
# Install files. Be careful to not copy over running programs.
|
||||
|
||||
for file in `ls libexec`
|
||||
for file in `ls libexec | grep '^[a-z]'`
|
||||
do
|
||||
compare_or_replace a+x,go-w libexec/$file $daemon_directory/$file || exit 1
|
||||
done
|
||||
|
@ -1,3 +1,51 @@
|
||||
Incompatible changes with snapshot 19990909
|
||||
===========================================
|
||||
|
||||
- You can not longer use virtual, canonical or aliases tables as
|
||||
SMTPD access control tables. Use the permit_address_map feature
|
||||
instead. The loss is compensated for.
|
||||
|
||||
Major changes with snapshot 19990909
|
||||
====================================
|
||||
|
||||
- Per-client/helo/sender/recipient UCE restrictions: you can now
|
||||
specify arbitrary restrictions on the right-hand side of SMTPD
|
||||
access tables. The only anomaly in this scheme is that header
|
||||
checks are the same for every message.
|
||||
|
||||
- Restriction classes allow you to conveniently group restrictions
|
||||
under one name. This is great for per-client/helo/sender/recipient
|
||||
UCE restrictions. For example in main.cf:
|
||||
|
||||
smtpd_restriction_classes = restrictive, permissive
|
||||
restrictive = reject_unknown_sender reject_unknown_client ...
|
||||
permissive = permit
|
||||
|
||||
Then use "restrictive" or "restrictive" on the right-hand side of
|
||||
your per-client/helo/sender/recipient SMTPD access tables.
|
||||
|
||||
- Reject mail for non-existent local accounts. You can now use
|
||||
passwd/canonical/virtual/aliases tables for SMTPD access control.
|
||||
For example, specify in main.cf:
|
||||
|
||||
relay_domains = $mydestination other domains...
|
||||
smtpd_recipient_restrictions =
|
||||
reject_unauth_destination
|
||||
permit_address_map unix:passwd.byname
|
||||
permit_address_map hash:/etc/canonical
|
||||
permit_address_map hash:/etc/postfix/virtual
|
||||
permit_address_map hash:/etc/aliases
|
||||
reject
|
||||
|
||||
That should stop a lot of the mail to non-existent recipients. It
|
||||
won't stop mail to broken aliases or to users with broken .forward
|
||||
files, though.
|
||||
|
||||
Unfortunately, permit_address_map does not combine well with
|
||||
check_relay_domains, because that restriction ALWAYS permits mail
|
||||
for local destinations. Instead of check_relay_domains, use some
|
||||
combination of permit_mynetworks and reject_unauth_destination.
|
||||
|
||||
Incompatible changes with postfix-19990906
|
||||
==========================================
|
||||
|
||||
@ -7,7 +55,7 @@ files while delivering to files specified in aliases/forward/include
|
||||
files. This is a no-op when the recipient lacks directory write
|
||||
permission.
|
||||
|
||||
- The LDAP client code no longer looks up name containing "*"
|
||||
- The LDAP client code no longer looks up a name containing "*"
|
||||
because it could be abused. See the LDAP_README file for how to
|
||||
restore previous behavior.
|
||||
|
||||
|
1
postfix/bounce/.indent.pro
vendored
1
postfix/bounce/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/cleanup/.indent.pro
vendored
1
postfix/cleanup/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -203,6 +203,8 @@ smtpd_sender_restrictions =
|
||||
# reject_non_fqdn_hostname: reject HELO hostname that is not in FQDN form
|
||||
# reject_non_fqdn_sender: reject sender address that is not in FQDN form
|
||||
# reject_non_fqdn_recipient: reject recipient address that is not in FQDN form
|
||||
# permit_address_map maptype:mapname: permit if the recipient address matches
|
||||
# the table. Matching is as with virtual/canonical tables.
|
||||
# reject: reject the request. Place this at the end of a restriction.
|
||||
# permit: permit the request. Place this at the end of a restriction.
|
||||
#
|
||||
|
1
postfix/dns/.indent.pro
vendored
1
postfix/dns/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/error/.indent.pro
vendored
1
postfix/error/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/fsstone/.indent.pro
vendored
1
postfix/fsstone/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/global/.indent.pro
vendored
1
postfix/global/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -718,6 +718,10 @@ extern char *var_rcpt_checks;
|
||||
#define DEF_ETRN_CHECKS ""
|
||||
extern char *var_etrn_checks;
|
||||
|
||||
#define VAR_REST_CLASSES "smtpd_restriction_classes"
|
||||
#define DEF_REST_CLASSES ""
|
||||
extern char *var_rest_classes;
|
||||
|
||||
/*
|
||||
* Names of specific restrictions, and the corresponding configuration
|
||||
* parameters that control the status codes sent in response to rejected
|
||||
@ -795,6 +799,8 @@ extern int var_smtpd_delay_reject;
|
||||
|
||||
#define REJECT_UNAUTH_PIPE "reject_unauth_pipelining"
|
||||
|
||||
#define PERMIT_ADDR_MAP "permit_address_map"
|
||||
|
||||
/*
|
||||
* Other.
|
||||
*/
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Version of this program.
|
||||
*/
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "Postfix-19990906"
|
||||
#define DEF_MAIL_VERSION "Snapshot-19990909"
|
||||
extern char *var_mail_version;
|
||||
|
||||
/* LICENSE
|
||||
|
@ -80,6 +80,9 @@
|
||||
*/
|
||||
extern CLNT_STREAM *rewrite_clnt_stream;
|
||||
|
||||
static VSTRING *last_addr;
|
||||
static RESOLVE_REPLY last_reply;
|
||||
|
||||
/* resolve_clnt_init - initialize reply */
|
||||
|
||||
void resolve_clnt_init(RESOLVE_REPLY *reply)
|
||||
@ -96,6 +99,14 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
||||
char *myname = "resolve_clnt_query";
|
||||
VSTREAM *stream;
|
||||
|
||||
/*
|
||||
* One-entry cache.
|
||||
*/
|
||||
if (last_addr == 0) {
|
||||
last_addr = vstring_alloc(100);
|
||||
resolve_clnt_init(&last_reply);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check. The result must not clobber the input because we may
|
||||
* have to retransmit the request.
|
||||
@ -105,6 +116,20 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
||||
if (addr == STR(reply->recipient))
|
||||
msg_panic("%s: result clobbers input", myname);
|
||||
|
||||
/*
|
||||
* Peek at the cache.
|
||||
*/
|
||||
if (strcmp(addr, STR(last_addr)) == 0) {
|
||||
vstring_strcpy(reply->transport, STR(last_reply.transport));
|
||||
vstring_strcpy(reply->nexthop, STR(last_reply.nexthop));
|
||||
vstring_strcpy(reply->recipient, STR(last_reply.recipient));
|
||||
if (msg_verbose)
|
||||
msg_info("%s: cached: `%s' -> t=`%s' h=`%s' r=`%s'",
|
||||
myname, addr, STR(reply->transport),
|
||||
STR(reply->nexthop), STR(reply->recipient));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep trying until we get a complete response. The resolve service is
|
||||
* CPU bound; making the client asynchronous would just complicate the
|
||||
@ -139,6 +164,14 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|
||||
sleep(10); /* XXX make configurable */
|
||||
clnt_stream_recover(rewrite_clnt_stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the cache.
|
||||
*/
|
||||
vstring_strcpy(last_addr, addr);
|
||||
vstring_strcpy(last_reply.transport, STR(reply->transport));
|
||||
vstring_strcpy(last_reply.nexthop, STR(reply->nexthop));
|
||||
vstring_strcpy(last_reply.recipient, STR(reply->recipient));
|
||||
}
|
||||
|
||||
/* resolve_clnt_free - destroy reply */
|
||||
|
@ -71,6 +71,9 @@
|
||||
*/
|
||||
CLNT_STREAM *rewrite_clnt_stream = 0;
|
||||
|
||||
VSTRING *last_addr;
|
||||
VSTRING *last_result;
|
||||
|
||||
/* rewrite_clnt - rewrite address to (transport, next hop, recipient) */
|
||||
|
||||
VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
@ -78,6 +81,14 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
char *myname = "rewrite_clnt";
|
||||
VSTREAM *stream;
|
||||
|
||||
/*
|
||||
* One-entry cache.
|
||||
*/
|
||||
if (last_addr == 0) {
|
||||
last_addr = vstring_alloc(100);
|
||||
last_result = vstring_alloc(100);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check. An address must be in externalized form. The result must
|
||||
* not clobber the input, because we may have to retransmit the query.
|
||||
@ -89,6 +100,17 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
if (addr == STR(result))
|
||||
msg_panic("rewrite_clnt: result clobbers input");
|
||||
|
||||
/*
|
||||
* Peek at the cache.
|
||||
*/
|
||||
if (strcmp(addr, STR(last_addr)) == 0) {
|
||||
vstring_strcpy(result, STR(last_result));
|
||||
if (msg_verbose)
|
||||
msg_info("rewrite_clnt: cached: %s: %s -> %s",
|
||||
rule, addr, vstring_str(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep trying until we get a complete response. The rewrite service is
|
||||
* CPU bound and making the client asynchronous would just complicate the
|
||||
@ -111,16 +133,19 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
if (msg_verbose)
|
||||
msg_info("rewrite_clnt: %s: %s -> %s",
|
||||
rule, addr, vstring_str(result));
|
||||
#if 0
|
||||
if (addr[0] != 0 && STR(result)[0] == 0)
|
||||
msg_warn("%s: null result for: <%s>", myname, addr);
|
||||
else
|
||||
#endif
|
||||
return (result);
|
||||
break;
|
||||
}
|
||||
sleep(10); /* XXX make configurable */
|
||||
clnt_stream_recover(rewrite_clnt_stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the cache.
|
||||
*/
|
||||
vstring_strcpy(last_addr, addr);
|
||||
vstring_strcpy(last_result, STR(result));
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* rewrite_clnt_internal - rewrite from/to internal form */
|
||||
|
@ -203,6 +203,12 @@ SMTPD(8) SMTPD(8)
|
||||
SMTPD(8) SMTPD(8)
|
||||
|
||||
|
||||
<b>restriction</b><i>_</i><b>classes</b>
|
||||
Declares the name of zero or more parameters that
|
||||
contain a list of UCE restrictions. The names of
|
||||
these parameters can then be used instead of the
|
||||
restriction lists that they represent.
|
||||
|
||||
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
|
||||
List of DNS domains that publish the addresses of
|
||||
blacklisted hosts.
|
||||
@ -250,13 +256,7 @@ SMTPD(8) SMTPD(8)
|
||||
<a href="master.8.html">master(8)</a> process manager
|
||||
syslogd(8) system logging
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
|
||||
|
||||
|
||||
@ -269,6 +269,13 @@ SMTPD(8) SMTPD(8)
|
||||
SMTPD(8) SMTPD(8)
|
||||
|
||||
|
||||
<b>LICENSE</b>
|
||||
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
|
||||
|
||||
@ -311,13 +318,6 @@ SMTPD(8) SMTPD(8)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -191,9 +191,10 @@ href="access.5.html">access database</a> for the client name, parent
|
||||
domains, client address, or networks obtained by stripping least
|
||||
significant octets. Reject the request if the result is <b>REJECT</b>
|
||||
or "[<b>45</b>]<i>XX text</i>". Permit the request if the result
|
||||
is anything else. The <b>access_map_reject_code</b> parameter
|
||||
specifies the response code for <b>REJECT</b> results (default:
|
||||
<b>554</b>).
|
||||
is <b>OK</b> or <b>RELAY</b>. Otherwise, treat the result as another
|
||||
list of UCE restrictions. The <b>access_map_reject_code</b>
|
||||
parameter specifies the response code for <b>REJECT</b> results
|
||||
(default: <b>554</b>).
|
||||
|
||||
<p>
|
||||
|
||||
@ -338,7 +339,8 @@ response code to rejected requests (default: <b>504</b>).
|
||||
href="access.5.html">access database</a> for the <b>HELO</b> hostname
|
||||
or parent domains in the specified table. Reject the request if
|
||||
the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
|
||||
the request when the result is anything else. The
|
||||
the request when the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
|
||||
treat the result as another list of UCE restrictions. The
|
||||
<b>access_map_reject_code </b> parameter specifies the response
|
||||
code for <b>REJECT</b> results (default: <b>554</b>).
|
||||
|
||||
@ -429,9 +431,10 @@ is always <b>450</b> in case of a temporary DNS error.
|
||||
href="access.5.html">access database</a> for the sender mail address,
|
||||
parent domain, or <i>localpart</i>@. Reject the request if the
|
||||
result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the
|
||||
request if the result is anything else. The <b>access_map_reject_code
|
||||
</b> parameter specifies the result code for rejected requests
|
||||
(default: <b>554</b>).
|
||||
request if the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
|
||||
treat the result as another list of UCE restrictions. The
|
||||
<b>access_map_reject_code </b> parameter specifies the result code
|
||||
for rejected requests (default: <b>554</b>).
|
||||
|
||||
<p>
|
||||
|
||||
@ -568,9 +571,10 @@ $inet_interfaces</a>.
|
||||
href="access.5.html">access database</a> for the resolved destination
|
||||
address, parent domain, or <i>localpart</i>@. Reject the request
|
||||
if the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".
|
||||
Permit the request if the result is anything else. The
|
||||
<b>access_map_reject_code </b> parameter specifies the result code
|
||||
for rejected requests (default: <b>554</b>).
|
||||
Permit the request if the result is <b>OK</b> or <b>RELAY</b>.
|
||||
Otherwise, treat the result as another list of UCE restrictions.
|
||||
The <b>access_map_reject_code </b> parameter specifies the result
|
||||
code for rejected requests (default: <b>554</b>).
|
||||
|
||||
<p>
|
||||
|
||||
@ -593,6 +597,16 @@ response code to rejected requests (default: <b>504</b>).
|
||||
|
||||
<p>
|
||||
|
||||
<dt> <b>permit_address_map</b> <i>maptype</i>:<i>mapname</i> <dd>
|
||||
Permit the request when the recipient address matches the named
|
||||
table. Table lookup is done as with the <a
|
||||
href="virtual.5.html">virtual</a> and <a
|
||||
href="canonical.5.html">canonical</a> tables. This also produces
|
||||
useful results with the <a href="aliases.5.html">aliases</a> and
|
||||
<b>unix:passwd.byname</b> maps.
|
||||
|
||||
<p>
|
||||
|
||||
<dt> <b><a href="#reject_unknown_sender_domain">reject_unknown_sender_domain</a></b>
|
||||
|
||||
<dt> <b><a href="#reject_non_fqdn_sender">reject_non_fqdn_sender</a></b>
|
||||
@ -691,9 +705,10 @@ address.
|
||||
href="access.5.html">access database</a> for the domain specified
|
||||
in the ETRN command, or its parent domains. Reject the request if
|
||||
the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
|
||||
the request if the result is anything else. The <b>access_map_reject_code
|
||||
</b> parameter specifies the result code for rejected requests
|
||||
(default: <b>554</b>).
|
||||
the request if the result is <b>OK</b> or <b>RELAY</b>. Otherwise,
|
||||
treat the result as another list of UCE restrictions. The
|
||||
<b>access_map_reject_code </b> parameter specifies the result code
|
||||
for rejected requests (default: <b>554</b>).
|
||||
|
||||
<p>
|
||||
|
||||
|
1
postfix/local/.indent.pro
vendored
1
postfix/local/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -147,6 +147,10 @@ Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands.
|
||||
.IP \fBsmtpd_etrn_restrictions\fR
|
||||
Restrict what domain names can be used in \fBETRN\fR commands,
|
||||
and what clients may issue \fBETRN\fR commands.
|
||||
.IP \fBrestriction_classes\fR
|
||||
Declares the name of zero or more parameters that contain a
|
||||
list of UCE restrictions. The names of these parameters can
|
||||
then be used instead of the restriction lists that they represent.
|
||||
.IP \fBmaps_rbl_domains\fR
|
||||
List of DNS domains that publish the addresses of blacklisted
|
||||
hosts.
|
||||
|
1
postfix/master/.indent.pro
vendored
1
postfix/master/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/pickup/.indent.pro
vendored
1
postfix/pickup/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/pipe/.indent.pro
vendored
1
postfix/pipe/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postalias/.indent.pro
vendored
1
postfix/postalias/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postcat/.indent.pro
vendored
1
postfix/postcat/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postconf/.indent.pro
vendored
1
postfix/postconf/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postdrop/.indent.pro
vendored
1
postfix/postdrop/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postfix/.indent.pro
vendored
1
postfix/postfix/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postkick/.indent.pro
vendored
1
postfix/postkick/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postlock/.indent.pro
vendored
1
postfix/postlock/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -86,7 +86,6 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
@ -102,6 +101,7 @@
|
||||
#include <dot_lockfile.h>
|
||||
#include <deliver_flock.h>
|
||||
#include <mail_conf.h>
|
||||
#include <sys_exits.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
|
1
postfix/postlog/.indent.pro
vendored
1
postfix/postlog/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postmap/.indent.pro
vendored
1
postfix/postmap/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/postsuper/.indent.pro
vendored
1
postfix/postsuper/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/qmgr/.indent.pro
vendored
1
postfix/qmgr/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/sendmail/.indent.pro
vendored
1
postfix/sendmail/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/showq/.indent.pro
vendored
1
postfix/showq/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/smtp/.indent.pro
vendored
1
postfix/smtp/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/smtpd/.indent.pro
vendored
1
postfix/smtpd/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
@ -131,6 +131,10 @@
|
||||
/* .IP \fBsmtpd_etrn_restrictions\fR
|
||||
/* Restrict what domain names can be used in \fBETRN\fR commands,
|
||||
/* and what clients may issue \fBETRN\fR commands.
|
||||
/* .IP \fBrestriction_classes\fR
|
||||
/* Declares the name of zero or more parameters that contain a
|
||||
/* list of UCE restrictions. The names of these parameters can
|
||||
/* then be used instead of the restriction lists that they represent.
|
||||
/* .IP \fBmaps_rbl_domains\fR
|
||||
/* List of DNS domains that publish the addresses of blacklisted
|
||||
/* hosts.
|
||||
@ -278,6 +282,7 @@ int var_non_fqdn_code;
|
||||
char *var_always_bcc;
|
||||
char *var_error_rcpt;
|
||||
int var_smtpd_delay_reject;
|
||||
char *var_rest_classes;
|
||||
|
||||
/*
|
||||
* Global state, for stand-alone mode queue file cleanup. When this is
|
||||
@ -1178,6 +1183,7 @@ int main(int argc, char **argv)
|
||||
VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0,
|
||||
VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
|
||||
VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
|
||||
VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0,
|
||||
0,
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,7 @@ typedef struct SMTPD_STATE {
|
||||
char *reason;
|
||||
char *sender;
|
||||
char *recipient;
|
||||
char *etrn_name;
|
||||
char *protocol;
|
||||
char *where;
|
||||
} SMTPD_STATE;
|
||||
|
@ -135,6 +135,13 @@
|
||||
/* Allow the request when the local mail system is mail exchanger
|
||||
/* for the recipient domain (this includes the case where the local
|
||||
/* system is the final destination).
|
||||
/* .IP permit_address_map maptype:mapname
|
||||
/* Permit the request when the recipient address matches the named
|
||||
/* table. Lookups are done in the same way as with virtual and
|
||||
/* canonical maps.
|
||||
/* .IP restriction_classes
|
||||
/* Defines a list of parameter names, each parameter being a list
|
||||
/* of restrictions that can be used anywhere a restriction is legal.
|
||||
/* .PP
|
||||
/* smtpd_check_client() validates the client host name or address.
|
||||
/* Relevant configuration parameters:
|
||||
@ -246,6 +253,7 @@
|
||||
#include <argv.h>
|
||||
#include <mymalloc.h>
|
||||
#include <dict.h>
|
||||
#include <htable.h>
|
||||
|
||||
/* DNS library. */
|
||||
|
||||
@ -261,6 +269,9 @@
|
||||
#include <mail_error.h>
|
||||
#include <resolve_local.h>
|
||||
#include <own_inet_addr.h>
|
||||
#include <mail_conf.h>
|
||||
#include <maps.h>
|
||||
#include <mail_addr_find.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
@ -302,6 +313,15 @@ static ARGV *mail_restrctions;
|
||||
static ARGV *rcpt_restrctions;
|
||||
static ARGV *etrn_restrctions;
|
||||
|
||||
static HTABLE *smtpd_rest_classes;
|
||||
|
||||
static HTABLE *smtpd_addr_maps;
|
||||
|
||||
/*
|
||||
* The routine that recursively applies restrictions.
|
||||
*/
|
||||
static int generic_checks(SMTPD_STATE *, ARGV *, char *, char *, char *);
|
||||
|
||||
/*
|
||||
* Reject context.
|
||||
*/
|
||||
@ -318,7 +338,7 @@ static ARGV *etrn_restrctions;
|
||||
|
||||
/* smtpd_check_parse - pre-parse restrictions */
|
||||
|
||||
static ARGV *smtpd_check_parse(char *checks)
|
||||
static ARGV *smtpd_check_parse(const char *checks)
|
||||
{
|
||||
char *saved_checks = mystrdup(checks);
|
||||
ARGV *argv = argv_alloc(1);
|
||||
@ -348,6 +368,10 @@ static ARGV *smtpd_check_parse(char *checks)
|
||||
|
||||
void smtpd_check_init(void)
|
||||
{
|
||||
char *saved_classes;
|
||||
const char *name;
|
||||
const char *value;
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* Pre-open access control lists before going to jail.
|
||||
@ -372,6 +396,35 @@ void smtpd_check_init(void)
|
||||
mail_restrctions = smtpd_check_parse(var_mail_checks);
|
||||
rcpt_restrctions = smtpd_check_parse(var_rcpt_checks);
|
||||
etrn_restrctions = smtpd_check_parse(var_etrn_checks);
|
||||
|
||||
/*
|
||||
* Parse the pre-defined restriction classes.
|
||||
*/
|
||||
smtpd_rest_classes = htable_create(1);
|
||||
if (*var_rest_classes) {
|
||||
cp = saved_classes = mystrdup(var_rest_classes);
|
||||
while ((name = mystrtok(&cp, " \t\r\n,")) != 0) {
|
||||
if ((value = mail_conf_lookup_eval(name)) == 0 || *value == 0)
|
||||
msg_fatal("restriction class `%s' needs a definition", name);
|
||||
htable_enter(smtpd_rest_classes, name,
|
||||
(char *) smtpd_check_parse(value));
|
||||
}
|
||||
myfree(saved_classes);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the place to specify definitions for complex restrictions
|
||||
* such as check_relay_domains in terms of more elementary restrictions.
|
||||
*/
|
||||
#if 0
|
||||
htable_enter("check_relay_domains",
|
||||
smtpd_check_parse("permit_mydomain reject_unauth_destination"));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Other one-off initializations.
|
||||
*/
|
||||
smtpd_addr_maps = htable_create(1);
|
||||
}
|
||||
|
||||
/* smtpd_check_reject - do the boring things that must be done */
|
||||
@ -946,14 +999,61 @@ static int reject_unknown_address(SMTPD_STATE *state, char *addr,
|
||||
return (reject_unknown_mailhost(state, domain, reply_name, reply_class));
|
||||
}
|
||||
|
||||
/* permit_addr_map - permit if address matches rewriting table */
|
||||
|
||||
static int permit_addr_map(SMTPD_STATE *state, char *table,
|
||||
char *reply_name, char *reply_class)
|
||||
{
|
||||
char *myname = "permit_addr_map";
|
||||
char *domain;
|
||||
MAPS *map;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s", myname, table, reply_name);
|
||||
|
||||
/*
|
||||
* Resolve the address.
|
||||
*/
|
||||
canon_addr_internal(query, reply_name);
|
||||
resolve_clnt_query(STR(query), &reply);
|
||||
|
||||
/*
|
||||
* Skip non-DNS forms. Skip non-local numerical forms.
|
||||
*/
|
||||
if ((domain = strrchr(STR(reply.recipient), '@')) == 0)
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
domain += 1;
|
||||
if (domain[0] == '#' || domain[0] == '[')
|
||||
if (STR(reply.nexthop)[0] != 0)
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
|
||||
/*
|
||||
* Look up the name in the specified table, using the usual magic of
|
||||
* canonical and virtual maps.
|
||||
*/
|
||||
if ((map = (MAPS *) htable_find(smtpd_addr_maps, table)) == 0) {
|
||||
map = maps_create("addr_map", table, DICT_FLAG_LOCK);
|
||||
htable_enter(smtpd_addr_maps, table, (char *) map);
|
||||
}
|
||||
#define TOSS_THE_EXTENSION ((char **) 0)
|
||||
|
||||
if (mail_addr_find(map, STR(reply.recipient), TOSS_THE_EXTENSION) != 0)
|
||||
return (SMTPD_CHECK_OK);
|
||||
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
/* check_table_result - translate table lookup result into pass/reject */
|
||||
|
||||
static int check_table_result(SMTPD_STATE *state, char *table,
|
||||
const char *value, const char *datum,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class,
|
||||
char *def_acl)
|
||||
{
|
||||
char *myname = "check_table_result";
|
||||
int code;
|
||||
ARGV *restrictions;
|
||||
int status;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s %s %s", myname, table, value, datum);
|
||||
@ -986,15 +1086,25 @@ static int check_table_result(SMTPD_STATE *state, char *table,
|
||||
}
|
||||
|
||||
/*
|
||||
* OK or RELAY or whatever means YES.
|
||||
* OK or RELAY means YES.
|
||||
*/
|
||||
if (strcasecmp(value, "OK") == 0 || strcasecmp(value, "RELAY") == 0)
|
||||
return (SMTPD_CHECK_OK);
|
||||
|
||||
/*
|
||||
* XXX Don't use passwd files or address rewriting maps as access tables.
|
||||
*/
|
||||
restrictions = argv_split(value, " \t\r\n,");
|
||||
status = generic_checks(state, restrictions, reply_name,
|
||||
reply_class, def_acl);
|
||||
argv_free(restrictions);
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* check_access - table lookup without substring magic */
|
||||
|
||||
static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class, char *def_acl)
|
||||
{
|
||||
char *myname = "check_access";
|
||||
char *low_name = lowercase(mystrdup(name));
|
||||
@ -1013,7 +1123,8 @@ static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
|
||||
if (flags == 0 || (flags & dict->flags) != 0) {
|
||||
if ((value = dict_get(dict, low_name)) != 0)
|
||||
CHK_ACCESS_RETURN(check_table_result(state, table, value, name,
|
||||
reply_name, reply_class));
|
||||
reply_name, reply_class,
|
||||
def_acl));
|
||||
if (dict_errno != 0)
|
||||
msg_fatal("%s: table lookup problem", table);
|
||||
}
|
||||
@ -1024,7 +1135,8 @@ static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
|
||||
|
||||
static int check_domain_access(SMTPD_STATE *state, char *table,
|
||||
char *domain, int flags,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class,
|
||||
char *def_acl)
|
||||
{
|
||||
char *myname = "check_domain_access";
|
||||
char *low_domain = lowercase(mystrdup(domain));
|
||||
@ -1047,7 +1159,8 @@ static int check_domain_access(SMTPD_STATE *state, char *table,
|
||||
if (flags == 0 || (flags & dict->flags) != 0) {
|
||||
if ((value = dict_get(dict, name)) != 0)
|
||||
CHK_DOMAIN_RETURN(check_table_result(state, table, value,
|
||||
domain, reply_name, reply_class));
|
||||
domain, reply_name, reply_class,
|
||||
def_acl));
|
||||
if (dict_errno != 0)
|
||||
msg_fatal("%s: table lookup problem", table);
|
||||
}
|
||||
@ -1060,7 +1173,8 @@ static int check_domain_access(SMTPD_STATE *state, char *table,
|
||||
|
||||
static int check_addr_access(SMTPD_STATE *state, char *table,
|
||||
char *address, int flags,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class,
|
||||
char *def_acl)
|
||||
{
|
||||
char *myname = "check_addr_access";
|
||||
char *addr;
|
||||
@ -1081,7 +1195,8 @@ static int check_addr_access(SMTPD_STATE *state, char *table,
|
||||
if (flags == 0 || (flags & dict->flags) != 0) {
|
||||
if ((value = dict_get(dict, addr)) != 0)
|
||||
return (check_table_result(state, table, value, address,
|
||||
reply_name, reply_class));
|
||||
reply_name, reply_class,
|
||||
def_acl));
|
||||
if (dict_errno != 0)
|
||||
msg_fatal("%s: table lookup problem", table);
|
||||
}
|
||||
@ -1095,7 +1210,8 @@ static int check_addr_access(SMTPD_STATE *state, char *table,
|
||||
|
||||
static int check_namadr_access(SMTPD_STATE *state, char *table,
|
||||
char *name, char *addr, int flags,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class,
|
||||
char *def_acl)
|
||||
{
|
||||
char *myname = "check_namadr_access";
|
||||
int status;
|
||||
@ -1108,14 +1224,16 @@ static int check_namadr_access(SMTPD_STATE *state, char *table,
|
||||
* wildcard may pre-empt a more specific address table entry.
|
||||
*/
|
||||
if ((status = check_domain_access(state, table, name, flags,
|
||||
reply_name, reply_class)) != 0)
|
||||
reply_name, reply_class,
|
||||
def_acl)) != 0)
|
||||
return (status);
|
||||
|
||||
/*
|
||||
* Look up the network address, or parent networks thereof.
|
||||
*/
|
||||
if ((status = check_addr_access(state, table, addr, flags,
|
||||
reply_name, reply_class)) != 0)
|
||||
reply_name, reply_class,
|
||||
def_acl)) != 0)
|
||||
return (status);
|
||||
|
||||
/*
|
||||
@ -1127,7 +1245,8 @@ static int check_namadr_access(SMTPD_STATE *state, char *table,
|
||||
/* check_mail_access - OK/FAIL based on mail address lookup */
|
||||
|
||||
static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
|
||||
char *reply_name, char *reply_class)
|
||||
char *reply_name, char *reply_class,
|
||||
char *def_acl)
|
||||
{
|
||||
char *myname = "check_mail_access";
|
||||
char *ratsign;
|
||||
@ -1156,14 +1275,14 @@ static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
|
||||
* Look up the full address.
|
||||
*/
|
||||
if ((status = check_access(state, table, STR(reply.recipient), FULL,
|
||||
reply_name, reply_class)) != 0)
|
||||
reply_name, reply_class, def_acl)) != 0)
|
||||
return (status);
|
||||
|
||||
/*
|
||||
* Look up the domain name, or parent domains thereof.
|
||||
*/
|
||||
if ((status = check_domain_access(state, table, ratsign + 1, PARTIAL,
|
||||
reply_name, reply_class)) != 0)
|
||||
reply_name, reply_class, def_acl)) != 0)
|
||||
return (status);
|
||||
|
||||
/*
|
||||
@ -1172,7 +1291,7 @@ static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
|
||||
local_at = mystrndup(STR(reply.recipient),
|
||||
ratsign - STR(reply.recipient) + 1);
|
||||
status = check_access(state, table, local_at, PARTIAL,
|
||||
reply_name, reply_class);
|
||||
reply_name, reply_class, def_acl);
|
||||
myfree(local_at);
|
||||
if (status != 0)
|
||||
return (status);
|
||||
@ -1267,170 +1386,226 @@ static int is_map_command(char *name, char *command, char ***argp)
|
||||
|
||||
/* generic_checks - generic restrictions */
|
||||
|
||||
static int generic_checks(SMTPD_STATE *state, char *name,
|
||||
char ***cpp, int *status,
|
||||
char *reply_name, char *reply_class)
|
||||
static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
char *reply_name, char *reply_class, char *def_acl)
|
||||
{
|
||||
char *myname = "generic_checks";
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
ARGV *list;
|
||||
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
return (0);
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: START", myname);
|
||||
|
||||
for (cpp = restrictions->argv; (name = *cpp) != 0; cpp++) {
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: name=%s", myname, name);
|
||||
|
||||
/*
|
||||
* Spoof the is_map_command() routine, so that we do not have to make
|
||||
* special cases for the implicit short-hand access map notation.
|
||||
*/
|
||||
if (strchr(name, ':') != 0) {
|
||||
name = def_acl;
|
||||
cpp -= 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic restrictions.
|
||||
*/
|
||||
if (strcasecmp(name, PERMIT_ALL) == 0) {
|
||||
*status = SMTPD_CHECK_OK;
|
||||
if ((*cpp)[1] != 0)
|
||||
status = SMTPD_CHECK_OK;
|
||||
if (cpp[1] != 0)
|
||||
msg_warn("restriction `%s' after `%s' is ignored",
|
||||
(*cpp)[1], PERMIT_ALL);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_ALL) == 0) {
|
||||
*status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
cpp[1], PERMIT_ALL);
|
||||
} else if (strcasecmp(name, REJECT_ALL) == 0) {
|
||||
status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
"%d <%s>: %s rejected: Access denied",
|
||||
var_reject_code, reply_name, reply_class);
|
||||
if ((*cpp)[1] != 0)
|
||||
if (cpp[1] != 0)
|
||||
msg_warn("restriction `%s' after `%s' is ignored",
|
||||
(*cpp)[1], REJECT_ALL);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) {
|
||||
*status = reject_unauth_pipelining(state);
|
||||
return (1);
|
||||
cpp[1], REJECT_ALL);
|
||||
} else if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) {
|
||||
status = reject_unauth_pipelining(state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Client name/address restrictions.
|
||||
*/
|
||||
if (strcasecmp(name, REJECT_UNKNOWN_CLIENT) == 0) {
|
||||
*status = reject_unknown_client(state);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, PERMIT_MYNETWORKS) == 0) {
|
||||
*status = permit_mynetworks(state);
|
||||
return (1);
|
||||
}
|
||||
if (is_map_command(name, CHECK_CLIENT_ACL, cpp)) {
|
||||
*status = check_namadr_access(state, **cpp, state->name, state->addr,
|
||||
FULL, state->namaddr, SMTPD_NAME_CLIENT);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_MAPS_RBL) == 0) {
|
||||
*status = reject_maps_rbl(state);
|
||||
return (1);
|
||||
else if (strcasecmp(name, REJECT_UNKNOWN_CLIENT) == 0) {
|
||||
status = reject_unknown_client(state);
|
||||
} else if (strcasecmp(name, PERMIT_MYNETWORKS) == 0) {
|
||||
status = permit_mynetworks(state);
|
||||
} else if (is_map_command(name, CHECK_CLIENT_ACL, &cpp)) {
|
||||
status = check_namadr_access(state, *cpp, state->name, state->addr,
|
||||
FULL, state->namaddr,
|
||||
SMTPD_NAME_CLIENT, def_acl);
|
||||
} else if (strcasecmp(name, REJECT_MAPS_RBL) == 0) {
|
||||
status = reject_maps_rbl(state);
|
||||
}
|
||||
|
||||
/*
|
||||
* HELO/EHLO parameter restrictions.
|
||||
*/
|
||||
if (is_map_command(name, CHECK_HELO_ACL, cpp) && state->helo_name) {
|
||||
else if (is_map_command(name, CHECK_HELO_ACL, &cpp)) {
|
||||
if (state->helo_name)
|
||||
*status = check_domain_access(state, **cpp, state->helo_name, FULL,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_INVALID_HOSTNAME) == 0) {
|
||||
status = check_domain_access(state, *cpp, state->helo_name,
|
||||
FULL, state->helo_name,
|
||||
SMTPD_NAME_HELO, def_acl);
|
||||
} else if (strcasecmp(name, REJECT_INVALID_HOSTNAME) == 0) {
|
||||
if (state->helo_name) {
|
||||
if (*state->helo_name != '[')
|
||||
*status = reject_invalid_hostname(state, state->helo_name,
|
||||
status = reject_invalid_hostname(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
else
|
||||
*status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_UNKNOWN_HOSTNAME) == 0) {
|
||||
} else if (strcasecmp(name, REJECT_UNKNOWN_HOSTNAME) == 0) {
|
||||
if (state->helo_name) {
|
||||
if (*state->helo_name != '[')
|
||||
*status = reject_unknown_hostname(state, state->helo_name,
|
||||
status = reject_unknown_hostname(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
else
|
||||
*status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, PERMIT_NAKED_IP_ADDR) == 0) {
|
||||
} else if (strcasecmp(name, PERMIT_NAKED_IP_ADDR) == 0) {
|
||||
if (state->helo_name) {
|
||||
if (state->helo_name[strspn(state->helo_name, "0123456789.")] == 0
|
||||
&& (*status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
&& (status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO)) == 0)
|
||||
*status = SMTPD_CHECK_OK;
|
||||
status = SMTPD_CHECK_OK;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
|
||||
} else if (strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
|
||||
if (state->helo_name) {
|
||||
if (*state->helo_name != '[')
|
||||
*status = reject_non_fqdn_hostname(state, state->helo_name,
|
||||
status = reject_non_fqdn_hostname(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
else
|
||||
*status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
status = reject_invalid_hostaddr(state, state->helo_name,
|
||||
state->helo_name, SMTPD_NAME_HELO);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sender mail address restrictions.
|
||||
*/
|
||||
if (is_map_command(name, CHECK_SENDER_ACL, cpp) && state->sender) {
|
||||
else if (is_map_command(name, CHECK_SENDER_ACL, &cpp)) {
|
||||
if (state->sender)
|
||||
*status = check_mail_access(state, **cpp, state->sender,
|
||||
state->sender, SMTPD_NAME_SENDER);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) {
|
||||
status = check_mail_access(state, *cpp, state->sender,
|
||||
state->sender,
|
||||
SMTPD_NAME_SENDER, def_acl);
|
||||
} else if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) {
|
||||
if (state->sender)
|
||||
*status = reject_unknown_address(state, state->sender,
|
||||
status = reject_unknown_address(state, state->sender,
|
||||
state->sender, SMTPD_NAME_SENDER);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_UNKNOWN_SENDDOM) == 0) {
|
||||
} else if (strcasecmp(name, REJECT_UNKNOWN_SENDDOM) == 0) {
|
||||
if (state->sender)
|
||||
*status = reject_unknown_address(state, state->sender,
|
||||
status = reject_unknown_address(state, state->sender,
|
||||
state->sender, SMTPD_NAME_SENDER);
|
||||
return (1);
|
||||
}
|
||||
if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) {
|
||||
if (*state->sender)
|
||||
*status = reject_non_fqdn_address(state, state->sender,
|
||||
} else if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) {
|
||||
if (state->sender && *state->sender)
|
||||
status = reject_non_fqdn_address(state, state->sender,
|
||||
state->sender, SMTPD_NAME_SENDER);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Recipient mail address restrictions.
|
||||
*/
|
||||
else if (is_map_command(name, CHECK_RECIP_ACL, &cpp)) {
|
||||
if (state->recipient)
|
||||
status = check_mail_access(state, *cpp, state->recipient,
|
||||
state->recipient,
|
||||
SMTPD_NAME_RECIPIENT, def_acl);
|
||||
} else if (strcasecmp(name, PERMIT_MX_BACKUP) == 0) {
|
||||
if (state->recipient)
|
||||
status = permit_mx_backup(state, state->recipient);
|
||||
} else if (strcasecmp(name, REJECT_UNAUTH_DEST) == 0) {
|
||||
if (state->recipient)
|
||||
status = reject_unauth_destination(state, state->recipient);
|
||||
} else if (strcasecmp(name, CHECK_RELAY_DOMAINS) == 0) {
|
||||
if (state->recipient)
|
||||
status = check_relay_domains(state, state->recipient,
|
||||
state->recipient, SMTPD_NAME_RECIPIENT);
|
||||
if (cpp[1] != 0)
|
||||
msg_warn("restriction `%s' after `%s' is ignored",
|
||||
cpp[1], CHECK_RELAY_DOMAINS);
|
||||
} else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
|
||||
if (state->recipient)
|
||||
status = reject_unknown_address(state, state->recipient,
|
||||
state->recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (strcasecmp(name, REJECT_NON_FQDN_RCPT) == 0) {
|
||||
if (state->recipient)
|
||||
status = reject_non_fqdn_address(state, state->recipient,
|
||||
state->recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (is_map_command(name, PERMIT_ADDR_MAP, &cpp)) {
|
||||
if (state->recipient)
|
||||
status = permit_addr_map(state, *cpp,
|
||||
state->recipient, SMTPD_NAME_RECIPIENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* ETRN domain name restrictions.
|
||||
*/
|
||||
else if (is_map_command(name, CHECK_ETRN_ACL, &cpp)) {
|
||||
if (state->etrn_name)
|
||||
status = check_domain_access(state, *cpp, state->etrn_name,
|
||||
FULL, state->etrn_name,
|
||||
SMTPD_NAME_ETRN, def_acl);
|
||||
}
|
||||
|
||||
/*
|
||||
* User-defined restriction class.
|
||||
*/
|
||||
else if ((list = (ARGV *) htable_find(smtpd_rest_classes, name)) != 0) {
|
||||
status = generic_checks(state, list, reply_name,
|
||||
reply_class, def_acl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Error: undefined restriction name.
|
||||
*/
|
||||
else {
|
||||
msg_warn("unknown smtpd restriction: \"%s\"", name);
|
||||
break;
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: name=%s status=%d", myname, name, status);
|
||||
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
if (msg_verbose && name == 0)
|
||||
msg_info("%s: END", myname);
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* smtpd_check_client - validate client name or address */
|
||||
|
||||
char *smtpd_check_client(SMTPD_STATE *state)
|
||||
{
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (state->name == 0 && state->addr == 0)
|
||||
return (0);
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
if (state->name == 0 || state->addr == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
for (cpp = client_restrctions->argv; (name = *cpp) != 0; cpp++) {
|
||||
if (strchr(name, ':') != 0) {
|
||||
status = check_namadr_access(state, name, state->name, state->addr,
|
||||
FULL, state->namaddr, SMTPD_NAME_CLIENT);
|
||||
} else if (generic_checks(state, name, &cpp, &status,
|
||||
state->namaddr, SMTPD_NAME_CLIENT) == 0) {
|
||||
msg_warn("unknown %s check: \"%s\"", VAR_CLIENT_CHECKS, name);
|
||||
break;
|
||||
}
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
status = generic_checks(state, client_restrctions, state->namaddr,
|
||||
SMTPD_NAME_CLIENT, CHECK_CLIENT_ACL);
|
||||
|
||||
return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
@ -1438,90 +1613,84 @@ char *smtpd_check_client(SMTPD_STATE *state)
|
||||
|
||||
char *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
|
||||
{
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
char *saved_helo = state->helo_name;
|
||||
char *saved_helo;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (helohost == 0)
|
||||
return (0);
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified. Minor kluge so that we
|
||||
* can delegate work to the generic routine.
|
||||
* Minor kluge so that we can delegate work to the generic routine and so
|
||||
* that we can syslog the recipient with the reject messages.
|
||||
*/
|
||||
state->helo_name = mystrdup(helohost);
|
||||
for (cpp = helo_restrctions->argv; (name = *cpp) != 0; cpp++) {
|
||||
if (strchr(name, ':') != 0) {
|
||||
status = check_domain_access(state, name, helohost, FULL,
|
||||
helohost, SMTPD_NAME_HELO);
|
||||
} else if (generic_checks(state, name, &cpp, &status,
|
||||
helohost, SMTPD_NAME_HELO) == 0) {
|
||||
msg_warn("unknown %s check: \"%s\"", VAR_HELO_CHECKS, name);
|
||||
break;
|
||||
}
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
myfree(state->helo_name);
|
||||
state->helo_name = saved_helo;
|
||||
return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
#define SMTPD_CHECK_PUSH(backup, current, new) { \
|
||||
backup = current; \
|
||||
current = mystrdup(new); \
|
||||
}
|
||||
|
||||
/* smtpd_check_mail - validate sender address */
|
||||
#define SMTPD_CHECK_POP(current, backup) { \
|
||||
myfree(current); \
|
||||
current = backup; \
|
||||
}
|
||||
|
||||
SMTPD_CHECK_PUSH(saved_helo, state->helo_name, helohost);
|
||||
|
||||
#define SMTPD_CHECK_HELO_RETURN(x) { \
|
||||
SMTPD_CHECK_POP(state->helo_name, saved_helo); \
|
||||
return (x); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
status = generic_checks(state, helo_restrctions, state->helo_name,
|
||||
SMTPD_NAME_HELO, CHECK_HELO_ACL);
|
||||
|
||||
SMTPD_CHECK_HELO_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
/* smtpd_check_mail - validate sender address, driver */
|
||||
|
||||
char *smtpd_check_mail(SMTPD_STATE *state, char *sender)
|
||||
{
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
char *saved_sender = state->sender;
|
||||
char *saved_sender;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (sender == 0)
|
||||
return (0);
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified. Minor kluge so that we
|
||||
* can delegate work to the generic routine.
|
||||
* Minor kluge so that we can delegate work to the generic routine and so
|
||||
* that we can syslog the recipient with the reject messages.
|
||||
*/
|
||||
state->sender = mystrdup(sender);
|
||||
for (cpp = mail_restrctions->argv; (name = *cpp) != 0; cpp++) {
|
||||
if (strchr(name, ':') != 0) {
|
||||
status = check_mail_access(state, name, sender,
|
||||
sender, SMTPD_NAME_SENDER);
|
||||
} else if (generic_checks(state, name, &cpp, &status,
|
||||
sender, SMTPD_NAME_SENDER) == 0) {
|
||||
msg_warn("unknown %s check: \"%s\"", VAR_MAIL_CHECKS, name);
|
||||
return (0);
|
||||
}
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
myfree(state->sender);
|
||||
state->sender = saved_sender;
|
||||
return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
SMTPD_CHECK_PUSH(saved_sender, state->sender, sender);
|
||||
|
||||
#define SMTPD_CHECK_MAIL_RETURN(x) { \
|
||||
SMTPD_CHECK_POP(state->sender, saved_sender); \
|
||||
return (x); \
|
||||
}
|
||||
|
||||
/* smtpd_check_rcpt - validate recipient address */
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
status = generic_checks(state, mail_restrctions, sender,
|
||||
SMTPD_NAME_SENDER, CHECK_SENDER_ACL);
|
||||
|
||||
SMTPD_CHECK_MAIL_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
/* smtpd_check_rcpt - validate recipient address, driver */
|
||||
|
||||
char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
{
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
char *saved_recipient = state->recipient;
|
||||
char *saved_recipient;
|
||||
char *err;
|
||||
|
||||
/*
|
||||
@ -1534,11 +1703,10 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
* Minor kluge so that we can delegate work to the generic routine and so
|
||||
* that we can syslog the recipient with the reject messages.
|
||||
*/
|
||||
state->recipient = mystrdup(recipient);
|
||||
SMTPD_CHECK_PUSH(saved_recipient, state->recipient, recipient);
|
||||
|
||||
#define SMTPD_CHECK_RCPT_RETURN(x) { \
|
||||
myfree(state->recipient); \
|
||||
state->recipient = saved_recipient; \
|
||||
SMTPD_CHECK_POP(state->recipient, saved_recipient); \
|
||||
return (x); \
|
||||
}
|
||||
|
||||
@ -1551,47 +1719,12 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
|| (err = smtpd_check_mail(state, state->sender)) != 0)
|
||||
SMTPD_CHECK_RCPT_RETURN(err);
|
||||
|
||||
/*
|
||||
* More initialization.
|
||||
*/
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
SMTPD_CHECK_RCPT_RETURN(0);
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
for (cpp = rcpt_restrctions->argv; (name = *cpp) != 0; cpp++) {
|
||||
if (strchr(name, ':') != 0) {
|
||||
status = check_mail_access(state, name, recipient,
|
||||
recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (is_map_command(name, CHECK_RECIP_ACL, &cpp)) {
|
||||
status = check_mail_access(state, *cpp, recipient,
|
||||
recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (strcasecmp(name, PERMIT_MX_BACKUP) == 0) {
|
||||
status = permit_mx_backup(state, recipient);
|
||||
} else if (strcasecmp(name, REJECT_UNAUTH_DEST) == 0) {
|
||||
status = reject_unauth_destination(state, recipient);
|
||||
} else if (strcasecmp(name, CHECK_RELAY_DOMAINS) == 0) {
|
||||
status = check_relay_domains(state, recipient,
|
||||
recipient, SMTPD_NAME_RECIPIENT);
|
||||
if (cpp[1] != 0)
|
||||
msg_warn("restriction `%s' after `%s' is ignored",
|
||||
cpp[1], CHECK_RELAY_DOMAINS);
|
||||
} else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
|
||||
status = reject_unknown_address(state, recipient,
|
||||
recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (strcasecmp(name, REJECT_NON_FQDN_RCPT) == 0) {
|
||||
status = reject_non_fqdn_address(state, recipient,
|
||||
recipient, SMTPD_NAME_RECIPIENT);
|
||||
} else if (generic_checks(state, name, &cpp, &status,
|
||||
recipient, SMTPD_NAME_RECIPIENT) == 0) {
|
||||
msg_warn("unknown %s check: \"%s\"", VAR_RCPT_CHECKS, name);
|
||||
break;
|
||||
}
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
status = generic_checks(state, rcpt_restrctions,
|
||||
recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL);
|
||||
|
||||
SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
@ -1599,47 +1732,42 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
|
||||
char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
|
||||
{
|
||||
char **cpp;
|
||||
char *name;
|
||||
int status;
|
||||
char *saved_etrn_name;
|
||||
char *err;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (domain == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Minor kluge so that we can delegate work to the generic routine and so
|
||||
* that we can syslog the recipient with the reject messages.
|
||||
*/
|
||||
SMTPD_CHECK_PUSH(saved_etrn_name, state->etrn_name, domain);
|
||||
|
||||
#define SMTPD_CHECK_ETRN_RETURN(x) { \
|
||||
SMTPD_CHECK_POP(state->etrn_name, saved_etrn_name); \
|
||||
return (x); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply delayed restrictions.
|
||||
*/
|
||||
if (var_smtpd_delay_reject)
|
||||
if ((err = smtpd_check_client(state)) != 0
|
||||
|| (err = smtpd_check_helo(state, state->helo_name)) != 0)
|
||||
return (err);
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (domain == 0)
|
||||
return (0);
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status != 0)
|
||||
return (0);
|
||||
SMTPD_CHECK_ETRN_RETURN(err);
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
for (cpp = etrn_restrctions->argv; (name = *cpp) != 0; cpp++) {
|
||||
if (strchr(name, ':') != 0) {
|
||||
status = check_domain_access(state, name, domain, FULL,
|
||||
domain, SMTPD_NAME_ETRN);
|
||||
} else if (is_map_command(name, CHECK_ETRN_ACL, &cpp)) {
|
||||
status = check_domain_access(state, *cpp, domain, FULL,
|
||||
domain, SMTPD_NAME_ETRN);
|
||||
} else if (generic_checks(state, name, &cpp, &status,
|
||||
domain, SMTPD_NAME_ETRN) == 0) {
|
||||
msg_warn("unknown %s check: \"%s\"", VAR_RCPT_CHECKS, name);
|
||||
break;
|
||||
}
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
status = generic_checks(state, etrn_restrctions, domain,
|
||||
SMTPD_NAME_ETRN, CHECK_ETRN_ACL);
|
||||
|
||||
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
/* smtpd_check_size - check optional SIZE parameter value */
|
||||
@ -1661,6 +1789,7 @@ char *smtpd_check_size(SMTPD_STATE *state, off_t size)
|
||||
return (STR(error_text));
|
||||
}
|
||||
fsspace(".", &fsbuf);
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: blocks %lu avail %lu min_free %lu size %lu",
|
||||
myname,
|
||||
@ -1713,6 +1842,7 @@ char *var_notify_classes = "";
|
||||
char *var_maps_rbl_domains;
|
||||
char *var_mydest;
|
||||
char *var_inet_interfaces;
|
||||
char *var_rest_classes;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
@ -1724,6 +1854,7 @@ static STRING_TABLE string_table[] = {
|
||||
VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains,
|
||||
VAR_MYDEST, DEF_MYDEST, &var_mydest,
|
||||
VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces,
|
||||
VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes,
|
||||
0,
|
||||
};
|
||||
|
||||
@ -1822,9 +1953,9 @@ static int int_update(char **argv)
|
||||
typedef struct {
|
||||
char *name;
|
||||
ARGV **target;
|
||||
} REST_TABLE;
|
||||
} SMTPD_REST_TABLE;
|
||||
|
||||
static REST_TABLE rest_table[] = {
|
||||
static SMTPD_REST_TABLE smtpd_rest_table[] = {
|
||||
"client_restrictions", &client_restrctions,
|
||||
"helo_restrictions", &helo_restrctions,
|
||||
"sender_restrictions", &mail_restrctions,
|
||||
@ -1833,13 +1964,13 @@ static REST_TABLE rest_table[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
/* rest_update - update restriction */
|
||||
/* smtpd_rest_update - update restriction */
|
||||
|
||||
static int rest_update(char **argv)
|
||||
static int smtpd_rest_update(char **argv)
|
||||
{
|
||||
REST_TABLE *rp;
|
||||
SMTPD_REST_TABLE *rp;
|
||||
|
||||
for (rp = rest_table; rp->name; rp++) {
|
||||
for (rp = smtpd_rest_table; rp->name; rp++) {
|
||||
if (strcasecmp(rp->name, argv[0]) == 0) {
|
||||
argv_free(rp->target[0]);
|
||||
rp->target[0] = smtpd_check_parse(argv[1]);
|
||||
@ -1980,7 +2111,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (int_update(args->argv)
|
||||
|| string_update(args->argv)
|
||||
|| rest_update(args->argv)) {
|
||||
|| smtpd_rest_update(args->argv)) {
|
||||
resp = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -150,7 +150,6 @@ rcpt foo
|
||||
#
|
||||
# Numerical HELO checks
|
||||
#
|
||||
msg_verbose 1
|
||||
helo_restrictions permit_naked_ip_address,reject_non_fqdn_hostname
|
||||
helo [1.2.3.4]
|
||||
helo [321.255.255.255]
|
||||
|
@ -307,93 +307,73 @@ OK
|
||||
>>> #
|
||||
>>> # Numerical HELO checks
|
||||
>>> #
|
||||
>>> msg_verbose 1
|
||||
OK
|
||||
>>> helo_restrictions permit_naked_ip_address,reject_non_fqdn_hostname
|
||||
OK
|
||||
>>> helo [1.2.3.4]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1.2.3.4]
|
||||
OK
|
||||
>>> helo [321.255.255.255]
|
||||
./smtpd_check: reject_invalid_hostaddr: [321.255.255.255]
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[321.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[321.255.255.255]>: Helo command rejected: invalid ip address
|
||||
>>> helo [0.255.255.255]
|
||||
./smtpd_check: reject_invalid_hostaddr: [0.255.255.255]
|
||||
./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[0.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[0.255.255.255]>: Helo command rejected: invalid ip address
|
||||
>>> helo [1.2.3.321]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1.2.3.321]
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.321]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[1.2.3.321]>: Helo command rejected: invalid ip address
|
||||
>>> helo [1.2.3]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1.2.3]
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[1.2.3]>: Helo command rejected: invalid ip address
|
||||
>>> helo [1.2.3.4.5]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1.2.3.4.5]
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address
|
||||
>>> helo [1..2.3.4]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1..2.3.4]
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1..2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[1..2.3.4]>: Helo command rejected: invalid ip address
|
||||
>>> helo [.1.2.3.4]
|
||||
./smtpd_check: reject_invalid_hostaddr: [.1.2.3.4]
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[.1.2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[.1.2.3.4]>: Helo command rejected: invalid ip address
|
||||
>>> helo [1.2.3.4.5.]
|
||||
./smtpd_check: reject_invalid_hostaddr: [1.2.3.4.5.]
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address
|
||||
>>> helo 1.2.3.4
|
||||
./smtpd_check: reject_invalid_hostaddr: 1.2.3.4
|
||||
OK
|
||||
>>> helo 321.255.255.255
|
||||
./smtpd_check: reject_invalid_hostaddr: 321.255.255.255
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <321.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <321.255.255.255>: Helo command rejected: invalid ip address
|
||||
>>> helo 0.255.255.255
|
||||
./smtpd_check: reject_invalid_hostaddr: 0.255.255.255
|
||||
./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <0.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <0.255.255.255>: Helo command rejected: invalid ip address
|
||||
>>> helo 1.2.3.321
|
||||
./smtpd_check: reject_invalid_hostaddr: 1.2.3.321
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.321>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <1.2.3.321>: Helo command rejected: invalid ip address
|
||||
>>> helo 1.2.3
|
||||
./smtpd_check: reject_invalid_hostaddr: 1.2.3
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <1.2.3>: Helo command rejected: invalid ip address
|
||||
>>> helo 1.2.3.4.5
|
||||
./smtpd_check: reject_invalid_hostaddr: 1.2.3.4.5
|
||||
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <1.2.3.4.5>: Helo command rejected: invalid ip address
|
||||
>>> helo 1..2.3.4
|
||||
./smtpd_check: reject_invalid_hostaddr: 1..2.3.4
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1..2.3.4>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <1..2.3.4>: Helo command rejected: invalid ip address
|
||||
>>> helo .1.2.3.4
|
||||
./smtpd_check: reject_invalid_hostaddr: .1.2.3.4
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <.1.2.3.4>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <.1.2.3.4>: Helo command rejected: invalid ip address
|
||||
>>> helo 1.2.3.4.5.
|
||||
./smtpd_check: reject_invalid_hostaddr: 1.2.3.4.5.
|
||||
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
|
||||
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5.>: Helo command rejected: invalid ip address; from=<foo>
|
||||
501 <1.2.3.4.5.>: Helo command rejected: invalid ip address
|
||||
|
@ -95,6 +95,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
|
||||
state->reason = 0;
|
||||
state->sender = 0;
|
||||
state->recipient = 0;
|
||||
state->etrn_name = 0;
|
||||
state->protocol = "SMTP";
|
||||
state->where = SMTPD_AFTER_CONNECT;
|
||||
|
||||
|
1
postfix/smtpstone/.indent.pro
vendored
1
postfix/smtpstone/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/trivial-rewrite/.indent.pro
vendored
1
postfix/trivial-rewrite/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
1
postfix/util/.indent.pro
vendored
1
postfix/util/.indent.pro
vendored
@ -87,6 +87,7 @@
|
||||
-TSINGLE_SERVER
|
||||
-TSINK_COMMAND
|
||||
-TSINK_STATE
|
||||
-TSMTPD_REST_TABLE
|
||||
-TSMTPD_STATE
|
||||
-TSMTPD_TOKEN
|
||||
-TSMTP_ADDR
|
||||
|
Loading…
x
Reference in New Issue
Block a user