Mercurial > sm-archive
diff test.cf @ 1:45c8592d5d13
initial version
author | carl |
---|---|
date | Fri, 10 Mar 2006 10:35:25 -0800 |
parents | |
children | 75e1a9bcbc2e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test.cf Fri Mar 10 10:35:25 2006 -0800 @@ -0,0 +1,1933 @@ +# +# Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# Copyright (c) 1983, 1995 Eric P. Allman. 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. +# +# + +###################################################################### +###################################################################### +##### +##### SENDMAIL CONFIGURATION FILE +##### +##### built by root@ns.five-ten-sg.com on Sat Sep 17 18:06:39 PDT 2005 +##### in /usr/usr/cvs/gpl/dnsbl +##### using /usr/share/sendmail-cf/ as configuration include directory +##### +###################################################################### +##### +##### DO NOT EDIT THIS FILE! Only edit the source .mc file. +##### +###################################################################### +###################################################################### + +##### $Id$ ##### +##### $Id$ ##### + +##### linux setup for Red Hat Linux ##### + +##### $Id$ ##### + + + +##### $Id$ ##### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +##### $Id$ ##### + + +##### $Id$ ##### + +##### $Id$ ##### + + +##### $Id$ ##### + + + +##### $Id$ ##### + + + +##### $Id$ ##### + + +##### $Id$ ##### + + +##### $Id$ ##### + + +##### $Id$ ##### + + +##### $Id$ ##### + + +##### $Id$ ##### + + +##### $Id$ ##### + + + + + + + + +##### $Id$ ##### + +# level 10 config file format +V10/Berkeley + +# override file safeties - setting this option compromises system security, +# addressing the actual file configuration problem is preferred +# need to set this before any file actions are encountered in the cf file +#O DontBlameSendmail=safe + +# default LDAP map specification +# need to set this now before any LDAP maps are defined +#O LDAPDefaultSpec=-h localhost + +################## +# local info # +################## + +# my LDAP cluster +# need to set this before any LDAP lookups are done (including classes) +#D{sendmailMTACluster}$m + +Cwlocalhost +# file containing names of hosts for which we receive email +Fw/etc/mail/sendmail.cw + +# my official domain name +# ... define this only if sendmail cannot automatically determine your domain +#Dj$w.Foo.COM + +# host/domain names ending with a token in class P are canonical +CP. + +# "Smart" relay host (may be null) +DS + + +# operators that cannot be in local usernames (i.e., network indicators) +CO @ % ! + +# a class with just dot (for identifying canonical names) +C.. + +# a class with just a left bracket (for identifying domain literals) +C[[ + +# access_db acceptance class +C{Accept}OK RELAY + + +# Resolve map (to check if a host exists in check_mail) +Kresolve host -a<OKR> -T<TEMP> +C{ResOk}OKR + + +# Hosts for which relaying is permitted ($=R) +FR/etc/mail/relay-domains + +# arithmetic map +Karith arith +# macro storage map +Kmacro macro +# possible values for TLS_connection in access map +C{Tls}VERIFY ENCR + + + + + +# dequoting map +Kdequote dequote + +# class E: names that should be exposed as from this host, even if we masquerade +# class L: names that should be delivered locally, even if we have a relay +# class M: domains that should be converted to $M +# class N: domains that should not be converted to $M +#CL root +F{VirtHost}/etc/mail/virtual-host-domains + +C{TrustAuthMech}LOGIN PLAIN +CR$={VirtHost} + + + +# my name for error messages +DnMAILER-DAEMON + + +CPREDIRECT + +# Access list database (for spam stomping) +Kaccess hash -T<TMPF> /etc/mail/access.db + +# Mailer table (overriding domains) +Kmailertable hash /etc/mail/mailertable.db + +# Virtual user table (maps incoming users) +Kvirtuser hash /etc/mail/virtusertable.db + +# Generics table (mapping outgoing addresses) +Kgenerics hash /etc/mail/genericstable.db + +# Configuration version number +DZ8.13.1 + + +############### +# Options # +############### + +# strip message body to 7 bits on input? +O SevenBitInput=False + +# 8-bit data handling +#O EightBitMode=pass8 + +# wait for alias file rebuild (default units: minutes) +O AliasWait=10 + +# location of alias file +O AliasFile=/etc/mail/aliases + +# minimum number of free blocks on filesystem +O MinFreeBlocks=100 + +# maximum message size +O MaxMessageSize=30000000 + +# substitution for space (blank) characters +O BlankSub=. + +# avoid connecting to "expensive" mailers on initial submission? +O HoldExpensive=False + +# checkpoint queue runs after every N successful deliveries +#O CheckpointInterval=10 + +# default delivery mode +O DeliveryMode=background + +# error message header/file +#O ErrorHeader=/etc/mail/error-header + +# error mode +#O ErrorMode=print + +# save Unix-style "From_" lines at top of header? +#O SaveFromLine=False + +# queue file mode (qf files) +#O QueueFileMode=0600 + +# temporary file mode +O TempFileMode=0600 + +# match recipients against GECOS field? +#O MatchGECOS=False + +# maximum hop count +#O MaxHopCount=25 + +# location of help file +O HelpFile=/etc/mail/helpfile + +# ignore dots as terminators in incoming messages? +#O IgnoreDots=False + +# name resolver options +#O ResolverOptions=+AAONLY + +# deliver MIME-encapsulated error messages? +O SendMimeErrors=True + +# Forward file search path +O ForwardPath=$z/.forward.$w:$z/.forward + +# open connection cache size +O ConnectionCacheSize=2 + +# open connection cache timeout +O ConnectionCacheTimeout=5m + +# persistent host status directory +#O HostStatusDirectory=.hoststat + +# single thread deliveries (requires HostStatusDirectory)? +#O SingleThreadDelivery=False + +# use Errors-To: header? +O UseErrorsTo=False + +# log level +O LogLevel=20 + +# send to me too, even in an alias expansion? +O MeToo=true + +# verify RHS in newaliases? +O CheckAliases=False + +# default messages to old style headers if no special punctuation? +O OldStyleHeaders=True + +# SMTP daemon options + +O DaemonPortOptions=port=26 + +# SMTP client options +#O ClientPortOptions=Family=inet, Address=0.0.0.0 + +# Modifiers to define {daemon_flags} for direct submissions +#O DirectSubmissionModifiers + +# Use as mail submission program? See sendmail/SECURITY +#O UseMSP + +# privacy flags +O PrivacyOptions=goaway,nobodyreturn,noreceipts + +# who (if anyone) should get extra copies of error messages +#O PostmasterCopy=Postmaster + +# slope of queue-only function +#O QueueFactor=600000 + +# limit on number of concurrent queue runners +#O MaxQueueChildren + +# maximum number of queue-runners per queue-grouping with multiple queues +#O MaxRunnersPerQueue=1 + +# priority of queue runners (nice(3)) +#O NiceQueueRun + +# shall we sort the queue by hostname first? +#O QueueSortOrder=priority + +# minimum time in queue before retry +#O MinQueueAge=30m + +# how many jobs can you process in the queue? +#O MaxQueueRunSize=10000 + +# perform initial split of envelope without checking MX records +#O FastSplit=1 + +# queue directory +O QueueDirectory=/var/spool/mqueue + +# key for shared memory; 0 to turn off +#O SharedMemoryKey=0 + + + +# timeouts (many of these) +#O Timeout.initial=5m +O Timeout.connect=1m +#O Timeout.aconnect=0s +#O Timeout.iconnect=5m +#O Timeout.helo=5m +#O Timeout.mail=10m +#O Timeout.rcpt=1h +#O Timeout.datainit=5m +#O Timeout.datablock=1h +#O Timeout.datafinal=1h +#O Timeout.rset=5m +#O Timeout.quit=2m +#O Timeout.misc=2m +#O Timeout.command=1h +O Timeout.ident=0 +#O Timeout.fileopen=60s +#O Timeout.control=2m +O Timeout.queuereturn=5d +#O Timeout.queuereturn.normal=5d +#O Timeout.queuereturn.urgent=2d +#O Timeout.queuereturn.non-urgent=7d +#O Timeout.queuereturn.dsn=5d +O Timeout.queuewarn=4h +#O Timeout.queuewarn.normal=4h +#O Timeout.queuewarn.urgent=1h +#O Timeout.queuewarn.non-urgent=12h +#O Timeout.queuewarn.dsn=4h +#O Timeout.hoststatus=30m +#O Timeout.resolver.retrans=5s +#O Timeout.resolver.retrans.first=5s +#O Timeout.resolver.retrans.normal=5s +#O Timeout.resolver.retry=4 +#O Timeout.resolver.retry.first=4 +#O Timeout.resolver.retry.normal=4 +#O Timeout.lhlo=2m +#O Timeout.auth=10m +#O Timeout.starttls=1h + +# time for DeliverBy; extension disabled if less than 0 +#O DeliverByMin=0 + +# should we not prune routes in route-addr syntax addresses? +#O DontPruneRoutes=False + +# queue up everything before forking? +O SuperSafe=True + +# status file +O StatusFile=/usr/usr/cvs/gpl/dnsbl/sendmail.st + +# time zone handling: +# if undefined, use system default +# if defined but null, use TZ envariable passed in +# if defined and non-null, use that info +#O TimeZoneSpec= + +# default UID (can be username or userid:groupid) +O DefaultUser=8:12 + +# list of locations of user database file (null means no lookup) +#O UserDatabaseSpec=/etc/mail/userdb + +# fallback MX host +#O FallbackMXhost=fall.back.host.net + +# fallback smart host +#O FallbackSmartHost=fall.back.host.net + +# if we are the best MX host for a site, try it directly instead of config err +#O TryNullMXList=False + +# load average at which we just queue messages +O QueueLA=12 + +# load average at which we refuse connections +O RefuseLA=8 + +# log interval when refusing connections for this long +#O RejectLogInterval=3h + +# load average at which we delay connections; 0 means no limit +#O DelayLA=0 + +# maximum number of children we allow at one time +O MaxDaemonChildren=20 + +# maximum number of new connections per second +O ConnectionRateThrottle=1 + +# Width of the window +#O ConnectionRateWindowSize=60s + +# work recipient factor +#O RecipientFactor=30000 + +# deliver each queued job in a separate process? +#O ForkEachJob=False + +# work class factor +#O ClassFactor=1800 + +# work time factor +#O RetryFactor=90000 + +# default character set +#O DefaultCharSet=iso-8859-1 + +# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others) +#O ServiceSwitchFile=/etc/mail/service.switch + +# hosts file (normally /etc/hosts) +#O HostsFile=/etc/hosts + +# dialup line delay on connection failure +#O DialDelay=10s + +# action to take if there are no recipients in the message +#O NoRecipientAction=add-to-undisclosed + +# chrooted environment for writing to files +#O SafeFileEnvironment=/arch + +# are colons OK in addresses? +#O ColonOkInAddr=True + +# shall I avoid expanding CNAMEs (violates protocols)? +#O DontExpandCnames=False + +# SMTP initial login message (old $e macro) +O SmtpGreetingMessage=$j Sendmail $v/$Z; $b + +# UNIX initial From header format (old $l macro) +O UnixFromLine=From $g $d + +# From: lines that have embedded newlines are unwrapped onto one line +#O SingleLineFromHeader=False + +# Allow HELO SMTP command that does not include a host name +#O AllowBogusHELO=False + +# Characters to be quoted in a full name phrase (@,;:\()[] are automatic) +#O MustQuoteChars=. + +# delimiter (operator) characters (old $o macro) +O OperatorChars=.:%@!^/[]+ + +# shall I avoid calling initgroups(3) because of high NIS costs? +#O DontInitGroups=False + +# are group-writable :include: and .forward files (un)trustworthy? +# True (the default) means they are not trustworthy. +#O UnsafeGroupWrites=True + + +# where do errors that occur when sending errors get sent? +O DoubleBounceAddress + +# where to save bounces if all else fails +#O DeadLetterDrop=/var/tmp/dead.letter + +# what user id do we assume for the majority of the processing? +#O RunAsUser=sendmail + +# maximum number of recipients per SMTP envelope +#O MaxRecipientsPerMessage=0 + +# limit the rate recipients per SMTP envelope are accepted +# once the threshold number of recipients have been rejected +O BadRcptThrottle=2 + +# shall we get local names from our installed interfaces? +O DontProbeInterfaces=true + +# Return-Receipt-To: header implies DSN request +#O RrtImpliesDsn=False + +# override connection address (for testing) +#O ConnectOnlyTo=0.0.0.0 + +# Trusted user for file ownership and starting the daemon +#O TrustedUser=root + +# Control socket for daemon management +#O ControlSocketName=/var/spool/mqueue/.control + +# Maximum MIME header length to protect MUAs +#O MaxMimeHeaderLength=0/0 + +# Maximum length of the sum of all headers +#O MaxHeadersLength=32768 + +# Maximum depth of alias recursion +#O MaxAliasRecursion=10 + +# location of pid file +O PidFile=/var/run/sm-test.pid + +# Prefix string for the process title shown on 'ps' listings +#O ProcessTitlePrefix=prefix + +# Data file (df) memory-buffer file maximum size +#O DataFileBufferSize=4096 + +# Transcript file (xf) memory-buffer file maximum size +#O XscriptFileBufferSize=4096 + +# lookup type to find information about local mailboxes +#O MailboxDatabase=pw + +# override compile time flag REQUIRES_DIR_FSYNC +#O RequiresDirfsync=true + +# list of authentication mechanisms +O AuthMechanisms=LOGIN PLAIN + +# Authentication realm +#O AuthRealm + +# default authentication information for outgoing connections +#O DefaultAuthInfo=/etc/mail/default-auth-info + +# SMTP AUTH flags +O AuthOptions=A + +# SMTP AUTH maximum encryption strength +#O AuthMaxBits + +# SMTP STARTTLS server options +#O TLSSrvOptions + +# Input mail filters +O InputMailFilters=dnsbl + +# Milter options +#O Milter.LogLevel +O Milter.macros.connect=j, _, {daemon_name}, {if_name}, {if_addr} +O Milter.macros.helo={tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer} +O Milter.macros.envfrom=i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author}, {mail_mailer}, {mail_host}, {mail_addr} +O Milter.macros.envrcpt={rcpt_mailer}, {rcpt_host}, {rcpt_addr} +O Milter.macros.eom={msg_id} + +# CA directory +#O CACertPath +# CA file +#O CACertFile +# Server Cert +#O ServerCertFile +# Server private key +#O ServerKeyFile +# Client Cert +#O ClientCertFile +# Client private key +#O ClientKeyFile +# File containing certificate revocation lists +#O CRLFile +# DHParameters (only required if DSA/DH is used) +#O DHParameters +# Random data source (required for systems without /dev/urandom under OpenSSL) +#O RandFile + +############################ +# QUEUE GROUP DEFINITIONS # +############################ + + +########################### +# Message precedences # +########################### + +Pfirst-class=0 +Pspecial-delivery=100 +Plist=-30 +Pbulk=-60 +Pjunk=-100 + +##################### +# Trusted users # +##################### + +# this is equivalent to setting class "t" +Ft/etc/mail/sendmail.ct +Troot +Tdaemon +Tuucp + +######################### +# Format of headers # +######################### + +H?P?Return-Path: <$g> +HReceived: $?sfrom $s $.$?_($?s$|from $.$_) + $.$?{auth_type}(authenticated$?{auth_ssf} bits=${auth_ssf}$.) + $.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version} + (version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})$.$?u + for $u; $|; + $.$b +H?D?Resent-Date: $a +H?D?Date: $a +H?F?Resent-From: $?x$x <$g>$|$g$. +H?F?From: $?x$x <$g>$|$g$. +H?x?Full-Name: $x +# HPosted-Date: $a +# H?l?Received-Date: $b +H?M?Resent-Message-Id: <$t.$i@$j> +H?M?Message-Id: <$t.$i@$j> + +# +###################################################################### +###################################################################### +##### +##### REWRITING RULES +##### +###################################################################### +###################################################################### + +############################################ +### Ruleset 3 -- Name Canonicalization ### +############################################ +Scanonify=3 + +# handle null input (translate to <@> special case) +R$@ $@ <@> + +# strip group: syntax (not inside angle brackets!) and trailing semicolon +R$* $: $1 <@> mark addresses +R$* < $* > $* <@> $: $1 < $2 > $3 unmark <addr> +R@ $* <@> $: @ $1 unmark @host:... +R$* [ IPv6 : $+ ] <@> $: $1 [ IPv6 : $2 ] unmark IPv6 addr +R$* :: $* <@> $: $1 :: $2 unmark node::addr +R:include: $* <@> $: :include: $1 unmark :include:... +R$* : $* [ $* ] $: $1 : $2 [ $3 ] <@> remark if leading colon +R$* : $* <@> $: $2 strip colon if marked +R$* <@> $: $1 unmark +R$* ; $1 strip trailing semi +R$* < $+ :; > $* $@ $2 :; <@> catch <list:;> +R$* < $* ; > $1 < $2 > bogus bracketed semi + +# null input now results from list:; syntax +R$@ $@ :; <@> + +# strip angle brackets -- note RFC733 heuristic to get innermost item +R$* $: < $1 > housekeeping <> +R$+ < $* > < $2 > strip excess on left +R< $* > $+ < $1 > strip excess on right +R<> $@ < @ > MAIL FROM:<> case +R< $+ > $: $1 remove housekeeping <> + +# strip route address <@a,@b,@c:user@d> -> <user@d> +R@ $+ , $+ $2 +R@ [ $* ] : $+ $2 +R@ $+ : $+ $2 + +# find focus for list syntax +R $+ : $* ; @ $+ $@ $>Canonify2 $1 : $2 ; < @ $3 > list syntax +R $+ : $* ; $@ $1 : $2; list syntax + +# find focus for @ syntax addresses +R$+ @ $+ $: $1 < @ $2 > focus on domain +R$+ < $+ @ $+ > $1 $2 < @ $3 > move gaze right +R$+ < @ $+ > $@ $>Canonify2 $1 < @ $2 > already canonical + + +# convert old-style addresses to a domain-based address +R$- ! $+ $@ $>Canonify2 $2 < @ $1 .UUCP > resolve uucp names +R$+ . $- ! $+ $@ $>Canonify2 $3 < @ $1 . $2 > domain uucps +R$+ ! $+ $@ $>Canonify2 $2 < @ $1 .UUCP > uucp subdomains + +# if we have % signs, take the rightmost one +R$* % $* $1 @ $2 First make them all @s. +R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last. +R$* @ $* $@ $>Canonify2 $1 < @ $2 > Insert < > and finish + +# else we must be a local name +R$* $@ $>Canonify2 $1 + + +################################################ +### Ruleset 96 -- bottom half of ruleset 3 ### +################################################ + +SCanonify2=96 + +# handle special cases for local names +R$* < @ localhost > $* $: $1 < @ $j . > $2 no domain at all +R$* < @ localhost . $m > $* $: $1 < @ $j . > $2 local domain +R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2 .UUCP domain + +# check for IPv4/IPv6 domain literal +R$* < @ [ $+ ] > $* $: $1 < @@ [ $2 ] > $3 mark [addr] +R$* < @@ $=w > $* $: $1 < @ $j . > $3 self-literal +R$* < @@ $+ > $* $@ $1 < @ $2 > $3 canon IP addr + + + + + +# if really UUCP, handle it immediately + +# try UUCP traffic as a local address +R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3 +R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3 + +# hostnames ending in class P are always canonical +R$* < @ $* $=P > $* $: $1 < @ $2 $3 . > $4 +R$* < @ $* $~P > $* $: $&{daemon_flags} $| $1 < @ $2 $3 > $4 +R$* CC $* $| $* < @ $+.$+ > $* $: $3 < @ $4.$5 . > $6 +R$* CC $* $| $* $: $3 +# pass to name server to make hostname canonical +R$* $| $* < @ $* > $* $: $2 < @ $[ $3 $] > $4 +R$* $| $* $: $2 + +# local host aliases and pseudo-domains are always canonical +R$* < @ $=w > $* $: $1 < @ $2 . > $3 +R$* < @ $=M > $* $: $1 < @ $2 . > $3 +R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3 +R$* < @ $=G > $* $: $1 < @ $2 . > $3 +R$* < @ $* . . > $* $1 < @ $2 . > $3 + + +################################################## +### Ruleset 4 -- Final Output Post-rewriting ### +################################################## +Sfinal=4 + +R$+ :; <@> $@ $1 : handle <list:;> +R$* <@> $@ handle <> and list:; + +# strip trailing dot off possibly canonical name +R$* < @ $+ . > $* $1 < @ $2 > $3 + +# eliminate internal code +R$* < @ *LOCAL* > $* $1 < @ $j > $2 + +# externalize local domain info +R$* < $+ > $* $1 $2 $3 defocus +R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3 <route-addr> canonical +R@ $* $@ @ $1 ... and exit + +# UUCP must always be presented in old form +R$+ @ $- . UUCP $2!$1 u@h.UUCP => h!u + +# delete duplicate local names +R$+ % $=w @ $=w $1 @ $2 u%host@host => u@host + + + +############################################################## +### Ruleset 97 -- recanonicalize and call ruleset zero ### +### (used for recursive calls) ### +############################################################## + +SRecurse=97 +R$* $: $>canonify $1 +R$* $@ $>parse $1 + + +###################################### +### Ruleset 0 -- Parse Address ### +###################################### + +Sparse=0 + +R$* $: $>Parse0 $1 initial parsing +R<@> $#local $: <@> special case error msgs +R$* $: $>ParseLocal $1 handle local hacks +R$* $: $>Parse1 $1 final parsing + +# +# Parse0 -- do initial syntax checking and eliminate local addresses. +# This should either return with the (possibly modified) input +# or return with a #error mailer. It should not return with a +# #mailer other than the #error mailer. +# + +SParse0 +R<@> $@ <@> special case error msgs +R$* : $* ; <@> $#error $@ 5.1.3 $: "553 List:; syntax illegal for recipient addresses" +R@ <@ $* > < @ $1 > catch "@@host" bogosity +R<@ $+> $#error $@ 5.1.3 $: "553 User address required" +R$+ <@> $#error $@ 5.1.3 $: "553 Hostname required" +R$* $: <> $1 +R<> $* < @ [ $* ] : $+ > $* $1 < @ [ $2 ] : $3 > $4 +R<> $* < @ [ $* ] , $+ > $* $1 < @ [ $2 ] , $3 > $4 +R<> $* < @ [ $* ] $+ > $* $#error $@ 5.1.2 $: "553 Invalid address" +R<> $* < @ [ $+ ] > $* $1 < @ [ $2 ] > $3 +R<> $* <$* : $* > $* $#error $@ 5.1.3 $: "553 Colon illegal in host name part" +R<> $* $1 +R$* < @ . $* > $* $#error $@ 5.1.2 $: "553 Invalid host name" +R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "553 Invalid host name" +R$* < @ $* @ > $* $#error $@ 5.1.2 $: "553 Invalid route address" +R$* @ $* < @ $* > $* $#error $@ 5.1.3 $: "553 Invalid route address" +R$* , $~O $* $#error $@ 5.1.3 $: "553 Invalid route address" + + +# now delete the local info -- note $=O to find characters that cause forwarding +R$* < @ > $* $@ $>Parse0 $>canonify $1 user@ => user +R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ... +R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here +R< @ $+ > $#error $@ 5.1.3 $: "553 User address required" +R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ... +R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" +R< @ *LOCAL* > $#error $@ 5.1.3 $: "553 User address required" +R$* $=O $* < @ *LOCAL* > + $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... +R$* < @ *LOCAL* > $: $1 + +# +# Parse1 -- the bottom half of ruleset 0. +# + +SParse1 + +# handle numeric address spec +R$* < @ [ $+ ] > $* $: $>ParseLocal $1 < @ [ $2 ] > $3 numeric internet spec +R$* < @ [ $+ ] > $* $: $1 < @ [ $2 ] : $S > $3 Add smart host to path +R$* < @ [ $+ ] : > $* $#esmtp $@ [$2] $: $1 < @ [$2] > $3 no smarthost: send +R$* < @ [ $+ ] : $- : $*> $* $#$3 $@ $4 $: $1 < @ [$2] > $5 smarthost with mailer +R$* < @ [ $+ ] : $+ > $* $#esmtp $@ $3 $: $1 < @ [$2] > $4 smarthost without mailer + +# handle virtual users +R$+ $: <!> $1 Mark for lookup +R<!> $+ < @ $={VirtHost} . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . > +R<!> $+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . > +R<@> $+ + $+ < @ $* . > + $: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . > +R<@> $+ + $* < @ $* . > + $: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . > +R<@> $+ + $* < @ $* . > + $: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . > +R<@> $+ + $+ < @ $+ . > $: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . > +R<@> $+ + $* < @ $+ . > $: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . > +R<@> $+ + $* < @ $+ . > $: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . > +R<@> $+ < @ $+ . > $: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . > +R<@> $+ $: $1 +R<!> $+ $: $1 +R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 +R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2 +R< $+ > $+ < @ $+ > $: $>Recurse $1 + +# short circuit local delivery so forwarded email works + + +R$=L < @ $=w . > $#local $: @ $1 special local names +R$+ < @ $=w . > $#local $: $1 regular local name + +# not local -- try mailer table lookup +R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name +R< $+ . > $* $: < $1 > $2 strip trailing dot +R< $+ > $* $: < $(mailertable $1 $) > $2 lookup +R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 check -- resolved? +R< $+ > $* $: $>Mailertable <$1> $2 try domain + +# resolve remotely connected UUCP links (if any) + +# resolve fake top level domains by forwarding to other hosts + + + +# pass names that still have a host to a smarthost (if defined) +R$* < @ $* > $* $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on smarthost name + +# deal with other remote names +R$* < @$* > $* $#esmtp $@ $2 $: $1 < @ $2 > $3 user@host.domain + +# handle locally delivered names +R$=L $#local $: @ $1 special local names +R$+ $#local $: $1 regular local names + +########################################################################### +### Ruleset 5 -- special rewriting after aliases have been expanded ### +########################################################################### + +SLocal_localaddr +Slocaladdr=5 +R$+ $: $1 $| $>"Local_localaddr" $1 +R$+ $| $#ok $@ $1 no change +R$+ $| $#$* $#$2 +R$+ $| $* $: $1 + + + + +# deal with plussed users so aliases work nicely +R$+ + * $#local $@ $&h $: $1 +R$+ + $* $#local $@ + $2 $: $1 + * + +# prepend an empty "forward host" on the front +R$+ $: <> $1 + + + +R< > $+ $: < > < $1 <> $&h > nope, restore +detail + +R< > < $+ <> + $* > $: < > < $1 + $2 > check whether +detail +R< > < $+ <> $* > $: < > < $1 > else discard +R< > < $+ + $* > $* < > < $1 > + $2 $3 find the user part +R< > < $+ > + $* $#local $@ $2 $: @ $1 strip the extra + +R< > < $+ > $@ $1 no +detail +R$+ $: $1 <> $&h add +detail back in + +R$+ <> + $* $: $1 + $2 check whether +detail +R$+ <> $* $: $1 else discard +R< local : $* > $* $: $>MailerToTriple < local : $1 > $2 no host extension +R< error : $* > $* $: $>MailerToTriple < error : $1 > $2 no host extension + +R< $~[ : $+ > $+ $: $>MailerToTriple < $1 : $2 > $3 < @ $2 > + +R< $+ > $+ $@ $>MailerToTriple < $1 > $2 < @ $1 > + + +################################################################### +### Ruleset 90 -- try domain part of mailertable entry ### +################################################################### + +SMailertable=90 +R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4 +R$* <$~[ : $* > $* $>MailerToTriple < $2 : $3 > $4 check -- resolved? +R$* < . $+ > $* $@ $>Mailertable $1 . <$2> $3 no -- strip & try again +R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "." +R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 "." found? +R< $* > $* $@ $2 no mailertable match + +################################################################### +### Ruleset 95 -- canonify mailer:[user@]host syntax to triple ### +################################################################### + +SMailerToTriple=95 +R< > $* $@ $1 strip off null relay +R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 +R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2 +R< error : $+ > $* $#error $: $1 +R< local : $* > $* $>CanonLocal < $1 > $2 +R< $~[ : $+ @ $+ > $*<$*>$* $# $1 $@ $3 $: $2<@$3> use literal user +R< $~[ : $+ > $* $# $1 $@ $2 $: $3 try qualified mailer +R< $=w > $* $@ $2 delete local host +R< $+ > $* $#relay $@ $1 $: $2 use unqualified mailer + +################################################################### +### Ruleset CanonLocal -- canonify local: syntax ### +################################################################### + +SCanonLocal +# strip local host from routed addresses +R< $* > < @ $+ > : $+ $@ $>Recurse $3 +R< $* > $+ $=O $+ < @ $+ > $@ $>Recurse $2 $3 $4 + +# strip trailing dot from any host name that may appear +R< $* > $* < @ $* . > $: < $1 > $2 < @ $3 > + +# handle local: syntax -- use old user, either with or without host +R< > $* < @ $* > $* $#local $@ $1@$2 $: $1 +R< > $+ $#local $@ $1 $: $1 + +# handle local:user@host syntax -- ignore host part +R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 > + +# handle local:user syntax +R< $+ > $* <@ $* > $* $#local $@ $2@$3 $: $1 +R< $+ > $* $#local $@ $2 $: $1 + +################################################################### +### Ruleset 93 -- convert header names to masqueraded form ### +################################################################### + +SMasqHdr=93 + +# handle generics database +R$+ < @ $=G . > $: < $1@$2 > $1 < @ $2 . > @ mark +R$+ < @ *LOCAL* > $: < $1@$j > $1 < @ *LOCAL* > @ mark +R< $+ > $+ < $* > @ $: < $(generics $1 $: @ $1 $) > $2 < $3 > +R<@$+ + $* @ $+> $+ < @ $+ > + $: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) > $4 < @ $5 > +R<@$+ + $* @ $+> $+ < @ $+ > + $: < $(generics $1@$3 $: $) > $4 < @ $5 > +R<@$+ > $+ < @ $+ > $: < > $2 < @ $3 > +R< > $+ < @ $+ . > $: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . > +R< > $+ < @ $+ > $: < $(generics $1 $: $) > $1 < @ $2 > +R< > $+ + $* < @ $+ > $: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 > +R< > $+ + $* < @ $+ > $: < $(generics $1 $: $) > $1 + $2 < @ $3 > +R< $* @ $* > $* < $* > $@ $>canonify $1 @ $2 found qualified +R< $+ > $* < $* > $: $>canonify $1 @ *LOCAL* found unqualified +R< > $* $: $1 not found + +# do not masquerade anything in class N +R$* < @ $* $=N . > $@ $1 < @ $2 $3 . > + +R$* < @ *LOCAL* > $@ $1 < @ $j . > + +################################################################### +### Ruleset 94 -- convert envelope names to masqueraded form ### +################################################################### + +SMasqEnv=94 +R$* < @ *LOCAL* > $* $: $1 < @ $j . > $2 + +################################################################### +### Ruleset 98 -- local part of ruleset zero (can be null) ### +################################################################### + +SParseLocal=98 + +# addresses sent to foo@host.REDIRECT will give a 551 error code +R$* < @ $+ .REDIRECT. > $: $1 < @ $2 . REDIRECT . > < ${opMode} > +R$* < @ $+ .REDIRECT. > <i> $: $1 < @ $2 . REDIRECT. > +R$* < @ $+ .REDIRECT. > < $- > $#error $@ 5.1.1 $: "551 User has moved; please try " <$1@$2> + + + + +###################################################################### +### D: LookUpDomain -- search for domain in access database +### +### Parameters: +### <$1> -- key (domain name) +### <$2> -- default (what to return if not found in db) +### <$3> -- mark (must be <(!|+) single-token>) +### ! does lookup only with tag +### + does lookup with and without tag +### <$4> -- passthru (additional data passed unchanged through) +###################################################################### + +SD +R<$*> <$+> <$- $-> <$*> $: < $(access $4:$1 $: ? $) > <$1> <$2> <$3 $4> <$5> +R<?> <$+> <$+> <+ $-> <$*> $: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4> +R<?> <[$+.$-]> <$+> <$- $-> <$*> $@ $>D <[$1]> <$3> <$4 $5> <$6> +R<?> <[$+::$-]> <$+> <$- $-> <$*> $: $>D <[$1]> <$3> <$4 $5> <$6> +R<?> <[$+:$-]> <$+> <$- $-> <$*> $: $>D <[$1]> <$3> <$4 $5> <$6> +R<?> <$+.$+> <$+> <$- $-> <$*> $@ $>D <$2> <$3> <$4 $5> <$6> +R<?> <$+> <$+> <$- $-> <$*> $@ <$2> <$5> +R<$* <TMPF>> <$+> <$+> <$- $-> <$*> $@ <<TMPF>> <$6> +R<$*> <$+> <$+> <$- $-> <$*> $@ <$1> <$6> + +###################################################################### +### A: LookUpAddress -- search for host address in access database +### +### Parameters: +### <$1> -- key (dot quadded host address) +### <$2> -- default (what to return if not found in db) +### <$3> -- mark (must be <(!|+) single-token>) +### ! does lookup only with tag +### + does lookup with and without tag +### <$4> -- passthru (additional data passed through) +###################################################################### + +SA +R<$+> <$+> <$- $-> <$*> $: < $(access $4:$1 $: ? $) > <$1> <$2> <$3 $4> <$5> +R<?> <$+> <$+> <+ $-> <$*> $: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4> +R<?> <$+::$-> <$+> <$- $-> <$*> $@ $>A <$1> <$3> <$4 $5> <$6> +R<?> <$+:$-> <$+> <$- $-> <$*> $@ $>A <$1> <$3> <$4 $5> <$6> +R<?> <$+.$-> <$+> <$- $-> <$*> $@ $>A <$1> <$3> <$4 $5> <$6> +R<?> <$+> <$+> <$- $-> <$*> $@ <$2> <$5> +R<$* <TMPF>> <$+> <$+> <$- $-> <$*> $@ <<TMPF>> <$6> +R<$*> <$+> <$+> <$- $-> <$*> $@ <$1> <$6> + +###################################################################### +### CanonAddr -- Convert an address into a standard form for +### relay checking. Route address syntax is +### crudely converted into a %-hack address. +### +### Parameters: +### $1 -- full recipient address +### +### Returns: +### parsed address, not in source route form +###################################################################### + +SCanonAddr +R$* $: $>Parse0 $>canonify $1 make domain canonical + + +###################################################################### +### ParseRecipient -- Strip off hosts in $=R as well as possibly +### $* $=m or the access database. +### Check user portion for host separators. +### +### Parameters: +### $1 -- full recipient address +### +### Returns: +### parsed, non-local-relaying address +###################################################################### + +SParseRecipient +R$* $: <?> $>CanonAddr $1 +R<?> $* < @ $* . > <?> $1 < @ $2 > strip trailing dots +R<?> $- < @ $* > $: <?> $(dequote $1 $) < @ $2 > dequote local part + +# if no $=O character, no host in the user portion, we are done +R<?> $* $=O $* < @ $* > $: <NO> $1 $2 $3 < @ $4> +R<?> $* $@ $1 + + +R<NO> $* < @ $=R > $: <RELAY> $1 < @ $2 > +R<NO> $* < @ $+ > $: <$(access To:$2 $: NO $)> $1 < @ $2 > +R<NO> $* < @ $+ > $: <$(access $2 $: NO $)> $1 < @ $2 > + + + +R<RELAY> $* < @ $* > $@ $>ParseRecipient $1 +R<$+> $* $@ $2 + + +###################################################################### +### check_relay -- check hostname/address on SMTP startup +###################################################################### + + + +SLocal_check_relay +Scheckrelay +R$* $: $1 $| $>"Local_check_relay" $1 +R$* $| $* $| $#$* $#$3 +R$* $| $* $| $* $@ $>"Basic_check_relay" $1 $| $2 + +SBasic_check_relay +# check for deferred delivery mode +R$* $: < $&{deliveryMode} > $1 +R< d > $* $@ deferred +R< $* > $* $: $2 + +R$+ $| $+ $: $>D < $1 > <?> <+ Connect> < $2 > +R $| $+ $: $>A < $1 > <?> <+ Connect> <> empty client_name +R<?> <$+> $: $>A < $1 > <?> <+ Connect> <> no: another lookup +R<?> <$*> $: OK found nothing +R<$={Accept}> <$*> $@ $1 return value of lookup +R<REJECT> <$*> $#error $@ 5.7.1 $: "550 Access denied" +R<DISCARD> <$*> $#discard $: discard +R<QUARANTINE:$+> <$*> $#error $@ quarantine $: $1 +R<ERROR:$-.$-.$-:$+> <$*> $#error $@ $1.$2.$3 $: $4 +R<ERROR:$+> <$*> $#error $: $1 +R<$* <TMPF>> <$*> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<$+> <$*> $#error $: $1 + + + +###################################################################### +### check_mail -- check SMTP `MAIL FROM:' command argument +###################################################################### + +SLocal_check_mail +Scheckmail +R$* $: $1 $| $>"Local_check_mail" $1 +R$* $| $#$* $#$2 +R$* $| $* $@ $>"Basic_check_mail" $1 + +SBasic_check_mail +# check for deferred delivery mode +R$* $: < $&{deliveryMode} > $1 +R< d > $* $@ deferred +R< $* > $* $: $2 + +# authenticated? +R$* $: $1 $| $>"tls_client" $&{verify} $| MAIL +R$* $| $#$+ $#$2 +R$* $| $* $: $1 + +R<> $@ <OK> we MUST accept <> (RFC 1123) +R$+ $: <?> $1 +R<?><$+> $: <@> <$1> +R<?>$+ $: <@> <$1> +R$* $: $&{daemon_flags} $| $1 +R$* f $* $| <@> < $* @ $- > $: < ? $&{client_name} > < $3 @ $4 > +R$* u $* $| <@> < $* > $: <?> < $3 > +R$* $| $* $: $2 +# handle case of @localhost on address +R<@> < $* @ localhost > $: < ? $&{client_name} > < $1 @ localhost > +R<@> < $* @ [127.0.0.1] > + $: < ? $&{client_name} > < $1 @ [127.0.0.1] > +R<@> < $* @ localhost.$m > + $: < ? $&{client_name} > < $1 @ localhost.$m > +R<@> < $* @ localhost.UUCP > + $: < ? $&{client_name} > < $1 @ localhost.UUCP > +R<@> $* $: $1 no localhost as domain +R<? $=w> $* $: $2 local client: ok +R<? $+> <$+> $#error $@ 5.5.4 $: "553 Real domain name required for sender address" +R<?> $* $: $1 +R$* $: <?> $>CanonAddr $1 canonify sender address and mark it +R<?> $* < @ $+ . > <?> $1 < @ $2 > strip trailing dots +# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc) +R<?> $* < @ $* $=P > $: <OKR> $1 < @ $2 $3 > +R<?> $* < @ $j > $: <OKR> $1 < @ $j > +R<?> $* < @ $+ > $: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 > +R<? $* <$->> $* < @ $+ > + $: <$2> $3 < @ $4 > + +# check sender address: user@address, user@, address +R<$+> $+ < @ $* > $: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3> +R<$+> $+ $: @<$1> <$2> $| <U:$2@> +R@ <$+> <$*> $| <$+> $: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <> +R<@> <$+> <$*> $| <$*> $: <$3> <$1> <$2> reverse result +# retransform for further use +R<?> <$+> <$*> $: <$1> $2 no match +R<$+> <$+> <$*> $: <$1> $3 relevant result, keep it + +# handle case of no @domain on address +R<?> $* $: $&{daemon_flags} $| <?> $1 +R$* u $* $| <?> $* $: <OKR> $3 +R$* $| $* $: $2 +R<?> $* $: < ? $&{client_addr} > $1 +R<?> $* $@ <OKR> ...local unqualed ok +R<? $+> $* $#error $@ 5.5.4 $: "553 Domain name required for sender address " $&f + ...remote is not +# check results +R<?> $* $: @ $1 mark address: nothing known about it +R<$={ResOk}> $* $@ <OKR> domain ok: stop +R<TEMP> $* $#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve" +R<PERM> $* $#error $@ 5.1.8 $: "553 Domain of sender address " $&f " does not exist" +R<$={Accept}> $* $# $1 accept from access map +R<DISCARD> $* $#discard $: discard +R<QUARANTINE:$+> $* $#error $@ quarantine $: $1 +R<REJECT> $* $#error $@ 5.7.1 $: "550 Access denied" +R<ERROR:$-.$-.$-:$+> $* $#error $@ $1.$2.$3 $: $4 +R<ERROR:$+> $* $#error $: $1 +R<<TMPF>> $* $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<$+> $* $#error $: $1 error from access db + +###################################################################### +### check_rcpt -- check SMTP `RCPT TO:' command argument +###################################################################### + +SLocal_check_rcpt +Scheckrcpt +R$* $: $1 $| $>"Local_check_rcpt" $1 +R$* $| $#$* $#$2 +R$* $| $* $@ $>"Basic_check_rcpt" $1 + +SBasic_check_rcpt +# empty address? +R<> $#error $@ nouser $: "553 User address required" +R$@ $#error $@ nouser $: "553 User address required" +# check for deferred delivery mode +R$* $: < $&{deliveryMode} > $1 +R< d > $* $@ deferred +R< $* > $* $: $2 + + +###################################################################### +R$* $: $1 $| @ $>"Rcpt_ok" $1 +R$* $| @ $#TEMP $+ $: $1 $| T $2 +R$* $| @ $#$* $#$2 +R$* $| @ RELAY $@ RELAY +R$* $| @ $* $: O $| $>"Relay_ok" $1 +R$* $| T $+ $: T $2 $| $>"Relay_ok" $1 +R$* $| $#TEMP $+ $#error $2 +R$* $| $#$* $#$2 +R$* $| RELAY $@ RELAY +R T $+ $| $* $#error $1 +# anything else is bogus +R$* $#error $@ 5.7.1 $: "550 Relaying denied. Proper authentication required." + + +###################################################################### +### Rcpt_ok: is the recipient ok? +###################################################################### +SRcpt_ok +R$* $: $>ParseRecipient $1 strip relayable hosts + + + + +# authenticated via TLS? +R$* $: $1 $| $>RelayTLS client authenticated? +R$* $| $# $+ $# $2 error/ok? +R$* $| $* $: $1 no + +R$* $: $1 $| $>"Local_Relay_Auth" $&{auth_type} +R$* $| $# $* $# $2 +R$* $| NO $: $1 +R$* $| $* $: $1 $| $&{auth_type} +R$* $| $: $1 +R$* $| $={TrustAuthMech} $# RELAY +R$* $| $* $: $1 +# anything terminating locally is ok +R$+ < @ $=w > $@ RELAY +R$+ < @ $=R > $@ RELAY +R$+ < @ $+ > $: <$(access To:$2 $: ? $)> <$1 < @ $2 >> +R<?> <$+ < @ $+ >> $: <$(access $2 $: ? $)> <$1 < @ $2 >> +R<RELAY> $* $@ RELAY +R<$* <TMPF>> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<$*> <$*> $: $2 + + + +# check for local user (i.e. unqualified address) +R$* $: <?> $1 +R<?> $* < @ $+ > $: <REMOTE> $1 < @ $2 > +# local user is ok +R<?> $+ $@ RELAY +R<$+> $* $: $2 + +###################################################################### +### Relay_ok: is the relay/sender ok? +###################################################################### +SRelay_ok +# anything originating locally is ok +# check IP address +R$* $: $&{client_addr} +R$@ $@ RELAY originated locally +R0 $@ RELAY originated locally +R127.0.0.1 $@ RELAY originated locally +RIPv6:::1 $@ RELAY originated locally +R$=R $* $@ RELAY relayable IP address +R$* $: $>A <$1> <?> <+ Connect> <$1> +R<RELAY> $* $@ RELAY relayable IP address + +R<<TMPF>> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<$*> <$*> $: $2 +R$* $: [ $1 ] put brackets around it... +R$=w $@ RELAY ... and see if it is local + + +# check client name: first: did it resolve? +R$* $: < $&{client_resolve} > +R<TEMP> $#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr} +R<FORGED> $#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name} +R<FAIL> $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name} +R$* $: <@> $&{client_name} +# pass to name server to make hostname canonical +R<@> $* $=P $:<?> $1 $2 +R<@> $+ $:<?> $[ $1 $] +R$* . $1 strip trailing dots +R<?> $=w $@ RELAY +R<?> $=R $@ RELAY +R<?> $* $: <$(access Connect:$1 $: ? $)> <$1> +R<?> <$*> $: <$(access $1 $: ? $)> <$1> +R<RELAY> $* $@ RELAY +R<$* <TMPF>> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<$*> <$*> $: $2 + +# turn a canonical address in the form user<@domain> +# qualify unqual. addresses with $j +SFullAddr +R$* <@ $+ . > $1 <@ $2 > +R$* <@ $* > $@ $1 <@ $2 > +R$+ $@ $1 <@ $j > + +SDelay_TLS_Clt +# authenticated? +R$* $: $1 $| $>"tls_client" $&{verify} $| MAIL +R$* $| $#$+ $#$2 +R$* $| $* $# $1 +R$* $# $1 + +SDelay_TLS_Clt2 +# authenticated? +R$* $: $1 $| $>"tls_client" $&{verify} $| MAIL +R$* $| $#$+ $#$2 +R$* $| $* $@ $1 +R$* $@ $1 + +# call all necessary rulesets +Scheck_rcpt +# R$@ $#error $@ 5.1.3 $: "553 Recipient address required" + +R$+ $: $1 $| $>checkrcpt $1 +R$+ $| $#error $* $#error $2 +R$+ $| $#discard $* $#discard $2 +R$+ $| $#$* $@ $>"Delay_TLS_Clt" $2 +R$+ $| $* $: <?> $>FullAddr $>CanonAddr $1 +R<?> $+ < @ $=w > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@> +R<?> $+ < @ $* > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > +# lookup the addresses only with Spam tag +R<> $* $| <$+> $: <@> $1 $| $>SearchList <! Spam> $| <$2> <> +R<@> $* $| $* $: $2 $1 reverse result +# is the recipient a spam friend? +R<FRIEND> $+ $@ $>"Delay_TLS_Clt2" SPAMFRIEND +R<$*> $+ $: $2 +R$* $: $1 $| $>checkmail <$&f> +R$* $| $#$* $#$2 +R$* $| $* $: $1 $| $>checkrelay $&{client_name} $| $&{client_addr} +R$* $| $#$* $#$2 +R$* $| $* $: $1 + + +###################################################################### +### F: LookUpFull -- search for an entry in access database +### +### lookup of full key (which should be an address) and +### variations if +detail exists: +* and without +detail +### +### Parameters: +### <$1> -- key +### <$2> -- default (what to return if not found in db) +### <$3> -- mark (must be <(!|+) single-token>) +### ! does lookup only with tag +### + does lookup with and without tag +### <$4> -- passthru (additional data passed unchanged through) +###################################################################### + +SF +R<$+> <$*> <$- $-> <$*> $: <$(access $4:$1 $: ? $)> <$1> <$2> <$3 $4> <$5> +R<?> <$+> <$*> <+ $-> <$*> $: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4> +R<?> <$+ + $* @ $+> <$*> <$- $-> <$*> + $: <$(access $6:$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7> +R<?> <$+ + $* @ $+> <$*> <+ $-> <$*> + $: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6> +R<?> <$+ + $* @ $+> <$*> <$- $-> <$*> + $: <$(access $6:$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7> +R<?> <$+ + $* @ $+> <$*> <+ $-> <$*> + $: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6> +R<?> <$+> <$*> <$- $-> <$*> $@ <$2> <$5> +R<$+ <TMPF>> <$*> <$- $-> <$*> $@ <<TMPF>> <$5> +R<$+> <$*> <$- $-> <$*> $@ <$1> <$5> + +###################################################################### +### E: LookUpExact -- search for an entry in access database +### +### Parameters: +### <$1> -- key +### <$2> -- default (what to return if not found in db) +### <$3> -- mark (must be <(!|+) single-token>) +### ! does lookup only with tag +### + does lookup with and without tag +### <$4> -- passthru (additional data passed unchanged through) +###################################################################### + +SE +R<$*> <$*> <$- $-> <$*> $: <$(access $4:$1 $: ? $)> <$1> <$2> <$3 $4> <$5> +R<?> <$+> <$*> <+ $-> <$*> $: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4> +R<?> <$+> <$*> <$- $-> <$*> $@ <$2> <$5> +R<$+ <TMPF>> <$*> <$- $-> <$*> $@ <<TMPF>> <$5> +R<$+> <$*> <$- $-> <$*> $@ <$1> <$5> + +###################################################################### +### U: LookUpUser -- search for an entry in access database +### +### lookup of key (which should be a local part) and +### variations if +detail exists: +* and without +detail +### +### Parameters: +### <$1> -- key (user@) +### <$2> -- default (what to return if not found in db) +### <$3> -- mark (must be <(!|+) single-token>) +### ! does lookup only with tag +### + does lookup with and without tag +### <$4> -- passthru (additional data passed unchanged through) +###################################################################### + +SU +R<$+> <$*> <$- $-> <$*> $: <$(access $4:$1 $: ? $)> <$1> <$2> <$3 $4> <$5> +R<?> <$+> <$*> <+ $-> <$*> $: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4> +R<?> <$+ + $* @> <$*> <$- $-> <$*> + $: <$(access $5:$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6> +R<?> <$+ + $* @> <$*> <+ $-> <$*> + $: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5> +R<?> <$+ + $* @> <$*> <$- $-> <$*> + $: <$(access $5:$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6> +R<?> <$+ + $* @> <$*> <+ $-> <$*> + $: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5> +R<?> <$+> <$*> <$- $-> <$*> $@ <$2> <$5> +R<$+ <TMPF>> <$*> <$- $-> <$*> $@ <<TMPF>> <$5> +R<$+> <$*> <$- $-> <$*> $@ <$1> <$5> + +###################################################################### +### SearchList: search a list of items in the access map +### Parameters: +### <exact tag> $| <mark:address> <mark:address> ... <> +### where "exact" is either "+" or "!": +### <+ TAG> lookup with and w/o tag +### <! TAG> lookup with tag +### possible values for "mark" are: +### D: recursive host lookup (LookUpDomain) +### E: exact lookup, no modifications +### F: full lookup, try user+ext@domain and user@domain +### U: user lookup, try user+ext and user (input must have trailing @) +### return: <RHS of lookup> or <?> (not found) +###################################################################### + +# class with valid marks for SearchList +C{Src}E F D U +SSearchList +# just call the ruleset with the name of the tag... nice trick... +R<$+> $| <$={Src}:$*> <$*> $: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <> +R<$+> $| <> $| <?> <> $@ <?> +R<$+> $| <$+> $| <?> <> $@ $>SearchList <$1> $| <$2> +R<$+> $| <$*> $| <$+> <> $@ <$3> +R<$+> $| <$+> $@ <$2> + + +###################################################################### +### trust_auth: is user trusted to authenticate as someone else? +### +### Parameters: +### $1: AUTH= parameter from MAIL command +###################################################################### + +SLocal_trust_auth +Strust_auth +R$* $: $&{auth_type} $| $1 +# required by RFC 2554 section 4. +R$@ $| $* $#error $@ 5.7.1 $: "550 not authenticated" +R$* $| $&{auth_authen} $@ identical +R$* $| <$&{auth_authen}> $@ identical +R$* $| $* $: $1 $| $>"Local_trust_auth" $2 +R$* $| $#$* $#$2 +R$* $#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author} + +###################################################################### +### Relay_Auth: allow relaying based on authentication? +### +### Parameters: +### $1: ${auth_type} +###################################################################### +SLocal_Relay_Auth + +###################################################################### +### srv_features: which features to offer to a client? +### (done in server) +###################################################################### +Ssrv_features +R$* $: $>D <$&{client_name}> <?> <! "Srv_Features"> <> +R<?>$* $: $>A <$&{client_addr}> <?> <! "Srv_Features"> <> +R<?>$* $: <$(access "Srv_Features": $: ? $)> +R<?>$* $@ OK +R<$* <TMPF>>$* $#temp +R<$+>$* $# $1 + +###################################################################### +### try_tls: try to use STARTTLS? +### (done in client) +###################################################################### +Stry_tls +R$* $: $>D <$&{server_name}> <?> <! "Try_TLS"> <> +R<?>$* $: $>A <$&{server_addr}> <?> <! "Try_TLS"> <> +R<?>$* $: <$(access "Try_TLS": $: ? $)> +R<?>$* $@ OK +R<$* <TMPF>>$* $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R<NO>$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]" + +###################################################################### +### tls_rcpt: is connection with server "good" enough? +### (done in client, per recipient) +### +### Parameters: +### $1: recipient +###################################################################### +Stls_rcpt +R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 +R$+ $: <?> $>CanonAddr $1 +R<?> $+ < @ $+ . > <?> $1 <@ $2 > +R<?> $+ < @ $+ > $: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:> +R<?> $+ $: $1 $| <U:$1@> <E:> +R$* $| $+ $: $1 $| $>SearchList <! "TLS_Rcpt"> $| $2 <> +R$* $| <?> $@ OK +R$* $| <$* <TMPF>> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R$* $| <$+> $@ $>"TLS_connection" $&{verify} $| <$2> + +###################################################################### +### tls_client: is connection with client "good" enough? +### (done in server) +### +### Parameters: +### ${verify} $| (MAIL|STARTTLS) +###################################################################### +Stls_client +R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 +R$* $| $* $: $1 $| $>D <$&{client_name}> <?> <! "TLS_Clt"> <> +R$* $| <?>$* $: $1 $| $>A <$&{client_addr}> <?> <! "TLS_Clt"> <> +R$* $| <?>$* $: $1 $| <$(access "TLS_Clt": $: ? $)> +R$* $| <$* <TMPF>> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R$* $@ $>"TLS_connection" $1 + +###################################################################### +### tls_server: is connection with server "good" enough? +### (done in client) +### +### Parameter: +### ${verify} +###################################################################### +Stls_server +R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 +R$* $: $1 $| $>D <$&{server_name}> <?> <! "TLS_Srv"> <> +R$* $| <?>$* $: $1 $| $>A <$&{server_addr}> <?> <! "TLS_Srv"> <> +R$* $| <?>$* $: $1 $| <$(access "TLS_Srv": $: ? $)> +R$* $| <$* <TMPF>> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R$* $@ $>"TLS_connection" $1 + +###################################################################### +### TLS_connection: is TLS connection "good" enough? +### +### Parameters: +### ${verify} $| <Requirement> [<>] +### Requirement: RHS from access map, may be ? for none. +###################################################################### +STLS_connection +R$* $| <$*>$* $: $1 $| <$2> +# create the appropriate error codes +R$* $| <PERM + $={Tls} $*> $: $1 $| <503:5.7.0> <$2 $3> +R$* $| <TEMP + $={Tls} $*> $: $1 $| <403:4.7.0> <$2 $3> +R$* $| <$={Tls} $*> $: $1 $| <403:4.7.0> <$2 $3> +# deal with TLS handshake failures: abort +RSOFTWARE $| <$-:$+> $* $#error $@ $2 $: $1 " TLS handshake failed." +RSOFTWARE $| $* $#error $@ 4.7.0 $: "403 TLS handshake failed." +R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1 +R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1 +R$* $| <$*> <$={Tls}:$->$* $: <$2> <$3:$4> <> $1 +R$* $| <$*> <$={Tls}:$- + $+>$* $: <$2> <$3:$4> <$5> $1 +R$* $| $* $@ OK +# authentication required: give appropriate error +# other side did authenticate (via STARTTLS) +R<$*><VERIFY> <> OK $@ OK +R<$*><VERIFY> <$+> OK $: <$1> <REQ:0> <$2> +R<$*><VERIFY:$-> <$*> OK $: <$1> <REQ:$2> <$3> +R<$*><ENCR:$-> <$*> $* $: <$1> <REQ:$2> <$3> +R<$-:$+><VERIFY $*> <$*> $#error $@ $2 $: $1 " authentication required" +R<$-:$+><VERIFY $*> <$*> FAIL $#error $@ $2 $: $1 " authentication failed" +R<$-:$+><VERIFY $*> <$*> NO $#error $@ $2 $: $1 " not authenticated" +R<$-:$+><VERIFY $*> <$*> NOT $#error $@ $2 $: $1 " no authentication requested" +R<$-:$+><VERIFY $*> <$*> NONE $#error $@ $2 $: $1 " other side does not support STARTTLS" +R<$-:$+><VERIFY $*> <$*> $+ $#error $@ $2 $: $1 " authentication failure " $4 +R<$*><REQ:$-> <$*> $: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf} +R<$*><REQ:$-> <$*> $- $: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $) +R<$-:$+><$-:$-> <$*> TRUE $#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3 +R<$-:$+><$-:$-> <$*> $* $: <$1:$2 ++ $5> +R<$-:$+ ++ > $@ OK +R<$-:$+ ++ $+ > $: <$1:$2> <$3> +R<$-:$+> < $+ ++ $+ > <$1:$2> <$3> <$4> +R<$-:$+> $+ $@ $>"TLS_req" $3 $| <$1:$2> + +###################################################################### +### TLS_req: check additional TLS requirements +### +### Parameters: [<list> <of> <req>] $| <$-:$+> +### $-: SMTP reply code +### $+: Enhanced Status Code +###################################################################### +STLS_req +R $| $+ $@ OK +R<CN> $* $| <$+> $: <CN:$&{TLS_Name}> $1 $| <$2> +R<CN:$&{cn_subject}> $* $| <$+> $@ $>"TLS_req" $1 $| <$2> +R<CN:$+> $* $| <$-:$+> $#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1 +R<CS:$&{cert_subject}> $* $| <$+> $@ $>"TLS_req" $1 $| <$2> +R<CS:$+> $* $| <$-:$+> $#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1 +R<CI:$&{cert_issuer}> $* $| <$+> $@ $>"TLS_req" $1 $| <$2> +R<CI:$+> $* $| <$-:$+> $#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1 +ROK $@ OK + +###################################################################### +### max: return the maximum of two values separated by : +### +### Parameters: [$-]:[$-] +###################################################################### +Smax +R: $: 0 +R:$- $: $1 +R$-: $: $1 +R$-:$- $: $(arith l $@ $1 $@ $2 $) : $1 : $2 +RTRUE:$-:$- $: $2 +R$-:$-:$- $: $2 + + +###################################################################### +### RelayTLS: allow relaying based on TLS authentication +### +### Parameters: +### none +###################################################################### +SRelayTLS +# authenticated? +R$* $: <?> $&{verify} +R<?> OK $: OK authenticated: continue +R<?> $* $@ NO not authenticated +R$* $: $&{cert_issuer} +R$+ $: $(access CERTISSUER:$1 $) +RRELAY $# RELAY +RSUBJECT $: <@> $&{cert_subject} +R<@> $+ $: <@> $(access CERTSUBJECT:$1 $) +R<@> RELAY $# RELAY +R$* $: NO + +###################################################################### +### authinfo: lookup authinfo in the access map +### +### Parameters: +### $1: {server_name} +### $2: {server_addr} +###################################################################### +Sauthinfo +R$* $: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <> +R$* $| <?>$* $: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <> +R$* $| <?>$* $: $1 $| <$(access AuthInfo: $: ? $)> <> +R$* $| <?>$* $@ no no authinfo available +R$* $| <$*> <> $# $2 + + + + + +# +###################################################################### +###################################################################### +##### +##### MAIL FILTER DEFINITIONS +##### +###################################################################### +###################################################################### + +Xdnsbl, S=local:/var/run/dnsbl/dnsbl.sock2, F=T, T=S:30s;R:30s;E:30s +# +###################################################################### +###################################################################### +##### +##### MAILER DEFINITIONS +##### +###################################################################### +###################################################################### + +##################################### +### SMTP Mailer specification ### +##################################### + +##### $Id$ ##### + +# +# common sender and masquerading recipient rewriting +# +SMasqSMTP +R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified +R$+ $@ $1 < @ *LOCAL* > add local qualification + +# +# convert pseudo-domain addresses to real domain addresses +# +SPseudoToReal + +# pass <route-addr>s through +R< @ $+ > $* $@ < @ $1 > $2 resolve <route-addr> + +# output fake domains as user%fake@relay + +# do UUCP heuristics; note that these are shared with UUCP mailers +R$+ < @ $+ .UUCP. > $: < $2 ! > $1 convert to UUCP form +R$+ < @ $* > $* $@ $1 < @ $2 > $3 not UUCP form + +# leave these in .UUCP form to avoid further tampering +R< $&h ! > $- ! $+ $@ $2 < @ $1 .UUCP. > +R< $&h ! > $-.$+ ! $+ $@ $3 < @ $1.$2 > +R< $&h ! > $+ $@ $1 < @ $&h .UUCP. > +R< $+ ! > $+ $: $1 ! $2 < @ $Y > use UUCP_RELAY +R$+ < @ $~[ $* : $+ > $@ $1 < @ $4 > strip mailer: part +R$+ < @ > $: $1 < @ *LOCAL* > if no UUCP_RELAY + + +# +# envelope sender rewriting +# +SEnvFromSMTP +R$+ $: $>PseudoToReal $1 sender/recipient common +R$* :; <@> $@ list:; special case +R$* $: $>MasqSMTP $1 qualify unqual'ed names +R$+ $: $>MasqEnv $1 do masquerading + + +# +# envelope recipient rewriting -- +# also header recipient if not masquerading recipients +# +SEnvToSMTP +R$+ $: $>PseudoToReal $1 sender/recipient common +R$+ $: $>MasqSMTP $1 qualify unqual'ed names +R$* < @ *LOCAL* > $* $: $1 < @ $j . > $2 + +# +# header sender and masquerading header recipient rewriting +# +SHdrFromSMTP +R$+ $: $>PseudoToReal $1 sender/recipient common +R:; <@> $@ list:; special case + +# do special header rewriting +R$* <@> $* $@ $1 <@> $2 pass null host through +R< @ $* > $* $@ < @ $1 > $2 pass route-addr through +R$* $: $>MasqSMTP $1 qualify unqual'ed names +R$+ $: $>MasqHdr $1 do masquerading + + +# +# relay mailer header masquerading recipient rewriting +# +SMasqRelay +R$+ $: $>MasqSMTP $1 +R$+ $: $>MasqHdr $1 + +Msmtp, P=[IPC], F=mDFMuX, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990, + T=DNS/RFC822/SMTP, + A=TCP $h +Mesmtp, P=[IPC], F=mDFMuXa, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990, + T=DNS/RFC822/SMTP, + A=TCP $h +Msmtp8, P=[IPC], F=mDFMuX8, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990, + T=DNS/RFC822/SMTP, + A=TCP $h +Mdsmtp, P=[IPC], F=mDFMuXa%, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990, + T=DNS/RFC822/SMTP, + A=TCP $h +Mrelay, P=[IPC], F=mDFMuXa8, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L=2040, + T=DNS/RFC822/SMTP, + A=TCP $h + + +######################*****############## +### PROCMAIL Mailer specification ### +##################*****################## + +##### $Id$ ##### + +Mprocmail, P=/usr/bin/procmail, F=DFMSPhnu9, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP/HdrFromSMTP, + T=DNS/RFC822/X-Unix, + A=procmail -Y -m $h $f $u + + +################################################## +### Local and Program Mailer specification ### +################################################## + +##### $Id$ ##### + +# +# Envelope sender rewriting +# +SEnvFromL +R<@> $n errors to mailer-daemon +R@ <@ $*> $n temporarily bypass Sun bogosity +R$+ $: $>AddDomain $1 add local domain if needed +R$* $: $>MasqEnv $1 do masquerading + +# +# Envelope recipient rewriting +# +SEnvToL +R$+ < @ $* > $: $1 strip host part +R$+ + $* $: < $&{addr_type} > $1 + $2 mark with addr type +R<e s> $+ + $* $: $1 remove +detail for sender +R< $* > $+ $: $2 else remove mark + +# +# Header sender rewriting +# +SHdrFromL +R<@> $n errors to mailer-daemon +R@ <@ $*> $n temporarily bypass Sun bogosity +R$+ $: $>AddDomain $1 add local domain if needed +R$* $: $>MasqHdr $1 do masquerading + +# +# Header recipient rewriting +# +SHdrToL +R$+ $: $>AddDomain $1 add local domain if needed +R$* < @ *LOCAL* > $* $: $1 < @ $j . > $2 + +# +# Common code to add local domain name (only if always-add-domain) +# +SAddDomain +R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified + +R$+ $@ $1 < @ *LOCAL* > add local qualification + +Mlocal, P=/usr/bin/procmail, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, + T=DNS/RFC822/X-Unix, + A=procmail -t -Y -a $h -d $u +Mprog, P=/bin/sh, F=lsDFMoqeu9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, D=$z:/, + T=X-Unix/X-Unix/X-Unix, + A=sh -c $u +