xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 13058a91)
1c2aa98e2SPeter Wemmdivert(-1)
2c2aa98e2SPeter Wemm#
306f25ae9SGregory Neil Shapiro# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
406f25ae9SGregory Neil Shapiro#	All rights reserved.
5c2aa98e2SPeter Wemm# Copyright (c) 1983, 1995 Eric P. Allman.  All rights reserved.
6c2aa98e2SPeter Wemm# Copyright (c) 1988, 1993
7c2aa98e2SPeter Wemm#	The Regents of the University of California.  All rights reserved.
8c2aa98e2SPeter Wemm#
9c2aa98e2SPeter Wemm# By using this file, you agree to the terms and conditions set
10c2aa98e2SPeter Wemm# forth in the LICENSE file which can be found at the top level of
11c2aa98e2SPeter Wemm# the sendmail distribution.
12c2aa98e2SPeter Wemm#
13c2aa98e2SPeter Wemm#
14c2aa98e2SPeter Wemmdivert(0)
15c2aa98e2SPeter Wemm
1613058a91SGregory Neil ShapiroVERSIONID(`$Id: proto.m4,v 8.446.2.5.2.44 2001/07/31 22:25:49 gshapiro Exp $')
17c2aa98e2SPeter Wemm
18c2aa98e2SPeter WemmMAILER(local)dnl
19c2aa98e2SPeter Wemm
2006f25ae9SGregory Neil Shapiro# level CF_LEVEL config file format
2106f25ae9SGregory Neil ShapiroV`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley')
22c2aa98e2SPeter Wemmdivert(-1)
23c2aa98e2SPeter Wemm
24c2aa98e2SPeter Wemm# do some sanity checking
25c2aa98e2SPeter Wemmifdef(`__OSTYPE__',,
2606f25ae9SGregory Neil Shapiro	`errprint(`*** ERROR: No system type defined (use OSTYPE macro)
2706f25ae9SGregory Neil Shapiro')')
28c2aa98e2SPeter Wemm
29c2aa98e2SPeter Wemm# pick our default mailers
30c2aa98e2SPeter Wemmifdef(`confSMTP_MAILER',, `define(`confSMTP_MAILER', `esmtp')')
31c2aa98e2SPeter Wemmifdef(`confLOCAL_MAILER',, `define(`confLOCAL_MAILER', `local')')
32c2aa98e2SPeter Wemmifdef(`confRELAY_MAILER',,
33c2aa98e2SPeter Wemm	`define(`confRELAY_MAILER',
34c2aa98e2SPeter Wemm		`ifdef(`_MAILER_smtp_', `relay',
35c2aa98e2SPeter Wemm			`ifdef(`_MAILER_uucp', `uucp-new', `unknown')')')')
36c2aa98e2SPeter Wemmifdef(`confUUCP_MAILER',, `define(`confUUCP_MAILER', `uucp-old')')
37c2aa98e2SPeter Wemmdefine(`_SMTP_', `confSMTP_MAILER')dnl		for readability only
38c2aa98e2SPeter Wemmdefine(`_LOCAL_', `confLOCAL_MAILER')dnl	for readability only
39c2aa98e2SPeter Wemmdefine(`_RELAY_', `confRELAY_MAILER')dnl	for readability only
40c2aa98e2SPeter Wemmdefine(`_UUCP_', `confUUCP_MAILER')dnl		for readability only
41c2aa98e2SPeter Wemm
42c2aa98e2SPeter Wemm# back compatibility with old config files
43c2aa98e2SPeter Wemmifdef(`confDEF_GROUP_ID',
4406f25ae9SGregory Neil Shapiro`errprint(`*** confDEF_GROUP_ID is obsolete.
4506f25ae9SGregory Neil Shapiro    Use confDEF_USER_ID with a colon in the value instead.
4606f25ae9SGregory Neil Shapiro')')
47c2aa98e2SPeter Wemmifdef(`confREAD_TIMEOUT',
4806f25ae9SGregory Neil Shapiro`errprint(`*** confREAD_TIMEOUT is obsolete.
4906f25ae9SGregory Neil Shapiro    Use individual confTO_<timeout> parameters instead.
5006f25ae9SGregory Neil Shapiro')')
51c2aa98e2SPeter Wemmifdef(`confMESSAGE_TIMEOUT',
52c2aa98e2SPeter Wemm	`define(`_ARG_', index(confMESSAGE_TIMEOUT, /))
53c2aa98e2SPeter Wemm	 ifelse(_ARG_, -1,
54c2aa98e2SPeter Wemm		`define(`confTO_QUEUERETURN', confMESSAGE_TIMEOUT)',
55c2aa98e2SPeter Wemm		`define(`confTO_QUEUERETURN',
56c2aa98e2SPeter Wemm			substr(confMESSAGE_TIMEOUT, 0, _ARG_))
57c2aa98e2SPeter Wemm		 define(`confTO_QUEUEWARN',
58c2aa98e2SPeter Wemm			substr(confMESSAGE_TIMEOUT, eval(_ARG_+1)))')')
59c2aa98e2SPeter Wemmifdef(`confMIN_FREE_BLOCKS', `ifelse(index(confMIN_FREE_BLOCKS, /), -1,,
6006f25ae9SGregory Neil Shapiro`errprint(`*** compound confMIN_FREE_BLOCKS is obsolete.
6106f25ae9SGregory Neil Shapiro    Use confMAX_MESSAGE_SIZE for the second part of the value.
6206f25ae9SGregory Neil Shapiro')')')
6306f25ae9SGregory Neil Shapiro
6406f25ae9SGregory Neil Shapiro
6506f25ae9SGregory Neil Shapiro# Sanity check on ldap_routing feature
6606f25ae9SGregory Neil Shapiro# If the user doesn't specify a new map, they better have given as a
6706f25ae9SGregory Neil Shapiro# default LDAP specification which has the LDAP base (and most likely the host)
6806f25ae9SGregory Neil Shapiroifdef(`confLDAP_DEFAULT_SPEC',, `ifdef(`_LDAP_ROUTING_WARN_', `errprint(`
6906f25ae9SGregory Neil ShapiroWARNING: Using default FEATURE(ldap_routing) map definition(s)
7006f25ae9SGregory Neil Shapirowithout setting confLDAP_DEFAULT_SPEC option.
7106f25ae9SGregory Neil Shapiro')')')dnl
72c2aa98e2SPeter Wemm
73c2aa98e2SPeter Wemm# clean option definitions below....
7406f25ae9SGregory Neil Shapirodefine(`_OPTION', `ifdef(`$2', `O $1`'ifelse(defn(`$2'), `',, `=$2')', `#O $1`'ifelse(`$3', `',,`=$3')')')dnl
75c2aa98e2SPeter Wemm
7606f25ae9SGregory Neil Shapirodnl required to "rename" the check_* rulesets...
7706f25ae9SGregory Neil Shapirodefine(`_U_',ifdef(`_DELAY_CHECKS_',`',`_'))
7806f25ae9SGregory Neil Shapirodnl default relaying denied message
7906f25ae9SGregory Neil Shapiroifdef(`confRELAY_MSG', `', `define(`confRELAY_MSG', `"550 Relaying denied"')')
808774250cSGregory Neil Shapirodefine(`CODE553', `553')
81c2aa98e2SPeter Wemmdivert(0)dnl
82c2aa98e2SPeter Wemm
8306f25ae9SGregory Neil Shapiro# override file safeties - setting this option compromises system security,
8406f25ae9SGregory Neil Shapiro# addressing the actual file configuration problem is preferred
8506f25ae9SGregory Neil Shapiro# need to set this before any file actions are encountered in the cf file
8606f25ae9SGregory Neil Shapiro_OPTION(DontBlameSendmail, `confDONT_BLAME_SENDMAIL', `safe')
8706f25ae9SGregory Neil Shapiro
8806f25ae9SGregory Neil Shapiro# default LDAP map specification
8906f25ae9SGregory Neil Shapiro# need to set this now before any LDAP maps are defined
9006f25ae9SGregory Neil Shapiro_OPTION(LDAPDefaultSpec, `confLDAP_DEFAULT_SPEC', `-h localhost')
91c2aa98e2SPeter Wemm
92c2aa98e2SPeter Wemm##################
93c2aa98e2SPeter Wemm#   local info   #
94c2aa98e2SPeter Wemm##################
95c2aa98e2SPeter Wemm
96c2aa98e2SPeter WemmCwlocalhost
97c2aa98e2SPeter Wemmifdef(`USE_CW_FILE',
98c2aa98e2SPeter Wemm`# file containing names of hosts for which we receive email
99c2aa98e2SPeter WemmFw`'confCW_FILE',
100c2aa98e2SPeter Wemm	`dnl')
101c2aa98e2SPeter Wemm
102c2aa98e2SPeter Wemm# my official domain name
103c2aa98e2SPeter Wemm# ... `define' this only if sendmail cannot automatically determine your domain
104c2aa98e2SPeter Wemmifdef(`confDOMAIN_NAME', `Dj`'confDOMAIN_NAME', `#Dj$w.Foo.COM')
105c2aa98e2SPeter Wemm
106c2aa98e2SPeter WemmCP.
107c2aa98e2SPeter Wemm
108c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
109c2aa98e2SPeter Wemm`# UUCP relay host
110c2aa98e2SPeter WemmDY`'UUCP_RELAY
111c2aa98e2SPeter WemmCPUUCP
112c2aa98e2SPeter Wemm
113c2aa98e2SPeter Wemm')dnl
114c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
115c2aa98e2SPeter Wemm`#  BITNET relay host
116c2aa98e2SPeter WemmDB`'BITNET_RELAY
117c2aa98e2SPeter WemmCPBITNET
118c2aa98e2SPeter Wemm
119c2aa98e2SPeter Wemm')dnl
120c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
121c2aa98e2SPeter Wemm`define(`_USE_DECNET_SYNTAX_', 1)dnl
122c2aa98e2SPeter Wemm# DECnet relay host
123c2aa98e2SPeter WemmDC`'DECNET_RELAY
124c2aa98e2SPeter WemmCPDECNET
125c2aa98e2SPeter Wemm
126c2aa98e2SPeter Wemm')dnl
127c2aa98e2SPeter Wemmifdef(`FAX_RELAY',
128c2aa98e2SPeter Wemm`# FAX relay host
129c2aa98e2SPeter WemmDF`'FAX_RELAY
130c2aa98e2SPeter WemmCPFAX
131c2aa98e2SPeter Wemm
132c2aa98e2SPeter Wemm')dnl
133c2aa98e2SPeter Wemm# "Smart" relay host (may be null)
134c2aa98e2SPeter WemmDS`'ifdef(`SMART_HOST', SMART_HOST)
135c2aa98e2SPeter Wemm
136c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
137c2aa98e2SPeter Wemm# place to which unknown users should be forwarded
138c2aa98e2SPeter WemmKuser user -m -a<>
139c2aa98e2SPeter WemmDL`'LUSER_RELAY',
140c2aa98e2SPeter Wemm`dnl')
141c2aa98e2SPeter Wemm
142c2aa98e2SPeter Wemm# operators that cannot be in local usernames (i.e., network indicators)
143c2aa98e2SPeter WemmCO @ % ifdef(`_NO_UUCP_', `', `!')
144c2aa98e2SPeter Wemm
145c2aa98e2SPeter Wemm# a class with just dot (for identifying canonical names)
146c2aa98e2SPeter WemmC..
147c2aa98e2SPeter Wemm
148c2aa98e2SPeter Wemm# a class with just a left bracket (for identifying domain literals)
149c2aa98e2SPeter WemmC[[
150c2aa98e2SPeter Wemm
15106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
15206f25ae9SGregory Neil Shapiro# access_db acceptance class
15306f25ae9SGregory Neil ShapiroC{Accept}OK RELAY
15406f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
15506f25ae9SGregory Neil Shapiroifdef(`_BLACKLIST_RCPT_',`dnl
15606f25ae9SGregory Neil Shapiro# possible access_db RHS for spam friends/haters
15706f25ae9SGregory Neil ShapiroC{SpamTag}SPAMFRIEND SPAMHATER')')',
158c2aa98e2SPeter Wemm`dnl')
159c2aa98e2SPeter Wemm
160c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',`dnl',`dnl
161c2aa98e2SPeter Wemm# Resolve map (to check if a host exists in check_mail)
162c2aa98e2SPeter WemmKresolve host -a<OK> -T<TEMP>')
163c2aa98e2SPeter Wemm
16413058a91SGregory Neil Shapiroifdef(`_NEED_MACRO_MAP_', `dnl
16513058a91SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
16613058a91SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
16713058a91SGregory Neil ShapiroKmacro macro')', `dnl')
16842e5d165SGregory Neil Shapiro
169c2aa98e2SPeter Wemmifdef(`confCR_FILE', `dnl
17042e5d165SGregory Neil Shapiro# Hosts for which relaying is permitted ($=R)
171c2aa98e2SPeter WemmFR`'confCR_FILE',
172c2aa98e2SPeter Wemm`dnl')
173c2aa98e2SPeter Wemm
17406f25ae9SGregory Neil Shapirodefine(`TLS_SRV_TAG', `TLS_Srv')dnl
17506f25ae9SGregory Neil Shapirodefine(`TLS_CLT_TAG', `TLS_Clt')dnl
17606f25ae9SGregory Neil Shapirodefine(`TLS_TRY_TAG', `Try_TLS')dnl
17706f25ae9SGregory Neil Shapirodefine(`TLS_OFF_TAG', `Offer_TLS')dnl
17806f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
17906f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
18006f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
18106f25ae9SGregory Neil ShapiroKarith arith')
18206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
18306f25ae9SGregory Neil Shapiro# possible values for tls_connect in access map
18406f25ae9SGregory Neil ShapiroC{tls}VERIFY ENCR', `dnl')
18506f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
18606f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
18706f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
18806f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
18906f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
19006f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
19106f25ae9SGregory Neil Shapiro
192c2aa98e2SPeter Wemm# who I send unqualified names to (null means deliver locally)
193c2aa98e2SPeter WemmDR`'ifdef(`LOCAL_RELAY', LOCAL_RELAY)
194c2aa98e2SPeter Wemm
195c2aa98e2SPeter Wemm# who gets all local email traffic ($R has precedence for unqualified names)
196c2aa98e2SPeter WemmDH`'ifdef(`MAIL_HUB', MAIL_HUB)
197c2aa98e2SPeter Wemm
198c2aa98e2SPeter Wemm# dequoting map
199c2aa98e2SPeter WemmKdequote dequote
200c2aa98e2SPeter Wemm
201c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
202c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
20306f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
204c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
20506f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
206c2aa98e2SPeter Wemm#CL root
207c2aa98e2SPeter Wemmundivert(5)dnl
20806f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
209c2aa98e2SPeter Wemm
210c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
211c2aa98e2SPeter WemmDM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME)
212c2aa98e2SPeter Wemm
213c2aa98e2SPeter Wemm# my name for error messages
214c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
215c2aa98e2SPeter Wemm
21606f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
217c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
218c2aa98e2SPeter Wemm
219c2aa98e2SPeter Wemm###############
220c2aa98e2SPeter Wemm#   Options   #
221c2aa98e2SPeter Wemm###############
222c2aa98e2SPeter Wemm
223c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
22406f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
225c2aa98e2SPeter Wemm
226c2aa98e2SPeter Wemm# 8-bit data handling
2278774250cSGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
228c2aa98e2SPeter Wemm
229c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
23006f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
231c2aa98e2SPeter Wemm
232c2aa98e2SPeter Wemm# location of alias file
23306f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
23406f25ae9SGregory Neil Shapiro
235c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
23606f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
237c2aa98e2SPeter Wemm
238c2aa98e2SPeter Wemm# maximum message size
23906f25ae9SGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `1000000')
240c2aa98e2SPeter Wemm
241c2aa98e2SPeter Wemm# substitution for space (blank) characters
24206f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
243c2aa98e2SPeter Wemm
244c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
24506f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
246c2aa98e2SPeter Wemm
247c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
24806f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
249c2aa98e2SPeter Wemm
250c2aa98e2SPeter Wemm# default delivery mode
25106f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
252c2aa98e2SPeter Wemm
253c2aa98e2SPeter Wemm# automatically rebuild the alias database?
25406f25ae9SGregory Neil Shapiro# NOTE: There is a potential for a denial of service attack if this is set.
25506f25ae9SGregory Neil Shapiro#       This option is deprecated and will be removed from a future version.
25606f25ae9SGregory Neil Shapiro_OPTION(AutoRebuildAliases, `confAUTO_REBUILD', `False')
257c2aa98e2SPeter Wemm
258c2aa98e2SPeter Wemm# error message header/file
25906f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
260c2aa98e2SPeter Wemm
261c2aa98e2SPeter Wemm# error mode
26206f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
263c2aa98e2SPeter Wemm
264c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
26506f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
266c2aa98e2SPeter Wemm
267c2aa98e2SPeter Wemm# temporary file mode
26806f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
269c2aa98e2SPeter Wemm
270c2aa98e2SPeter Wemm# match recipients against GECOS field?
27106f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
272c2aa98e2SPeter Wemm
273c2aa98e2SPeter Wemm# maximum hop count
27406f25ae9SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `17')
275c2aa98e2SPeter Wemm
276c2aa98e2SPeter Wemm# location of help file
27706f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
278c2aa98e2SPeter Wemm
279c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
28006f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
281c2aa98e2SPeter Wemm
282c2aa98e2SPeter Wemm# name resolver options
28306f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
284c2aa98e2SPeter Wemm
285c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
28606f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
287c2aa98e2SPeter Wemm
288c2aa98e2SPeter Wemm# Forward file search path
28906f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
290c2aa98e2SPeter Wemm
291c2aa98e2SPeter Wemm# open connection cache size
29206f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
293c2aa98e2SPeter Wemm
294c2aa98e2SPeter Wemm# open connection cache timeout
29506f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
296c2aa98e2SPeter Wemm
297c2aa98e2SPeter Wemm# persistent host status directory
29806f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
299c2aa98e2SPeter Wemm
300c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
30106f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
302c2aa98e2SPeter Wemm
303c2aa98e2SPeter Wemm# use Errors-To: header?
30406f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
305c2aa98e2SPeter Wemm
306c2aa98e2SPeter Wemm# log level
30706f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
308c2aa98e2SPeter Wemm
309c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
31006f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
311c2aa98e2SPeter Wemm
312c2aa98e2SPeter Wemm# verify RHS in newaliases?
31306f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
314c2aa98e2SPeter Wemm
315c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
31606f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
317c2aa98e2SPeter Wemm
318c2aa98e2SPeter Wemm# SMTP daemon options
31906f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
32006f25ae9SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.  See cf/README for more information.
32106f25ae9SGregory Neil Shapiro)'dnl
32206f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
32342e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
32442e5d165SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-IPv4, Family=inet
32542e5d165SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-IPv6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
32606f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
32706f25ae9SGregory Neil Shapiro
32806f25ae9SGregory Neil Shapiro# SMTP client options
32906f25ae9SGregory Neil Shapiro_OPTION(ClientPortOptions, `confCLIENT_OPTIONS', `Address=0.0.0.0')
330c2aa98e2SPeter Wemm
331c2aa98e2SPeter Wemm# privacy flags
33206f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
333c2aa98e2SPeter Wemm
334c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
33506f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
336c2aa98e2SPeter Wemm
337c2aa98e2SPeter Wemm# slope of queue-only function
33806f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
339c2aa98e2SPeter Wemm
340c2aa98e2SPeter Wemm# queue directory
34106f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
342c2aa98e2SPeter Wemm
343c2aa98e2SPeter Wemm# timeouts (many of these)
34406f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
34506f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
34606f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
34706f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
34806f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
34906f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
35006f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
35106f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
35206f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
35306f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
35406f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
35506f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
35606f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
35706f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
35806f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
35906f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
36006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
36106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
36206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
36306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
36406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
36506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
36606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
36706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
36806f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
36906f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
37006f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
37106f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
37206f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
37306f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
37406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
375c2aa98e2SPeter Wemm
376c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
37706f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
378c2aa98e2SPeter Wemm
379c2aa98e2SPeter Wemm# queue up everything before forking?
38006f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
381c2aa98e2SPeter Wemm
382c2aa98e2SPeter Wemm# status file
38306f25ae9SGregory Neil ShapiroO StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', `MAIL_SETTINGS_DIR`'statistics')
384c2aa98e2SPeter Wemm
385c2aa98e2SPeter Wemm# time zone handling:
386c2aa98e2SPeter Wemm#  if undefined, use system default
387c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
388c2aa98e2SPeter Wemm#  if defined and non-null, use that info
389c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
390c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
391c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
392c2aa98e2SPeter Wemm
393c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
39406f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
395c2aa98e2SPeter Wemm
396c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
39706f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
398c2aa98e2SPeter Wemm
399c2aa98e2SPeter Wemm# fallback MX host
40006f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
401c2aa98e2SPeter Wemm
402c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
40306f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
404c2aa98e2SPeter Wemm
405c2aa98e2SPeter Wemm# load average at which we just queue messages
40606f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
407c2aa98e2SPeter Wemm
408c2aa98e2SPeter Wemm# load average at which we refuse connections
40906f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
410c2aa98e2SPeter Wemm
411c2aa98e2SPeter Wemm# maximum number of children we allow at one time
41206f25ae9SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `12')
413c2aa98e2SPeter Wemm
414c2aa98e2SPeter Wemm# maximum number of new connections per second
415193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
416c2aa98e2SPeter Wemm
417c2aa98e2SPeter Wemm# work recipient factor
41806f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
419c2aa98e2SPeter Wemm
420c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
42106f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
422c2aa98e2SPeter Wemm
423c2aa98e2SPeter Wemm# work class factor
42406f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
425c2aa98e2SPeter Wemm
426c2aa98e2SPeter Wemm# work time factor
42706f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
428c2aa98e2SPeter Wemm
429c2aa98e2SPeter Wemm# shall we sort the queue by hostname first?
43006f25ae9SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
431c2aa98e2SPeter Wemm
432c2aa98e2SPeter Wemm# minimum time in queue before retry
43306f25ae9SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
434c2aa98e2SPeter Wemm
435c2aa98e2SPeter Wemm# default character set
43606f25ae9SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `iso-8859-1')
437c2aa98e2SPeter Wemm
438c2aa98e2SPeter Wemm# service switch file (ignored on Solaris, Ultrix, OSF/1, others)
43906f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
440c2aa98e2SPeter Wemm
441c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
44206f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
443c2aa98e2SPeter Wemm
444c2aa98e2SPeter Wemm# dialup line delay on connection failure
44506f25ae9SGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `10s')
446c2aa98e2SPeter Wemm
447c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
44806f25ae9SGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `add-to-undisclosed')
449c2aa98e2SPeter Wemm
450c2aa98e2SPeter Wemm# chrooted environment for writing to files
45106f25ae9SGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `/arch')
452c2aa98e2SPeter Wemm
453c2aa98e2SPeter Wemm# are colons OK in addresses?
45406f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
455c2aa98e2SPeter Wemm
456c2aa98e2SPeter Wemm# how many jobs can you process in the queue?
45706f25ae9SGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `10000')
458c2aa98e2SPeter Wemm
459c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
46006f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
461c2aa98e2SPeter Wemm
462c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
46306f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
464c2aa98e2SPeter Wemm
465c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
46606f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
467c2aa98e2SPeter Wemm
468c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
46906f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
470c2aa98e2SPeter Wemm
471c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
47206f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
473c2aa98e2SPeter Wemm
474c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
47506f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
476c2aa98e2SPeter Wemm
477c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
47806f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
479c2aa98e2SPeter Wemm
480c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
48106f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
482c2aa98e2SPeter Wemm
483c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
48406f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
485c2aa98e2SPeter Wemm
486c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
48706f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
48806f25ae9SGregory Neil Shapiro
48906f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
49006f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
491c2aa98e2SPeter Wemm
492c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
49306f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
494c2aa98e2SPeter Wemm
495c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
49606f25ae9SGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `100')
497c2aa98e2SPeter Wemm
498c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
49906f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
500c2aa98e2SPeter Wemm
50106f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
50206f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
50306f25ae9SGregory Neil Shapiro
50406f25ae9SGregory Neil Shapiro# override connection address (for testing)
50506f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
50606f25ae9SGregory Neil Shapiro
50706f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
50806f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
50906f25ae9SGregory Neil Shapiro
51006f25ae9SGregory Neil Shapiro# Control socket for daemon management
51106f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
51206f25ae9SGregory Neil Shapiro
51306f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
51406f25ae9SGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
51506f25ae9SGregory Neil Shapiro
51606f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
51706f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
51806f25ae9SGregory Neil Shapiro
51906f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
52006f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
52106f25ae9SGregory Neil Shapiro
52206f25ae9SGregory Neil Shapiro# location of pid file
52306f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
52406f25ae9SGregory Neil Shapiro
52506f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
52606f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
52706f25ae9SGregory Neil Shapiro
52806f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
52906f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
53006f25ae9SGregory Neil Shapiro
53106f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
53206f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
53306f25ae9SGregory Neil Shapiro
53406f25ae9SGregory Neil Shapiro# list of authentication mechanisms
53506f25ae9SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
53606f25ae9SGregory Neil Shapiro
53706f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
53806f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
53906f25ae9SGregory Neil Shapiro
54006f25ae9SGregory Neil Shapiro# SMTP AUTH flags
54106f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
54206f25ae9SGregory Neil Shapiro
54306f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
54406f25ae9SGregory Neil Shapiro# Input mail filters
54506f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
54606f25ae9SGregory Neil Shapiro
54706f25ae9SGregory Neil Shapiro# Milter options
54806f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
54906f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
55006f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
55106f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')')
55206f25ae9SGregory Neil Shapiro
55306f25ae9SGregory Neil Shapiro# CA directory
55406f25ae9SGregory Neil Shapiro_OPTION(CACERTPath, `confCACERT_PATH', `')
55506f25ae9SGregory Neil Shapiro# CA file
55606f25ae9SGregory Neil Shapiro_OPTION(CACERTFile, `confCACERT', `')
55706f25ae9SGregory Neil Shapiro# Server Cert
55806f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
55906f25ae9SGregory Neil Shapiro# Server private key
56006f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
56106f25ae9SGregory Neil Shapiro# Client Cert
56206f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
56306f25ae9SGregory Neil Shapiro# Client private key
56406f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
56506f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
56606f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
56706f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
56806f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
56906f25ae9SGregory Neil Shapiro
57006f25ae9SGregory Neil Shapiroifdef(`confQUEUE_FILE_MODE',
57106f25ae9SGregory Neil Shapiro`# queue file mode (qf files)
57206f25ae9SGregory Neil ShapiroO QueueFileMode=confQUEUE_FILE_MODE
57325bab6e9SPeter Wemm')
574065a643dSPeter Wemm
575c2aa98e2SPeter Wemm###########################
576c2aa98e2SPeter Wemm#   Message precedences   #
577c2aa98e2SPeter Wemm###########################
578c2aa98e2SPeter Wemm
579c2aa98e2SPeter WemmPfirst-class=0
580c2aa98e2SPeter WemmPspecial-delivery=100
581c2aa98e2SPeter WemmPlist=-30
582c2aa98e2SPeter WemmPbulk=-60
583c2aa98e2SPeter WemmPjunk=-100
584c2aa98e2SPeter Wemm
585c2aa98e2SPeter Wemm#####################
586c2aa98e2SPeter Wemm#   Trusted users   #
587c2aa98e2SPeter Wemm#####################
588c2aa98e2SPeter Wemm
589c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
59006f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
591c2aa98e2SPeter WemmTroot
592c2aa98e2SPeter WemmTdaemon
593c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
594c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
595c2aa98e2SPeter Wemm
596c2aa98e2SPeter Wemm#########################
597c2aa98e2SPeter Wemm#   Format of headers   #
598c2aa98e2SPeter Wemm#########################
599c2aa98e2SPeter Wemm
600c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
601c2aa98e2SPeter WemmH?P?Return-Path: <$g>
602c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
603c2aa98e2SPeter WemmH?D?Resent-Date: $a
604c2aa98e2SPeter WemmH?D?Date: $a
605c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
606c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
607c2aa98e2SPeter WemmH?x?Full-Name: $x
608c2aa98e2SPeter Wemm# HPosted-Date: $a
609c2aa98e2SPeter Wemm# H?l?Received-Date: $b
610c2aa98e2SPeter WemmH?M?Resent-Message-Id: <$t.$i@$j>
611c2aa98e2SPeter WemmH?M?Message-Id: <$t.$i@$j>
61206f25ae9SGregory Neil Shapiro
613c2aa98e2SPeter Wemm#
614c2aa98e2SPeter Wemm######################################################################
615c2aa98e2SPeter Wemm######################################################################
616c2aa98e2SPeter Wemm#####
617c2aa98e2SPeter Wemm#####			REWRITING RULES
618c2aa98e2SPeter Wemm#####
619c2aa98e2SPeter Wemm######################################################################
620c2aa98e2SPeter Wemm######################################################################
621c2aa98e2SPeter Wemm
622c2aa98e2SPeter Wemm############################################
623c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
624c2aa98e2SPeter Wemm############################################
62506f25ae9SGregory Neil ShapiroScanonify=3
626c2aa98e2SPeter Wemm
627c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
628c2aa98e2SPeter WemmR$@			$@ <@>
629c2aa98e2SPeter Wemm
630c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
631c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
632c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
633c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
634c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
635c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
63613058a91SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
637c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
638c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
639c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
640c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
641193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
642c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
643c2aa98e2SPeter Wemm
644c2aa98e2SPeter Wemm# null input now results from list:; syntax
645c2aa98e2SPeter WemmR$@			$@ :; <@>
646c2aa98e2SPeter Wemm
647c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
648c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
649c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
650c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
651c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
652c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
653c2aa98e2SPeter Wemm
65406f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
655c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
656c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
657c2aa98e2SPeter Wemm
658c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
65906f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
66006f25ae9SGregory Neil Shapirodnl',`dnl
66106f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
66206f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
66306f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
66406f25ae9SGregory Neil Shapirodnl')
665c2aa98e2SPeter Wemm
666c2aa98e2SPeter Wemm# find focus for list syntax
66706f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
668c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
669c2aa98e2SPeter Wemm
670c2aa98e2SPeter Wemm# find focus for @ syntax addresses
671c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
672c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
67306f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
674c2aa98e2SPeter Wemm
675c2aa98e2SPeter Wemm# do some sanity checking
676c2aa98e2SPeter WemmR$* < @ $* : $* > $*	$1 < @ $2 $3 > $4		nix colons in addrs
677c2aa98e2SPeter Wemm
678c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
679c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
68006f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
68106f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
68206f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
683c2aa98e2SPeter Wemm')
684c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
685c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
68606f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
68706f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
688c2aa98e2SPeter Wemm',
689c2aa98e2SPeter Wemm	`dnl')
690c2aa98e2SPeter Wemm# if we have % signs, take the rightmost one
691c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
692c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
69306f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
694c2aa98e2SPeter Wemm
695c2aa98e2SPeter Wemm# else we must be a local name
69606f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
697c2aa98e2SPeter Wemm
698c2aa98e2SPeter Wemm
699c2aa98e2SPeter Wemm################################################
700c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
701c2aa98e2SPeter Wemm################################################
702c2aa98e2SPeter Wemm
70306f25ae9SGregory Neil ShapiroSCanonify2=96
704c2aa98e2SPeter Wemm
705c2aa98e2SPeter Wemm# handle special cases for local names
706c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
707c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
708c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
709c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
71006f25ae9SGregory Neil Shapiro
71106f25ae9SGregory Neil Shapiro# check for IPv6 domain literal (save quoted form)
71213058a91SGregory Neil ShapiroR$* < @ [ IPv6 : $+ ] > $*	$: $2 $| $1 < @@ [ $(dequote $2 $) ] > $3	mark IPv6 addr
71313058a91SGregory Neil ShapiroR$+ $| $* < @@ $=w > $*		$: $2 < @ $j . > $4		self-literal
71413058a91SGregory Neil ShapiroR$+ $| $* < @@ [ $+ ] > $*	$@ $2 < @ [ IPv6 : $1 ] > $4	canon IP addr
71506f25ae9SGregory Neil Shapiro
71606f25ae9SGregory Neil Shapiro# check for IPv4 domain literal
717c2aa98e2SPeter WemmR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [a.b.c.d]
718c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
719c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
720c2aa98e2SPeter Wemm
72106f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
722c2aa98e2SPeter Wemm# look up domains in the domain table
723c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
724c2aa98e2SPeter Wemm
72506f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
726c2aa98e2SPeter Wemm
72706f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
728c2aa98e2SPeter Wemm# handle BITNET mapping
729c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
730c2aa98e2SPeter Wemm
73106f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
732c2aa98e2SPeter Wemm# handle UUCP mapping
733c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
734c2aa98e2SPeter Wemm
735c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
736c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
737c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
738c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
739c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
740c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
741c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
742c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
743c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
744c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
745c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
746c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
747c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
748c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
749c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
750c2aa98e2SPeter Wemm
751c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
752c2aa98e2SPeter Wemm# try UUCP traffic as a local address
753c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
754c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
755c2aa98e2SPeter Wemm')')
75606f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
75706f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
75806f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
75906f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
76006f25ae9SGregory Neil Shapirodnl which daemon flags are set?
76106f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
76206f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
76306f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
76406f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
76506f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
76606f25ae9SGregory Neil Shapirodnl do not canonify unless:
76706f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
76806f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
76906f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
77006f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
77106f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
77206f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
77306f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
77406f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
77506f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
77606f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
77706f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
77806f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
77906f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
78006f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
78106f25ae9SGregory Neil Shapirodnl then $- does not work.
78206f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
78306f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*	$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
78406f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
78506f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
786193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
787193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
788193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
78906f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
790c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
79106f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
79206f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
79306f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
794c2aa98e2SPeter Wemm
795c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
796c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
797c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
798c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
799c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
80006f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
80106f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
80206f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
80306f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
80406f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
80506f25ae9SGregory Neil Shapiro`dnl')
80606f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
80706f25ae9SGregory Neil Shapirodnl by one of the rules before
808c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
809c2aa98e2SPeter Wemm
810c2aa98e2SPeter Wemm
811c2aa98e2SPeter Wemm##################################################
812c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
813c2aa98e2SPeter Wemm##################################################
81406f25ae9SGregory Neil ShapiroSfinal=4
815c2aa98e2SPeter Wemm
816193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
817c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
818c2aa98e2SPeter Wemm
819c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
820c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
821c2aa98e2SPeter Wemm
82206f25ae9SGregory Neil Shapiro# eliminate internal code
823c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
824c2aa98e2SPeter Wemm
825c2aa98e2SPeter Wemm# externalize local domain info
826c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
827c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
828c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
829c2aa98e2SPeter Wemm
830c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
831c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
832c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
833c2aa98e2SPeter Wemm
834c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
835c2aa98e2SPeter Wemm`# put DECnet back in :: form
836c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
837c2aa98e2SPeter Wemm	`dnl')
838c2aa98e2SPeter Wemm# delete duplicate local names
839c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
840c2aa98e2SPeter Wemm
841c2aa98e2SPeter Wemm
842c2aa98e2SPeter Wemm
843c2aa98e2SPeter Wemm##############################################################
844c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
845c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
846c2aa98e2SPeter Wemm##############################################################
847c2aa98e2SPeter Wemm
84806f25ae9SGregory Neil ShapiroSRecurse=97
84906f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
85006f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
851c2aa98e2SPeter Wemm
852c2aa98e2SPeter Wemm
853c2aa98e2SPeter Wemm######################################
854c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
855c2aa98e2SPeter Wemm######################################
856c2aa98e2SPeter Wemm
85706f25ae9SGregory Neil ShapiroSparse=0
858c2aa98e2SPeter Wemm
859c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
860c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
86106f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
862c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
863c2aa98e2SPeter Wemm
864c2aa98e2SPeter Wemm#
865c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
866c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
867c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
868c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
869c2aa98e2SPeter Wemm#
870c2aa98e2SPeter Wemm
871c2aa98e2SPeter WemmSParse0
872c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
8738774250cSGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "CODE553 List:; syntax illegal for recipient addresses"
87406f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
8758774250cSGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "CODE553 User address required"
876c2aa98e2SPeter WemmR$*			$: <> $1
877c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*	$1 < @ [ $2 ] > $3
8788774250cSGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "CODE553 Colon illegal in host name part"
879c2aa98e2SPeter WemmR<> $*			$1
8808774250cSGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "CODE553 Invalid host name"
8818774250cSGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "CODE553 Invalid host name"
88206f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
8838774250cSGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.2 $: "CODE553 Invalid route address"
884c2aa98e2SPeter Wemm
885c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
88606f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
88706f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
888c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
8898774250cSGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "CODE553 User address required"
89006f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
891c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
8928774250cSGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "CODE553 User address required"
893c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
89406f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
895c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
896c2aa98e2SPeter Wemm
897c2aa98e2SPeter Wemm#
898c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
899c2aa98e2SPeter Wemm#
900c2aa98e2SPeter Wemm
901c2aa98e2SPeter WemmSParse1
90206f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
90306f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
90406f25ae9SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2>',
905c2aa98e2SPeter Wemm`dnl')
906c2aa98e2SPeter Wemm
90706f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
90806f25ae9SGregory Neil Shapiro`# handle numeric address spec
90906f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
91006f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
91106f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$1 < @ [ $2 ] : $S > $3		Add smart host to path
91213058a91SGregory Neil ShapiroR$* < @ [ IPv6 : $+ ] : > $*
91313058a91SGregory Neil Shapiro		$#_SMTP_ $@ [ $(dequote $2 $) ] $: $1 < @ [IPv6 : $2 ] > $3	no smarthost: send
91406f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*	$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
91506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
91606f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
91706f25ae9SGregory Neil Shapiro	`dnl')
91806f25ae9SGregory Neil Shapiro
91906f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
920c2aa98e2SPeter Wemm# handle virtual users
92106f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
92206f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
92306f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
92406f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
92506f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
926c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
92706f25ae9SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
928c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
929c2aa98e2SPeter Wemm			$: < $(virtuser $1 @ $3 $@ $1 $: @ $) > $1 + $2 < @ $3 . >
93006f25ae9SGregory Neil Shapirodnl try default entry: @domain
93106f25ae9SGregory Neil Shapirodnl +*@domain
93206f25ae9SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
93306f25ae9SGregory Neil Shapirodnl @domain if +detail exists
93406f25ae9SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
93506f25ae9SGregory Neil Shapirodnl without +detail (or no match)
936c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
937c2aa98e2SPeter WemmR<@> $+			$: $1
93806f25ae9SGregory Neil ShapiroR<!> $+			$: $1
93906f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
940c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
94113058a91SGregory Neil Shapirodnl this is not a documented option
94213058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
9438774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
9448774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
9458774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
9468774250cSGregory Neil Shapirodnl', `dnl')
947c2aa98e2SPeter Wemm
948c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
949c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
95006f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
95142e5d165SGregory Neil Shapiro
95242e5d165SGregory Neil Shapiro
953c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
954c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
95506f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
95606f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
957c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
958c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
959c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
960c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
961c2aa98e2SPeter Wemm
96206f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
963c2aa98e2SPeter Wemm# not local -- try mailer table lookup
964c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
965c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
966c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
96706f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
96806f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
96906f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
970c2aa98e2SPeter Wemm`dnl')
97106f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
972c2aa98e2SPeter Wemm
973c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
974c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
975c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
97606f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
977c2aa98e2SPeter Wemm	`dnl')
978c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
97906f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
980c2aa98e2SPeter Wemm	`dnl')
981c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
98206f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
983c2aa98e2SPeter Wemm	`dnl')')
984c2aa98e2SPeter Wemm
985c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
986c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
98706f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
988c2aa98e2SPeter Wemm	`dnl')
989c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
99006f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
991c2aa98e2SPeter Wemm	`dnl')
992c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
993c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
994c2aa98e2SPeter Wemm	`dnl')
995c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
996c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
997c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
99806f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
999c2aa98e2SPeter Wemm	`dnl')')
1000c2aa98e2SPeter Wemm
1001c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1002c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
100306f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1004c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1005c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1006c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1007c2aa98e2SPeter Wemm	`dnl')')
1008c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1009c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
101006f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1011c2aa98e2SPeter Wemm	`dnl')
1012c2aa98e2SPeter Wemm
1013c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1014c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1015c2aa98e2SPeter Wemmundivert(1)', `dnl')
1016c2aa98e2SPeter Wemm
1017c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
101806f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1019c2aa98e2SPeter Wemm
1020c2aa98e2SPeter Wemm# deal with other remote names
1021c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1022c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
10238774250cSGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "CODE553 Unrecognized host name " $2')
1024c2aa98e2SPeter Wemm
1025c2aa98e2SPeter Wemm# handle locally delivered names
1026c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1027c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1028c2aa98e2SPeter Wemm
1029c2aa98e2SPeter Wemm###########################################################################
1030c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1031c2aa98e2SPeter Wemm###########################################################################
1032c2aa98e2SPeter Wemm
103306f25ae9SGregory Neil ShapiroSLocal_localaddr
103406f25ae9SGregory Neil ShapiroSlocaladdr=5
103506f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
103606f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
103706f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1038c2aa98e2SPeter Wemm
103942e5d165SGregory Neil Shapiroifdef(`_FFR_5_', `
104042e5d165SGregory Neil Shapiro# Preserve host in a macro
104142e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
104242e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1043c2aa98e2SPeter Wemm
104442e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `
104542e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
104642e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
104742e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
104842e5d165SGregory Neil Shapiro')
1049c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1050c2aa98e2SPeter WemmR$+			$: <> $1
1051c2aa98e2SPeter Wemm
1052c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1053c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
105442e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `
105542e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
105642e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
105742e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
105842e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
105906f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
106042e5d165SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')',
1061c2aa98e2SPeter Wemm`dnl')
1062c2aa98e2SPeter Wemm
1063c2aa98e2SPeter Wemm# see if we have a relay or a hub
1064c2aa98e2SPeter WemmR< > $+			$: < $H > $1			try hub
1065c2aa98e2SPeter WemmR< > $+			$: < $R > $1			try relay
106642e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `
106742e5d165SGregory Neil ShapiroR< > $+			$@ $1', `
106806f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
106906f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
107006f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1071c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
107242e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1073c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
10742e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
10752e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
107642e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
107706f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
107806f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
107906f25ae9SGregory Neil ShapiroR< $- : $+ > $+		$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
108006f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1081c2aa98e2SPeter Wemm
108206f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1083c2aa98e2SPeter Wemm###################################################################
1084c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
108506f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1086c2aa98e2SPeter Wemm###################################################################
1087c2aa98e2SPeter Wemm
108806f25ae9SGregory Neil ShapiroSMailertable=90
108906f25ae9SGregory Neil Shapirodnl shift and check
109006f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1091c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
109206f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
109306f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
109406f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
109506f25ae9SGregory Neil Shapirodnl is $2 always empty?
1096c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
109706f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
109806f25ae9SGregory Neil Shapirodnl return full address
1099c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1100c2aa98e2SPeter Wemm`dnl')
1101c2aa98e2SPeter Wemm
1102c2aa98e2SPeter Wemm###################################################################
1103c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
110406f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
110506f25ae9SGregory Neil Shapirodnl	<> address				-> address
110606f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
110706f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
110806f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
110906f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
111006f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
111113058a91SGregory Neil Shapirodnl	<[IPv6:number]> address			-> relay number address
111206f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1113c2aa98e2SPeter Wemm###################################################################
1114c2aa98e2SPeter Wemm
111506f25ae9SGregory Neil ShapiroSMailerToTriple=95
1116c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
111706f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1118c2aa98e2SPeter WemmR< error : $- $+ > $*		$#error $@ $(dequote $1 $) $: $2
1119c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
1120c2aa98e2SPeter WemmR< $- : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
1121c2aa98e2SPeter WemmR< $- : $+ > $*			$# $1 $@ $2 $: $3	try qualified mailer
1122c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
112313058a91SGregory Neil ShapiroR< [ IPv6 : $+ ] > $*		$#_RELAY_ $@ $(dequote $1 $) $: $2	use unqualified mailer
1124c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1125c2aa98e2SPeter Wemm
1126c2aa98e2SPeter Wemm###################################################################
1127c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
112806f25ae9SGregory Neil Shapirodnl input: <user> address
112906f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
113006f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
113106f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
113206f25ae9SGregory Neil Shapirodnl <> user				-> local user user
113306f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
113406f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
113506f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1136c2aa98e2SPeter Wemm###################################################################
1137c2aa98e2SPeter Wemm
1138c2aa98e2SPeter WemmSCanonLocal
11392e43090eSPeter Wemm# strip local host from routed addresses
114006f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
114106f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
11422e43090eSPeter Wemm
1143c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1144c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1145c2aa98e2SPeter Wemm
1146c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1147c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1148c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1149c2aa98e2SPeter Wemm
1150c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1151c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1152c2aa98e2SPeter Wemm
1153c2aa98e2SPeter Wemm# handle local:user syntax
1154c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1155c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1156c2aa98e2SPeter Wemm
1157c2aa98e2SPeter Wemm###################################################################
1158c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1159c2aa98e2SPeter Wemm###################################################################
1160c2aa98e2SPeter Wemm
116106f25ae9SGregory Neil ShapiroSMasqHdr=93
1162c2aa98e2SPeter Wemm
116306f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1164c2aa98e2SPeter Wemm# handle generics database
1165c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
116606f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1167c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1168c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1169c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
117006f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
117106f25ae9SGregory Neil Shapirodnl ignore the first case for now
117206f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
117306f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
117406f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
117506f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
117606f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
117706f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
117806f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
117906f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
118006f25ae9SGregory Neil Shapirodnl no match, remove mark
118106f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
118206f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
118306f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
118406f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
118506f25ae9SGregory Neil Shapirodnl no match, try local part
1186c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
118706f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
118806f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
118906f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
119006f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1191c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1192c2aa98e2SPeter Wemm`dnl')
1193c2aa98e2SPeter Wemm
119406f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
119506f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
119606f25ae9SGregory Neil Shapiro
1197c2aa98e2SPeter Wemm# special case the users that should be exposed
1198c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1199c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1200c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1201c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1202c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1203c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1204c2aa98e2SPeter Wemm
1205c2aa98e2SPeter Wemm# handle domain-specific masquerading
1206c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1207c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1208c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1209c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1210c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1211c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1212c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1213c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
1214c2aa98e2SPeter Wemm
1215c2aa98e2SPeter Wemm###################################################################
1216c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1217c2aa98e2SPeter Wemm###################################################################
1218c2aa98e2SPeter Wemm
121906f25ae9SGregory Neil ShapiroSMasqEnv=94
1220c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
122106f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1222c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1223c2aa98e2SPeter Wemm
1224c2aa98e2SPeter Wemm###################################################################
1225c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1226c2aa98e2SPeter Wemm###################################################################
1227c2aa98e2SPeter Wemm
122806f25ae9SGregory Neil ShapiroSParseLocal=98
122906f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1230c2aa98e2SPeter Wemm
123106f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
123206f25ae9SGregory Neil ShapiroSLDAPExpand
123306f25ae9SGregory Neil Shapiro# do the LDAP lookups
123406f25ae9SGregory Neil ShapiroR<$+><$+>		$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2>
123506f25ae9SGregory Neil Shapiro
123606f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
123706f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
123806f25ae9SGregory Neil ShapiroR< $+ > < $=w > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
123906f25ae9SGregory Neil ShapiroR< $+ > <  > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
124006f25ae9SGregory Neil Shapiro
124106f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
124206f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
124306f25ae9SGregory Neil ShapiroR< $+ > < $+ > < $+ > < $+ >	$#_RELAY_ $@ $2 $: $>canonify $1
124406f25ae9SGregory Neil Shapiro
124506f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
124606f25ae9SGregory Neil Shapiro# return original address
124706f25ae9SGregory Neil ShapiroR< > < $=w > <$+> <$+>		$@ $2
124806f25ae9SGregory Neil Shapiro
124906f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
125006f25ae9SGregory Neil Shapiro# relay to mailHost with original address
125106f25ae9SGregory Neil ShapiroR< > < $+ > <$+> <$+>		$#_RELAY_ $@ $1 $: $2
125206f25ae9SGregory Neil Shapiro
125306f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost,
125406f25ae9SGregory Neil Shapiro# try @domain
125506f25ae9SGregory Neil ShapiroR< > < > <$+> <$+ @ $+>		$@ $>LDAPExpand <$1> <@ $3>
125606f25ae9SGregory Neil Shapiro
125706f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
125806f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
125906f25ae9SGregory Neil Shapiro# user does not exist
126006f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$#error $@ nouser $: "550 User unknown"',
126106f25ae9SGregory Neil Shapiro`dnl
126206f25ae9SGregory Neil Shapiro# return the original address
126306f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$@ $1')',
126406f25ae9SGregory Neil Shapiro`dnl')
126506f25ae9SGregory Neil Shapiro
126606f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
126706f25ae9SGregory Neil Shapiro')')
126806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1269c2aa98e2SPeter Wemm######################################################################
1270c2aa98e2SPeter Wemm###  LookUpDomain -- search for domain in access database
1271c2aa98e2SPeter Wemm###
1272c2aa98e2SPeter Wemm###	Parameters:
1273c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1274c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
127506f25ae9SGregory Neil Shapirodnl			must not be empty
1276c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed unchanged through)
127706f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
127806f25ae9SGregory Neil Shapiro###			! does lookup only with tag
127906f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
128006f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
128106f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1282c2aa98e2SPeter Wemm######################################################################
1283c2aa98e2SPeter Wemm
1284c2aa98e2SPeter WemmSLookUpDomain
128506f25ae9SGregory Neil Shapirodnl remove IPv6 mark and dequote address
128606f25ae9SGregory Neil Shapirodnl it is a bit ugly because it is checked on each "iteration"
128713058a91SGregory Neil ShapiroR<[IPv6 : $+]> <$+> <$*> <$*>	$: <[$(dequote $1 $)]> <$2> <$3> <$4>
128806f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
128906f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
129006f25ae9SGregory Neil ShapiroR<$*> <$+> <$*> <$- $->		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
129106f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
129206f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
129306f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$- $->	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4> <$5 $6>', `dnl')
129406f25ae9SGregory Neil Shapirodnl lookup without tag?
129506f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $*>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
129606f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
129706f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <+ $*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <$4> <+ $5>', `dnl')
129806f25ae9SGregory Neil Shapirodnl lookup IP address (no check is done whether it is an IP number!)
129906f25ae9SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$*> <$*>	$@ $>LookUpDomain <[$1]> <$3> <$4> <$5>
130006f25ae9SGregory Neil Shapirodnl lookup IPv6 address
1301193538b7SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$*> <$*>	$: $>LookUpDomain <[$1]> <$3> <$4> <$5>
130206f25ae9SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$*> <$*>	$: $>LookUpDomain <[$1]> <$3> <$4> <$5>
130306f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
130406f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$*>	$@ $>LookUpDomain <$2> <$3> <$4> <$5>
130506f25ae9SGregory Neil Shapirodnl not found, no subdomain: return default
130606f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
130706f25ae9SGregory Neil Shapirodnl return result of lookup
130806f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>
1309c2aa98e2SPeter Wemm
1310c2aa98e2SPeter Wemm######################################################################
1311c2aa98e2SPeter Wemm###  LookUpAddress -- search for host address in access database
1312c2aa98e2SPeter Wemm###
1313c2aa98e2SPeter Wemm###	Parameters:
1314c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1315c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
131606f25ae9SGregory Neil Shapirodnl			must not be empty
1317c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed through)
131806f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
131906f25ae9SGregory Neil Shapiro###			! does lookup only with tag
132006f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
132106f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
132206f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1323c2aa98e2SPeter Wemm######################################################################
1324c2aa98e2SPeter Wemm
1325c2aa98e2SPeter WemmSLookUpAddress
132606f25ae9SGregory Neil Shapirodnl lookup with tag
132706f25ae9SGregory Neil ShapiroR<$+> <$+> <$*> <$- $+>		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
132806f25ae9SGregory Neil Shapirodnl lookup without tag
132906f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $+>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
133006f25ae9SGregory Neil Shapirodnl no match; IPv6: remove last part
1331193538b7SGregory Neil ShapiroR<?> <$+::$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
133206f25ae9SGregory Neil ShapiroR<?> <$+:$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
133306f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
133406f25ae9SGregory Neil ShapiroR<?> <$+.$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
133506f25ae9SGregory Neil Shapirodnl no match: return default
133606f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
133706f25ae9SGregory Neil Shapirodnl match: return result
133806f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>',
1339c2aa98e2SPeter Wemm`dnl')
1340c2aa98e2SPeter Wemm
1341c2aa98e2SPeter Wemm######################################################################
1342065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1343065a643dSPeter Wemm###			relay checking.  Route address syntax is
1344065a643dSPeter Wemm###			crudely converted into a %-hack address.
1345065a643dSPeter Wemm###
1346065a643dSPeter Wemm###	Parameters:
1347065a643dSPeter Wemm###		$1 -- full recipient address
1348065a643dSPeter Wemm###
1349065a643dSPeter Wemm###	Returns:
1350065a643dSPeter Wemm###		parsed address, not in source route form
135106f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
135206f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1353065a643dSPeter Wemm######################################################################
1354065a643dSPeter Wemm
1355065a643dSPeter WemmSCanonAddr
135606f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
135706f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1358065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1359065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1360065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
136106f25ae9SGregory Neil Shapirodnl')
1362065a643dSPeter Wemm
1363065a643dSPeter Wemm######################################################################
1364c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1365c2aa98e2SPeter Wemm###			$* $=m or the access database.
1366c2aa98e2SPeter Wemm###			Check user portion for host separators.
1367c2aa98e2SPeter Wemm###
1368c2aa98e2SPeter Wemm###	Parameters:
1369c2aa98e2SPeter Wemm###		$1 -- full recipient address
1370c2aa98e2SPeter Wemm###
1371c2aa98e2SPeter Wemm###	Returns:
1372c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1373c2aa98e2SPeter Wemm######################################################################
1374c2aa98e2SPeter Wemm
1375c2aa98e2SPeter WemmSParseRecipient
137606f25ae9SGregory Neil Shapirodnl mark and canonify address
1377065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
137806f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1379c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
138006f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1381c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1382c2aa98e2SPeter Wemm
1383c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1384c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
138506f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1386c2aa98e2SPeter WemmR<?> $*				$@ $1
1387c2aa98e2SPeter Wemm
138806f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>, where localpart contains $=O
138906f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1390c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1391c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1392c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
1393065a643dSPeter Wemm
1394065a643dSPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
139506f25ae9SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
1396065a643dSPeter WemmR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1397065a643dSPeter WemmR<MX> < : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
139806f25ae9SGregory Neil Shapirodnl yes: mark it as <RELAY>
1399065a643dSPeter WemmR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
140006f25ae9SGregory Neil Shapirodnl no: put old <NO> mark back
1401065a643dSPeter WemmR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
1402065a643dSPeter Wemm
140306f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
140406f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
1405c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1406c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
140706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
140806f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1409065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1410c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
141106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
141206f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>LookUpDomain <$2> <NO> <$1 < @ $2 >> <+To>
1413c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1414065a643dSPeter Wemm
141506f25ae9SGregory Neil Shapiro
1416c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
1417c2aa98e2SPeter WemmR<$-> $*			$@ $2
1418c2aa98e2SPeter Wemm
141906f25ae9SGregory Neil Shapiro
1420c2aa98e2SPeter Wemm######################################################################
1421c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1422c2aa98e2SPeter Wemm######################################################################
1423c2aa98e2SPeter Wemm
1424c2aa98e2SPeter WemmSLocal_check_relay
142506f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1426c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1427c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1428c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1429c2aa98e2SPeter Wemm
1430c2aa98e2SPeter WemmSBasic_check_relay
1431c2aa98e2SPeter Wemm# check for deferred delivery mode
1432c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1433c2aa98e2SPeter WemmR< d > $*		$@ deferred
1434c2aa98e2SPeter WemmR< $* > $*		$: $2
1435c2aa98e2SPeter Wemm
143606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
143742e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
143806f25ae9SGregory Neil ShapiroR$+ $| $+		$: $>LookUpDomain < $1 > <?> < $2 > <+Connect>
143942e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
144006f25ae9SGregory Neil ShapiroR<?> <$+>		$: $>LookUpAddress < $1 > <?> < $1 > <+Connect>	no: another lookup
144142e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
144206f25ae9SGregory Neil ShapiroR<?> < $+ >		$: $1					found nothing
144342e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
144442e5d165SGregory Neil Shapirodnl or {client_addr}
144542e5d165SGregory Neil ShapiroR<$={Accept}> < $* >	$@ $1				return value of lookup
144606f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
1447c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
144806f25ae9SGregory Neil Shapirodnl error tag
144942e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
145042e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
145106f25ae9SGregory Neil Shapirodnl generic error from access map
145242e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1453c2aa98e2SPeter Wemm
1454c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
145506f25ae9SGregory Neil Shapiro# DNS based IP address spam list
1456c2aa98e2SPeter WemmR$*			$: $&{client_addr}
145706f25ae9SGregory Neil ShapiroR::ffff:$-.$-.$-.$-	$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
145806f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
145906f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
146006f25ae9SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Mail from " $&{client_addr} " refused by blackhole site _RBL_"',
1461c2aa98e2SPeter Wemm`dnl')
146206f25ae9SGregory Neil Shapiroundivert(8)
1463c2aa98e2SPeter Wemm
1464c2aa98e2SPeter Wemm######################################################################
1465c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1466c2aa98e2SPeter Wemm######################################################################
1467c2aa98e2SPeter Wemm
1468c2aa98e2SPeter WemmSLocal_check_mail
146906f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1470c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1471c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1472c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1473c2aa98e2SPeter Wemm
1474c2aa98e2SPeter WemmSBasic_check_mail
1475c2aa98e2SPeter Wemm# check for deferred delivery mode
1476c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1477c2aa98e2SPeter WemmR< d > $*		$@ deferred
1478c2aa98e2SPeter WemmR< $* > $*		$: $2
1479c2aa98e2SPeter Wemm
148006f25ae9SGregory Neil Shapiro# authenticated?
148106f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
148206f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
148306f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
148406f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
148506f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
148606f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
148706f25ae9SGregory Neil Shapiro
148806f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
148906f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
149006f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
149106f25ae9SGregory Neil Shapirodnl do some additional checks
149206f25ae9SGregory Neil Shapirodnl no user@host
149306f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
149406f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
149506f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
149606f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
149706f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
149806f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
149906f25ae9SGregory Neil ShapiroR$+			$: <?> $1
150006f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
150106f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
150206f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
150306f25ae9SGregory Neil Shapirodnl prepend daemon_flags
150406f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
150506f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
150606f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
150706f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
150806f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
150906f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
151006f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
151106f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
151206f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
151306f25ae9SGregory Neil Shapirodnl remove daemon_flags
151406f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
151506f25ae9SGregory Neil Shapiro# handle case of @localhost on address
151606f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
151706f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
151806f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
151906f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
152006f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
152106f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
152206f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
152306f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
152406f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
152506f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
152606f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
152706f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
152806f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
152906f25ae9SGregory Neil Shapirodnl	or:    <address>
153006f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
153106f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
15328774250cSGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "CODE553 Real domain name required for sender address"
153306f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
153406f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
153506f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
153606f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
153706f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
153806f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1539065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1540c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
154106f25ae9SGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <OK> $1 < @ $2 $3 >
154206f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
1543c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
154406f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <OK> $1 < @ $2 >		... unresolvable OK',
154506f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
154606f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
154706f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
154806f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, OK, PERM, TEMP
154906f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1550c2aa98e2SPeter Wemm
155106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
155206f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
155306f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
155406f25ae9SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, OK, PERM, TEMP
155506f25ae9SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <H:$3>
155606f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
155706f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
155806f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
155906f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
156006f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+From> $| <$3> <>
156106f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
156206f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
156306f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1564c2aa98e2SPeter Wemm# retransform for further use
156506f25ae9SGregory Neil Shapirodnl required form:
156606f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
156706f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
156806f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
156906f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
157006f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1571c2aa98e2SPeter Wemm
1572c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1573c2aa98e2SPeter Wemm# handle case of no @domain on address
157406f25ae9SGregory Neil Shapirodnl prepend daemon_flags
157506f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
157606f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
157706f25ae9SGregory Neil ShapiroR$* u $* $| <?> $*	$: <OK> $3
157806f25ae9SGregory Neil Shapirodnl remove daemon_flags
157906f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
1580c2aa98e2SPeter WemmR<?> $*			$: < ? $&{client_name} > $1
1581c2aa98e2SPeter WemmR<?> $*			$@ <OK>				...local unqualed ok
15828774250cSGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "CODE553 Domain name required for sender address " $&f
1583c2aa98e2SPeter Wemm							...remote is not')
1584c2aa98e2SPeter Wemm# check results
158506f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1586c2aa98e2SPeter WemmR<OK> $*		$@ <OK>
158706f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
15888774250cSGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "CODE553 Domain of sender address " $&f " does not exist"
158906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
159006f25ae9SGregory Neil ShapiroR<$={Accept}> $*	$# $1
1591c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
159206f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
159306f25ae9SGregory Neil Shapirodnl error tag
159406f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
159506f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
159606f25ae9SGregory Neil Shapirodnl generic error from access map
159706f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1598c2aa98e2SPeter Wemm`dnl')
1599c2aa98e2SPeter Wemm
1600c2aa98e2SPeter Wemm######################################################################
1601c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
1602c2aa98e2SPeter Wemm######################################################################
1603c2aa98e2SPeter Wemm
1604c2aa98e2SPeter WemmSLocal_check_rcpt
160506f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
1606c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
1607c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1608c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
1609c2aa98e2SPeter Wemm
1610c2aa98e2SPeter WemmSBasic_check_rcpt
1611c2aa98e2SPeter Wemm# check for deferred delivery mode
1612c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1613c2aa98e2SPeter WemmR< d > $*		$@ deferred
1614c2aa98e2SPeter WemmR< $* > $*		$: $2
1615c2aa98e2SPeter Wemm
161606f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
161706f25ae9SGregory Neil Shapiro# require qualified recipient?
161806f25ae9SGregory Neil ShapiroR$+			$: <?> $1
161906f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
162006f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
162106f25ae9SGregory Neil Shapirodnl prepend daemon_flags
162206f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
162306f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
162406f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
162506f25ae9SGregory Neil ShapiroR$* r $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
162606f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
162706f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
162806f25ae9SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Domain name required"
162906f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
163006f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
163106f25ae9SGregory Neil Shapiro
1632c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
1633065a643dSPeter WemmR$*			$: $>CanonAddr $1
1634c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
1635c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
1636c2aa98e2SPeter Wemm
1637065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
1638065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
1639065a643dSPeter Wemm# unlimited bestmx
1640065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
1641065a643dSPeter Wemm`dnl
1642065a643dSPeter Wemm# limit bestmx to $=B
16432e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
164406f25ae9SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Basic_check_rcpt" $1 $2 $3
1645065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
1646065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
1647065a643dSPeter Wemm
1648c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
164906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1650c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
1651c2aa98e2SPeter WemmR$*			$: <?> $1
165206f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
165306f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
165406f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <H:$2>
165506f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <H:$2>
165606f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
165706f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
165806f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
165906f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+To> $| <$2> <>
166006f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
166106f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
166206f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
166306f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
166406f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
166506f25ae9SGregory Neil Shapirodnl as generic error message...
166606f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
166706f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
166806f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
166906f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
1670c2aa98e2SPeter WemmR<REJECT> $*		$#error $@ 5.2.1 $: "550 Mailbox disabled for this recipient"
167106f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
167206f25ae9SGregory Neil Shapirodnl error tag
167306f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
167406f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
167506f25ae9SGregory Neil Shapirodnl generic error from access map
167606f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
167706f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
1678c2aa98e2SPeter Wemm
167906f25ae9SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)')
168006f25ae9SGregory Neil Shapiro# authenticated?
168106f25ae9SGregory Neil Shapirodnl do this unconditionally? this requires to manage CAs carefully
168206f25ae9SGregory Neil Shapirodnl just because someone has a CERT signed by a "trusted" CA
168306f25ae9SGregory Neil Shapirodnl does not mean we want to allow relaying for her,
168406f25ae9SGregory Neil Shapirodnl either use a subroutine or provide something more sophisticated
168506f25ae9SGregory Neil Shapirodnl this could for example check the DN (maybe an access map lookup)
168606f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>RelayAuth $1 $| $&{verify}	client authenticated?
168706f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2				error/ok?
168806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1				no
168906f25ae9SGregory Neil Shapiro
169006f25ae9SGregory Neil Shapiro# authenticated by a trusted mechanism?
169106f25ae9SGregory Neil ShapiroR$*			$: $1 $| $&{auth_type}
169206f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
169306f25ae9SGregory Neil ShapiroR$* $|			$: $1
169406f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
169506f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
169606f25ae9SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAYAUTH
169706f25ae9SGregory Neil Shapirodnl undo addition of ${auth_type}
169806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
1699193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
170006f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
1701193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
1702193538b7SGregory Neil ShapiroR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
1703c2aa98e2SPeter Wemm# anything terminating locally is ok
1704c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
170506f25ae9SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAYTO', `dnl')
170606f25ae9SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAYTO
1707c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
170806f25ae9SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAYTO
170906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
171006f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>
171106f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
171206f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
171306f25ae9SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAYTO
171406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
171506f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: $>LookUpDomain <$2> <?> <$1 < @ $2 >> <+To>',`dnl')')
171606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
171706f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
171806f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYTO
1719c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
1720c2aa98e2SPeter Wemm
172106f25ae9SGregory Neil Shapiro
1722c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
1723c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
172406f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
172506f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
1726c2aa98e2SPeter WemmR< : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
172706f25ae9SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAYTO
1728065a643dSPeter WemmR< : $* : > $*		$: $2',
1729c2aa98e2SPeter Wemm`dnl')
1730c2aa98e2SPeter Wemm
1731c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
1732c2aa98e2SPeter WemmR$*			$: <?> $1
1733065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
1734c2aa98e2SPeter Wemm# local user is ok
173506f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
173606f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
173706f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
173806f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
173906f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
174006f25ae9SGregory Neil ShapiroR<?> postmaster		$@ TOPOSTMASTER
174106f25ae9SGregory Neil Shapiro# require qualified recipient?
174206f25ae9SGregory Neil Shapirodnl prepend daemon_flags
174306f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
174406f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
174506f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
174606f25ae9SGregory Neil Shapirodnl r flag? add client_name
174706f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
174806f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
174906f25ae9SGregory Neil Shapiro# no qualified recipient required
175006f25ae9SGregory Neil ShapiroR$* $| <?> $+		$@ RELAYTOLOCAL
175106f25ae9SGregory Neil Shapirodnl client_name is empty
175206f25ae9SGregory Neil ShapiroR<?> <?> $+		$@ RELAYTOLOCAL
175306f25ae9SGregory Neil Shapirodnl client_name is local
175406f25ae9SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAYTOLOCAL
175506f25ae9SGregory Neil Shapirodnl client_name is not local
175606f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
175706f25ae9SGregory Neil Shapirodnl no qualified recipient required
175806f25ae9SGregory Neil ShapiroR<?> $+			$@ RELAYTOLOCAL')
175906f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
1760c2aa98e2SPeter WemmR<$+> $*		$: $2
176106f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
1762c2aa98e2SPeter Wemm
1763c2aa98e2SPeter Wemm# anything originating locally is ok
1764c2aa98e2SPeter Wemm# check IP address
1765c2aa98e2SPeter WemmR$*			$: $&{client_addr}
176606f25ae9SGregory Neil ShapiroR$@			$@ RELAYFROM		originated locally
176706f25ae9SGregory Neil ShapiroR0			$@ RELAYFROM		originated locally
176806f25ae9SGregory Neil ShapiroR$=R $*			$@ RELAYFROM		relayable IP address
176906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
177006f25ae9SGregory Neil ShapiroR$*			$: $>LookUpAddress <$1> <?> <$1> <+Connect>
177106f25ae9SGregory Neil ShapiroR<RELAY> $* 		$@ RELAYFROM		relayable IP address
1772c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
1773c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
177406f25ae9SGregory Neil ShapiroR$=w			$@ RELAYFROM		... and see if it is local
1775c2aa98e2SPeter Wemm
177606f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
177706f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
177806f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
177906f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
178006f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
178106f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
178206f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
1783c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
178406f25ae9SGregory Neil Shapiro# check whether local FROM is ok
178506f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w . >	$@ RELAYFROMMAIL	FROM local', `dnl')
178606f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
178706f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
178806f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 < @ $2 > $| $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', `<H:$2>') <>
178906f25ae9SGregory Neil ShapiroR$* <RELAY>		$@ RELAYFROMMAIL	RELAY FROM sender ok', `dnl
179006f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_', `errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
179106f25ae9SGregory Neil Shapiro')',
179206f25ae9SGregory Neil Shapiro`dnl')
179306f25ae9SGregory Neil Shapirodnl')', `dnl')
179406f25ae9SGregory Neil Shapiro
179506f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
179606f25ae9SGregory Neil Shapirodnl input: ignored
179706f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
179806f25ae9SGregory Neil ShapiroR<TEMP>			$#error $@ 4.7.1 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
179906f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
180006f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
180106f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
180206f25ae9SGregory Neil ShapiroR$*			$: <?> $&{client_name}
180306f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical
180406f25ae9SGregory Neil ShapiroR<?> $* $~P 		$:<?>  $[ $1 $2 $]
180506f25ae9SGregory Neil ShapiroR$* .			$1			strip trailing dots
180606f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
180706f25ae9SGregory Neil ShapiroR<?>			$@ RELAYFROM
180806f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
180906f25ae9SGregory Neil ShapiroR<?> $* $=m		$@ RELAYFROM', `dnl')
181006f25ae9SGregory Neil ShapiroR<?> $=w		$@ RELAYFROM
181106f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
181206f25ae9SGregory Neil Shapiro`R<?> $=R		$@ RELAYFROM
181306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
181406f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
181506f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
181606f25ae9SGregory Neil Shapiro`R<?> $* $=R			$@ RELAYFROM
181706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
181806f25ae9SGregory Neil ShapiroR<?> $*			$: $>LookUpDomain <$1> <?> <$1> <+Connect>',`dnl')')
181906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
182006f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYFROM
182106f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
1822c2aa98e2SPeter Wemm
1823c2aa98e2SPeter Wemm# anything else is bogus
182406f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
182506f25ae9SGregory Neil Shapirodivert(0)
182606f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
182706f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
182806f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
182906f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
183006f25ae9SGregory Neil ShapiroSFullAddr
183106f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
183206f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
183306f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
1834c2aa98e2SPeter Wemm
183506f25ae9SGregory Neil Shapiro# call all necessary rulesets
183606f25ae9SGregory Neil ShapiroScheck_rcpt
183706f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
183806f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
183906f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
184006f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
184106f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
184206f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
184306f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
184406f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
184506f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
184606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
184706f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
184806f25ae9SGregory Neil Shapiro')')dnl
184906f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
185006f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
185106f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
185206f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <U: $1@>
185306f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 >
185406f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
185506f25ae9SGregory Neil Shapiro# lookup the addresses only with To tag
185606f25ae9SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <!To> $| <$2> <>
185706f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
185806f25ae9SGregory Neil Shapirodnl', `dnl')
185906f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
186006f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
186106f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
186206f25ae9SGregory Neil Shapiro	`errprint(`*** ERROR: define either SpamHater or SpamFriend
186306f25ae9SGregory Neil Shapiro')', `dnl')
186406f25ae9SGregory Neil ShapiroR<SPAMFRIEND> $+	$@ SPAMFRIEND
186506f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
186606f25ae9SGregory Neil Shapiro`dnl')
186706f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
186806f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
186906f25ae9SGregory Neil ShapiroR<SPAMHATER> $+		$: $1			spam hater: continue checks
187006f25ae9SGregory Neil ShapiroR<$*> $+		$@ NOSPAMHATER		everyone else: stop
187106f25ae9SGregory Neil Shapirodnl',`dnl')
187206f25ae9SGregory Neil Shapirodnl run further checks: check_mail
187306f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
187406f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkmail <$&f>
187506f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
187606f25ae9SGregory Neil Shapirodnl run further checks: check_relay
187706f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
187806f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
187906f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
188006f25ae9SGregory Neil Shapiro', `dnl')
188106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
188206f25ae9SGregory Neil Shapiro######################################################################
188306f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
188406f25ae9SGregory Neil Shapiro###	Parameters:
188506f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
188606f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
188706f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
188806f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
188906f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
189006f25ae9SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: H: if there
189106f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
189206f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
189306f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
189406f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
189506f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
189606f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
189706f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
189806f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
189906f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
190006f25ae9SGregory Neil Shapiro###		H: recursive host lookup (LookUpDomain)
190106f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
190206f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
190306f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
190406f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
190506f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
190606f25ae9SGregory Neil Shapiro######################################################################
190706f25ae9SGregory Neil Shapiro
190806f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
190906f25ae9SGregory Neil Shapirodnl if A is activated: add it
191006f25ae9SGregory Neil ShapiroC{src}E F H U
191106f25ae9SGregory Neil ShapiroSSearchList
191206f25ae9SGregory Neil Shapiro# mark H: lookup domain
191306f25ae9SGregory Neil ShapiroR<$+> $| <H:$+> <$*>		$: <$1> $| <@> $>LookUpDomain <$2> <?> <$3> <$1>
191406f25ae9SGregory Neil ShapiroR<$+> $| <@> <$+> <$*>		$: <$1> $| <$2> <$3>
191506f25ae9SGregory Neil Shapirodnl A: NOT YET REQUIRED
191606f25ae9SGregory Neil Shapirodnl R<$+> $| <A:$+> <$*>	$: <$1> $| <@> $>LookUpAddress <$2> <?> <$3> <$1>
191706f25ae9SGregory Neil Shapirodnl R<$+> $| <@> <$+> <$*>	$: <$1> $| <$2> <$3>
191806f25ae9SGregory Neil Shapirodnl lookup of the item with tag
191906f25ae9SGregory Neil Shapirodnl this applies to F: U: E:
192006f25ae9SGregory Neil ShapiroR<$- $-> $| <$={src}:$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$4 $: $3:$4 $)> <$5>
192106f25ae9SGregory Neil Shapirodnl no match, try without tag
192206f25ae9SGregory Neil ShapiroR<+ $-> $| <$={src}:$+> <$*>	$: <+ $1> $| <$(access $3 $: $2:$3 $)> <$4>
192306f25ae9SGregory Neil Shapirodnl do we really have to distinguish these cases?
192406f25ae9SGregory Neil Shapirodnl probably yes, there might be a + in the domain part (is that allowed?)
192506f25ae9SGregory Neil Shapirodnl user+detail lookups: should it be:
192606f25ae9SGregory Neil Shapirodnl user+detail, user+*, user; just like aliases?
192706f25ae9SGregory Neil ShapiroR<$- $-> $| <F:$* + $*@$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@$5 $: F:$3 + $4@$5$)> <$6>
192806f25ae9SGregory Neil ShapiroR<+ $-> $| <F:$* + $*@$+> <$*>	$: <+ $1> $| <$(access $2@$4 $: F:$2 + $3@$4$)> <$5>
192906f25ae9SGregory Neil Shapirodnl user lookups are always with trailing @
193006f25ae9SGregory Neil Shapirodnl do not remove the @ from the lookup:
193106f25ae9SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
193206f25ae9SGregory Neil ShapiroR<$- $-> $| <U:$* + $*> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@ $: U:$3 + $4$)> <$5>
193306f25ae9SGregory Neil Shapirodnl no match, try without tag
193406f25ae9SGregory Neil ShapiroR<+ $-> $| <U:$* + $*> <$*>	$: <+ $1> $| <$(access $2@ $: U:$2 + $3$)> <$4>
193506f25ae9SGregory Neil Shapirodnl no match, try rest of list
193606f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <$+>	$@ $>SearchList <$1> $| <$4>
193706f25ae9SGregory Neil Shapirodnl no match, list empty: return failure
193806f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <>	$@ <?>
193906f25ae9SGregory Neil Shapirodnl got result, return it
194006f25ae9SGregory Neil ShapiroR<$+> $| <$+> <$*>		$@ <$2>
194106f25ae9SGregory Neil Shapirodnl return result from recursive invocation
194206f25ae9SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>', `dnl')
194306f25ae9SGregory Neil Shapiro
194406f25ae9SGregory Neil Shapiro# is user trusted to authenticate as someone else?
194506f25ae9SGregory Neil Shapirodnl AUTH= parameter from MAIL command
194606f25ae9SGregory Neil ShapiroStrust_auth
194706f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
194806f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
194906f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
195006f25ae9SGregory Neil Shapirodnl seems to be useful...
195106f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
195206f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
195306f25ae9SGregory Neil Shapirodnl call user supplied code
195406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $1
195506f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
195606f25ae9SGregory Neil Shapirodnl default: error
195706f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
195806f25ae9SGregory Neil Shapiro
195906f25ae9SGregory Neil Shapirodnl empty ruleset definition so it can be called
196006f25ae9SGregory Neil ShapiroSLocal_trust_auth
196106f25ae9SGregory Neil Shapiro
196206f25ae9SGregory Neil Shapiroifdef(`_FFR_TLS_O_T', `dnl
196306f25ae9SGregory Neil ShapiroSoffer_tls
196406f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{client_name}> <?> <> <! TLS_OFF_TAG>
196506f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_OFF_TAG>
196606f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_OFF_TAG: $: ? $)>
196706f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
196806f25ae9SGregory Neil ShapiroR<NO> <>	$#error $@ 5.7.1 $: "550 do not offer TLS for " $&{client_name} " ["$&{client_addr}"]"
196906f25ae9SGregory Neil Shapiro
197006f25ae9SGregory Neil ShapiroStry_tls
197106f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{server_name}> <?> <> <! TLS_TRY_TAG>
197206f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_TRY_TAG>
197306f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG: $: ? $)>
197406f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
1975193538b7SGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"
197606f25ae9SGregory Neil Shapiro')dnl
197706f25ae9SGregory Neil Shapiro
197806f25ae9SGregory Neil Shapiro# is connection with client "good" enough? (done in server)
197906f25ae9SGregory Neil Shapiro# input: ${verify} $| (MAIL|STARTTLS)
198006f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
198106f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
198206f25ae9SGregory Neil ShapiroStls_client
198306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
198406f25ae9SGregory Neil Shapirodnl ignore second arg for now
198506f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
198606f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
198706f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
198806f25ae9SGregory Neil ShapiroR$* $| $*	$: $1 $| $>LookUpDomain <$&{client_name}> <?> <> <! TLS_CLT_TAG>
198906f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_CLT_TAG>
199006f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
199106f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
199206f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
199306f25ae9SGregory Neil ShapiroR$* $| $*	$@ $>"tls_connection" $1')
199406f25ae9SGregory Neil Shapiro
199506f25ae9SGregory Neil Shapiro# is connection with server "good" enough? (done in client)
199606f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
199706f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
199806f25ae9SGregory Neil Shapiro# input: ${verify}
199906f25ae9SGregory Neil ShapiroStls_server
200006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
200106f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>LookUpDomain <$&{server_name}> <?> <> <! TLS_SRV_TAG>
200206f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_SRV_TAG>
200306f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
200406f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
200506f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
200606f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1')
200706f25ae9SGregory Neil Shapiro
200806f25ae9SGregory Neil ShapiroStls_connection
200906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
201006f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
201106f25ae9SGregory Neil Shapirodnl input: $&{verify} $| <ResultOfLookup> [<>]
201206f25ae9SGregory Neil Shapirodnl remove optional <>
201306f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
201406f25ae9SGregory Neil Shapirodnl permanent or temporary error?
201506f25ae9SGregory Neil ShapiroR$* $| <PERM + $={tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
201606f25ae9SGregory Neil ShapiroR$* $| <TEMP + $={tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
201706f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
201806f25ae9SGregory Neil ShapiroR$* $| <$={tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
201906f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
202006f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
202106f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
202206f25ae9SGregory Neil Shapirodnl use default error
202306f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
202406f25ae9SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> $1
202506f25ae9SGregory Neil ShapiroR$* $| <$*> <$={tls}:$->$*	$: <$2> <$3:$4> $1
202606f25ae9SGregory Neil Shapirodnl some other value in access map: accept
202706f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
202806f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
202906f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
203006f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
203106f25ae9SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> ${verify}
203206f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
203306f25ae9SGregory Neil ShapiroR<$*><VERIFY> OK		$@ OK
203406f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
203506f25ae9SGregory Neil ShapiroR<$*><VERIFY:$-> OK		$: <$1> <REQ:$2>
203606f25ae9SGregory Neil Shapirodnl just some level of encryption required
203706f25ae9SGregory Neil ShapiroR<$*><ENCR:$-> $*		$: <$1> <REQ:$2>
203806f25ae9SGregory Neil Shapirodnl verification required but ${verify} is not set
203906f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*>		$#error $@ $2 $: $1 " authentication required"
204006f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> FAIL	$#error $@ $2 $: $1 " authentication failed"
204106f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NO		$#error $@ $2 $: $1 " not authenticated"
204206f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
204306f25ae9SGregory Neil Shapirodnl some other value for ${verify}
204406f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> $+		$#error $@ $2 $: $1 " authentication failure " $4
204506f25ae9SGregory Neil Shapirodnl some level of encryption required: get the maximum level
204606f25ae9SGregory Neil ShapiroR<$*><REQ:$->			$: <$1> <REQ:$2> $>max $&{cipher_bits} : $&{auth_ssf}
204706f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
204806f25ae9SGregory Neil ShapiroR<$*><REQ:$-> $-		$: <$1> <$2:$3> $(arith l $@ $3 $@ $2 $)
204906f25ae9SGregory Neil ShapiroR<$-:$+><$-:$-> TRUE		$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
205006f25ae9SGregory Neil Shapiro
205106f25ae9SGregory Neil ShapiroSmax
205206f25ae9SGregory Neil Shapirodnl compute the max of two values separated by :
205306f25ae9SGregory Neil ShapiroR:		$: 0
205406f25ae9SGregory Neil ShapiroR:$-		$: $1
205506f25ae9SGregory Neil ShapiroR$-:		$: $1
205606f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
205706f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
205806f25ae9SGregory Neil ShapiroR$-:$-:$-	$: $2',
205906f25ae9SGregory Neil Shapiro`dnl use default error
206006f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
206106f25ae9SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."')
206206f25ae9SGregory Neil Shapiro
206306f25ae9SGregory Neil ShapiroSRelayAuth
206406f25ae9SGregory Neil Shapiro# authenticated?
206506f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
206606f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
206706f25ae9SGregory Neil Shapirodnl CA in CERTPath so we can authenticate users, we do not allow
206806f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
206906f25ae9SGregory Neil Shapirodnl but anyway).
207006f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
207106f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
207206f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
207306f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
207406f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
207506f25ae9SGregory Neil Shapirodnl cert subject.
207606f25ae9SGregory Neil ShapiroR$* $| OK		$: $1
207706f25ae9SGregory Neil ShapiroR$* $| $*		$@ NO		not authenticated
207806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
207906f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
208006f25ae9SGregory Neil ShapiroR$*			$: $1 $| $(CERTIssuer $&{cert_issuer} $)',
208106f25ae9SGregory Neil Shapiro`R$*			$: $1 $| $&{cert_issuer}')
208206f25ae9SGregory Neil ShapiroR$* $| $+		$: $1 $| $(access CERTISSUER:$2 $)
208306f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
208406f25ae9SGregory Neil ShapiroR$* $| RELAY		$# RELAYCERTISSUER
208506f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
208606f25ae9SGregory Neil ShapiroR$* $| SUBJECT		$: $1 $| <@> $(CERTSubject $&{cert_subject} $)',
208706f25ae9SGregory Neil Shapiro`R$* $| SUBJECT		$: $1 $| <@> $&{cert_subject}')
208842e5d165SGregory Neil ShapiroR$* $| <@> $+		$: $1 $| <@> $(access CERTSUBJECT:$2 $)
208906f25ae9SGregory Neil ShapiroR$* $| <@> RELAY	$# RELAYCERTSUBJECT
209006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
209106f25ae9SGregory Neil Shapiro
209206f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
209306f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
209406f25ae9SGregory Neil Shapiro#
209506f25ae9SGregory Neil Shapiro######################################################################
209606f25ae9SGregory Neil Shapiro######################################################################
209706f25ae9SGregory Neil Shapiro#####
209806f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
209906f25ae9SGregory Neil Shapiro#####
210006f25ae9SGregory Neil Shapiro######################################################################
210106f25ae9SGregory Neil Shapiro######################################################################
210206f25ae9SGregory Neil Shapiro_MAIL_FILTERS_')
2103c2aa98e2SPeter Wemm#
2104c2aa98e2SPeter Wemm######################################################################
2105c2aa98e2SPeter Wemm######################################################################
2106c2aa98e2SPeter Wemm#####
2107c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
2108c2aa98e2SPeter Wemm#####
2109c2aa98e2SPeter Wemm######################################################################
2110c2aa98e2SPeter Wemm######################################################################
211106f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
211242e5d165SGregory Neil Shapiro
2113