diff options
| author | heas <heas@NetBSD.org> | 2004-03-27 16:31:19 +0000 |
|---|---|---|
| committer | heas <heas@NetBSD.org> | 2004-03-27 16:31:19 +0000 |
| commit | f32166d8a91a2c82316a00a40ee4842e27ec245d (patch) | |
| tree | 23fa8e0342da03f7dc80d4e582d0351d2a2f3724 /gnu/dist/postfix/src/smtpd | |
| parent | 5f1ffa71fcd47bffcc5eb3f23221d6570b558e8f (diff) | |
merge from 2.0.19 import
Diffstat (limited to 'gnu/dist/postfix/src/smtpd')
| -rw-r--r-- | gnu/dist/postfix/src/smtpd/smtpd.c | 49 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtpd/smtpd_check.c | 112 |
2 files changed, 101 insertions, 60 deletions
diff --git a/gnu/dist/postfix/src/smtpd/smtpd.c b/gnu/dist/postfix/src/smtpd/smtpd.c index 185ddd22777..4fd11947101 100644 --- a/gnu/dist/postfix/src/smtpd/smtpd.c +++ b/gnu/dist/postfix/src/smtpd/smtpd.c @@ -59,7 +59,7 @@ /* Disallow non-RFC 821 style addresses in SMTP commands. For example, /* the RFC822-style address forms with comments that Sendmail allows. /* .IP \fBbroken_sasl_auth_clients\fR -/* Support older Microsoft clients that mis-implement the AUTH +/* Support Microsoft clients that implement an older version of the AUTH /* protocol, and that expect an EHLO response of "250 AUTH=list" /* instead of "250 AUTH list". /* .IP \fBsmtpd_noop_commands\fR @@ -73,7 +73,7 @@ /* This parameter uses the same syntax as the right-hand side of /* a Postfix transport table. /* .SH "Authentication controls" -/* .IP \fBenable_sasl_authentication\fR +/* .IP \fBsmtpd_sasl_auth_enable\fR /* Enable per-session authentication as per RFC 2554 (SASL). /* This functionality is available only when explicitly selected /* at program build time and explicitly enabled at runtime. @@ -629,7 +629,9 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg, int naddr; int non_addr; char *err = 0; - char *junk; + char *junk = 0; + char *text; + char *colon; /* * Special case. @@ -653,11 +655,19 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg, msg_info("%s: input: %s", myname, STR(arg->vstrval)); if (STR(arg->vstrval)[0] == '<' && STR(arg->vstrval)[LEN(arg->vstrval) - 1] == '>') { - junk = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2); - tree = tok822_parse(junk); - myfree(junk); + junk = text = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2); } else - tree = tok822_parse(STR(arg->vstrval)); + text = STR(arg->vstrval); + + /* + * Truncate deprecated route address form. + */ + if (*text == '@' && (colon = strchr(text, ':')) != 0) + text = colon + 1; + tree = tok822_parse(text); + + if (junk) + myfree(junk); /* * Find trouble. @@ -796,7 +806,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) verp_delims = arg + VERP_CMD_LEN + 1; if (verp_delims_verify(verp_delims) != 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; - smtpd_chat_reply(state, "501 %s needs two characters from %s", + smtpd_chat_reply(state, "501 Error: %s needs two characters from %s", VERP_CMD, var_verp_filter); return (-1); } @@ -808,7 +818,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) } } if (verp_delims && argv[2].strval[0] == 0) { - smtpd_chat_reply(state, "503 Error: XVERP requires non-null sender"); + smtpd_chat_reply(state, "503 Error: %s requires non-null sender", + VERP_CMD); return (-1); } state->time = time((time_t *) 0); @@ -837,10 +848,12 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) /* * Record the time of arrival and the sender envelope address. */ - rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld", - (long) time((time_t *) 0)); - if (*var_filter_xport) - rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport); + if (SMTPD_STAND_ALONE(state) == 0) { + rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld", + (long) time((time_t *) 0)); + if (*var_filter_xport) + rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport); + } rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval); if (encoding != 0) rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", @@ -893,6 +906,7 @@ static void mail_reset(SMTPD_STATE *state) if (var_smtpd_sasl_enable) smtpd_sasl_mail_reset(state); #endif + state->discard = 0; } /* rcpt_cmd - process RCPT TO command */ @@ -951,10 +965,6 @@ 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); - } } /* @@ -1259,7 +1269,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) return (-1); } if (SMTPD_STAND_ALONE(state) == 0 - && (err = smtpd_check_rcptmap(state, argv[1].strval)) != 0) { + && (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) { smtpd_chat_reply(state, "%s", err); return (-1); } @@ -1463,7 +1473,8 @@ static void smtpd_proto(SMTPD_STATE *state) break; case 0: - if (var_smtpd_delay_reject == 0 + if (SMTPD_STAND_ALONE(state) == 0 + && var_smtpd_delay_reject == 0 && (state->access_denied = smtpd_check_client(state)) != 0) { smtpd_chat_reply(state, "%s", state->access_denied); } else { diff --git a/gnu/dist/postfix/src/smtpd/smtpd_check.c b/gnu/dist/postfix/src/smtpd/smtpd_check.c index 678a86f0b04..755e551a7ae 100644 --- a/gnu/dist/postfix/src/smtpd/smtpd_check.c +++ b/gnu/dist/postfix/src/smtpd/smtpd_check.c @@ -24,10 +24,6 @@ /* SMTPD_STATE *state; /* char *recipient; /* -/* char *smtpd_check_rcptmap(state, recipient) -/* SMTPD_STATE *state; -/* char *recipient; -/* /* char *smtpd_check_etrn(state, destination) /* SMTPD_STATE *state; /* char *destination; @@ -192,11 +188,7 @@ /* .IP smtpd_recipient_restrictions /* Restrictions on the recipient address that is sent with the RCPT /* TO command. -/* .PP -/* smtpd_check_rcptmap() validates the recipient address provided -/* with an RCPT TO request and sets the rcptmap_checked flag. -/* Relevant configuration parameters: -/* .IP local_recipients_map +/* .IP local_recipient_maps /* Tables of user names (not addresses) that exist in $mydestination. /* Mail for local users not in these tables is rejected. /* .PP @@ -795,6 +787,13 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, va_end(ap); /* + * Ensure RFC compliance. We could do this inside smtpd_chat_reply() and + * switch to multi-line for long replies. + */ + vstring_truncate(error_text, 510); + VSTRING_TERMINATE(error_text); + + /* * Validate the response, that is, the response must begin with a * three-digit status code, and the first digit must be 4 or 5. If the * response is bad, log a warning and send a generic response instead. @@ -1622,6 +1621,31 @@ static int reject_unknown_address(SMTPD_STATE *state, const char *addr, return (reject_unknown_mailhost(state, domain, reply_name, reply_class)); } +/* warn_skip_access_action - FILTER etc. action in unsupported context */ + +static void warn_skip_access_action(const char *table, const char *action, + const char *reply_class) +{ + + /* + * Warn only about FILTER/HOLD/etc. access table actions that appear in + * restrictions where they will always be ignored. + */ + if (strcmp(reply_class, SMTPD_NAME_CLIENT) == 0 + || strcmp(reply_class, SMTPD_NAME_HELO) == 0 + || strcmp(reply_class, SMTPD_NAME_SENDER) == 0) { + if (var_smtpd_delay_reject == 0) + msg_warn("access table %s: with %s=%s, " + "action %s is always skipped in %s restrictions", + table, VAR_SMTPD_DELAY_REJECT, CONFIG_BOOL_NO, + action, reply_class); + } else { + msg_warn("access table %s: action %s is always " + "skipped in %s restrictions", + table, action, reply_class); + } +} + /* check_table_result - translate table lookup result into pass/reject */ static int check_table_result(SMTPD_STATE *state, const char *table, @@ -1673,6 +1697,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table, * mind, and reject/discard the message for other reasons. */ if (STREQUAL(value, "FILTER", cmd_len)) { +#ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "FILTER", reply_class); + return (SMTPD_CHECK_DUNNO); + } +#endif if (*cmd_text == 0) { msg_warn("access map %s entry \"%s\" has FILTER entry without value", table, datum); @@ -1697,6 +1727,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table, * reject/discard the message for other reasons. */ if (STREQUAL(value, "HOLD", cmd_len)) { +#ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "HOLD", reply_class); + return (SMTPD_CHECK_DUNNO); + } +#endif vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers HOLD action"); log_whatsup(state, "hold", STR(error_text)); @@ -1709,17 +1745,21 @@ static int check_table_result(SMTPD_STATE *state, const char *table, /* * DISCARD means silently discard and claim successful delivery. - * - * XXX Set some global flag that disables all further restrictions. - * Triggering a "reject" or "hold" action after "discard" is silly. */ if (STREQUAL(value, "DISCARD", cmd_len)) { +#ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "DISCARD", reply_class); + return (SMTPD_CHECK_DUNNO); + } +#endif vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers DISCARD action"); log_whatsup(state, "discard", STR(error_text)); #ifndef TEST rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", CLEANUP_FLAG_DISCARD); + state->discard = 1; #endif return (SMTPD_CHECK_OK); } @@ -2548,6 +2588,9 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, for (cpp = restrictions->argv; (name = *cpp) != 0; cpp++) { + if (state->discard != 0) + break; + if (msg_verbose) msg_info("%s: name=%s", myname, name); @@ -2998,10 +3041,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) /* * The "check_recipient_maps" restriction is relevant only when - * responding to RCPT TO. It's effectively disabled with DATA (recipient - * context is explicitly turned off) and not applicable with undelayed - * client/helo/sender restrictions (no recipient info) or with ETRN - * (command not allowed in the middle of an ongoing MAIL transaction). + * responding to RCPT TO or VRFY. */ state->rcptmap_checked = 0; @@ -3027,7 +3067,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) SMTPD_CHECK_RESET(); status = setjmp(smtpd_check_buf); if (status == 0 && rcpt_restrctions->argc) - status = generic_checks(state, rcpt_restrctions, + status = generic_checks(state, rcpt_restrctions, recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL); /* @@ -3038,6 +3078,14 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) status = smtpd_check_reject(state, state->defer_if_permit.class, "%s", STR(state->defer_if_permit.reason)); + /* + * If the "check_recipient_maps" restriction was not applied, and if mail + * is not being rejected or discarded, validate the recipient here. + */ + if (status != SMTPD_CHECK_REJECT && state->rcptmap_checked == 0 + && state->discard == 0) + status = check_rcpt_maps(state, recipient); + SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } @@ -3102,25 +3150,6 @@ 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"; - int status; - - if (msg_verbose) - msg_info("%s: %s", myname, recipient); - - /* - * Return here in case of serious trouble. - */ - if ((status = setjmp(smtpd_check_buf)) == 0) - status = check_rcpt_maps(state, recipient); - - return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); -} - /* check_rcpt_maps - generic_checks() interface for recipient table check */ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) @@ -3198,13 +3227,13 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) if ((reply->flags & RESOLVE_CLASS_LOCAL) && *var_local_rcpt_maps - /* Generated by bounce, absorbed by qmgr. */ + /* Generated by bounce, absorbed by qmgr. */ && !MATCH_LEFT(var_double_bounce_sender, CONST_STR(reply->recipient), strlen(var_double_bounce_sender)) - /* Absorbed by qmgr. */ + /* Absorbed by qmgr. */ && !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient), strlen(MAIL_ADDR_POSTMASTER)) - /* Generated by bounce. */ + /* Generated by bounce. */ && !MATCH_LEFT(MAIL_ADDR_MAIL_DAEMON, CONST_STR(reply->recipient), strlen(MAIL_ADDR_MAIL_DAEMON)) && NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) @@ -3486,6 +3515,7 @@ int var_local_rcpt_code; int var_relay_rcpt_code; int var_virt_mailbox_code; int var_virt_alias_code; +int var_show_unk_rcpt_table; static INT_TABLE int_table[] = { "msg_verbose", 0, &msg_verbose, @@ -3505,6 +3535,7 @@ static INT_TABLE int_table[] = { VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code, VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, + VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table, 0, }; @@ -3883,8 +3914,7 @@ int main(int argc, char **argv) } else if (strcasecmp(args->argv[0], "rcpt") == 0) { state.where = "RCPT"; TRIM_ADDR(args->argv[1], addr); - (resp = smtpd_check_rcpt(&state, addr)) - || (resp = smtpd_check_rcptmap(&state, addr)); + resp = smtpd_check_rcpt(&state, addr); } break; |
