xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 2fb4f839)
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
1862fb4f839SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
1872fb4f839SGregory Neil Shapirodefine(`_FULL_TLS_CONNECTION_CHECK_', `1')', `dnl
1882fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `define(`_FULL_TLS_CONNECTION_CHECK_', `1')')')
18940266059SGregory Neil Shapirodefine(`TLS_SRV_TAG', `"TLS_Srv"')dnl
19040266059SGregory Neil Shapirodefine(`TLS_CLT_TAG', `"TLS_Clt"')dnl
19140266059SGregory Neil Shapirodefine(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl
19240266059SGregory Neil Shapirodefine(`TLS_TRY_TAG', `"Try_TLS"')dnl
19340266059SGregory Neil Shapirodefine(`SRV_FEAT_TAG', `"Srv_Features"')dnl
1942fb4f839SGregory Neil Shapirodefine(`CLT_FEAT_TAG', `"Clt_Features"')dnl
19506f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
19606f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
19706f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
19806f25ae9SGregory Neil ShapiroKarith arith')
1992fb4f839SGregory Neil Shapiroifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl
20040266059SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
20140266059SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
20240266059SGregory Neil ShapiroKmacro macro')
20340266059SGregory Neil Shapiro# possible values for TLS_connection in access map
2045b0945b5SGregory Neil ShapiroC{Tls}VERIFY ENCR
2055b0945b5SGregory Neil ShapiroC{TlsVerified}OK TRUSTED
2065b0945b5SGregory Neil Shapirodnl', `dnl')
20706f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
20806f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
20906f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
21006f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
21106f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
21206f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
2132fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
2142fb4f839SGregory Neil ShapiroKstsxsni regex -a: -s3 (.*)(servername=)(.*)
2152fb4f839SGregory Neil ShapiroKstsxsni2 regex -a: -s2 (.*)(servername=.*)
2162fb4f839SGregory Neil ShapiroKstsxmatch regex -a: -s2 (match=)(.*)
2172fb4f839SGregory Neil Shapiro# flag d: turn off DANE
2182fb4f839SGregory Neil ShapiroKstsxnodaneflag regex -a@ -s3 (.*)(flags=)([^;]*d)(.*)
2192fb4f839SGregory Neil Shapiro', `dnl')
22006f25ae9SGregory Neil Shapiro
22140266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
222fabecb74SGregory Neil Shapiro# who I send unqualified names to if `FEATURE(stickyhost)' is used
22313bd1963SGregory Neil Shapiro# (null means deliver locally)
22440266059SGregory Neil ShapiroDR`'LOCAL_RELAY')
225c2aa98e2SPeter Wemm
22640266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
22713bd1963SGregory Neil Shapiro# who gets all local email traffic
228fabecb74SGregory Neil Shapiro# ($R has precedence for unqualified names if `FEATURE(stickyhost)' is used)
22940266059SGregory Neil ShapiroDH`'MAIL_HUB')
230c2aa98e2SPeter Wemm
231c2aa98e2SPeter Wemm# dequoting map
23240266059SGregory Neil ShapiroKdequote dequote`'ifdef(`confDEQUOTE_OPTS', ` confDEQUOTE_OPTS', `')
233c2aa98e2SPeter Wemm
234c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
235c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
23606f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
237c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
23806f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
239c2aa98e2SPeter Wemm#CL root
240c2aa98e2SPeter Wemmundivert(5)dnl
24106f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
242c2aa98e2SPeter Wemm
24340266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
244c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
24540266059SGregory Neil ShapiroDM`'MASQUERADE_NAME')
246c2aa98e2SPeter Wemm
247c2aa98e2SPeter Wemm# my name for error messages
248c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
249c2aa98e2SPeter Wemm
25006f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
251c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
252c2aa98e2SPeter Wemm
253c2aa98e2SPeter Wemm###############
254c2aa98e2SPeter Wemm#   Options   #
255c2aa98e2SPeter Wemm###############
25640266059SGregory Neil Shapiroifdef(`confAUTO_REBUILD',
25740266059SGregory Neil Shapiro`errprint(WARNING: `confAUTO_REBUILD' is no longer valid.
25840266059SGregory Neil Shapiro	There was a potential for a denial of service attack if this is set.
25940266059SGregory Neil Shapiro)')dnl
260c2aa98e2SPeter Wemm
261c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
26206f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
263c2aa98e2SPeter Wemm
264c2aa98e2SPeter Wemm# 8-bit data handling
2658774250cSGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
266c2aa98e2SPeter Wemm
267c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
26806f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
269c2aa98e2SPeter Wemm
270c2aa98e2SPeter Wemm# location of alias file
27106f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
27206f25ae9SGregory Neil Shapiro
273c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
27406f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
275c2aa98e2SPeter Wemm
276c2aa98e2SPeter Wemm# maximum message size
277e92d3f3fSGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0')
278c2aa98e2SPeter Wemm
279c2aa98e2SPeter Wemm# substitution for space (blank) characters
28006f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
281c2aa98e2SPeter Wemm
282c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
28306f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
284c2aa98e2SPeter Wemm
285c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
28606f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
287c2aa98e2SPeter Wemm
288c2aa98e2SPeter Wemm# default delivery mode
28906f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
290c2aa98e2SPeter Wemm
291c2aa98e2SPeter Wemm# error message header/file
29206f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
293c2aa98e2SPeter Wemm
294c2aa98e2SPeter Wemm# error mode
29506f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
296c2aa98e2SPeter Wemm
297c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
29806f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
299c2aa98e2SPeter Wemm
30040266059SGregory Neil Shapiro# queue file mode (qf files)
30140266059SGregory Neil Shapiro_OPTION(QueueFileMode, `confQUEUE_FILE_MODE', `0600')
30240266059SGregory Neil Shapiro
303c2aa98e2SPeter Wemm# temporary file mode
30406f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
305c2aa98e2SPeter Wemm
306c2aa98e2SPeter Wemm# match recipients against GECOS field?
30706f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
308c2aa98e2SPeter Wemm
309c2aa98e2SPeter Wemm# maximum hop count
31040266059SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `25')
311c2aa98e2SPeter Wemm
312c2aa98e2SPeter Wemm# location of help file
31306f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
314c2aa98e2SPeter Wemm
315c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
31606f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
317c2aa98e2SPeter Wemm
318c2aa98e2SPeter Wemm# name resolver options
31906f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
320c2aa98e2SPeter Wemm
321c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
32206f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
323c2aa98e2SPeter Wemm
324c2aa98e2SPeter Wemm# Forward file search path
32506f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
326c2aa98e2SPeter Wemm
327c2aa98e2SPeter Wemm# open connection cache size
32806f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
329c2aa98e2SPeter Wemm
330c2aa98e2SPeter Wemm# open connection cache timeout
33106f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
332c2aa98e2SPeter Wemm
333c2aa98e2SPeter Wemm# persistent host status directory
33406f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
335c2aa98e2SPeter Wemm
336c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
33706f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
338c2aa98e2SPeter Wemm
339c2aa98e2SPeter Wemm# use Errors-To: header?
34006f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
341c2aa98e2SPeter Wemm
342da7d7b9cSGregory Neil Shapiro# use compressed IPv6 address format?
343da7d7b9cSGregory Neil Shapiro_OPTION(UseCompressedIPv6Addresses, `confUSE_COMPRESSED_IPV6_ADDRESSES', `')
344da7d7b9cSGregory Neil Shapiro
345c2aa98e2SPeter Wemm# log level
34606f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
347c2aa98e2SPeter Wemm
348c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
34906f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
350c2aa98e2SPeter Wemm
351c2aa98e2SPeter Wemm# verify RHS in newaliases?
35206f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
353c2aa98e2SPeter Wemm
354c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
35506f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
356c2aa98e2SPeter Wemm
357c2aa98e2SPeter Wemm# SMTP daemon options
35806f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
359605302a5SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
360605302a5SGregory Neil Shapiro	Use `DAEMON_OPTIONS()'; see cf/README.
36106f25ae9SGregory Neil Shapiro)'dnl
36206f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
36342e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
36440266059SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
36540266059SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
36606f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
36706f25ae9SGregory Neil Shapiro
36806f25ae9SGregory Neil Shapiro# SMTP client options
36940266059SGregory Neil Shapiroifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
37040266059SGregory Neil Shapiro`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
37140266059SGregory Neil Shapiro)'dnl
37240266059SGregory Neil Shapiro`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
37340266059SGregory Neil Shapiroifelse(defn(`_CPO_'), `',
37440266059SGregory Neil Shapiro`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
37540266059SGregory Neil Shapiro
37640266059SGregory Neil Shapiro# Modifiers to `define' {daemon_flags} for direct submissions
37740266059SGregory Neil Shapiro_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
37840266059SGregory Neil Shapiro
37940266059SGregory Neil Shapiro# Use as mail submission program? See sendmail/SECURITY
38040266059SGregory Neil Shapiro_OPTION(UseMSP, `confUSE_MSP', `')
381c2aa98e2SPeter Wemm
382c2aa98e2SPeter Wemm# privacy flags
38306f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
384c2aa98e2SPeter Wemm
385c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
38606f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
387c2aa98e2SPeter Wemm
388c2aa98e2SPeter Wemm# slope of queue-only function
38906f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
390c2aa98e2SPeter Wemm
39140266059SGregory Neil Shapiro# limit on number of concurrent queue runners
39240266059SGregory Neil Shapiro_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
39340266059SGregory Neil Shapiro
39440266059SGregory Neil Shapiro# maximum number of queue-runners per queue-grouping with multiple queues
39540266059SGregory Neil Shapiro_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
39640266059SGregory Neil Shapiro
39740266059SGregory Neil Shapiro# priority of queue runners (nice(3))
39840266059SGregory Neil Shapiro_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
39940266059SGregory Neil Shapiro
40040266059SGregory Neil Shapiro# shall we sort the queue by hostname first?
40140266059SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
40240266059SGregory Neil Shapiro
40340266059SGregory Neil Shapiro# minimum time in queue before retry
40440266059SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
40540266059SGregory Neil Shapiro
406da7d7b9cSGregory Neil Shapiro# maximum time in queue before retry (if > 0; only for exponential delay)
407da7d7b9cSGregory Neil Shapiro_OPTION(MaxQueueAge, `confMAX_QUEUE_AGE', `')
408da7d7b9cSGregory Neil Shapiro
40940266059SGregory Neil Shapiro# how many jobs can you process in the queue?
4104e4196cbSGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
41140266059SGregory Neil Shapiro
41240266059SGregory Neil Shapiro# perform initial split of envelope without checking MX records
41340266059SGregory Neil Shapiro_OPTION(FastSplit, `confFAST_SPLIT', `1')
41440266059SGregory Neil Shapiro
415c2aa98e2SPeter Wemm# queue directory
41606f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
417c2aa98e2SPeter Wemm
418d0cef73dSGregory Neil Shapiro# key for shared memory; 0 to turn off, -1 to auto-select
41940266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
42040266059SGregory Neil Shapiro
421d0cef73dSGregory Neil Shapiro# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
422d0cef73dSGregory Neil Shapiro_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
423605302a5SGregory Neil Shapiro
424c2aa98e2SPeter Wemm# timeouts (many of these)
42506f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
42606f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
42740266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
42806f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
42906f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
43206f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
43306f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
43506f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
43806f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
44006f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
44106f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
44206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
44306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
44406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
44506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
446e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
44706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
44806f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
44906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
45006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
451e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
45206f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
45306f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
45406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
45506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
45606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
45706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
45806f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
45940266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
46040266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
46140266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
46240266059SGregory Neil Shapiro
46340266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
46440266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
465c2aa98e2SPeter Wemm
466c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
46706f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
468c2aa98e2SPeter Wemm
469c2aa98e2SPeter Wemm# queue up everything before forking?
47006f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
471c2aa98e2SPeter Wemm
472c2aa98e2SPeter Wemm# status file
473d0cef73dSGregory Neil Shapiro_OPTION(StatusFile, `STATUS_FILE')
474c2aa98e2SPeter Wemm
475c2aa98e2SPeter Wemm# time zone handling:
476c2aa98e2SPeter Wemm#  if undefined, use system default
477c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
478c2aa98e2SPeter Wemm#  if defined and non-null, use that info
479c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
480c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
481c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
482c2aa98e2SPeter Wemm
483c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
48406f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
485c2aa98e2SPeter Wemm
486c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
48706f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
488c2aa98e2SPeter Wemm
489c2aa98e2SPeter Wemm# fallback MX host
49006f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
491c2aa98e2SPeter Wemm
492e92d3f3fSGregory Neil Shapiro# fallback smart host
493e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
494e92d3f3fSGregory Neil Shapiro
495c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
49606f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
497c2aa98e2SPeter Wemm
498c2aa98e2SPeter Wemm# load average at which we just queue messages
49906f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
500c2aa98e2SPeter Wemm
501c2aa98e2SPeter Wemm# load average at which we refuse connections
50206f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
503c2aa98e2SPeter Wemm
504e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
505e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
506e92d3f3fSGregory Neil Shapiro
50740266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
50840266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
50940266059SGregory Neil Shapiro
510c2aa98e2SPeter Wemm# maximum number of children we allow at one time
511739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
512c2aa98e2SPeter Wemm
513c2aa98e2SPeter Wemm# maximum number of new connections per second
514193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
515c2aa98e2SPeter Wemm
516e92d3f3fSGregory Neil Shapiro# Width of the window
517e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
518e92d3f3fSGregory Neil Shapiro
519c2aa98e2SPeter Wemm# work recipient factor
52006f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
521c2aa98e2SPeter Wemm
522c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
52306f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
524c2aa98e2SPeter Wemm
525c2aa98e2SPeter Wemm# work class factor
52606f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
527c2aa98e2SPeter Wemm
528c2aa98e2SPeter Wemm# work time factor
52906f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
530c2aa98e2SPeter Wemm
531c2aa98e2SPeter Wemm# default character set
532b6bacd31SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
533c2aa98e2SPeter Wemm
53440266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
53506f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
536c2aa98e2SPeter Wemm
537c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
53806f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
539c2aa98e2SPeter Wemm
540c2aa98e2SPeter Wemm# dialup line delay on connection failure
5414e4196cbSGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `0s')
542c2aa98e2SPeter Wemm
543c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
5444e4196cbSGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
545c2aa98e2SPeter Wemm
546c2aa98e2SPeter Wemm# chrooted environment for writing to files
5474e4196cbSGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
548c2aa98e2SPeter Wemm
549c2aa98e2SPeter Wemm# are colons OK in addresses?
55006f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
551c2aa98e2SPeter Wemm
552c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
55306f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
554c2aa98e2SPeter Wemm
555c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
55606f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
557c2aa98e2SPeter Wemm
558c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
55906f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
560c2aa98e2SPeter Wemm
561c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
56206f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
563c2aa98e2SPeter Wemm
564c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
56506f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
566c2aa98e2SPeter Wemm
567c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
56806f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
569c2aa98e2SPeter Wemm
570c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
57106f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
572c2aa98e2SPeter Wemm
573c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
57406f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
575c2aa98e2SPeter Wemm
576c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
57740266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
57806f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
57940266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
58040266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
58140266059SGregory Neil Shapiro')')
582c2aa98e2SPeter Wemm
583c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
58406f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
58506f25ae9SGregory Neil Shapiro
586d0cef73dSGregory Neil Shapiro# issue temporary errors (4xy) instead of permanent errors (5xy)?
587d0cef73dSGregory Neil Shapiro_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
588d0cef73dSGregory Neil Shapiro
58906f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
59006f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
591c2aa98e2SPeter Wemm
592c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
59306f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
594c2aa98e2SPeter Wemm
595c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
596e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
597c2aa98e2SPeter Wemm
59840266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
59940266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
600e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
60140266059SGregory Neil Shapiro
6029bd497b8SGregory Neil Shapiro
603c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
60406f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
605c2aa98e2SPeter Wemm
60606f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
60706f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
60806f25ae9SGregory Neil Shapiro
60906f25ae9SGregory Neil Shapiro# override connection address (for testing)
61006f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
61106f25ae9SGregory Neil Shapiro
61206f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
61306f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
61406f25ae9SGregory Neil Shapiro
61506f25ae9SGregory Neil Shapiro# Control socket for daemon management
61606f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
61706f25ae9SGregory Neil Shapiro
61806f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
619e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
62006f25ae9SGregory Neil Shapiro
62106f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
62206f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
62306f25ae9SGregory Neil Shapiro
62406f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
62506f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
62606f25ae9SGregory Neil Shapiro
62706f25ae9SGregory Neil Shapiro# location of pid file
62806f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
62906f25ae9SGregory Neil Shapiro
63006f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
63106f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
63206f25ae9SGregory Neil Shapiro
63306f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
63406f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
63506f25ae9SGregory Neil Shapiro
63606f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
63706f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
63806f25ae9SGregory Neil Shapiro
63940266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
64040266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
64140266059SGregory Neil Shapiro
642e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
643e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
644e92d3f3fSGregory Neil Shapiro
64506f25ae9SGregory Neil Shapiro# list of authentication mechanisms
64640266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
64706f25ae9SGregory Neil Shapiro
648e92d3f3fSGregory Neil Shapiro# Authentication realm
649e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
650e92d3f3fSGregory Neil Shapiro
65106f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
65206f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
65306f25ae9SGregory Neil Shapiro
65406f25ae9SGregory Neil Shapiro# SMTP AUTH flags
65506f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
65606f25ae9SGregory Neil Shapiro
65740266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
65840266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
65940266059SGregory Neil Shapiro
66040266059SGregory Neil Shapiro# SMTP STARTTLS server options
66140266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
66240266059SGregory Neil Shapiro
663da7d7b9cSGregory Neil Shapiro# SSL cipherlist
664da7d7b9cSGregory Neil Shapiro_OPTION(CipherList, `confCIPHER_LIST', `')
665da7d7b9cSGregory Neil Shapiro# server side SSL options
666da7d7b9cSGregory Neil Shapiro_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `')
667da7d7b9cSGregory Neil Shapiro# client side SSL options
668da7d7b9cSGregory Neil Shapiro_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `')
6695b0945b5SGregory Neil Shapiro# SSL Engine
6705b0945b5SGregory Neil Shapiro_OPTION(SSLEngine, `confSSL_ENGINE', `')
6715b0945b5SGregory Neil Shapiro# Path to dynamic library for SSLEngine
6725b0945b5SGregory Neil Shapiro_OPTION(SSLEnginePath, `confSSL_ENGINE_PATH', `')
6735b0945b5SGregory Neil Shapiro# TLS: fall back to clear text after handshake failure?
6745b0945b5SGregory Neil Shapiro_OPTION(TLSFallbacktoClear, `confTLS_FALLBACK_TO_CLEAR', `')
6759bd497b8SGregory Neil Shapiro
67606f25ae9SGregory Neil Shapiro# Input mail filters
67706f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
67806f25ae9SGregory Neil Shapiro
679739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
68006f25ae9SGregory Neil Shapiro# Milter options
68140266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
68206f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
68306f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
68406f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
685323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
686d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
687d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
688d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
68906f25ae9SGregory Neil Shapiro
69006f25ae9SGregory Neil Shapiro# CA directory
69113bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
69206f25ae9SGregory Neil Shapiro# CA file
69313bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
69406f25ae9SGregory Neil Shapiro# Server Cert
69506f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
69606f25ae9SGregory Neil Shapiro# Server private key
69706f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
69806f25ae9SGregory Neil Shapiro# Client Cert
69906f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
70006f25ae9SGregory Neil Shapiro# Client private key
70106f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
702e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
703e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
7045b0945b5SGregory Neil Shapiro# Directory containing hashes pointing to certificate revocation status files
7055b0945b5SGregory Neil Shapiro_OPTION(CRLPath, `confCRL_PATH', `')
70606f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
70706f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
70806f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
70906f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
710da7d7b9cSGregory Neil Shapiro# fingerprint algorithm (digest) to use for the presented cert
711da7d7b9cSGregory Neil Shapiro_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `')
7125b0945b5SGregory Neil Shapiro# enable DANE?
7135b0945b5SGregory Neil Shapiro_OPTION(DANE, `confDANE', `false')
71406f25ae9SGregory Neil Shapiro
715d0cef73dSGregory Neil Shapiro# Maximum number of "useless" commands before slowing down
716d0cef73dSGregory Neil Shapiro_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
717d0cef73dSGregory Neil Shapiro
718d0cef73dSGregory Neil Shapiro# Name to use for EHLO (defaults to $j)
719d0cef73dSGregory Neil Shapiro_OPTION(HeloName, `confHELO_NAME')
720d0cef73dSGregory Neil Shapiro
721da7d7b9cSGregory Neil Shapiroifdef(`_NEED_SMTPOPMODES_', `dnl
722da7d7b9cSGregory Neil Shapiro# SMTP operation modes
723da7d7b9cSGregory Neil ShapiroC{SMTPOpModes} s d D')
724da7d7b9cSGregory Neil Shapiro
72540266059SGregory Neil Shapiro############################
72640266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
72740266059SGregory Neil Shapiro############################
72840266059SGregory Neil Shapiro_QUEUE_GROUP_
729065a643dSPeter Wemm
730c2aa98e2SPeter Wemm###########################
731c2aa98e2SPeter Wemm#   Message precedences   #
732c2aa98e2SPeter Wemm###########################
733c2aa98e2SPeter Wemm
734c2aa98e2SPeter WemmPfirst-class=0
735c2aa98e2SPeter WemmPspecial-delivery=100
736c2aa98e2SPeter WemmPlist=-30
737c2aa98e2SPeter WemmPbulk=-60
738c2aa98e2SPeter WemmPjunk=-100
739c2aa98e2SPeter Wemm
740c2aa98e2SPeter Wemm#####################
741c2aa98e2SPeter Wemm#   Trusted users   #
742c2aa98e2SPeter Wemm#####################
743c2aa98e2SPeter Wemm
744c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
74506f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
746c2aa98e2SPeter WemmTroot
747c2aa98e2SPeter WemmTdaemon
748c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
749c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
750c2aa98e2SPeter Wemm
751c2aa98e2SPeter Wemm#########################
752c2aa98e2SPeter Wemm#   Format of headers   #
753c2aa98e2SPeter Wemm#########################
754c2aa98e2SPeter Wemm
755c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
756e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
757c2aa98e2SPeter WemmH?P?Return-Path: <$g>
758c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
759c2aa98e2SPeter WemmH?D?Resent-Date: $a
760c2aa98e2SPeter WemmH?D?Date: $a
761c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
762c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
763c2aa98e2SPeter WemmH?x?Full-Name: $x
764c2aa98e2SPeter Wemm# HPosted-Date: $a
765c2aa98e2SPeter Wemm# H?l?Received-Date: $b
766e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
767e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
76806f25ae9SGregory Neil Shapiro
769c2aa98e2SPeter Wemm#
770c2aa98e2SPeter Wemm######################################################################
771c2aa98e2SPeter Wemm######################################################################
772c2aa98e2SPeter Wemm#####
773c2aa98e2SPeter Wemm#####			REWRITING RULES
774c2aa98e2SPeter Wemm#####
775c2aa98e2SPeter Wemm######################################################################
776c2aa98e2SPeter Wemm######################################################################
777c2aa98e2SPeter Wemm
778c2aa98e2SPeter Wemm############################################
779c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
780c2aa98e2SPeter Wemm############################################
78106f25ae9SGregory Neil ShapiroScanonify=3
782c2aa98e2SPeter Wemm
783c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
784c2aa98e2SPeter WemmR$@			$@ <@>
785c2aa98e2SPeter Wemm
786c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
787c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
788c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
789c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
79040266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
791c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
792c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
793c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
794c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
795c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
796c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
797193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
798c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
799c2aa98e2SPeter Wemm
800c2aa98e2SPeter Wemm# null input now results from list:; syntax
801c2aa98e2SPeter WemmR$@			$@ :; <@>
802c2aa98e2SPeter Wemm
803c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
804c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
805c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
806c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
807c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
808c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
809c2aa98e2SPeter Wemm
81006f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
811c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
812c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
813c2aa98e2SPeter Wemm
814c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
81540266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
81640266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
81740266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
81806f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
81906f25ae9SGregory Neil Shapirodnl',`dnl
82006f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
82106f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
82240266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
82340266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
82406f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
82506f25ae9SGregory Neil Shapirodnl')
826c2aa98e2SPeter Wemm
827c2aa98e2SPeter Wemm# find focus for list syntax
82806f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
829c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
830c2aa98e2SPeter Wemm
831c2aa98e2SPeter Wemm# find focus for @ syntax addresses
832c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
833c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
83406f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
835c2aa98e2SPeter Wemm
83640266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
83740266059SGregory Neil Shapirodnl # do some sanity checking
83840266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
839c2aa98e2SPeter Wemm
840c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
841c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
84206f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
84306f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
84406f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
845c2aa98e2SPeter Wemm')
846c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
847c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
84806f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
84906f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
850c2aa98e2SPeter Wemm',
851c2aa98e2SPeter Wemm	`dnl')
852da7d7b9cSGregory Neil Shapiroifdef(`_NO_PERCENTHACK_', `dnl',
853da7d7b9cSGregory Neil Shapiro`# if we have % signs, take the rightmost one
854c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
855c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
856da7d7b9cSGregory Neil Shapiro')
85706f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
858c2aa98e2SPeter Wemm
859c2aa98e2SPeter Wemm# else we must be a local name
86006f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
861c2aa98e2SPeter Wemm
862c2aa98e2SPeter Wemm
863c2aa98e2SPeter Wemm################################################
864c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
865c2aa98e2SPeter Wemm################################################
866c2aa98e2SPeter Wemm
86706f25ae9SGregory Neil ShapiroSCanonify2=96
868c2aa98e2SPeter Wemm
869c2aa98e2SPeter Wemm# handle special cases for local names
870c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
871c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
872c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
873c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
87406f25ae9SGregory Neil Shapiro
87540266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
87640266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
877c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
878c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
879c2aa98e2SPeter Wemm
88006f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
881c2aa98e2SPeter Wemm# look up domains in the domain table
882c2aa98e2SPeter WemmR$* < @ $+ > $*		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
883c2aa98e2SPeter Wemm
88406f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
885c2aa98e2SPeter Wemm
88606f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
887c2aa98e2SPeter Wemm# handle BITNET mapping
888c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
889c2aa98e2SPeter Wemm
89006f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
891c2aa98e2SPeter Wemm# handle UUCP mapping
892c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
893c2aa98e2SPeter Wemm
894c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
895c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
896c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
897c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
898c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
899c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
900c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
901c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
902c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
903c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
904c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
905c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
906c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
907c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
908c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
909c2aa98e2SPeter Wemm
910c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
911c2aa98e2SPeter Wemm# try UUCP traffic as a local address
912c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
913c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
914c2aa98e2SPeter Wemm')')
91506f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
91606f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
91706f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
91806f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
91906f25ae9SGregory Neil Shapirodnl which daemon flags are set?
92006f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
92106f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
92206f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
92306f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
92406f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
92506f25ae9SGregory Neil Shapirodnl do not canonify unless:
92606f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
92706f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
92806f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
92906f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
93006f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
93106f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
93206f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
93306f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
93406f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
93506f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
93606f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
93706f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
93806f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
93906f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
94006f25ae9SGregory Neil Shapirodnl then $- does not work.
94106f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
94206f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
94306f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
94406f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
945193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
946193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
947193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
94806f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
94940266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
95040266059SGregory Neil Shapiro# do not canonify header addresses
95140266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
95240266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
95340266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
954c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
95506f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
95606f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
95706f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
958c2aa98e2SPeter Wemm
959c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
960c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
961c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
962c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
963c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
96406f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
96506f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
96606f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
96706f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $*	$: $1 < @ $2 $3 . > $4',
96806f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $*	$: $1 < @ $2 . > $3')',
96906f25ae9SGregory Neil Shapiro`dnl')
97040266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
97140266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
97240266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
97340266059SGregory Neil Shapiro`R$* < @ $* $=G > $*	$: $1 < @ $2 $3 . > $4',
97440266059SGregory Neil Shapiro`R$* < @ $=G > $*	$: $1 < @ $2 . > $3')',
97540266059SGregory Neil Shapiro`dnl')
97606f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
97706f25ae9SGregory Neil Shapirodnl by one of the rules before
978c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
979c2aa98e2SPeter Wemm
980c2aa98e2SPeter Wemm
981c2aa98e2SPeter Wemm##################################################
982c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
983c2aa98e2SPeter Wemm##################################################
98406f25ae9SGregory Neil ShapiroSfinal=4
985c2aa98e2SPeter Wemm
986193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
987c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
988c2aa98e2SPeter Wemm
989c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
990c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
991c2aa98e2SPeter Wemm
99206f25ae9SGregory Neil Shapiro# eliminate internal code
993c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
994c2aa98e2SPeter Wemm
995c2aa98e2SPeter Wemm# externalize local domain info
996c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
997c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
998c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
999c2aa98e2SPeter Wemm
1000c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1001c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
1002c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
1003c2aa98e2SPeter Wemm
1004c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
1005c2aa98e2SPeter Wemm`# put DECnet back in :: form
1006c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
1007c2aa98e2SPeter Wemm	`dnl')
1008c2aa98e2SPeter Wemm# delete duplicate local names
1009c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
1010c2aa98e2SPeter Wemm
1011c2aa98e2SPeter Wemm
1012c2aa98e2SPeter Wemm
1013c2aa98e2SPeter Wemm##############################################################
1014c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
1015c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
1016c2aa98e2SPeter Wemm##############################################################
1017c2aa98e2SPeter Wemm
101806f25ae9SGregory Neil ShapiroSRecurse=97
101906f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
102006f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
1021c2aa98e2SPeter Wemm
1022c2aa98e2SPeter Wemm
1023c2aa98e2SPeter Wemm######################################
1024c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
1025c2aa98e2SPeter Wemm######################################
1026c2aa98e2SPeter Wemm
102706f25ae9SGregory Neil ShapiroSparse=0
1028c2aa98e2SPeter Wemm
1029c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
1030c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
103106f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
1032c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
1033c2aa98e2SPeter Wemm
1034c2aa98e2SPeter Wemm#
1035c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
1036c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
1037c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
1038c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
1039c2aa98e2SPeter Wemm#
1040c2aa98e2SPeter Wemm
1041c2aa98e2SPeter WemmSParse0
1042c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
104340266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
104406f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
104540266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
104640266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
1047c2aa98e2SPeter WemmR$*			$: <> $1
104840266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
104940266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
105040266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
105140266059SGregory Neil Shapirodnl but no a@[b]c
105240266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
1053c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
105440266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1055c2aa98e2SPeter WemmR<> $*			$1
105640266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
105740266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
105840266059SGregory Neil Shapirodnl no a@b@
105940266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
106040266059SGregory Neil Shapirodnl no a@b@c
106140266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
106206f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
106340266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
106440266059SGregory Neil Shapiro
106540266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
106640266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
106740266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
106840266059SGregory Neil Shapirodnl', `dnl')
1069c2aa98e2SPeter Wemm
1070c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
107106f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
107206f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1073c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
107440266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
107506f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1076c2aa98e2SPeter WemmR$-			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
107740266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1078c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
107906f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1080c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1081c2aa98e2SPeter Wemm
1082da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1083da7d7b9cSGregory Neil ShapiroR$+			$: $>ParseBcc $1', `dnl')
1084da7d7b9cSGregory Neil Shapiroifdef(`_PREFIX_MOD_', `dnl
1085da7d7b9cSGregory Neil Shapirodnl do this only for addr_type=e r?
1086da7d7b9cSGregory Neil ShapiroR _PREFIX_MOD_ $+	$: $1 $(macro {rcpt_flags} $@ _PREFIX_FLAGS_ $)
1087da7d7b9cSGregory Neil Shapiro')dnl
1088da7d7b9cSGregory Neil Shapiro
1089c2aa98e2SPeter Wemm#
1090c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1091c2aa98e2SPeter Wemm#
1092c2aa98e2SPeter Wemm
1093c2aa98e2SPeter WemmSParse1
109406f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
109506f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
109640266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
109740266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1098c2aa98e2SPeter Wemm`dnl')
1099c2aa98e2SPeter Wemm
110006f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
110106f25ae9SGregory Neil Shapiro`# handle numeric address spec
110206f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
110306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
11045ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
110506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
110606f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
110706f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
110806f25ae9SGregory Neil Shapiro	`dnl')
110906f25ae9SGregory Neil Shapiro
111006f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1111c2aa98e2SPeter Wemm# handle virtual users
111240266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
111340266059SGregory Neil Shapirodnl this is not a documented option
111440266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
111540266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
111640266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
111740266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
111840266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
111940266059SGregory Neil ShapiroR$+ < @ $+ >			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
112040266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
112140266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
112240266059SGregory Neil Shapiro`dnl')
112306f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
112440266059SGregory Neil Shapirodnl input: <!> local<@domain>
112506f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
112606f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . >	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
112706f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . >	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
112840266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
112906f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . >	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
113040266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
113140266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
113240266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
113340266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113440266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1135c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
113640266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113740266059SGregory Neil Shapirodnl user+detail: try user@domain
1138c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
113940266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114006f25ae9SGregory Neil Shapirodnl try default entry: @domain
114140266059SGregory Neil Shapirodnl ++@domain
114240266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114306f25ae9SGregory Neil Shapirodnl +*@domain
114440266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114506f25ae9SGregory Neil Shapirodnl @domain if +detail exists
114694c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
114794c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
114894c01205SGregory Neil Shapirodnl without +detail
1149c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
115040266059SGregory Neil Shapirodnl no match
1151c2aa98e2SPeter WemmR<@> $+			$: $1
115240266059SGregory Neil Shapirodnl remove mark
115306f25ae9SGregory Neil ShapiroR<!> $+			$: $1
115406f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $*	$#error $@ $1.$2.$3 $: $4
1155c2aa98e2SPeter WemmR< error : $- $+ > $*	$#error $@ $(dequote $1 $) $: $2
115640266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
115740266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
115840266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
115940266059SGregory Neil Shapiro# it is the same: stop now
116040266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
116140266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $*			$: < $1 > $2 < @ $3 >
116240266059SGregory Neil Shapirodnl', `dnl')
116313058a91SGregory Neil Shapirodnl this is not a documented option
116413058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11658774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11668774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11678774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11688774250cSGregory Neil Shapirodnl', `dnl')
1169c2aa98e2SPeter Wemm
1170c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1171c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
117206f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
117342e5d165SGregory Neil Shapiro
117442e5d165SGregory Neil Shapiro
1175c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1176c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
117706f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
117806f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1179c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1180c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1181c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1182c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1183c2aa98e2SPeter Wemm
118406f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1185c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1186c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1187c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1188c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
118906f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
119006f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
119106f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1192c2aa98e2SPeter Wemm`dnl')
119306f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1194c2aa98e2SPeter Wemm
1195c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1196c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1197c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
119806f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1199c2aa98e2SPeter Wemm	`dnl')
1200c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
120106f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1202c2aa98e2SPeter Wemm	`dnl')
1203c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
120406f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1205c2aa98e2SPeter Wemm	`dnl')')
1206c2aa98e2SPeter Wemm
1207c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1208c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
120906f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1210c2aa98e2SPeter Wemm	`dnl')
1211c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
121206f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1213c2aa98e2SPeter Wemm	`dnl')
1214c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1215c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1216c2aa98e2SPeter Wemm	`dnl')
1217c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1218c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1219c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
122006f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1221c2aa98e2SPeter Wemm	`dnl')')
1222c2aa98e2SPeter Wemm
1223c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1224c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
122506f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1226c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1227c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1228c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1229c2aa98e2SPeter Wemm	`dnl')')
1230c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1231c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
123206f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1233c2aa98e2SPeter Wemm	`dnl')
1234c2aa98e2SPeter Wemm
1235c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1236c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1237c2aa98e2SPeter Wemmundivert(1)', `dnl')
1238c2aa98e2SPeter Wemm
1239c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
124006f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1241c2aa98e2SPeter Wemm
1242c2aa98e2SPeter Wemm# deal with other remote names
1243c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1244c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
124540266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1246c2aa98e2SPeter Wemm
1247c2aa98e2SPeter Wemm# handle locally delivered names
1248c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1249c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1250c2aa98e2SPeter Wemm
1251da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1252da7d7b9cSGregory Neil ShapiroSParseBcc
1253da7d7b9cSGregory Neil ShapiroR$+			$: $&{addr_type} $| $&A $| $1
1254da7d7b9cSGregory Neil ShapiroRe b $| $+ $| $+	$>MailerToTriple < $1 > $2	copy?
1255da7d7b9cSGregory Neil ShapiroR$* $| $* $| $+		$@ $3				no copy
1256da7d7b9cSGregory Neil Shapiro')
1257da7d7b9cSGregory Neil Shapiro
1258c2aa98e2SPeter Wemm###########################################################################
1259c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1260c2aa98e2SPeter Wemm###########################################################################
1261c2aa98e2SPeter Wemm
126206f25ae9SGregory Neil ShapiroSLocal_localaddr
126306f25ae9SGregory Neil ShapiroSlocaladdr=5
126406f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
126540266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
126606f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
126706f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1268c2aa98e2SPeter Wemm
126940266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
127040266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
127140266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
127240266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
127340266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
127440266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12756a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
127640266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
127740266059SGregory Neil Shapiro')dnl
127840266059SGregory Neil Shapiro
127940266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
128042e5d165SGregory Neil Shapiro# Preserve host in a macro
128142e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
128242e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1283c2aa98e2SPeter Wemm
128440266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
128542e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
128642e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
128742e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
128842e5d165SGregory Neil Shapiro')
1289c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1290c2aa98e2SPeter WemmR$+			$: <> $1
1291c2aa98e2SPeter Wemm
1292c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1293c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
129440266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
129542e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
129642e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
129742e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
129842e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
129906f25ae9SGregory Neil ShapiroR< > $+			$: < $L > $(user $1 $)		look up user
130040266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
130140266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
130240266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
130340266059SGregory Neil Shapirodnl')
1304c2aa98e2SPeter Wemm
130540266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
130640266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
130740266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
130840266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
130940266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
131040266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
131106f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
131240266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
131340266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
131406f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
131506f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1316c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
131742e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1318c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
13192e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
132040266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
132140266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
13222e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
132342e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
132406f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
132506f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
132640266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
132740266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
132840266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
132940266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
133040266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
133140266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
133206f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1333c2aa98e2SPeter Wemm
133406f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
133540266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
133640266059SGregory Neil Shapiro###################################################################
133740266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
133840266059SGregory Neil Shapirodnl input: <Domain> FullAddress
133940266059SGregory Neil Shapiro###################################################################
134040266059SGregory Neil Shapiro
134140266059SGregory Neil ShapiroSLDAPMailertable
134240266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
134340266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
134440266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
134540266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
134640266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
134740266059SGregory Neil Shapiro`dnl')
134840266059SGregory Neil Shapiro
1349c2aa98e2SPeter Wemm###################################################################
1350c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry		###
135106f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1352c2aa98e2SPeter Wemm###################################################################
1353c2aa98e2SPeter Wemm
135406f25ae9SGregory Neil ShapiroSMailertable=90
135506f25ae9SGregory Neil Shapirodnl shift and check
135606f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1357c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
135806f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
135906f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
136006f25ae9SGregory Neil ShapiroR$* < . $+ > $*		$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
136106f25ae9SGregory Neil Shapirodnl is $2 always empty?
1362c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
136306f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
136406f25ae9SGregory Neil Shapirodnl return full address
1365c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1366c2aa98e2SPeter Wemm`dnl')
1367c2aa98e2SPeter Wemm
1368c2aa98e2SPeter Wemm###################################################################
1369c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
137006f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
137106f25ae9SGregory Neil Shapirodnl	<> address				-> address
137206f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1373a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
137406f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
137506f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
137606f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
137706f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
137806f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1379c2aa98e2SPeter Wemm###################################################################
1380c2aa98e2SPeter Wemm
138106f25ae9SGregory Neil ShapiroSMailerToTriple=95
1382c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
138306f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $*	$#error $@ $1.$2.$3 $: $4
1384a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1385a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1386c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
138740266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
138840266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
138940266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1390c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1391c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1392c2aa98e2SPeter Wemm
1393c2aa98e2SPeter Wemm###################################################################
1394c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
139506f25ae9SGregory Neil Shapirodnl input: <user> address
139606f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
139706f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
139806f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
139906f25ae9SGregory Neil Shapirodnl <> user				-> local user user
140006f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
140106f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
140206f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1403c2aa98e2SPeter Wemm###################################################################
1404c2aa98e2SPeter Wemm
1405c2aa98e2SPeter WemmSCanonLocal
14062e43090eSPeter Wemm# strip local host from routed addresses
140706f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
140806f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
14092e43090eSPeter Wemm
1410c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1411c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1412c2aa98e2SPeter Wemm
1413c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1414c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1415c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1416c2aa98e2SPeter Wemm
1417c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1418c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1419c2aa98e2SPeter Wemm
1420c2aa98e2SPeter Wemm# handle local:user syntax
1421c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1422c2aa98e2SPeter WemmR< $+ > $*			$#_LOCAL_ $@ $2    $: $1
1423c2aa98e2SPeter Wemm
1424c2aa98e2SPeter Wemm###################################################################
1425c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1426c2aa98e2SPeter Wemm###################################################################
1427c2aa98e2SPeter Wemm
142806f25ae9SGregory Neil ShapiroSMasqHdr=93
1429c2aa98e2SPeter Wemm
143006f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1431c2aa98e2SPeter Wemm# handle generics database
1432c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
143306f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1434c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1435c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1436c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
143706f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
143806f25ae9SGregory Neil Shapirodnl ignore the first case for now
143906f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
144040266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
144106f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
144206f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
144306f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
144406f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
144506f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
144606f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
144706f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
144806f25ae9SGregory Neil Shapirodnl no match, remove mark
144906f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
145006f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
145106f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
145206f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
145306f25ae9SGregory Neil Shapirodnl no match, try local part
1454c2aa98e2SPeter WemmR< > $+ < @ $+ >	$: < $(generics $1 $: $) > $1 < @ $2 >
145506f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ >	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
145606f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ >	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
145706f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
145806f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1459c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1460c2aa98e2SPeter Wemm`dnl')
1461c2aa98e2SPeter Wemm
146206f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
146306f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
146406f25ae9SGregory Neil Shapiro
146540266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1466c2aa98e2SPeter Wemm# special case the users that should be exposed
1467c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1468c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1469c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1470c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1471c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1472c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1473c2aa98e2SPeter Wemm
1474c2aa98e2SPeter Wemm# handle domain-specific masquerading
1475c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1476c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1477c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1478c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1479c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1480c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1481c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1482c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
148340266059SGregory Neil Shapirodnl', `dnl no masquerading
148440266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
148540266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1486c2aa98e2SPeter Wemm
1487c2aa98e2SPeter Wemm###################################################################
1488c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1489c2aa98e2SPeter Wemm###################################################################
1490c2aa98e2SPeter Wemm
149106f25ae9SGregory Neil ShapiroSMasqEnv=94
1492c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
149306f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1494c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1495c2aa98e2SPeter Wemm
1496c2aa98e2SPeter Wemm###################################################################
1497c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1498c2aa98e2SPeter Wemm###################################################################
1499c2aa98e2SPeter Wemm
150006f25ae9SGregory Neil ShapiroSParseLocal=98
150106f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1502c2aa98e2SPeter Wemm
150306f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
150440266059SGregory Neil Shapiro######################################################################
150540266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
150640266059SGregory Neil Shapiro###
150740266059SGregory Neil Shapiro###	Parameters:
150840266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
150940266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
151040266059SGregory Neil Shapiro###		<$3> -- +detail information
151140266059SGregory Neil Shapiro###
151240266059SGregory Neil Shapiro###	Returns:
151340266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
151440266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
151540266059SGregory Neil Shapiro######################################################################
151640266059SGregory Neil Shapiro
151706f25ae9SGregory Neil ShapiroSLDAPExpand
151806f25ae9SGregory Neil Shapiro# do the LDAP lookups
151940266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
152006f25ae9SGregory Neil Shapiro
1521e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1522e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1523e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1524e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1525e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
15265b0945b5SGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: _TMPFMSG_(`OPM')')
1527e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1528e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1529605302a5SGregory Neil Shapiro
153006f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
153106f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
153240266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
153340266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
153440266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
153540266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
153640266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
153706f25ae9SGregory Neil Shapiro
153894c01205SGregory Neil Shapiro
153906f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
154006f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
154140266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
154240266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
154340266059SGregory Neil Shapiro# check mailertable for host, relay from there
154440266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
154540266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
154640266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
154740266059SGregory Neil Shapiro# check mailertable for host, relay from there
154840266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
154940266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
155006f25ae9SGregory Neil Shapiro
155106f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
155206f25ae9SGregory Neil Shapiro# return original address
155340266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
155406f25ae9SGregory Neil Shapiro
155594c01205SGregory Neil Shapiro
155606f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
155706f25ae9SGregory Neil Shapiro# relay to mailHost with original address
155840266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
155940266059SGregory Neil Shapiro# check mailertable for host, relay from there
156040266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
156140266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
156206f25ae9SGregory Neil Shapiro
156340266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
156440266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
156540266059SGregory Neil Shapiro# try without +detail
156640266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
156740266059SGregory Neil Shapiro
15689bd497b8SGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `
15699bd497b8SGregory Neil Shapiro# pretend we did the @domain lookup
15709bd497b8SGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
157140266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
157206f25ae9SGregory Neil Shapiro# try @domain
157340266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
157440266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1575e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
157606f25ae9SGregory Neil Shapiro
157706f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
157806f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
157906f25ae9SGregory Neil Shapiro# user does not exist
158040266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
158140266059SGregory Neil Shapiro# only give error for envelope recipient
158240266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1583e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1584e92d3f3fSGregory Neil Shapiro# and the sender too
1585e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
158640266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
158706f25ae9SGregory Neil Shapiro`dnl
158806f25ae9SGregory Neil Shapiro# return the original address
1589ba00ec3dSGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')
1590ba00ec3dSGregory Neil Shapiro')
1591ba00ec3dSGregory Neil Shapiro
159206f25ae9SGregory Neil Shapiro
159306f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
159406f25ae9SGregory Neil Shapiro')')
159540266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1596c2aa98e2SPeter Wemm######################################################################
159740266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1598c2aa98e2SPeter Wemm###
1599c2aa98e2SPeter Wemm###	Parameters:
1600c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1601c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
160206f25ae9SGregory Neil Shapirodnl			must not be empty
160340266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
160406f25ae9SGregory Neil Shapiro###			! does lookup only with tag
160506f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
160640266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
160706f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
160806f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1609c2aa98e2SPeter Wemm######################################################################
1610c2aa98e2SPeter Wemm
161140266059SGregory Neil ShapiroSD
161206f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
161306f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
161440266059SGregory Neil Shapirodnl    2    3  4    5
161540266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
161606f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
161706f25ae9SGregory Neil Shapirodnl lookup without tag?
161840266059SGregory Neil Shapirodnl   1    2      3    4
161940266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
162040266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
162140266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
162240266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
162340266059SGregory Neil Shapirodnl   1  2    3    4  5    6
162440266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
162540266059SGregory Neil Shapirodnl   1  2    3      4    5
162640266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
162740266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
162840266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
162940266059SGregory Neil Shapirodnl      1    2    3  4    5
163040266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
163140266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
163240266059SGregory Neil Shapirodnl    1  2     3    4  5    6
163340266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
163440266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
163540266059SGregory Neil Shapiro`dnl not found: IPv6 net
163640266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
163740266059SGregory Neil Shapirodnl    1   2     3    4  5    6
163840266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
163940266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
164006f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
164140266059SGregory Neil Shapirodnl   1  2    3    4  5    6
164240266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
164340266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
164440266059SGregory Neil Shapirodnl   1    2      3    4
164540266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
164640266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
164740266059SGregory Neil Shapirodnl   1    2    3  4    5
164840266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
164940266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
165040266059SGregory Neil Shapirodnl            2    3    4  5    6
165140266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
165240266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
165340266059SGregory Neil Shapirodnl    2    3    4  5    6
165440266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1655c2aa98e2SPeter Wemm
1656c2aa98e2SPeter Wemm######################################################################
165740266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1658c2aa98e2SPeter Wemm###
1659c2aa98e2SPeter Wemm###	Parameters:
1660c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1661c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
166206f25ae9SGregory Neil Shapirodnl			must not be empty
166340266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
166406f25ae9SGregory Neil Shapiro###			! does lookup only with tag
166506f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
166640266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
166706f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
166806f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1669c2aa98e2SPeter Wemm######################################################################
1670c2aa98e2SPeter Wemm
167140266059SGregory Neil ShapiroSA
167206f25ae9SGregory Neil Shapirodnl lookup with tag
167340266059SGregory Neil Shapirodnl    2    3  4    5
167440266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
167506f25ae9SGregory Neil Shapirodnl lookup without tag
167640266059SGregory Neil Shapirodnl   1    2      3    4
167740266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
167840266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
167940266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
168040266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
168140266059SGregory Neil Shapirodnl      1    2    3  4    5
168240266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
168340266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
168440266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
168540266059SGregory Neil Shapirodnl   1   2    3    4  5    6
168640266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
168740266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
168806f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
168940266059SGregory Neil Shapirodnl   1  2    3    4  5    6
169040266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
169106f25ae9SGregory Neil Shapirodnl no match: return default
169240266059SGregory Neil Shapirodnl   1    2    3  4    5
169340266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
169440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
169540266059SGregory Neil Shapirodnl            2    3    4  5    6
169640266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
169706f25ae9SGregory Neil Shapirodnl match: return result
169840266059SGregory Neil Shapirodnl    2    3    4  5    6
169940266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
170040266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
170140266059SGregory Neil Shapirodivert(0)
1702c2aa98e2SPeter Wemm######################################################################
1703065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1704065a643dSPeter Wemm###			relay checking.  Route address syntax is
1705065a643dSPeter Wemm###			crudely converted into a %-hack address.
1706065a643dSPeter Wemm###
1707065a643dSPeter Wemm###	Parameters:
1708065a643dSPeter Wemm###		$1 -- full recipient address
1709065a643dSPeter Wemm###
1710065a643dSPeter Wemm###	Returns:
1711065a643dSPeter Wemm###		parsed address, not in source route form
171206f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
171306f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1714065a643dSPeter Wemm######################################################################
1715065a643dSPeter Wemm
1716065a643dSPeter WemmSCanonAddr
171706f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
171806f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1719065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1720065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1721065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
172206f25ae9SGregory Neil Shapirodnl')
1723065a643dSPeter Wemm
1724065a643dSPeter Wemm######################################################################
1725c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1726c2aa98e2SPeter Wemm###			$* $=m or the access database.
1727c2aa98e2SPeter Wemm###			Check user portion for host separators.
1728c2aa98e2SPeter Wemm###
1729c2aa98e2SPeter Wemm###	Parameters:
1730c2aa98e2SPeter Wemm###		$1 -- full recipient address
1731c2aa98e2SPeter Wemm###
1732c2aa98e2SPeter Wemm###	Returns:
1733c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1734c2aa98e2SPeter Wemm######################################################################
1735c2aa98e2SPeter Wemm
1736c2aa98e2SPeter WemmSParseRecipient
173706f25ae9SGregory Neil Shapirodnl mark and canonify address
1738065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
173906f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1740c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
174106f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1742c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1743c2aa98e2SPeter Wemm
1744c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1745c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
174606f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1747c2aa98e2SPeter WemmR<?> $*				$@ $1
1748c2aa98e2SPeter Wemm
174940266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
175006f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1751c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1752c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1753c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
175406f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
175506f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
175640266059SGregory Neil Shapiro
175740266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
175840266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
17595b0945b5SGregory Neil Shapirodnl other To: entries: blocklist recipient; generic entries?
176040266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1761c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1762c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
176306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
176406f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1765065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1766c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
176706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
176840266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1769c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1770065a643dSPeter Wemm
177106f25ae9SGregory Neil Shapiro
177240266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
177340266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
177440266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1775e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
177640266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
177740266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
177840266059SGregory Neil Shapirodnl no: put old <NO> mark back
177940266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
178040266059SGregory Neil Shapiro
178140266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1782c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
178340266059SGregory Neil Shapirodnl something else
178440266059SGregory Neil ShapiroR<$+> $*			$@ $2
1785c2aa98e2SPeter Wemm
178606f25ae9SGregory Neil Shapiro
1787c2aa98e2SPeter Wemm######################################################################
1788c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1789c2aa98e2SPeter Wemm######################################################################
1790c2aa98e2SPeter Wemm
1791e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1792e92d3f3fSGregory Neil ShapiroScheck_relay
1793e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1794e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1795e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1796e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1797e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1798e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1799e92d3f3fSGregory Neil Shapirodnl')
1800e92d3f3fSGregory Neil Shapiro
1801c2aa98e2SPeter WemmSLocal_check_relay
180206f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1803e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1804e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1805c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1806c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1807c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1808c2aa98e2SPeter Wemm
1809c2aa98e2SPeter WemmSBasic_check_relay
1810c2aa98e2SPeter Wemm# check for deferred delivery mode
181194c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1812c2aa98e2SPeter WemmR< d > $*		$@ deferred
1813c2aa98e2SPeter WemmR< $* > $*		$: $2
1814c2aa98e2SPeter Wemm
181506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
181642e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
181740266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
181842e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
181913bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
182013bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
182113bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
182240266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
182340266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
182440266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
182540266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
182642e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1827e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
182840266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1829e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
183006f25ae9SGregory Neil Shapirodnl error tag
183142e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
183242e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
18335b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: _TMPFMSG_(`CR')', `dnl')
183406f25ae9SGregory Neil Shapirodnl generic error from access map
183542e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1836c2aa98e2SPeter Wemm
1837c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
183806f25ae9SGregory Neil Shapiro# DNS based IP address spam list
183940266059SGregory Neil Shapirodnl workspace: ignored...
1840c2aa98e2SPeter WemmR$*			$: $&{client_addr}
184106f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
184206f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
184394c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1844c2aa98e2SPeter Wemm`dnl')
1845e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1846e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1847e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1848e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1849e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1850e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1851e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1852e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
18536f9c8e5bSGregory Neil Shapiroundivert(8)dnl LOCAL_DNSBL
1854d0cef73dSGregory Neil Shapiroifdef(`_REQUIRE_RDNS_', `dnl
1855d0cef73dSGregory Neil ShapiroR$*			$: $&{client_addr} $| $&{client_resolve}
1856d0cef73dSGregory Neil ShapiroR$=R $*			$@ RELAY		We relay for these
1857d0cef73dSGregory Neil ShapiroR$* $| OK		$@ OK			Resolves.
1858d0cef73dSGregory Neil ShapiroR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1859d0cef73dSGregory Neil ShapiroR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1860d0cef73dSGregory Neil ShapiroR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1861d0cef73dSGregory Neil Shapiro', `dnl')
1862c2aa98e2SPeter Wemm
1863c2aa98e2SPeter Wemm######################################################################
1864c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1865c2aa98e2SPeter Wemm######################################################################
1866c2aa98e2SPeter Wemm
1867c2aa98e2SPeter WemmSLocal_check_mail
186806f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1869c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1870c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1871c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1872c2aa98e2SPeter Wemm
1873c2aa98e2SPeter WemmSBasic_check_mail
1874c2aa98e2SPeter Wemm# check for deferred delivery mode
187594c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1876c2aa98e2SPeter WemmR< d > $*		$@ deferred
1877c2aa98e2SPeter WemmR< $* > $*		$: $2
1878c2aa98e2SPeter Wemm
187906f25ae9SGregory Neil Shapiro# authenticated?
188006f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
188106f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
188206f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
188306f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
188406f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
188506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
188606f25ae9SGregory Neil Shapiro
188706f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
188806f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
188906f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
189006f25ae9SGregory Neil Shapirodnl do some additional checks
189106f25ae9SGregory Neil Shapirodnl no user@host
189206f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
189306f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
189406f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
189506f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
189606f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
189706f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
189806f25ae9SGregory Neil ShapiroR$+			$: <?> $1
189906f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
190006f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
190106f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
190206f25ae9SGregory Neil Shapirodnl prepend daemon_flags
190306f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
190406f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
190506f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
190606f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
190706f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
190806f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
190906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
191006f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
191106f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
191206f25ae9SGregory Neil Shapirodnl remove daemon_flags
191306f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
191406f25ae9SGregory Neil Shapiro# handle case of @localhost on address
191506f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
191606f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
191706f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
1918da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] >
1919da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] >
1920da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:::1] >
1921da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:::1] >
192206f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
192306f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
192406f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
192506f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
192606f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
192706f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
192806f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
192906f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
193006f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
193106f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
193206f25ae9SGregory Neil Shapirodnl	or:    <address>
193306f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
193406f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
193540266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
193606f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
193706f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
193806f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
193906f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
194006f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
194106f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1942065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1943c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1944959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
194506f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
194694c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1947959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1948c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
194940266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
195006f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
195106f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
195206f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
195340266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
195406f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1955c2aa98e2SPeter Wemm
195606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
195706f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
195806f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
195940266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
196040266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
196106f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
196206f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
196306f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
196406f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
196506f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
196606f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
196706f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
196806f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1969c2aa98e2SPeter Wemm# retransform for further use
197006f25ae9SGregory Neil Shapirodnl required form:
197106f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
197206f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
197306f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
197406f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
197506f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1976c2aa98e2SPeter Wemm
1977c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1978c2aa98e2SPeter Wemm# handle case of no @domain on address
197906f25ae9SGregory Neil Shapirodnl prepend daemon_flags
198006f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
198106f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
198240266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
198306f25ae9SGregory Neil Shapirodnl remove daemon_flags
198406f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
198513bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1986959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
198740266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1988c2aa98e2SPeter Wemm							...remote is not')
1989c2aa98e2SPeter Wemm# check results
199006f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1991d0cef73dSGregory Neil ShapiroR<$={ResOk}> $*		$: @ $2		domain ok
199206f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
199340266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
199406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
199540266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1996c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
1997e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
1998e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
199906f25ae9SGregory Neil Shapirodnl error tag
200006f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
200106f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
20025b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`CM')', `dnl')
200306f25ae9SGregory Neil Shapirodnl generic error from access map
200406f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
2005c2aa98e2SPeter Wemm`dnl')
2006d0cef73dSGregory Neil Shapirodnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
2007d0cef73dSGregory Neil Shapiro
2008d0cef73dSGregory Neil Shapiroifdef(`_BADMX_CHK_', `dnl
2009d0cef73dSGregory Neil ShapiroR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
2010d0cef73dSGregory Neil ShapiroR$* $| $#$*		$#$2
2011d0cef73dSGregory Neil Shapiro
2012d0cef73dSGregory Neil ShapiroSBadMX
2013d0cef73dSGregory Neil Shapiro# Look up MX records and ferret away a copy of the original address.
2014d0cef73dSGregory Neil Shapiro# input: domain part of address to check
2015d0cef73dSGregory Neil ShapiroR$+				$:<MX><$1><:$(mxlist $1$):><:>
2016d0cef73dSGregory Neil Shapiro# workspace: <MX><domain><: mxlist-result $><:>
2017d0cef73dSGregory Neil ShapiroR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
2018d0cef73dSGregory Neil Shapiro# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
2019d0cef73dSGregory Neil Shapiro# Recursively run badmx check on each mx.
2020d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
2021d0cef73dSGregory Neil Shapiro# See if any of them fail.
2022e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
2023d0cef73dSGregory Neil Shapiro# Reverse the mxlists so we can use the same argument order again.
2024d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2025d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
2026d0cef73dSGregory Neil Shapiro
2027d0cef73dSGregory Neil Shapiro# Reverse the lists so we can use the same argument order again.
2028d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2029d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
2030d0cef73dSGregory Neil Shapiro
2031e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
2032d0cef73dSGregory Neil Shapiro`dnl')
2033d0cef73dSGregory Neil Shapiro
2034c2aa98e2SPeter Wemm
2035c2aa98e2SPeter Wemm######################################################################
2036c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
2037c2aa98e2SPeter Wemm######################################################################
2038c2aa98e2SPeter Wemm
2039c2aa98e2SPeter WemmSLocal_check_rcpt
204006f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
2041c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
2042c2aa98e2SPeter WemmR$* $| $#$*		$#$2
2043c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
2044c2aa98e2SPeter Wemm
2045c2aa98e2SPeter WemmSBasic_check_rcpt
204640266059SGregory Neil Shapiro# empty address?
204740266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
204840266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
2049c2aa98e2SPeter Wemm# check for deferred delivery mode
205094c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
2051c2aa98e2SPeter WemmR< d > $*		$@ deferred
2052c2aa98e2SPeter WemmR< $* > $*		$: $2
2053c2aa98e2SPeter Wemm
205406f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
205540266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
205640266059SGregory Neil Shapirodnl it is not activated.
205740266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
205840266059SGregory Neil Shapirodnl available down below; look for the same macro.
205940266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
206040266059SGregory Neil Shapirodnl canonicalization.
206140266059SGregory Neil Shapiro# require fully qualified domain part?
206240266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
206306f25ae9SGregory Neil ShapiroR$+			$: <?> $1
206406f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
206506f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
206640266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
206713bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
206806f25ae9SGregory Neil Shapirodnl prepend daemon_flags
206940266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
207006f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
2071af9557fdSGregory Neil Shapirodnl _r_equire qual.rcpt: ok
2072a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
207306f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
2074a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
207506f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
207606f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
207740266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
207806f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
207906f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
208006f25ae9SGregory Neil Shapiro
208140266059SGregory Neil Shapirodnl ##################################################################
208240266059SGregory Neil Shapirodnl call subroutines for recipient and relay
208340266059SGregory Neil Shapirodnl possible returns from subroutines:
208440266059SGregory Neil Shapirodnl $#TEMP	temporary failure
208540266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
208640266059SGregory Neil Shapirodnl $#other	stop processing
208740266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
208840266059SGregory Neil Shapirodnl other	otherwise
208940266059SGregory Neil Shapiro######################################################################
209040266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
209140266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
209240266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
209340266059SGregory Neil Shapirodnl error or ok (stop)
209440266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
209540266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
209640266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
209740266059SGregory Neil Shapirodnl something else: call check sender (relay)
209840266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
209940266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
210040266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
210140266059SGregory Neil Shapirodnl temporary failure? return that
210240266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
210340266059SGregory Neil Shapirodnl error or ok (stop)
210440266059SGregory Neil ShapiroR$* $| $#$*		$#$2
210540266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
210640266059SGregory Neil Shapirodnl something else: return previous temp failure
210740266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
210840266059SGregory Neil Shapiro# anything else is bogus
210940266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
211040266059SGregory Neil Shapirodivert(0)
211140266059SGregory Neil Shapiro
211240266059SGregory Neil Shapiro######################################################################
211340266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
211440266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
211540266059SGregory Neil Shapirodnl output: see explanation at call
211640266059SGregory Neil Shapiro######################################################################
211740266059SGregory Neil ShapiroSRcpt_ok
2118c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2119065a643dSPeter WemmR$*			$: $>CanonAddr $1
2120c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2121c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2122c2aa98e2SPeter Wemm
2123065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2124065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2125065a643dSPeter Wemm# unlimited bestmx
2126065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2127065a643dSPeter Wemm`dnl
2128065a643dSPeter Wemm# limit bestmx to $=B
21292e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
213040266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2131065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2132065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2133065a643dSPeter Wemm
21345b0945b5SGregory Neil Shapiroifdef(`_BLOCKLIST_RCPT_',`dnl
213506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21365b0945b5SGregory Neil Shapiro# blocklist local users or any host from receiving mail
2137c2aa98e2SPeter WemmR$*			$: <?> $1
213806f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
213906f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
214040266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
214140266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
214206f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
214306f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
214406f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
214506f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
214606f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
214706f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
214840266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
214940266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
215040266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
215140266059SGregory Neil Shapirodnl that would make a lot of things easier.
215206f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
215340266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
215440266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
215540266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
215640266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
215706f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
215806f25ae9SGregory Neil Shapirodnl as generic error message...
215906f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
216006f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
216106f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
216206f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
216340266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
216406f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2165e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
216606f25ae9SGregory Neil Shapirodnl error tag
216706f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
216806f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
21695b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`ROK1')', `dnl')
217006f25ae9SGregory Neil Shapirodnl generic error from access map
217106f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
217206f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2173c2aa98e2SPeter Wemm
217440266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
217540266059SGregory Neil Shapiro# authenticated via TLS?
217640266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
217706f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
217806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
217906f25ae9SGregory Neil Shapiro
218040266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
218140266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
218240266059SGregory Neil ShapiroR$* $| $# $*		$# $2
218340266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
218440266059SGregory Neil ShapiroR$* $| NO		$: $1
218540266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
218640266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
218706f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
218806f25ae9SGregory Neil ShapiroR$* $|			$: $1
218906f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
219006f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
219140266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
219240266059SGregory Neil Shapirodnl remove ${auth_type}
219306f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2194193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
219506f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2196193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2197193538b7SGregory Neil ShapiroR$* ! $*		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2198da7d7b9cSGregory Neil Shapiroifelse(defn(`_NO_PERCENTHACK_'), `r',
2199da7d7b9cSGregory Neil Shapiro`R$* % $* < @ $* >	$: <REMOTE> $1 < @ PERCENT_HACK >
2200da7d7b9cSGregory Neil ShapiroR$* % $*		$: <REMOTE> $1 < @ PERCENT_HACK >', `dnl')
2201c2aa98e2SPeter Wemm# anything terminating locally is ok
2202c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
220340266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
220440266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2205c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
220640266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
220706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
22089bd497b8SGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
22099bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
22109bd497b8SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
22119bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
221206f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
221306f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
221440266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
221506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2216e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2217e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2218e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2219e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2220e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
222106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
222206f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
222340266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
22245b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`ROK2')', `dnl')
2225c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2226c2aa98e2SPeter Wemm
222706f25ae9SGregory Neil Shapiro
2228c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2229c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
223006f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
223106f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2232e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
223340266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2234065a643dSPeter WemmR< : $* : > $*		$: $2',
2235c2aa98e2SPeter Wemm`dnl')
2236c2aa98e2SPeter Wemm
2237c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2238c2aa98e2SPeter WemmR$*			$: <?> $1
2239065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2240c2aa98e2SPeter Wemm# local user is ok
224106f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
224206f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
224306f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
224406f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
224506f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
224640266059SGregory Neil ShapiroR<?> postmaster		$@ OK
224706f25ae9SGregory Neil Shapiro# require qualified recipient?
224806f25ae9SGregory Neil Shapirodnl prepend daemon_flags
224906f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
225006f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
225106f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
225206f25ae9SGregory Neil Shapirodnl r flag? add client_name
225306f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
225406f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
225506f25ae9SGregory Neil Shapiro# no qualified recipient required
225640266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
225706f25ae9SGregory Neil Shapirodnl client_name is empty
225840266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
225906f25ae9SGregory Neil Shapirodnl client_name is local
226040266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
226106f25ae9SGregory Neil Shapirodnl client_name is not local
226206f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
226306f25ae9SGregory Neil Shapirodnl no qualified recipient required
226440266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
226506f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2266c2aa98e2SPeter WemmR<$+> $*		$: $2
226706f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2268c2aa98e2SPeter Wemm
226940266059SGregory Neil Shapiro######################################################################
227040266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
227140266059SGregory Neil Shapirodnl input: ignored
227240266059SGregory Neil Shapirodnl output: see explanation at call
227340266059SGregory Neil Shapiro######################################################################
227440266059SGregory Neil ShapiroSRelay_ok
2275c2aa98e2SPeter Wemm# anything originating locally is ok
2276c2aa98e2SPeter Wemm# check IP address
2277c2aa98e2SPeter WemmR$*			$: $&{client_addr}
227840266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
227940266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
228013bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
2281da7d7b9cSGregory Neil ShapiroRIPv6:0:0:0:0:0:0:0:1	$@ RELAY		originated locally
2282da7d7b9cSGregory Neil Shapirodnl if compiled with IPV6_FULL=0
228313bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
228440266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
228506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
228640266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
228740266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY		relayable IP address
2288959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2289959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2290959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2291959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2292959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2293959366dcSGregory Neil ShapiroR<REJECT> $*		$@ REJECT		rejected IP address')
22945b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl')
2295c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2296c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
229740266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2298c2aa98e2SPeter Wemm
229906f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
230006f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
230106f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
230206f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
230306f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
230406f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
230506f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
230640266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2307c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
230806f25ae9SGregory Neil Shapiro# check whether local FROM is ok
230940266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
231006f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2311605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
231240266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
23135b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK2')', `dnl')
231440266059SGregory Neil Shapiro', `dnl
231540266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
231640266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
231706f25ae9SGregory Neil Shapiro')',
231806f25ae9SGregory Neil Shapiro`dnl')
231906f25ae9SGregory Neil Shapirodnl')', `dnl')
232040266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
232140266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
232240266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
232306f25ae9SGregory Neil Shapiro
232406f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
232506f25ae9SGregory Neil Shapirodnl input: ignored
232606f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2327e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
232806f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
232906f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
233006f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
233140266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
233206f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
233313bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
233413bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
233513bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
233613bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
233713bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
233840266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
233940266059SGregory Neil Shapiro# pass to name server to make hostname canonical
234040266059SGregory Neil ShapiroR<@> $* $=P		$:<?>  $1 $2
234140266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
234240266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
234340266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
234406f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
234540266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
234640266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
234706f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
234840266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
234906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235006f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
235106f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
235240266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
235306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235440266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
235506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235640266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
23575b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK3')', `dnl')
235806f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
235940266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
236006f25ae9SGregory Neil Shapirodivert(0)
236106f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
236206f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
236306f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
236406f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
236506f25ae9SGregory Neil ShapiroSFullAddr
236606f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
236706f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
236806f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2369c2aa98e2SPeter Wemm
2370a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
237113bd1963SGregory Neil Shapiro# authenticated?
237213bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
237313bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
237413bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
237513bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
237613bd1963SGregory Neil Shapirodnl return result from checkrcpt
2377a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
237813bd1963SGregory Neil ShapiroR$*			$# $1
237913bd1963SGregory Neil Shapiro
2380a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
238113bd1963SGregory Neil Shapiro# authenticated?
238213bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
238313bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
238413bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
238513bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
238613bd1963SGregory Neil Shapirodnl return result from friend/hater check
2387a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
238813bd1963SGregory Neil ShapiroR$*			$@ $1
238913bd1963SGregory Neil Shapiro
239006f25ae9SGregory Neil Shapiro# call all necessary rulesets
239106f25ae9SGregory Neil ShapiroScheck_rcpt
239206f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
239306f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
239406f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
239513bd1963SGregory Neil Shapiro
239606f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
239706f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
239813bd1963SGregory Neil Shapirodnl on error (or discard) stop now
239913bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
240013bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
240113bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2402a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
240306f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
240406f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
240506f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
240606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
240706f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
240806f25ae9SGregory Neil Shapiro')')dnl
240906f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
24105b0945b5SGregory Neil Shapirodnl this code has been copied from BLOCKLIST... etc
241106f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
241240266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
241340266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
241406f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
241540266059SGregory Neil Shapiro# lookup the addresses only with Spam tag
241640266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
241706f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
241806f25ae9SGregory Neil Shapirodnl', `dnl')
241906f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
242006f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
242106f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
242213bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
242306f25ae9SGregory Neil Shapiro')', `dnl')
2424a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
242506f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
242606f25ae9SGregory Neil Shapiro`dnl')
242706f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
242806f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
242940266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2430a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
243106f25ae9SGregory Neil Shapirodnl',`dnl')
2432d0cef73dSGregory Neil Shapiro
243306f25ae9SGregory Neil Shapirodnl run further checks: check_mail
243406f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
243540266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
243640266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
243740266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2438605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
243906f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
244006f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2441605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
244206f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
244306f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
244406f25ae9SGregory Neil Shapiro', `dnl')
244540266059SGregory Neil Shapiro
2446d0cef73dSGregory Neil Shapiroifdef(`_BLOCK_BAD_HELO_', `dnl
2447d0cef73dSGregory Neil ShapiroR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2448d0cef73dSGregory Neil Shapirodnl Bypass the test for users who have authenticated.
2449d0cef73dSGregory Neil ShapiroR$* $| <$+>		$: $1				skip if auth
2450d0cef73dSGregory Neil ShapiroR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2451d0cef73dSGregory Neil Shapirodnl Bypass for local clients -- IP address starts with $=R
2452d0cef73dSGregory Neil ShapiroR$* $| <$=R $*> [$*]	$: $1				skip if local client
2453d0cef73dSGregory Neil Shapirodnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2454d0cef73dSGregory Neil ShapiroR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2455d0cef73dSGregory Neil Shapirodnl Reject our IP - assumes "[ip]" is in class $=w
2456d0cef73dSGregory Neil ShapiroR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2457d0cef73dSGregory Neil Shapirodnl Reject our hostname
2458d0cef73dSGregory Neil ShapiroR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2459d0cef73dSGregory Neil Shapirodnl Pass anything else with a "." in the domain parameter
2460d0cef73dSGregory Neil ShapiroR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
24615dd76dd0SGregory Neil Shapirodnl Pass IPv6: address literals
24625dd76dd0SGregory Neil ShapiroR$* $| <$*> [IPv6:$+]	$: $1				qualified domain ok
2463d0cef73dSGregory Neil Shapirodnl Reject if there was no "." or only an initial or final "."
2464d0cef73dSGregory Neil ShapiroR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2465d0cef73dSGregory Neil Shapirodnl Clean up the workspace
2466d0cef73dSGregory Neil ShapiroR$* $| $*		$: $1
2467d0cef73dSGregory Neil Shapiro', `dnl')
2468d0cef73dSGregory Neil Shapiro
246940266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
247040266059SGregory Neil Shapiro######################################################################
247140266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
247240266059SGregory Neil Shapiro###
247340266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
247440266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
247540266059SGregory Neil Shapiro###
247640266059SGregory Neil Shapiro###	Parameters:
247740266059SGregory Neil Shapiro###		<$1> -- key
247840266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
247940266059SGregory Neil Shapirodnl			must not be empty
248040266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
248140266059SGregory Neil Shapiro###			! does lookup only with tag
248240266059SGregory Neil Shapiro###			+ does lookup with and without tag
248340266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
248440266059SGregory Neil Shapirodnl returns:		<default> <passthru>
248540266059SGregory Neil Shapirodnl			<result> <passthru>
248640266059SGregory Neil Shapiro######################################################################
248740266059SGregory Neil Shapiro
248840266059SGregory Neil ShapiroSF
248940266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
249040266059SGregory Neil Shapirodnl full lookup
249140266059SGregory Neil Shapirodnl    2    3  4    5
249240266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
249340266059SGregory Neil Shapirodnl no match, try without tag
249440266059SGregory Neil Shapirodnl   1    2      3    4
249540266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
249640266059SGregory Neil Shapirodnl no match, +detail: try +*
249740266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
249840266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
249940266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
250040266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
250140266059SGregory Neil Shapirodnl   1    2    3    4      5    6
250240266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
250340266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
250440266059SGregory Neil Shapirodnl no match, +detail: try without +detail
250540266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
250640266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
250740266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
250840266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
250940266059SGregory Neil Shapirodnl   1    2    3    4      5    6
251040266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
251140266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
251240266059SGregory Neil Shapirodnl no match, return <default> <passthru>
251340266059SGregory Neil Shapirodnl   1    2    3  4    5
251440266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
251540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
251640266059SGregory Neil Shapirodnl            2    3  4    5
251740266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
251840266059SGregory Neil Shapirodnl match, return <match> <passthru>
251940266059SGregory Neil Shapirodnl    2    3  4    5
252040266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
252140266059SGregory Neil Shapiro
252240266059SGregory Neil Shapiro######################################################################
252340266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
252440266059SGregory Neil Shapiro###
252540266059SGregory Neil Shapiro###	Parameters:
252640266059SGregory Neil Shapiro###		<$1> -- key
252740266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
252840266059SGregory Neil Shapirodnl			must not be empty
252940266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
253040266059SGregory Neil Shapiro###			! does lookup only with tag
253140266059SGregory Neil Shapiro###			+ does lookup with and without tag
253240266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
253340266059SGregory Neil Shapirodnl returns:		<default> <passthru>
253440266059SGregory Neil Shapirodnl			<result> <passthru>
253540266059SGregory Neil Shapiro######################################################################
253640266059SGregory Neil Shapiro
253740266059SGregory Neil ShapiroSE
253840266059SGregory Neil Shapirodnl    2    3  4    5
253940266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
254040266059SGregory Neil Shapirodnl no match, try without tag
254140266059SGregory Neil Shapirodnl   1    2      3    4
254240266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
254340266059SGregory Neil Shapirodnl no match, return default passthru
254440266059SGregory Neil Shapirodnl   1    2    3  4    5
254540266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
254640266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
254740266059SGregory Neil Shapirodnl            2    3  4    5
254840266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
254940266059SGregory Neil Shapirodnl match, return <match> <passthru>
255040266059SGregory Neil Shapirodnl    2    3  4    5
255140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
255240266059SGregory Neil Shapiro
255340266059SGregory Neil Shapiro######################################################################
255440266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
255540266059SGregory Neil Shapiro###
255640266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
255740266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
255840266059SGregory Neil Shapiro###
255940266059SGregory Neil Shapiro###	Parameters:
256040266059SGregory Neil Shapiro###		<$1> -- key (user@)
256140266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
256240266059SGregory Neil Shapirodnl			must not be empty
256340266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
256440266059SGregory Neil Shapiro###			! does lookup only with tag
256540266059SGregory Neil Shapiro###			+ does lookup with and without tag
256640266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
256740266059SGregory Neil Shapirodnl returns:		<default> <passthru>
256840266059SGregory Neil Shapirodnl			<result> <passthru>
256940266059SGregory Neil Shapiro######################################################################
257040266059SGregory Neil Shapiro
257140266059SGregory Neil ShapiroSU
257240266059SGregory Neil Shapirodnl user lookups are always with trailing @
257340266059SGregory Neil Shapirodnl    2    3  4    5
257440266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
257540266059SGregory Neil Shapirodnl no match, try without tag
257640266059SGregory Neil Shapirodnl   1    2      3    4
257740266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
257840266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
257940266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
258040266059SGregory Neil Shapirodnl no match, +detail: try +*
258140266059SGregory Neil Shapirodnl   1    2      3    4  5    6
258240266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
258340266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
258440266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
258540266059SGregory Neil Shapirodnl   1    2      3      4    5
258640266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
258740266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
258840266059SGregory Neil Shapirodnl no match, +detail: try without +detail
258940266059SGregory Neil Shapirodnl   1    2      3    4  5    6
259040266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
259140266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
259240266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
259340266059SGregory Neil Shapirodnl   1    2      3      4    5
259440266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
259540266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
259640266059SGregory Neil Shapirodnl no match, return <default> <passthru>
259740266059SGregory Neil Shapirodnl   1    2    3  4    5
259840266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
259940266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
260040266059SGregory Neil Shapirodnl            2    3  4    5
260140266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
260240266059SGregory Neil Shapirodnl match, return <match> <passthru>
260340266059SGregory Neil Shapirodnl    2    3  4    5
260440266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
260540266059SGregory Neil Shapiro
260606f25ae9SGregory Neil Shapiro######################################################################
260706f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
260806f25ae9SGregory Neil Shapiro###	Parameters:
260906f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
261006f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
261106f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
261206f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
261306f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
261440266059SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: D: if there
261506f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
261606f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
261706f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
261806f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
261906f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
262006f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
262106f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
262206f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
262306f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
262440266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
262506f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
262606f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
262706f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
262806f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
262906f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
263006f25ae9SGregory Neil Shapiro######################################################################
263106f25ae9SGregory Neil Shapiro
263206f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
263306f25ae9SGregory Neil Shapirodnl if A is activated: add it
2634e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
263506f25ae9SGregory Neil ShapiroSSearchList
263640266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
263740266059SGregory Neil Shapirodnl       2       3    4
2638e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
263940266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
264040266059SGregory Neil Shapirodnl no match and nothing left: return
264140266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
264240266059SGregory Neil Shapirodnl no match but something left: continue
264340266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
264440266059SGregory Neil Shapirodnl match: return
264540266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
264606f25ae9SGregory Neil Shapirodnl return result from recursive invocation
264740266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
264840266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
264940266059SGregory Neil Shapirodivert(0)
265006f25ae9SGregory Neil Shapiro
265140266059SGregory Neil Shapiro######################################################################
265240266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
265340266059SGregory Neil Shapiro###
265440266059SGregory Neil Shapiro###	Parameters:
265540266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
265640266059SGregory Neil Shapiro######################################################################
265740266059SGregory Neil Shapiro
265840266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
265940266059SGregory Neil ShapiroSLocal_trust_auth
266006f25ae9SGregory Neil ShapiroStrust_auth
266106f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
266206f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
266306f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
266406f25ae9SGregory Neil Shapirodnl seems to be useful...
266506f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
266606f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
266706f25ae9SGregory Neil Shapirodnl call user supplied code
2668a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
266906f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
267006f25ae9SGregory Neil Shapirodnl default: error
267106f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
267206f25ae9SGregory Neil Shapiro
267340266059SGregory Neil Shapiro######################################################################
267440266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
267540266059SGregory Neil Shapiro###
267640266059SGregory Neil Shapiro###	Parameters:
267740266059SGregory Neil Shapiro###		$1: ${auth_type}
267840266059SGregory Neil Shapiro######################################################################
267940266059SGregory Neil ShapiroSLocal_Relay_Auth
268006f25ae9SGregory Neil Shapiro
268140266059SGregory Neil Shapiro######################################################################
268240266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
268340266059SGregory Neil Shapiro###	(done in server)
268440266059SGregory Neil Shapiro######################################################################
268540266059SGregory Neil ShapiroSsrv_features
268640266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
268740266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
268840266059SGregory Neil ShapiroR$* $| $#$*		$#$2
268940266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2690e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
269140266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
269240266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
269340266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
269406f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
269540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
269640266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2697e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
269806f25ae9SGregory Neil Shapiro
269940266059SGregory Neil Shapiro######################################################################
27002fb4f839SGregory Neil Shapiro###  clt_features: which features to use with a server?
27012fb4f839SGregory Neil Shapiro###	(done in client)
27022fb4f839SGregory Neil Shapiro######################################################################
27032fb4f839SGregory Neil ShapiroSclt_features
27042fb4f839SGregory Neil Shapiroifdef(`_LOCAL_CLT_FEATURES_', `dnl
27052fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"Local_clt_features" $1
27062fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
27072fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
27082fb4f839SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
27092fb4f839SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! CLT_FEAT_TAG> <>
27102fb4f839SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! CLT_FEAT_TAG> <>
27112fb4f839SGregory Neil ShapiroR<?>$*		$: <$(access CLT_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
27122fb4f839SGregory Neil ShapiroR<?>$*		$@ OK
27132fb4f839SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27142fb4f839SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
27152fb4f839SGregory Neil ShapiroR<$+>$*		$# $1')
27162fb4f839SGregory Neil Shapiro
27172fb4f839SGregory Neil Shapiro######################################################################
271840266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
271940266059SGregory Neil Shapiro###	(done in client)
272040266059SGregory Neil Shapiro######################################################################
272106f25ae9SGregory Neil ShapiroStry_tls
272240266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
272340266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
272440266059SGregory Neil ShapiroR$* $| $#$*		$#$2
272540266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2726e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
272740266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
272840266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
272940266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
273006f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
273140266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27325b0945b5SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl')
2733e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
273406f25ae9SGregory Neil Shapiro
27352fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
27362fb4f839SGregory Neil ShapiroSTLS_NameInList
27372fb4f839SGregory Neil ShapiroR$* :$&{TLS_Name}: $*	$@ ok
27382fb4f839SGregory Neil ShapiroR$*			$@ $1
27392fb4f839SGregory Neil Shapiro
27402fb4f839SGregory Neil Shapirodnl check SAN for STS
27412fb4f839SGregory Neil ShapiroSSTS_SAN
27422fb4f839SGregory Neil Shapiroifdef(`_STS_SAN', `dnl
27432fb4f839SGregory Neil ShapiroR$*			$: $&{server_name}
27442fb4f839SGregory Neil Shapirodnl exact match
27452fb4f839SGregory Neil ShapiroR$={cert_altnames}	$@ ok
27462fb4f839SGregory Neil Shapiro# strip only one level (no recursion!)
27472fb4f839SGregory Neil ShapiroR$-.$+			$: $2
27482fb4f839SGregory Neil Shapirodnl wildcard: *. or just .?
27492fb4f839SGregory Neil ShapiroR *.$={cert_altnames}	$@ ok
27502fb4f839SGregory Neil Shapirodnl R .$={cert_altnames}	$@ ok
27512fb4f839SGregory Neil Shapirodnl always temporary error? make it an option (of the feature)?
27522fb4f839SGregory Neil ShapiroR$*			$#error $@ 4.7.0 $: 450 $&{server_name} not listed in SANs', `dnl')
27532fb4f839SGregory Neil Shapiro
27542fb4f839SGregory Neil Shapirodnl input: ${verify}
27552fb4f839SGregory Neil Shapirodnl output: $# error ... (from TLS_connection)
27562fb4f839SGregory Neil Shapirodnl  everything else: ok
27572fb4f839SGregory Neil ShapiroSSTS_secure
27582fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
27592fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
27602fb4f839SGregory Neil ShapiroR $| $*		$@ ok
27612fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
27622fb4f839SGregory Neil ShapiroR$*@$+ $| $*	$2 $| $3
27632fb4f839SGregory Neil ShapiroR$+. $| $*	$1 $| $2
27642fb4f839SGregory Neil ShapiroR$+ $| $*	$: $(sts $1 $: none $) $| $2
27652fb4f839SGregory Neil ShapiroR$* <TMPF> $| $*	$#error $@ 4.7.0 $: 450 STS lookup temp fail
27662fb4f839SGregory Neil Shapirodnl check whether connection is "secure"
27672fb4f839SGregory Neil Shapirodnl always temporary error? make it an option (of the feature)?
27682fb4f839SGregory Neil ShapiroR$* secure $* $| $*	$@ $>"TLS_connection" $3 $| <TEMP+VERIFY:128>
27692fb4f839SGregory Neil ShapiroR$* $| $*	$: $2
27702fb4f839SGregory Neil Shapiro
27712fb4f839SGregory Neil Shapirodnl check STS policy: secure and match? if so, check list
27722fb4f839SGregory Neil ShapiroSSTS_Check
27732fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
27742fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
27752fb4f839SGregory Neil ShapiroR $| $*		$@ ok
27762fb4f839SGregory Neil Shapiro# use the original argument for the test, not {rcpt_addr}
27772fb4f839SGregory Neil ShapiroR$* $| $*	$: $2 $| $2
27782fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
27792fb4f839SGregory Neil ShapiroR$*@$+ $| $*	$2 $| $3
27802fb4f839SGregory Neil ShapiroR$+. $| $*	$1 $| $2
27812fb4f839SGregory Neil ShapiroR$* $| $*	$: $(sts $1 $: none $) $| mark
27822fb4f839SGregory Neil ShapiroR$* <TMPF> $| $*	$#error $@ 4.7.0 $: 450 STS lookup temp fail
27832fb4f839SGregory Neil Shapirodnl STS check only for "secure"
27842fb4f839SGregory Neil Shapirodnl do this only if {sts_sni} is set?
27852fb4f839SGregory Neil Shapirodnl workspace: result of sts lookup $| mark
27862fb4f839SGregory Neil ShapiroR$* secure $* $| mark	$: $2 $| trmatch
27872fb4f839SGregory Neil Shapirodnl not "secure": no check
27882fb4f839SGregory Neil ShapiroR$* $| mark	$@ ok
27892fb4f839SGregory Neil Shapirodnl remove servername=hostname, keep match=
27902fb4f839SGregory Neil ShapiroR$* servername=hostname $| trmatch	$: $1 $| trmatch
27912fb4f839SGregory Neil Shapirodnl extra list of matches, i.e., remove match=
27922fb4f839SGregory Neil ShapiroR$+ $| trmatch				$: : $(stsxmatch $1 $: : $)
27932fb4f839SGregory Neil Shapirodnl no match= data
27942fb4f839SGregory Neil ShapiroR$* $| trmatch		$@ $>STS_SAN
27952fb4f839SGregory Neil Shapirodnl Remove trailing dots from each entry in the list;
27962fb4f839SGregory Neil Shapirodnl those should not be there, but better safe than sorry.
27972fb4f839SGregory Neil ShapiroR$*:$+.:$*	$1:$2:$3
27982fb4f839SGregory Neil ShapiroR:$+:		$: $(macro {TLS_Name} $@ $&{server_name} $) $>TLS_NameInList :$1:
27992fb4f839SGregory Neil ShapiroR$* ok		$@ $>STS_SAN
28002fb4f839SGregory Neil ShapiroR$*		$: $1 $| $&{server_name}
28012fb4f839SGregory Neil ShapiroR:$* $| $-.$+	$: $(macro {TLS_Name} $@ .$3 $) $>TLS_NameInList :$1
28022fb4f839SGregory Neil ShapiroR$* ok		$@ $>STS_SAN
28032fb4f839SGregory Neil ShapiroR:$*:		$#error $@ 4.7.0 $: 450 $&{server_name} not found in " "$1', `dnl')
28042fb4f839SGregory Neil Shapiro
280540266059SGregory Neil Shapiro######################################################################
280640266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
280740266059SGregory Neil Shapiro###	(done in client, per recipient)
280840266059SGregory Neil Shapirodnl called from deliver() before RCPT command
280940266059SGregory Neil Shapiro###
281040266059SGregory Neil Shapiro###	Parameters:
281140266059SGregory Neil Shapiro###		$1: recipient
281240266059SGregory Neil Shapiro######################################################################
281340266059SGregory Neil ShapiroStls_rcpt
281440266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
281540266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
281640266059SGregory Neil ShapiroR$* $| $#$*		$#$2
281740266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
28182fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
28192fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"STS_Check" $1
28202fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
28212fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2822e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
282340266059SGregory Neil Shapirodnl store name of other side
282440266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
282540266059SGregory Neil Shapirodnl canonify recipient address
282640266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
282740266059SGregory Neil Shapirodnl strip trailing dots
282840266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
282940266059SGregory Neil Shapirodnl full address?
283040266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
283140266059SGregory Neil Shapirodnl only localpart?
283240266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
283340266059SGregory Neil Shapirodnl look it up
283440266059SGregory Neil Shapirodnl also look up a default value via E:
283540266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
283640266059SGregory Neil Shapirodnl found nothing: stop here
283740266059SGregory Neil ShapiroR$* $| <?>	$@ OK
283840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
28395b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TR')', `dnl')
284040266059SGregory Neil Shapirodnl use the generic routine (for now)
284140266059SGregory Neil ShapiroR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
284240266059SGregory Neil Shapiro
284340266059SGregory Neil Shapiro######################################################################
284440266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
284540266059SGregory Neil Shapiro###	(done in server)
284640266059SGregory Neil Shapiro###
284740266059SGregory Neil Shapiro###	Parameters:
284840266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
284940266059SGregory Neil Shapiro######################################################################
285006f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
285106f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
285206f25ae9SGregory Neil ShapiroStls_client
285340266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
2854e3793f76SGregory Neil ShapiroR$*			$: $1 <?> $>"Local_tls_client" $1
2855e3793f76SGregory Neil ShapiroR$* <?> $#$*		$#$2
2856e3793f76SGregory Neil ShapiroR$* <?> $*		$: $1', `dnl')
285706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
285840266059SGregory Neil Shapirodnl store name of other side
28599bd497b8SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
286006f25ae9SGregory Neil Shapirodnl ignore second arg for now
286106f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
286206f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
286306f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
286440266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
286540266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
286606f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
286706f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
286840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
28695b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TC')', `dnl')
287040266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
287140266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
287206f25ae9SGregory Neil Shapiro
287340266059SGregory Neil Shapiro######################################################################
287440266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
287540266059SGregory Neil Shapiro###	(done in client)
287640266059SGregory Neil Shapiro###
287740266059SGregory Neil Shapiro###	Parameter:
287840266059SGregory Neil Shapiro###		${verify}
287940266059SGregory Neil Shapiro######################################################################
288006f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
288106f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
288206f25ae9SGregory Neil ShapiroStls_server
288340266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
288440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
288540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
288640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
28875b0945b5SGregory Neil Shapiroifdef(`_TLS_FAILURES_',`dnl
28885b0945b5SGregory Neil ShapiroR$*		$: $(macro {saved_verify} $@ $1 $) $1')
28892fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
28902fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"STS_secure" $1
28912fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
28922fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
289306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
289440266059SGregory Neil Shapirodnl store name of other side
289540266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
289640266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
289740266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
289806f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
289906f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
290040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
29015b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TS')', `dnl')
290240266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
290340266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
290406f25ae9SGregory Neil Shapiro
290540266059SGregory Neil Shapiro######################################################################
290640266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
290740266059SGregory Neil Shapiro###
290840266059SGregory Neil Shapiro###	Parameters:
290906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
291040266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
291140266059SGregory Neil Shapiro###		${verify}')
291240266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
291340266059SGregory Neil Shapirodnl	syntax for Requirement:
291440266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
291540266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
291640266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
291740266059SGregory Neil Shapiro######################################################################
29182fb4f839SGregory Neil Shapiroifdef(`TLS_PERM_ERR', `dnl
29192fb4f839SGregory Neil Shapirodefine(`TLS_DSNCODE', `5.7.0')dnl
29202fb4f839SGregory Neil Shapirodefine(`TLS_ERRCODE', `554')',`dnl
29212fb4f839SGregory Neil Shapirodefine(`TLS_DSNCODE', `4.7.0')dnl
29222fb4f839SGregory Neil Shapirodefine(`TLS_ERRCODE', `454')')dnl
29232fb4f839SGregory Neil Shapirodefine(`SW_MSG', `TLS handshake failed.')dnl
29242fb4f839SGregory Neil Shapirodefine(`DANE_MSG', `DANE check failed.')dnl
29252fb4f839SGregory Neil Shapirodefine(`PROT_MSG', `STARTTLS failed.')dnl
29262fb4f839SGregory Neil Shapirodefine(`CNF_MSG', `STARTTLS temporarily not possible.')dnl
292740266059SGregory Neil ShapiroSTLS_connection
29282fb4f839SGregory Neil Shapiroifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl', `dnl use default error
292940266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
29302fb4f839SGregory Neil ShapiroRSOFTWARE	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE SW_MSG"
29312fb4f839SGregory Neil ShapiroRDANE_FAIL	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
29322fb4f839SGregory Neil ShapiroRPROTOCOL	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE PROT_MSG"
29332fb4f839SGregory Neil ShapiroRCONFIG		$#error $@ TLS_DSNCODE $: "TLS_ERRCODE CNF_MSG"
293440266059SGregory Neil Shapirodivert(-1)')
293506f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
293640266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
293706f25ae9SGregory Neil Shapirodnl remove optional <>
293806f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
293940266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
294040266059SGregory Neil Shapiro# create the appropriate error codes
294106f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2942e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2943e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
294406f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
29452fb4f839SGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <TLS_ERRCODE:TLS_DSNCODE> <$2 $3>
294640266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
29472fb4f839SGregory Neil Shapirodefine(`TLS_ERRORS', `dnl
29482fb4f839SGregory Neil ShapiroR`'$1 $| <$-:$+> $`'*		$`'#error $`'@ $`'2 $: $`'1 " $2"
29492fb4f839SGregory Neil Shapirodnl no <reply:dns> i.e. no requirements in the access map
29502fb4f839SGregory Neil Shapirodnl use default error
29512fb4f839SGregory Neil ShapiroR`'$1 $| $`'*		$`'#error $`'@ TLS_DSNCODE $: "TLS_ERRCODE $2"')dnl
295240266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
29532fb4f839SGregory Neil ShapiroTLS_ERRORS(SOFTWARE,SW_MSG)
29544e4196cbSGregory Neil Shapiro# deal with TLS protocol errors: abort
29552fb4f839SGregory Neil ShapiroTLS_ERRORS(PROTOCOL,PROT_MSG)
29565b0945b5SGregory Neil Shapiro# deal with DANE errors: abort
29572fb4f839SGregory Neil ShapiroTLS_ERRORS(DANE_FAIL,DANE_MSG)
29582fb4f839SGregory Neil Shapiro# deal with CONFIG (tls_clt_features) errors: abort
29592fb4f839SGregory Neil ShapiroTLS_ERRORS(CONFIG,CNF_MSG)
296040266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
296140266059SGregory Neil Shapirodnl separate optional requirements
296240266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2963e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
296440266059SGregory Neil Shapirodnl separate optional requirements
2965e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
296606f25ae9SGregory Neil Shapirodnl some other value in access map: accept
296706f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
296806f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
296906f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
297006f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
297140266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
297206f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
29735b0945b5SGregory Neil ShapiroR<$*><VERIFY> <> $={TlsVerified}	$@ OK
297440266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
297540266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
29765b0945b5SGregory Neil ShapiroR<$*><VERIFY> <$+> $={TlsVerified}	$: <$1> <REQ:0> <$2>
297706f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
29785b0945b5SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> $={TlsVerified}	$: <$1> <REQ:$2> <$3>
297906f25ae9SGregory Neil Shapirodnl just some level of encryption required
298040266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
298140266059SGregory Neil Shapirodnl workspace:
29825b0945b5SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!~ $={TlsVerified})
298340266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
298440266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
298540266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
298640266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
298740266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
298840266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
298940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
29905b0945b5SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> CLEAR	$#error $@ $2 $: $1 " STARTTLS disabled locally"
299106f25ae9SGregory Neil Shapirodnl some other value for ${verify}
299240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
299340266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
299440266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
299506f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
299640266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
299740266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
299840266059SGregory Neil Shapirodnl strength requirements fulfilled
299940266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
300040266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
300140266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
300240266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
300340266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
300440266059SGregory Neil Shapirodnl workspace:
300540266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
300640266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
300740266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
300840266059SGregory Neil Shapirodnl continue: check  extensions
300940266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
301040266059SGregory Neil Shapirodnl split extensions into own list
301140266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
301240266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
301340266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
301406f25ae9SGregory Neil Shapiro
301540266059SGregory Neil Shapiro######################################################################
301640266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
301740266059SGregory Neil Shapiro###
301840266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
301940266059SGregory Neil Shapiro###		$-: SMTP reply code
302040266059SGregory Neil Shapiro###		$+: Enhanced Status Code
302140266059SGregory Neil Shapirodnl  further requirements for this ruleset:
302240266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
302340266059SGregory Neil Shapirodnl
302440266059SGregory Neil Shapirodnl	right now this is only a logical AND
302540266059SGregory Neil Shapirodnl	i.e. all requirements must be true
302640266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
302740266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
302840266059SGregory Neil Shapirodnl	operations (no precedences etc)?
302940266059SGregory Neil Shapiro######################################################################
303040266059SGregory Neil ShapiroSTLS_req
303140266059SGregory Neil Shapirodnl no additional requirements: ok
303240266059SGregory Neil ShapiroR $| $+		$@ OK
303340266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
303440266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
30355b0945b5SGregory Neil Shapiroifdef(`_FFR_TLS_ALTNAMES', `dnl
30365b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $2 $| <$3>
30375b0945b5SGregory Neil ShapiroR<CN:$-.$+> $* $| <$+>			$: <CN:*.$2> $3 $| <$4>
30385b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $3 $| <$3>
30395b0945b5SGregory Neil ShapiroR<CN:$*> $* $| <$+>			$: <CN:$&{TLS_Name}> $2 $| <$3>', `dnl')
304040266059SGregory Neil Shapirodnl match, check rest
304140266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
304240266059SGregory Neil Shapirodnl CN does not match
304340266059SGregory Neil Shapirodnl  1   2      3  4
304440266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
304540266059SGregory Neil Shapirodnl cert subject
304640266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
304740266059SGregory Neil Shapirodnl CS does not match
304840266059SGregory Neil Shapirodnl  1   2      3  4
304913bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
305040266059SGregory Neil Shapirodnl match, check rest
305140266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
305240266059SGregory Neil Shapirodnl CI does not match
305340266059SGregory Neil Shapirodnl  1   2      3  4
305413bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
30555b0945b5SGregory Neil Shapirodnl
30565b0945b5SGregory Neil ShapiroR<CITag:$-> $* $| <$+>	$: <$(access $1:$&{cert_issuer} $: ? $)> $2 $| <$3>
30575b0945b5SGregory Neil ShapiroR<?> $* $| <$-:$+>	$#error $@ $3 $: $2 " Cert Issuer " $&{cert_issuer} " not acceptable"
30585b0945b5SGregory Neil ShapiroR<OK> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
305940266059SGregory Neil Shapirodnl return from recursive call
306040266059SGregory Neil ShapiroROK			$@ OK
306140266059SGregory Neil Shapiro
306240266059SGregory Neil Shapiro######################################################################
306340266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
306440266059SGregory Neil Shapiro###
306540266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
306640266059SGregory Neil Shapiro######################################################################
306706f25ae9SGregory Neil ShapiroSmax
306806f25ae9SGregory Neil ShapiroR:		$: 0
306906f25ae9SGregory Neil ShapiroR:$-		$: $1
307006f25ae9SGregory Neil ShapiroR$-:		$: $1
307106f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
307206f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
307340266059SGregory Neil ShapiroR$-:$-:$-	$: $2
307440266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
307540266059SGregory Neil Shapirodivert(0)
307606f25ae9SGregory Neil Shapiro
30772fb4f839SGregory Neil Shapirodnl this must also be activated without _TLS_SESSION_FEATURES_
30782fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
30792fb4f839SGregory Neil Shapirodnl caller preserves workspace
30802fb4f839SGregory Neil ShapiroSSet_SNI
30812fb4f839SGregory Neil ShapiroR$*		$: <$&{rcpt_addr}>
30822fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
30832fb4f839SGregory Neil ShapiroR<>		$@ ""
30842fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
30852fb4f839SGregory Neil ShapiroR<$*@$+>	$2
30862fb4f839SGregory Neil ShapiroR$+.		$1
30872fb4f839SGregory Neil ShapiroR$+		$: $(sts $1 $: none $)
30882fb4f839SGregory Neil ShapiroR$* <TMPF>	$#error $@ 4.7.0 $: 450 STS lookup temp fail
30892fb4f839SGregory Neil ShapiroRnone		$@ ""
30902fb4f839SGregory Neil Shapirodnl get servername=sni and store it in {sts_sni}
30912fb4f839SGregory Neil Shapirodnl stsxsni extracts the value of servername= (sni)
30922fb4f839SGregory Neil Shapirodnl stsxsni2 extracts servername=sni so it can be returned to the caller
30932fb4f839SGregory Neil ShapiroR$* secure $*	$: $(stsxsni $2 $: : $) $| sts=secure; $(stsxsni2 $2 $: : $)
30942fb4f839SGregory Neil Shapirodnl store {server_addr} as sni if there was a match
30952fb4f839SGregory Neil Shapirodnl Note: this implies that only servername=hostname (literally!)
30962fb4f839SGregory Neil Shapirodnl is only ever returned.
30972fb4f839SGregory Neil ShapiroR$+: $| $+ :	$: $(macro {sts_sni} $@ $&{server_name} $) set $| $2
30982fb4f839SGregory Neil ShapiroR$* $| $*	$@ $2
30992fb4f839SGregory Neil ShapiroR$*		$@ ""
31002fb4f839SGregory Neil Shapirodnl', `dnl')
31012fb4f839SGregory Neil Shapiro
3102da7d7b9cSGregory Neil Shapiroifdef(`_TLS_SESSION_FEATURES_', `dnl
31032fb4f839SGregory Neil Shapirodefine(`_NEED_TLS_CLT_FEATURES')
3104da7d7b9cSGregory Neil ShapiroStls_srv_features
3105da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3106da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Srv_Features> <$2>
3107da7d7b9cSGregory Neil ShapiroR<?> <$*>		$: $>A <$1> <?> <! TLS_Srv_Features> <$1>
3108da7d7b9cSGregory Neil ShapiroR<?> <$*>		$@ ""
3109da7d7b9cSGregory Neil ShapiroR<$+> <$*>		$@ $1
3110da7d7b9cSGregory Neil Shapiro', `dnl
3111da7d7b9cSGregory Neil ShapiroR$*		$@ ""')
31122fb4f839SGregory Neil Shapiro', `dnl
31132fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_',`define(`_NEED_TLS_CLT_FEATURES')')dnl
31142fb4f839SGregory Neil Shapiro')dnl
3115da7d7b9cSGregory Neil Shapiro
31162fb4f839SGregory Neil Shapiroifdef(`_NEED_TLS_CLT_FEATURES', `dnl
3117da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
31182fb4f839SGregory Neil ShapiroStls_clt_feat_acc
3119da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Clt_Features> <$2>
3120da7d7b9cSGregory Neil ShapiroR<?> <$*>		$: $>A <$1> <?> <! TLS_Clt_Features> <$1>
3121da7d7b9cSGregory Neil ShapiroR<?> <$*>		$@ ""
31222fb4f839SGregory Neil ShapiroR<$+> <$*>		$@ $1')
31232fb4f839SGregory Neil Shapiro
31242fb4f839SGregory Neil ShapiroSDANE_disabled
31252fb4f839SGregory Neil Shapirodnl Note: most of this is handled in the binary.
31262fb4f839SGregory Neil Shapirodnl input: access map lookup for tls_clt_features
31272fb4f839SGregory Neil Shapirodnl output:
31282fb4f839SGregory Neil Shapirodnl <>: disabled
31292fb4f839SGregory Neil Shapirodnl <DANE>: enabled
31302fb4f839SGregory Neil ShapiroR$+	$: < $(stsxnodaneflag $1 $: NOFLAGS $) >
31312fb4f839SGregory Neil ShapiroR<$* @>	$@ <>
31322fb4f839SGregory Neil ShapiroR$*	$: < $&{sts_sni} >
31332fb4f839SGregory Neil ShapiroR<>	$@ <>
31342fb4f839SGregory Neil Shapiro# check this too?
31352fb4f839SGregory Neil Shapiro# R$*		$: $&{client_flags}
31362fb4f839SGregory Neil Shapiro# R$* DD $*	$@ <>
31372fb4f839SGregory Neil ShapiroR$*	$@ <DANE>
31382fb4f839SGregory Neil Shapiro
31392fb4f839SGregory Neil ShapiroSSTS_disabled
31402fb4f839SGregory Neil Shapirodnl input: ignored
31412fb4f839SGregory Neil Shapirodnl output:
31422fb4f839SGregory Neil Shapirodnl <>: disabled
31432fb4f839SGregory Neil Shapirodnl <STS>: enabled
31442fb4f839SGregory Neil ShapiroR$*		$: $&{client_flags}
31452fb4f839SGregory Neil ShapiroR$* MM $*	$@ <>
31462fb4f839SGregory Neil Shapirodnl
31472fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
31482fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
31492fb4f839SGregory Neil ShapiroR $| $*		$@ <>
31502fb4f839SGregory Neil ShapiroR$*		$@ <STS>
31512fb4f839SGregory Neil Shapiro
31522fb4f839SGregory Neil ShapiroStls_clt_features
31532fb4f839SGregory Neil Shapirodnl host $| ip
31542fb4f839SGregory Neil ShapiroR$*			$: $1 $| <>
31552fb4f839SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
31562fb4f839SGregory Neil ShapiroR$* $| <>		$: $1 $| $>"tls_clt_feat_acc" $1
31572fb4f839SGregory Neil ShapiroR$* $| $* $| $*		$: $1 $| $2 $| <$3>', `dnl')
31582fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
31592fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty>
31602fb4f839SGregory Neil ShapiroR$* $| $* $| <$*>	$: $1 $| $2 $| <$3> $| $>"STS_disabled" sts
31612fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| STS_disabled result
31622fb4f839SGregory Neil Shapirodnl disable STS check? return access result
31632fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| <>	$@ $3
31642fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| STS_disabled result
31652fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| $*		$: $1 $| $2 $| <$3> $| $>"DANE_disabled" $3
31662fb4f839SGregory Neil Shapirodnl DANE enabled: return access result; take care of empty return
31672fb4f839SGregory Neil ShapiroR$* $| $* $| <$+> $| <DANE>		$@ $3
31682fb4f839SGregory Neil ShapiroR$* $| $* $| <> $| <DANE>		$@ ""
31692fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| <DANE_disabled result>
31702fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| <$*>	$: $1 $| $2 $| <$3> $| $>"Set_SNI" $1
31712fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| sni result
31722fb4f839SGregory Neil Shapirodnl return sni result if not empty but acc is
31732fb4f839SGregory Neil ShapiroR$* $| $* $| <""> $| $+		$@ $3
31742fb4f839SGregory Neil Shapirodnl return acc + sni result if not empty
31752fb4f839SGregory Neil ShapiroR$* $| $* $| <$+;> $| $+		$@ $3 ; $4
31762fb4f839SGregory Neil Shapirodnl return acc + sni result if not empty
31772fb4f839SGregory Neil ShapiroR$* $| $* $| <$+> $| $+		$@ $3 ; $4
31782fb4f839SGregory Neil Shapirodnl return sni result if not empty
31792fb4f839SGregory Neil ShapiroR$* $| $* $| <> $| $+		$@ $3
31802fb4f839SGregory Neil Shapirodnl remove sni result
31812fb4f839SGregory Neil ShapiroR$* $| $* $| $* $| $*		$: $1 $| $2 $| $3
31822fb4f839SGregory Neil Shapiro', `dnl')
31832fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty>
31842fb4f839SGregory Neil ShapiroR$* $| $* $| <"">	$@ ""
31852fb4f839SGregory Neil ShapiroR$* $| $* $| <$+>	$@ $3
3186da7d7b9cSGregory Neil ShapiroR$*			$@ ""')
3187da7d7b9cSGregory Neil Shapiro
318840266059SGregory Neil Shapiro######################################################################
318940266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
319040266059SGregory Neil Shapiro###
319140266059SGregory Neil Shapiro###	Parameters:
319240266059SGregory Neil Shapiro###		none
319340266059SGregory Neil Shapiro######################################################################
319440266059SGregory Neil ShapiroSRelayTLS
319506f25ae9SGregory Neil Shapiro# authenticated?
319606f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
319706f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
319813bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
319906f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
320006f25ae9SGregory Neil Shapirodnl but anyway).
320106f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
320206f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
320306f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
320406f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
320506f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
320606f25ae9SGregory Neil Shapirodnl cert subject.
320706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
320840266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
32095b0945b5SGregory Neil ShapiroR<?> $={TlsVerified}	$: OK		authenticated: continue
321040266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
321106f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
321240266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
321340266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
321440266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
321506f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
321640266059SGregory Neil ShapiroRRELAY			$# RELAY
321706f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
321840266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
321940266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
322040266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
322140266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
322240266059SGregory Neil ShapiroR$*			$: NO', `dnl')
322340266059SGregory Neil Shapiro
322440266059SGregory Neil Shapiro######################################################################
322540266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
322640266059SGregory Neil Shapiro###
322740266059SGregory Neil Shapiro###	Parameters:
322840266059SGregory Neil Shapiro###		$1: {server_name}
322940266059SGregory Neil Shapiro###		$2: {server_addr}
323040266059SGregory Neil Shapirodnl	both are currently ignored
323140266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
323240266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
323340266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
323440266059SGregory Neil Shapiro######################################################################
323540266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
323640266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
323740266059SGregory Neil Shapirodnl (which may be considered a good thing).
323840266059SGregory Neil ShapiroSauthinfo
323940266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
324040266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
324140266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
324240266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
324340266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
324440266059SGregory Neil ShapiroR<$*>		$# $1
324540266059SGregory Neil Shapirodnl', `dnl
324640266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
324740266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
324840266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
324940266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
325040266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
325140266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
325240266059SGregory Neil Shapirodnl', `dnl')')
325306f25ae9SGregory Neil Shapiro
3254e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
3255e92d3f3fSGregory Neil Shapiro######################################################################
3256e92d3f3fSGregory Neil Shapiro###  RateControl:
3257e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3258e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3259e92d3f3fSGregory Neil Shapiro######################################################################
3260e92d3f3fSGregory Neil ShapiroSRateControl
3261e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3262e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3263e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3264e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
3265e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3266e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3267e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
32685b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`RC')', `dnl')
3269e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3270e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3271ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
3272e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
3273ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
3274e92d3f3fSGregory Neil Shapiro')')
3275e92d3f3fSGregory Neil Shapiro
3276e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
3277e92d3f3fSGregory Neil Shapiro######################################################################
3278e92d3f3fSGregory Neil Shapiro###  ConnControl:
3279e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3280e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3281e92d3f3fSGregory Neil Shapiro######################################################################
3282e92d3f3fSGregory Neil ShapiroSConnControl
3283e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3284e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3285e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3286e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
3287e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3288e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3289e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
32905b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`CC')', `dnl')
3291e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3292e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3293ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
3294e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
3295ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
3296e92d3f3fSGregory Neil Shapiro')')
3297e92d3f3fSGregory Neil Shapiro
329806f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
329906f25ae9SGregory Neil Shapiro#
330006f25ae9SGregory Neil Shapiro######################################################################
330106f25ae9SGregory Neil Shapiro######################################################################
330206f25ae9SGregory Neil Shapiro#####
330306f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
330406f25ae9SGregory Neil Shapiro#####
330506f25ae9SGregory Neil Shapiro######################################################################
330606f25ae9SGregory Neil Shapiro######################################################################
330740266059SGregory Neil Shapiro_MAIL_FILTERS_
3308c2aa98e2SPeter Wemm#
3309c2aa98e2SPeter Wemm######################################################################
3310c2aa98e2SPeter Wemm######################################################################
3311c2aa98e2SPeter Wemm#####
3312c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
3313c2aa98e2SPeter Wemm#####
3314c2aa98e2SPeter Wemm######################################################################
3315c2aa98e2SPeter Wemm######################################################################
331606f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
331742e5d165SGregory Neil Shapiro
33182fb4f839SGregory Neil Shapiro
33192fb4f839SGregory Neil Shapirodnl Helper ruleset for -bt mode to invoke rulesets
33202fb4f839SGregory Neil Shapirodnl which take two arguments separated by $|
33212fb4f839SGregory Neil Shapirodnl For example:
33222fb4f839SGregory Neil Shapirodnl Start,check_relay host.name $| I.P.V.4
33232fb4f839SGregory Neil Shapirodnl SStart
33242fb4f839SGregory Neil Shapirodnl R$* $$| $*		$: $1 $| $2
3325