2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-19991216

This commit is contained in:
Wietse Venema
1999-12-16 00:00:00 -05:00
parent 86d2e38b17
commit 1ca1119df9
44 changed files with 324 additions and 156 deletions

1
postfix/.indent.pro vendored
View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -3369,3 +3369,44 @@ Apologies for any names omitted.
Bugfix: address rewriting would panic on a lone \ at the
end of a line where an address was expected. Jason Hoos @
thwack.net. File: global/rewrite_clnt.c.
19991215
Bugfix: the strict RFC821 envelope address check should
not be applied to VRFY commands. File: smtpd/smtpd.c.
Cleanup: permit_recipient_maps is gone, because that could
only be used inside UCE restrictions.
19991216
Feature: allow an empty inet_interfaces parameter, just
like an empty mydestination parameter. It's needed for a
true null client that delivers no mail locally at all.
Feature: "disable_vrfy_command = yes" disables some forms
of address harvesting used by spammers.
Workaround: added the alias map parameter definition to
the smtpd code. This is a symptom of a general problem
with parameters that have non-empty default values: unless
a program explicitly defines such a parameter, the parameter
defaults to the empty string when used in other parameters.
There's also a problem with evaluation order.
Feature: the SMTP server rejects mail for unknown users in
virtual domains that are defined by Postfix virtual domain
files. File: smtpd/smtpd_check.c.
Feature: reject mail for unknown local users at the SMTP
port. The local_recipient_maps configuration parameter
specifies maps with all addresses that are local with
respect to $mydestination or $inet_interfaces. Example:
"local_recipient_maps = $alias_maps unix:passwd.byname".
This feature is disabled by default. You may have to copy
the passwd file into the chroot jail. File: smtpd/smtpd_check.c.
Feature: the sendmail -f option now understands '<user>'
and even understands address forms with RFC 822-style
comments.

View File

@@ -108,7 +108,10 @@ directory of the source tree and type:
To build with a non-default compiler, you need to specify the name
of the compiler:
% make makefiles CC=/opt/SUNWspro/bin/cc
% make makefiles CC=/opt/SUNWspro/bin/cc (Solaris)
% make
% make makefiles CC="/opt/ansic/bin/cc -Ae" (HP-UX)
% make
% make makefiles CC="purify cc"

View File

@@ -199,7 +199,8 @@ test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
for path in $SENDMAIL_PATH $NEWALIASES_PATH $MAILQ_PATH
do
mkdir -p `echo $path|sed 's/[^/]*[/]*$//'`
dir=`echo $path|sed 's/[^/]*[/]*$//'`
test -d $dir || mkdir -p $dir || exit 1
done
# Install files. Be careful to not copy over running programs.
@@ -285,7 +286,7 @@ no) ;;
*) (
cd man || exit 1
for dir in man?
do mkdir -p $MANPAGES/$dir || exit 1
do test -d $MANPAGES/$dir || mkdir -p $MANPAGES/$dir || exit 1
done
for file in man?/*
do

View File

@@ -17,7 +17,7 @@ makefiles Makefiles:
update printfck:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $(OPTS) $@) || exit 1; \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $(OPTS) $@ MAKELEVEL=) || exit 1; \
done
printfck: update

View File

@@ -1,6 +1,11 @@
Incompatible changes with snapshot 19991211
Incompatible changes with snapshot 19991216
===========================================
- The experimental permit_recipient_map feature is gone. It was
never part of an official release. It is replaced by a
"local_recipient_map" parameter that allows the SMTP server to
reject mail for unknown local users (see below).
- In an SMTPD access map, an all-numeric right-hand side now means
OK. This is for better cooperation with out-of-band authentication
mechanisms such as POP before SMTP etc.
@@ -13,8 +18,8 @@ reinstate the old behavior, specify "allow_min_user = yes" in
main.cf.
- You can no longer use virtual, canonical or aliases tables as
SMTPD access control tables. Use the permit_recipient_map feature
instead. The loss is compensated for (see below).
SMTPD access control tables. Use the local_recipient_maps feature
instead.
- transport_maps entries override mydestination. For every
$mydestination domain that matches a transport map entry, or a
@@ -22,13 +27,27 @@ parent domain of a transport map entry, you must now add a
corresponding "domain.name local:" entry in your transport_maps.
See the html/faq.html sections for firewalls and intranets.
Major changes with snapshot 19991211
Major changes with snapshot 19991216
====================================
- Updated LDAP client code (John Hensley).
- Updated mysql client code (Scott Cotton).
- The SMTP server now rejects mail for unknown users in virtual
domains that are defined by Postfix virtual maps.
- The SMTP server optionally rejects mail for unknown local users.
Use "local_recipient_maps = $alias_maps, unix:passwd.byname" if
your local mail is delivered by a UNIX-style local delivery agent.
See example in conf/main.cf.
- Use "disable_vrfy_command = yes" to disable the SMTP VRFY command.
This prevents some forms of address harvesting.
- The sendmail "-f" option now understands <user> and even understands
forms with RFC 822-style comments.
- New "qmgr_fudge_factor" parameter allows you to balance mailing
list performance against response time for one-to-one mail. The
fudge factor controls what percentage of delivery resources Postfix
@@ -50,26 +69,12 @@ regardless of what main.cf specifies.
- The Postfix SMTP server now understands a wider range of illegal
address forms in MAIL FROM and RCPT TO commands. In order to disable
those forms, specify "strict_rfc821_envelopes = yes".
illegal forms, specify "strict_rfc821_envelopes = yes". This also
disables support for MAIL FROM and RCPT TO addresses without <>.
- Per-client/helo/sender/recipient UCE restrictions (fully-recursive
UCE restriction parser). See the RESTRICTION_CLASS file for details.
- Block mail for most non-existent users at the SMTP port. Example:
a non-relaying host could use the following to reject mail for
non-existent local users and for all non-local destinations.
smtpd_recipient_restrictions =
reject_unknown_sender_domain
permit_recipient_map unix:passwd.byname
permit_recipient_map hash:/etc/postfix/canonical
permit_recipient_map hash:/etc/postfix/virtual
permit_recipient_map hash:/etc/aliases
reject
I haven't figured out yet how to use this easily on hosts that must
relay mail for other systems.
- Use "postmap -q key" or "postalias -q key" for testing Postfix
lookup tables or alias files.

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -116,6 +116,21 @@ mail_owner = postfix
#mydestination = $myhostname, localhost.$mydomain, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
# REJECTING UNKNOWN LOCAL USERS
#
# The local_recipient_maps parameter specifies optional lookup tables
# with all users that are local with respect to $mydestination and
# $inet_interfaces. If this parameter is defined, then the SMTP server
# will reject mail for unknown local users.
#
# The local_recipient_maps parameter accepts tables with bare usernames
# such as unix:passwd.byname and alias maps.
#
# Beware: if the Postfix SMTP server runs chrooted, you may have to
# copy the passwd database into the jail. This is system dependent.
#
#local_recipient_maps = $alias_maps unix:passwd.byname
# INTERNET VERSUS INTRANET
#
# The relayhost parameter specifies the default host to send mail to

View File

@@ -8,6 +8,12 @@
# MISCELLANEOUS
#
# The disable_vrfy_command parameter allows you to disable the SMTP
# VRFY command. This stops some techniques used by spammers to harvest
# email addresses.
#
#disable_vrfy_command = no
# The smtpd_banner parameter specifies the text that follows the 220
# status code in the SMTP greeting banner. Some people like to see
# the mail version advertised. By default, Postfix shows no version.
@@ -208,9 +214,6 @@ 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_recipient_map maptype:mapname: permit if the recipient matches
# the table. Matching is as with virtual/canonical tables.
# You can also use unix:passwd.byname or alias maps.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
#

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -261,7 +261,7 @@ void mail_params_init()
VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0,
VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0,
VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0,
VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 1, 0,
VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 0, 0,
VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0,
VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0,
VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 1, 0,

View File

@@ -222,6 +222,13 @@ extern char *var_always_bcc;
#define DEF_STRICT_RFC821_ENV 0
extern bool var_strict_rfc821_env;
/*
* Standards violation: disable VRFY.
*/
#define VAR_DISABLE_VRFY_CMD "disable_vrfy_command"
#define DEF_DISABLE_VRFY_CMD 0
extern bool var_disable_vrfy_cmd;
/*
* trivial rewrite/resolve service: mapping tables.
*/
@@ -819,7 +826,12 @@ extern int var_smtpd_delay_reject;
#define REJECT_UNAUTH_PIPE "reject_unauth_pipelining"
#define PERMIT_RCPT_MAP "permit_recipient_map"
/*
* Heuristic to reject most unknown recipients at the SMTP port.
*/
#define VAR_LOCAL_RCPT_MAPS "local_recipient_maps"
#define DEF_LOCAL_RCPT_MAPS ""
extern char *var_local_rcpt_maps;
/*
* Other.

View File

@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-19991211"
#define DEF_MAIL_VERSION "Snapshot-19991216"
extern char *var_mail_version;
/* LICENSE

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -487,9 +487,9 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
/*
* Bounce mail to non-existent users in virtual domains.
*/
if (!match_def_local_transport(STR(reply.transport))
&& qmgr_virtual != 0
&& (at = strrchr(recipient->address, '@')) != 0) {
if (qmgr_virtual != 0
&& (at = strrchr(recipient->address, '@')) != 0
&& !resolve_local(at + 1)) {
domain = lowercase(mystrdup(at + 1));
junk = maps_find(qmgr_virtual, domain, 0);
myfree(domain);

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -311,6 +311,7 @@ static void enqueue(const char *sender, const char *full_name, char **recipients
uid_t uid = getuid();
int status;
struct stat st;
int naddr;
/*
* Initialize.
@@ -323,10 +324,20 @@ static void enqueue(const char *sender, const char *full_name, char **recipients
* pickup would not be able to run chrooted, and it may not be desirable
* to use login names at all.
*/
if (sender == 0)
if (sender != 0) {
tree = tok822_parse(sender);
for (naddr = 0, tp = tree; tp != 0; tp = tp->next)
if (tp->type == TOK822_ADDR)
naddr++, tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
tok822_free_tree(tree);
saved_sender = mystrdup(STR(buf));
if (naddr > 1)
msg_warn("-f option specified malformed sender: %s", sender);
} else {
if ((sender = username()) == 0)
msg_fatal("unable to find out your login name");
saved_sender = mystrdup(sender);
saved_sender = mystrdup(sender);
}
/*
* Open the queue file. Save the queue file name, so the run-time error

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -79,6 +79,10 @@
/* Limit the number of \fBReceived:\fR message headers.
/* .IP \fBnotify_classes\fR
/* List of error classes. Of special interest are:
/* .IP \fBlocal_recipient_maps\fR
/* List of maps with user names that are local to \fB$myorigin\fR
/* or \fB$inet_interfaces\fR. If this parameter is defined,
/* then the SMTP server rejects mail for unknown local users.
/* .RS
/* .IP \fBpolicy\fR
/* When a client violates any policy, mail a transcript of the
@@ -290,6 +294,12 @@ char *var_error_rcpt;
int var_smtpd_delay_reject;
char *var_rest_classes;
int var_strict_rfc821_env;
bool var_disable_vrfy_cmd;
char *var_canonical_maps;
char *var_rcpt_canon_maps;
char *var_virtual_maps;
char *var_alias_maps;
char *var_local_rcpt_maps;
/*
* Global state, for stand-alone mode queue file cleanup. When this is
@@ -442,7 +452,7 @@ static void mail_open_stream(SMTPD_STATE *state)
/* extract_addr - extract address from rubble */
static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
int allow_empty_addr)
int allow_empty_addr, int strict_rfc821)
{
char *myname = "extract_addr";
TOK822 *tree;
@@ -501,7 +511,7 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
* Report trouble. Log a warning only if we are going to sleep+reject.
*/
if (naddr != 1
|| (var_strict_rfc821_env && (non_addr || *STR(arg->vstrval) != '<'))) {
|| (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) {
msg_warn("Illegal address syntax from %s in %s command: %s",
state->namaddr, state->where, STR(arg->vstrval));
err = "501 Bad address syntax";
@@ -562,7 +572,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "501 Bad address syntax");
return (-1);
}
if ((err = extract_addr(state, argv + 2, PERMIT_EMPTY_ADDR)) != 0) {
if ((err = extract_addr(state, argv + 2, PERMIT_EMPTY_ADDR, var_strict_rfc821_env)) != 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "%s", err);
return (-1);
@@ -669,7 +679,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "501 Bad address syntax");
return (-1);
}
if ((err = extract_addr(state, argv + 2, REJECT_EMPTY_ADDR)) != 0) {
if ((err = extract_addr(state, argv + 2, REJECT_EMPTY_ADDR, var_strict_rfc821_env)) != 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "%s", err);
return (-1);
@@ -684,6 +694,10 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "%s", err);
return (-1);
}
if ((err = smtpd_check_rcptmap(state, argv[2].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
}
/*
* Store the recipient. Remember the first one.
@@ -929,6 +943,13 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
* stop doing recipient restriction checks and lose the opportunity to
* say "user unknown" at the SMTP port.
*/
#define SLOPPY 0
if (var_disable_vrfy_cmd) {
state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "502 VRFY command is disabled");
return (-1);
}
if (argc < 2) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 Syntax: VRFY address");
@@ -936,22 +957,21 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
}
if (argc > 2)
collapse_args(argc - 1, argv + 1);
if ((err = extract_addr(state, argv + 1, REJECT_EMPTY_ADDR)) != 0) {
if ((err = extract_addr(state, argv + 1, REJECT_EMPTY_ADDR, SLOPPY)) != 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "%s", err);
return (-1);
}
if (SMTPD_STAND_ALONE(state) == 0)
err = smtpd_check_rcpt(state, argv[1].strval);
/*
* End untokenize.
*/
if (err != 0) {
if (SMTPD_STAND_ALONE(state) == 0
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
}
smtpd_chat_reply(state, "252 Send mail to find out");
if ((err = smtpd_check_rcptmap(state, argv[1].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
}
smtpd_chat_reply(state, "250 <%s>", argv[1].strval);
return (0);
}
@@ -1027,7 +1047,7 @@ static int quit_cmd(SMTPD_STATE *state, int unused_argc, SMTPD_TOKEN *unused_arg
typedef struct SMTPD_CMD {
char *name;
int (*action) (SMTPD_STATE *, int, SMTPD_TOKEN *);
} SMTPD_CMD;
} SMTPD_CMD;
static SMTPD_CMD smtpd_cmd_table[] = {
"HELO", helo_cmd,
@@ -1304,6 +1324,7 @@ int main(int argc, char **argv)
VAR_HELO_REQUIRED, DEF_HELO_REQUIRED, &var_helo_required,
VAR_SMTPD_DELAY_REJECT, DEF_SMTPD_DELAY_REJECT, &var_smtpd_delay_reject,
VAR_STRICT_RFC821_ENV, DEF_STRICT_RFC821_ENV, &var_strict_rfc821_env,
VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
0,
};
static CONFIG_STR_TABLE str_table[] = {
@@ -1320,6 +1341,11 @@ int main(int argc, char **argv)
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,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
0,
};

View File

@@ -138,10 +138,6 @@
/* 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_recipient_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.
@@ -302,24 +298,30 @@ static RESOLVE_REPLY reply;
static VSTRING *query;
static VSTRING *error_text;
/*
* Pre-opened SMTP recipient maps.
*/
static MAPS *local_rcpt_maps;
static MAPS *rcpt_canon_maps;
static MAPS *canonical_maps;
static MAPS *virtual_maps;
/*
* Pre-opened access control lists.
*/
static DOMAIN_LIST *relay_domains;
static NAMADR_LIST *mynetworks;
static DOMAIN_LIST *relay_domains;
static NAMADR_LIST *mynetworks;
/*
* Pre-parsed restriction lists.
*/
static ARGV *client_restrctions;
static ARGV *client_restrctions;
static ARGV *helo_restrctions;
static ARGV *mail_restrctions;
static ARGV *rcpt_restrctions;
static ARGV *etrn_restrctions;
static HTABLE *smtpd_rest_classes;
static HTABLE *smtpd_rcpt_maps;
static HTABLE *smtpd_rest_classes;
/*
* The routine that recursively applies restrictions.
@@ -383,6 +385,18 @@ void smtpd_check_init(void)
mynetworks = namadr_list_init(var_mynetworks);
relay_domains = domain_list_init(var_relay_domains);
/*
* Pre-parse and pre-open the recipient maps.
*/
local_rcpt_maps = maps_create(VAR_LOCAL_RCPT_MAPS, var_local_rcpt_maps,
DICT_FLAG_LOCK);
rcpt_canon_maps = maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps,
DICT_FLAG_LOCK);
canonical_maps = maps_create(VAR_CANONICAL_MAPS, var_canonical_maps,
DICT_FLAG_LOCK);
virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps,
DICT_FLAG_LOCK);
/*
* Reply is used as a cache for resolved addresses, and error_text is
* used for returning error responses.
@@ -424,16 +438,11 @@ void smtpd_check_init(void)
htable_enter("check_relay_domains",
smtpd_check_parse("permit_mydomain reject_unauth_destination"));
#endif
/*
* Other one-off initializations.
*/
smtpd_rcpt_maps = htable_create(1);
}
/* smtpd_check_reject - do the boring things that must be done */
static int smtpd_check_reject(SMTPD_STATE * state, int error_class,
static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
char *format,...)
{
va_list ap;
@@ -486,7 +495,7 @@ static int smtpd_check_reject(SMTPD_STATE * state, int error_class,
/* reject_unknown_client - fail if client hostname is unknown */
static int reject_unknown_client(SMTPD_STATE * state)
static int reject_unknown_client(SMTPD_STATE *state)
{
char *myname = "reject_unknown_client";
@@ -504,7 +513,7 @@ static int reject_unknown_client(SMTPD_STATE * state)
/* permit_mynetworks - succeed if client is in a trusted network */
static int permit_mynetworks(SMTPD_STATE * state)
static int permit_mynetworks(SMTPD_STATE *state)
{
char *myname = "permit_mynetworks";
@@ -537,7 +546,7 @@ static char *dup_if_truncate(char *name)
/* reject_invalid_hostaddr - fail if host address is incorrect */
static int reject_invalid_hostaddr(SMTPD_STATE * state, char *addr,
static int reject_invalid_hostaddr(SMTPD_STATE *state, char *addr,
char *reply_name, char *reply_class)
{
char *myname = "reject_invalid_hostaddr";
@@ -574,7 +583,7 @@ static int reject_invalid_hostaddr(SMTPD_STATE * state, char *addr,
/* reject_invalid_hostname - fail if host/domain syntax is incorrect */
static int reject_invalid_hostname(SMTPD_STATE * state, char *name,
static int reject_invalid_hostname(SMTPD_STATE *state, char *name,
char *reply_name, char *reply_class)
{
char *myname = "reject_invalid_hostname";
@@ -610,7 +619,7 @@ static int reject_invalid_hostname(SMTPD_STATE * state, char *name,
/* reject_non_fqdn_hostname - fail if host name is not in fqdn form */
static int reject_non_fqdn_hostname(SMTPD_STATE * state, char *name,
static int reject_non_fqdn_hostname(SMTPD_STATE *state, char *name,
char *reply_name, char *reply_class)
{
char *myname = "reject_non_fqdn_hostname";
@@ -646,7 +655,7 @@ static int reject_non_fqdn_hostname(SMTPD_STATE * state, char *name,
/* reject_unknown_hostname - fail if name has no A or MX record */
static int reject_unknown_hostname(SMTPD_STATE * state, char *name,
static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
char *reply_name, char *reply_class)
{
char *myname = "reject_unknown_hostname";
@@ -668,7 +677,7 @@ static int reject_unknown_hostname(SMTPD_STATE * state, char *name,
/* reject_unknown_mailhost - fail if name has no A or MX record */
static int reject_unknown_mailhost(SMTPD_STATE * state, char *name,
static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
char *reply_name, char *reply_class)
{
char *myname = "reject_unknown_mailhost";
@@ -690,7 +699,7 @@ static int reject_unknown_mailhost(SMTPD_STATE * state, char *name,
/* check_relay_domains - OK/FAIL for message relaying */
static int check_relay_domains(SMTPD_STATE * state, char *recipient,
static int check_relay_domains(SMTPD_STATE *state, char *recipient,
char *reply_name, char *reply_class)
{
char *myname = "check_relay_domains";
@@ -773,7 +782,7 @@ static int permit_auth_destination(char *recipient)
/* reject_unauth_destination - FAIL for message relaying */
static int reject_unauth_destination(SMTPD_STATE * state, char *recipient)
static int reject_unauth_destination(SMTPD_STATE *state, char *recipient)
{
char *myname = "reject_unauth_destination";
char *domain;
@@ -812,7 +821,7 @@ static int reject_unauth_destination(SMTPD_STATE * state, char *recipient)
/* reject_unauth_pipelining - reject improper use of SMTP command pipelining */
static int reject_unauth_pipelining(SMTPD_STATE * state)
static int reject_unauth_pipelining(SMTPD_STATE *state)
{
char *myname = "reject_unauth_pipelining";
@@ -872,7 +881,7 @@ static int has_my_addr(char *host)
/* permit_mx_backup - permit use of me as MX backup for recipient domain */
static int permit_mx_backup(SMTPD_STATE * unused_state, const char *recipient)
static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
{
char *myname = "permit_mx_backup";
char *domain;
@@ -957,7 +966,7 @@ static int permit_mx_backup(SMTPD_STATE * unused_state, const char *recipient)
/* reject_non_fqdn_address - fail if address is not in fqdn form */
static int reject_non_fqdn_address(SMTPD_STATE * state, char *addr,
static int reject_non_fqdn_address(SMTPD_STATE *state, char *addr,
char *reply_name, char *reply_class)
{
char *myname = "reject_non_fqdn_address";
@@ -1010,7 +1019,7 @@ static int reject_non_fqdn_address(SMTPD_STATE * state, char *addr,
/* reject_unknown_address - fail if address does not resolve */
static int reject_unknown_address(SMTPD_STATE * state, char *addr,
static int reject_unknown_address(SMTPD_STATE *state, char *addr,
char *reply_name, char *reply_class)
{
char *myname = "reject_unknown_address";
@@ -1043,70 +1052,16 @@ static int reject_unknown_address(SMTPD_STATE * state, char *addr,
return (reject_unknown_mailhost(state, domain, reply_name, reply_class));
}
/* permit_rcpt_map - permit if recipient address matches rewriting table */
static int permit_rcpt_map(char *table, char *reply_name)
{
char *myname = "permit_rcpt_map";
char *domain;
MAPS *map;
DICT *dict;
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 (!match_any_local_transport(STR(reply.transport)))
return (SMTPD_CHECK_DUNNO);
/*
* Look up the name in the specified table, using the usual magic of
* canonical and virtual maps. Be sure this map was declared in a main.cf
* restriction or restriction class. The maps must be opened before the
* process enters a chroot jail.
*
* XXX What follows is a kludge to wrap up the recipient map in a form
* usable by mail_addr_find(). Perhaps we should have a mail_addr_find()
* interface that will search just one map instead of a list of maps.
*/
if ((map = (MAPS *) htable_find(smtpd_rcpt_maps, table)) == 0) {
if ((dict = dict_handle(table)) == 0)
msg_panic("%s: dictionary not found: %s", myname, table);
map = maps_create("rcpt_map", "", DICT_FLAG_LOCK);
maps_append(map, table, dict);
htable_enter(smtpd_rcpt_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,
static int check_table_result(SMTPD_STATE *state, char *table,
const char *value, const char *datum,
char *reply_name, char *reply_class,
char *def_acl)
{
char *myname = "check_table_result";
int code;
ARGV *restrictions;
ARGV *restrictions;
int status;
if (msg_verbose)
@@ -1189,7 +1144,7 @@ static int check_table_result(SMTPD_STATE * state, char *table,
/* check_access - table lookup without substring magic */
static int check_access(SMTPD_STATE * state, char *table, char *name, int flags,
static int check_access(SMTPD_STATE *state, char *table, char *name, int flags,
char *reply_name, char *reply_class, char *def_acl)
{
char *myname = "check_access";
@@ -1219,7 +1174,7 @@ static int check_access(SMTPD_STATE * state, char *table, char *name, int flags,
/* check_domain_access - domainname-based table lookup */
static int check_domain_access(SMTPD_STATE * state, char *table,
static int check_domain_access(SMTPD_STATE *state, char *table,
char *domain, int flags,
char *reply_name, char *reply_class,
char *def_acl)
@@ -1259,7 +1214,7 @@ static int check_domain_access(SMTPD_STATE * state, char *table,
/* check_addr_access - address-based table lookup */
static int check_addr_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 *def_acl)
@@ -1296,7 +1251,7 @@ static int check_addr_access(SMTPD_STATE * state, char *table,
/* check_namadr_access - OK/FAIL based on host name/address lookup */
static int check_namadr_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 *def_acl)
@@ -1332,7 +1287,7 @@ 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,
static int check_mail_access(SMTPD_STATE *state, char *table, char *addr,
char *reply_name, char *reply_class,
char *def_acl)
{
@@ -1392,7 +1347,7 @@ static int check_mail_access(SMTPD_STATE * state, char *table, char *addr,
/* reject_maps_rbl - reject if client address in real-time blackhole list */
static int reject_maps_rbl(SMTPD_STATE * state)
static int reject_maps_rbl(SMTPD_STATE *state)
{
char *myname = "reject_maps_rbl";
ARGV *octets = argv_split(state->addr, ".");
@@ -1488,7 +1443,7 @@ static int is_map_command(char *name, char *command, char ***argp)
/* generic_checks - generic restrictions */
static int generic_checks(SMTPD_STATE * state, ARGV *restrictions,
static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
char *reply_name, char *reply_class, char *def_acl)
{
char *myname = "generic_checks";
@@ -1646,9 +1601,6 @@ static int generic_checks(SMTPD_STATE * state, ARGV *restrictions,
if (state->recipient)
status = reject_non_fqdn_address(state, state->recipient,
state->recipient, SMTPD_NAME_RECIPIENT);
} else if (is_map_command(name, PERMIT_RCPT_MAP, &cpp)) {
if (state->recipient)
status = permit_rcpt_map(*cpp, state->recipient);
}
/*
@@ -1690,7 +1642,7 @@ static int generic_checks(SMTPD_STATE * state, ARGV *restrictions,
/* smtpd_check_client - validate client name or address */
char *smtpd_check_client(SMTPD_STATE * state)
char *smtpd_check_client(SMTPD_STATE *state)
{
int status;
@@ -1714,7 +1666,7 @@ char *smtpd_check_client(SMTPD_STATE * state)
/* smtpd_check_helo - validate HELO hostname */
char *smtpd_check_helo(SMTPD_STATE * state, char *helohost)
char *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
{
int status;
char *saved_helo;
@@ -1760,7 +1712,7 @@ char *smtpd_check_helo(SMTPD_STATE * state, char *helohost)
/* smtpd_check_mail - validate sender address, driver */
char *smtpd_check_mail(SMTPD_STATE * state, char *sender)
char *smtpd_check_mail(SMTPD_STATE *state, char *sender)
{
int status;
char *saved_sender;
@@ -1796,7 +1748,7 @@ char *smtpd_check_mail(SMTPD_STATE * state, char *sender)
/* smtpd_check_rcpt - validate recipient address, driver */
char *smtpd_check_rcpt(SMTPD_STATE * state, char *recipient)
char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
{
int status;
char *saved_recipient;
@@ -1842,7 +1794,7 @@ char *smtpd_check_rcpt(SMTPD_STATE * state, char *recipient)
/* smtpd_check_etrn - validate ETRN request */
char *smtpd_check_etrn(SMTPD_STATE * state, char *domain)
char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
{
int status;
char *saved_etrn_name;
@@ -1885,9 +1837,78 @@ char *smtpd_check_etrn(SMTPD_STATE * state, char *domain)
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
/* smtpd_check_rcptmap - permit if recipient address matches lookup table */
char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
{
char *myname = "smtpd_check_rcptmap";
char *saved_recipient;
char *domain;
/*
* XXX This module does a lot of unnecessary guessing. The SMTP server
* (and presumably, pickup daemon) should run the envelopes through a
* rewriting service that does all the canonical and virtual mapping.
*/
if (msg_verbose)
msg_info("%s: %s", myname, 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.
*/
SMTPD_CHECK_PUSH(saved_recipient, state->recipient, recipient);
/*
* Resolve the address.
*/
canon_addr_internal(query, recipient);
resolve_clnt_query(STR(query), &reply);
/*
* Skip non-DNS forms. Skip non-local numerical forms.
*/
if ((domain = strrchr(STR(reply.recipient), '@')) == 0)
SMTPD_CHECK_RCPT_RETURN(0);
domain += 1;
if (domain[0] == '#' || domain[0] == '[')
if (!resolve_local(domain))
SMTPD_CHECK_RCPT_RETURN(0);
/*
* Reject mail to unknown addresses in domains that match $mydestination
* or $inet_interfaces (Postfix local). Reject mail to unknown addresses
* in Postfix virtual domains (Postfix virtual). Accept mail to other
* domains. Toss any extension information found by the lookup routines.
*/
#define NOP ((char **) 0)
if (resolve_local(domain)) {
if (*var_local_rcpt_maps
&& !mail_addr_find(rcpt_canon_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(canonical_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(local_rcpt_maps, STR(reply.recipient), NOP)) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"550 <%s>: User unknown", recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
} else {
if (*var_virtual_maps
&& !mail_addr_find(rcpt_canon_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(canonical_maps, STR(reply.recipient), NOP)
&& !mail_addr_find(virtual_maps, STR(reply.recipient), NOP)
&& maps_find(virtual_maps, domain, 0)) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"550 <%s>: User unknown", recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
}
SMTPD_CHECK_RCPT_RETURN(0);
}
/* smtpd_check_size - check optional SIZE parameter value */
char *smtpd_check_size(SMTPD_STATE * state, off_t size)
char *smtpd_check_size(SMTPD_STATE *state, off_t size)
{
char *myname = "smtpd_check_size";
struct fsspace fsbuf;
@@ -1963,7 +1984,7 @@ typedef struct {
char *name;
char *defval;
char **target;
} STRING_TABLE;
} STRING_TABLE;
static STRING_TABLE string_table[] = {
VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains,
@@ -2008,7 +2029,7 @@ typedef struct {
char *name;
int defval;
int *target;
} INT_TABLE;
} INT_TABLE;
int var_unk_client_code;
int var_bad_name_code;
@@ -2118,7 +2139,7 @@ static void rest_class(char *class)
/* resolve_clnt_init - initialize reply */
void resolve_clnt_init(RESOLVE_REPLY * reply)
void resolve_clnt_init(RESOLVE_REPLY *reply)
{
reply->transport = vstring_alloc(100);
reply->nexthop = vstring_alloc(100);
@@ -2127,7 +2148,7 @@ void resolve_clnt_init(RESOLVE_REPLY * reply)
/* canon_addr_internal - stub */
VSTRING *canon_addr_internal(VSTRING * result, const char *addr)
VSTRING *canon_addr_internal(VSTRING *result, const char *addr)
{
if (addr == STR(result))
msg_panic("canon_addr_internal: result clobbers input");
@@ -2138,7 +2159,7 @@ VSTRING *canon_addr_internal(VSTRING * result, const char *addr)
/* resolve_clnt_query - stub */
void resolve_clnt_query(const char *addr, RESOLVE_REPLY * reply)
void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
{
if (addr == STR(reply->recipient))
msg_panic("resolve_clnt_query: result clobbers input");
@@ -2151,7 +2172,7 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY * reply)
/* smtpd_chat_reset - stub */
void smtpd_chat_reset(SMTPD_STATE * unused_state)
void smtpd_chat_reset(SMTPD_STATE *unused_state)
{
}

View File

@@ -16,6 +16,7 @@ extern void smtpd_check_init(void);
extern char *smtpd_check_client(SMTPD_STATE *);
extern char *smtpd_check_helo(SMTPD_STATE *, char *);
extern char *smtpd_check_mail(SMTPD_STATE *, char *);
extern char *smtpd_check_rcptmap(SMTPD_STATE *, char *);
extern char *smtpd_check_size(SMTPD_STATE *, off_t);
extern char *smtpd_check_rcpt(SMTPD_STATE *, char *);
extern char *smtpd_check_etrn(SMTPD_STATE *, char *);

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR

View File

@@ -87,6 +87,7 @@
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
-TSMTPD_CMD
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTP_ADDR