xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 5b0945b5)
1c2aa98e2SPeter Wemmdivert(-1)
2c2aa98e2SPeter Wemm#
35dd76dd0SGregory Neil Shapiro# Copyright (c) 1998-2010 Proofpoint, 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
164313cc83SGregory Neil ShapiroVERSIONID(`$Id: proto.m4,v 8.762 2013-11-22 20:51:13 ca Exp $')
17c2aa98e2SPeter Wemm
1806f25ae9SGregory Neil Shapiro# level CF_LEVEL config file format
196f9c8e5bSGregory Neil ShapiroV`'CF_LEVEL`'ifdef(`NO_VENDOR',`', `/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley')')
20c2aa98e2SPeter Wemmdivert(-1)
21c2aa98e2SPeter Wemm
2240266059SGregory Neil Shapirodnl if MAILER(`local') not defined: do it ourself; be nice
2340266059SGregory Neil Shapirodnl maybe we should issue a warning?
2440266059SGregory Neil Shapiroifdef(`_MAILER_local_',`', `MAILER(local)')
2540266059SGregory Neil Shapiro
26c2aa98e2SPeter Wemm# do some sanity checking
27c2aa98e2SPeter Wemmifdef(`__OSTYPE__',,
2806f25ae9SGregory Neil Shapiro	`errprint(`*** ERROR: No system type defined (use OSTYPE macro)
2906f25ae9SGregory Neil Shapiro')')
30c2aa98e2SPeter Wemm
31c2aa98e2SPeter Wemm# pick our default mailers
32c2aa98e2SPeter Wemmifdef(`confSMTP_MAILER',, `define(`confSMTP_MAILER', `esmtp')')
33c2aa98e2SPeter Wemmifdef(`confLOCAL_MAILER',, `define(`confLOCAL_MAILER', `local')')
34c2aa98e2SPeter Wemmifdef(`confRELAY_MAILER',,
35c2aa98e2SPeter Wemm	`define(`confRELAY_MAILER',
36c2aa98e2SPeter Wemm		`ifdef(`_MAILER_smtp_', `relay',
37c2aa98e2SPeter Wemm			`ifdef(`_MAILER_uucp', `uucp-new', `unknown')')')')
38c2aa98e2SPeter Wemmifdef(`confUUCP_MAILER',, `define(`confUUCP_MAILER', `uucp-old')')
39c2aa98e2SPeter Wemmdefine(`_SMTP_', `confSMTP_MAILER')dnl		for readability only
40c2aa98e2SPeter Wemmdefine(`_LOCAL_', `confLOCAL_MAILER')dnl	for readability only
41c2aa98e2SPeter Wemmdefine(`_RELAY_', `confRELAY_MAILER')dnl	for readability only
42c2aa98e2SPeter Wemmdefine(`_UUCP_', `confUUCP_MAILER')dnl		for readability only
43c2aa98e2SPeter Wemm
44c2aa98e2SPeter Wemm# back compatibility with old config files
45c2aa98e2SPeter Wemmifdef(`confDEF_GROUP_ID',
4606f25ae9SGregory Neil Shapiro`errprint(`*** confDEF_GROUP_ID is obsolete.
4706f25ae9SGregory Neil Shapiro    Use confDEF_USER_ID with a colon in the value instead.
4806f25ae9SGregory Neil Shapiro')')
49c2aa98e2SPeter Wemmifdef(`confREAD_TIMEOUT',
5006f25ae9SGregory Neil Shapiro`errprint(`*** confREAD_TIMEOUT is obsolete.
5106f25ae9SGregory Neil Shapiro    Use individual confTO_<timeout> parameters instead.
5206f25ae9SGregory Neil Shapiro')')
53c2aa98e2SPeter Wemmifdef(`confMESSAGE_TIMEOUT',
54c2aa98e2SPeter Wemm	`define(`_ARG_', index(confMESSAGE_TIMEOUT, /))
55c2aa98e2SPeter Wemm	 ifelse(_ARG_, -1,
56c2aa98e2SPeter Wemm		`define(`confTO_QUEUERETURN', confMESSAGE_TIMEOUT)',
57c2aa98e2SPeter Wemm		`define(`confTO_QUEUERETURN',
58c2aa98e2SPeter Wemm			substr(confMESSAGE_TIMEOUT, 0, _ARG_))
59c2aa98e2SPeter Wemm		 define(`confTO_QUEUEWARN',
60c2aa98e2SPeter Wemm			substr(confMESSAGE_TIMEOUT, eval(_ARG_+1)))')')
61c2aa98e2SPeter Wemmifdef(`confMIN_FREE_BLOCKS', `ifelse(index(confMIN_FREE_BLOCKS, /), -1,,
6206f25ae9SGregory Neil Shapiro`errprint(`*** compound confMIN_FREE_BLOCKS is obsolete.
6306f25ae9SGregory Neil Shapiro    Use confMAX_MESSAGE_SIZE for the second part of the value.
6406f25ae9SGregory Neil Shapiro')')')
6506f25ae9SGregory Neil Shapiro
6606f25ae9SGregory Neil Shapiro
6706f25ae9SGregory Neil Shapiro# Sanity check on ldap_routing feature
6806f25ae9SGregory Neil Shapiro# If the user doesn't specify a new map, they better have given as a
6906f25ae9SGregory Neil Shapiro# default LDAP specification which has the LDAP base (and most likely the host)
7006f25ae9SGregory Neil Shapiroifdef(`confLDAP_DEFAULT_SPEC',, `ifdef(`_LDAP_ROUTING_WARN_', `errprint(`
7106f25ae9SGregory Neil ShapiroWARNING: Using default FEATURE(ldap_routing) map definition(s)
7206f25ae9SGregory Neil Shapirowithout setting confLDAP_DEFAULT_SPEC option.
7306f25ae9SGregory Neil Shapiro')')')dnl
74c2aa98e2SPeter Wemm
75c2aa98e2SPeter Wemm# clean option definitions below....
7606f25ae9SGregory Neil Shapirodefine(`_OPTION', `ifdef(`$2', `O $1`'ifelse(defn(`$2'), `',, `=$2')', `#O $1`'ifelse(`$3', `',,`=$3')')')dnl
77c2aa98e2SPeter Wemm
7806f25ae9SGregory Neil Shapirodnl required to "rename" the check_* rulesets...
7906f25ae9SGregory Neil Shapirodefine(`_U_',ifdef(`_DELAY_CHECKS_',`',`_'))
8006f25ae9SGregory Neil Shapirodnl default relaying denied message
8140266059SGregory Neil Shapiroifdef(`confRELAY_MSG', `', `define(`confRELAY_MSG',
8240266059SGregory Neil Shapiroifdef(`_USE_AUTH_', `"550 Relaying denied. Proper authentication required."', `"550 Relaying denied"'))')
8340266059SGregory Neil Shapiroifdef(`confRCPTREJ_MSG', `', `define(`confRCPTREJ_MSG', `"550 Mailbox disabled for this recipient"')')
8440266059SGregory Neil Shapirodefine(`_CODE553', `553')
85c2aa98e2SPeter Wemmdivert(0)dnl
86c2aa98e2SPeter Wemm
8706f25ae9SGregory Neil Shapiro# override file safeties - setting this option compromises system security,
8806f25ae9SGregory Neil Shapiro# addressing the actual file configuration problem is preferred
8906f25ae9SGregory Neil Shapiro# need to set this before any file actions are encountered in the cf file
9006f25ae9SGregory Neil Shapiro_OPTION(DontBlameSendmail, `confDONT_BLAME_SENDMAIL', `safe')
9106f25ae9SGregory Neil Shapiro
9206f25ae9SGregory Neil Shapiro# default LDAP map specification
9306f25ae9SGregory Neil Shapiro# need to set this now before any LDAP maps are defined
9406f25ae9SGregory Neil Shapiro_OPTION(LDAPDefaultSpec, `confLDAP_DEFAULT_SPEC', `-h localhost')
95c2aa98e2SPeter Wemm
96c2aa98e2SPeter Wemm##################
97c2aa98e2SPeter Wemm#   local info   #
98c2aa98e2SPeter Wemm##################
99c2aa98e2SPeter Wemm
10040266059SGregory Neil Shapiro# my LDAP cluster
10140266059SGregory Neil Shapiro# need to set this before any LDAP lookups are done (including classes)
10240266059SGregory Neil Shapiroifdef(`confLDAP_CLUSTER', `D{sendmailMTACluster}`'confLDAP_CLUSTER', `#D{sendmailMTACluster}$m')
10340266059SGregory Neil Shapiro
104c2aa98e2SPeter WemmCwlocalhost
105c2aa98e2SPeter Wemmifdef(`USE_CW_FILE',
106c2aa98e2SPeter Wemm`# file containing names of hosts for which we receive email
107c2aa98e2SPeter WemmFw`'confCW_FILE',
108c2aa98e2SPeter Wemm	`dnl')
109c2aa98e2SPeter Wemm
110c2aa98e2SPeter Wemm# my official domain name
111c2aa98e2SPeter Wemm# ... `define' this only if sendmail cannot automatically determine your domain
112c2aa98e2SPeter Wemmifdef(`confDOMAIN_NAME', `Dj`'confDOMAIN_NAME', `#Dj$w.Foo.COM')
113c2aa98e2SPeter Wemm
114323f6dcbSGregory Neil Shapiro# host/domain names ending with a token in class P are canonical
115c2aa98e2SPeter WemmCP.
116c2aa98e2SPeter Wemm
117c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
118c2aa98e2SPeter Wemm`# UUCP relay host
119c2aa98e2SPeter WemmDY`'UUCP_RELAY
120c2aa98e2SPeter WemmCPUUCP
121c2aa98e2SPeter Wemm
122c2aa98e2SPeter Wemm')dnl
123c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
124c2aa98e2SPeter Wemm`#  BITNET relay host
125c2aa98e2SPeter WemmDB`'BITNET_RELAY
126c2aa98e2SPeter WemmCPBITNET
127c2aa98e2SPeter Wemm
128c2aa98e2SPeter Wemm')dnl
129c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
130c2aa98e2SPeter Wemm`define(`_USE_DECNET_SYNTAX_', 1)dnl
131c2aa98e2SPeter Wemm# DECnet relay host
132c2aa98e2SPeter WemmDC`'DECNET_RELAY
133c2aa98e2SPeter WemmCPDECNET
134c2aa98e2SPeter Wemm
135c2aa98e2SPeter Wemm')dnl
136c2aa98e2SPeter Wemmifdef(`FAX_RELAY',
137c2aa98e2SPeter Wemm`# FAX relay host
138c2aa98e2SPeter WemmDF`'FAX_RELAY
139c2aa98e2SPeter WemmCPFAX
140c2aa98e2SPeter Wemm
141c2aa98e2SPeter Wemm')dnl
142c2aa98e2SPeter Wemm# "Smart" relay host (may be null)
14340266059SGregory Neil ShapiroDS`'ifdef(`SMART_HOST', `SMART_HOST')
144c2aa98e2SPeter Wemm
145c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
146c2aa98e2SPeter Wemm# place to which unknown users should be forwarded
147c2aa98e2SPeter WemmKuser user -m -a<>
148c2aa98e2SPeter WemmDL`'LUSER_RELAY',
149c2aa98e2SPeter Wemm`dnl')
150c2aa98e2SPeter Wemm
151c2aa98e2SPeter Wemm# operators that cannot be in local usernames (i.e., network indicators)
152da7d7b9cSGregory Neil ShapiroCO @ ifdef(`_NO_PERCENTHACK_', `', `%') ifdef(`_NO_UUCP_', `', `!')
153c2aa98e2SPeter Wemm
154c2aa98e2SPeter Wemm# a class with just dot (for identifying canonical names)
155c2aa98e2SPeter WemmC..
156c2aa98e2SPeter Wemm
157c2aa98e2SPeter Wemm# a class with just a left bracket (for identifying domain literals)
158c2aa98e2SPeter WemmC[[
159c2aa98e2SPeter Wemm
16006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
16106f25ae9SGregory Neil Shapiro# access_db acceptance class
16206f25ae9SGregory Neil ShapiroC{Accept}OK RELAY
16340266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
1645b0945b5SGregory Neil Shapiroifdef(`_BLOCKLIST_RCPT_',`dnl
16506f25ae9SGregory Neil Shapiro# possible access_db RHS for spam friends/haters
16606f25ae9SGregory Neil ShapiroC{SpamTag}SPAMFRIEND SPAMHATER')')',
167c2aa98e2SPeter Wemm`dnl')
168c2aa98e2SPeter Wemm
16940266059SGregory Neil Shapirodnl mark for "domain is ok" (resolved or accepted anyway)
17040266059SGregory Neil Shapirodefine(`_RES_OK_', `OKR')dnl
171c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',`dnl',`dnl
172c2aa98e2SPeter Wemm# Resolve map (to check if a host exists in check_mail)
17340266059SGregory Neil ShapiroKresolve host -a<_RES_OK_> -T<TEMP>')
17440266059SGregory Neil ShapiroC{ResOk}_RES_OK_
175c2aa98e2SPeter Wemm
17613058a91SGregory Neil Shapiroifdef(`_NEED_MACRO_MAP_', `dnl
17713058a91SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
17813058a91SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
17913058a91SGregory Neil ShapiroKmacro macro')', `dnl')
18042e5d165SGregory Neil Shapiro
181c2aa98e2SPeter Wemmifdef(`confCR_FILE', `dnl
18242e5d165SGregory Neil Shapiro# Hosts for which relaying is permitted ($=R)
183c2aa98e2SPeter WemmFR`'confCR_FILE',
184c2aa98e2SPeter Wemm`dnl')
185c2aa98e2SPeter Wemm
18640266059SGregory Neil Shapirodefine(`TLS_SRV_TAG', `"TLS_Srv"')dnl
18740266059SGregory Neil Shapirodefine(`TLS_CLT_TAG', `"TLS_Clt"')dnl
18840266059SGregory Neil Shapirodefine(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl
18940266059SGregory Neil Shapirodefine(`TLS_TRY_TAG', `"Try_TLS"')dnl
19040266059SGregory Neil Shapirodefine(`SRV_FEAT_TAG', `"Srv_Features"')dnl
19106f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
19206f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
19306f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
19406f25ae9SGregory Neil ShapiroKarith arith')
19506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
19640266059SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
19740266059SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
19840266059SGregory Neil ShapiroKmacro macro')
19940266059SGregory Neil Shapiro# possible values for TLS_connection in access map
2005b0945b5SGregory Neil ShapiroC{Tls}VERIFY ENCR
2015b0945b5SGregory Neil ShapiroC{TlsVerified}OK TRUSTED
2025b0945b5SGregory Neil Shapirodnl', `dnl')
20306f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
20406f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
20506f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
20606f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
20706f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
20806f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
20906f25ae9SGregory Neil Shapiro
21040266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
211fabecb74SGregory Neil Shapiro# who I send unqualified names to if `FEATURE(stickyhost)' is used
21213bd1963SGregory Neil Shapiro# (null means deliver locally)
21340266059SGregory Neil ShapiroDR`'LOCAL_RELAY')
214c2aa98e2SPeter Wemm
21540266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
21613bd1963SGregory Neil Shapiro# who gets all local email traffic
217fabecb74SGregory Neil Shapiro# ($R has precedence for unqualified names if `FEATURE(stickyhost)' is used)
21840266059SGregory Neil ShapiroDH`'MAIL_HUB')
219c2aa98e2SPeter Wemm
220c2aa98e2SPeter Wemm# dequoting map
22140266059SGregory Neil ShapiroKdequote dequote`'ifdef(`confDEQUOTE_OPTS', ` confDEQUOTE_OPTS', `')
222c2aa98e2SPeter Wemm
223c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
224c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
22506f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
226c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
22706f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
228c2aa98e2SPeter Wemm#CL root
229c2aa98e2SPeter Wemmundivert(5)dnl
23006f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
231c2aa98e2SPeter Wemm
23240266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
233c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
23440266059SGregory Neil ShapiroDM`'MASQUERADE_NAME')
235c2aa98e2SPeter Wemm
236c2aa98e2SPeter Wemm# my name for error messages
237c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
238c2aa98e2SPeter Wemm
23906f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
240c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
241c2aa98e2SPeter Wemm
242c2aa98e2SPeter Wemm###############
243c2aa98e2SPeter Wemm#   Options   #
244c2aa98e2SPeter Wemm###############
24540266059SGregory Neil Shapiroifdef(`confAUTO_REBUILD',
24640266059SGregory Neil Shapiro`errprint(WARNING: `confAUTO_REBUILD' is no longer valid.
24740266059SGregory Neil Shapiro	There was a potential for a denial of service attack if this is set.
24840266059SGregory Neil Shapiro)')dnl
249c2aa98e2SPeter Wemm
250c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
25106f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
252c2aa98e2SPeter Wemm
253c2aa98e2SPeter Wemm# 8-bit data handling
2548774250cSGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
255c2aa98e2SPeter Wemm
256c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
25706f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
258c2aa98e2SPeter Wemm
259c2aa98e2SPeter Wemm# location of alias file
26006f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
26106f25ae9SGregory Neil Shapiro
262c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
26306f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
264c2aa98e2SPeter Wemm
265c2aa98e2SPeter Wemm# maximum message size
266e92d3f3fSGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0')
267c2aa98e2SPeter Wemm
268c2aa98e2SPeter Wemm# substitution for space (blank) characters
26906f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
270c2aa98e2SPeter Wemm
271c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
27206f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
273c2aa98e2SPeter Wemm
274c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
27506f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
276c2aa98e2SPeter Wemm
277c2aa98e2SPeter Wemm# default delivery mode
27806f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
279c2aa98e2SPeter Wemm
280c2aa98e2SPeter Wemm# error message header/file
28106f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
282c2aa98e2SPeter Wemm
283c2aa98e2SPeter Wemm# error mode
28406f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
285c2aa98e2SPeter Wemm
286c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
28706f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
288c2aa98e2SPeter Wemm
28940266059SGregory Neil Shapiro# queue file mode (qf files)
29040266059SGregory Neil Shapiro_OPTION(QueueFileMode, `confQUEUE_FILE_MODE', `0600')
29140266059SGregory Neil Shapiro
292c2aa98e2SPeter Wemm# temporary file mode
29306f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
294c2aa98e2SPeter Wemm
295c2aa98e2SPeter Wemm# match recipients against GECOS field?
29606f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
297c2aa98e2SPeter Wemm
298c2aa98e2SPeter Wemm# maximum hop count
29940266059SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `25')
300c2aa98e2SPeter Wemm
301c2aa98e2SPeter Wemm# location of help file
30206f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
303c2aa98e2SPeter Wemm
304c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
30506f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
306c2aa98e2SPeter Wemm
307c2aa98e2SPeter Wemm# name resolver options
30806f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
309c2aa98e2SPeter Wemm
310c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
31106f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
312c2aa98e2SPeter Wemm
313c2aa98e2SPeter Wemm# Forward file search path
31406f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
315c2aa98e2SPeter Wemm
316c2aa98e2SPeter Wemm# open connection cache size
31706f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
318c2aa98e2SPeter Wemm
319c2aa98e2SPeter Wemm# open connection cache timeout
32006f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
321c2aa98e2SPeter Wemm
322c2aa98e2SPeter Wemm# persistent host status directory
32306f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
324c2aa98e2SPeter Wemm
325c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
32606f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
327c2aa98e2SPeter Wemm
328c2aa98e2SPeter Wemm# use Errors-To: header?
32906f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
330c2aa98e2SPeter Wemm
331da7d7b9cSGregory Neil Shapiro# use compressed IPv6 address format?
332da7d7b9cSGregory Neil Shapiro_OPTION(UseCompressedIPv6Addresses, `confUSE_COMPRESSED_IPV6_ADDRESSES', `')
333da7d7b9cSGregory Neil Shapiro
334c2aa98e2SPeter Wemm# log level
33506f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
336c2aa98e2SPeter Wemm
337c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
33806f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
339c2aa98e2SPeter Wemm
340c2aa98e2SPeter Wemm# verify RHS in newaliases?
34106f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
342c2aa98e2SPeter Wemm
343c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
34406f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
345c2aa98e2SPeter Wemm
346c2aa98e2SPeter Wemm# SMTP daemon options
34706f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
348605302a5SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
349605302a5SGregory Neil Shapiro	Use `DAEMON_OPTIONS()'; see cf/README.
35006f25ae9SGregory Neil Shapiro)'dnl
35106f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
35242e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
35340266059SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
35440266059SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
35506f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
35606f25ae9SGregory Neil Shapiro
35706f25ae9SGregory Neil Shapiro# SMTP client options
35840266059SGregory Neil Shapiroifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
35940266059SGregory Neil Shapiro`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
36040266059SGregory Neil Shapiro)'dnl
36140266059SGregory Neil Shapiro`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
36240266059SGregory Neil Shapiroifelse(defn(`_CPO_'), `',
36340266059SGregory Neil Shapiro`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
36440266059SGregory Neil Shapiro
36540266059SGregory Neil Shapiro# Modifiers to `define' {daemon_flags} for direct submissions
36640266059SGregory Neil Shapiro_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
36740266059SGregory Neil Shapiro
36840266059SGregory Neil Shapiro# Use as mail submission program? See sendmail/SECURITY
36940266059SGregory Neil Shapiro_OPTION(UseMSP, `confUSE_MSP', `')
370c2aa98e2SPeter Wemm
371c2aa98e2SPeter Wemm# privacy flags
37206f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
373c2aa98e2SPeter Wemm
374c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
37506f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
376c2aa98e2SPeter Wemm
377c2aa98e2SPeter Wemm# slope of queue-only function
37806f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
379c2aa98e2SPeter Wemm
38040266059SGregory Neil Shapiro# limit on number of concurrent queue runners
38140266059SGregory Neil Shapiro_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
38240266059SGregory Neil Shapiro
38340266059SGregory Neil Shapiro# maximum number of queue-runners per queue-grouping with multiple queues
38440266059SGregory Neil Shapiro_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
38540266059SGregory Neil Shapiro
38640266059SGregory Neil Shapiro# priority of queue runners (nice(3))
38740266059SGregory Neil Shapiro_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
38840266059SGregory Neil Shapiro
38940266059SGregory Neil Shapiro# shall we sort the queue by hostname first?
39040266059SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
39140266059SGregory Neil Shapiro
39240266059SGregory Neil Shapiro# minimum time in queue before retry
39340266059SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
39440266059SGregory Neil Shapiro
395da7d7b9cSGregory Neil Shapiro# maximum time in queue before retry (if > 0; only for exponential delay)
396da7d7b9cSGregory Neil Shapiro_OPTION(MaxQueueAge, `confMAX_QUEUE_AGE', `')
397da7d7b9cSGregory Neil Shapiro
39840266059SGregory Neil Shapiro# how many jobs can you process in the queue?
3994e4196cbSGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
40040266059SGregory Neil Shapiro
40140266059SGregory Neil Shapiro# perform initial split of envelope without checking MX records
40240266059SGregory Neil Shapiro_OPTION(FastSplit, `confFAST_SPLIT', `1')
40340266059SGregory Neil Shapiro
404c2aa98e2SPeter Wemm# queue directory
40506f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
406c2aa98e2SPeter Wemm
407d0cef73dSGregory Neil Shapiro# key for shared memory; 0 to turn off, -1 to auto-select
40840266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
40940266059SGregory Neil Shapiro
410d0cef73dSGregory Neil Shapiro# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
411d0cef73dSGregory Neil Shapiro_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
412605302a5SGregory Neil Shapiro
413c2aa98e2SPeter Wemm# timeouts (many of these)
41406f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
41506f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
41640266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
41706f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
41806f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
41906f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
42006f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
42106f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
42206f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
42306f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
42406f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
42506f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
42606f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
42706f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
42806f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
42906f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
43206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
43306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
435e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
43806f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
440e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
44106f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
44206f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
44306f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
44406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
44506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
44606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
44706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
44840266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
44940266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
45040266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
45140266059SGregory Neil Shapiro
45240266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
45340266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
454c2aa98e2SPeter Wemm
455c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
45606f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
457c2aa98e2SPeter Wemm
458c2aa98e2SPeter Wemm# queue up everything before forking?
45906f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
460c2aa98e2SPeter Wemm
461c2aa98e2SPeter Wemm# status file
462d0cef73dSGregory Neil Shapiro_OPTION(StatusFile, `STATUS_FILE')
463c2aa98e2SPeter Wemm
464c2aa98e2SPeter Wemm# time zone handling:
465c2aa98e2SPeter Wemm#  if undefined, use system default
466c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
467c2aa98e2SPeter Wemm#  if defined and non-null, use that info
468c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
469c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
470c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
471c2aa98e2SPeter Wemm
472c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
47306f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
474c2aa98e2SPeter Wemm
475c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
47606f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
477c2aa98e2SPeter Wemm
478c2aa98e2SPeter Wemm# fallback MX host
47906f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
480c2aa98e2SPeter Wemm
481e92d3f3fSGregory Neil Shapiro# fallback smart host
482e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
483e92d3f3fSGregory Neil Shapiro
484c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
48506f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
486c2aa98e2SPeter Wemm
487c2aa98e2SPeter Wemm# load average at which we just queue messages
48806f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
489c2aa98e2SPeter Wemm
490c2aa98e2SPeter Wemm# load average at which we refuse connections
49106f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
492c2aa98e2SPeter Wemm
493e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
494e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
495e92d3f3fSGregory Neil Shapiro
49640266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
49740266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
49840266059SGregory Neil Shapiro
499c2aa98e2SPeter Wemm# maximum number of children we allow at one time
500739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
501c2aa98e2SPeter Wemm
502c2aa98e2SPeter Wemm# maximum number of new connections per second
503193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
504c2aa98e2SPeter Wemm
505e92d3f3fSGregory Neil Shapiro# Width of the window
506e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
507e92d3f3fSGregory Neil Shapiro
508c2aa98e2SPeter Wemm# work recipient factor
50906f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
510c2aa98e2SPeter Wemm
511c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
51206f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
513c2aa98e2SPeter Wemm
514c2aa98e2SPeter Wemm# work class factor
51506f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
516c2aa98e2SPeter Wemm
517c2aa98e2SPeter Wemm# work time factor
51806f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
519c2aa98e2SPeter Wemm
520c2aa98e2SPeter Wemm# default character set
521b6bacd31SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
522c2aa98e2SPeter Wemm
52340266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
52406f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
525c2aa98e2SPeter Wemm
526c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
52706f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
528c2aa98e2SPeter Wemm
529c2aa98e2SPeter Wemm# dialup line delay on connection failure
5304e4196cbSGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `0s')
531c2aa98e2SPeter Wemm
532c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
5334e4196cbSGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
534c2aa98e2SPeter Wemm
535c2aa98e2SPeter Wemm# chrooted environment for writing to files
5364e4196cbSGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
537c2aa98e2SPeter Wemm
538c2aa98e2SPeter Wemm# are colons OK in addresses?
53906f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
540c2aa98e2SPeter Wemm
541c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
54206f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
543c2aa98e2SPeter Wemm
544c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
54506f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
546c2aa98e2SPeter Wemm
547c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
54806f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
549c2aa98e2SPeter Wemm
550c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
55106f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
552c2aa98e2SPeter Wemm
553c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
55406f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
555c2aa98e2SPeter Wemm
556c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
55706f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
558c2aa98e2SPeter Wemm
559c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
56006f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
561c2aa98e2SPeter Wemm
562c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
56306f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
564c2aa98e2SPeter Wemm
565c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
56640266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
56706f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
56840266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
56940266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
57040266059SGregory Neil Shapiro')')
571c2aa98e2SPeter Wemm
572c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
57306f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
57406f25ae9SGregory Neil Shapiro
575d0cef73dSGregory Neil Shapiro# issue temporary errors (4xy) instead of permanent errors (5xy)?
576d0cef73dSGregory Neil Shapiro_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
577d0cef73dSGregory Neil Shapiro
57806f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
57906f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
580c2aa98e2SPeter Wemm
581c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
58206f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
583c2aa98e2SPeter Wemm
584c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
585e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
586c2aa98e2SPeter Wemm
58740266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
58840266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
589e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
59040266059SGregory Neil Shapiro
5919bd497b8SGregory Neil Shapiro
592c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
59306f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
594c2aa98e2SPeter Wemm
59506f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
59606f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
59706f25ae9SGregory Neil Shapiro
59806f25ae9SGregory Neil Shapiro# override connection address (for testing)
59906f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
60006f25ae9SGregory Neil Shapiro
60106f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
60206f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
60306f25ae9SGregory Neil Shapiro
60406f25ae9SGregory Neil Shapiro# Control socket for daemon management
60506f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
60606f25ae9SGregory Neil Shapiro
60706f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
608e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
60906f25ae9SGregory Neil Shapiro
61006f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
61106f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
61206f25ae9SGregory Neil Shapiro
61306f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
61406f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
61506f25ae9SGregory Neil Shapiro
61606f25ae9SGregory Neil Shapiro# location of pid file
61706f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
61806f25ae9SGregory Neil Shapiro
61906f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
62006f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
62106f25ae9SGregory Neil Shapiro
62206f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
62306f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
62406f25ae9SGregory Neil Shapiro
62506f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
62606f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
62706f25ae9SGregory Neil Shapiro
62840266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
62940266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
63040266059SGregory Neil Shapiro
631e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
632e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
633e92d3f3fSGregory Neil Shapiro
63406f25ae9SGregory Neil Shapiro# list of authentication mechanisms
63540266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
63606f25ae9SGregory Neil Shapiro
637e92d3f3fSGregory Neil Shapiro# Authentication realm
638e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
639e92d3f3fSGregory Neil Shapiro
64006f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
64106f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
64206f25ae9SGregory Neil Shapiro
64306f25ae9SGregory Neil Shapiro# SMTP AUTH flags
64406f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
64506f25ae9SGregory Neil Shapiro
64640266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
64740266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
64840266059SGregory Neil Shapiro
64940266059SGregory Neil Shapiro# SMTP STARTTLS server options
65040266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
65140266059SGregory Neil Shapiro
652da7d7b9cSGregory Neil Shapiro# SSL cipherlist
653da7d7b9cSGregory Neil Shapiro_OPTION(CipherList, `confCIPHER_LIST', `')
654da7d7b9cSGregory Neil Shapiro# server side SSL options
655da7d7b9cSGregory Neil Shapiro_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `')
656da7d7b9cSGregory Neil Shapiro# client side SSL options
657da7d7b9cSGregory Neil Shapiro_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `')
6585b0945b5SGregory Neil Shapiro# SSL Engine
6595b0945b5SGregory Neil Shapiro_OPTION(SSLEngine, `confSSL_ENGINE', `')
6605b0945b5SGregory Neil Shapiro# Path to dynamic library for SSLEngine
6615b0945b5SGregory Neil Shapiro_OPTION(SSLEnginePath, `confSSL_ENGINE_PATH', `')
6625b0945b5SGregory Neil Shapiro# TLS: fall back to clear text after handshake failure?
6635b0945b5SGregory Neil Shapiro_OPTION(TLSFallbacktoClear, `confTLS_FALLBACK_TO_CLEAR', `')
6649bd497b8SGregory Neil Shapiro
66506f25ae9SGregory Neil Shapiro# Input mail filters
66606f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
66706f25ae9SGregory Neil Shapiro
668739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
66906f25ae9SGregory Neil Shapiro# Milter options
67040266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
67106f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
67206f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
67306f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
674323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
675d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
676d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
677d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
67806f25ae9SGregory Neil Shapiro
67906f25ae9SGregory Neil Shapiro# CA directory
68013bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
68106f25ae9SGregory Neil Shapiro# CA file
68213bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
68306f25ae9SGregory Neil Shapiro# Server Cert
68406f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
68506f25ae9SGregory Neil Shapiro# Server private key
68606f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
68706f25ae9SGregory Neil Shapiro# Client Cert
68806f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
68906f25ae9SGregory Neil Shapiro# Client private key
69006f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
691e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
692e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
6935b0945b5SGregory Neil Shapiro# Directory containing hashes pointing to certificate revocation status files
6945b0945b5SGregory Neil Shapiro_OPTION(CRLPath, `confCRL_PATH', `')
69506f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
69606f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
69706f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
69806f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
699da7d7b9cSGregory Neil Shapiro# fingerprint algorithm (digest) to use for the presented cert
700da7d7b9cSGregory Neil Shapiro_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `')
7015b0945b5SGregory Neil Shapiro# enable DANE?
7025b0945b5SGregory Neil Shapiro_OPTION(DANE, `confDANE', `false')
70306f25ae9SGregory Neil Shapiro
704d0cef73dSGregory Neil Shapiro# Maximum number of "useless" commands before slowing down
705d0cef73dSGregory Neil Shapiro_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
706d0cef73dSGregory Neil Shapiro
707d0cef73dSGregory Neil Shapiro# Name to use for EHLO (defaults to $j)
708d0cef73dSGregory Neil Shapiro_OPTION(HeloName, `confHELO_NAME')
709d0cef73dSGregory Neil Shapiro
710da7d7b9cSGregory Neil Shapiroifdef(`_NEED_SMTPOPMODES_', `dnl
711da7d7b9cSGregory Neil Shapiro# SMTP operation modes
712da7d7b9cSGregory Neil ShapiroC{SMTPOpModes} s d D')
713da7d7b9cSGregory Neil Shapiro
71440266059SGregory Neil Shapiro############################
71540266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
71640266059SGregory Neil Shapiro############################
71740266059SGregory Neil Shapiro_QUEUE_GROUP_
718065a643dSPeter Wemm
719c2aa98e2SPeter Wemm###########################
720c2aa98e2SPeter Wemm#   Message precedences   #
721c2aa98e2SPeter Wemm###########################
722c2aa98e2SPeter Wemm
723c2aa98e2SPeter WemmPfirst-class=0
724c2aa98e2SPeter WemmPspecial-delivery=100
725c2aa98e2SPeter WemmPlist=-30
726c2aa98e2SPeter WemmPbulk=-60
727c2aa98e2SPeter WemmPjunk=-100
728c2aa98e2SPeter Wemm
729c2aa98e2SPeter Wemm#####################
730c2aa98e2SPeter Wemm#   Trusted users   #
731c2aa98e2SPeter Wemm#####################
732c2aa98e2SPeter Wemm
733c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
73406f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
735c2aa98e2SPeter WemmTroot
736c2aa98e2SPeter WemmTdaemon
737c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
738c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
739c2aa98e2SPeter Wemm
740c2aa98e2SPeter Wemm#########################
741c2aa98e2SPeter Wemm#   Format of headers   #
742c2aa98e2SPeter Wemm#########################
743c2aa98e2SPeter Wemm
744c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
745e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
746c2aa98e2SPeter WemmH?P?Return-Path: <$g>
747c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
748c2aa98e2SPeter WemmH?D?Resent-Date: $a
749c2aa98e2SPeter WemmH?D?Date: $a
750c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
751c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
752c2aa98e2SPeter WemmH?x?Full-Name: $x
753c2aa98e2SPeter Wemm# HPosted-Date: $a
754c2aa98e2SPeter Wemm# H?l?Received-Date: $b
755e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
756e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
75706f25ae9SGregory Neil Shapiro
758c2aa98e2SPeter Wemm#
759c2aa98e2SPeter Wemm######################################################################
760c2aa98e2SPeter Wemm######################################################################
761c2aa98e2SPeter Wemm#####
762c2aa98e2SPeter Wemm#####			REWRITING RULES
763c2aa98e2SPeter Wemm#####
764c2aa98e2SPeter Wemm######################################################################
765c2aa98e2SPeter Wemm######################################################################
766c2aa98e2SPeter Wemm
767c2aa98e2SPeter Wemm############################################
768c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
769c2aa98e2SPeter Wemm############################################
77006f25ae9SGregory Neil ShapiroScanonify=3
771c2aa98e2SPeter Wemm
772c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
773c2aa98e2SPeter WemmR$@			$@ <@>
774c2aa98e2SPeter Wemm
775c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
776c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
777c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
778c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
77940266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
780c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
781c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
782c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
783c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
784c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
785c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
786193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
787c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
788c2aa98e2SPeter Wemm
789c2aa98e2SPeter Wemm# null input now results from list:; syntax
790c2aa98e2SPeter WemmR$@			$@ :; <@>
791c2aa98e2SPeter Wemm
792c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
793c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
794c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
795c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
796c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
797c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
798c2aa98e2SPeter Wemm
79906f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
800c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
801c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
802c2aa98e2SPeter Wemm
803c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
80440266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
80540266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
80640266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
80706f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
80806f25ae9SGregory Neil Shapirodnl',`dnl
80906f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
81006f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
81140266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
81240266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
81306f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
81406f25ae9SGregory Neil Shapirodnl')
815c2aa98e2SPeter Wemm
816c2aa98e2SPeter Wemm# find focus for list syntax
81706f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
818c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
819c2aa98e2SPeter Wemm
820c2aa98e2SPeter Wemm# find focus for @ syntax addresses
821c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
822c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
82306f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
824c2aa98e2SPeter Wemm
82540266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
82640266059SGregory Neil Shapirodnl # do some sanity checking
82740266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
828c2aa98e2SPeter Wemm
829c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
830c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
83106f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
83206f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
83306f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
834c2aa98e2SPeter Wemm')
835c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
836c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
83706f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
83806f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
839c2aa98e2SPeter Wemm',
840c2aa98e2SPeter Wemm	`dnl')
841da7d7b9cSGregory Neil Shapiroifdef(`_NO_PERCENTHACK_', `dnl',
842da7d7b9cSGregory Neil Shapiro`# if we have % signs, take the rightmost one
843c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
844c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
845da7d7b9cSGregory Neil Shapiro')
84606f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
847c2aa98e2SPeter Wemm
848c2aa98e2SPeter Wemm# else we must be a local name
84906f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
850c2aa98e2SPeter Wemm
851c2aa98e2SPeter Wemm
852c2aa98e2SPeter Wemm################################################
853c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
854c2aa98e2SPeter Wemm################################################
855c2aa98e2SPeter Wemm
85606f25ae9SGregory Neil ShapiroSCanonify2=96
857c2aa98e2SPeter Wemm
858c2aa98e2SPeter Wemm# handle special cases for local names
859c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
860c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
861c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
862c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
86306f25ae9SGregory Neil Shapiro
86440266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
86540266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
866c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
867c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
868c2aa98e2SPeter Wemm
86906f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
870c2aa98e2SPeter Wemm# look up domains in the domain table
871c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
872c2aa98e2SPeter Wemm
87306f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
874c2aa98e2SPeter Wemm
87506f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
876c2aa98e2SPeter Wemm# handle BITNET mapping
877c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
878c2aa98e2SPeter Wemm
87906f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
880c2aa98e2SPeter Wemm# handle UUCP mapping
881c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
882c2aa98e2SPeter Wemm
883c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
884c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
885c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
886c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
887c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
888c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
889c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
890c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
891c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
892c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
893c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
894c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
895c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
896c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
897c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
898c2aa98e2SPeter Wemm
899c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
900c2aa98e2SPeter Wemm# try UUCP traffic as a local address
901c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
902c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
903c2aa98e2SPeter Wemm')')
90406f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
90506f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
90606f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
90706f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
90806f25ae9SGregory Neil Shapirodnl which daemon flags are set?
90906f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
91006f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
91106f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
91206f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
91306f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
91406f25ae9SGregory Neil Shapirodnl do not canonify unless:
91506f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
91606f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
91706f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
91806f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
91906f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
92006f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
92106f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
92206f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
92306f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
92406f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
92506f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
92606f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
92706f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
92806f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
92906f25ae9SGregory Neil Shapirodnl then $- does not work.
93006f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
93106f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
93206f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
93306f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
934193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
935193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
936193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
93706f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
93840266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
93940266059SGregory Neil Shapiro# do not canonify header addresses
94040266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
94140266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
94240266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
943c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
94406f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
94506f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
94606f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
947c2aa98e2SPeter Wemm
948c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
949c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
950c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
951c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
952c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
95306f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
95406f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
95506f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
95606f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
95706f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
95806f25ae9SGregory Neil Shapiro`dnl')
95940266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
96040266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
96140266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
96240266059SGregory Neil Shapiro`R$* < @ $* $=G > $* 	$: $1 < @ $2 $3 . > $4',
96340266059SGregory Neil Shapiro`R$* < @ $=G > $* 	$: $1 < @ $2 . > $3')',
96440266059SGregory Neil Shapiro`dnl')
96506f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
96606f25ae9SGregory Neil Shapirodnl by one of the rules before
967c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
968c2aa98e2SPeter Wemm
969c2aa98e2SPeter Wemm
970c2aa98e2SPeter Wemm##################################################
971c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
972c2aa98e2SPeter Wemm##################################################
97306f25ae9SGregory Neil ShapiroSfinal=4
974c2aa98e2SPeter Wemm
975193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
976c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
977c2aa98e2SPeter Wemm
978c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
979c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
980c2aa98e2SPeter Wemm
98106f25ae9SGregory Neil Shapiro# eliminate internal code
982c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
983c2aa98e2SPeter Wemm
984c2aa98e2SPeter Wemm# externalize local domain info
985c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
986c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
987c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
988c2aa98e2SPeter Wemm
989c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
990c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
991c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
992c2aa98e2SPeter Wemm
993c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
994c2aa98e2SPeter Wemm`# put DECnet back in :: form
995c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
996c2aa98e2SPeter Wemm	`dnl')
997c2aa98e2SPeter Wemm# delete duplicate local names
998c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
999c2aa98e2SPeter Wemm
1000c2aa98e2SPeter Wemm
1001c2aa98e2SPeter Wemm
1002c2aa98e2SPeter Wemm##############################################################
1003c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
1004c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
1005c2aa98e2SPeter Wemm##############################################################
1006c2aa98e2SPeter Wemm
100706f25ae9SGregory Neil ShapiroSRecurse=97
100806f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
100906f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
1010c2aa98e2SPeter Wemm
1011c2aa98e2SPeter Wemm
1012c2aa98e2SPeter Wemm######################################
1013c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
1014c2aa98e2SPeter Wemm######################################
1015c2aa98e2SPeter Wemm
101606f25ae9SGregory Neil ShapiroSparse=0
1017c2aa98e2SPeter Wemm
1018c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
1019c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
102006f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
1021c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
1022c2aa98e2SPeter Wemm
1023c2aa98e2SPeter Wemm#
1024c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
1025c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
1026c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
1027c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
1028c2aa98e2SPeter Wemm#
1029c2aa98e2SPeter Wemm
1030c2aa98e2SPeter WemmSParse0
1031c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
103240266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
103306f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
103440266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
103540266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
1036c2aa98e2SPeter WemmR$*			$: <> $1
103740266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
103840266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
103940266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
104040266059SGregory Neil Shapirodnl but no a@[b]c
104140266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
1042c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
104340266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1044c2aa98e2SPeter WemmR<> $*			$1
104540266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
104640266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
104740266059SGregory Neil Shapirodnl no a@b@
104840266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
104940266059SGregory Neil Shapirodnl no a@b@c
105040266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
105106f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
105240266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
105340266059SGregory Neil Shapiro
105440266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
105540266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
105640266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
105740266059SGregory Neil Shapirodnl', `dnl')
1058c2aa98e2SPeter Wemm
1059c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
106006f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
106106f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1062c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
106340266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
106406f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1065c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
106640266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1067c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
106806f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1069c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1070c2aa98e2SPeter Wemm
1071da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1072da7d7b9cSGregory Neil ShapiroR$+			$: $>ParseBcc $1', `dnl')
1073da7d7b9cSGregory Neil Shapiroifdef(`_PREFIX_MOD_', `dnl
1074da7d7b9cSGregory Neil Shapirodnl do this only for addr_type=e r?
1075da7d7b9cSGregory Neil ShapiroR _PREFIX_MOD_ $+	$: $1 $(macro {rcpt_flags} $@ _PREFIX_FLAGS_ $)
1076da7d7b9cSGregory Neil Shapiro')dnl
1077da7d7b9cSGregory Neil Shapiro
1078c2aa98e2SPeter Wemm#
1079c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1080c2aa98e2SPeter Wemm#
1081c2aa98e2SPeter Wemm
1082c2aa98e2SPeter WemmSParse1
108306f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
108406f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
108540266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
108640266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1087c2aa98e2SPeter Wemm`dnl')
1088c2aa98e2SPeter Wemm
108906f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
109006f25ae9SGregory Neil Shapiro`# handle numeric address spec
109106f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
109206f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
10935ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
109406f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
109506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
109606f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
109706f25ae9SGregory Neil Shapiro	`dnl')
109806f25ae9SGregory Neil Shapiro
109906f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1100c2aa98e2SPeter Wemm# handle virtual users
110140266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
110240266059SGregory Neil Shapirodnl this is not a documented option
110340266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
110440266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
110540266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
110640266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
110740266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
110840266059SGregory Neil ShapiroR$+ < @ $+ > 			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
110940266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
111040266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
111140266059SGregory Neil Shapiro`dnl')
111206f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
111340266059SGregory Neil Shapirodnl input: <!> local<@domain>
111406f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
111506f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
111606f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
111740266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
111806f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
111940266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
112040266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
112140266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
112240266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
112340266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1124c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
112540266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
112640266059SGregory Neil Shapirodnl user+detail: try user@domain
1127c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
112840266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
112906f25ae9SGregory Neil Shapirodnl try default entry: @domain
113040266059SGregory Neil Shapirodnl ++@domain
113140266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113206f25ae9SGregory Neil Shapirodnl +*@domain
113340266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113406f25ae9SGregory Neil Shapirodnl @domain if +detail exists
113594c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
113694c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
113794c01205SGregory Neil Shapirodnl without +detail
1138c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
113940266059SGregory Neil Shapirodnl no match
1140c2aa98e2SPeter WemmR<@> $+			$: $1
114140266059SGregory Neil Shapirodnl remove mark
114206f25ae9SGregory Neil ShapiroR<!> $+			$: $1
114306f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1144c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
114540266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
114640266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
114740266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
114840266059SGregory Neil Shapiro# it is the same: stop now
114940266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
115040266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $* 			$: < $1 > $2 < @ $3 >
115140266059SGregory Neil Shapirodnl', `dnl')
115213058a91SGregory Neil Shapirodnl this is not a documented option
115313058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11548774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11558774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11568774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11578774250cSGregory Neil Shapirodnl', `dnl')
1158c2aa98e2SPeter Wemm
1159c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1160c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
116106f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
116242e5d165SGregory Neil Shapiro
116342e5d165SGregory Neil Shapiro
1164c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1165c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
116606f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
116706f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1168c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1169c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1170c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1171c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1172c2aa98e2SPeter Wemm
117306f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1174c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1175c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1176c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1177c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
117806f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
117906f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
118006f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1181c2aa98e2SPeter Wemm`dnl')
118206f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1183c2aa98e2SPeter Wemm
1184c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1185c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1186c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
118706f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1188c2aa98e2SPeter Wemm	`dnl')
1189c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
119006f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1191c2aa98e2SPeter Wemm	`dnl')
1192c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
119306f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1194c2aa98e2SPeter Wemm	`dnl')')
1195c2aa98e2SPeter Wemm
1196c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1197c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
119806f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1199c2aa98e2SPeter Wemm	`dnl')
1200c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
120106f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1202c2aa98e2SPeter Wemm	`dnl')
1203c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1204c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1205c2aa98e2SPeter Wemm	`dnl')
1206c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1207c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1208c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
120906f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1210c2aa98e2SPeter Wemm	`dnl')')
1211c2aa98e2SPeter Wemm
1212c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1213c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
121406f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1215c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1216c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1217c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1218c2aa98e2SPeter Wemm	`dnl')')
1219c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1220c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
122106f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1222c2aa98e2SPeter Wemm	`dnl')
1223c2aa98e2SPeter Wemm
1224c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1225c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1226c2aa98e2SPeter Wemmundivert(1)', `dnl')
1227c2aa98e2SPeter Wemm
1228c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
122906f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1230c2aa98e2SPeter Wemm
1231c2aa98e2SPeter Wemm# deal with other remote names
1232c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1233c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
123440266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1235c2aa98e2SPeter Wemm
1236c2aa98e2SPeter Wemm# handle locally delivered names
1237c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1238c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1239c2aa98e2SPeter Wemm
1240da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1241da7d7b9cSGregory Neil ShapiroSParseBcc
1242da7d7b9cSGregory Neil ShapiroR$+			$: $&{addr_type} $| $&A $| $1
1243da7d7b9cSGregory Neil ShapiroRe b $| $+ $| $+	$>MailerToTriple < $1 > $2	copy?
1244da7d7b9cSGregory Neil ShapiroR$* $| $* $| $+		$@ $3				no copy
1245da7d7b9cSGregory Neil Shapiro')
1246da7d7b9cSGregory Neil Shapiro
1247c2aa98e2SPeter Wemm###########################################################################
1248c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1249c2aa98e2SPeter Wemm###########################################################################
1250c2aa98e2SPeter Wemm
125106f25ae9SGregory Neil ShapiroSLocal_localaddr
125206f25ae9SGregory Neil ShapiroSlocaladdr=5
125306f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
125440266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
125506f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
125606f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1257c2aa98e2SPeter Wemm
125840266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
125940266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
126040266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
126140266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
126240266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
126340266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12646a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
126540266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
126640266059SGregory Neil Shapiro')dnl
126740266059SGregory Neil Shapiro
126840266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
126942e5d165SGregory Neil Shapiro# Preserve host in a macro
127042e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
127142e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1272c2aa98e2SPeter Wemm
127340266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
127442e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
127542e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
127642e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
127742e5d165SGregory Neil Shapiro')
1278c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1279c2aa98e2SPeter WemmR$+			$: <> $1
1280c2aa98e2SPeter Wemm
1281c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1282c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
128340266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
128442e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
128542e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
128642e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
128742e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
128806f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
128940266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
129040266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
129140266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
129240266059SGregory Neil Shapirodnl')
1293c2aa98e2SPeter Wemm
129440266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
129540266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
129640266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
129740266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
129840266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
129940266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
130006f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
130140266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
130240266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
130306f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
130406f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1305c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
130642e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1307c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
13082e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
130940266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
131040266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
13112e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
131242e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
131306f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
131406f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
131540266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
131640266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
131740266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
131840266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
131940266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
132040266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
132106f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1322c2aa98e2SPeter Wemm
132306f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
132440266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
132540266059SGregory Neil Shapiro###################################################################
132640266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
132740266059SGregory Neil Shapirodnl input: <Domain> FullAddress
132840266059SGregory Neil Shapiro###################################################################
132940266059SGregory Neil Shapiro
133040266059SGregory Neil ShapiroSLDAPMailertable
133140266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
133240266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
133340266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
133440266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
133540266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
133640266059SGregory Neil Shapiro`dnl')
133740266059SGregory Neil Shapiro
1338c2aa98e2SPeter Wemm###################################################################
1339c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
134006f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1341c2aa98e2SPeter Wemm###################################################################
1342c2aa98e2SPeter Wemm
134306f25ae9SGregory Neil ShapiroSMailertable=90
134406f25ae9SGregory Neil Shapirodnl shift and check
134506f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1346c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
134706f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
134806f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
134906f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
135006f25ae9SGregory Neil Shapirodnl is $2 always empty?
1351c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
135206f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
135306f25ae9SGregory Neil Shapirodnl return full address
1354c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1355c2aa98e2SPeter Wemm`dnl')
1356c2aa98e2SPeter Wemm
1357c2aa98e2SPeter Wemm###################################################################
1358c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
135906f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
136006f25ae9SGregory Neil Shapirodnl	<> address				-> address
136106f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1362a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
136306f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
136406f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
136506f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
136606f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
136706f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1368c2aa98e2SPeter Wemm###################################################################
1369c2aa98e2SPeter Wemm
137006f25ae9SGregory Neil ShapiroSMailerToTriple=95
1371c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
137206f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1373a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1374a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1375c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
137640266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
137740266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
137840266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1379c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1380c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1381c2aa98e2SPeter Wemm
1382c2aa98e2SPeter Wemm###################################################################
1383c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
138406f25ae9SGregory Neil Shapirodnl input: <user> address
138506f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
138606f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
138706f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
138806f25ae9SGregory Neil Shapirodnl <> user				-> local user user
138906f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
139006f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
139106f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1392c2aa98e2SPeter Wemm###################################################################
1393c2aa98e2SPeter Wemm
1394c2aa98e2SPeter WemmSCanonLocal
13952e43090eSPeter Wemm# strip local host from routed addresses
139606f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
139706f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
13982e43090eSPeter Wemm
1399c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1400c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1401c2aa98e2SPeter Wemm
1402c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1403c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1404c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1405c2aa98e2SPeter Wemm
1406c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1407c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1408c2aa98e2SPeter Wemm
1409c2aa98e2SPeter Wemm# handle local:user syntax
1410c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1411c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1412c2aa98e2SPeter Wemm
1413c2aa98e2SPeter Wemm###################################################################
1414c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1415c2aa98e2SPeter Wemm###################################################################
1416c2aa98e2SPeter Wemm
141706f25ae9SGregory Neil ShapiroSMasqHdr=93
1418c2aa98e2SPeter Wemm
141906f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1420c2aa98e2SPeter Wemm# handle generics database
1421c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
142206f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1423c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1424c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1425c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
142606f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
142706f25ae9SGregory Neil Shapirodnl ignore the first case for now
142806f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
142940266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
143006f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
143106f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
143206f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
143306f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
143406f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
143506f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
143606f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
143706f25ae9SGregory Neil Shapirodnl no match, remove mark
143806f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
143906f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
144006f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
144106f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
144206f25ae9SGregory Neil Shapirodnl no match, try local part
1443c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
144406f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
144506f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
144606f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
144706f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1448c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1449c2aa98e2SPeter Wemm`dnl')
1450c2aa98e2SPeter Wemm
145106f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
145206f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
145306f25ae9SGregory Neil Shapiro
145440266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1455c2aa98e2SPeter Wemm# special case the users that should be exposed
1456c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1457c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1458c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1459c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1460c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1461c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1462c2aa98e2SPeter Wemm
1463c2aa98e2SPeter Wemm# handle domain-specific masquerading
1464c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1465c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1466c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1467c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1468c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1469c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1470c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1471c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
147240266059SGregory Neil Shapirodnl', `dnl no masquerading
147340266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
147440266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1475c2aa98e2SPeter Wemm
1476c2aa98e2SPeter Wemm###################################################################
1477c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1478c2aa98e2SPeter Wemm###################################################################
1479c2aa98e2SPeter Wemm
148006f25ae9SGregory Neil ShapiroSMasqEnv=94
1481c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
148206f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1483c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1484c2aa98e2SPeter Wemm
1485c2aa98e2SPeter Wemm###################################################################
1486c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1487c2aa98e2SPeter Wemm###################################################################
1488c2aa98e2SPeter Wemm
148906f25ae9SGregory Neil ShapiroSParseLocal=98
149006f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1491c2aa98e2SPeter Wemm
149206f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
149340266059SGregory Neil Shapiro######################################################################
149440266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
149540266059SGregory Neil Shapiro###
149640266059SGregory Neil Shapiro###	Parameters:
149740266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
149840266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
149940266059SGregory Neil Shapiro###		<$3> -- +detail information
150040266059SGregory Neil Shapiro###
150140266059SGregory Neil Shapiro###	Returns:
150240266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
150340266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
150440266059SGregory Neil Shapiro######################################################################
150540266059SGregory Neil Shapiro
150606f25ae9SGregory Neil ShapiroSLDAPExpand
150706f25ae9SGregory Neil Shapiro# do the LDAP lookups
150840266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
150906f25ae9SGregory Neil Shapiro
1510e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1511e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1512e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1513e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1514e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
15155b0945b5SGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: _TMPFMSG_(`OPM')')
1516e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1517e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1518605302a5SGregory Neil Shapiro
151906f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
152006f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
152140266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
152240266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
152340266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
152440266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
152540266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
152606f25ae9SGregory Neil Shapiro
152794c01205SGregory Neil Shapiro
152806f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
152906f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
153040266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
153140266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
153240266059SGregory Neil Shapiro# check mailertable for host, relay from there
153340266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
153440266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
153540266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
153640266059SGregory Neil Shapiro# check mailertable for host, relay from there
153740266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
153840266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
153906f25ae9SGregory Neil Shapiro
154006f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
154106f25ae9SGregory Neil Shapiro# return original address
154240266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
154306f25ae9SGregory Neil Shapiro
154494c01205SGregory Neil Shapiro
154506f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
154606f25ae9SGregory Neil Shapiro# relay to mailHost with original address
154740266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
154840266059SGregory Neil Shapiro# check mailertable for host, relay from there
154940266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
155040266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
155106f25ae9SGregory Neil Shapiro
155240266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
155340266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
155440266059SGregory Neil Shapiro# try without +detail
155540266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
155640266059SGregory Neil Shapiro
15579bd497b8SGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `
15589bd497b8SGregory Neil Shapiro# pretend we did the @domain lookup
15599bd497b8SGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
156040266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
156106f25ae9SGregory Neil Shapiro# try @domain
156240266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
156340266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1564e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
156506f25ae9SGregory Neil Shapiro
156606f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
156706f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
156806f25ae9SGregory Neil Shapiro# user does not exist
156940266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
157040266059SGregory Neil Shapiro# only give error for envelope recipient
157140266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1572e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1573e92d3f3fSGregory Neil Shapiro# and the sender too
1574e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
157540266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
157606f25ae9SGregory Neil Shapiro`dnl
157706f25ae9SGregory Neil Shapiro# return the original address
1578ba00ec3dSGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')
1579ba00ec3dSGregory Neil Shapiro')
1580ba00ec3dSGregory Neil Shapiro
158106f25ae9SGregory Neil Shapiro
158206f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
158306f25ae9SGregory Neil Shapiro')')
158440266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1585c2aa98e2SPeter Wemm######################################################################
158640266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1587c2aa98e2SPeter Wemm###
1588c2aa98e2SPeter Wemm###	Parameters:
1589c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1590c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
159106f25ae9SGregory Neil Shapirodnl			must not be empty
159240266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
159306f25ae9SGregory Neil Shapiro###			! does lookup only with tag
159406f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
159540266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
159606f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
159706f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1598c2aa98e2SPeter Wemm######################################################################
1599c2aa98e2SPeter Wemm
160040266059SGregory Neil ShapiroSD
160106f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
160206f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
160340266059SGregory Neil Shapirodnl    2    3  4    5
160440266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
160506f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
160606f25ae9SGregory Neil Shapirodnl lookup without tag?
160740266059SGregory Neil Shapirodnl   1    2      3    4
160840266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
160940266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
161040266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
161140266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
161240266059SGregory Neil Shapirodnl   1  2    3    4  5    6
161340266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
161440266059SGregory Neil Shapirodnl   1  2    3      4    5
161540266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
161640266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
161740266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
161840266059SGregory Neil Shapirodnl      1    2    3  4    5
161940266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
162040266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
162140266059SGregory Neil Shapirodnl    1  2     3    4  5    6
162240266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
162340266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
162440266059SGregory Neil Shapiro`dnl not found: IPv6 net
162540266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
162640266059SGregory Neil Shapirodnl    1   2     3    4  5    6
162740266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
162840266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
162906f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
163040266059SGregory Neil Shapirodnl   1  2    3    4  5    6
163140266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
163240266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
163340266059SGregory Neil Shapirodnl   1    2      3    4
163440266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
163540266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
163640266059SGregory Neil Shapirodnl   1    2    3  4    5
163740266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
163840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
163940266059SGregory Neil Shapirodnl            2    3    4  5    6
164040266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
164140266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
164240266059SGregory Neil Shapirodnl    2    3    4  5    6
164340266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1644c2aa98e2SPeter Wemm
1645c2aa98e2SPeter Wemm######################################################################
164640266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1647c2aa98e2SPeter Wemm###
1648c2aa98e2SPeter Wemm###	Parameters:
1649c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1650c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
165106f25ae9SGregory Neil Shapirodnl			must not be empty
165240266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
165306f25ae9SGregory Neil Shapiro###			! does lookup only with tag
165406f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
165540266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
165606f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
165706f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1658c2aa98e2SPeter Wemm######################################################################
1659c2aa98e2SPeter Wemm
166040266059SGregory Neil ShapiroSA
166106f25ae9SGregory Neil Shapirodnl lookup with tag
166240266059SGregory Neil Shapirodnl    2    3  4    5
166340266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
166406f25ae9SGregory Neil Shapirodnl lookup without tag
166540266059SGregory Neil Shapirodnl   1    2      3    4
166640266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
166740266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
166840266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
166940266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
167040266059SGregory Neil Shapirodnl      1    2    3  4    5
167140266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
167240266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
167340266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
167440266059SGregory Neil Shapirodnl   1   2    3    4  5    6
167540266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
167640266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
167706f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
167840266059SGregory Neil Shapirodnl   1  2    3    4  5    6
167940266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
168006f25ae9SGregory Neil Shapirodnl no match: return default
168140266059SGregory Neil Shapirodnl   1    2    3  4    5
168240266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
168340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
168440266059SGregory Neil Shapirodnl            2    3    4  5    6
168540266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
168606f25ae9SGregory Neil Shapirodnl match: return result
168740266059SGregory Neil Shapirodnl    2    3    4  5    6
168840266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
168940266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
169040266059SGregory Neil Shapirodivert(0)
1691c2aa98e2SPeter Wemm######################################################################
1692065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1693065a643dSPeter Wemm###			relay checking.  Route address syntax is
1694065a643dSPeter Wemm###			crudely converted into a %-hack address.
1695065a643dSPeter Wemm###
1696065a643dSPeter Wemm###	Parameters:
1697065a643dSPeter Wemm###		$1 -- full recipient address
1698065a643dSPeter Wemm###
1699065a643dSPeter Wemm###	Returns:
1700065a643dSPeter Wemm###		parsed address, not in source route form
170106f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
170206f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1703065a643dSPeter Wemm######################################################################
1704065a643dSPeter Wemm
1705065a643dSPeter WemmSCanonAddr
170606f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
170706f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1708065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1709065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1710065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
171106f25ae9SGregory Neil Shapirodnl')
1712065a643dSPeter Wemm
1713065a643dSPeter Wemm######################################################################
1714c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1715c2aa98e2SPeter Wemm###			$* $=m or the access database.
1716c2aa98e2SPeter Wemm###			Check user portion for host separators.
1717c2aa98e2SPeter Wemm###
1718c2aa98e2SPeter Wemm###	Parameters:
1719c2aa98e2SPeter Wemm###		$1 -- full recipient address
1720c2aa98e2SPeter Wemm###
1721c2aa98e2SPeter Wemm###	Returns:
1722c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1723c2aa98e2SPeter Wemm######################################################################
1724c2aa98e2SPeter Wemm
1725c2aa98e2SPeter WemmSParseRecipient
172606f25ae9SGregory Neil Shapirodnl mark and canonify address
1727065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
172806f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1729c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
173006f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1731c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1732c2aa98e2SPeter Wemm
1733c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1734c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
173506f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1736c2aa98e2SPeter WemmR<?> $*				$@ $1
1737c2aa98e2SPeter Wemm
173840266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
173906f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1740c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1741c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1742c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
174306f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
174406f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
174540266059SGregory Neil Shapiro
174640266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
174740266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
17485b0945b5SGregory Neil Shapirodnl other To: entries: blocklist recipient; generic entries?
174940266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1750c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1751c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
175206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
175306f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1754065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1755c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
175606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
175740266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1758c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1759065a643dSPeter Wemm
176006f25ae9SGregory Neil Shapiro
176140266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
176240266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
176340266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1764e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
176540266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
176640266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
176740266059SGregory Neil Shapirodnl no: put old <NO> mark back
176840266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
176940266059SGregory Neil Shapiro
177040266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1771c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
177240266059SGregory Neil Shapirodnl something else
177340266059SGregory Neil ShapiroR<$+> $*			$@ $2
1774c2aa98e2SPeter Wemm
177506f25ae9SGregory Neil Shapiro
1776c2aa98e2SPeter Wemm######################################################################
1777c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1778c2aa98e2SPeter Wemm######################################################################
1779c2aa98e2SPeter Wemm
1780e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1781e92d3f3fSGregory Neil ShapiroScheck_relay
1782e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1783e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1784e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1785e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1786e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1787e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1788e92d3f3fSGregory Neil Shapirodnl')
1789e92d3f3fSGregory Neil Shapiro
1790c2aa98e2SPeter WemmSLocal_check_relay
179106f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1792e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1793e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1794c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1795c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1796c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1797c2aa98e2SPeter Wemm
1798c2aa98e2SPeter WemmSBasic_check_relay
1799c2aa98e2SPeter Wemm# check for deferred delivery mode
180094c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1801c2aa98e2SPeter WemmR< d > $*		$@ deferred
1802c2aa98e2SPeter WemmR< $* > $*		$: $2
1803c2aa98e2SPeter Wemm
180406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
180542e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
180640266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
180742e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
180813bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
180913bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
181013bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
181140266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
181240266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
181340266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
181440266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
181542e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1816e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
181740266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1818e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
181906f25ae9SGregory Neil Shapirodnl error tag
182042e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
182142e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
18225b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: _TMPFMSG_(`CR')', `dnl')
182306f25ae9SGregory Neil Shapirodnl generic error from access map
182442e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1825c2aa98e2SPeter Wemm
1826c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
182706f25ae9SGregory Neil Shapiro# DNS based IP address spam list
182840266059SGregory Neil Shapirodnl workspace: ignored...
1829c2aa98e2SPeter WemmR$*			$: $&{client_addr}
183006f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
183106f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
183294c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1833c2aa98e2SPeter Wemm`dnl')
1834e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1835e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1836e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1837e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1838e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1839e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1840e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1841e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
18426f9c8e5bSGregory Neil Shapiroundivert(8)dnl LOCAL_DNSBL
1843d0cef73dSGregory Neil Shapiroifdef(`_REQUIRE_RDNS_', `dnl
1844d0cef73dSGregory Neil ShapiroR$*			$: $&{client_addr} $| $&{client_resolve}
1845d0cef73dSGregory Neil ShapiroR$=R $*			$@ RELAY		We relay for these
1846d0cef73dSGregory Neil ShapiroR$* $| OK		$@ OK			Resolves.
1847d0cef73dSGregory Neil ShapiroR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1848d0cef73dSGregory Neil ShapiroR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1849d0cef73dSGregory Neil ShapiroR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1850d0cef73dSGregory Neil Shapiro', `dnl')
1851c2aa98e2SPeter Wemm
1852c2aa98e2SPeter Wemm######################################################################
1853c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1854c2aa98e2SPeter Wemm######################################################################
1855c2aa98e2SPeter Wemm
1856c2aa98e2SPeter WemmSLocal_check_mail
185706f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1858c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1859c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1860c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1861c2aa98e2SPeter Wemm
1862c2aa98e2SPeter WemmSBasic_check_mail
1863c2aa98e2SPeter Wemm# check for deferred delivery mode
186494c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1865c2aa98e2SPeter WemmR< d > $*		$@ deferred
1866c2aa98e2SPeter WemmR< $* > $*		$: $2
1867c2aa98e2SPeter Wemm
186806f25ae9SGregory Neil Shapiro# authenticated?
186906f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
187006f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
187106f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
187206f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
187306f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
187406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
187506f25ae9SGregory Neil Shapiro
187606f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
187706f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
187806f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
187906f25ae9SGregory Neil Shapirodnl do some additional checks
188006f25ae9SGregory Neil Shapirodnl no user@host
188106f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
188206f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
188306f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
188406f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
188506f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
188606f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
188706f25ae9SGregory Neil ShapiroR$+			$: <?> $1
188806f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
188906f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
189006f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
189106f25ae9SGregory Neil Shapirodnl prepend daemon_flags
189206f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
189306f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
189406f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
189506f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
189606f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
189706f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
189806f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
189906f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
190006f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
190106f25ae9SGregory Neil Shapirodnl remove daemon_flags
190206f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
190306f25ae9SGregory Neil Shapiro# handle case of @localhost on address
190406f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
190506f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
190606f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
1907da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] >
1908da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] >
1909da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:::1] >
1910da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:::1] >
191106f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
191206f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
191306f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
191406f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
191506f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
191606f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
191706f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
191806f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
191906f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
192006f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
192106f25ae9SGregory Neil Shapirodnl	or:    <address>
192206f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
192306f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
192440266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
192506f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
192606f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
192706f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
192806f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
192906f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
193006f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1931065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1932c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1933959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
193406f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
193594c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1936959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1937c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
193840266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
193906f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
194006f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
194106f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
194240266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
194306f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1944c2aa98e2SPeter Wemm
194506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
194606f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
194706f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
194840266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
194940266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
195006f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
195106f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
195206f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
195306f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
195406f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
195506f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
195606f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
195706f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1958c2aa98e2SPeter Wemm# retransform for further use
195906f25ae9SGregory Neil Shapirodnl required form:
196006f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
196106f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
196206f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
196306f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
196406f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1965c2aa98e2SPeter Wemm
1966c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1967c2aa98e2SPeter Wemm# handle case of no @domain on address
196806f25ae9SGregory Neil Shapirodnl prepend daemon_flags
196906f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
197006f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
197140266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
197206f25ae9SGregory Neil Shapirodnl remove daemon_flags
197306f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
197413bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1975959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
197640266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1977c2aa98e2SPeter Wemm							...remote is not')
1978c2aa98e2SPeter Wemm# check results
197906f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1980d0cef73dSGregory Neil ShapiroR<$={ResOk}> $*		$: @ $2		domain ok
198106f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
198240266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
198306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
198440266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1985c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
1986e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
1987e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
198806f25ae9SGregory Neil Shapirodnl error tag
198906f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
199006f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
19915b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`CM')', `dnl')
199206f25ae9SGregory Neil Shapirodnl generic error from access map
199306f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1994c2aa98e2SPeter Wemm`dnl')
1995d0cef73dSGregory Neil Shapirodnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
1996d0cef73dSGregory Neil Shapiro
1997d0cef73dSGregory Neil Shapiroifdef(`_BADMX_CHK_', `dnl
1998d0cef73dSGregory Neil ShapiroR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
1999d0cef73dSGregory Neil ShapiroR$* $| $#$*		$#$2
2000d0cef73dSGregory Neil Shapiro
2001d0cef73dSGregory Neil ShapiroSBadMX
2002d0cef73dSGregory Neil Shapiro# Look up MX records and ferret away a copy of the original address.
2003d0cef73dSGregory Neil Shapiro# input: domain part of address to check
2004d0cef73dSGregory Neil ShapiroR$+				$:<MX><$1><:$(mxlist $1$):><:>
2005d0cef73dSGregory Neil Shapiro# workspace: <MX><domain><: mxlist-result $><:>
2006d0cef73dSGregory Neil ShapiroR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
2007d0cef73dSGregory Neil Shapiro# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
2008d0cef73dSGregory Neil Shapiro# Recursively run badmx check on each mx.
2009d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
2010d0cef73dSGregory Neil Shapiro# See if any of them fail.
2011e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
2012d0cef73dSGregory Neil Shapiro# Reverse the mxlists so we can use the same argument order again.
2013d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2014d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
2015d0cef73dSGregory Neil Shapiro
2016d0cef73dSGregory Neil Shapiro# Reverse the lists so we can use the same argument order again.
2017d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2018d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
2019d0cef73dSGregory Neil Shapiro
2020e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
2021d0cef73dSGregory Neil Shapiro`dnl')
2022d0cef73dSGregory Neil Shapiro
2023c2aa98e2SPeter Wemm
2024c2aa98e2SPeter Wemm######################################################################
2025c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
2026c2aa98e2SPeter Wemm######################################################################
2027c2aa98e2SPeter Wemm
2028c2aa98e2SPeter WemmSLocal_check_rcpt
202906f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
2030c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
2031c2aa98e2SPeter WemmR$* $| $#$*		$#$2
2032c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
2033c2aa98e2SPeter Wemm
2034c2aa98e2SPeter WemmSBasic_check_rcpt
203540266059SGregory Neil Shapiro# empty address?
203640266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
203740266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
2038c2aa98e2SPeter Wemm# check for deferred delivery mode
203994c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
2040c2aa98e2SPeter WemmR< d > $*		$@ deferred
2041c2aa98e2SPeter WemmR< $* > $*		$: $2
2042c2aa98e2SPeter Wemm
204306f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
204440266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
204540266059SGregory Neil Shapirodnl it is not activated.
204640266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
204740266059SGregory Neil Shapirodnl available down below; look for the same macro.
204840266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
204940266059SGregory Neil Shapirodnl canonicalization.
205040266059SGregory Neil Shapiro# require fully qualified domain part?
205140266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
205206f25ae9SGregory Neil ShapiroR$+			$: <?> $1
205306f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
205406f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
205540266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
205613bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
205706f25ae9SGregory Neil Shapirodnl prepend daemon_flags
205840266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
205906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
2060af9557fdSGregory Neil Shapirodnl _r_equire qual.rcpt: ok
2061a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
206206f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
2063a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
206406f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
206506f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
206640266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
206706f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
206806f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
206906f25ae9SGregory Neil Shapiro
207040266059SGregory Neil Shapirodnl ##################################################################
207140266059SGregory Neil Shapirodnl call subroutines for recipient and relay
207240266059SGregory Neil Shapirodnl possible returns from subroutines:
207340266059SGregory Neil Shapirodnl $#TEMP	temporary failure
207440266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
207540266059SGregory Neil Shapirodnl $#other	stop processing
207640266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
207740266059SGregory Neil Shapirodnl other	otherwise
207840266059SGregory Neil Shapiro######################################################################
207940266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
208040266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
208140266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
208240266059SGregory Neil Shapirodnl error or ok (stop)
208340266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
208440266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
208540266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
208640266059SGregory Neil Shapirodnl something else: call check sender (relay)
208740266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
208840266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
208940266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
209040266059SGregory Neil Shapirodnl temporary failure? return that
209140266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
209240266059SGregory Neil Shapirodnl error or ok (stop)
209340266059SGregory Neil ShapiroR$* $| $#$*		$#$2
209440266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
209540266059SGregory Neil Shapirodnl something else: return previous temp failure
209640266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
209740266059SGregory Neil Shapiro# anything else is bogus
209840266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
209940266059SGregory Neil Shapirodivert(0)
210040266059SGregory Neil Shapiro
210140266059SGregory Neil Shapiro######################################################################
210240266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
210340266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
210440266059SGregory Neil Shapirodnl output: see explanation at call
210540266059SGregory Neil Shapiro######################################################################
210640266059SGregory Neil ShapiroSRcpt_ok
2107c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2108065a643dSPeter WemmR$*			$: $>CanonAddr $1
2109c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2110c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2111c2aa98e2SPeter Wemm
2112065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2113065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2114065a643dSPeter Wemm# unlimited bestmx
2115065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2116065a643dSPeter Wemm`dnl
2117065a643dSPeter Wemm# limit bestmx to $=B
21182e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
211940266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2120065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2121065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2122065a643dSPeter Wemm
21235b0945b5SGregory Neil Shapiroifdef(`_BLOCKLIST_RCPT_',`dnl
212406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21255b0945b5SGregory Neil Shapiro# blocklist local users or any host from receiving mail
2126c2aa98e2SPeter WemmR$*			$: <?> $1
212706f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
212806f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
212940266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
213040266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
213106f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
213206f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
213306f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
213406f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
213506f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
213606f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
213740266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
213840266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
213940266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
214040266059SGregory Neil Shapirodnl that would make a lot of things easier.
214106f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
214240266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
214340266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
214440266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
214540266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
214606f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
214706f25ae9SGregory Neil Shapirodnl as generic error message...
214806f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
214906f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
215006f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
215106f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
215240266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
215306f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2154e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
215506f25ae9SGregory Neil Shapirodnl error tag
215606f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
215706f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
21585b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`ROK1')', `dnl')
215906f25ae9SGregory Neil Shapirodnl generic error from access map
216006f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
216106f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2162c2aa98e2SPeter Wemm
216340266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
216440266059SGregory Neil Shapiro# authenticated via TLS?
216540266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
216606f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
216706f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
216806f25ae9SGregory Neil Shapiro
216940266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
217040266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
217140266059SGregory Neil ShapiroR$* $| $# $*		$# $2
217240266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
217340266059SGregory Neil ShapiroR$* $| NO		$: $1
217440266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
217540266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
217606f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
217706f25ae9SGregory Neil ShapiroR$* $|			$: $1
217806f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
217906f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
218040266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
218140266059SGregory Neil Shapirodnl remove ${auth_type}
218206f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2183193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
218406f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2185193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2186193538b7SGregory Neil ShapiroR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2187da7d7b9cSGregory Neil Shapiroifelse(defn(`_NO_PERCENTHACK_'), `r',
2188da7d7b9cSGregory Neil Shapiro`R$* % $* < @ $* >	$: <REMOTE> $1 < @ PERCENT_HACK >
2189da7d7b9cSGregory Neil ShapiroR$* % $* 		$: <REMOTE> $1 < @ PERCENT_HACK >', `dnl')
2190c2aa98e2SPeter Wemm# anything terminating locally is ok
2191c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
219240266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
219340266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2194c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
219540266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
219606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21979bd497b8SGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
21989bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
21999bd497b8SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
22009bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
220106f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
220206f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
220340266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
220406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2205e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2206e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2207e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2208e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2209e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
221006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
221106f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
221240266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
22135b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`ROK2')', `dnl')
2214c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2215c2aa98e2SPeter Wemm
221606f25ae9SGregory Neil Shapiro
2217c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2218c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
221906f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
222006f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2221e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
222240266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2223065a643dSPeter WemmR< : $* : > $*		$: $2',
2224c2aa98e2SPeter Wemm`dnl')
2225c2aa98e2SPeter Wemm
2226c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2227c2aa98e2SPeter WemmR$*			$: <?> $1
2228065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2229c2aa98e2SPeter Wemm# local user is ok
223006f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
223106f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
223206f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
223306f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
223406f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
223540266059SGregory Neil ShapiroR<?> postmaster		$@ OK
223606f25ae9SGregory Neil Shapiro# require qualified recipient?
223706f25ae9SGregory Neil Shapirodnl prepend daemon_flags
223806f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
223906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
224006f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
224106f25ae9SGregory Neil Shapirodnl r flag? add client_name
224206f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
224306f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
224406f25ae9SGregory Neil Shapiro# no qualified recipient required
224540266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
224606f25ae9SGregory Neil Shapirodnl client_name is empty
224740266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
224806f25ae9SGregory Neil Shapirodnl client_name is local
224940266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
225006f25ae9SGregory Neil Shapirodnl client_name is not local
225106f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
225206f25ae9SGregory Neil Shapirodnl no qualified recipient required
225340266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
225406f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2255c2aa98e2SPeter WemmR<$+> $*		$: $2
225606f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2257c2aa98e2SPeter Wemm
225840266059SGregory Neil Shapiro######################################################################
225940266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
226040266059SGregory Neil Shapirodnl input: ignored
226140266059SGregory Neil Shapirodnl output: see explanation at call
226240266059SGregory Neil Shapiro######################################################################
226340266059SGregory Neil ShapiroSRelay_ok
2264c2aa98e2SPeter Wemm# anything originating locally is ok
2265c2aa98e2SPeter Wemm# check IP address
2266c2aa98e2SPeter WemmR$*			$: $&{client_addr}
226740266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
226840266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
226913bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
2270da7d7b9cSGregory Neil ShapiroRIPv6:0:0:0:0:0:0:0:1	$@ RELAY		originated locally
2271da7d7b9cSGregory Neil Shapirodnl if compiled with IPV6_FULL=0
227213bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
227340266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
227406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
227540266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
227640266059SGregory Neil ShapiroR<RELAY> $* 		$@ RELAY		relayable IP address
2277959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2278959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2279959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2280959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2281959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2282959366dcSGregory Neil ShapiroR<REJECT> $* 		$@ REJECT		rejected IP address')
22835b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl')
2284c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2285c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
228640266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2287c2aa98e2SPeter Wemm
228806f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
228906f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
229006f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
229106f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
229206f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
229306f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
229406f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
229540266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2296c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
229706f25ae9SGregory Neil Shapiro# check whether local FROM is ok
229840266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
229906f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2300605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
230140266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
23025b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK2')', `dnl')
230340266059SGregory Neil Shapiro', `dnl
230440266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
230540266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
230606f25ae9SGregory Neil Shapiro')',
230706f25ae9SGregory Neil Shapiro`dnl')
230806f25ae9SGregory Neil Shapirodnl')', `dnl')
230940266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
231040266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
231140266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
231206f25ae9SGregory Neil Shapiro
231306f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
231406f25ae9SGregory Neil Shapirodnl input: ignored
231506f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2316e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
231706f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
231806f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
231906f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
232040266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
232106f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
232213bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
232313bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
232413bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
232513bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
232613bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
232740266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
232840266059SGregory Neil Shapiro# pass to name server to make hostname canonical
232940266059SGregory Neil ShapiroR<@> $* $=P 		$:<?>  $1 $2
233040266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
233140266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
233240266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
233306f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
233440266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
233540266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
233606f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
233740266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
233806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
233906f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
234006f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
234140266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
234206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
234340266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
234406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
234540266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
23465b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK3')', `dnl')
234706f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
234840266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
234906f25ae9SGregory Neil Shapirodivert(0)
235006f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
235106f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
235206f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
235306f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
235406f25ae9SGregory Neil ShapiroSFullAddr
235506f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
235606f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
235706f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2358c2aa98e2SPeter Wemm
2359a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
236013bd1963SGregory Neil Shapiro# authenticated?
236113bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
236213bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
236313bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
236413bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
236513bd1963SGregory Neil Shapirodnl return result from checkrcpt
2366a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
236713bd1963SGregory Neil ShapiroR$*			$# $1
236813bd1963SGregory Neil Shapiro
2369a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
237013bd1963SGregory Neil Shapiro# authenticated?
237113bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
237213bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
237313bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
237413bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
237513bd1963SGregory Neil Shapirodnl return result from friend/hater check
2376a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
237713bd1963SGregory Neil ShapiroR$*			$@ $1
237813bd1963SGregory Neil Shapiro
237906f25ae9SGregory Neil Shapiro# call all necessary rulesets
238006f25ae9SGregory Neil ShapiroScheck_rcpt
238106f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
238206f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
238306f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
238413bd1963SGregory Neil Shapiro
238506f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
238606f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
238713bd1963SGregory Neil Shapirodnl on error (or discard) stop now
238813bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
238913bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
239013bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2391a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
239206f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
239306f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
239406f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
239506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
239606f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
239706f25ae9SGregory Neil Shapiro')')dnl
239806f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
23995b0945b5SGregory Neil Shapirodnl this code has been copied from BLOCKLIST... etc
240006f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
240140266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
240240266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
240306f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
240440266059SGregory Neil Shapiro# lookup the addresses only with Spam tag
240540266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
240606f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
240706f25ae9SGregory Neil Shapirodnl', `dnl')
240806f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
240906f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
241006f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
241113bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
241206f25ae9SGregory Neil Shapiro')', `dnl')
2413a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
241406f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
241506f25ae9SGregory Neil Shapiro`dnl')
241606f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
241706f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
241840266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2419a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
242006f25ae9SGregory Neil Shapirodnl',`dnl')
2421d0cef73dSGregory Neil Shapiro
242206f25ae9SGregory Neil Shapirodnl run further checks: check_mail
242306f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
242440266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
242540266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
242640266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2427605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
242806f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
242906f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2430605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
243106f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
243206f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
243306f25ae9SGregory Neil Shapiro', `dnl')
243440266059SGregory Neil Shapiro
2435d0cef73dSGregory Neil Shapiroifdef(`_BLOCK_BAD_HELO_', `dnl
2436d0cef73dSGregory Neil ShapiroR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2437d0cef73dSGregory Neil Shapirodnl Bypass the test for users who have authenticated.
2438d0cef73dSGregory Neil ShapiroR$* $| <$+>		$: $1				skip if auth
2439d0cef73dSGregory Neil ShapiroR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2440d0cef73dSGregory Neil Shapirodnl Bypass for local clients -- IP address starts with $=R
2441d0cef73dSGregory Neil ShapiroR$* $| <$=R $*> [$*]	$: $1				skip if local client
2442d0cef73dSGregory Neil Shapirodnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2443d0cef73dSGregory Neil ShapiroR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2444d0cef73dSGregory Neil Shapirodnl Reject our IP - assumes "[ip]" is in class $=w
2445d0cef73dSGregory Neil ShapiroR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2446d0cef73dSGregory Neil Shapirodnl Reject our hostname
2447d0cef73dSGregory Neil ShapiroR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2448d0cef73dSGregory Neil Shapirodnl Pass anything else with a "." in the domain parameter
2449d0cef73dSGregory Neil ShapiroR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
24505dd76dd0SGregory Neil Shapirodnl Pass IPv6: address literals
24515dd76dd0SGregory Neil ShapiroR$* $| <$*> [IPv6:$+]	$: $1				qualified domain ok
2452d0cef73dSGregory Neil Shapirodnl Reject if there was no "." or only an initial or final "."
2453d0cef73dSGregory Neil ShapiroR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2454d0cef73dSGregory Neil Shapirodnl Clean up the workspace
2455d0cef73dSGregory Neil ShapiroR$* $| $*		$: $1
2456d0cef73dSGregory Neil Shapiro', `dnl')
2457d0cef73dSGregory Neil Shapiro
245840266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
245940266059SGregory Neil Shapiro######################################################################
246040266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
246140266059SGregory Neil Shapiro###
246240266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
246340266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
246440266059SGregory Neil Shapiro###
246540266059SGregory Neil Shapiro###	Parameters:
246640266059SGregory Neil Shapiro###		<$1> -- key
246740266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
246840266059SGregory Neil Shapirodnl			must not be empty
246940266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
247040266059SGregory Neil Shapiro###			! does lookup only with tag
247140266059SGregory Neil Shapiro###			+ does lookup with and without tag
247240266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
247340266059SGregory Neil Shapirodnl returns:		<default> <passthru>
247440266059SGregory Neil Shapirodnl 			<result> <passthru>
247540266059SGregory Neil Shapiro######################################################################
247640266059SGregory Neil Shapiro
247740266059SGregory Neil ShapiroSF
247840266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
247940266059SGregory Neil Shapirodnl full lookup
248040266059SGregory Neil Shapirodnl    2    3  4    5
248140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
248240266059SGregory Neil Shapirodnl no match, try without tag
248340266059SGregory Neil Shapirodnl   1    2      3    4
248440266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
248540266059SGregory Neil Shapirodnl no match, +detail: try +*
248640266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
248740266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
248840266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
248940266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
249040266059SGregory Neil Shapirodnl   1    2    3    4      5    6
249140266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
249240266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
249340266059SGregory Neil Shapirodnl no match, +detail: try without +detail
249440266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
249540266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
249640266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
249740266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
249840266059SGregory Neil Shapirodnl   1    2    3    4      5    6
249940266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
250040266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
250140266059SGregory Neil Shapirodnl no match, return <default> <passthru>
250240266059SGregory Neil Shapirodnl   1    2    3  4    5
250340266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
250440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
250540266059SGregory Neil Shapirodnl            2    3  4    5
250640266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
250740266059SGregory Neil Shapirodnl match, return <match> <passthru>
250840266059SGregory Neil Shapirodnl    2    3  4    5
250940266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
251040266059SGregory Neil Shapiro
251140266059SGregory Neil Shapiro######################################################################
251240266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
251340266059SGregory Neil Shapiro###
251440266059SGregory Neil Shapiro###	Parameters:
251540266059SGregory Neil Shapiro###		<$1> -- key
251640266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
251740266059SGregory Neil Shapirodnl			must not be empty
251840266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
251940266059SGregory Neil Shapiro###			! does lookup only with tag
252040266059SGregory Neil Shapiro###			+ does lookup with and without tag
252140266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
252240266059SGregory Neil Shapirodnl returns:		<default> <passthru>
252340266059SGregory Neil Shapirodnl 			<result> <passthru>
252440266059SGregory Neil Shapiro######################################################################
252540266059SGregory Neil Shapiro
252640266059SGregory Neil ShapiroSE
252740266059SGregory Neil Shapirodnl    2    3  4    5
252840266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
252940266059SGregory Neil Shapirodnl no match, try without tag
253040266059SGregory Neil Shapirodnl   1    2      3    4
253140266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
253240266059SGregory Neil Shapirodnl no match, return default passthru
253340266059SGregory Neil Shapirodnl   1    2    3  4    5
253440266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
253540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
253640266059SGregory Neil Shapirodnl            2    3  4    5
253740266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
253840266059SGregory Neil Shapirodnl match, return <match> <passthru>
253940266059SGregory Neil Shapirodnl    2    3  4    5
254040266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
254140266059SGregory Neil Shapiro
254240266059SGregory Neil Shapiro######################################################################
254340266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
254440266059SGregory Neil Shapiro###
254540266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
254640266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
254740266059SGregory Neil Shapiro###
254840266059SGregory Neil Shapiro###	Parameters:
254940266059SGregory Neil Shapiro###		<$1> -- key (user@)
255040266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
255140266059SGregory Neil Shapirodnl			must not be empty
255240266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
255340266059SGregory Neil Shapiro###			! does lookup only with tag
255440266059SGregory Neil Shapiro###			+ does lookup with and without tag
255540266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
255640266059SGregory Neil Shapirodnl returns:		<default> <passthru>
255740266059SGregory Neil Shapirodnl 			<result> <passthru>
255840266059SGregory Neil Shapiro######################################################################
255940266059SGregory Neil Shapiro
256040266059SGregory Neil ShapiroSU
256140266059SGregory Neil Shapirodnl user lookups are always with trailing @
256240266059SGregory Neil Shapirodnl    2    3  4    5
256340266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
256440266059SGregory Neil Shapirodnl no match, try without tag
256540266059SGregory Neil Shapirodnl   1    2      3    4
256640266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
256740266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
256840266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
256940266059SGregory Neil Shapirodnl no match, +detail: try +*
257040266059SGregory Neil Shapirodnl   1    2      3    4  5    6
257140266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
257240266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
257340266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
257440266059SGregory Neil Shapirodnl   1    2      3      4    5
257540266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
257640266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
257740266059SGregory Neil Shapirodnl no match, +detail: try without +detail
257840266059SGregory Neil Shapirodnl   1    2      3    4  5    6
257940266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
258040266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
258140266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
258240266059SGregory Neil Shapirodnl   1    2      3      4    5
258340266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
258440266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
258540266059SGregory Neil Shapirodnl no match, return <default> <passthru>
258640266059SGregory Neil Shapirodnl   1    2    3  4    5
258740266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
258840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
258940266059SGregory Neil Shapirodnl            2    3  4    5
259040266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
259140266059SGregory Neil Shapirodnl match, return <match> <passthru>
259240266059SGregory Neil Shapirodnl    2    3  4    5
259340266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
259440266059SGregory Neil Shapiro
259506f25ae9SGregory Neil Shapiro######################################################################
259606f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
259706f25ae9SGregory Neil Shapiro###	Parameters:
259806f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
259906f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
260006f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
260106f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
260206f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
260340266059SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: D: if there
260406f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
260506f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
260606f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
260706f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
260806f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
260906f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
261006f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
261106f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
261206f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
261340266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
261406f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
261506f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
261606f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
261706f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
261806f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
261906f25ae9SGregory Neil Shapiro######################################################################
262006f25ae9SGregory Neil Shapiro
262106f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
262206f25ae9SGregory Neil Shapirodnl if A is activated: add it
2623e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
262406f25ae9SGregory Neil ShapiroSSearchList
262540266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
262640266059SGregory Neil Shapirodnl       2       3    4
2627e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
262840266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
262940266059SGregory Neil Shapirodnl no match and nothing left: return
263040266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
263140266059SGregory Neil Shapirodnl no match but something left: continue
263240266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
263340266059SGregory Neil Shapirodnl match: return
263440266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
263506f25ae9SGregory Neil Shapirodnl return result from recursive invocation
263640266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
263740266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
263840266059SGregory Neil Shapirodivert(0)
263906f25ae9SGregory Neil Shapiro
264040266059SGregory Neil Shapiro######################################################################
264140266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
264240266059SGregory Neil Shapiro###
264340266059SGregory Neil Shapiro###	Parameters:
264440266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
264540266059SGregory Neil Shapiro######################################################################
264640266059SGregory Neil Shapiro
264740266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
264840266059SGregory Neil ShapiroSLocal_trust_auth
264906f25ae9SGregory Neil ShapiroStrust_auth
265006f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
265106f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
265206f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
265306f25ae9SGregory Neil Shapirodnl seems to be useful...
265406f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
265506f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
265606f25ae9SGregory Neil Shapirodnl call user supplied code
2657a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
265806f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
265906f25ae9SGregory Neil Shapirodnl default: error
266006f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
266106f25ae9SGregory Neil Shapiro
266240266059SGregory Neil Shapiro######################################################################
266340266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
266440266059SGregory Neil Shapiro###
266540266059SGregory Neil Shapiro###	Parameters:
266640266059SGregory Neil Shapiro###		$1: ${auth_type}
266740266059SGregory Neil Shapiro######################################################################
266840266059SGregory Neil ShapiroSLocal_Relay_Auth
266906f25ae9SGregory Neil Shapiro
267040266059SGregory Neil Shapiro######################################################################
267140266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
267240266059SGregory Neil Shapiro###	(done in server)
267340266059SGregory Neil Shapiro######################################################################
267440266059SGregory Neil ShapiroSsrv_features
267540266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
267640266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
267740266059SGregory Neil ShapiroR$* $| $#$*		$#$2
267840266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2679e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
268040266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
268140266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
268240266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
268306f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
268440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
268540266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2686e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
268706f25ae9SGregory Neil Shapiro
268840266059SGregory Neil Shapiro######################################################################
268940266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
269040266059SGregory Neil Shapiro###	(done in client)
269140266059SGregory Neil Shapiro######################################################################
269206f25ae9SGregory Neil ShapiroStry_tls
269340266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
269440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
269540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
269640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2697e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
269840266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
269940266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
270040266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
270106f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
270240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27035b0945b5SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl')
2704e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
270506f25ae9SGregory Neil Shapiro
270640266059SGregory Neil Shapiro######################################################################
270740266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
270840266059SGregory Neil Shapiro###	(done in client, per recipient)
270940266059SGregory Neil Shapirodnl called from deliver() before RCPT command
271040266059SGregory Neil Shapiro###
271140266059SGregory Neil Shapiro###	Parameters:
271240266059SGregory Neil Shapiro###		$1: recipient
271340266059SGregory Neil Shapiro######################################################################
271440266059SGregory Neil ShapiroStls_rcpt
271540266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
271640266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
271740266059SGregory Neil ShapiroR$* $| $#$*		$#$2
271840266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2719e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
272040266059SGregory Neil Shapirodnl store name of other side
272140266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
272240266059SGregory Neil Shapirodnl canonify recipient address
272340266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
272440266059SGregory Neil Shapirodnl strip trailing dots
272540266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
272640266059SGregory Neil Shapirodnl full address?
272740266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
272840266059SGregory Neil Shapirodnl only localpart?
272940266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
273040266059SGregory Neil Shapirodnl look it up
273140266059SGregory Neil Shapirodnl also look up a default value via E:
273240266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
273340266059SGregory Neil Shapirodnl found nothing: stop here
273440266059SGregory Neil ShapiroR$* $| <?>	$@ OK
273540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27365b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TR')', `dnl')
273740266059SGregory Neil Shapirodnl use the generic routine (for now)
273840266059SGregory Neil ShapiroR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
273940266059SGregory Neil Shapiro
274040266059SGregory Neil Shapiro######################################################################
274140266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
274240266059SGregory Neil Shapiro###	(done in server)
274340266059SGregory Neil Shapiro###
274440266059SGregory Neil Shapiro###	Parameters:
274540266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
274640266059SGregory Neil Shapiro######################################################################
274706f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
274806f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
274906f25ae9SGregory Neil ShapiroStls_client
275040266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
2751e3793f76SGregory Neil ShapiroR$*			$: $1 <?> $>"Local_tls_client" $1
2752e3793f76SGregory Neil ShapiroR$* <?> $#$*		$#$2
2753e3793f76SGregory Neil ShapiroR$* <?> $*		$: $1', `dnl')
275406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
275540266059SGregory Neil Shapirodnl store name of other side
27569bd497b8SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
275706f25ae9SGregory Neil Shapirodnl ignore second arg for now
275806f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
275906f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
276006f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
276140266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
276240266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
276306f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
276406f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
276540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27665b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TC')', `dnl')
276740266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
276840266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
276906f25ae9SGregory Neil Shapiro
277040266059SGregory Neil Shapiro######################################################################
277140266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
277240266059SGregory Neil Shapiro###	(done in client)
277340266059SGregory Neil Shapiro###
277440266059SGregory Neil Shapiro###	Parameter:
277540266059SGregory Neil Shapiro###		${verify}
277640266059SGregory Neil Shapiro######################################################################
277706f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
277806f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
277906f25ae9SGregory Neil ShapiroStls_server
278040266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
278140266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
278240266059SGregory Neil ShapiroR$* $| $#$*		$#$2
278340266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
27845b0945b5SGregory Neil Shapiroifdef(`_TLS_FAILURES_',`dnl
27855b0945b5SGregory Neil ShapiroR$*		$: $(macro {saved_verify} $@ $1 $) $1')
278606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
278740266059SGregory Neil Shapirodnl store name of other side
278840266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
278940266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
279040266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
279106f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
279206f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
279340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27945b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TS')', `dnl')
279540266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
279640266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
279706f25ae9SGregory Neil Shapiro
279840266059SGregory Neil Shapiro######################################################################
279940266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
280040266059SGregory Neil Shapiro###
280140266059SGregory Neil Shapiro###	Parameters:
280206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
280340266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
280440266059SGregory Neil Shapiro###		${verify}')
280540266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
280640266059SGregory Neil Shapirodnl	syntax for Requirement:
280740266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
280840266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
280940266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
281040266059SGregory Neil Shapiro######################################################################
281140266059SGregory Neil ShapiroSTLS_connection
281240266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
281340266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
281440266059SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
28155b0945b5SGregory Neil ShapiroRDANE_FAIL	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed."
281640266059SGregory Neil Shapirodivert(-1)')
281706f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
281840266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
281906f25ae9SGregory Neil Shapirodnl remove optional <>
282006f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
282140266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
282240266059SGregory Neil Shapiro# create the appropriate error codes
282306f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2824e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2825e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
282606f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
2827e92d3f3fSGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
282840266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
282940266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
283006f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
28315b0945b5SGregory Neil Shapirodnl no <reply:dns> i.e. no requirements in the access map
283206f25ae9SGregory Neil Shapirodnl use default error
283306f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
28344e4196cbSGregory Neil Shapiro# deal with TLS protocol errors: abort
28354e4196cbSGregory Neil ShapiroRPROTOCOL $| <$-:$+> $* 	$#error $@ $2 $: $1 " STARTTLS failed."
28365b0945b5SGregory Neil Shapirodnl no <reply:dns> i.e. no requirements in the access map
28374e4196cbSGregory Neil Shapirodnl use default error
28384e4196cbSGregory Neil ShapiroRPROTOCOL $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
28395b0945b5SGregory Neil Shapiro# deal with DANE errors: abort
28405b0945b5SGregory Neil ShapiroRDANE_FAIL $| <$-:$+> $* 	$#error $@ $2 $: $1 " DANE check failed."
28415b0945b5SGregory Neil Shapirodnl no <reply:dns> i.e. no requirements in the access map
28425b0945b5SGregory Neil Shapirodnl use default error
28435b0945b5SGregory Neil ShapiroRDANE_FAIL $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed."
284440266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
284540266059SGregory Neil Shapirodnl separate optional requirements
284640266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2847e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
284840266059SGregory Neil Shapirodnl separate optional requirements
2849e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
285006f25ae9SGregory Neil Shapirodnl some other value in access map: accept
285106f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
285206f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
285306f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
285406f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
285540266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
285606f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
28575b0945b5SGregory Neil ShapiroR<$*><VERIFY> <> $={TlsVerified}	$@ OK
285840266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
285940266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
28605b0945b5SGregory Neil ShapiroR<$*><VERIFY> <$+> $={TlsVerified}	$: <$1> <REQ:0> <$2>
286106f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
28625b0945b5SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> $={TlsVerified}	$: <$1> <REQ:$2> <$3>
286306f25ae9SGregory Neil Shapirodnl just some level of encryption required
286440266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
286540266059SGregory Neil Shapirodnl workspace:
28665b0945b5SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!~ $={TlsVerified})
286740266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
286840266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
286940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
287040266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
287140266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
287240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
287340266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
28745b0945b5SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> CLEAR	$#error $@ $2 $: $1 " STARTTLS disabled locally"
287506f25ae9SGregory Neil Shapirodnl some other value for ${verify}
287640266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
287740266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
287840266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
287906f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
288040266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
288140266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
288240266059SGregory Neil Shapirodnl strength requirements fulfilled
288340266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
288440266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
288540266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
288640266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
288740266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
288840266059SGregory Neil Shapirodnl workspace:
288940266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
289040266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
289140266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
289240266059SGregory Neil Shapirodnl continue: check  extensions
289340266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
289440266059SGregory Neil Shapirodnl split extensions into own list
289540266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
289640266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
289740266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
289806f25ae9SGregory Neil Shapiro
289940266059SGregory Neil Shapiro######################################################################
290040266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
290140266059SGregory Neil Shapiro###
290240266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
290340266059SGregory Neil Shapiro###		$-: SMTP reply code
290440266059SGregory Neil Shapiro###		$+: Enhanced Status Code
290540266059SGregory Neil Shapirodnl  further requirements for this ruleset:
290640266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
290740266059SGregory Neil Shapirodnl
290840266059SGregory Neil Shapirodnl	right now this is only a logical AND
290940266059SGregory Neil Shapirodnl	i.e. all requirements must be true
291040266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
291140266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
291240266059SGregory Neil Shapirodnl	operations (no precedences etc)?
291340266059SGregory Neil Shapiro######################################################################
291440266059SGregory Neil ShapiroSTLS_req
291540266059SGregory Neil Shapirodnl no additional requirements: ok
291640266059SGregory Neil ShapiroR $| $+		$@ OK
291740266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
291840266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
29195b0945b5SGregory Neil Shapiroifdef(`_FFR_TLS_ALTNAMES', `dnl
29205b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $2 $| <$3>
29215b0945b5SGregory Neil ShapiroR<CN:$-.$+> $* $| <$+>			$: <CN:*.$2> $3 $| <$4>
29225b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $3 $| <$3>
29235b0945b5SGregory Neil ShapiroR<CN:$*> $* $| <$+>			$: <CN:$&{TLS_Name}> $2 $| <$3>', `dnl')
292440266059SGregory Neil Shapirodnl match, check rest
292540266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
292640266059SGregory Neil Shapirodnl CN does not match
292740266059SGregory Neil Shapirodnl  1   2      3  4
292840266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
292940266059SGregory Neil Shapirodnl cert subject
293040266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
293140266059SGregory Neil Shapirodnl CS does not match
293240266059SGregory Neil Shapirodnl  1   2      3  4
293313bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
293440266059SGregory Neil Shapirodnl match, check rest
293540266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
293640266059SGregory Neil Shapirodnl CI does not match
293740266059SGregory Neil Shapirodnl  1   2      3  4
293813bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
29395b0945b5SGregory Neil Shapirodnl
29405b0945b5SGregory Neil ShapiroR<CITag:$-> $* $| <$+>	$: <$(access $1:$&{cert_issuer} $: ? $)> $2 $| <$3>
29415b0945b5SGregory Neil ShapiroR<?> $* $| <$-:$+>	$#error $@ $3 $: $2 " Cert Issuer " $&{cert_issuer} " not acceptable"
29425b0945b5SGregory Neil ShapiroR<OK> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
294340266059SGregory Neil Shapirodnl return from recursive call
294440266059SGregory Neil ShapiroROK			$@ OK
294540266059SGregory Neil Shapiro
294640266059SGregory Neil Shapiro######################################################################
294740266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
294840266059SGregory Neil Shapiro###
294940266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
295040266059SGregory Neil Shapiro######################################################################
295106f25ae9SGregory Neil ShapiroSmax
295206f25ae9SGregory Neil ShapiroR:		$: 0
295306f25ae9SGregory Neil ShapiroR:$-		$: $1
295406f25ae9SGregory Neil ShapiroR$-:		$: $1
295506f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
295606f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
295740266059SGregory Neil ShapiroR$-:$-:$-	$: $2
295840266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
295940266059SGregory Neil Shapirodivert(0)
296006f25ae9SGregory Neil Shapiro
2961da7d7b9cSGregory Neil Shapiroifdef(`_TLS_SESSION_FEATURES_', `dnl
2962da7d7b9cSGregory Neil ShapiroStls_srv_features
2963da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2964da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Srv_Features> <$2>
2965da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$: $>A <$1> <?> <! TLS_Srv_Features> <$1>
2966da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$@ ""
2967da7d7b9cSGregory Neil ShapiroR<$+> <$*> 		$@ $1
2968da7d7b9cSGregory Neil Shapiro', `dnl
2969da7d7b9cSGregory Neil ShapiroR$* 		$@ ""')
2970da7d7b9cSGregory Neil Shapiro
2971da7d7b9cSGregory Neil ShapiroStls_clt_features
2972da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2973da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Clt_Features> <$2>
2974da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$: $>A <$1> <?> <! TLS_Clt_Features> <$1>
2975da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$@ ""
2976da7d7b9cSGregory Neil ShapiroR<$+> <$*> 		$@ $1
2977da7d7b9cSGregory Neil Shapiro', `dnl
2978da7d7b9cSGregory Neil ShapiroR$* 		$@ ""')
2979da7d7b9cSGregory Neil Shapiro')
2980da7d7b9cSGregory Neil Shapiro
298140266059SGregory Neil Shapiro######################################################################
298240266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
298340266059SGregory Neil Shapiro###
298440266059SGregory Neil Shapiro###	Parameters:
298540266059SGregory Neil Shapiro###		none
298640266059SGregory Neil Shapiro######################################################################
298740266059SGregory Neil ShapiroSRelayTLS
298806f25ae9SGregory Neil Shapiro# authenticated?
298906f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
299006f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
299113bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
299206f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
299306f25ae9SGregory Neil Shapirodnl but anyway).
299406f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
299506f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
299606f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
299706f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
299806f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
299906f25ae9SGregory Neil Shapirodnl cert subject.
300006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
300140266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
30025b0945b5SGregory Neil ShapiroR<?> $={TlsVerified}	$: OK		authenticated: continue
300340266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
300406f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
300540266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
300640266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
300740266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
300806f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
300940266059SGregory Neil ShapiroRRELAY			$# RELAY
301006f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
301140266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
301240266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
301340266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
301440266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
301540266059SGregory Neil ShapiroR$*			$: NO', `dnl')
301640266059SGregory Neil Shapiro
301740266059SGregory Neil Shapiro######################################################################
301840266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
301940266059SGregory Neil Shapiro###
302040266059SGregory Neil Shapiro###	Parameters:
302140266059SGregory Neil Shapiro###		$1: {server_name}
302240266059SGregory Neil Shapiro###		$2: {server_addr}
302340266059SGregory Neil Shapirodnl	both are currently ignored
302440266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
302540266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
302640266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
302740266059SGregory Neil Shapiro######################################################################
302840266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
302940266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
303040266059SGregory Neil Shapirodnl (which may be considered a good thing).
303140266059SGregory Neil ShapiroSauthinfo
303240266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
303340266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
303440266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
303540266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
303640266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
303740266059SGregory Neil ShapiroR<$*>		$# $1
303840266059SGregory Neil Shapirodnl', `dnl
303940266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
304040266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
304140266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
304240266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
304340266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
304440266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
304540266059SGregory Neil Shapirodnl', `dnl')')
304606f25ae9SGregory Neil Shapiro
3047e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
3048e92d3f3fSGregory Neil Shapiro######################################################################
3049e92d3f3fSGregory Neil Shapiro###  RateControl:
3050e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3051e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3052e92d3f3fSGregory Neil Shapiro######################################################################
3053e92d3f3fSGregory Neil ShapiroSRateControl
3054e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3055e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3056e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3057e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
3058e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3059e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3060e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
30615b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`RC')', `dnl')
3062e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3063e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3064ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
3065e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
3066ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
3067e92d3f3fSGregory Neil Shapiro')')
3068e92d3f3fSGregory Neil Shapiro
3069e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
3070e92d3f3fSGregory Neil Shapiro######################################################################
3071e92d3f3fSGregory Neil Shapiro###  ConnControl:
3072e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3073e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3074e92d3f3fSGregory Neil Shapiro######################################################################
3075e92d3f3fSGregory Neil ShapiroSConnControl
3076e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3077e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3078e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3079e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
3080e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3081e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3082e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
30835b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`CC')', `dnl')
3084e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3085e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3086ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
3087e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
3088ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
3089e92d3f3fSGregory Neil Shapiro')')
3090e92d3f3fSGregory Neil Shapiro
309106f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
309206f25ae9SGregory Neil Shapiro#
309306f25ae9SGregory Neil Shapiro######################################################################
309406f25ae9SGregory Neil Shapiro######################################################################
309506f25ae9SGregory Neil Shapiro#####
309606f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
309706f25ae9SGregory Neil Shapiro#####
309806f25ae9SGregory Neil Shapiro######################################################################
309906f25ae9SGregory Neil Shapiro######################################################################
310040266059SGregory Neil Shapiro_MAIL_FILTERS_
3101c2aa98e2SPeter Wemm#
3102c2aa98e2SPeter Wemm######################################################################
3103c2aa98e2SPeter Wemm######################################################################
3104c2aa98e2SPeter Wemm#####
3105c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
3106c2aa98e2SPeter Wemm#####
3107c2aa98e2SPeter Wemm######################################################################
3108c2aa98e2SPeter Wemm######################################################################
310906f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
311042e5d165SGregory Neil Shapiro
3111