xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 42e5d165)
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
1642e5d165SGregory Neil ShapiroVERSIONID(`$Id: proto.m4,v 8.446.2.5.2.29 2000/09/15 04:45:14 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
16342e5d165SGregory Neil Shapiroifdef(`_FFR_5_', `# macro storage map
16442e5d165SGregory Neil ShapiroKmacro macro')
16542e5d165SGregory Neil Shapiro
166c2aa98e2SPeter Wemmifdef(`confCR_FILE', `dnl
16742e5d165SGregory Neil Shapiro# Hosts for which relaying is permitted ($=R)
168c2aa98e2SPeter WemmFR`'confCR_FILE',
169c2aa98e2SPeter Wemm`dnl')
170c2aa98e2SPeter Wemm
17106f25ae9SGregory Neil Shapirodefine(`TLS_SRV_TAG', `TLS_Srv')dnl
17206f25ae9SGregory Neil Shapirodefine(`TLS_CLT_TAG', `TLS_Clt')dnl
17306f25ae9SGregory Neil Shapirodefine(`TLS_TRY_TAG', `Try_TLS')dnl
17406f25ae9SGregory Neil Shapirodefine(`TLS_OFF_TAG', `Offer_TLS')dnl
17506f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
17606f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
17706f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
17806f25ae9SGregory Neil ShapiroKarith arith')
17906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
18006f25ae9SGregory Neil Shapiro# possible values for tls_connect in access map
18106f25ae9SGregory Neil ShapiroC{tls}VERIFY ENCR', `dnl')
18206f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
18306f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
18406f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
18506f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
18606f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
18706f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
18806f25ae9SGregory Neil Shapiro
189c2aa98e2SPeter Wemm# who I send unqualified names to (null means deliver locally)
190c2aa98e2SPeter WemmDR`'ifdef(`LOCAL_RELAY', LOCAL_RELAY)
191c2aa98e2SPeter Wemm
192c2aa98e2SPeter Wemm# who gets all local email traffic ($R has precedence for unqualified names)
193c2aa98e2SPeter WemmDH`'ifdef(`MAIL_HUB', MAIL_HUB)
194c2aa98e2SPeter Wemm
195c2aa98e2SPeter Wemm# dequoting map
196c2aa98e2SPeter WemmKdequote dequote
197c2aa98e2SPeter Wemm
198c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
199c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
20006f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
201c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
20206f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
203c2aa98e2SPeter Wemm#CL root
204c2aa98e2SPeter Wemmundivert(5)dnl
20506f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
206c2aa98e2SPeter Wemm
207c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
208c2aa98e2SPeter WemmDM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME)
209c2aa98e2SPeter Wemm
210c2aa98e2SPeter Wemm# my name for error messages
211c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
212c2aa98e2SPeter Wemm
21306f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
214c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
215c2aa98e2SPeter Wemm
216c2aa98e2SPeter Wemm###############
217c2aa98e2SPeter Wemm#   Options   #
218c2aa98e2SPeter Wemm###############
219c2aa98e2SPeter Wemm
220c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
22106f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
222c2aa98e2SPeter Wemm
223c2aa98e2SPeter Wemm# 8-bit data handling
22406f25ae9SGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `adaptive')
225c2aa98e2SPeter Wemm
226c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
22706f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
228c2aa98e2SPeter Wemm
229c2aa98e2SPeter Wemm# location of alias file
23006f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
23106f25ae9SGregory Neil Shapiro
232c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
23306f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
234c2aa98e2SPeter Wemm
235c2aa98e2SPeter Wemm# maximum message size
23606f25ae9SGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `1000000')
237c2aa98e2SPeter Wemm
238c2aa98e2SPeter Wemm# substitution for space (blank) characters
23906f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
240c2aa98e2SPeter Wemm
241c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
24206f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
243c2aa98e2SPeter Wemm
244c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
24506f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
246c2aa98e2SPeter Wemm
247c2aa98e2SPeter Wemm# default delivery mode
24806f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
249c2aa98e2SPeter Wemm
250c2aa98e2SPeter Wemm# automatically rebuild the alias database?
25106f25ae9SGregory Neil Shapiro# NOTE: There is a potential for a denial of service attack if this is set.
25206f25ae9SGregory Neil Shapiro#       This option is deprecated and will be removed from a future version.
25306f25ae9SGregory Neil Shapiro_OPTION(AutoRebuildAliases, `confAUTO_REBUILD', `False')
254c2aa98e2SPeter Wemm
255c2aa98e2SPeter Wemm# error message header/file
25606f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
257c2aa98e2SPeter Wemm
258c2aa98e2SPeter Wemm# error mode
25906f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
260c2aa98e2SPeter Wemm
261c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
26206f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
263c2aa98e2SPeter Wemm
264c2aa98e2SPeter Wemm# temporary file mode
26506f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
266c2aa98e2SPeter Wemm
267c2aa98e2SPeter Wemm# match recipients against GECOS field?
26806f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
269c2aa98e2SPeter Wemm
270c2aa98e2SPeter Wemm# maximum hop count
27106f25ae9SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `17')
272c2aa98e2SPeter Wemm
273c2aa98e2SPeter Wemm# location of help file
27406f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
275c2aa98e2SPeter Wemm
276c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
27706f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
278c2aa98e2SPeter Wemm
279c2aa98e2SPeter Wemm# name resolver options
28006f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
281c2aa98e2SPeter Wemm
282c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
28306f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
284c2aa98e2SPeter Wemm
285c2aa98e2SPeter Wemm# Forward file search path
28606f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
287c2aa98e2SPeter Wemm
288c2aa98e2SPeter Wemm# open connection cache size
28906f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
290c2aa98e2SPeter Wemm
291c2aa98e2SPeter Wemm# open connection cache timeout
29206f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
293c2aa98e2SPeter Wemm
294c2aa98e2SPeter Wemm# persistent host status directory
29506f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
296c2aa98e2SPeter Wemm
297c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
29806f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
299c2aa98e2SPeter Wemm
300c2aa98e2SPeter Wemm# use Errors-To: header?
30106f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
302c2aa98e2SPeter Wemm
303c2aa98e2SPeter Wemm# log level
30406f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
305c2aa98e2SPeter Wemm
306c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
30706f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
308c2aa98e2SPeter Wemm
309c2aa98e2SPeter Wemm# verify RHS in newaliases?
31006f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
311c2aa98e2SPeter Wemm
312c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
31306f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
314c2aa98e2SPeter Wemm
315c2aa98e2SPeter Wemm# SMTP daemon options
31606f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
31706f25ae9SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.  See cf/README for more information.
31806f25ae9SGregory Neil Shapiro)'dnl
31906f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
32042e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
32142e5d165SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-IPv4, Family=inet
32242e5d165SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-IPv6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
32306f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
32406f25ae9SGregory Neil Shapiro
32506f25ae9SGregory Neil Shapiro# SMTP client options
32606f25ae9SGregory Neil Shapiro_OPTION(ClientPortOptions, `confCLIENT_OPTIONS', `Address=0.0.0.0')
327c2aa98e2SPeter Wemm
328c2aa98e2SPeter Wemm# privacy flags
32906f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
330c2aa98e2SPeter Wemm
331c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
33206f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
333c2aa98e2SPeter Wemm
334c2aa98e2SPeter Wemm# slope of queue-only function
33506f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
336c2aa98e2SPeter Wemm
337c2aa98e2SPeter Wemm# queue directory
33806f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
339c2aa98e2SPeter Wemm
340c2aa98e2SPeter Wemm# timeouts (many of these)
34106f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
34206f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
34306f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
34406f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
34506f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
34606f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
34706f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
34806f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
34906f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
35006f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
35106f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
35206f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
35306f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
35406f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
35506f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
35606f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
35706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
35806f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
35906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
36006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
36106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
36206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
36306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
36406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
36506f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
36606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
36706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
36806f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
36906f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
37006f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
37106f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
372c2aa98e2SPeter Wemm
373c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
37406f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
375c2aa98e2SPeter Wemm
376c2aa98e2SPeter Wemm# queue up everything before forking?
37706f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
378c2aa98e2SPeter Wemm
379c2aa98e2SPeter Wemm# status file
38006f25ae9SGregory Neil ShapiroO StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', `MAIL_SETTINGS_DIR`'statistics')
381c2aa98e2SPeter Wemm
382c2aa98e2SPeter Wemm# time zone handling:
383c2aa98e2SPeter Wemm#  if undefined, use system default
384c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
385c2aa98e2SPeter Wemm#  if defined and non-null, use that info
386c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
387c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
388c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
389c2aa98e2SPeter Wemm
390c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
39106f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
392c2aa98e2SPeter Wemm
393c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
39406f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
395c2aa98e2SPeter Wemm
396c2aa98e2SPeter Wemm# fallback MX host
39706f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
398c2aa98e2SPeter Wemm
399c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
40006f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
401c2aa98e2SPeter Wemm
402c2aa98e2SPeter Wemm# load average at which we just queue messages
40306f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
404c2aa98e2SPeter Wemm
405c2aa98e2SPeter Wemm# load average at which we refuse connections
40606f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
407c2aa98e2SPeter Wemm
408c2aa98e2SPeter Wemm# maximum number of children we allow at one time
40906f25ae9SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `12')
410c2aa98e2SPeter Wemm
411c2aa98e2SPeter Wemm# maximum number of new connections per second
41206f25ae9SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `3')
413c2aa98e2SPeter Wemm
414c2aa98e2SPeter Wemm# work recipient factor
41506f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
416c2aa98e2SPeter Wemm
417c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
41806f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
419c2aa98e2SPeter Wemm
420c2aa98e2SPeter Wemm# work class factor
42106f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
422c2aa98e2SPeter Wemm
423c2aa98e2SPeter Wemm# work time factor
42406f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
425c2aa98e2SPeter Wemm
426c2aa98e2SPeter Wemm# shall we sort the queue by hostname first?
42706f25ae9SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
428c2aa98e2SPeter Wemm
429c2aa98e2SPeter Wemm# minimum time in queue before retry
43006f25ae9SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
431c2aa98e2SPeter Wemm
432c2aa98e2SPeter Wemm# default character set
43306f25ae9SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `iso-8859-1')
434c2aa98e2SPeter Wemm
435c2aa98e2SPeter Wemm# service switch file (ignored on Solaris, Ultrix, OSF/1, others)
43606f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
437c2aa98e2SPeter Wemm
438c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
43906f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
440c2aa98e2SPeter Wemm
441c2aa98e2SPeter Wemm# dialup line delay on connection failure
44206f25ae9SGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `10s')
443c2aa98e2SPeter Wemm
444c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
44506f25ae9SGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `add-to-undisclosed')
446c2aa98e2SPeter Wemm
447c2aa98e2SPeter Wemm# chrooted environment for writing to files
44806f25ae9SGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `/arch')
449c2aa98e2SPeter Wemm
450c2aa98e2SPeter Wemm# are colons OK in addresses?
45106f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
452c2aa98e2SPeter Wemm
453c2aa98e2SPeter Wemm# how many jobs can you process in the queue?
45406f25ae9SGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `10000')
455c2aa98e2SPeter Wemm
456c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
45706f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
458c2aa98e2SPeter Wemm
459c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
46006f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
461c2aa98e2SPeter Wemm
462c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
46306f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
464c2aa98e2SPeter Wemm
465c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
46606f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
467c2aa98e2SPeter Wemm
468c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
46906f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
470c2aa98e2SPeter Wemm
471c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
47206f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
473c2aa98e2SPeter Wemm
474c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
47506f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
476c2aa98e2SPeter Wemm
477c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
47806f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
479c2aa98e2SPeter Wemm
480c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
48106f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
482c2aa98e2SPeter Wemm
483c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
48406f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
48506f25ae9SGregory Neil Shapiro
48606f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
48706f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
488c2aa98e2SPeter Wemm
489c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
49006f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
491c2aa98e2SPeter Wemm
492c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
49306f25ae9SGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `100')
494c2aa98e2SPeter Wemm
495c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
49606f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
497c2aa98e2SPeter Wemm
49806f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
49906f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
50006f25ae9SGregory Neil Shapiro
50106f25ae9SGregory Neil Shapiro# override connection address (for testing)
50206f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
50306f25ae9SGregory Neil Shapiro
50406f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
50506f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
50606f25ae9SGregory Neil Shapiro
50706f25ae9SGregory Neil Shapiro# Control socket for daemon management
50806f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
50906f25ae9SGregory Neil Shapiro
51006f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
51106f25ae9SGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
51206f25ae9SGregory Neil Shapiro
51306f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
51406f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
51506f25ae9SGregory Neil Shapiro
51606f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
51706f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
51806f25ae9SGregory Neil Shapiro
51906f25ae9SGregory Neil Shapiro# location of pid file
52006f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
52106f25ae9SGregory Neil Shapiro
52206f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
52306f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
52406f25ae9SGregory Neil Shapiro
52506f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
52606f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
52706f25ae9SGregory Neil Shapiro
52806f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
52906f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
53006f25ae9SGregory Neil Shapiro
53106f25ae9SGregory Neil Shapiro# list of authentication mechanisms
53206f25ae9SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
53306f25ae9SGregory Neil Shapiro
53406f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
53506f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
53606f25ae9SGregory Neil Shapiro
53706f25ae9SGregory Neil Shapiro# SMTP AUTH flags
53806f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
53906f25ae9SGregory Neil Shapiro
54006f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
54106f25ae9SGregory Neil Shapiro# Input mail filters
54206f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
54306f25ae9SGregory Neil Shapiro
54406f25ae9SGregory Neil Shapiro# Milter options
54506f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
54606f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
54706f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
54806f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')')
54906f25ae9SGregory Neil Shapiro
55006f25ae9SGregory Neil Shapiro# CA directory
55106f25ae9SGregory Neil Shapiro_OPTION(CACERTPath, `confCACERT_PATH', `')
55206f25ae9SGregory Neil Shapiro# CA file
55306f25ae9SGregory Neil Shapiro_OPTION(CACERTFile, `confCACERT', `')
55406f25ae9SGregory Neil Shapiro# Server Cert
55506f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
55606f25ae9SGregory Neil Shapiro# Server private key
55706f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
55806f25ae9SGregory Neil Shapiro# Client Cert
55906f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
56006f25ae9SGregory Neil Shapiro# Client private key
56106f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
56206f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
56306f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
56406f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
56506f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
56606f25ae9SGregory Neil Shapiro
56706f25ae9SGregory Neil Shapiroifdef(`confQUEUE_FILE_MODE',
56806f25ae9SGregory Neil Shapiro`# queue file mode (qf files)
56906f25ae9SGregory Neil ShapiroO QueueFileMode=confQUEUE_FILE_MODE
57025bab6e9SPeter Wemm')
571065a643dSPeter Wemm
572c2aa98e2SPeter Wemm###########################
573c2aa98e2SPeter Wemm#   Message precedences   #
574c2aa98e2SPeter Wemm###########################
575c2aa98e2SPeter Wemm
576c2aa98e2SPeter WemmPfirst-class=0
577c2aa98e2SPeter WemmPspecial-delivery=100
578c2aa98e2SPeter WemmPlist=-30
579c2aa98e2SPeter WemmPbulk=-60
580c2aa98e2SPeter WemmPjunk=-100
581c2aa98e2SPeter Wemm
582c2aa98e2SPeter Wemm#####################
583c2aa98e2SPeter Wemm#   Trusted users   #
584c2aa98e2SPeter Wemm#####################
585c2aa98e2SPeter Wemm
586c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
58706f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
588c2aa98e2SPeter WemmTroot
589c2aa98e2SPeter WemmTdaemon
590c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
591c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
592c2aa98e2SPeter Wemm
593c2aa98e2SPeter Wemm#########################
594c2aa98e2SPeter Wemm#   Format of headers   #
595c2aa98e2SPeter Wemm#########################
596c2aa98e2SPeter Wemm
597c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
598c2aa98e2SPeter WemmH?P?Return-Path: <$g>
599c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
600c2aa98e2SPeter WemmH?D?Resent-Date: $a
601c2aa98e2SPeter WemmH?D?Date: $a
602c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
603c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
604c2aa98e2SPeter WemmH?x?Full-Name: $x
605c2aa98e2SPeter Wemm# HPosted-Date: $a
606c2aa98e2SPeter Wemm# H?l?Received-Date: $b
607c2aa98e2SPeter WemmH?M?Resent-Message-Id: <$t.$i@$j>
608c2aa98e2SPeter WemmH?M?Message-Id: <$t.$i@$j>
60906f25ae9SGregory Neil Shapiro
610c2aa98e2SPeter Wemm#
611c2aa98e2SPeter Wemm######################################################################
612c2aa98e2SPeter Wemm######################################################################
613c2aa98e2SPeter Wemm#####
614c2aa98e2SPeter Wemm#####			REWRITING RULES
615c2aa98e2SPeter Wemm#####
616c2aa98e2SPeter Wemm######################################################################
617c2aa98e2SPeter Wemm######################################################################
618c2aa98e2SPeter Wemm
619c2aa98e2SPeter Wemm############################################
620c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
621c2aa98e2SPeter Wemm############################################
62206f25ae9SGregory Neil ShapiroScanonify=3
623c2aa98e2SPeter Wemm
624c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
625c2aa98e2SPeter WemmR$@			$@ <@>
626c2aa98e2SPeter Wemm
627c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
628c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
629c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
630c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
631c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
632c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
63306f25ae9SGregory Neil ShapiroR$* [ IPv6 $- ] <@>	$: $1 [ IPv6 $2 ]		unmark IPv6 addr
634c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
635c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
636c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
637c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
638c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
639c2aa98e2SPeter Wemm
640c2aa98e2SPeter Wemm# null input now results from list:; syntax
641c2aa98e2SPeter WemmR$@			$@ :; <@>
642c2aa98e2SPeter Wemm
643c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
644c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
645c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
646c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
647c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
648c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
649c2aa98e2SPeter Wemm
65006f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
651c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
652c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
653c2aa98e2SPeter Wemm
654c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
65506f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
65606f25ae9SGregory Neil Shapirodnl',`dnl
65706f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
65806f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
65906f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
66006f25ae9SGregory Neil Shapirodnl')
661c2aa98e2SPeter Wemm
662c2aa98e2SPeter Wemm# find focus for list syntax
66306f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
664c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
665c2aa98e2SPeter Wemm
666c2aa98e2SPeter Wemm# find focus for @ syntax addresses
667c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
668c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
66906f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
670c2aa98e2SPeter Wemm
671c2aa98e2SPeter Wemm# do some sanity checking
672c2aa98e2SPeter WemmR$* < @ $* : $* > $*	$1 < @ $2 $3 > $4		nix colons in addrs
673c2aa98e2SPeter Wemm
674c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
675c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
67606f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
67706f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
67806f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
679c2aa98e2SPeter Wemm')
680c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
681c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
68206f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
68306f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
684c2aa98e2SPeter Wemm',
685c2aa98e2SPeter Wemm	`dnl')
686c2aa98e2SPeter Wemm# if we have % signs, take the rightmost one
687c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
688c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
68906f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
690c2aa98e2SPeter Wemm
691c2aa98e2SPeter Wemm# else we must be a local name
69206f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
693c2aa98e2SPeter Wemm
694c2aa98e2SPeter Wemm
695c2aa98e2SPeter Wemm################################################
696c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
697c2aa98e2SPeter Wemm################################################
698c2aa98e2SPeter Wemm
69906f25ae9SGregory Neil ShapiroSCanonify2=96
700c2aa98e2SPeter Wemm
701c2aa98e2SPeter Wemm# handle special cases for local names
702c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
703c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
704c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
705c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
70606f25ae9SGregory Neil Shapiro
70706f25ae9SGregory Neil Shapiro# check for IPv6 domain literal (save quoted form)
70806f25ae9SGregory Neil ShapiroR$* < @ [ IPv6 $- ] > $*	$: $2 $| $1 < @@ [ $(dequote $2 $) ] > $3	mark IPv6 addr
70906f25ae9SGregory Neil ShapiroR$- $| $* < @@ $=w > $*		$: $2 < @ $j . > $4		self-literal
71006f25ae9SGregory Neil ShapiroR$- $| $* < @@ [ $+ ] > $*	$@ $2 < @ [ IPv6 $1 ] > $4	canon IP addr
71106f25ae9SGregory Neil Shapiro
71206f25ae9SGregory Neil Shapiro# check for IPv4 domain literal
713c2aa98e2SPeter WemmR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [a.b.c.d]
714c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
715c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
716c2aa98e2SPeter Wemm
71706f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
718c2aa98e2SPeter Wemm# look up domains in the domain table
719c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
720c2aa98e2SPeter Wemm
72106f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
722c2aa98e2SPeter Wemm
72306f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
724c2aa98e2SPeter Wemm# handle BITNET mapping
725c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
726c2aa98e2SPeter Wemm
72706f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
728c2aa98e2SPeter Wemm# handle UUCP mapping
729c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
730c2aa98e2SPeter Wemm
731c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
732c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
733c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
734c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
735c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
736c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
737c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
738c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
739c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
740c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
741c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
742c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
743c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
744c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
745c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
746c2aa98e2SPeter Wemm
747c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
748c2aa98e2SPeter Wemm# try UUCP traffic as a local address
749c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
750c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
751c2aa98e2SPeter Wemm')')
75206f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
75306f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
75406f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
75506f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
75606f25ae9SGregory Neil Shapirodnl which daemon flags are set?
75706f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
75806f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
75906f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
76006f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
76106f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
76206f25ae9SGregory Neil Shapirodnl do not canonify unless:
76306f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
76406f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
76506f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
76606f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
76706f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
76806f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
76906f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
77006f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
77106f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
77206f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
77306f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
77406f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
77506f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
77606f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
77706f25ae9SGregory Neil Shapirodnl then $- does not work.
77806f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
77906f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*	$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
78006f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
78106f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
78206f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
783c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
78406f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
78506f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
78606f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
787c2aa98e2SPeter Wemm
788c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
789c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
790c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
791c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
792c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
79306f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
79406f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
79506f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
79606f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
79706f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
79806f25ae9SGregory Neil Shapiro`dnl')
79906f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
80006f25ae9SGregory Neil Shapirodnl by one of the rules before
801c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
802c2aa98e2SPeter Wemm
803c2aa98e2SPeter Wemm
804c2aa98e2SPeter Wemm##################################################
805c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
806c2aa98e2SPeter Wemm##################################################
80706f25ae9SGregory Neil ShapiroSfinal=4
808c2aa98e2SPeter Wemm
809c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
810c2aa98e2SPeter Wemm
811c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
812c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
813c2aa98e2SPeter Wemm
81406f25ae9SGregory Neil Shapiro# eliminate internal code
815c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
816c2aa98e2SPeter Wemm
817c2aa98e2SPeter Wemm# externalize local domain info
818c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
819c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
820c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
821c2aa98e2SPeter Wemm
822c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
823c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
824c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
825c2aa98e2SPeter Wemm
826c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
827c2aa98e2SPeter Wemm`# put DECnet back in :: form
828c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
829c2aa98e2SPeter Wemm	`dnl')
830c2aa98e2SPeter Wemm# delete duplicate local names
831c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
832c2aa98e2SPeter Wemm
833c2aa98e2SPeter Wemm
834c2aa98e2SPeter Wemm
835c2aa98e2SPeter Wemm##############################################################
836c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
837c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
838c2aa98e2SPeter Wemm##############################################################
839c2aa98e2SPeter Wemm
84006f25ae9SGregory Neil ShapiroSRecurse=97
84106f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
84206f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
843c2aa98e2SPeter Wemm
844c2aa98e2SPeter Wemm
845c2aa98e2SPeter Wemm######################################
846c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
847c2aa98e2SPeter Wemm######################################
848c2aa98e2SPeter Wemm
84906f25ae9SGregory Neil ShapiroSparse=0
850c2aa98e2SPeter Wemm
851c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
852c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
85306f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
854c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
855c2aa98e2SPeter Wemm
856c2aa98e2SPeter Wemm#
857c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
858c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
859c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
860c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
861c2aa98e2SPeter Wemm#
862c2aa98e2SPeter Wemm
863c2aa98e2SPeter WemmSParse0
864c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
86542e5d165SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "501 List:; syntax illegal for recipient addresses"
86606f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
86742e5d165SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "501 User address required"
868c2aa98e2SPeter WemmR$*			$: <> $1
869c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*	$1 < @ [ $2 ] > $3
87042e5d165SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "501 Colon illegal in host name part"
871c2aa98e2SPeter WemmR<> $*			$1
87242e5d165SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "501 Invalid host name"
87342e5d165SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "501 Invalid host name"
87406f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
87542e5d165SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.2 $: "501 Invalid route address"
876c2aa98e2SPeter Wemm
877c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
87806f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
87906f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
880c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
88142e5d165SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "501 User address required"
88206f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
883c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
88442e5d165SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "501 User address required"
885c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
88606f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
887c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
888c2aa98e2SPeter Wemm
889c2aa98e2SPeter Wemm#
890c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
891c2aa98e2SPeter Wemm#
892c2aa98e2SPeter Wemm
893c2aa98e2SPeter WemmSParse1
89406f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
89506f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
89606f25ae9SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2>',
897c2aa98e2SPeter Wemm`dnl')
898c2aa98e2SPeter Wemm
89906f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
90006f25ae9SGregory Neil Shapiro`# handle numeric address spec
90106f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
90206f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
90306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$1 < @ [ $2 ] : $S > $3		Add smart host to path
90406f25ae9SGregory Neil ShapiroR$* < @ [ IPv6 $- ] : > $*
90506f25ae9SGregory Neil Shapiro		$#_SMTP_ $@ [ $(dequote $2 $) ] $: $1 < @ [IPv6 $2 ] > $3	no smarthost: send
90606f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*	$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
90706f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
90806f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
90906f25ae9SGregory Neil Shapiro	`dnl')
91006f25ae9SGregory Neil Shapiro
91106f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
912c2aa98e2SPeter Wemm# handle virtual users
91306f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
91406f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
91506f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
91606f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
91706f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
918c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
91906f25ae9SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
920c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
921c2aa98e2SPeter Wemm			$: < $(virtuser $1 @ $3 $@ $1 $: @ $) > $1 + $2 < @ $3 . >
92206f25ae9SGregory Neil Shapirodnl try default entry: @domain
92306f25ae9SGregory Neil Shapirodnl +*@domain
92406f25ae9SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
92506f25ae9SGregory Neil Shapirodnl @domain if +detail exists
92606f25ae9SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $: @ $) > $1 + $2 < @ $3 . >
92706f25ae9SGregory Neil Shapirodnl without +detail (or no match)
928c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
929c2aa98e2SPeter WemmR<@> $+			$: $1
93006f25ae9SGregory Neil ShapiroR<!> $+			$: $1
93106f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
932c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
93306f25ae9SGregory Neil ShapiroR< $+ > $+ < @ $+ >	$: $>Recurse $1',
934c2aa98e2SPeter Wemm`dnl')
935c2aa98e2SPeter Wemm
936c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
937c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
93806f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
93942e5d165SGregory Neil Shapiro
94042e5d165SGregory Neil Shapiro
941c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
942c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
94306f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
94406f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
945c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
946c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
947c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
948c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
949c2aa98e2SPeter Wemm
95006f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
951c2aa98e2SPeter Wemm# not local -- try mailer table lookup
952c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
953c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
954c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
95506f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
95606f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
95706f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
958c2aa98e2SPeter Wemm`dnl')
95906f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
960c2aa98e2SPeter Wemm
961c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
962c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
963c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
96406f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
965c2aa98e2SPeter Wemm	`dnl')
966c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
96706f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
968c2aa98e2SPeter Wemm	`dnl')
969c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
97006f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
971c2aa98e2SPeter Wemm	`dnl')')
972c2aa98e2SPeter Wemm
973c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
974c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
97506f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
976c2aa98e2SPeter Wemm	`dnl')
977c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
97806f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
979c2aa98e2SPeter Wemm	`dnl')
980c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
981c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
982c2aa98e2SPeter Wemm	`dnl')
983c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
984c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
985c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
98606f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
987c2aa98e2SPeter Wemm	`dnl')')
988c2aa98e2SPeter Wemm
989c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
990c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
99106f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
992c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
993c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
994c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
995c2aa98e2SPeter Wemm	`dnl')')
996c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
997c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
99806f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
999c2aa98e2SPeter Wemm	`dnl')
1000c2aa98e2SPeter Wemm
1001c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1002c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1003c2aa98e2SPeter Wemmundivert(1)', `dnl')
1004c2aa98e2SPeter Wemm
1005c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
100606f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1007c2aa98e2SPeter Wemm
1008c2aa98e2SPeter Wemm# deal with other remote names
1009c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1010c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
101142e5d165SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "501 Unrecognized host name " $2')
1012c2aa98e2SPeter Wemm
1013c2aa98e2SPeter Wemm# handle locally delivered names
1014c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1015c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1016c2aa98e2SPeter Wemm
1017c2aa98e2SPeter Wemm###########################################################################
1018c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1019c2aa98e2SPeter Wemm###########################################################################
1020c2aa98e2SPeter Wemm
102106f25ae9SGregory Neil ShapiroSLocal_localaddr
102206f25ae9SGregory Neil ShapiroSlocaladdr=5
102306f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
102406f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
102506f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1026c2aa98e2SPeter Wemm
102742e5d165SGregory Neil Shapiroifdef(`_FFR_5_', `
102842e5d165SGregory Neil Shapiro# Preserve host in a macro
102942e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
103042e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1031c2aa98e2SPeter Wemm
103242e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `
103342e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
103442e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
103542e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
103642e5d165SGregory Neil Shapiro')
1037c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1038c2aa98e2SPeter WemmR$+			$: <> $1
1039c2aa98e2SPeter Wemm
1040c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1041c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
104242e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `
104342e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
104442e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
104542e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
104642e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
104706f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
104842e5d165SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')',
1049c2aa98e2SPeter Wemm`dnl')
1050c2aa98e2SPeter Wemm
1051c2aa98e2SPeter Wemm# see if we have a relay or a hub
1052c2aa98e2SPeter WemmR< > $+			$: < $H > $1			try hub
1053c2aa98e2SPeter WemmR< > $+			$: < $R > $1			try relay
105442e5d165SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `
105542e5d165SGregory Neil ShapiroR< > $+			$@ $1', `
105606f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
105706f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
105806f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1059c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
106042e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1061c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
10622e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
10632e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
106442e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
106506f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
106606f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
106706f25ae9SGregory Neil ShapiroR< $- : $+ > $+		$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
106806f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1069c2aa98e2SPeter Wemm
107006f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1071c2aa98e2SPeter Wemm###################################################################
1072c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
107306f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1074c2aa98e2SPeter Wemm###################################################################
1075c2aa98e2SPeter Wemm
107606f25ae9SGregory Neil ShapiroSMailertable=90
107706f25ae9SGregory Neil Shapirodnl shift and check
107806f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1079c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
108006f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
108106f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
108206f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
108306f25ae9SGregory Neil Shapirodnl is $2 always empty?
1084c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
108506f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
108606f25ae9SGregory Neil Shapirodnl return full address
1087c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1088c2aa98e2SPeter Wemm`dnl')
1089c2aa98e2SPeter Wemm
1090c2aa98e2SPeter Wemm###################################################################
1091c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
109206f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
109306f25ae9SGregory Neil Shapirodnl	<> address				-> address
109406f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
109506f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
109606f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
109706f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
109806f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
109906f25ae9SGregory Neil Shapirodnl	<[IPv6 number]> address			-> relay number address
110006f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1101c2aa98e2SPeter Wemm###################################################################
1102c2aa98e2SPeter Wemm
110306f25ae9SGregory Neil ShapiroSMailerToTriple=95
1104c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
110506f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1106c2aa98e2SPeter WemmR< error : $- $+ > $*		$#error $@ $(dequote $1 $) $: $2
1107c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
1108c2aa98e2SPeter WemmR< $- : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
1109c2aa98e2SPeter WemmR< $- : $+ > $*			$# $1 $@ $2 $: $3	try qualified mailer
1110c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
111106f25ae9SGregory Neil ShapiroR< [ IPv6 $+ ] > $*		$#_RELAY_ $@ $(dequote $1 $) $: $2	use unqualified mailer
1112c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1113c2aa98e2SPeter Wemm
1114c2aa98e2SPeter Wemm###################################################################
1115c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
111606f25ae9SGregory Neil Shapirodnl input: <user> address
111706f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
111806f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
111906f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
112006f25ae9SGregory Neil Shapirodnl <> user				-> local user user
112106f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
112206f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
112306f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1124c2aa98e2SPeter Wemm###################################################################
1125c2aa98e2SPeter Wemm
1126c2aa98e2SPeter WemmSCanonLocal
11272e43090eSPeter Wemm# strip local host from routed addresses
112806f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
112906f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
11302e43090eSPeter Wemm
1131c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1132c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1133c2aa98e2SPeter Wemm
1134c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1135c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1136c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1137c2aa98e2SPeter Wemm
1138c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1139c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1140c2aa98e2SPeter Wemm
1141c2aa98e2SPeter Wemm# handle local:user syntax
1142c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1143c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1144c2aa98e2SPeter Wemm
1145c2aa98e2SPeter Wemm###################################################################
1146c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1147c2aa98e2SPeter Wemm###################################################################
1148c2aa98e2SPeter Wemm
114906f25ae9SGregory Neil ShapiroSMasqHdr=93
1150c2aa98e2SPeter Wemm
115106f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1152c2aa98e2SPeter Wemm# handle generics database
1153c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
115406f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1155c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1156c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1157c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
115806f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
115906f25ae9SGregory Neil Shapirodnl ignore the first case for now
116006f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
116106f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
116206f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
116306f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
116406f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
116506f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
116606f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
116706f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
116806f25ae9SGregory Neil Shapirodnl no match, remove mark
116906f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
117006f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
117106f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
117206f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
117306f25ae9SGregory Neil Shapirodnl no match, try local part
1174c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
117506f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
117606f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
117706f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
117806f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1179c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1180c2aa98e2SPeter Wemm`dnl')
1181c2aa98e2SPeter Wemm
118206f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
118306f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
118406f25ae9SGregory Neil Shapiro
1185c2aa98e2SPeter Wemm# special case the users that should be exposed
1186c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1187c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1188c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1189c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1190c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1191c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1192c2aa98e2SPeter Wemm
1193c2aa98e2SPeter Wemm# handle domain-specific masquerading
1194c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1195c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1196c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1197c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1198c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1199c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1200c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1201c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
1202c2aa98e2SPeter Wemm
1203c2aa98e2SPeter Wemm###################################################################
1204c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1205c2aa98e2SPeter Wemm###################################################################
1206c2aa98e2SPeter Wemm
120706f25ae9SGregory Neil ShapiroSMasqEnv=94
1208c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
120906f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1210c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1211c2aa98e2SPeter Wemm
1212c2aa98e2SPeter Wemm###################################################################
1213c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1214c2aa98e2SPeter Wemm###################################################################
1215c2aa98e2SPeter Wemm
121606f25ae9SGregory Neil ShapiroSParseLocal=98
121706f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1218c2aa98e2SPeter Wemm
121906f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
122006f25ae9SGregory Neil ShapiroSLDAPExpand
122106f25ae9SGregory Neil Shapiro# do the LDAP lookups
122206f25ae9SGregory Neil ShapiroR<$+><$+>		$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2>
122306f25ae9SGregory Neil Shapiro
122406f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
122506f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
122606f25ae9SGregory Neil ShapiroR< $+ > < $=w > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
122706f25ae9SGregory Neil ShapiroR< $+ > <  > < $+ > < $+ >	$@ $>Parse0 $>canonify $1
122806f25ae9SGregory Neil Shapiro
122906f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
123006f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
123106f25ae9SGregory Neil ShapiroR< $+ > < $+ > < $+ > < $+ >	$#_RELAY_ $@ $2 $: $>canonify $1
123206f25ae9SGregory Neil Shapiro
123306f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
123406f25ae9SGregory Neil Shapiro# return original address
123506f25ae9SGregory Neil ShapiroR< > < $=w > <$+> <$+>		$@ $2
123606f25ae9SGregory Neil Shapiro
123706f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
123806f25ae9SGregory Neil Shapiro# relay to mailHost with original address
123906f25ae9SGregory Neil ShapiroR< > < $+ > <$+> <$+>		$#_RELAY_ $@ $1 $: $2
124006f25ae9SGregory Neil Shapiro
124106f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost,
124206f25ae9SGregory Neil Shapiro# try @domain
124306f25ae9SGregory Neil ShapiroR< > < > <$+> <$+ @ $+>		$@ $>LDAPExpand <$1> <@ $3>
124406f25ae9SGregory Neil Shapiro
124506f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
124606f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
124706f25ae9SGregory Neil Shapiro# user does not exist
124806f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$#error $@ nouser $: "550 User unknown"',
124906f25ae9SGregory Neil Shapiro`dnl
125006f25ae9SGregory Neil Shapiro# return the original address
125106f25ae9SGregory Neil ShapiroR< > < > <$+> <@ $+>		$@ $1')',
125206f25ae9SGregory Neil Shapiro`dnl')
125306f25ae9SGregory Neil Shapiro
125406f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
125506f25ae9SGregory Neil Shapiro')')
125606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1257c2aa98e2SPeter Wemm######################################################################
1258c2aa98e2SPeter Wemm###  LookUpDomain -- search for domain in access database
1259c2aa98e2SPeter Wemm###
1260c2aa98e2SPeter Wemm###	Parameters:
1261c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1262c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
126306f25ae9SGregory Neil Shapirodnl			must not be empty
1264c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed unchanged through)
126506f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
126606f25ae9SGregory Neil Shapiro###			! does lookup only with tag
126706f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
126806f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
126906f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1270c2aa98e2SPeter Wemm######################################################################
1271c2aa98e2SPeter Wemm
1272c2aa98e2SPeter WemmSLookUpDomain
127306f25ae9SGregory Neil Shapirodnl remove IPv6 mark and dequote address
127406f25ae9SGregory Neil Shapirodnl it is a bit ugly because it is checked on each "iteration"
127506f25ae9SGregory Neil ShapiroR<[IPv6 $-]> <$+> <$*> <$*>	$: <[$(dequote $1 $)]> <$2> <$3> <$4>
127606f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
127706f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
127806f25ae9SGregory Neil ShapiroR<$*> <$+> <$*> <$- $->		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
127906f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
128006f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
128106f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$- $->	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4> <$5 $6>', `dnl')
128206f25ae9SGregory Neil Shapirodnl lookup without tag?
128306f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $*>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
128406f25ae9SGregory Neil Shapiroifdef(`_FFR_LOOKUPDOTDOMAIN', `dnl omit first component: lookup .rest
128506f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <+ $*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <$4> <+ $5>', `dnl')
128606f25ae9SGregory Neil Shapirodnl lookup IP address (no check is done whether it is an IP number!)
128706f25ae9SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$*> <$*>	$@ $>LookUpDomain <[$1]> <$3> <$4> <$5>
128806f25ae9SGregory Neil Shapirodnl lookup IPv6 address
128906f25ae9SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$*> <$*>	$: $>LookUpDomain <[$1]> <$3> <$4> <$5>
129006f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
129106f25ae9SGregory Neil ShapiroR<?> <$+.$+> <$+> <$*> <$*>	$@ $>LookUpDomain <$2> <$3> <$4> <$5>
129206f25ae9SGregory Neil Shapirodnl not found, no subdomain: return default
129306f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
129406f25ae9SGregory Neil Shapirodnl return result of lookup
129506f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>
1296c2aa98e2SPeter Wemm
1297c2aa98e2SPeter Wemm######################################################################
1298c2aa98e2SPeter Wemm###  LookUpAddress -- search for host address in access database
1299c2aa98e2SPeter Wemm###
1300c2aa98e2SPeter Wemm###	Parameters:
1301c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1302c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
130306f25ae9SGregory Neil Shapirodnl			must not be empty
1304c2aa98e2SPeter Wemm###		<$3> -- passthru (additional data passed through)
130506f25ae9SGregory Neil Shapiro###		<$4> -- mark (must be <(!|+) single-token>)
130606f25ae9SGregory Neil Shapiro###			! does lookup only with tag
130706f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
130806f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
130906f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1310c2aa98e2SPeter Wemm######################################################################
1311c2aa98e2SPeter Wemm
1312c2aa98e2SPeter WemmSLookUpAddress
131306f25ae9SGregory Neil Shapirodnl lookup with tag
131406f25ae9SGregory Neil ShapiroR<$+> <$+> <$*> <$- $+>		$: < $(access $5`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3> <$4 $5>
131506f25ae9SGregory Neil Shapirodnl lookup without tag
131606f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <+ $+>	$: < $(access $1 $: ? $) > <$1> <$2> <$3> <+ $4>
131706f25ae9SGregory Neil Shapirodnl no match; IPv6: remove last part
131806f25ae9SGregory Neil ShapiroR<?> <$+:$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
131906f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
132006f25ae9SGregory Neil ShapiroR<?> <$+.$-> <$+> <$*> <$*>	$@ $>LookUpAddress <$1> <$3> <$4> <$5>
132106f25ae9SGregory Neil Shapirodnl no match: return default
132206f25ae9SGregory Neil ShapiroR<?> <$+> <$+> <$*> <$*>	$@ <$2> <$3>
132306f25ae9SGregory Neil Shapirodnl match: return result
132406f25ae9SGregory Neil ShapiroR<$*> <$+> <$+> <$*> <$*>	$@ <$1> <$4>',
1325c2aa98e2SPeter Wemm`dnl')
1326c2aa98e2SPeter Wemm
1327c2aa98e2SPeter Wemm######################################################################
1328065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1329065a643dSPeter Wemm###			relay checking.  Route address syntax is
1330065a643dSPeter Wemm###			crudely converted into a %-hack address.
1331065a643dSPeter Wemm###
1332065a643dSPeter Wemm###	Parameters:
1333065a643dSPeter Wemm###		$1 -- full recipient address
1334065a643dSPeter Wemm###
1335065a643dSPeter Wemm###	Returns:
1336065a643dSPeter Wemm###		parsed address, not in source route form
133706f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
133806f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1339065a643dSPeter Wemm######################################################################
1340065a643dSPeter Wemm
1341065a643dSPeter WemmSCanonAddr
134206f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
134306f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1344065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1345065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1346065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
134706f25ae9SGregory Neil Shapirodnl')
1348065a643dSPeter Wemm
1349065a643dSPeter Wemm######################################################################
1350c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1351c2aa98e2SPeter Wemm###			$* $=m or the access database.
1352c2aa98e2SPeter Wemm###			Check user portion for host separators.
1353c2aa98e2SPeter Wemm###
1354c2aa98e2SPeter Wemm###	Parameters:
1355c2aa98e2SPeter Wemm###		$1 -- full recipient address
1356c2aa98e2SPeter Wemm###
1357c2aa98e2SPeter Wemm###	Returns:
1358c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1359c2aa98e2SPeter Wemm######################################################################
1360c2aa98e2SPeter Wemm
1361c2aa98e2SPeter WemmSParseRecipient
136206f25ae9SGregory Neil Shapirodnl mark and canonify address
1363065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
136406f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1365c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
136606f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1367c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1368c2aa98e2SPeter Wemm
1369c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1370c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
137106f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1372c2aa98e2SPeter WemmR<?> $*				$@ $1
1373c2aa98e2SPeter Wemm
137406f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>, where localpart contains $=O
137506f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1376c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1377c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1378c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
1379065a643dSPeter Wemm
1380065a643dSPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
138106f25ae9SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
1382065a643dSPeter WemmR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1383065a643dSPeter WemmR<MX> < : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
138406f25ae9SGregory Neil Shapirodnl yes: mark it as <RELAY>
1385065a643dSPeter WemmR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
138606f25ae9SGregory Neil Shapirodnl no: put old <NO> mark back
1387065a643dSPeter WemmR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
1388065a643dSPeter Wemm
138906f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
139006f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
1391c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1392c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
139306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
139406f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1395065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1396c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
139706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
139806f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>LookUpDomain <$2> <NO> <$1 < @ $2 >> <+To>
1399c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1400065a643dSPeter Wemm
140106f25ae9SGregory Neil Shapiro
1402c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
1403c2aa98e2SPeter WemmR<$-> $*			$@ $2
1404c2aa98e2SPeter Wemm
140506f25ae9SGregory Neil Shapiro
1406c2aa98e2SPeter Wemm######################################################################
1407c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1408c2aa98e2SPeter Wemm######################################################################
1409c2aa98e2SPeter Wemm
1410c2aa98e2SPeter WemmSLocal_check_relay
141106f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1412c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1413c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1414c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1415c2aa98e2SPeter Wemm
1416c2aa98e2SPeter WemmSBasic_check_relay
1417c2aa98e2SPeter Wemm# check for deferred delivery mode
1418c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1419c2aa98e2SPeter WemmR< d > $*		$@ deferred
1420c2aa98e2SPeter WemmR< $* > $*		$: $2
1421c2aa98e2SPeter Wemm
142206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
142342e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
142406f25ae9SGregory Neil ShapiroR$+ $| $+		$: $>LookUpDomain < $1 > <?> < $2 > <+Connect>
142542e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
142606f25ae9SGregory Neil ShapiroR<?> <$+>		$: $>LookUpAddress < $1 > <?> < $1 > <+Connect>	no: another lookup
142742e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
142806f25ae9SGregory Neil ShapiroR<?> < $+ >		$: $1					found nothing
142942e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
143042e5d165SGregory Neil Shapirodnl or {client_addr}
143142e5d165SGregory Neil ShapiroR<$={Accept}> < $* >	$@ $1				return value of lookup
143206f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
1433c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
143406f25ae9SGregory Neil Shapirodnl error tag
143542e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
143642e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
143706f25ae9SGregory Neil Shapirodnl generic error from access map
143842e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1439c2aa98e2SPeter Wemm
1440c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
144106f25ae9SGregory Neil Shapiro# DNS based IP address spam list
1442c2aa98e2SPeter WemmR$*			$: $&{client_addr}
144306f25ae9SGregory Neil ShapiroR::ffff:$-.$-.$-.$-	$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
144406f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
144506f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
144606f25ae9SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Mail from " $&{client_addr} " refused by blackhole site _RBL_"',
1447c2aa98e2SPeter Wemm`dnl')
144806f25ae9SGregory Neil Shapiroundivert(8)
1449c2aa98e2SPeter Wemm
1450c2aa98e2SPeter Wemm######################################################################
1451c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1452c2aa98e2SPeter Wemm######################################################################
1453c2aa98e2SPeter Wemm
1454c2aa98e2SPeter WemmSLocal_check_mail
145506f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1456c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1457c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1458c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1459c2aa98e2SPeter Wemm
1460c2aa98e2SPeter WemmSBasic_check_mail
1461c2aa98e2SPeter Wemm# check for deferred delivery mode
1462c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1463c2aa98e2SPeter WemmR< d > $*		$@ deferred
1464c2aa98e2SPeter WemmR< $* > $*		$: $2
1465c2aa98e2SPeter Wemm
146606f25ae9SGregory Neil Shapiro# authenticated?
146706f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
146806f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
146906f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
147006f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
147106f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
147206f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
147306f25ae9SGregory Neil Shapiro
147406f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
147506f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
147606f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
147706f25ae9SGregory Neil Shapirodnl do some additional checks
147806f25ae9SGregory Neil Shapirodnl no user@host
147906f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
148006f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
148106f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
148206f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
148306f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
148406f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
148506f25ae9SGregory Neil ShapiroR$+			$: <?> $1
148606f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
148706f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
148806f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
148906f25ae9SGregory Neil Shapirodnl prepend daemon_flags
149006f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
149106f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
149206f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
149306f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
149406f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
149506f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
149606f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
149706f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
149806f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
149906f25ae9SGregory Neil Shapirodnl remove daemon_flags
150006f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
150106f25ae9SGregory Neil Shapiro# handle case of @localhost on address
150206f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
150306f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
150406f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
150506f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
150606f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
150706f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
150806f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
150906f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
151006f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
151106f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
151206f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
151306f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
151406f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
151506f25ae9SGregory Neil Shapirodnl	or:    <address>
151606f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
151706f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
151842e5d165SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "501 Real domain name required for sender address"
151906f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
152006f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
152106f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
152206f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
152306f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
152406f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1525065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1526c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
152706f25ae9SGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <OK> $1 < @ $2 $3 >
152806f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
1529c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
153006f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <OK> $1 < @ $2 >		... unresolvable OK',
153106f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
153206f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
153306f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
153406f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, OK, PERM, TEMP
153506f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1536c2aa98e2SPeter Wemm
153706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
153806f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
153906f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
154006f25ae9SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, OK, PERM, TEMP
154106f25ae9SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <H:$3>
154206f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
154306f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
154406f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
154506f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
154606f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+From> $| <$3> <>
154706f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
154806f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
154906f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1550c2aa98e2SPeter Wemm# retransform for further use
155106f25ae9SGregory Neil Shapirodnl required form:
155206f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
155306f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
155406f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
155506f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
155606f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1557c2aa98e2SPeter Wemm
1558c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1559c2aa98e2SPeter Wemm# handle case of no @domain on address
156006f25ae9SGregory Neil Shapirodnl prepend daemon_flags
156106f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
156206f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
156306f25ae9SGregory Neil ShapiroR$* u $* $| <?> $*	$: <OK> $3
156406f25ae9SGregory Neil Shapirodnl remove daemon_flags
156506f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
1566c2aa98e2SPeter WemmR<?> $*			$: < ? $&{client_name} > $1
1567c2aa98e2SPeter WemmR<?> $*			$@ <OK>				...local unqualed ok
156842e5d165SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "501 Domain name required for sender address " $&f
1569c2aa98e2SPeter Wemm							...remote is not')
1570c2aa98e2SPeter Wemm# check results
157106f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1572c2aa98e2SPeter WemmR<OK> $*		$@ <OK>
157306f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
157406f25ae9SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "501 Domain of sender address " $&f " does not exist"
157506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
157606f25ae9SGregory Neil ShapiroR<$={Accept}> $*	$# $1
1577c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
157806f25ae9SGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"')
157906f25ae9SGregory Neil Shapirodnl error tag
158006f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
158106f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
158206f25ae9SGregory Neil Shapirodnl generic error from access map
158306f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1584c2aa98e2SPeter Wemm`dnl')
1585c2aa98e2SPeter Wemm
1586c2aa98e2SPeter Wemm######################################################################
1587c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
1588c2aa98e2SPeter Wemm######################################################################
1589c2aa98e2SPeter Wemm
1590c2aa98e2SPeter WemmSLocal_check_rcpt
159106f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
1592c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
1593c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1594c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
1595c2aa98e2SPeter Wemm
1596c2aa98e2SPeter WemmSBasic_check_rcpt
1597c2aa98e2SPeter Wemm# check for deferred delivery mode
1598c2aa98e2SPeter WemmR$*			$: < ${deliveryMode} > $1
1599c2aa98e2SPeter WemmR< d > $*		$@ deferred
1600c2aa98e2SPeter WemmR< $* > $*		$: $2
1601c2aa98e2SPeter Wemm
160206f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
160306f25ae9SGregory Neil Shapiro# require qualified recipient?
160406f25ae9SGregory Neil ShapiroR$+			$: <?> $1
160506f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
160606f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
160706f25ae9SGregory Neil Shapirodnl prepend daemon_flags
160806f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
160906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
161006f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
161106f25ae9SGregory Neil ShapiroR$* r $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
161206f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
161306f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
161406f25ae9SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Domain name required"
161506f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
161606f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
161706f25ae9SGregory Neil Shapiro
1618c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
1619065a643dSPeter WemmR$*			$: $>CanonAddr $1
1620c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
1621c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
1622c2aa98e2SPeter Wemm
1623065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
1624065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
1625065a643dSPeter Wemm# unlimited bestmx
1626065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
1627065a643dSPeter Wemm`dnl
1628065a643dSPeter Wemm# limit bestmx to $=B
16292e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
163006f25ae9SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Basic_check_rcpt" $1 $2 $3
1631065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
1632065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
1633065a643dSPeter Wemm
1634c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
163506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1636c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
1637c2aa98e2SPeter WemmR$*			$: <?> $1
163806f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
163906f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
164006f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <H:$2>
164106f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <H:$2>
164206f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
164306f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
164406f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
164506f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+To> $| <$2> <>
164606f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
164706f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
164806f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
164906f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
165006f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
165106f25ae9SGregory Neil Shapirodnl as generic error message...
165206f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
165306f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
165406f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
165506f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
1656c2aa98e2SPeter WemmR<REJECT> $*		$#error $@ 5.2.1 $: "550 Mailbox disabled for this recipient"
165706f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
165806f25ae9SGregory Neil Shapirodnl error tag
165906f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
166006f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
166106f25ae9SGregory Neil Shapirodnl generic error from access map
166206f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
166306f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
1664c2aa98e2SPeter Wemm
166506f25ae9SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)')
166606f25ae9SGregory Neil Shapiro# authenticated?
166706f25ae9SGregory Neil Shapirodnl do this unconditionally? this requires to manage CAs carefully
166806f25ae9SGregory Neil Shapirodnl just because someone has a CERT signed by a "trusted" CA
166906f25ae9SGregory Neil Shapirodnl does not mean we want to allow relaying for her,
167006f25ae9SGregory Neil Shapirodnl either use a subroutine or provide something more sophisticated
167106f25ae9SGregory Neil Shapirodnl this could for example check the DN (maybe an access map lookup)
167206f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>RelayAuth $1 $| $&{verify}	client authenticated?
167306f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2				error/ok?
167406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1				no
167506f25ae9SGregory Neil Shapiro
167606f25ae9SGregory Neil Shapiro# authenticated by a trusted mechanism?
167706f25ae9SGregory Neil ShapiroR$*			$: $1 $| $&{auth_type}
167806f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
167906f25ae9SGregory Neil ShapiroR$* $|			$: $1
168006f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
168106f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
168206f25ae9SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAYAUTH
168306f25ae9SGregory Neil Shapirodnl undo addition of ${auth_type}
168406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
168506f25ae9SGregory Neil Shapirodnl workspace: localpart<@domain>
168606f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
168706f25ae9SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
1688c2aa98e2SPeter Wemm# anything terminating locally is ok
1689c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
169006f25ae9SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAYTO', `dnl')
169106f25ae9SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAYTO
1692c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
169306f25ae9SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAYTO
169406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
169506f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>
169606f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
169706f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
169806f25ae9SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAYTO
169906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
170006f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: $>LookUpDomain <$2> <?> <$1 < @ $2 >> <+To>',`dnl')')
170106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
170206f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
170306f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYTO
1704c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
1705c2aa98e2SPeter Wemm
170606f25ae9SGregory Neil Shapiro
1707c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
1708c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
170906f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
171006f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
1711c2aa98e2SPeter WemmR< : $* <TEMP> : > $*	$#error $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1
171206f25ae9SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAYTO
1713065a643dSPeter WemmR< : $* : > $*		$: $2',
1714c2aa98e2SPeter Wemm`dnl')
1715c2aa98e2SPeter Wemm
1716c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
1717c2aa98e2SPeter WemmR$*			$: <?> $1
1718065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
1719c2aa98e2SPeter Wemm# local user is ok
172006f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
172106f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
172206f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
172306f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
172406f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
172506f25ae9SGregory Neil ShapiroR<?> postmaster		$@ TOPOSTMASTER
172606f25ae9SGregory Neil Shapiro# require qualified recipient?
172706f25ae9SGregory Neil Shapirodnl prepend daemon_flags
172806f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
172906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
173006f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
173106f25ae9SGregory Neil Shapirodnl r flag? add client_name
173206f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
173306f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
173406f25ae9SGregory Neil Shapiro# no qualified recipient required
173506f25ae9SGregory Neil ShapiroR$* $| <?> $+		$@ RELAYTOLOCAL
173606f25ae9SGregory Neil Shapirodnl client_name is empty
173706f25ae9SGregory Neil ShapiroR<?> <?> $+		$@ RELAYTOLOCAL
173806f25ae9SGregory Neil Shapirodnl client_name is local
173906f25ae9SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAYTOLOCAL
174006f25ae9SGregory Neil Shapirodnl client_name is not local
174106f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
174206f25ae9SGregory Neil Shapirodnl no qualified recipient required
174306f25ae9SGregory Neil ShapiroR<?> $+			$@ RELAYTOLOCAL')
174406f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
1745c2aa98e2SPeter WemmR<$+> $*		$: $2
174606f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
1747c2aa98e2SPeter Wemm
1748c2aa98e2SPeter Wemm# anything originating locally is ok
1749c2aa98e2SPeter Wemm# check IP address
1750c2aa98e2SPeter WemmR$*			$: $&{client_addr}
175106f25ae9SGregory Neil ShapiroR$@			$@ RELAYFROM		originated locally
175206f25ae9SGregory Neil ShapiroR0			$@ RELAYFROM		originated locally
175306f25ae9SGregory Neil ShapiroR$=R $*			$@ RELAYFROM		relayable IP address
175406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
175506f25ae9SGregory Neil ShapiroR$*			$: $>LookUpAddress <$1> <?> <$1> <+Connect>
175606f25ae9SGregory Neil ShapiroR<RELAY> $* 		$@ RELAYFROM		relayable IP address
1757c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
1758c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
175906f25ae9SGregory Neil ShapiroR$=w			$@ RELAYFROM		... and see if it is local
1760c2aa98e2SPeter Wemm
176106f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
176206f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
176306f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
176406f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
176506f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
176606f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
176706f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
1768c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
176906f25ae9SGregory Neil Shapiro# check whether local FROM is ok
177006f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w . >	$@ RELAYFROMMAIL	FROM local', `dnl')
177106f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
177206f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
177306f25ae9SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 < @ $2 > $| $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', `<H:$2>') <>
177406f25ae9SGregory Neil ShapiroR$* <RELAY>		$@ RELAYFROMMAIL	RELAY FROM sender ok', `dnl
177506f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_', `errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
177606f25ae9SGregory Neil Shapiro')',
177706f25ae9SGregory Neil Shapiro`dnl')
177806f25ae9SGregory Neil Shapirodnl')', `dnl')
177906f25ae9SGregory Neil Shapiro
178006f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
178106f25ae9SGregory Neil Shapirodnl input: ignored
178206f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
178306f25ae9SGregory Neil ShapiroR<TEMP>			$#error $@ 4.7.1 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
178406f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
178506f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
178606f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
178706f25ae9SGregory Neil ShapiroR$*			$: <?> $&{client_name}
178806f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical
178906f25ae9SGregory Neil ShapiroR<?> $* $~P 		$:<?>  $[ $1 $2 $]
179006f25ae9SGregory Neil ShapiroR$* .			$1			strip trailing dots
179106f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
179206f25ae9SGregory Neil ShapiroR<?>			$@ RELAYFROM
179306f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
179406f25ae9SGregory Neil ShapiroR<?> $* $=m		$@ RELAYFROM', `dnl')
179506f25ae9SGregory Neil ShapiroR<?> $=w		$@ RELAYFROM
179606f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
179706f25ae9SGregory Neil Shapiro`R<?> $=R		$@ RELAYFROM
179806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
179906f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
180006f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
180106f25ae9SGregory Neil Shapiro`R<?> $* $=R			$@ RELAYFROM
180206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
180306f25ae9SGregory Neil ShapiroR<?> $*			$: $>LookUpDomain <$1> <?> <$1> <+Connect>',`dnl')')
180406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
180506f25ae9SGregory Neil ShapiroR<RELAY> $*		$@ RELAYFROM
180606f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
1807c2aa98e2SPeter Wemm
1808c2aa98e2SPeter Wemm# anything else is bogus
180906f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
181006f25ae9SGregory Neil Shapirodivert(0)
181106f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
181206f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
181306f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
181406f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
181506f25ae9SGregory Neil ShapiroSFullAddr
181606f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
181706f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
181806f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
1819c2aa98e2SPeter Wemm
182006f25ae9SGregory Neil Shapiro# call all necessary rulesets
182106f25ae9SGregory Neil ShapiroScheck_rcpt
182206f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
182306f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
182406f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
182506f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
182606f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
182706f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
182806f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
182906f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
183006f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
183106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
183206f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
183306f25ae9SGregory Neil Shapiro')')dnl
183406f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
183506f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
183606f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
183706f25ae9SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <U: $1@>
183806f25ae9SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 >
183906f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
184006f25ae9SGregory Neil Shapiro# lookup the addresses only with To tag
184106f25ae9SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <!To> $| <$2> <>
184206f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
184306f25ae9SGregory Neil Shapirodnl', `dnl')
184406f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
184506f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
184606f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
184706f25ae9SGregory Neil Shapiro	`errprint(`*** ERROR: define either SpamHater or SpamFriend
184806f25ae9SGregory Neil Shapiro')', `dnl')
184906f25ae9SGregory Neil ShapiroR<SPAMFRIEND> $+	$@ SPAMFRIEND
185006f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
185106f25ae9SGregory Neil Shapiro`dnl')
185206f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
185306f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
185406f25ae9SGregory Neil ShapiroR<SPAMHATER> $+		$: $1			spam hater: continue checks
185506f25ae9SGregory Neil ShapiroR<$*> $+		$@ NOSPAMHATER		everyone else: stop
185606f25ae9SGregory Neil Shapirodnl',`dnl')
185706f25ae9SGregory Neil Shapirodnl run further checks: check_mail
185806f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
185906f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkmail <$&f>
186006f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
186106f25ae9SGregory Neil Shapirodnl run further checks: check_relay
186206f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
186306f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
186406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
186506f25ae9SGregory Neil Shapiro', `dnl')
186606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
186706f25ae9SGregory Neil Shapiro######################################################################
186806f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
186906f25ae9SGregory Neil Shapiro###	Parameters:
187006f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
187106f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
187206f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
187306f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
187406f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
187506f25ae9SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: H: if there
187606f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
187706f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
187806f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
187906f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
188006f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
188106f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
188206f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
188306f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
188406f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
188506f25ae9SGregory Neil Shapiro###		H: recursive host lookup (LookUpDomain)
188606f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
188706f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
188806f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
188906f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
189006f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
189106f25ae9SGregory Neil Shapiro######################################################################
189206f25ae9SGregory Neil Shapiro
189306f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
189406f25ae9SGregory Neil Shapirodnl if A is activated: add it
189506f25ae9SGregory Neil ShapiroC{src}E F H U
189606f25ae9SGregory Neil ShapiroSSearchList
189706f25ae9SGregory Neil Shapiro# mark H: lookup domain
189806f25ae9SGregory Neil ShapiroR<$+> $| <H:$+> <$*>		$: <$1> $| <@> $>LookUpDomain <$2> <?> <$3> <$1>
189906f25ae9SGregory Neil ShapiroR<$+> $| <@> <$+> <$*>		$: <$1> $| <$2> <$3>
190006f25ae9SGregory Neil Shapirodnl A: NOT YET REQUIRED
190106f25ae9SGregory Neil Shapirodnl R<$+> $| <A:$+> <$*>	$: <$1> $| <@> $>LookUpAddress <$2> <?> <$3> <$1>
190206f25ae9SGregory Neil Shapirodnl R<$+> $| <@> <$+> <$*>	$: <$1> $| <$2> <$3>
190306f25ae9SGregory Neil Shapirodnl lookup of the item with tag
190406f25ae9SGregory Neil Shapirodnl this applies to F: U: E:
190506f25ae9SGregory Neil ShapiroR<$- $-> $| <$={src}:$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$4 $: $3:$4 $)> <$5>
190606f25ae9SGregory Neil Shapirodnl no match, try without tag
190706f25ae9SGregory Neil ShapiroR<+ $-> $| <$={src}:$+> <$*>	$: <+ $1> $| <$(access $3 $: $2:$3 $)> <$4>
190806f25ae9SGregory Neil Shapirodnl do we really have to distinguish these cases?
190906f25ae9SGregory Neil Shapirodnl probably yes, there might be a + in the domain part (is that allowed?)
191006f25ae9SGregory Neil Shapirodnl user+detail lookups: should it be:
191106f25ae9SGregory Neil Shapirodnl user+detail, user+*, user; just like aliases?
191206f25ae9SGregory Neil ShapiroR<$- $-> $| <F:$* + $*@$+> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@$5 $: F:$3 + $4@$5$)> <$6>
191306f25ae9SGregory Neil ShapiroR<+ $-> $| <F:$* + $*@$+> <$*>	$: <+ $1> $| <$(access $2@$4 $: F:$2 + $3@$4$)> <$5>
191406f25ae9SGregory Neil Shapirodnl user lookups are always with trailing @
191506f25ae9SGregory Neil Shapirodnl do not remove the @ from the lookup:
191606f25ae9SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
191706f25ae9SGregory Neil ShapiroR<$- $-> $| <U:$* + $*> <$*>	$: <$1 $2> $| <$(access $2`'_TAG_DELIM_`'$3@ $: U:$3 + $4$)> <$5>
191806f25ae9SGregory Neil Shapirodnl no match, try without tag
191906f25ae9SGregory Neil ShapiroR<+ $-> $| <U:$* + $*> <$*>	$: <+ $1> $| <$(access $2@ $: U:$2 + $3$)> <$4>
192006f25ae9SGregory Neil Shapirodnl no match, try rest of list
192106f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <$+>	$@ $>SearchList <$1> $| <$4>
192206f25ae9SGregory Neil Shapirodnl no match, list empty: return failure
192306f25ae9SGregory Neil ShapiroR<$+> $| <$={src}:$+> <>	$@ <?>
192406f25ae9SGregory Neil Shapirodnl got result, return it
192506f25ae9SGregory Neil ShapiroR<$+> $| <$+> <$*>		$@ <$2>
192606f25ae9SGregory Neil Shapirodnl return result from recursive invocation
192706f25ae9SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>', `dnl')
192806f25ae9SGregory Neil Shapiro
192906f25ae9SGregory Neil Shapiro# is user trusted to authenticate as someone else?
193006f25ae9SGregory Neil Shapirodnl AUTH= parameter from MAIL command
193106f25ae9SGregory Neil ShapiroStrust_auth
193206f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
193306f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
193406f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
193506f25ae9SGregory Neil Shapirodnl seems to be useful...
193606f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
193706f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
193806f25ae9SGregory Neil Shapirodnl call user supplied code
193906f25ae9SGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $1
194006f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
194106f25ae9SGregory Neil Shapirodnl default: error
194206f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
194306f25ae9SGregory Neil Shapiro
194406f25ae9SGregory Neil Shapirodnl empty ruleset definition so it can be called
194506f25ae9SGregory Neil ShapiroSLocal_trust_auth
194606f25ae9SGregory Neil Shapiro
194706f25ae9SGregory Neil Shapiroifdef(`_FFR_TLS_O_T', `dnl
194806f25ae9SGregory Neil ShapiroSoffer_tls
194906f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{client_name}> <?> <> <! TLS_OFF_TAG>
195006f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_OFF_TAG>
195106f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_OFF_TAG: $: ? $)>
195206f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
195306f25ae9SGregory Neil ShapiroR<NO> <>	$#error $@ 5.7.1 $: "550 do not offer TLS for " $&{client_name} " ["$&{client_addr}"]"
195406f25ae9SGregory Neil Shapiro
195506f25ae9SGregory Neil ShapiroStry_tls
195606f25ae9SGregory Neil ShapiroR$*		$: $>LookUpDomain <$&{server_name}> <?> <> <! TLS_TRY_TAG>
195706f25ae9SGregory Neil ShapiroR<?>$*		$: $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_TRY_TAG>
195806f25ae9SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG: $: ? $)>
195906f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
196006f25ae9SGregory Neil ShapiroR<NO> <>	$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"
196106f25ae9SGregory Neil Shapiro')dnl
196206f25ae9SGregory Neil Shapiro
196306f25ae9SGregory Neil Shapiro# is connection with client "good" enough? (done in server)
196406f25ae9SGregory Neil Shapiro# input: ${verify} $| (MAIL|STARTTLS)
196506f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
196606f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
196706f25ae9SGregory Neil ShapiroStls_client
196806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
196906f25ae9SGregory Neil Shapirodnl ignore second arg for now
197006f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
197106f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
197206f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
197306f25ae9SGregory Neil ShapiroR$* $| $*	$: $1 $| $>LookUpDomain <$&{client_name}> <?> <> <! TLS_CLT_TAG>
197406f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{client_addr}> <?> <> <! TLS_CLT_TAG>
197506f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
197606f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
197706f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
197806f25ae9SGregory Neil ShapiroR$* $| $*	$@ $>"tls_connection" $1')
197906f25ae9SGregory Neil Shapiro
198006f25ae9SGregory Neil Shapiro# is connection with server "good" enough? (done in client)
198106f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
198206f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
198306f25ae9SGregory Neil Shapiro# input: ${verify}
198406f25ae9SGregory Neil ShapiroStls_server
198506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
198606f25ae9SGregory Neil ShapiroR$*		$: $1 $| $>LookUpDomain <$&{server_name}> <?> <> <! TLS_SRV_TAG>
198706f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>LookUpAddress <$&{server_addr}> <?> <> <! TLS_SRV_TAG>
198806f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
198906f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
199006f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1', `dnl
199106f25ae9SGregory Neil ShapiroR$*		$@ $>"tls_connection" $1')
199206f25ae9SGregory Neil Shapiro
199306f25ae9SGregory Neil ShapiroStls_connection
199406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
199506f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
199606f25ae9SGregory Neil Shapirodnl input: $&{verify} $| <ResultOfLookup> [<>]
199706f25ae9SGregory Neil Shapirodnl remove optional <>
199806f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
199906f25ae9SGregory Neil Shapirodnl permanent or temporary error?
200006f25ae9SGregory Neil ShapiroR$* $| <PERM + $={tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
200106f25ae9SGregory Neil ShapiroR$* $| <TEMP + $={tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
200206f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
200306f25ae9SGregory Neil ShapiroR$* $| <$={tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
200406f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
200506f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
200606f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
200706f25ae9SGregory Neil Shapirodnl use default error
200806f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
200906f25ae9SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> $1
201006f25ae9SGregory Neil ShapiroR$* $| <$*> <$={tls}:$->$*	$: <$2> <$3:$4> $1
201106f25ae9SGregory Neil Shapirodnl some other value in access map: accept
201206f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
201306f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
201406f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
201506f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
201606f25ae9SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> ${verify}
201706f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
201806f25ae9SGregory Neil ShapiroR<$*><VERIFY> OK		$@ OK
201906f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
202006f25ae9SGregory Neil ShapiroR<$*><VERIFY:$-> OK		$: <$1> <REQ:$2>
202106f25ae9SGregory Neil Shapirodnl just some level of encryption required
202206f25ae9SGregory Neil ShapiroR<$*><ENCR:$-> $*		$: <$1> <REQ:$2>
202306f25ae9SGregory Neil Shapirodnl verification required but ${verify} is not set
202406f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*>		$#error $@ $2 $: $1 " authentication required"
202506f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> FAIL	$#error $@ $2 $: $1 " authentication failed"
202606f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NO		$#error $@ $2 $: $1 " not authenticated"
202706f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
202806f25ae9SGregory Neil Shapirodnl some other value for ${verify}
202906f25ae9SGregory Neil ShapiroR<$-:$+><VERIFY $*> $+		$#error $@ $2 $: $1 " authentication failure " $4
203006f25ae9SGregory Neil Shapirodnl some level of encryption required: get the maximum level
203106f25ae9SGregory Neil ShapiroR<$*><REQ:$->			$: <$1> <REQ:$2> $>max $&{cipher_bits} : $&{auth_ssf}
203206f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
203306f25ae9SGregory Neil ShapiroR<$*><REQ:$-> $-		$: <$1> <$2:$3> $(arith l $@ $3 $@ $2 $)
203406f25ae9SGregory Neil ShapiroR<$-:$+><$-:$-> TRUE		$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
203506f25ae9SGregory Neil Shapiro
203606f25ae9SGregory Neil ShapiroSmax
203706f25ae9SGregory Neil Shapirodnl compute the max of two values separated by :
203806f25ae9SGregory Neil ShapiroR:		$: 0
203906f25ae9SGregory Neil ShapiroR:$-		$: $1
204006f25ae9SGregory Neil ShapiroR$-:		$: $1
204106f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
204206f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
204306f25ae9SGregory Neil ShapiroR$-:$-:$-	$: $2',
204406f25ae9SGregory Neil Shapiro`dnl use default error
204506f25ae9SGregory Neil Shapirodnl deal with TLS handshake failures: abort
204606f25ae9SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."')
204706f25ae9SGregory Neil Shapiro
204806f25ae9SGregory Neil ShapiroSRelayAuth
204906f25ae9SGregory Neil Shapiro# authenticated?
205006f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
205106f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
205206f25ae9SGregory Neil Shapirodnl CA in CERTPath so we can authenticate users, we do not allow
205306f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
205406f25ae9SGregory Neil Shapirodnl but anyway).
205506f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
205606f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
205706f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
205806f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
205906f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
206006f25ae9SGregory Neil Shapirodnl cert subject.
206106f25ae9SGregory Neil ShapiroR$* $| OK		$: $1
206206f25ae9SGregory Neil ShapiroR$* $| $*		$@ NO		not authenticated
206306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
206406f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
206506f25ae9SGregory Neil ShapiroR$*			$: $1 $| $(CERTIssuer $&{cert_issuer} $)',
206606f25ae9SGregory Neil Shapiro`R$*			$: $1 $| $&{cert_issuer}')
206706f25ae9SGregory Neil ShapiroR$* $| $+		$: $1 $| $(access CERTISSUER:$2 $)
206806f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
206906f25ae9SGregory Neil ShapiroR$* $| RELAY		$# RELAYCERTISSUER
207006f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
207106f25ae9SGregory Neil ShapiroR$* $| SUBJECT		$: $1 $| <@> $(CERTSubject $&{cert_subject} $)',
207206f25ae9SGregory Neil Shapiro`R$* $| SUBJECT		$: $1 $| <@> $&{cert_subject}')
207342e5d165SGregory Neil ShapiroR$* $| <@> $+		$: $1 $| <@> $(access CERTSUBJECT:$2 $)
207406f25ae9SGregory Neil ShapiroR$* $| <@> RELAY	$# RELAYCERTSUBJECT
207506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
207606f25ae9SGregory Neil Shapiro
207706f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
207806f25ae9SGregory Neil Shapiroifdef(`_FFR_MILTER', `
207906f25ae9SGregory Neil Shapiro#
208006f25ae9SGregory Neil Shapiro######################################################################
208106f25ae9SGregory Neil Shapiro######################################################################
208206f25ae9SGregory Neil Shapiro#####
208306f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
208406f25ae9SGregory Neil Shapiro#####
208506f25ae9SGregory Neil Shapiro######################################################################
208606f25ae9SGregory Neil Shapiro######################################################################
208706f25ae9SGregory Neil Shapiro_MAIL_FILTERS_')
2088c2aa98e2SPeter Wemm#
2089c2aa98e2SPeter Wemm######################################################################
2090c2aa98e2SPeter Wemm######################################################################
2091c2aa98e2SPeter Wemm#####
2092c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
2093c2aa98e2SPeter Wemm#####
2094c2aa98e2SPeter Wemm######################################################################
2095c2aa98e2SPeter Wemm######################################################################
209606f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
209742e5d165SGregory Neil Shapiro
2098