From: Wietse Venema Date: Thu, 1 Jan 2004 05:00:00 +0000 (-0500) Subject: postfix-2.0.16-20040101 X-Git-Tag: v2.1-RC1-20040331~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f5ee7e4ada3ce42d3d4536988445fdd34c71674;p=thirdparty%2Fpostfix.git postfix-2.0.16-20040101 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 81bcad503..316d12058 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -8942,6 +8942,22 @@ Apologies for any names omitted. Bugfix: stricter address syntax test broke "sendmail -bs". File: smtpd/smtpd.c. +20040101 + + Cleanup: the Postfix SMTP server rejects a MAIL FROM address + that matches a local, virtual or relay domain, while the + address is not listed in the corresponding local, virtual + or relay recipient table. + + Feature: the reject_unlisted_sender(recipient) SMTPD access + restriction rejects an address that matches a local, virtual + or relay domain, while the address is not listed in the + corresponding local, virtual or relay recipient table. + + Compatibility: the check_recipient_maps restriction works + like reject_unlisted_recipient, but will eventually be + removed from Postfix. + Open problems: Low: in the SMTP client, pass the session, request and diff --git a/postfix/README_FILES/SMTPD_POLICY_README b/postfix/README_FILES/SMTPD_POLICY_README index 172243ec5..e59db0fd9 100644 --- a/postfix/README_FILES/SMTPD_POLICY_README +++ b/postfix/README_FILES/SMTPD_POLICY_README @@ -170,7 +170,9 @@ Greylisting mail from frequently forged domains ----------------------------------------------- It is relatively safe to turn on greylisting for specific domains -that often appear in forged email. +that often appear in forged email. However, sites like AOL may +blacklist you when they find that you are probing them too often +and/or if you're probing them too often for non-existent addresses. /etc/postfix/main.cf: smtpd_recipient_restrictions = @@ -229,7 +231,7 @@ database will eventually run your file system out of space. When the status file exceeds some reasonable size you can simply delete the file without adverse effects. In the worst case, new mail will be delayed by one hour. To lessen the impact, delete the -file in the middle of the night. +file in the middle of the night during a weekend. SAMPLE POLICY ROUTINE ===================== diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 1977e4107..09a6cf81d 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -22,6 +22,13 @@ snapshot release). Patches change the patchlevel and the release date. Snapshots change only the release date, unless they include the same bugfixes as a patch release. +Incompatible changes with Postfix snapshot 2.0.16-2004XXXX +========================================================== + +The SMTP server no longer accept sender addresses that match a +local, virtual or relay domain while the address is not listed in +the corresponding local, virtual or relay recipient table. + Incompatible changes with Postfix snapshot 2.0.16-20031226 ========================================================== diff --git a/postfix/conf/pcre_table b/postfix/conf/pcre_table index ff03d585b..b14e334c8 100644 --- a/postfix/conf/pcre_table +++ b/postfix/conf/pcre_table @@ -41,6 +41,8 @@ # # if /pattern/flags # +# endif +# # if !/pattern/flags # # endif Match the search string against the patterns diff --git a/postfix/conf/regexp_table b/postfix/conf/regexp_table index 56b7ad7db..75565b212 100644 --- a/postfix/conf/regexp_table +++ b/postfix/conf/regexp_table @@ -41,6 +41,8 @@ # # if /pattern/flags # +# endif +# # if !/pattern/flags # # endif Match the search string against the patterns diff --git a/postfix/conf/sample-smtpd.cf b/postfix/conf/sample-smtpd.cf index a1f9a2c05..4e421987f 100644 --- a/postfix/conf/sample-smtpd.cf +++ b/postfix/conf/sample-smtpd.cf @@ -491,11 +491,15 @@ smtpd_helo_restrictions = # The smtpd_sender_restrictions parameter specifies optional restrictions # on sender addresses that SMTP clients can send in MAIL FROM commands. # -# The default is to permit any sender address. The following -# restrictions are available: +# The default is to permit any sender address that passes the restrictions +# marked with (+). The following restrictions are available: # # permit_mynetworks: permit if the client address matches $mynetworks. # reject_unknown_sender_domain: reject sender domain without A or MX record. +# +reject_unlisted_sender: reject a sender address in a local, virtual or +# relay domain that is not listed as a valid address. +# This restriction is automatically added at the end if not explicitly +# specified. # reject_rhsbl_sender domain.tld: reject sender domain name if it is listed # in an A record under domain.tld. # check_sender_access maptype:mapname @@ -559,10 +563,13 @@ smtpd_sender_restrictions = # - destinations that match $virtual_mailbox_domains. # These destinations do not need to be listed in $relay_domains. # -# The following restrictions are available (* is part of default setting): +# The following restrictions are available (* is part of default setting, +# and + is appended by default if not explicitly specified): # # *permit_mynetworks: permit if the client address matches $mynetworks. # reject_unknown_sender_domain: reject sender domain without A or MX record. +# reject_unlisted_sender: reject a sender address in a local, virtual or +# relay domain that is not listed as a valid address. # reject_unverified_sender: reject undeliverable sender address. # reject_unverified_recipient: reject undeliverable recipient address. # reject_multi_recipient_bounce: reject mail from <> with multiple recipients. @@ -583,6 +590,12 @@ smtpd_sender_restrictions = # Use the optional permit_mx_backup_networks parameter to also # require that the primary MX hosts match a list of network blocks. # reject_unknown_recipient_domain: reject domains without A or MX record. +# +reject_unlisted_recipient: reject a recipient address in a local, virtual +# or relay domain that is not listed as a valid address. +# This restriction is automatically added at the end if not explicitly +# specified. +# +check_recipient_maps: a backwards compatibility alias for the +# reject_unlisted_recipient restriction. # check_recipient_access maptype:mapname # look up recipient address, parent domain, or localpart@. # see access(5) for possible lookup results. diff --git a/postfix/html/faq.html b/postfix/html/faq.html index a5ea4ecf2..fb9e7b0d4 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -153,8 +153,6 @@ distribution list
  • Postfix breaks the majordomo "approve" command -
  • Postfix does not try all the MX addresses -
  • Postfix accepts MAIL FROM and RCPT TO "| command" @@ -221,8 +219,6 @@ domains with "relay access denied"
  • Mail fails consistently with timeout or lost connection -
  • Postfix does not try all the MX addresses -
  • What does "fatal: unknown service: smtp/tcp" mean?
  • Mail delivery fails with: "unknown @@ -1906,21 +1902,6 @@ and convince the person responsible for it to fix the configuration.
    -

    Postfix does not try all the MX -addresses

    - -When delivering mail, Postfix tries all MX addresses in order of -preference, and stops at the first server that speaks SMTP. However, -once an SMTP greeting is received, Postfix will not move on to the -next MX host if the delivery fails. - -

    - -This will eventually be solved when Postfix implements SMTP -connection caching. - -


    -

    What does "fatal: unknown service: smtp/tcp" mean?

    diff --git a/postfix/html/pcre_table.5.html b/postfix/html/pcre_table.5.html index 32155442a..3e17b5f75 100644 --- a/postfix/html/pcre_table.5.html +++ b/postfix/html/pcre_table.5.html @@ -42,6 +42,8 @@ PCRE_TABLE(5) PCRE_TABLE(5) if /pattern/flags + endif + if !/pattern/flags endif Match the search string against the patterns diff --git a/postfix/html/regexp_table.5.html b/postfix/html/regexp_table.5.html index a0ab127b8..90fb8029a 100644 --- a/postfix/html/regexp_table.5.html +++ b/postfix/html/regexp_table.5.html @@ -1,4 +1,4 @@ -
    +  
     REGEXP_TABLE(5)                                   REGEXP_TABLE(5)
     
     NAME
    @@ -42,6 +42,8 @@ REGEXP_TABLE(5)                                   REGEXP_TABLE(5)
     
            if /pattern/flags
     
    +       endif
    +
            if !/pattern/flags
     
            endif  Match   the  search  string  against  the  patterns
    diff --git a/postfix/html/uce.html b/postfix/html/uce.html
    index afa38f2d0..9498a5697 100644
    --- a/postfix/html/uce.html
    +++ b/postfix/html/uce.html
    @@ -815,6 +815,42 @@ the MAIL FROM command.
     
     

    + + +

    reject_unlisted_sender
    Reject the request when +the sender address matches one of the domain lists below, but +is not listed in one of the corresponding address lists: + +
    + + + + + + + + + + + + + + +
    Domain list Address list
    $mydestination or +$inet_interfaces$local_recipient_maps
    $virtual_alias_domains $virtual_alias_maps
    $virtual_mailbox_domains $virtual_mailbox_maps
    $relay_domains $relay_recipient_maps
    + +
    + +Note 1: a null $local_recipient_maps or $relay_recipient_maps setting +means that no address check is done for the corresponding domains. + +

    + +Note 2: Postfix applies an implicit reject_unlisted_sender +restriction at the end of all sender restrictions. + +

    +

    reject_non_fqdn_sender
    Reject the request when @@ -1062,17 +1098,17 @@ with the RCPT TO command.

    - + -

    check_recipient_maps
    Reject the request -when the recipient address is not listed in one of the following -lookup tables: +
    reject_unlisted_recipient
    Reject the request when +the recipient address matches one of the domain lists below, but +is not listed in one of the corresponding lookup tables:
    - + @@ -1089,15 +1125,21 @@ lookup tables: Note 1: a null $local_recipient_maps or $relay_recipient_maps setting -means that no recipient check is done for the corresponding domains. +means that no address check is done for the corresponding domains.

    -Note 2: Postfix applies an implicit check_recipient_maps +Note 2: Postfix applies an implicit reject_unlisted_recipient restriction at the end of all recipient restrictions.

    +Note 3: the check_recipient_maps restriction is a backwards +compatible alias for reject_unlisted_recipient. It will +eventually be removed from Postfix. + +

    +

    reject_multi_recipient_bounce
    Reject the request diff --git a/postfix/man/man5/pcre_table.5 b/postfix/man/man5/pcre_table.5 index 2b05c2fe4..a4d703260 100644 --- a/postfix/man/man5/pcre_table.5 +++ b/postfix/man/man5/pcre_table.5 @@ -41,6 +41,7 @@ are lines whose first non-whitespace character is a `#'. A logical line starts with non-whitespace text. A line that starts with whitespace continues a logical line. .IP "\fBif /\fIpattern\fB/\fIflags\fR" +.IP "\fBendif\fR" .IP "\fBif !/\fIpattern\fB/\fIflags\fR" .IP "\fBendif\fR" Match the search string against the patterns between \fBif\fR diff --git a/postfix/man/man5/regexp_table.5 b/postfix/man/man5/regexp_table.5 index 5b9b078e1..03bcc7cc7 100644 --- a/postfix/man/man5/regexp_table.5 +++ b/postfix/man/man5/regexp_table.5 @@ -41,6 +41,7 @@ are lines whose first non-whitespace character is a `#'. A logical line starts with non-whitespace text. A line that starts with whitespace continues a logical line. .IP "\fBif /\fIpattern\fB/\fIflags\fR" +.IP "\fBendif\fR" .IP "\fBif !/\fIpattern\fB/\fIflags\fR" .IP "\fBendif\fR" Match the search string against the patterns between \fBif\fR diff --git a/postfix/proto/pcre_table b/postfix/proto/pcre_table index 0ace904da..b182b54c8 100644 --- a/postfix/proto/pcre_table +++ b/postfix/proto/pcre_table @@ -33,6 +33,7 @@ # A logical line starts with non-whitespace text. A line that # starts with whitespace continues a logical line. # .IP "\fBif /\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" # .IP "\fBif !/\fIpattern\fB/\fIflags\fR" # .IP "\fBendif\fR" # Match the search string against the patterns between \fBif\fR diff --git a/postfix/proto/regexp_table b/postfix/proto/regexp_table index ca4b94067..e12b0f789 100644 --- a/postfix/proto/regexp_table +++ b/postfix/proto/regexp_table @@ -33,6 +33,7 @@ # A logical line starts with non-whitespace text. A line that # starts with whitespace continues a logical line. # .IP "\fBif /\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" # .IP "\fBif !/\fIpattern\fB/\fIflags\fR" # .IP "\fBendif\fR" # Match the search string against the patterns between \fBif\fR diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 4d5ee846d..6ab8730f4 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1315,6 +1315,8 @@ extern int var_non_fqdn_code; #define REJECT_UNKNOWN_SENDDOM "reject_unknown_sender_domain" #define REJECT_UNKNOWN_RCPTDOM "reject_unknown_recipient_domain" #define REJECT_UNKNOWN_ADDRESS "reject_unknown_address" +#define REJECT_UNLISTED_SENDER "reject_unlisted_sender" +#define REJECT_UNLISTED_RCPT "reject_unlisted_recipient" #define CHECK_RCPT_MAPS "check_recipient_maps" #define VAR_UNK_ADDR_CODE "unknown_address_reject_code" #define DEF_UNK_ADDR_CODE 450 diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 734fd52db..c7e7a0bba 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ -#define MAIL_RELEASE_DATE "20031231" +#define MAIL_RELEASE_DATE "20040101" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE diff --git a/postfix/src/global/resolve_clnt.h b/postfix/src/global/resolve_clnt.h index d96ea1863..ace680731 100644 --- a/postfix/src/global/resolve_clnt.h +++ b/postfix/src/global/resolve_clnt.h @@ -36,6 +36,10 @@ #define RESOLVE_CLASS_FINAL \ (RESOLVE_CLASS_LOCAL | RESOLVE_CLASS_ALIAS | RESOLVE_CLASS_VIRTUAL) +#define RESOLVE_CLASS_MASK \ + (RESOLVE_CLASS_LOCAL | RESOLVE_CLASS_ALIAS | RESOLVE_CLASS_VIRTUAL \ + | RESOLVE_CLASS_RELAY | RESOLVE_CLASS_DEFAULT) + typedef struct RESOLVE_REPLY { VSTRING *transport; VSTRING *nexthop; diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 9c9bea0a6..c5bbe139d 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -106,7 +106,8 @@ typedef struct SMTPD_STATE { /* * Specific to smtpd access checks. */ - int rcptmap_checked; + int sender_rcptmap_checked; /* sender validated against maps */ + int recipient_rcptmap_checked; /* recipient validated against maps */ int warn_if_reject; /* force reject into warning */ SMTPD_DEFER defer_if_reject; /* force reject into deferral */ SMTPD_DEFER defer_if_permit; /* force permit into deferral */ diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index dda63db50..79255a53d 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -107,9 +107,12 @@ /* Apply the specified access table to the DNS server host name and IP /* addresses for the helo hostname, sender, or recipient, respectively. /* If no NS record is found, the parent domain is used instead. -/* .IP "check_recipient_maps" -/* Reject recipients not listed as valid local, virtual or relay -/* recipients. +/* .IP "reject_unlisted_sender" +/* Reject senders in local, virtual or relay domains that are not +/* listed as a valid address. +/* .IP "reject_unlisted_recipient" +/* Reject recipients in local, virtual or relay domains that are +/* not listed as a valid address. /* .IP reject_multi_recipient_bounce /* Reject mail from <> with multiple envelope recipients. /* .IP reject_rbl_client rbl.domain.tld @@ -442,7 +445,9 @@ static int generic_checks(SMTPD_STATE *, ARGV *, const char *, const char *, con /* * Recipient table check. */ -static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient); +static int check_sender_rcpt_maps(SMTPD_STATE *, const char *); +static int check_recipient_rcpt_maps(SMTPD_STATE *, const char *); +static int check_rcpt_maps(SMTPD_STATE *, const char *, const char *); /* * Reject context. @@ -3282,6 +3287,9 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, status = reject_rbl_domain(state, *cpp, state->sender, SMTPD_NAME_SENDER); } + } else if (strcasecmp(name, REJECT_UNLISTED_SENDER) == 0) { + if (state->sender && *state->sender) + status = check_sender_rcpt_maps(state, state->sender); } /* @@ -3348,9 +3356,10 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, status = reject_rbl_domain(state, *cpp, state->recipient, SMTPD_NAME_RECIPIENT); } - } else if (strcasecmp(name, CHECK_RCPT_MAPS) == 0) { + } else if (strcasecmp(name, CHECK_RCPT_MAPS) == 0 + || strcasecmp(name, REJECT_UNLISTED_RCPT) == 0) { if (state->recipient && *state->recipient) - status = check_rcpt_maps(state, state->recipient); + status = check_recipient_rcpt_maps(state, state->recipient); } else if (strcasecmp(name, REJECT_MUL_RCPT_BOUNCE) == 0) { if (state->sender && *state->sender == 0 && state->rcpt_count > (strcmp(state->where, "DATA") ? 0 : 1)) @@ -3416,7 +3425,6 @@ int smtpd_check_addr(const char *addr) { const RESOLVE_REPLY *resolve_reply; char *myname = "smtpd_check_addr"; - int status; if (msg_verbose) msg_info("%s: addr=%s", myname, addr); @@ -3556,6 +3564,7 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) */ state->defer_if_permit.active = state->defer_if_permit_client | state->defer_if_permit_helo; + state->sender_rcptmap_checked = 0; /* * Apply restrictions in the order as specified. @@ -3567,6 +3576,14 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) SMTPD_NAME_SENDER, CHECK_SENDER_ACL); state->defer_if_permit_sender = state->defer_if_permit.active; + /* + * 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->sender_rcptmap_checked == 0 + && state->discard == 0 && *sender) + status = check_sender_rcpt_maps(state, sender); + SMTPD_CHECK_MAIL_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } @@ -3623,7 +3640,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) * The "check_recipient_maps" restriction is relevant only when * responding to RCPT TO or VRFY. */ - state->rcptmap_checked = 0; + state->recipient_rcptmap_checked = 0; /* * Apply delayed restrictions. @@ -3662,9 +3679,9 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) * 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 + if (status != SMTPD_CHECK_REJECT && state->recipient_rcptmap_checked == 0 && state->discard == 0) - status = check_rcpt_maps(state, recipient); + status = check_recipient_rcpt_maps(state, recipient); SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } @@ -3730,11 +3747,10 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain) SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } -/* check_rcpt_maps - generic_checks() interface for recipient table check */ +/* check_recipient_rcpt_maps - generic_checks() recipient table check */ -static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) +static int check_recipient_rcpt_maps(SMTPD_STATE *state, const char *recipient) { - const RESOLVE_REPLY *reply; /* * Duplicate suppression. There's an implicit check_recipient_maps @@ -3742,9 +3758,35 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) */ if (smtpd_input_transp_mask & INPUT_TRANSP_UNKNOWN_RCPT) return (0); - if (state->rcptmap_checked == 1) + if (state->recipient_rcptmap_checked == 1) + return (0); + state->recipient_rcptmap_checked = 1; + return (check_rcpt_maps(state, recipient, SMTPD_NAME_RECIPIENT)); +} + +/* check_sender_rcpt_maps - generic_checks() sender table check */ + +static int check_sender_rcpt_maps(SMTPD_STATE *state, const char *sender) +{ + + /* + * Duplicate suppression. There's an implicit check_sender_maps + * restriction at the end of all sender restrictions. + */ + if (smtpd_input_transp_mask & INPUT_TRANSP_UNKNOWN_RCPT) + return (0); + if (state->sender_rcptmap_checked == 1) return (0); - state->rcptmap_checked = 1; + state->sender_rcptmap_checked = 1; + return (check_rcpt_maps(state, sender, SMTPD_NAME_SENDER)); +} + +/* check_rcpt_maps - generic_checks() interface for recipient table check */ + +static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient, + const char *reply_class) +{ + const RESOLVE_REPLY *reply; if (msg_verbose) msg_info(">>> CHECKING RECIPIENT MAPS <<<"); @@ -3788,10 +3830,11 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) */ if (strcmp(STR(reply->transport), MAIL_SERVICE_ERROR) == 0) return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, - "%d <%s>: %s", + "%d <%s>: %s rejected: %s", (reply->flags & RESOLVE_CLASS_ALIAS) ? var_virt_alias_code : 550, - recipient, STR(reply->nexthop))); + recipient, reply_class, + STR(reply->nexthop))); /* * Reject mail to unknown addresses in local domains (domains that match @@ -3807,52 +3850,60 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) */ #define MATCH_LEFT(l, r, n) (strncasecmp((l), (r), (n)) == 0 && (r)[n] == '@') - if ((reply->flags & RESOLVE_CLASS_LOCAL) - && *var_local_rcpt_maps - /* Generated by bounce, absorbed by qmgr. */ + switch (reply->flags & RESOLVE_CLASS_MASK) { + + case RESOLVE_CLASS_LOCAL: + if (*var_local_rcpt_maps + /* Generated by bounce, absorbed by qmgr. */ && !MATCH_LEFT(var_double_bounce_sender, CONST_STR(reply->recipient), strlen(var_double_bounce_sender)) - /* Absorbed by qmgr. */ - && !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient), - strlen(MAIL_ADDR_POSTMASTER)) - /* 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))) - return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, - "%d <%s>: User unknown%s", - var_local_rcpt_code, recipient, - var_show_unk_rcpt_table ? - " in local recipient table" : "")); + /* Absorbed by qmgr. */ + && !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient), + strlen(MAIL_ADDR_POSTMASTER)) + /* 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))) + return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, + "%d <%s>: %s rejected: User unknown%s", + var_local_rcpt_code, recipient, + reply_class, var_show_unk_rcpt_table ? + " in local recipient table" : "")); + break; - /* - * Reject mail to unknown addresses in virtual mailbox domains. - */ - if ((reply->flags & RESOLVE_CLASS_VIRTUAL) - && *var_virt_mailbox_maps - && NOMATCH(virt_mailbox_maps, CONST_STR(reply->recipient))) - return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, - "%d <%s>: User unknown%s", - var_virt_mailbox_code, recipient, - var_show_unk_rcpt_table ? - " in virtual mailbox table" : "")); + /* + * Reject mail to unknown addresses in virtual mailbox domains. + */ + case RESOLVE_CLASS_VIRTUAL: + if (*var_virt_mailbox_maps + && NOMATCH(virt_mailbox_maps, CONST_STR(reply->recipient))) + return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, + "%d <%s>: %s rejected: User unknown%s", + var_virt_mailbox_code, recipient, + reply_class, var_show_unk_rcpt_table ? + " in virtual mailbox table" : "")); + break; - /* - * Reject mail to unknown addresses in relay domains. - */ - if ((reply->flags & RESOLVE_CLASS_RELAY) - && *var_relay_rcpt_maps - && NOMATCH(relay_rcpt_maps, CONST_STR(reply->recipient))) - return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, - "%d <%s>: User unknown%s", - var_relay_rcpt_code, recipient, - var_show_unk_rcpt_table ? - " in relay recipient table" : "")); + /* + * Reject mail to unknown addresses in relay domains. + */ + case RESOLVE_CLASS_RELAY: + if (*var_relay_rcpt_maps + && NOMATCH(relay_rcpt_maps, CONST_STR(reply->recipient))) + return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, + "%d <%s>: %s rejected: User unknown%s", + var_relay_rcpt_code, recipient, + reply_class, var_show_unk_rcpt_table ? + " in relay recipient table" : "")); + break; - /* - * Accept all other addresses - including addresses that passed the above - * tests because of some table lookup problem. - */ + /* + * Accept all other addresses - including addresses that passed the + * above tests because of some table lookup problem. + */ + default: + break; + } return (0); }
    Recipient domain matches Recipient lookup table
    Domain list Address list
    $mydestination or $inet_interfaces