xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 06f25ae9)
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
1606f25ae9SGregory Neil ShapiroVERSIONID(`$Id: proto.m4,v 8.446.2.5.2.12 2000/07/19 21:41:19 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"')')
80c2aa98e2SPeter Wemmdivert(0)dnl
81c2aa98e2SPeter Wemm
8206f25ae9SGregory Neil Shapiro# override file safeties - setting this option compromises system security,
8306f25ae9SGregory Neil Shapiro# addressing the actual file configuration problem is preferred
8406f25ae9SGregory Neil Shapiro# need to set this before any file actions are encountered in the cf file
8506f25ae9SGregory Neil Shapiro_OPTION(DontBlameSendmail, `confDONT_BLAME_SENDMAIL', `safe')
8606f25ae9SGregory Neil Shapiro
8706f25ae9SGregory Neil Shapiro# default LDAP map specification
8806f25ae9SGregory Neil Shapiro# need to set this now before any LDAP maps are defined
8906f25ae9SGregory Neil Shapiro_OPTION(LDAPDefaultSpec, `confLDAP_DEFAULT_SPEC', `-h localhost')
90c2aa98e2SPeter Wemm
91c2aa98e2SPeter Wemm##################
92c2aa98e2SPeter Wemm#   local info   #
93c2aa98e2SPeter Wemm##################
94c2aa98e2SPeter Wemm
95c2aa98e2SPeter WemmCwlocalhost
96c2aa98e2SPeter Wemmifdef(`USE_CW_FILE',
97c2aa98e2SPeter Wemm`# file containing names of hosts for which we receive email
98c2aa98e2SPeter WemmFw`'confCW_FILE',
99c2aa98e2SPeter Wemm	`dnl')
100c2aa98e2SPeter Wemm
101c2aa98e2SPeter Wemm# my official domain name
102c2aa98e2SPeter Wemm# ... `define' this only if sendmail cannot automatically determine your domain
103c2aa98e2SPeter Wemmifdef(`confDOMAIN_NAME', `Dj`'confDOMAIN_NAME', `#Dj$w.Foo.COM')
104c2aa98e2SPeter Wemm
105c2aa98e2SPeter WemmCP.
106c2aa98e2SPeter Wemm
107c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
108c2aa98e2SPeter Wemm`# UUCP relay host
109c2aa98e2SPeter WemmDY`'UUCP_RELAY
110c2aa98e2SPeter WemmCPUUCP
111c2aa98e2SPeter Wemm
112c2aa98e2SPeter Wemm')dnl
113c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
114c2aa98e2SPeter Wemm`#  BITNET relay host
115c2aa98e2SPeter WemmDB`'BITNET_RELAY
116c2aa98e2SPeter WemmCPBITNET
117c2aa98e2SPeter Wemm
118c2aa98e2SPeter Wemm')dnl
119c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
120c2aa98e2SPeter Wemm`define(`_USE_DECNET_SYNTAX_', 1)dnl
121c2aa98e2SPeter Wemm# DECnet relay host
122c2aa98e2SPeter WemmDC`'DECNET_RELAY
123c2aa98e2SPeter WemmCPDECNET
124c2aa98e2SPeter Wemm
125c2aa98e2SPeter Wemm')dnl
126c2aa98e2SPeter Wemmifdef(`FAX_RELAY',
127c2aa98e2SPeter Wemm`# FAX relay host
128c2aa98e2SPeter WemmDF`'FAX_RELAY
129c2aa98e2SPeter WemmCPFAX
130c2aa98e2SPeter Wemm
131c2aa98e2SPeter Wemm')dnl
132c2aa98e2SPeter Wemm# "Smart" relay host (may be null)
133c2aa98e2SPeter WemmDS`'ifdef(`SMART_HOST', SMART_HOST)
134c2aa98e2SPeter Wemm
135c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
136c2aa98e2SPeter Wemm# place to which unknown users should be forwarded
137c2aa98e2SPeter WemmKuser user -m -a<>
138c2aa98e2SPeter WemmDL`'LUSER_RELAY',
139c2aa98e2SPeter Wemm`dnl')
140c2aa98e2SPeter Wemm
141c2aa98e2SPeter Wemm# operators that cannot be in local usernames (i.e., network indicators)
142c2aa98e2SPeter WemmCO @ % ifdef(`_NO_UUCP_', `', `!')
143c2aa98e2SPeter Wemm
144c2aa98e2SPeter Wemm# a class with just dot (for identifying canonical names)
145c2aa98e2SPeter WemmC..
146c2aa98e2SPeter Wemm
147c2aa98e2SPeter Wemm# a class with just a left bracket (for identifying domain literals)
148c2aa98e2SPeter WemmC[[
149c2aa98e2SPeter Wemm
15006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
15106f25ae9SGregory Neil Shapiro# access_db acceptance class
15206f25ae9SGregory Neil ShapiroC{Accept}OK RELAY
15306f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
15406f25ae9SGregory Neil Shapiroifdef(`_BLACKLIST_RCPT_',`dnl
15506f25ae9SGregory Neil Shapiro# possible access_db RHS for spam friends/haters
15606f25ae9SGregory Neil ShapiroC{SpamTag}SPAMFRIEND SPAMHATER')')',
157c2aa98e2SPeter Wemm`dnl')
158c2aa98e2SPeter Wemm
159c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',`dnl',`dnl
160c2aa98e2SPeter Wemm# Resolve map (to check if a host exists in check_mail)
161c2aa98e2SPeter WemmKresolve host -a<OK> -T<TEMP>')
162c2aa98e2SPeter Wemm
163c2aa98e2SPeter Wemmifdef(`confCR_FILE', `dnl
164c2aa98e2SPeter Wemm# Hosts that will permit relaying ($=R)
165c2aa98e2SPeter WemmFR`'confCR_FILE',
166c2aa98e2SPeter Wemm`dnl')
167c2aa98e2SPeter Wemm
16806f25ae9SGregory Neil Shapirodefine(`TLS_SRV_TAG', `TLS_Srv')dnl
16906f25ae9SGregory Neil Shapirodefine(`TLS_CLT_TAG', `TLS_Clt')dnl
17006f25ae9SGregory Neil Shapirodefine(`TLS_TRY_TAG', `Try_TLS')dnl
17106f25ae9SGregory Neil Shapirodefine(`TLS_OFF_TAG', `Offer_TLS')dnl
17206f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
17306f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
17406f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
17506f25ae9SGregory Neil ShapiroKarith arith')
17606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
17706f25ae9SGregory Neil Shapiro# possible values for tls_connect in access map
17806f25ae9SGregory Neil ShapiroC{tls}VERIFY ENCR', `dnl')
17906f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
18006f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
18106f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
18206f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
18306f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
18406f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
18506f25ae9SGregory Neil Shapiro
186c2aa98e2SPeter Wemm# who I send unqualified names to (null means deliver locally)
187c2aa98e2SPeter WemmDR`'ifdef(`LOCAL_RELAY', LOCAL_RELAY)
188c2aa98e2SPeter Wemm
189c2aa98e2SPeter Wemm# who gets all local email traffic ($R has precedence for unqualified names)
190c2aa98e2SPeter WemmDH`'ifdef(`MAIL_HUB', MAIL_HUB)
191c2aa98e2SPeter Wemm
192c2aa98e2SPeter Wemm# dequoting map
193c2aa98e2SPeter WemmKdequote dequote
194c2aa98e2SPeter Wemm
195c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
196c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
19706f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
198c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
19906f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
200c2aa98e2SPeter Wemm#CL root
201c2aa98e2SPeter Wemmundivert(5)dnl
20206f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
203c2aa98e2SPeter Wemm
204c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
205c2aa98e2SPeter WemmDM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME)
206c2aa98e2SPeter Wemm
207c2aa98e2SPeter Wemm# my name for error messages
208c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
209c2aa98e2SPeter Wemm
21006f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
211c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
212c2aa98e2SPeter Wemm
213c2aa98e2SPeter Wemm###############
214c2aa98e2SPeter Wemm#   Options   #
215c2aa98e2SPeter Wemm###############
216c2aa98e2SPeter Wemm
217c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
21806f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
219c2aa98e2SPeter Wemm
220c2aa98e2SPeter Wemm# 8-bit data handling
22106f25ae9SGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `adaptive')
222c2aa98e2SPeter Wemm
223c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
22406f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
225c2aa98e2SPeter Wemm
226c2aa98e2SPeter Wemm# location of alias file
22706f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
22806f25ae9SGregory Neil Shapiro
229c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
23006f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
231c2aa98e2SPeter Wemm
232c2aa98e2SPeter Wemm# maximum message size
23306f25ae9SGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `1000000')
234c2aa98e2SPeter Wemm
235c2aa98e2SPeter Wemm# substitution for space (blank) characters
23606f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
237c2aa98e2SPeter Wemm
238c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
23906f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
240c2aa98e2SPeter Wemm
241c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
24206f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
243c2aa98e2SPeter Wemm
244c2aa98e2SPeter Wemm# default delivery mode
24506f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
246c2aa98e2SPeter Wemm
247c2aa98e2SPeter Wemm# automatically rebuild the alias database?
24806f25ae9SGregory Neil Shapiro# NOTE: There is a potential for a denial of service attack if this is set.
24906f25ae9SGregory Neil Shapiro#       This option is deprecated and will be removed from a future version.
25006f25ae9SGregory Neil Shapiro_OPTION(AutoRebuildAliases, `confAUTO_REBUILD', `False')
251c2aa98e2SPeter Wemm
252c2aa98e2SPeter Wemm# error message header/file
25306f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
254c2aa98e2SPeter Wemm
255c2aa98e2SPeter Wemm# error mode
25606f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
257c2aa98e2SPeter Wemm
258c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
25906f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
260c2aa98e2SPeter Wemm
261c2aa98e2SPeter Wemm# temporary file mode
26206f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
263c2aa98e2SPeter Wemm
264c2aa98e2SPeter Wemm# match recipients against GECOS field?
26506f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
266c2aa98e2SPeter Wemm
267c2aa98e2SPeter Wemm# maximum hop count
26806f25ae9SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `17')
269c2aa98e2SPeter Wemm
270c2aa98e2SPeter Wemm# location of help file
27106f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
272c2aa98e2SPeter Wemm
273c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
27406f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
275c2aa98e2SPeter Wemm
276c2aa98e2SPeter Wemm# name resolver options
27706f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
278c2aa98e2SPeter Wemm
279c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
28006f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
281c2aa98e2SPeter Wemm
282c2aa98e2SPeter Wemm# Forward file search path
28306f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
284c2aa98e2SPeter Wemm
285c2aa98e2SPeter Wemm# open connection cache size
28606f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
287c2aa98e2SPeter Wemm
288c2aa98e2SPeter Wemm# open connection cache timeout
28906f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
290c2aa98e2SPeter Wemm
291c2aa98e2SPeter Wemm# persistent host status directory
29206f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
293c2aa98e2SPeter Wemm
294c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
29506f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
296c2aa98e2SPeter Wemm
297c2aa98e2SPeter Wemm# use Errors-To: header?
29806f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
299c2aa98e2SPeter Wemm
300c2aa98e2SPeter Wemm# log level
30106f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
302c2aa98e2SPeter Wemm
303c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
30406f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
305c2aa98e2SPeter Wemm
306c2aa98e2SPeter Wemm# verify RHS in newaliases?
30706f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
308c2aa98e2SPeter Wemm
309c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
31006f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
311c2aa98e2SPeter Wemm
312c2aa98e2SPeter Wemm# SMTP daemon options
31306f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
31406f25ae9SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.  See cf/README for more information.
31506f25ae9SGregory Neil Shapiro)'dnl
31606f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
31706f25ae9SGregory Neil Shapiroifelse(defn(`_DPO_'), `', `O DaemonPortOptions=Name=MTA', `_DPO_')
31806f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
31906f25ae9SGregory Neil Shapiro
32006f25ae9SGregory Neil Shapiro# SMTP client options
32106f25ae9SGregory Neil Shapiro_OPTION(ClientPortOptions, `confCLIENT_OPTIONS', `Address=0.0.0.0')
322c2aa98e2SPeter Wemm
323c2aa98e2SPeter Wemm# privacy flags
32406f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
325c2aa98e2SPeter Wemm
326c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
32706f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
328c2aa98e2SPeter Wemm
329c2aa98e2SPeter Wemm# slope of queue-only function
33006f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
331c2aa98e2SPeter Wemm
332c2aa98e2SPeter Wemm# queue directory
33306f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
334c2aa98e2SPeter Wemm
335c2aa98e2SPeter Wemm# timeouts (many of these)
33606f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
33706f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
33806f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
33906f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
34006f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
34106f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
34206f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
34306f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
34406f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
34506f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
34606f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
34706f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
34806f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
34906f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
35006f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
35106f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
35206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
35306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
35406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
35506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
35606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
35706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
35806f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
35906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
36006f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
36106f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
36206f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
36306f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
36406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
36506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
36606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
367c2aa98e2SPeter Wemm
368c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
36906f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
370c2aa98e2SPeter Wemm
371c2aa98e2SPeter Wemm# queue up everything before forking?
37206f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
373c2aa98e2SPeter Wemm
374c2aa98e2SPeter Wemm# status file
37506f25ae9SGregory Neil ShapiroO StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', `MAIL_SETTINGS_DIR`'statistics')
376c2aa98e2SPeter Wemm
377c2aa98e2SPeter Wemm# time zone handling:
378c2aa98e2SPeter Wemm#  if undefined, use system default
379c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
380c2aa98e2SPeter Wemm#  if defined and non-null, use that info
381c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
382c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
383c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
384c2aa98e2SPeter Wemm
385c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
38606f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
387c2aa98e2SPeter Wemm
388c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
38906f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
390c2aa98e2SPeter Wemm
391c2aa98e2SPeter Wemm# fallback MX host
39206f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
393c2aa98e2SPeter Wemm
394c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
39506f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
396c2aa98e2SPeter Wemm
397c2aa98e2SPeter Wemm# load average at which we just queue messages
39806f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
399c2aa98e2SPeter Wemm
400c2aa98e2SPeter Wemm# load average at which we refuse connections
40106f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
402c2aa98e2SPeter Wemm
403c2aa98e2SPeter Wemm# maximum number of children we allow at one time
40406f25ae9SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `12')
405c2aa98e2SPeter Wemm
406c2aa98e2SPeter Wemm# maximum number of new connections per second
40706f25ae9SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `3')
408c2aa98e2SPeter Wemm
409c2aa98e2SPeter Wemm# work recipient factor
41006f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
411c2aa98e2SPeter Wemm
412c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
41306f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
414c2aa98e2SPeter Wemm
415c2aa98e2SPeter Wemm# work class factor
41606f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
417c2aa98e2SPeter Wemm
418c2aa98e2SPeter Wemm# work time factor
41906f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
420c2aa98e2SPeter Wemm
421c2aa98e2SPeter Wemm# shall we sort the queue by hostname first?
42206f25ae9SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
423c2aa98e2SPeter Wemm
424c2aa98e2SPeter Wemm# minimum time in queue before retry
42506f25ae9SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
426c2aa98e2SPeter Wemm
427c2aa98e2SPeter Wemm# default character set
42806f25ae9SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `iso-8859-1')
429c2aa98e2SPeter Wemm
430c2aa98e2SPeter Wemm# service switch file (ignored on Solaris, Ultrix, OSF/1, others)
43106f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
432c2aa98e2SPeter Wemm
433c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
43406f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
435c2aa98e2SPeter Wemm
436c2aa98e2SPeter Wemm# dialup line delay on connection failure
43706f25ae9SGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `10s')
438c2aa98e2SPeter Wemm
439c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
44006f25ae9SGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `add-to-undisclosed')
441c2aa98e2SPeter Wemm
442c2aa98e2SPeter Wemm# chrooted environment for writing to files
44306f25ae9SGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `/arch')
444c2aa98e2SPeter Wemm
445c2aa98e2SPeter Wemm# are colons OK in addresses?
44606f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
447c2aa98e2SPeter Wemm
448c2aa98e2SPeter Wemm# how many jobs can you process in the queue?
44906f25ae9SGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `10000')
450c2aa98e2SPeter Wemm
451c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
45206f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
453c2aa98e2SPeter Wemm
454c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
45506f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
456c2aa98e2SPeter Wemm
457c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
45806f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
459c2aa98e2SPeter Wemm
460c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
46106f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
462c2aa98e2SPeter Wemm
463c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
46406f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
465c2aa98e2SPeter Wemm
466c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
46706f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
468c2aa98e2SPeter Wemm
469c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
47006f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
471c2aa98e2SPeter Wemm
472c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
47306f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
474c2aa98e2SPeter Wemm
475c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
47606f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
477c2aa98e2SPeter Wemm
478c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
47906f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
48006f25ae9SGregory Neil Shapiro
48106f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
48206f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
483c2aa98e2SPeter Wemm
484c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
48506f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
486c2aa98e2SPeter Wemm
487c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
48806f25ae9SGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `100')
489c2aa98e2SPeter Wemm
490c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
49106f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
492c2aa98e2SPeter Wemm
49306f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
49406f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
49506f25ae9SGregory Neil Shapiro
49606f25ae9SGregory Neil Shapiro# override connection address (for testing)
49706f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
49806f25ae9SGregory Neil Shapiro
49906f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
50006f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
50106f25ae9SGregory Neil Shapiro
50206f25ae9SGregory Neil Shapiro# Control socket for daemon management
50306f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
50406f25ae9SGregory Neil Shapiro
50506f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
50606f25ae9SGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
50706f25ae9SGregory Neil Shapiro
50806f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
50906f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
51006f25ae9SGregory Neil Shapiro
51106f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
51206f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
51306f25ae9SGregory Neil Shapiro
51406f25ae9SGregory Neil Shapiro# location of pid file
51506f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
51606f25ae9SGregory Neil Shapiro
51706f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
51806f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
51906f25ae9SGregory Neil Shapiro
52006f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
52106f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
52206f25ae9SGregory Neil Shapiro
52306f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
52406f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
52506f25ae9SGregory Neil Shapiro
52606f25ae9SGregory Neil Shapiro# list of authentication mechanisms
52706f25ae9SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
52806f25ae9SGregory Neil Shapiro
52906f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
53006f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
53106f25ae9SGregory Neil Shapiro
53206f25ae9SGregory Neil Shapiro# SMTP AUTH flags
53306f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
53406f25ae9SGregory Neil Shapiro
53506f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
53606f25ae9SGregory Neil Shapiro# Input mail filters
53706f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
53806f25ae9SGregory Neil Shapiro
53906f25ae9SGregory Neil Shapiro# Milter options
54006f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
54106f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
54206f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
54306f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')')
54406f25ae9SGregory Neil Shapiro
54506f25ae9SGregory Neil Shapiro# CA directory
54606f25ae9SGregory Neil Shapiro_OPTION(CACERTPath, `confCACERT_PATH', `')
54706f25ae9SGregory Neil Shapiro# CA file
54806f25ae9SGregory Neil Shapiro_OPTION(CACERTFile, `confCACERT', `')
54906f25ae9SGregory Neil Shapiro# Server Cert
55006f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
55106f25ae9SGregory Neil Shapiro# Server private key
55206f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
55306f25ae9SGregory Neil Shapiro# Client Cert
55406f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
55506f25ae9SGregory Neil Shapiro# Client private key
55606f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
55706f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
55806f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
55906f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
56006f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
56106f25ae9SGregory Neil Shapiro
56206f25ae9SGregory Neil Shapiroifdef(`confQUEUE_FILE_MODE',
56306f25ae9SGregory Neil Shapiro`# queue file mode (qf files)
56406f25ae9SGregory Neil ShapiroO QueueFileMode=confQUEUE_FILE_MODE
56525bab6e9SPeter Wemm')
566065a643dSPeter Wemm
567c2aa98e2SPeter Wemm###########################
568c2aa98e2SPeter Wemm#   Message precedences   #
569c2aa98e2SPeter Wemm###########################
570c2aa98e2SPeter Wemm
571c2aa98e2SPeter WemmPfirst-class=0
572c2aa98e2SPeter WemmPspecial-delivery=100
573c2aa98e2SPeter WemmPlist=-30
574c2aa98e2SPeter WemmPbulk=-60
575c2aa98e2SPeter WemmPjunk=-100
576c2aa98e2SPeter Wemm
577c2aa98e2SPeter Wemm#####################
578c2aa98e2SPeter Wemm#   Trusted users   #
579c2aa98e2SPeter Wemm#####################
580c2aa98e2SPeter Wemm
581c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
58206f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
583c2aa98e2SPeter WemmTroot
584c2aa98e2SPeter WemmTdaemon
585c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
586c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
587c2aa98e2SPeter Wemm
588c2aa98e2SPeter Wemm#########################
589c2aa98e2SPeter Wemm#   Format of headers   #
590c2aa98e2SPeter Wemm#########################
591c2aa98e2SPeter Wemm
592c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
593c2aa98e2SPeter WemmH?P?Return-Path: <$g>
594c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
595c2aa98e2SPeter WemmH?D?Resent-Date: $a
596c2aa98e2SPeter WemmH?D?Date: $a
597c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
598c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
599c2aa98e2SPeter WemmH?x?Full-Name: $x
600c2aa98e2SPeter Wemm# HPosted-Date: $a
601c2aa98e2SPeter Wemm# H?l?Received-Date: $b
602c2aa98e2SPeter WemmH?M?Resent-Message-Id: <$t.$i@$j>
603c2aa98e2SPeter WemmH?M?Message-Id: <$t.$i@$j>
60406f25ae9SGregory Neil Shapiro
605c2aa98e2SPeter Wemm#
606c2aa98e2SPeter Wemm######################################################################
607c2aa98e2SPeter Wemm######################################################################
608c2aa98e2SPeter Wemm#####
609c2aa98e2SPeter Wemm#####			REWRITING RULES
610c2aa98e2SPeter Wemm#####
611c2aa98e2SPeter Wemm######################################################################
612c2aa98e2SPeter Wemm######################################################################
613c2aa98e2SPeter Wemm
614c2aa98e2SPeter Wemm############################################
615c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
616c2aa98e2SPeter Wemm############################################
61706f25ae9SGregory Neil ShapiroScanonify=3
618c2aa98e2SPeter Wemm
619c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
620c2aa98e2SPeter WemmR$@			$@ <@>
621c2aa98e2SPeter Wemm
622c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
623c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
624c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
625c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
626c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
627c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
62806f25ae9SGregory Neil ShapiroR$* [ IPv6 $- ] <@>	$: $1 [ IPv6 $2 ]		unmark IPv6 addr
629c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
630c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
631c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
632c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
633c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
634c2aa98e2SPeter Wemm
635c2aa98e2SPeter Wemm# null input now results from list:; syntax
636c2aa98e2SPeter WemmR$@			$@ :; <@>
637c2aa98e2SPeter Wemm
638c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
639c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
640c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
641c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
642c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
643c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
644c2aa98e2SPeter Wemm
64506f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
646c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
647c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
648c2aa98e2SPeter Wemm
649c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
65006f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
65106f25ae9SGregory Neil Shapirodnl',`dnl
65206f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
65306f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
65406f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
65506f25ae9SGregory Neil Shapirodnl')
656c2aa98e2SPeter Wemm
657c2aa98e2SPeter Wemm# find focus for list syntax
65806f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
659c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
660c2aa98e2SPeter Wemm
661c2aa98e2SPeter Wemm# find focus for @ syntax addresses
662c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
663c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
66406f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
665c2aa98e2SPeter Wemm
666c2aa98e2SPeter Wemm# do some sanity checking
667c2aa98e2SPeter WemmR$* < @ $* : $* > $*	$1 < @ $2 $3 > $4		nix colons in addrs
668c2aa98e2SPeter Wemm
669c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
670c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
67106f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
67206f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
67306f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
674c2aa98e2SPeter Wemm')
675c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
676c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
67706f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
67806f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
679c2aa98e2SPeter Wemm',
680c2aa98e2SPeter Wemm	`dnl')
681c2aa98e2SPeter Wemm# if we have % signs, take the rightmost one
682c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
683c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
68406f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
685c2aa98e2SPeter Wemm
686c2aa98e2SPeter Wemm# else we must be a local name
68706f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
688c2aa98e2SPeter Wemm
689c2aa98e2SPeter Wemm
690c2aa98e2SPeter Wemm################################################
691c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
692c2aa98e2SPeter Wemm################################################
693c2aa98e2SPeter Wemm
69406f25ae9SGregory Neil ShapiroSCanonify2=96
695c2aa98e2SPeter Wemm
696c2aa98e2SPeter Wemm# handle special cases for local names
697c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
698c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
699c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
700c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
70106f25ae9SGregory Neil Shapiro
70206f25ae9SGregory Neil Shapiro# check for IPv6 domain literal (save quoted form)
70306f25ae9SGregory Neil ShapiroR$* < @ [ IPv6 $- ] > $*	$: $2 $| $1 < @@ [ $(dequote $2 $) ] > $3	mark IPv6 addr
70406f25ae9SGregory Neil ShapiroR$- $| $* < @@ $=w > $*		$: $2 < @ $j . > $4		self-literal
70506f25ae9SGregory Neil ShapiroR$- $| $* < @@ [ $+ ] > $*	$@ $2 < @ [ IPv6 $1 ] > $4	canon IP addr
70606f25ae9SGregory Neil Shapiro
70706f25ae9SGregory Neil Shapiro# check for IPv4 domain literal
708c2aa98e2SPeter WemmR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [a.b.c.d]
709c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
710c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
711c2aa98e2SPeter Wemm
71206f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
713c2aa98e2SPeter Wemm# look up domains in the domain table
714c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
715c2aa98e2SPeter Wemm
71606f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
717c2aa98e2SPeter Wemm
71806f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
719c2aa98e2SPeter Wemm# handle BITNET mapping
720c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
721c2aa98e2SPeter Wemm
72206f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
723c2aa98e2SPeter Wemm# handle UUCP mapping
724c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
725c2aa98e2SPeter Wemm
726c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
727c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
728c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
729c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
730c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
731c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
732c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
733c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
734c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
735c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
736c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
737c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
738c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
739c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
740c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
741c2aa98e2SPeter Wemm
742c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
743c2aa98e2SPeter Wemm# try UUCP traffic as a local address
744c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
745c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
746c2aa98e2SPeter Wemm')')
74706f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
74806f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
74906f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
75006f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
75106f25ae9SGregory Neil Shapirodnl which daemon flags are set?
75206f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
75306f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
75406f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
75506f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
75606f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
75706f25ae9SGregory Neil Shapirodnl do not canonify unless:
75806f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
75906f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
76006f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
76106f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
76206f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
76306f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
76406f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
76506f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
76606f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
76706f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
76806f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
76906f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
77006f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
77106f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
77206f25ae9SGregory Neil Shapirodnl then $- does not work.
77306f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
77406f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*	$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
77506f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
77606f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
77706f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
778c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
77906f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
78006f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
78106f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
782c2aa98e2SPeter Wemm
783c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
784c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
785c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
786c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
787c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
78806f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
78906f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
79006f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
79106f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
79206f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
79306f25ae9SGregory Neil Shapiro`dnl')
79406f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
79506f25ae9SGregory Neil Shapirodnl by one of the rules before
796c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
797c2aa98e2SPeter Wemm
798c2aa98e2SPeter Wemm
799c2aa98e2SPeter Wemm##################################################
800c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
801c2aa98e2SPeter Wemm##################################################
80206f25ae9SGregory Neil ShapiroSfinal=4
803c2aa98e2SPeter Wemm
804c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
805c2aa98e2SPeter Wemm
806c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
807c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
808c2aa98e2SPeter Wemm
80906f25ae9SGregory Neil Shapiro# eliminate internal code
810c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
811c2aa98e2SPeter Wemm
812c2aa98e2SPeter Wemm# externalize local domain info
813c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
814c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
815c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
816c2aa98e2SPeter Wemm
817c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
818c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
819c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
820c2aa98e2SPeter Wemm
821c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
822c2aa98e2SPeter Wemm`# put DECnet back in :: form
823c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
824c2aa98e2SPeter Wemm	`dnl')
825c2aa98e2SPeter Wemm# delete duplicate local names
826c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
827c2aa98e2SPeter Wemm
828c2aa98e2SPeter Wemm
829c2aa98e2SPeter Wemm
830c2aa98e2SPeter Wemm##############################################################
831c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
832c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
833c2aa98e2SPeter Wemm##############################################################
834c2aa98e2SPeter Wemm
83506f25ae9SGregory Neil ShapiroSRecurse=97
83606f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
83706f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
838c2aa98e2SPeter Wemm
839c2aa98e2SPeter Wemm
840c2aa98e2SPeter Wemm######################################
841c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
842c2aa98e2SPeter Wemm######################################
843c2aa98e2SPeter Wemm
84406f25ae9SGregory Neil ShapiroSparse=0
845c2aa98e2SPeter Wemm
846c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
847c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
84806f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
849c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
850c2aa98e2SPeter Wemm
851c2aa98e2SPeter Wemm#
852c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
853c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
854c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
855c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
856c2aa98e2SPeter Wemm#
857c2aa98e2SPeter Wemm
858c2aa98e2SPeter WemmSParse0
859c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
86006f25ae9SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "553 List:; syntax illegal for recipient addresses"
86106f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
86206f25ae9SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "553 User address required"
863c2aa98e2SPeter WemmR$*			$: <> $1
864c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*	$1 < @ [ $2 ] > $3
86506f25ae9SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "553 Colon illegal in host name part"
866c2aa98e2SPeter WemmR<> $*			$1
86706f25ae9SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "553 Invalid host name"
86806f25ae9SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "553 Invalid host name"
86906f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
87006f25ae9SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.2 $: "553 Invalid route address"
871c2aa98e2SPeter Wemm
872c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
87306f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
87406f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
875c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
87606f25ae9SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "553 User address required"
87706f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
878c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
87906f25ae9SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "553 User address required"
880c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
88106f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
882c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
883c2aa98e2SPeter Wemm
884c2aa98e2SPeter Wemm#
885c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
886c2aa98e2SPeter Wemm#
887c2aa98e2SPeter Wemm
888c2aa98e2SPeter WemmSParse1
88906f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
89006f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
89106f25ae9SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2>',
892c2aa98e2SPeter Wemm`dnl')
893c2aa98e2SPeter Wemm
89406f25ae9SGregory Neil Shapiro
89506f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
89606f25ae9SGregory Neil Shapiro`# handle numeric address spec
89706f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
89806f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
89906f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$1 < @ [ $2 ] : $S > $3		Add smart host to path
90006f25ae9SGregory Neil ShapiroR$* < @ [ IPv6 $- ] : > $*
90106f25ae9SGregory Neil Shapiro		$#_SMTP_ $@ [ $(dequote $2 $) ] $: $1 < @ [IPv6 $2 ] > $3	no smarthost: send
90206f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*	$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
90306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
90406f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
90506f25ae9SGregory Neil Shapiro	`dnl')
90606f25ae9SGregory Neil Shapiro
90706f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
908c2aa98e2SPeter Wemm# handle virtual users
90906f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
91006f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
91106f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
91206f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
91306f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
914c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
91506f25ae9SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
916c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
917c2aa98e2SPeter Wemm			$: < $(virtuser $1 @ $3 $@ $1 $: @ $) > $1 + $2 < @ $3 . >
91806f25ae9SGregory Neil Shapirodnl try default entry: @domain
91906f25ae9SGregory Neil Shapirodnl +*@domain
92006f25ae9SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
92106f25ae9SGregory Neil Shapirodnl @domain if +detail exists
92206f25ae9SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
92306f25ae9SGregory Neil Shapirodnl without +detail (or no match)
924c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
925c2aa98e2SPeter WemmR<@> $+			$: $1
92606f25ae9SGregory Neil ShapiroR<!> $+			$: $1
92706f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
928c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
92906f25ae9SGregory Neil ShapiroR< $+ > $+ < @ $+ >	$: $>Recurse $1',
930c2aa98e2SPeter Wemm`dnl')
931c2aa98e2SPeter Wemm
932c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
933c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
93406f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
935c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
936c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
93706f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
93806f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
939c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
940c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
941c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
942c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
943c2aa98e2SPeter Wemm
94406f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
945c2aa98e2SPeter Wemm# not local -- try mailer table lookup
946c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
947c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
948c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
94906f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
95006f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
95106f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
952c2aa98e2SPeter Wemm`dnl')
95306f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
954c2aa98e2SPeter Wemm
955c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
956c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
957c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
95806f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
959c2aa98e2SPeter Wemm	`dnl')
960c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
96106f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
962c2aa98e2SPeter Wemm	`dnl')
963c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
96406f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
965c2aa98e2SPeter Wemm	`dnl')')
966c2aa98e2SPeter Wemm
967c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
968c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
96906f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
970c2aa98e2SPeter Wemm	`dnl')
971c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
97206f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
973c2aa98e2SPeter Wemm	`dnl')
974c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
975c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
976c2aa98e2SPeter Wemm	`dnl')
977c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
978c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
979c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
98006f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
981c2aa98e2SPeter Wemm	`dnl')')
982c2aa98e2SPeter Wemm
983c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
984c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
98506f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
986c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
987c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
988c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
989c2aa98e2SPeter Wemm	`dnl')')
990c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
991c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
99206f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
993c2aa98e2SPeter Wemm	`dnl')
994c2aa98e2SPeter Wemm
995c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
996c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
997c2aa98e2SPeter Wemmundivert(1)', `dnl')
998c2aa98e2SPeter Wemm
999c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
100006f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1001c2aa98e2SPeter Wemm
1002c2aa98e2SPeter Wemm# deal with other remote names
1003c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1004c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
100506f25ae9SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "553 Unrecognized host name " $2')
1006c2aa98e2SPeter Wemm
1007c2aa98e2SPeter Wemm# handle locally delivered names
1008c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1009c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1010c2aa98e2SPeter Wemm
1011c2aa98e2SPeter Wemm###########################################################################
1012c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1013c2aa98e2SPeter Wemm###########################################################################
1014c2aa98e2SPeter Wemm
101506f25ae9SGregory Neil ShapiroSLocal_localaddr
101606f25ae9SGregory Neil ShapiroSlocaladdr=5
101706f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
101806f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
101906f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1020c2aa98e2SPeter Wemm
1021c2aa98e2SPeter Wemm# deal with plussed users so aliases work nicely
1022c2aa98e2SPeter WemmR$+ + *			$#_LOCAL_ $@ $&h $: $1
1023c2aa98e2SPeter WemmR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *
1024c2aa98e2SPeter Wemm
1025c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1026c2aa98e2SPeter WemmR$+			$: <> $1
1027c2aa98e2SPeter Wemm
1028c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1029c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
103006f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
103106f25ae9SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L',
1032c2aa98e2SPeter Wemm`dnl')
1033c2aa98e2SPeter Wemm
1034c2aa98e2SPeter Wemm# see if we have a relay or a hub
1035c2aa98e2SPeter WemmR< > $+			$: < $H > $1			try hub
1036c2aa98e2SPeter WemmR< > $+			$: < $R > $1			try relay
103706f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
103806f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
103906f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1040c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
1041c2aa98e2SPeter WemmR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1		strip the extra +
1042c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
10432e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
10442e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
10452e43090eSPeter WemmR$+ <> $*		$: $1				else discard
104606f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
104706f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
104806f25ae9SGregory Neil ShapiroR< $- : $+ > $+		$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
104906f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1050c2aa98e2SPeter Wemm
105106f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1052c2aa98e2SPeter Wemm###################################################################
1053c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
105406f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1055c2aa98e2SPeter Wemm###################################################################
1056c2aa98e2SPeter Wemm
105706f25ae9SGregory Neil ShapiroSMailertable=90
105806f25ae9SGregory Neil Shapirodnl shift and check
105906f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1060c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
106106f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
106206f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
106306f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
106406f25ae9SGregory Neil Shapirodnl is $2 always empty?
1065c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
106606f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
106706f25ae9SGregory Neil Shapirodnl return full address
1068c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1069c2aa98e2SPeter Wemm`dnl')
1070c2aa98e2SPeter Wemm
1071c2aa98e2SPeter Wemm###################################################################
1072c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
107306f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
107406f25ae9SGregory Neil Shapirodnl	<> address				-> address
107506f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
107606f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
107706f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
107806f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
107906f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
108006f25ae9SGregory Neil Shapirodnl	<[IPv6 number]> address			-> relay number address
108106f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1082c2aa98e2SPeter Wemm###################################################################
1083c2aa98e2SPeter Wemm
108406f25ae9SGregory Neil ShapiroSMailerToTriple=95
1085c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
108606f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1087c2aa98e2SPeter WemmR< error : $- $+ > $*		$#error $@ $(dequote $1 $) $: $2
1088c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
1089c2aa98e2SPeter WemmR< $- : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
1090c2aa98e2SPeter WemmR< $- : $+ > $*			$# $1 $@ $2 $: $3	try qualified mailer
1091c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
109206f25ae9SGregory Neil ShapiroR< [ IPv6 $+ ] > $*		$#_RELAY_ $@ $(dequote $1 $) $: $2	use unqualified mailer
1093c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1094c2aa98e2SPeter Wemm
1095c2aa98e2SPeter Wemm###################################################################
1096c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
109706f25ae9SGregory Neil Shapirodnl input: <user> address
109806f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
109906f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
110006f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
110106f25ae9SGregory Neil Shapirodnl <> user				-> local user user
110206f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
110306f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
110406f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1105c2aa98e2SPeter Wemm###################################################################
1106c2aa98e2SPeter Wemm
1107c2aa98e2SPeter WemmSCanonLocal
11082e43090eSPeter Wemm# strip local host from routed addresses
110906f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
111006f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
11112e43090eSPeter Wemm
1112c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1113c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1114c2aa98e2SPeter Wemm
1115c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1116c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1117c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1118c2aa98e2SPeter Wemm
1119c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1120c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1121c2aa98e2SPeter Wemm
1122c2aa98e2SPeter Wemm# handle local:user syntax
1123c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1124c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1125c2aa98e2SPeter Wemm
1126c2aa98e2SPeter Wemm###################################################################
1127c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1128c2aa98e2SPeter Wemm###################################################################
1129c2aa98e2SPeter Wemm
113006f25ae9SGregory Neil ShapiroSMasqHdr=93
1131c2aa98e2SPeter Wemm
113206f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1133c2aa98e2SPeter Wemm# handle generics database
1134c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
113506f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1136c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1137c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1138c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
113906f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
114006f25ae9SGregory Neil Shapirodnl ignore the first case for now
114106f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
114206f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
114306f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
114406f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
114506f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
114606f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
114706f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
114806f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
114906f25ae9SGregory Neil Shapirodnl no match, remove mark
115006f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
115106f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
115206f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
115306f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
115406f25ae9SGregory Neil Shapirodnl no match, try local part
1155c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
115606f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
115706f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
115806f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
115906f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1160c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1161c2aa98e2SPeter Wemm`dnl')
1162c2aa98e2SPeter Wemm
116306f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
116406f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
116506f25ae9SGregory Neil Shapiro
1166c2aa98e2SPeter Wemm# special case the users that should be exposed
1167c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1168c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1169c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1170c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1171c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1172c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1173c2aa98e2SPeter Wemm
1174c2aa98e2SPeter Wemm# handle domain-specific masquerading
1175c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1176c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1177c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1178c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1179c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1180c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1181c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1182c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
1183c2aa98e2SPeter Wemm
1184c2aa98e2SPeter Wemm###################################################################
1185c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1186c2aa98e2SPeter Wemm###################################################################
1187c2aa98e2SPeter Wemm
118806f25ae9SGregory Neil ShapiroSMasqEnv=94
1189c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
119006f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1191c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1192c2aa98e2SPeter Wemm
1193c2aa98e2SPeter Wemm###################################################################
1194c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1195c2aa98e2SPeter Wemm###################################################################
1196c2aa98e2SPeter Wemm
119706f25ae9SGregory Neil ShapiroSParseLocal=98
119806f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1199c2aa98e2SPeter Wemm
120006f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
120106f25ae9SGregory Neil ShapiroSLDAPExpand
120206f25ae9SGregory Neil Shapiro# do the LDAP lookups
120306f25ae9SGregory Neil ShapiroR<$+><$+>		$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2>
120406f25ae9SGregory Neil Shapiro
120506f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
120606f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
120706f25ae9SGregory Neil ShapiroR< $+ > < $=w > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
120806f25ae9SGregory Neil ShapiroR< $+ > <  > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
120906f25ae9SGregory Neil Shapiro
121006f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
121106f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
121206f25ae9SGregory Neil ShapiroR< $+ > < $+ > < $+ > < $+ >	$#_RELAY_ $@ $2 $: $>canonify $1
121306f25ae9SGregory Neil Shapiro
121406f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
121506f25ae9SGregory Neil Shapiro# return original address
121606f25ae9SGregory Neil ShapiroR< > < $=w > <$+> <$+>		$@ $2
121706f25ae9SGregory Neil Shapiro
121806f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
121906f25ae9SGregory Neil Shapiro# relay to mailHost with original address
122006f25ae9SGregory Neil ShapiroR< > < $+ > <$+> <$+>		$#_RELAY_ $@ $1 $: $2
122106f25ae9SGregory Neil Shapiro
122206f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost,
122306f25ae9SGregory Neil Shapiro# try @domain
122406f25ae9SGregory Neil ShapiroR< > < > <$+> <$+ @ $+>		$@ $>LDAPExpand <$1> <@ $3>
122506f25ae9SGregory Neil Shapiro
122606f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
122706f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
122806f25ae9SGregory Neil Shapiro# user does not exist
122906f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$#error $@ nouser $: "550 User unknown"',
123006f25ae9SGregory Neil Shapiro`dnl
123106f25ae9SGregory Neil Shapiro# return the original address
123206f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$@ $1')',
123306f25ae9SGregory Neil Shapiro`dnl')
123406f25ae9SGregory Neil Shapiro
123506f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
123606f25ae9SGregory Neil Shapiro')')
123706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1238c2aa98e2SPeter Wemm######################################################################
1239c2aa98e2SPeter Wemm###  LookUpDomain -- search for domain in access database
1240c2aa98e2SPeter Wemm###
1241c2aa98e2SPeter Wemm###	Parameters:
1242c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1243c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
124406f25ae9SGregory Neil Shapirodnl			must not be empty
1245c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed unchanged through)
124606f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
124706f25ae9SGregory Neil Shapiro###			! does lookup only with tag
124806f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
124906f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
125006f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1251c2aa98e2SPeter Wemm######################################################################
1252c2aa98e2SPeter Wemm
1253c2aa98e2SPeter WemmSLookUpDomain
125406f25ae9SGregory Neil Shapirodnl remove IPv6 mark and dequote address
125506f25ae9SGregory Neil Shapirodnl it is a bit ugly because it is checked on each "iteration"
125606f25ae9SGregory Neil ShapiroR<[IPv6 $-]> <$+> <$*> <$*>	$: <[$(dequote $1 $)]> <$2> <$3> <$4>
125706f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
125806f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
125906f25ae9SGregory Neil ShapiroR<$*> <$+> <$*> <$- $->		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
126006f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
126106f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
126206f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$- $->	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4> <$5 $6>', `dnl')
126306f25ae9SGregory Neil Shapirodnl lookup without tag?
126406f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $*>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
126506f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
126606f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <+ $*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <$4> <+ $5>', `dnl')
126706f25ae9SGregory Neil Shapirodnl lookup IP address (no check is done whether it is an IP number!)
126806f25ae9SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$*> <$*>	$@ $>LookUpDomain <[$1]> <$3> <$4> <$5>
126906f25ae9SGregory Neil Shapirodnl lookup IPv6 address
127006f25ae9SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$*> <$*>	$: $>LookUpDomain <[$1]> <$3> <$4> <$5>
127106f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
127206f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$*>	$@ $>LookUpDomain <$2> <$3> <$4> <$5>
127306f25ae9SGregory Neil Shapirodnl not found, no subdomain: return default
127406f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
127506f25ae9SGregory Neil Shapirodnl return result of lookup
127606f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>
1277c2aa98e2SPeter Wemm
1278c2aa98e2SPeter Wemm######################################################################
1279c2aa98e2SPeter Wemm###  LookUpAddress -- search for host address in access database
1280c2aa98e2SPeter Wemm###
1281c2aa98e2SPeter Wemm###	Parameters:
1282c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1283c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
128406f25ae9SGregory Neil Shapirodnl			must not be empty
1285c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed through)
128606f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
128706f25ae9SGregory Neil Shapiro###			! does lookup only with tag
128806f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
128906f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
129006f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1291c2aa98e2SPeter Wemm######################################################################
1292c2aa98e2SPeter Wemm
1293c2aa98e2SPeter WemmSLookUpAddress
129406f25ae9SGregory Neil Shapirodnl lookup with tag
129506f25ae9SGregory Neil ShapiroR<$+> <$+> <$*> <$- $+>		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
129606f25ae9SGregory Neil Shapirodnl lookup without tag
129706f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $+>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
129806f25ae9SGregory Neil Shapirodnl no match; IPv6: remove last part
129906f25ae9SGregory Neil ShapiroR<?> <$+:$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
130006f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
130106f25ae9SGregory Neil ShapiroR<?> <$+.$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
130206f25ae9SGregory Neil Shapirodnl no match: return default
130306f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
130406f25ae9SGregory Neil Shapirodnl match: return result
130506f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>',
1306c2aa98e2SPeter Wemm`dnl')
1307c2aa98e2SPeter Wemm
1308c2aa98e2SPeter Wemm######################################################################
1309065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1310065a643dSPeter Wemm###			relay checking.  Route address syntax is
1311065a643dSPeter Wemm###			crudely converted into a %-hack address.
1312065a643dSPeter Wemm###
1313065a643dSPeter Wemm###	Parameters:
1314065a643dSPeter Wemm###		$1 -- full recipient address
1315065a643dSPeter Wemm###
1316065a643dSPeter Wemm###	Returns:
1317065a643dSPeter Wemm###		parsed address, not in source route form
131806f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
131906f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1320065a643dSPeter Wemm######################################################################
1321065a643dSPeter Wemm
1322065a643dSPeter WemmSCanonAddr
132306f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
132406f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1325065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1326065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1327065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
132806f25ae9SGregory Neil Shapirodnl')
1329065a643dSPeter Wemm
1330065a643dSPeter Wemm######################################################################
1331c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1332c2aa98e2SPeter Wemm###			$* $=m or the access database.
1333c2aa98e2SPeter Wemm###			Check user portion for host separators.
1334c2aa98e2SPeter Wemm###
1335c2aa98e2SPeter Wemm###	Parameters:
1336c2aa98e2SPeter Wemm###		$1 -- full recipient address
1337c2aa98e2SPeter Wemm###
1338c2aa98e2SPeter Wemm###	Returns:
1339c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1340c2aa98e2SPeter Wemm######################################################################
1341c2aa98e2SPeter Wemm
1342c2aa98e2SPeter WemmSParseRecipient
134306f25ae9SGregory Neil Shapirodnl mark and canonify address
1344065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
134506f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1346c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
134706f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1348c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1349c2aa98e2SPeter Wemm
1350c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1351c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
135206f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1353c2aa98e2SPeter WemmR<?> $*				$@ $1
1354c2aa98e2SPeter Wemm
135506f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>, where localpart contains $=O
135606f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1357c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1358c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1359c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
1360065a643dSPeter Wemm
1361065a643dSPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
136206f25ae9SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
1363065a643dSPeter WemmR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1364065a643dSPeter WemmR<MX> < : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
136506f25ae9SGregory Neil Shapirodnl yes: mark it as <RELAY>
1366065a643dSPeter WemmR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
136706f25ae9SGregory Neil Shapirodnl no: put old <NO> mark back
1368065a643dSPeter WemmR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
1369065a643dSPeter Wemm
137006f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
137106f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
1372c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1373c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
137406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
137506f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1376065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1377c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
137806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
137906f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>LookUpDomain <$2> <NO> <$1 < @ $2 >> <+To>
1380c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1381065a643dSPeter Wemm
138206f25ae9SGregory Neil Shapiro
1383c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
1384c2aa98e2SPeter WemmR<$-> $*			$@ $2
1385c2aa98e2SPeter Wemm
138606f25ae9SGregory Neil Shapiro
1387c2aa98e2SPeter Wemm######################################################################
1388c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1389c2aa98e2SPeter Wemm######################################################################
1390c2aa98e2SPeter Wemm
1391c2aa98e2SPeter WemmSLocal_check_relay
139206f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1393c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1394c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1395c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1396c2aa98e2SPeter Wemm
1397c2aa98e2SPeter WemmSBasic_check_relay
1398c2aa98e2SPeter Wemm# check for deferred delivery mode
1399c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1400c2aa98e2SPeter WemmR< d > $*		$@ deferred
1401c2aa98e2SPeter WemmR< $* > $*		$: $2
1402c2aa98e2SPeter Wemm
140306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
140406f25ae9SGregory Neil ShapiroR$+ $| $+		$: $>LookUpDomain < $1 > <?> < $2 > <+Connect>
140506f25ae9SGregory Neil ShapiroR<?> <$+>		$: $>LookUpAddress < $1 > <?> < $1 > <+Connect>	no: another lookup
140606f25ae9SGregory Neil ShapiroR<?> < $+ >		$: $1					found nothing
140706f25ae9SGregory Neil ShapiroR<$={Accept}> < $* >	$@ $1
140806f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
1409c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
141006f25ae9SGregory Neil Shapirodnl error tag
141106f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
141206f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
141306f25ae9SGregory Neil Shapirodnl generic error from access map
141406f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1', `dnl')
1415c2aa98e2SPeter Wemm
1416c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
141706f25ae9SGregory Neil Shapiro# DNS based IP address spam list
1418c2aa98e2SPeter WemmR$*			$: $&{client_addr}
141906f25ae9SGregory Neil ShapiroR::ffff:$-.$-.$-.$-	$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
142006f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
142106f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
142206f25ae9SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Mail from " $&{client_addr} " refused by blackhole site _RBL_"',
1423c2aa98e2SPeter Wemm`dnl')
142406f25ae9SGregory Neil Shapiroundivert(8)
1425c2aa98e2SPeter Wemm
1426c2aa98e2SPeter Wemm######################################################################
1427c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1428c2aa98e2SPeter Wemm######################################################################
1429c2aa98e2SPeter Wemm
1430c2aa98e2SPeter WemmSLocal_check_mail
143106f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1432c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1433c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1434c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1435c2aa98e2SPeter Wemm
1436c2aa98e2SPeter WemmSBasic_check_mail
1437c2aa98e2SPeter Wemm# check for deferred delivery mode
1438c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1439c2aa98e2SPeter WemmR< d > $*		$@ deferred
1440c2aa98e2SPeter WemmR< $* > $*		$: $2
1441c2aa98e2SPeter Wemm
144206f25ae9SGregory Neil Shapiro# authenticated?
144306f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
144406f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
144506f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
144606f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
144706f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
144806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
144906f25ae9SGregory Neil Shapiro
145006f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
145106f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
145206f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
145306f25ae9SGregory Neil Shapirodnl do some additional checks
145406f25ae9SGregory Neil Shapirodnl no user@host
145506f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
145606f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
145706f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
145806f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
145906f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
146006f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
146106f25ae9SGregory Neil ShapiroR$+			$: <?> $1
146206f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
146306f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
146406f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
146506f25ae9SGregory Neil Shapirodnl prepend daemon_flags
146606f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
146706f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
146806f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
146906f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
147006f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
147106f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
147206f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
147306f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
147406f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
147506f25ae9SGregory Neil Shapirodnl remove daemon_flags
147606f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
147706f25ae9SGregory Neil Shapiro# handle case of @localhost on address
147806f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
147906f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
148006f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
148106f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
148206f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
148306f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
148406f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
148506f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
148606f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
148706f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
148806f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
148906f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
149006f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
149106f25ae9SGregory Neil Shapirodnl	or:    <address>
149206f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
149306f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
149406f25ae9SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Real domain name required"
149506f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
149606f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
149706f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
149806f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
149906f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
150006f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1501065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1502c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
150306f25ae9SGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <OK> $1 < @ $2 $3 >
150406f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
1505c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
150606f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <OK> $1 < @ $2 >		... unresolvable OK',
150706f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
150806f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
150906f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
151006f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, OK, PERM, TEMP
151106f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1512c2aa98e2SPeter Wemm
151306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
151406f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
151506f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
151606f25ae9SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, OK, PERM, TEMP
151706f25ae9SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <H:$3>
151806f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
151906f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
152006f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
152106f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
152206f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+From> $| <$3> <>
152306f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
152406f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
152506f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1526c2aa98e2SPeter Wemm# retransform for further use
152706f25ae9SGregory Neil Shapirodnl required form:
152806f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
152906f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
153006f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
153106f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
153206f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1533c2aa98e2SPeter Wemm
1534c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1535c2aa98e2SPeter Wemm# handle case of no @domain on address
153606f25ae9SGregory Neil Shapirodnl prepend daemon_flags
153706f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
153806f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
153906f25ae9SGregory Neil ShapiroR$* u $* $| <?> $*	$: <OK> $3
154006f25ae9SGregory Neil Shapirodnl remove daemon_flags
154106f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
1542c2aa98e2SPeter WemmR<?> $*			$: < ? $&{client_name} > $1
1543c2aa98e2SPeter WemmR<?> $*			$@ <OK>				...local unqualed ok
1544c2aa98e2SPeter WemmR<? $+> $*		$#error $@ 5.5.4 $: "553 Domain name required"
1545c2aa98e2SPeter Wemm							...remote is not')
1546c2aa98e2SPeter Wemm# check results
154706f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1548c2aa98e2SPeter WemmR<OK> $*		$@ <OK>
154906f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
155006f25ae9SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "501 Domain of sender address " $&f " does not exist"
155106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
155206f25ae9SGregory Neil ShapiroR<$={Accept}> $*	$# $1
1553c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
155406f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
155506f25ae9SGregory Neil Shapirodnl error tag
155606f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
155706f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
155806f25ae9SGregory Neil Shapirodnl generic error from access map
155906f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1560c2aa98e2SPeter Wemm`dnl')
1561c2aa98e2SPeter Wemm
1562c2aa98e2SPeter Wemm######################################################################
1563c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
1564c2aa98e2SPeter Wemm######################################################################
1565c2aa98e2SPeter Wemm
1566c2aa98e2SPeter WemmSLocal_check_rcpt
156706f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
1568c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
1569c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1570c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
1571c2aa98e2SPeter Wemm
1572c2aa98e2SPeter WemmSBasic_check_rcpt
1573c2aa98e2SPeter Wemm# check for deferred delivery mode
1574c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1575c2aa98e2SPeter WemmR< d > $*		$@ deferred
1576c2aa98e2SPeter WemmR< $* > $*		$: $2
1577c2aa98e2SPeter Wemm
157806f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
157906f25ae9SGregory Neil Shapiro# require qualified recipient?
158006f25ae9SGregory Neil ShapiroR$+			$: <?> $1
158106f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
158206f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
158306f25ae9SGregory Neil Shapirodnl prepend daemon_flags
158406f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
158506f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
158606f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
158706f25ae9SGregory Neil ShapiroR$* r $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
158806f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
158906f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
159006f25ae9SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Domain name required"
159106f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
159206f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
159306f25ae9SGregory Neil Shapiro
1594c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
1595065a643dSPeter WemmR$*			$: $>CanonAddr $1
1596c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
1597c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
1598c2aa98e2SPeter Wemm
1599065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
1600065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
1601065a643dSPeter Wemm# unlimited bestmx
1602065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
1603065a643dSPeter Wemm`dnl
1604065a643dSPeter Wemm# limit bestmx to $=B
16052e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
160606f25ae9SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Basic_check_rcpt" $1 $2 $3
1607065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
1608065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
1609065a643dSPeter Wemm
1610c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
161106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1612c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
1613c2aa98e2SPeter WemmR$*			$: <?> $1
161406f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
161506f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
161606f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <H:$2>
161706f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <H:$2>
161806f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
161906f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
162006f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
162106f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+To> $| <$2> <>
162206f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
162306f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
162406f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
162506f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
162606f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
162706f25ae9SGregory Neil Shapirodnl as generic error message...
162806f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
162906f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
163006f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
163106f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
1632c2aa98e2SPeter WemmR<REJECT> $*		$#error $@ 5.2.1 $: "550 Mailbox disabled for this recipient"
163306f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
163406f25ae9SGregory Neil Shapirodnl error tag
163506f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
163606f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
163706f25ae9SGregory Neil Shapirodnl generic error from access map
163806f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
163906f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
1640c2aa98e2SPeter Wemm
164106f25ae9SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)')
164206f25ae9SGregory Neil Shapiro# authenticated?
164306f25ae9SGregory Neil Shapirodnl do this unconditionally? this requires to manage CAs carefully
164406f25ae9SGregory Neil Shapirodnl just because someone has a CERT signed by a "trusted" CA
164506f25ae9SGregory Neil Shapirodnl does not mean we want to allow relaying for her,
164606f25ae9SGregory Neil Shapirodnl either use a subroutine or provide something more sophisticated
164706f25ae9SGregory Neil Shapirodnl this could for example check the DN (maybe an access map lookup)
164806f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>RelayAuth $1 $| $&{verify}	client authenticated?
164906f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2				error/ok?
165006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1				no
165106f25ae9SGregory Neil Shapiro
165206f25ae9SGregory Neil Shapiro# authenticated by a trusted mechanism?
165306f25ae9SGregory Neil ShapiroR$*			$: $1 $| $&{auth_type}
165406f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
165506f25ae9SGregory Neil ShapiroR$* $|			$: $1
165606f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
165706f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
165806f25ae9SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAYAUTH
165906f25ae9SGregory Neil Shapirodnl undo addition of ${auth_type}
166006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
166106f25ae9SGregory Neil Shapirodnl workspace: localpart<@domain>
166206f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
166306f25ae9SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
1664c2aa98e2SPeter Wemm# anything terminating locally is ok
1665c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
166606f25ae9SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAYTO', `dnl')
166706f25ae9SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAYTO
1668c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
166906f25ae9SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAYTO
167006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
167106f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>
167206f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
167306f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
167406f25ae9SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAYTO
167506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
167606f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: $>LookUpDomain <$2> <?> <$1 < @ $2 >> <+To>',`dnl')')
167706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
167806f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
167906f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYTO
1680c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
1681c2aa98e2SPeter Wemm
168206f25ae9SGregory Neil Shapiro
1683c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
1684c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
168506f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
168606f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
1687c2aa98e2SPeter WemmR< : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
168806f25ae9SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAYTO
1689065a643dSPeter WemmR< : $* : > $*		$: $2',
1690c2aa98e2SPeter Wemm`dnl')
1691c2aa98e2SPeter Wemm
1692c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
1693c2aa98e2SPeter WemmR$*			$: <?> $1
1694065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
1695c2aa98e2SPeter Wemm# local user is ok
169606f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
169706f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
169806f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
169906f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
170006f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
170106f25ae9SGregory Neil ShapiroR<?> postmaster		$@ TOPOSTMASTER
170206f25ae9SGregory Neil Shapiro# require qualified recipient?
170306f25ae9SGregory Neil Shapirodnl prepend daemon_flags
170406f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
170506f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
170606f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
170706f25ae9SGregory Neil Shapirodnl r flag? add client_name
170806f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
170906f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
171006f25ae9SGregory Neil Shapiro# no qualified recipient required
171106f25ae9SGregory Neil ShapiroR$* $| <?> $+		$@ RELAYTOLOCAL
171206f25ae9SGregory Neil Shapirodnl client_name is empty
171306f25ae9SGregory Neil ShapiroR<?> <?> $+		$@ RELAYTOLOCAL
171406f25ae9SGregory Neil Shapirodnl client_name is local
171506f25ae9SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAYTOLOCAL
171606f25ae9SGregory Neil Shapirodnl client_name is not local
171706f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
171806f25ae9SGregory Neil Shapirodnl no qualified recipient required
171906f25ae9SGregory Neil ShapiroR<?> $+			$@ RELAYTOLOCAL')
172006f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
1721c2aa98e2SPeter WemmR<$+> $*		$: $2
172206f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
1723c2aa98e2SPeter Wemm
1724c2aa98e2SPeter Wemm# anything originating locally is ok
1725c2aa98e2SPeter Wemm# check IP address
1726c2aa98e2SPeter WemmR$*			$: $&{client_addr}
172706f25ae9SGregory Neil ShapiroR$@			$@ RELAYFROM		originated locally
172806f25ae9SGregory Neil ShapiroR0			$@ RELAYFROM		originated locally
172906f25ae9SGregory Neil ShapiroR$=R $*			$@ RELAYFROM		relayable IP address
173006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
173106f25ae9SGregory Neil ShapiroR$*			$: $>LookUpAddress <$1> <?> <$1> <+Connect>
173206f25ae9SGregory Neil ShapiroR<RELAY> $* 		$@ RELAYFROM		relayable IP address
1733c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
1734c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
173506f25ae9SGregory Neil ShapiroR$=w			$@ RELAYFROM		... and see if it is local
1736c2aa98e2SPeter Wemm
173706f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
173806f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
173906f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
174006f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
174106f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
174206f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
174306f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
1744c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
174506f25ae9SGregory Neil Shapiro# check whether local FROM is ok
174606f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w . >	$@ RELAYFROMMAIL	FROM local', `dnl')
174706f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
174806f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
174906f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 < @ $2 > $| $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', `<H:$2>') <>
175006f25ae9SGregory Neil ShapiroR$* <RELAY>		$@ RELAYFROMMAIL	RELAY FROM sender ok', `dnl
175106f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_', `errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
175206f25ae9SGregory Neil Shapiro')',
175306f25ae9SGregory Neil Shapiro`dnl')
175406f25ae9SGregory Neil Shapirodnl')', `dnl')
175506f25ae9SGregory Neil Shapiro
175606f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
175706f25ae9SGregory Neil Shapirodnl input: ignored
175806f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
175906f25ae9SGregory Neil ShapiroR<TEMP>			$#error $@ 4.7.1 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
176006f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
176106f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
176206f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
176306f25ae9SGregory Neil ShapiroR$*			$: <?> $&{client_name}
176406f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical
176506f25ae9SGregory Neil ShapiroR<?> $* $~P 		$:<?>  $[ $1 $2 $]
176606f25ae9SGregory Neil ShapiroR$* .			$1			strip trailing dots
176706f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
176806f25ae9SGregory Neil ShapiroR<?>			$@ RELAYFROM
176906f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
177006f25ae9SGregory Neil ShapiroR<?> $* $=m		$@ RELAYFROM', `dnl')
177106f25ae9SGregory Neil ShapiroR<?> $=w		$@ RELAYFROM
177206f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
177306f25ae9SGregory Neil Shapiro`R<?> $=R		$@ RELAYFROM
177406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
177506f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
177606f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
177706f25ae9SGregory Neil Shapiro`R<?> $* $=R			$@ RELAYFROM
177806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
177906f25ae9SGregory Neil ShapiroR<?> $*			$: $>LookUpDomain <$1> <?> <$1> <+Connect>',`dnl')')
178006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
178106f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYFROM
178206f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
1783c2aa98e2SPeter Wemm
1784c2aa98e2SPeter Wemm# anything else is bogus
178506f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
178606f25ae9SGregory Neil Shapirodivert(0)
178706f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
178806f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
178906f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
179006f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
179106f25ae9SGregory Neil ShapiroSFullAddr
179206f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
179306f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
179406f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
1795c2aa98e2SPeter Wemm
179606f25ae9SGregory Neil Shapiro# call all necessary rulesets
179706f25ae9SGregory Neil ShapiroScheck_rcpt
179806f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
179906f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
180006f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
180106f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
180206f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
180306f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
180406f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
180506f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
180606f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
180706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
180806f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
180906f25ae9SGregory Neil Shapiro')')dnl
181006f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
181106f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
181206f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
181306f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <U: $1@>
181406f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 >
181506f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
181606f25ae9SGregory Neil Shapiro# lookup the addresses only with To tag
181706f25ae9SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <!To> $| <$2> <>
181806f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
181906f25ae9SGregory Neil Shapirodnl', `dnl')
182006f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
182106f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
182206f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
182306f25ae9SGregory Neil Shapiro	`errprint(`*** ERROR: define either SpamHater or SpamFriend
182406f25ae9SGregory Neil Shapiro')', `dnl')
182506f25ae9SGregory Neil ShapiroR<SPAMFRIEND> $+	$@ SPAMFRIEND
182606f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
182706f25ae9SGregory Neil Shapiro`dnl')
182806f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
182906f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
183006f25ae9SGregory Neil ShapiroR<SPAMHATER> $+		$: $1			spam hater: continue checks
183106f25ae9SGregory Neil ShapiroR<$*> $+		$@ NOSPAMHATER		everyone else: stop
183206f25ae9SGregory Neil Shapirodnl',`dnl')
183306f25ae9SGregory Neil Shapirodnl run further checks: check_mail
183406f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
183506f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkmail <$&f>
183606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
183706f25ae9SGregory Neil Shapirodnl run further checks: check_relay
183806f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
183906f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
184006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
184106f25ae9SGregory Neil Shapiro', `dnl')
184206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
184306f25ae9SGregory Neil Shapiro######################################################################
184406f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
184506f25ae9SGregory Neil Shapiro###	Parameters:
184606f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
184706f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
184806f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
184906f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
185006f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
185106f25ae9SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: H: if there
185206f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
185306f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
185406f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
185506f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
185606f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
185706f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
185806f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
185906f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
186006f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
186106f25ae9SGregory Neil Shapiro###		H: recursive host lookup (LookUpDomain)
186206f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
186306f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
186406f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
186506f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
186606f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
186706f25ae9SGregory Neil Shapiro######################################################################
186806f25ae9SGregory Neil Shapiro
186906f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
187006f25ae9SGregory Neil Shapirodnl if A is activated: add it
187106f25ae9SGregory Neil ShapiroC{src}E F H U
187206f25ae9SGregory Neil ShapiroSSearchList
187306f25ae9SGregory Neil Shapiro# mark H: lookup domain
187406f25ae9SGregory Neil ShapiroR<$+> $| <H:$+> <$*>		$: <$1> $| <@> $>LookUpDomain <$2> <?> <$3> <$1>
187506f25ae9SGregory Neil ShapiroR<$+> $| <@> <$+> <$*>		$: <$1> $| <$2> <$3>
187606f25ae9SGregory Neil Shapirodnl A: NOT YET REQUIRED
187706f25ae9SGregory Neil Shapirodnl R<$+> $| <A:$+> <$*>	$: <$1> $| <@> $>LookUpAddress <$2> <?> <$3> <$1>
187806f25ae9SGregory Neil Shapirodnl R<$+> $| <@> <$+> <$*>	$: <$1> $| <$2> <$3>
187906f25ae9SGregory Neil Shapirodnl lookup of the item with tag
188006f25ae9SGregory Neil Shapirodnl this applies to F: U: E:
188106f25ae9SGregory Neil ShapiroR<$- $-> $| <$={src}:$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$4 $: $3:$4 $)> <$5>
188206f25ae9SGregory Neil Shapirodnl no match, try without tag
188306f25ae9SGregory Neil ShapiroR<+ $-> $| <$={src}:$+> <$*>	$: <+ $1> $| <$(access $3 $: $2:$3 $)> <$4>
188406f25ae9SGregory Neil Shapirodnl do we really have to distinguish these cases?
188506f25ae9SGregory Neil Shapirodnl probably yes, there might be a + in the domain part (is that allowed?)
188606f25ae9SGregory Neil Shapirodnl user+detail lookups: should it be:
188706f25ae9SGregory Neil Shapirodnl user+detail, user+*, user; just like aliases?
188806f25ae9SGregory Neil ShapiroR<$- $-> $| <F:$* + $*@$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@$5 $: F:$3 + $4@$5$)> <$6>
188906f25ae9SGregory Neil ShapiroR<+ $-> $| <F:$* + $*@$+> <$*>	$: <+ $1> $| <$(access $2@$4 $: F:$2 + $3@$4$)> <$5>
189006f25ae9SGregory Neil Shapirodnl user lookups are always with trailing @
189106f25ae9SGregory Neil Shapirodnl do not remove the @ from the lookup:
189206f25ae9SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
189306f25ae9SGregory Neil ShapiroR<$- $-> $| <U:$* + $*> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@ $: U:$3 + $4$)> <$5>
189406f25ae9SGregory Neil Shapirodnl no match, try without tag
189506f25ae9SGregory Neil ShapiroR<+ $-> $| <U:$* + $*> <$*>	$: <+ $1> $| <$(access $2@ $: U:$2 + $3$)> <$4>
189606f25ae9SGregory Neil Shapirodnl no match, try rest of list
189706f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <$+>	$@ $>SearchList <$1> $| <$4>
189806f25ae9SGregory Neil Shapirodnl no match, list empty: return failure
189906f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <>	$@ <?>
190006f25ae9SGregory Neil Shapirodnl got result, return it
190106f25ae9SGregory Neil ShapiroR<$+> $| <$+> <$*>		$@ <$2>
190206f25ae9SGregory Neil Shapirodnl return result from recursive invocation
190306f25ae9SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>', `dnl')
190406f25ae9SGregory Neil Shapiro
190506f25ae9SGregory Neil Shapiro# is user trusted to authenticate as someone else?
190606f25ae9SGregory Neil Shapirodnl AUTH= parameter from MAIL command
190706f25ae9SGregory Neil ShapiroStrust_auth
190806f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
190906f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
191006f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
191106f25ae9SGregory Neil Shapirodnl seems to be useful...
191206f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
191306f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
191406f25ae9SGregory Neil Shapirodnl call user supplied code
191506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $1
191606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
191706f25ae9SGregory Neil Shapirodnl default: error
191806f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
191906f25ae9SGregory Neil Shapiro
192006f25ae9SGregory Neil Shapirodnl empty ruleset definition so it can be called
192106f25ae9SGregory Neil ShapiroSLocal_trust_auth
192206f25ae9SGregory Neil Shapiro
192306f25ae9SGregory Neil Shapiroifdef(`_FFR_TLS_O_T', `dnl
192406f25ae9SGregory Neil ShapiroSoffer_tls
192506f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{client_name}> <?> <> <! TLS_OFF_TAG>
192606f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_OFF_TAG>
192706f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_OFF_TAG: $: ? $)>
192806f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
192906f25ae9SGregory Neil ShapiroR<NO> <>	$#error $@ 5.7.1 $: "550 do not offer TLS for " $&{client_name} " ["$&{client_addr}"]"
193006f25ae9SGregory Neil Shapiro
193106f25ae9SGregory Neil ShapiroStry_tls
193206f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{server_name}> <?> <> <! TLS_TRY_TAG>
193306f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_TRY_TAG>
193406f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG: $: ? $)>
193506f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
193606f25ae9SGregory Neil ShapiroR<NO> <>	$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"
193706f25ae9SGregory Neil Shapiro')dnl
193806f25ae9SGregory Neil Shapiro
193906f25ae9SGregory Neil Shapiro# is connection with client "good" enough? (done in server)
194006f25ae9SGregory Neil Shapiro# input: ${verify} $| (MAIL|STARTTLS)
194106f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
194206f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
194306f25ae9SGregory Neil ShapiroStls_client
194406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
194506f25ae9SGregory Neil Shapirodnl ignore second arg for now
194606f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
194706f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
194806f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
194906f25ae9SGregory Neil ShapiroR$* $| $*	$: $1 $| $>LookUpDomain <$&{client_name}> <?> <> <! TLS_CLT_TAG>
195006f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_CLT_TAG>
195106f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
195206f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
195306f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
195406f25ae9SGregory Neil ShapiroR$* $| $*	$@ $>"tls_connection" $1')
195506f25ae9SGregory Neil Shapiro
195606f25ae9SGregory Neil Shapiro# is connection with server "good" enough? (done in client)
195706f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
195806f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
195906f25ae9SGregory Neil Shapiro# input: ${verify}
196006f25ae9SGregory Neil ShapiroStls_server
196106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
196206f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>LookUpDomain <$&{server_name}> <?> <> <! TLS_SRV_TAG>
196306f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_SRV_TAG>
196406f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
196506f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
196606f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
196706f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1')
196806f25ae9SGregory Neil Shapiro
196906f25ae9SGregory Neil ShapiroStls_connection
197006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
197106f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
197206f25ae9SGregory Neil Shapirodnl input: $&{verify} $| <ResultOfLookup> [<>]
197306f25ae9SGregory Neil Shapirodnl remove optional <>
197406f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
197506f25ae9SGregory Neil Shapirodnl permanent or temporary error?
197606f25ae9SGregory Neil ShapiroR$* $| <PERM + $={tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
197706f25ae9SGregory Neil ShapiroR$* $| <TEMP + $={tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
197806f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
197906f25ae9SGregory Neil ShapiroR$* $| <$={tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
198006f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
198106f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
198206f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
198306f25ae9SGregory Neil Shapirodnl use default error
198406f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
198506f25ae9SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> $1
198606f25ae9SGregory Neil ShapiroR$* $| <$*> <$={tls}:$->$*	$: <$2> <$3:$4> $1
198706f25ae9SGregory Neil Shapirodnl some other value in access map: accept
198806f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
198906f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
199006f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
199106f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
199206f25ae9SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> ${verify}
199306f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
199406f25ae9SGregory Neil ShapiroR<$*><VERIFY> OK		$@ OK
199506f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
199606f25ae9SGregory Neil ShapiroR<$*><VERIFY:$-> OK		$: <$1> <REQ:$2>
199706f25ae9SGregory Neil Shapirodnl just some level of encryption required
199806f25ae9SGregory Neil ShapiroR<$*><ENCR:$-> $*		$: <$1> <REQ:$2>
199906f25ae9SGregory Neil Shapirodnl verification required but ${verify} is not set
200006f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*>		$#error $@ $2 $: $1 " authentication required"
200106f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> FAIL	$#error $@ $2 $: $1 " authentication failed"
200206f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NO		$#error $@ $2 $: $1 " not authenticated"
200306f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
200406f25ae9SGregory Neil Shapirodnl some other value for ${verify}
200506f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> $+		$#error $@ $2 $: $1 " authentication failure " $4
200606f25ae9SGregory Neil Shapirodnl some level of encryption required: get the maximum level
200706f25ae9SGregory Neil ShapiroR<$*><REQ:$->			$: <$1> <REQ:$2> $>max $&{cipher_bits} : $&{auth_ssf}
200806f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
200906f25ae9SGregory Neil ShapiroR<$*><REQ:$-> $-		$: <$1> <$2:$3> $(arith l $@ $3 $@ $2 $)
201006f25ae9SGregory Neil ShapiroR<$-:$+><$-:$-> TRUE		$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
201106f25ae9SGregory Neil Shapiro
201206f25ae9SGregory Neil ShapiroSmax
201306f25ae9SGregory Neil Shapirodnl compute the max of two values separated by :
201406f25ae9SGregory Neil ShapiroR:		$: 0
201506f25ae9SGregory Neil ShapiroR:$-		$: $1
201606f25ae9SGregory Neil ShapiroR$-:		$: $1
201706f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
201806f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
201906f25ae9SGregory Neil ShapiroR$-:$-:$-	$: $2',
202006f25ae9SGregory Neil Shapiro`dnl use default error
202106f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
202206f25ae9SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."')
202306f25ae9SGregory Neil Shapiro
202406f25ae9SGregory Neil ShapiroSRelayAuth
202506f25ae9SGregory Neil Shapiro# authenticated?
202606f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
202706f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
202806f25ae9SGregory Neil Shapirodnl CA in CERTPath so we can authenticate users, we do not allow
202906f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
203006f25ae9SGregory Neil Shapirodnl but anyway).
203106f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
203206f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
203306f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
203406f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
203506f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
203606f25ae9SGregory Neil Shapirodnl cert subject.
203706f25ae9SGregory Neil ShapiroR$* $| OK		$: $1
203806f25ae9SGregory Neil ShapiroR$* $| $*		$@ NO		not authenticated
203906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
204006f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
204106f25ae9SGregory Neil ShapiroR$*			$: $1 $| $(CERTIssuer $&{cert_issuer} $)',
204206f25ae9SGregory Neil Shapiro`R$*			$: $1 $| $&{cert_issuer}')
204306f25ae9SGregory Neil ShapiroR$* $| $+		$: $1 $| $(access CERTISSUER:$2 $)
204406f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
204506f25ae9SGregory Neil ShapiroR$* $| RELAY		$# RELAYCERTISSUER
204606f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
204706f25ae9SGregory Neil ShapiroR$* $| SUBJECT		$: $1 $| <@> $(CERTSubject $&{cert_subject} $)',
204806f25ae9SGregory Neil Shapiro`R$* $| SUBJECT		$: $1 $| <@> $&{cert_subject}')
204906f25ae9SGregory Neil ShapiroR$* $| <@> $+		$: $1 $| <@> $(access CERTSUBJECT:$&{cert_subject} $)
205006f25ae9SGregory Neil ShapiroR$* $| <@> RELAY	$# RELAYCERTSUBJECT
205106f25ae9SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
205206f25ae9SGregory Neil Shapiro
205306f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
205406f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
205506f25ae9SGregory Neil Shapiro#
205606f25ae9SGregory Neil Shapiro######################################################################
205706f25ae9SGregory Neil Shapiro######################################################################
205806f25ae9SGregory Neil Shapiro#####
205906f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
206006f25ae9SGregory Neil Shapiro#####
206106f25ae9SGregory Neil Shapiro######################################################################
206206f25ae9SGregory Neil Shapiro######################################################################
206306f25ae9SGregory Neil Shapiro_MAIL_FILTERS_')
2064c2aa98e2SPeter Wemm#
2065c2aa98e2SPeter Wemm######################################################################
2066c2aa98e2SPeter Wemm######################################################################
2067c2aa98e2SPeter Wemm#####
2068c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
2069c2aa98e2SPeter Wemm#####
2070c2aa98e2SPeter Wemm######################################################################
2071c2aa98e2SPeter Wemm######################################################################
207206f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
2073