divert(-1) # Copyright (c) 2004 by Mark Kramer # All rights reserved. # Copyright (c) 1988, 1993 # The Regents of the University of California. All rights reserved. # # By using this file, you agree to the terms and conditions set # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # # # # some modifications 2004 by Victor Ustugov aka corvax # dnl # опционально можно указать пути к скриптам: dnl # define(`confSRS_ENVFROM2SRC', `/usr/local/scripts/SRS/envfrom2srs.pl')dnl dnl # define(`confSRS_REVERSE_SRC', `/usr/local/scripts/SRS/srs2envtol.pl')dnl dnl # dnl # в качестве первого параметра hack'а нужно указать домен, используемый для SRS dnl # (указан в confSRS_ENVFROM2SRC в качестве $fwdomain) dnl # этот домен должен быть указан в классе $w dnl # пример: dnl # HACK(`perlsrs', `srs.domain.tld') dnl # dnl # домены, адреса из которых не будут переписаны: dnl # LOCAL - не будут переписываться адреса из доменов, перечисленных dnl # в классе $w (local-host-names) dnl # RELAY_DOMAINS - не будут переписываться адреса из доменов, перечисленных dnl # в классе $R (relay-domains) dnl # FILE - не переписываться адреса из доменов, перечисленных в указанном файле dnl # значения можно перечислять в виде списка с пробелом в качестве разделителя dnl # пример: dnl # define(`confSRS_DOMAINS_SKIP', `LOCAL RELAY_DOMAINS')dnl dnl # имя файла с доменами, адреса которых не надо переписывать dnl # define(`confSRS_DOMAINS_SKIP_FILE', `/etc/mail/domains-srs-skip')dnl dnl # если будет указано относительное имя файла, к нему будет добавлен домен MAIL_SETTINGS_DIR (/etc/mail) dnl # если в параметре confSRS_DOMAINS_SKIP будет присутствовать значение `FILE', а dnl # значение confSRS_DOMAINS_SKIP_FILE будет пустым или неопределенным, то будет исползовано dnl # имя файла domains-srs-skip dnl # dnl # при изменении политики исключений при переписывании адресов отправителя dnl # может возникнуть ситуация, при которой будет необходимо проверять валидность dnl # приема bounce message на неподписанный адрес по набору старых исключений. dnl # dnl # например, ранее переписывались все адреса, кроме локальных доменов ($w) и dnl # рилеемых доменов ($R). dnl # впоследствии было принято решение не переписывать адреса dnl # только локальных доменов. dnl # после перегенерации sendmail.cf может возникнуть ситуация, при которой мы dnl # получим bounce message на неподписанный адрес из рилеемого домена ($R), который dnl # был сгенерирован в ответ на письмо с непереписанным адресом в соответствии со dnl # старой политикой перезаписи адресов. dnl # в таком случае необходимо в течении некоторого переходного периода для перезаписи dnl # адресов использовать новую политику исключений (в данном случае исключаются только dnl # локальные домены из класса $w), а для проверки возможности приема bounce message dnl # на неподписанный адрес применять старую политику исключений (в данном случае dnl # исключаются адреса из локальных доменов из класса $w и адреса из рилеемых доменов dnl # из класса $R) dnl # dnl # при необходимости указания политики исключений из проверки bounce message, отличной dnl # от политики исключения перезаписи адресов отправителей, она указывается в параметре dnl # confSRS_DOMAINS_SKIP_VERIFY_BOUNCE dnl # возможные значения параметра такие же, как у confSRS_DOMAINS_SKIP dnl # если параметр confSRS_DOMAINS_SKIP_VERIFY_BOUNCE не определен (это не касается случая, dnl # когда параметр определен, но имеет нулевую длину), то политика исключений при проверке dnl # bounce messages считается такой же, как политика исключений перезаписи адресов отправителей dnl # dnl # если в параметре confSRS_DOMAINS_SKIP_VERIFY_BOUNCE присутствует значение `FILE' и при dnl # этом значение параметра confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE не определено или имеет dnl # нулевую длину, вместо него будет использовано значение параметра confSRS_DOMAINS_SKIP_FILE dnl # dnl # необходимость переписывания исходящего адреса отправителя и проверки на dnl # возможности приема bounce message на неподписанный адрес указывается в dnl # access_db с квалификатором SRS_SkipMail и значениями: dnl # SKIP - адрес отправителя не переписывается и на dnl # этот неподписанный адрес принимаеются bouce message dnl # любое значение, кроме SKIP - адрес отправителя переписывается и на этот неподписанный dnl # адрес не принимаются bouce message, даже если домен указан в dnl # confSRS_DOMAINS_SKIP dnl # пример: dnl # SRS_SkipMail:addr@some.domain.tld SKIP dnl # SRS_SkipMail:root@domain.tld DO_NOT_SKIP dnl # dnl # bounce messages принимаются на подписанные SRS адреса и на неподписанные адреса dnl # postmaster и abuse из локальных доменов ($w) и relay_domains ($R) dnl # dnl # необходимость проверки приема bounce message на неподписанный адрес указывается в dnl # access_db с квалификатором SRS_VerifyBounce и значениями: dnl # SKIP - на этот неподписанный адрес принимаеются bouce message dnl # любое значение, кроме SKIP - на этот неподписанный адрес не принимаются bouce message, dnl # даже если домен указан в confSRS_DOMAINS_SKIP или это dnl # адрес postmaster или abuse из локального домена ($w) и relay_domains ($R) dnl # пример: dnl # SRS_VerifyBounce:addr@some.domain.tld SKIP dnl # SRS_VerifyBounce:root@domain.tld DO_NOT_SKIP dnl # dnl # пример 1: dnl # необходимо переписывать адреса отправителей всех не локальных доменов, не рилеемых доменов dnl # и нескольких доменов, указанных отдельно в access_db dnl # при этом необходимо адрес one_user из домена local.domain.tld переписывать dnl # при этом необходимо адрес another_user из домена relayed.another.domain.tld не переписывать dnl # dnl # в итоге: dnl # адреса всех локальных и рилеемых доменов не переписываются: dnl # define(`confSRS_DOMAINS_SKIP', `LOCAL RELAY_DOMAINS')dnl dnl # адреса отправителей нескольких доменов, указанных отдельно в access_db переписываются: dnl # SRS_SkipMail:domain1.tld DO_NOT_SKIP dnl # SRS_SkipMail:domain2.tld DO_NOT_SKIP dnl # адрес one_user из домена local.domain.tld переписывается dnl # SRS_SkipMail:one_user@local.domain.tld DO_NOT_SKIP dnl # dnl # пример 2: dnl # необходимо переписывать все адреса отправителей всех локальных доменов, за исключением dnl # local.domain.tld dnl # при этом необходимо адрес one_user из домена local.domain.tld переписывать dnl # dnl # в итоге: dnl # адреса всех локальных доменов переписываются (нет `LOCAL' в confSRS_DOMAINS_SKIP) dnl # define(`confSRS_DOMAINS_SKIP', `')dnl dnl # один из локальных доменов исключается из SRS dnl # SRS_SkipMail:local.domain.tld SKIP dnl # один из адресов из этого локального домена не исключается из SRS dnl # SRS_SkipMail:one_user@local.domain.tld DO_NOT_SKIP dnl # divert(0) VERSIONID(`$Id: perlsrs.m4,v 1.2 2004/04/01 20:37:09 mkramer Exp $') ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before HACK(perlsrs) ')') ifelse(len(X`'_ARG_), `1', `errprint(`*** WARNING: HACK(perlsrs) requires domain for SRS dorwards as a first parameter ')', `define(`confSRS_FWD_DOMAIN', _ARG_)') LOCAL_CONFIG ifdef(`confSRS_DOMAINS_SKIP_VERIFY_BOUNCE', `', `define(`confSRS_DOMAINS_SKIP_VERIFY_BOUNCE', confSRS_DOMAINS_SKIP)') ifelse_strstr(confSRS_DOMAINS_SKIP, `FILE', ` ifdef(`confSRS_DOMAINS_SKIP_FILE', `', `define(`confSRS_DOMAINS_SKIP_FILE', `domains-srs-skip')') ifelse(len(X`'confSRS_DOMAINS_SKIP_FILE), `1', `define(`confSRS_DOMAINS_SKIP_FILE', `domains-srs-skip')') F{SRS_DOMAINS_SKIP}`'ifelse(substr(confSRS_DOMAINS_SKIP_FILE, 0, 1), `/', `', MAIL_SETTINGS_DIR)`'confSRS_DOMAINS_SKIP_FILE ') ifelse_strstr(confSRS_DOMAINS_SKIP_VERIFY_BOUNCE, `FILE', ` ifdef(`confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE', `', ` define(`confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE', confSRS_DOMAINS_SKIP_FILE) ') ifelse(len(X`'confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE), `1', ` define(`confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE', confSRS_DOMAINS_SKIP_FILE) ') F{SRS_DOMAINS_SKIP_VERIFY_BOUNCE}`'ifelse(substr(confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE, 0, 1), `/', `', MAIL_SETTINGS_DIR)`'confSRS_DOMAINS_SKIP_VERIFY_BOUNCE_FILE ') # Forward SRS program map Kmake_srs program ifdef(`confSRS_ENVFROM2SRC', confSRS_ENVFROM2SRC, `/usr/local/scripts/SRS/envfrom2srs.pl') # Reverse SRS program map Kreverse_srs program ifdef(`confSRS_REVERSE_SRC', confSRS_REVERSE_SRC, `/usr/local/scripts/SRS/srs2envtol.pl') # SRS regex map Kis_srs regex ^ $1 $| < $&{SkipSRS} > R $* $| $: $1 R $* $| $: $1 R $* $| $* $: $1 ifelse_strstr(confSRS_DOMAINS_SKIP, `LOCAL', ` R $+ < @ $=w . > $: $1 < @ $2 . > R $+ < @ $=w > $: $1 < @ $2 > ') ifelse_strstr(confSRS_DOMAINS_SKIP, `RELAY_DOMAINS', ` R $+ < @ $=R . > $: $1 < @ $2 . > R $+ < @ $=R > $: $1 < @ $2 > ') ifelse_strstr(confSRS_DOMAINS_SKIP, `FILE', ` R $+ < @ $={SRS_DOMAINS_SKIP} . > $: $1 < @ $2 . > R $+ < @ $={SRS_DOMAINS_SKIP} > $: $1 < @ $2 > ') R $* $: $1 R $* $: $(make_srs $1 $) make SRS R <$*> $* $: $2 LOCAL_RULE_0 # Do we need to reverse SRS address? #R $* $: $1 $| $(is_srs $1 $) R $+ < @ confSRS_FWD_DOMAIN . > $: $1 < @ confSRS_FWD_DOMAIN . > $| $(is_srs $1@confSRS_FWD_DOMAIN $) R $* $| $@ $: $1 $| $| $(reverse_srs $1 $) R $* $| $| $+<@$+.> $: $2 < @ $3 . > R $* $| $| $+<@$+> $: $2 < @ $3 . > R $* $| $| $+@$+ $: $2 < @ $3 . > R $* $| $| $* $: $2 R $* $| $* $: $1 R $+ < @ confSRS_FWD_DOMAIN . > $: $1 < @ confSRS_FWD_DOMAIN . > $| $(is_srs $1@confSRS_FWD_DOMAIN $) R $* $| $@ $#error $@ 5.1.1 $: "Invalid SRS bounce" R $* $| $* $: $1 LOCAL_RULESETS SLocal_check_mail dnl uncomment the line below if you do not use HACK(`precheck_envelope') #R $* $: $>Parse0 $>3 $1 R $+ < @ $+ . > $: $1 < @ $2 . > $| $1@$2 R $+ < @ $+ > $: $1 < @ $2 > $| $1@$2 R $* $| $+@$+ $: $1 $| $>SearchList $| <> # skip rewrite sender address R $* $| $: $1 $(macro {SkipSRS} $@ YES $) # we do not know R $* $| $: $1 $(macro {SkipSRS} $@ UNDEF $) # do not skip rewrite sender address R $* $| $* $: $1 $(macro {SkipSRS} $@ NO $) SLocal_check_rcpt dnl uncomment the line below if you do not use HACK(`precheck_envelope') #R $* $: $>Parse0 $>3 $1 # check envelope from R $* $: $1 $| <$&f> # mark for bounce verify R $* $| <> $: $1 # mark for bounce verify R $* $| <<>> $: $1 # do not need to verify bounce for non empty envelope sender R $* $| <$*> $: $1 R $+ < @ $+ . > $: $1 < @ $2 . > $| $1@$2 R $+ < @ $+ > $: $1 < @ $2 > $| $1@$2 R $+ @ $+ $: $1@$2 $| $1@$2 R $+ @ $+ $| < $+ @ $+ > $: $1@$2 $| $3@$4 # lookup to access_db for address with qualifier SRS_VerifyBounce R $* $| $+@$+ $: $1 $| $2@$3 $| $>SearchList $| <> # skip verify bounce for addresses with value SKIP R $* $| $+@$+ $| $: $1 # found nothing R $* $| $+@$+ $| $: $1 $| $2@$3 # do not skip verify bounce for addresses with not SKIP R $* $| $+@$+ $| $* $: $1 $| $2@$3 # lookup to access_db for address with qualifier SRS_SkipMail R $* $| $+@$+ $: $1 $| $2@$3 $| $>SearchList $| <> # skip verify bounce for addresses with value SKIP R $* $| $+@$+ $| $: $1 # found nothing R $* $| $+@$+ $| $: $1 $| $2@$3 # do not skip verify bounce for addresses with not SKIP R $* $| $+@$+ $| $* $: $1 $| $2@$3 ifelse_strstr(confSRS_DOMAINS_SKIP_VERIFY_BOUNCE, `LOCAL', ` # skip verify bounce for $w (local) domains R $+ $| $+@$=w $: $1 ') ifelse_strstr(confSRS_DOMAINS_SKIP_VERIFY_BOUNCE, `RELAY_DOMAINS', ` # skip verify bounce for $R (relayed) domains R $+ $| $+@$=R $: $1 ') ifelse_strstr(confSRS_DOMAINS_SKIP_VERIFY_BOUNCE, `FILE', ` # skip verify bounce for domains from file confSRS_DOMAINS_SKIP_FILE R $+ $| $+@$={SRS_DOMAINS_SKIP_VERIFY_BOUNCE} $: $1 ') R $* $| postmaster @ $=w $: $1 R $* $| abuse @ $=w $: $1 R $* $| postmaster @ $=R $: $1 R $* $| abuse @ $=R $: $1 R $* $| $* $: $1 $| $2 R $* $| $+@$+ $: $1 $| $(is_srs $2@$3 $) R $* $| $@ $: $1 R $* $| $* $: $1 R $* $#error $@ 5.1.1 $: "Bounce address not SRS signed!" R <$*> $* $: $2