xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision d39bd2c1)
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
250d39bd2c1SGregory Neil Shapiroifdef(`confOPENSSL_CNF',, `define(`confOPENSSL_CNF', `/etc/mail/sendmail.ossl')')
25106f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
252d39bd2c1SGregory Neil Shapiroifelse(defn(`confOPENSSL_CNF'), `', `', `EOPENSSL_CONF=confOPENSSL_CNF')
253c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
254c2aa98e2SPeter Wemm
255c2aa98e2SPeter Wemm###############
256c2aa98e2SPeter Wemm#   Options   #
257c2aa98e2SPeter Wemm###############
25840266059SGregory Neil Shapiroifdef(`confAUTO_REBUILD',
25940266059SGregory Neil Shapiro`errprint(WARNING: `confAUTO_REBUILD' is no longer valid.
26040266059SGregory Neil Shapiro	There was a potential for a denial of service attack if this is set.
26140266059SGregory Neil Shapiro)')dnl
262c2aa98e2SPeter Wemm
263c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
26406f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
265c2aa98e2SPeter Wemm
266c2aa98e2SPeter Wemm# 8-bit data handling
2678774250cSGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
268c2aa98e2SPeter Wemm
269c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
27006f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
271c2aa98e2SPeter Wemm
272c2aa98e2SPeter Wemm# location of alias file
27306f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
27406f25ae9SGregory Neil Shapiro
275c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
27606f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
277c2aa98e2SPeter Wemm
278c2aa98e2SPeter Wemm# maximum message size
279e92d3f3fSGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0')
280c2aa98e2SPeter Wemm
281c2aa98e2SPeter Wemm# substitution for space (blank) characters
28206f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
283c2aa98e2SPeter Wemm
284c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
28506f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
286c2aa98e2SPeter Wemm
287c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
28806f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
289c2aa98e2SPeter Wemm
290c2aa98e2SPeter Wemm# default delivery mode
29106f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
292c2aa98e2SPeter Wemm
293c2aa98e2SPeter Wemm# error message header/file
29406f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
295c2aa98e2SPeter Wemm
296c2aa98e2SPeter Wemm# error mode
29706f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
298c2aa98e2SPeter Wemm
299c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
30006f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
301c2aa98e2SPeter Wemm
30240266059SGregory Neil Shapiro# queue file mode (qf files)
30340266059SGregory Neil Shapiro_OPTION(QueueFileMode, `confQUEUE_FILE_MODE', `0600')
30440266059SGregory Neil Shapiro
305c2aa98e2SPeter Wemm# temporary file mode
30606f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
307c2aa98e2SPeter Wemm
308c2aa98e2SPeter Wemm# match recipients against GECOS field?
30906f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
310c2aa98e2SPeter Wemm
311c2aa98e2SPeter Wemm# maximum hop count
31240266059SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `25')
313c2aa98e2SPeter Wemm
314c2aa98e2SPeter Wemm# location of help file
31506f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
316c2aa98e2SPeter Wemm
317c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
31806f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
319c2aa98e2SPeter Wemm
320c2aa98e2SPeter Wemm# name resolver options
32106f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
322c2aa98e2SPeter Wemm
323c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
32406f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
325c2aa98e2SPeter Wemm
326c2aa98e2SPeter Wemm# Forward file search path
32706f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
328c2aa98e2SPeter Wemm
329c2aa98e2SPeter Wemm# open connection cache size
33006f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
331c2aa98e2SPeter Wemm
332c2aa98e2SPeter Wemm# open connection cache timeout
33306f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
334c2aa98e2SPeter Wemm
335c2aa98e2SPeter Wemm# persistent host status directory
33606f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
337c2aa98e2SPeter Wemm
338c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
33906f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
340c2aa98e2SPeter Wemm
341c2aa98e2SPeter Wemm# use Errors-To: header?
34206f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
343c2aa98e2SPeter Wemm
344da7d7b9cSGregory Neil Shapiro# use compressed IPv6 address format?
345da7d7b9cSGregory Neil Shapiro_OPTION(UseCompressedIPv6Addresses, `confUSE_COMPRESSED_IPV6_ADDRESSES', `')
346da7d7b9cSGregory Neil Shapiro
347c2aa98e2SPeter Wemm# log level
34806f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
349c2aa98e2SPeter Wemm
350c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
35106f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
352c2aa98e2SPeter Wemm
353c2aa98e2SPeter Wemm# verify RHS in newaliases?
35406f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
355c2aa98e2SPeter Wemm
356c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
35706f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
358c2aa98e2SPeter Wemm
359c2aa98e2SPeter Wemm# SMTP daemon options
36006f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
361605302a5SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
362605302a5SGregory Neil Shapiro	Use `DAEMON_OPTIONS()'; see cf/README.
36306f25ae9SGregory Neil Shapiro)'dnl
36406f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
36542e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
36640266059SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
36740266059SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
36806f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
36906f25ae9SGregory Neil Shapiro
37006f25ae9SGregory Neil Shapiro# SMTP client options
37140266059SGregory Neil Shapiroifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
37240266059SGregory Neil Shapiro`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
37340266059SGregory Neil Shapiro)'dnl
37440266059SGregory Neil Shapiro`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
37540266059SGregory Neil Shapiroifelse(defn(`_CPO_'), `',
37640266059SGregory Neil Shapiro`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
37740266059SGregory Neil Shapiro
37840266059SGregory Neil Shapiro# Modifiers to `define' {daemon_flags} for direct submissions
37940266059SGregory Neil Shapiro_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
38040266059SGregory Neil Shapiro
38140266059SGregory Neil Shapiro# Use as mail submission program? See sendmail/SECURITY
38240266059SGregory Neil Shapiro_OPTION(UseMSP, `confUSE_MSP', `')
383c2aa98e2SPeter Wemm
384c2aa98e2SPeter Wemm# privacy flags
38506f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
386c2aa98e2SPeter Wemm
387c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
38806f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
389c2aa98e2SPeter Wemm
390c2aa98e2SPeter Wemm# slope of queue-only function
39106f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
392c2aa98e2SPeter Wemm
39340266059SGregory Neil Shapiro# limit on number of concurrent queue runners
39440266059SGregory Neil Shapiro_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
39540266059SGregory Neil Shapiro
39640266059SGregory Neil Shapiro# maximum number of queue-runners per queue-grouping with multiple queues
39740266059SGregory Neil Shapiro_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
39840266059SGregory Neil Shapiro
39940266059SGregory Neil Shapiro# priority of queue runners (nice(3))
40040266059SGregory Neil Shapiro_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
40140266059SGregory Neil Shapiro
40240266059SGregory Neil Shapiro# shall we sort the queue by hostname first?
40340266059SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
40440266059SGregory Neil Shapiro
40540266059SGregory Neil Shapiro# minimum time in queue before retry
40640266059SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
40740266059SGregory Neil Shapiro
408da7d7b9cSGregory Neil Shapiro# maximum time in queue before retry (if > 0; only for exponential delay)
409da7d7b9cSGregory Neil Shapiro_OPTION(MaxQueueAge, `confMAX_QUEUE_AGE', `')
410da7d7b9cSGregory Neil Shapiro
41140266059SGregory Neil Shapiro# how many jobs can you process in the queue?
4124e4196cbSGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
41340266059SGregory Neil Shapiro
41440266059SGregory Neil Shapiro# perform initial split of envelope without checking MX records
41540266059SGregory Neil Shapiro_OPTION(FastSplit, `confFAST_SPLIT', `1')
41640266059SGregory Neil Shapiro
417c2aa98e2SPeter Wemm# queue directory
41806f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
419c2aa98e2SPeter Wemm
420d0cef73dSGregory Neil Shapiro# key for shared memory; 0 to turn off, -1 to auto-select
42140266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
42240266059SGregory Neil Shapiro
423d0cef73dSGregory Neil Shapiro# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
424d0cef73dSGregory Neil Shapiro_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
425605302a5SGregory Neil Shapiro
426c2aa98e2SPeter Wemm# timeouts (many of these)
42706f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
42806f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
42940266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
43206f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
43306f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
43506f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
43806f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
44006f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
44106f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
44206f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
44306f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
44406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
44506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
44606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
44706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
448e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
44906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
45006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
45106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
45206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
453e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
45406f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
45506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
45606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
45706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
45806f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
45906f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
46006f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
46140266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
46240266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
46340266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
46440266059SGregory Neil Shapiro
46540266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
46640266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
467c2aa98e2SPeter Wemm
468c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
46906f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
470c2aa98e2SPeter Wemm
471c2aa98e2SPeter Wemm# queue up everything before forking?
47206f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
473c2aa98e2SPeter Wemm
474c2aa98e2SPeter Wemm# status file
475d0cef73dSGregory Neil Shapiro_OPTION(StatusFile, `STATUS_FILE')
476c2aa98e2SPeter Wemm
477c2aa98e2SPeter Wemm# time zone handling:
478c2aa98e2SPeter Wemm#  if undefined, use system default
479c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
480c2aa98e2SPeter Wemm#  if defined and non-null, use that info
481c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
482c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
483c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
484c2aa98e2SPeter Wemm
485c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
48606f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
487c2aa98e2SPeter Wemm
488c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
48906f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
490c2aa98e2SPeter Wemm
491c2aa98e2SPeter Wemm# fallback MX host
49206f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
493c2aa98e2SPeter Wemm
494e92d3f3fSGregory Neil Shapiro# fallback smart host
495e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
496e92d3f3fSGregory Neil Shapiro
497c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
49806f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
499c2aa98e2SPeter Wemm
500c2aa98e2SPeter Wemm# load average at which we just queue messages
50106f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
502c2aa98e2SPeter Wemm
503c2aa98e2SPeter Wemm# load average at which we refuse connections
50406f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
505c2aa98e2SPeter Wemm
506e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
507e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
508e92d3f3fSGregory Neil Shapiro
50940266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
51040266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
51140266059SGregory Neil Shapiro
512c2aa98e2SPeter Wemm# maximum number of children we allow at one time
513739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
514c2aa98e2SPeter Wemm
515c2aa98e2SPeter Wemm# maximum number of new connections per second
516193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
517c2aa98e2SPeter Wemm
518e92d3f3fSGregory Neil Shapiro# Width of the window
519e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
520e92d3f3fSGregory Neil Shapiro
521c2aa98e2SPeter Wemm# work recipient factor
52206f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
523c2aa98e2SPeter Wemm
524c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
52506f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
526c2aa98e2SPeter Wemm
527c2aa98e2SPeter Wemm# work class factor
52806f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
529c2aa98e2SPeter Wemm
530c2aa98e2SPeter Wemm# work time factor
53106f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
532c2aa98e2SPeter Wemm
533c2aa98e2SPeter Wemm# default character set
534b6bacd31SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
535c2aa98e2SPeter Wemm
53640266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
53706f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
538c2aa98e2SPeter Wemm
539c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
54006f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
541c2aa98e2SPeter Wemm
542c2aa98e2SPeter Wemm# dialup line delay on connection failure
5434e4196cbSGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `0s')
544c2aa98e2SPeter Wemm
545c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
5464e4196cbSGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
547c2aa98e2SPeter Wemm
548c2aa98e2SPeter Wemm# chrooted environment for writing to files
5494e4196cbSGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
550c2aa98e2SPeter Wemm
551c2aa98e2SPeter Wemm# are colons OK in addresses?
55206f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
553c2aa98e2SPeter Wemm
554c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
55506f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
556c2aa98e2SPeter Wemm
557c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
55806f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
559c2aa98e2SPeter Wemm
560c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
56106f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
562c2aa98e2SPeter Wemm
563c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
56406f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
565c2aa98e2SPeter Wemm
566c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
56706f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
568c2aa98e2SPeter Wemm
569c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
57006f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
571c2aa98e2SPeter Wemm
572c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
57306f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
574c2aa98e2SPeter Wemm
575c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
57606f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
577c2aa98e2SPeter Wemm
578c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
57940266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
58006f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
58140266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
58240266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
58340266059SGregory Neil Shapiro')')
584c2aa98e2SPeter Wemm
585c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
58606f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
58706f25ae9SGregory Neil Shapiro
588d0cef73dSGregory Neil Shapiro# issue temporary errors (4xy) instead of permanent errors (5xy)?
589d0cef73dSGregory Neil Shapiro_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
590d0cef73dSGregory Neil Shapiro
59106f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
59206f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
593c2aa98e2SPeter Wemm
594c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
59506f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
596c2aa98e2SPeter Wemm
597c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
598e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
599c2aa98e2SPeter Wemm
60040266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
60140266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
602e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
60340266059SGregory Neil Shapiro
6049bd497b8SGregory Neil Shapiro
605c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
60606f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
607c2aa98e2SPeter Wemm
60806f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
60906f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
61006f25ae9SGregory Neil Shapiro
61106f25ae9SGregory Neil Shapiro# override connection address (for testing)
61206f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
61306f25ae9SGregory Neil Shapiro
61406f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
61506f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
61606f25ae9SGregory Neil Shapiro
61706f25ae9SGregory Neil Shapiro# Control socket for daemon management
61806f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
61906f25ae9SGregory Neil Shapiro
62006f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
621e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
62206f25ae9SGregory Neil Shapiro
62306f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
62406f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
62506f25ae9SGregory Neil Shapiro
62606f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
62706f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
62806f25ae9SGregory Neil Shapiro
62906f25ae9SGregory Neil Shapiro# location of pid file
63006f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
63106f25ae9SGregory Neil Shapiro
63206f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
63306f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
63406f25ae9SGregory Neil Shapiro
63506f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
63606f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
63706f25ae9SGregory Neil Shapiro
63806f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
63906f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
64006f25ae9SGregory Neil Shapiro
64140266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
64240266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
64340266059SGregory Neil Shapiro
644e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
645e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
646e92d3f3fSGregory Neil Shapiro
64706f25ae9SGregory Neil Shapiro# list of authentication mechanisms
64840266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
64906f25ae9SGregory Neil Shapiro
650e92d3f3fSGregory Neil Shapiro# Authentication realm
651e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
652e92d3f3fSGregory Neil Shapiro
65306f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
65406f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
65506f25ae9SGregory Neil Shapiro
65606f25ae9SGregory Neil Shapiro# SMTP AUTH flags
65706f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
65806f25ae9SGregory Neil Shapiro
65940266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
66040266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
66140266059SGregory Neil Shapiro
66240266059SGregory Neil Shapiro# SMTP STARTTLS server options
66340266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
66440266059SGregory Neil Shapiro
665da7d7b9cSGregory Neil Shapiro# SSL cipherlist
666da7d7b9cSGregory Neil Shapiro_OPTION(CipherList, `confCIPHER_LIST', `')
667da7d7b9cSGregory Neil Shapiro# server side SSL options
668da7d7b9cSGregory Neil Shapiro_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `')
669da7d7b9cSGregory Neil Shapiro# client side SSL options
670da7d7b9cSGregory Neil Shapiro_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `')
6715b0945b5SGregory Neil Shapiro# SSL Engine
6725b0945b5SGregory Neil Shapiro_OPTION(SSLEngine, `confSSL_ENGINE', `')
6735b0945b5SGregory Neil Shapiro# Path to dynamic library for SSLEngine
6745b0945b5SGregory Neil Shapiro_OPTION(SSLEnginePath, `confSSL_ENGINE_PATH', `')
6755b0945b5SGregory Neil Shapiro# TLS: fall back to clear text after handshake failure?
6765b0945b5SGregory Neil Shapiro_OPTION(TLSFallbacktoClear, `confTLS_FALLBACK_TO_CLEAR', `')
6779bd497b8SGregory Neil Shapiro
67806f25ae9SGregory Neil Shapiro# Input mail filters
67906f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
68006f25ae9SGregory Neil Shapiro
681739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
68206f25ae9SGregory Neil Shapiro# Milter options
68340266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
68406f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
68506f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
68606f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
687323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
688d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
689d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
690d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
69106f25ae9SGregory Neil Shapiro
69206f25ae9SGregory Neil Shapiro# CA directory
69313bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
69406f25ae9SGregory Neil Shapiro# CA file
69513bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
69606f25ae9SGregory Neil Shapiro# Server Cert
69706f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
69806f25ae9SGregory Neil Shapiro# Server private key
69906f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
70006f25ae9SGregory Neil Shapiro# Client Cert
70106f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
70206f25ae9SGregory Neil Shapiro# Client private key
70306f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
704e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
705e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
7065b0945b5SGregory Neil Shapiro# Directory containing hashes pointing to certificate revocation status files
7075b0945b5SGregory Neil Shapiro_OPTION(CRLPath, `confCRL_PATH', `')
70806f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
70906f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
71006f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
71106f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
712da7d7b9cSGregory Neil Shapiro# fingerprint algorithm (digest) to use for the presented cert
713da7d7b9cSGregory Neil Shapiro_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `')
7145b0945b5SGregory Neil Shapiro# enable DANE?
7155b0945b5SGregory Neil Shapiro_OPTION(DANE, `confDANE', `false')
71606f25ae9SGregory Neil Shapiro
717d0cef73dSGregory Neil Shapiro# Maximum number of "useless" commands before slowing down
718d0cef73dSGregory Neil Shapiro_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
719d0cef73dSGregory Neil Shapiro
720d0cef73dSGregory Neil Shapiro# Name to use for EHLO (defaults to $j)
721d0cef73dSGregory Neil Shapiro_OPTION(HeloName, `confHELO_NAME')
722d0cef73dSGregory Neil Shapiro
723da7d7b9cSGregory Neil Shapiroifdef(`_NEED_SMTPOPMODES_', `dnl
724da7d7b9cSGregory Neil Shapiro# SMTP operation modes
725da7d7b9cSGregory Neil ShapiroC{SMTPOpModes} s d D')
726da7d7b9cSGregory Neil Shapiro
72740266059SGregory Neil Shapiro############################
72840266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
72940266059SGregory Neil Shapiro############################
73040266059SGregory Neil Shapiro_QUEUE_GROUP_
731065a643dSPeter Wemm
732c2aa98e2SPeter Wemm###########################
733c2aa98e2SPeter Wemm#   Message precedences   #
734c2aa98e2SPeter Wemm###########################
735c2aa98e2SPeter Wemm
736c2aa98e2SPeter WemmPfirst-class=0
737c2aa98e2SPeter WemmPspecial-delivery=100
738c2aa98e2SPeter WemmPlist=-30
739c2aa98e2SPeter WemmPbulk=-60
740c2aa98e2SPeter WemmPjunk=-100
741c2aa98e2SPeter Wemm
742c2aa98e2SPeter Wemm#####################
743c2aa98e2SPeter Wemm#   Trusted users   #
744c2aa98e2SPeter Wemm#####################
745c2aa98e2SPeter Wemm
746c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
74706f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
748c2aa98e2SPeter WemmTroot
749c2aa98e2SPeter WemmTdaemon
750c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
751c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
752c2aa98e2SPeter Wemm
753c2aa98e2SPeter Wemm#########################
754c2aa98e2SPeter Wemm#   Format of headers   #
755c2aa98e2SPeter Wemm#########################
756c2aa98e2SPeter Wemm
757c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
758e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
759c2aa98e2SPeter WemmH?P?Return-Path: <$g>
760c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
761c2aa98e2SPeter WemmH?D?Resent-Date: $a
762c2aa98e2SPeter WemmH?D?Date: $a
763c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
764c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
765c2aa98e2SPeter WemmH?x?Full-Name: $x
766c2aa98e2SPeter Wemm# HPosted-Date: $a
767c2aa98e2SPeter Wemm# H?l?Received-Date: $b
768e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
769e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
77006f25ae9SGregory Neil Shapiro
771c2aa98e2SPeter Wemm#
772c2aa98e2SPeter Wemm######################################################################
773c2aa98e2SPeter Wemm######################################################################
774c2aa98e2SPeter Wemm#####
775c2aa98e2SPeter Wemm#####			REWRITING RULES
776c2aa98e2SPeter Wemm#####
777c2aa98e2SPeter Wemm######################################################################
778c2aa98e2SPeter Wemm######################################################################
779c2aa98e2SPeter Wemm
780c2aa98e2SPeter Wemm############################################
781c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
782c2aa98e2SPeter Wemm############################################
78306f25ae9SGregory Neil ShapiroScanonify=3
784c2aa98e2SPeter Wemm
785c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
786c2aa98e2SPeter WemmR$@			$@ <@>
787c2aa98e2SPeter Wemm
788c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
789c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
790c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
791c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
79240266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
793c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
794c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
795c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
796c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
797c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
798c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
799193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
800c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
801c2aa98e2SPeter Wemm
802c2aa98e2SPeter Wemm# null input now results from list:; syntax
803c2aa98e2SPeter WemmR$@			$@ :; <@>
804c2aa98e2SPeter Wemm
805c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
806c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
807c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
808c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
809c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
810c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
811c2aa98e2SPeter Wemm
81206f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
813c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
814c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
815c2aa98e2SPeter Wemm
816c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
81740266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
81840266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
81940266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
82006f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
82106f25ae9SGregory Neil Shapirodnl',`dnl
82206f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
82306f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
82440266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
82540266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
82606f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
82706f25ae9SGregory Neil Shapirodnl')
828c2aa98e2SPeter Wemm
829c2aa98e2SPeter Wemm# find focus for list syntax
83006f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
831c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
832c2aa98e2SPeter Wemm
833c2aa98e2SPeter Wemm# find focus for @ syntax addresses
834c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
835c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
83606f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
837c2aa98e2SPeter Wemm
83840266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
83940266059SGregory Neil Shapirodnl # do some sanity checking
84040266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
841c2aa98e2SPeter Wemm
842c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
843c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
84406f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
84506f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
84606f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
847c2aa98e2SPeter Wemm')
848c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
849c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
85006f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
85106f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
852c2aa98e2SPeter Wemm',
853c2aa98e2SPeter Wemm	`dnl')
854da7d7b9cSGregory Neil Shapiroifdef(`_NO_PERCENTHACK_', `dnl',
855da7d7b9cSGregory Neil Shapiro`# if we have % signs, take the rightmost one
856c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
857c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
858da7d7b9cSGregory Neil Shapiro')
85906f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
860c2aa98e2SPeter Wemm
861c2aa98e2SPeter Wemm# else we must be a local name
86206f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
863c2aa98e2SPeter Wemm
864c2aa98e2SPeter Wemm
865c2aa98e2SPeter Wemm################################################
866c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
867c2aa98e2SPeter Wemm################################################
868c2aa98e2SPeter Wemm
86906f25ae9SGregory Neil ShapiroSCanonify2=96
870c2aa98e2SPeter Wemm
871c2aa98e2SPeter Wemm# handle special cases for local names
872c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
873c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
874c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
875c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
87606f25ae9SGregory Neil Shapiro
87740266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
87840266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
879c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
880c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
881c2aa98e2SPeter Wemm
88206f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
883c2aa98e2SPeter Wemm# look up domains in the domain table
884c2aa98e2SPeter WemmR$* < @ $+ > $*		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
885c2aa98e2SPeter Wemm
88606f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
887c2aa98e2SPeter Wemm
88806f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
889c2aa98e2SPeter Wemm# handle BITNET mapping
890c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
891c2aa98e2SPeter Wemm
89206f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
893c2aa98e2SPeter Wemm# handle UUCP mapping
894c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
895c2aa98e2SPeter Wemm
896c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
897c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
898c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
899c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
900c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
901c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
902c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
903c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
904c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
905c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
906c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
907c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
908c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
909c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
910c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
911c2aa98e2SPeter Wemm
912c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
913c2aa98e2SPeter Wemm# try UUCP traffic as a local address
914c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
915c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
916c2aa98e2SPeter Wemm')')
91706f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
91806f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
91906f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
92006f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
92106f25ae9SGregory Neil Shapirodnl which daemon flags are set?
92206f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
92306f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
92406f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
92506f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
92606f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
92706f25ae9SGregory Neil Shapirodnl do not canonify unless:
92806f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
92906f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
93006f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
93106f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
93206f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
93306f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
93406f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
93506f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
93606f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
93706f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
93806f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
93906f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
94006f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
94106f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
94206f25ae9SGregory Neil Shapirodnl then $- does not work.
94306f25ae9SGregory Neil Shapiro# look up unqualified hostnames
94406f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
94506f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
94606f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
947193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
948193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
949193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
95006f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
95140266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
95240266059SGregory Neil Shapiro# do not canonify header addresses
95340266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
95440266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
95540266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
956c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
95706f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
95806f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
95906f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
960c2aa98e2SPeter Wemm
961c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
962c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
963c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
964c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
965c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
96606f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
96706f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
96806f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
96906f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $*	$: $1 < @ $2 $3 . > $4',
97006f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $*	$: $1 < @ $2 . > $3')',
97106f25ae9SGregory Neil Shapiro`dnl')
97240266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
97340266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
97440266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
97540266059SGregory Neil Shapiro`R$* < @ $* $=G > $*	$: $1 < @ $2 $3 . > $4',
97640266059SGregory Neil Shapiro`R$* < @ $=G > $*	$: $1 < @ $2 . > $3')',
97740266059SGregory Neil Shapiro`dnl')
97806f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
97906f25ae9SGregory Neil Shapirodnl by one of the rules before
980c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
981c2aa98e2SPeter Wemm
982c2aa98e2SPeter Wemm
983c2aa98e2SPeter Wemm##################################################
984c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
985c2aa98e2SPeter Wemm##################################################
98606f25ae9SGregory Neil ShapiroSfinal=4
987c2aa98e2SPeter Wemm
988193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
989c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
990c2aa98e2SPeter Wemm
991c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
992c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
993c2aa98e2SPeter Wemm
99406f25ae9SGregory Neil Shapiro# eliminate internal code
995c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
996c2aa98e2SPeter Wemm
997c2aa98e2SPeter Wemm# externalize local domain info
998c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
999c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
1000c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
1001c2aa98e2SPeter Wemm
1002c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1003c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
1004c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
1005c2aa98e2SPeter Wemm
1006c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
1007c2aa98e2SPeter Wemm`# put DECnet back in :: form
1008c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
1009c2aa98e2SPeter Wemm	`dnl')
1010c2aa98e2SPeter Wemm# delete duplicate local names
1011c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
1012c2aa98e2SPeter Wemm
1013c2aa98e2SPeter Wemm
1014c2aa98e2SPeter Wemm
1015c2aa98e2SPeter Wemm##############################################################
1016c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
1017c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
1018c2aa98e2SPeter Wemm##############################################################
1019c2aa98e2SPeter Wemm
102006f25ae9SGregory Neil ShapiroSRecurse=97
102106f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
102206f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
1023c2aa98e2SPeter Wemm
1024c2aa98e2SPeter Wemm
1025c2aa98e2SPeter Wemm######################################
1026c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
1027c2aa98e2SPeter Wemm######################################
1028c2aa98e2SPeter Wemm
102906f25ae9SGregory Neil ShapiroSparse=0
1030c2aa98e2SPeter Wemm
1031c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
1032c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
103306f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
1034c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
1035c2aa98e2SPeter Wemm
1036c2aa98e2SPeter Wemm#
1037c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
1038c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
1039c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
1040c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
1041c2aa98e2SPeter Wemm#
1042c2aa98e2SPeter Wemm
1043c2aa98e2SPeter WemmSParse0
1044c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
104540266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
104606f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
104740266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
104840266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
1049c2aa98e2SPeter WemmR$*			$: <> $1
105040266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
105140266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
105240266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
105340266059SGregory Neil Shapirodnl but no a@[b]c
105440266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
1055c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
105640266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1057c2aa98e2SPeter WemmR<> $*			$1
105840266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
105940266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
106040266059SGregory Neil Shapirodnl no a@b@
106140266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
106240266059SGregory Neil Shapirodnl no a@b@c
106340266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
106406f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
106540266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
106640266059SGregory Neil Shapiro
106740266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
106840266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
106940266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
107040266059SGregory Neil Shapirodnl', `dnl')
1071c2aa98e2SPeter Wemm
1072c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
107306f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
107406f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1075c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
107640266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
107706f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1078c2aa98e2SPeter WemmR$-			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
107940266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1080c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
108106f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1082c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1083c2aa98e2SPeter Wemm
1084da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1085da7d7b9cSGregory Neil ShapiroR$+			$: $>ParseBcc $1', `dnl')
1086da7d7b9cSGregory Neil Shapiroifdef(`_PREFIX_MOD_', `dnl
1087da7d7b9cSGregory Neil Shapirodnl do this only for addr_type=e r?
1088da7d7b9cSGregory Neil ShapiroR _PREFIX_MOD_ $+	$: $1 $(macro {rcpt_flags} $@ _PREFIX_FLAGS_ $)
1089da7d7b9cSGregory Neil Shapiro')dnl
1090da7d7b9cSGregory Neil Shapiro
1091c2aa98e2SPeter Wemm#
1092c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1093c2aa98e2SPeter Wemm#
1094c2aa98e2SPeter Wemm
1095c2aa98e2SPeter WemmSParse1
109606f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
109706f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
109840266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
109940266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1100c2aa98e2SPeter Wemm`dnl')
1101c2aa98e2SPeter Wemm
110206f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
110306f25ae9SGregory Neil Shapiro`# handle numeric address spec
110406f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
110506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
11065ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
110706f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
110806f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
110906f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
111006f25ae9SGregory Neil Shapiro	`dnl')
111106f25ae9SGregory Neil Shapiro
111206f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1113c2aa98e2SPeter Wemm# handle virtual users
111440266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
111540266059SGregory Neil Shapirodnl this is not a documented option
111640266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
111740266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
111840266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
111940266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
112040266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
112140266059SGregory Neil ShapiroR$+ < @ $+ >			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
112240266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
112340266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
112440266059SGregory Neil Shapiro`dnl')
112506f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
112640266059SGregory Neil Shapirodnl input: <!> local<@domain>
112706f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
112806f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . >	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
112906f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . >	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
113040266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
113106f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . >	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
113240266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
113340266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
113440266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
113540266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113640266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1137c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
113840266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
113940266059SGregory Neil Shapirodnl user+detail: try user@domain
1140c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
114140266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114206f25ae9SGregory Neil Shapirodnl try default entry: @domain
114340266059SGregory Neil Shapirodnl ++@domain
114440266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114506f25ae9SGregory Neil Shapirodnl +*@domain
114640266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
114706f25ae9SGregory Neil Shapirodnl @domain if +detail exists
114894c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
114994c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
115094c01205SGregory Neil Shapirodnl without +detail
1151c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
115240266059SGregory Neil Shapirodnl no match
1153c2aa98e2SPeter WemmR<@> $+			$: $1
115440266059SGregory Neil Shapirodnl remove mark
115506f25ae9SGregory Neil ShapiroR<!> $+			$: $1
115606f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $*	$#error $@ $1.$2.$3 $: $4
1157c2aa98e2SPeter WemmR< error : $- $+ > $*	$#error $@ $(dequote $1 $) $: $2
115840266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
115940266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
116040266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
116140266059SGregory Neil Shapiro# it is the same: stop now
116240266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
116340266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $*			$: < $1 > $2 < @ $3 >
116440266059SGregory Neil Shapirodnl', `dnl')
116513058a91SGregory Neil Shapirodnl this is not a documented option
116613058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11678774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11688774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11698774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11708774250cSGregory Neil Shapirodnl', `dnl')
1171c2aa98e2SPeter Wemm
1172c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1173c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
117406f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
117542e5d165SGregory Neil Shapiro
117642e5d165SGregory Neil Shapiro
1177c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1178c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
117906f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
118006f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1181c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1182c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1183c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1184c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1185c2aa98e2SPeter Wemm
118606f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1187c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1188c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1189c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1190c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
119106f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
119206f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
119306f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1194c2aa98e2SPeter Wemm`dnl')
119506f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1196c2aa98e2SPeter Wemm
1197c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1198c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1199c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
120006f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1201c2aa98e2SPeter Wemm	`dnl')
1202c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
120306f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1204c2aa98e2SPeter Wemm	`dnl')
1205c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
120606f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1207c2aa98e2SPeter Wemm	`dnl')')
1208c2aa98e2SPeter Wemm
1209c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1210c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
121106f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1212c2aa98e2SPeter Wemm	`dnl')
1213c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
121406f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1215c2aa98e2SPeter Wemm	`dnl')
1216c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1217c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1218c2aa98e2SPeter Wemm	`dnl')
1219c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1220c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1221c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
122206f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1223c2aa98e2SPeter Wemm	`dnl')')
1224c2aa98e2SPeter Wemm
1225c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1226c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
122706f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1228c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1229c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1230c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1231c2aa98e2SPeter Wemm	`dnl')')
1232c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1233c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
123406f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1235c2aa98e2SPeter Wemm	`dnl')
1236c2aa98e2SPeter Wemm
1237c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1238c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1239d39bd2c1SGregory Neil Shapiroundivert(1)dnl LOCAL_NET_CONFIG', `dnl')
1240c2aa98e2SPeter Wemm
1241c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
124206f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1243c2aa98e2SPeter Wemm
1244c2aa98e2SPeter Wemm# deal with other remote names
1245c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1246c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
124740266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1248c2aa98e2SPeter Wemm
1249c2aa98e2SPeter Wemm# handle locally delivered names
1250c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1251c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1252c2aa98e2SPeter Wemm
1253da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1254da7d7b9cSGregory Neil ShapiroSParseBcc
1255da7d7b9cSGregory Neil ShapiroR$+			$: $&{addr_type} $| $&A $| $1
1256da7d7b9cSGregory Neil ShapiroRe b $| $+ $| $+	$>MailerToTriple < $1 > $2	copy?
1257da7d7b9cSGregory Neil ShapiroR$* $| $* $| $+		$@ $3				no copy
1258da7d7b9cSGregory Neil Shapiro')
1259da7d7b9cSGregory Neil Shapiro
1260c2aa98e2SPeter Wemm###########################################################################
1261c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1262c2aa98e2SPeter Wemm###########################################################################
1263c2aa98e2SPeter Wemm
126406f25ae9SGregory Neil ShapiroSLocal_localaddr
126506f25ae9SGregory Neil ShapiroSlocaladdr=5
126606f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
126740266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
126806f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
126906f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1270c2aa98e2SPeter Wemm
127140266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
127240266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
127340266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
127440266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
127540266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
127640266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12776a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
127840266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
127940266059SGregory Neil Shapiro')dnl
128040266059SGregory Neil Shapiro
128140266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
128242e5d165SGregory Neil Shapiro# Preserve host in a macro
128342e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
128442e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1285c2aa98e2SPeter Wemm
128640266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
128742e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
128842e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
128942e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
129042e5d165SGregory Neil Shapiro')
1291c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1292c2aa98e2SPeter WemmR$+			$: <> $1
1293c2aa98e2SPeter Wemm
1294c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1295c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
129640266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
129742e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
129842e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
129942e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
130042e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
130106f25ae9SGregory Neil ShapiroR< > $+			$: < $L > $(user $1 $)		look up user
130240266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
130340266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
130440266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
130540266059SGregory Neil Shapirodnl')
1306c2aa98e2SPeter Wemm
130740266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
130840266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
130940266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
131040266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
131140266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
131240266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
131306f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
131440266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
131540266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
131606f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
131706f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1318c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
131942e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1320c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
13212e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
132240266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
132340266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
13242e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
132542e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
132606f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
132706f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
132840266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
132940266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
133040266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
133140266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
133240266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
133340266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
133406f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1335c2aa98e2SPeter Wemm
133606f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
133740266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
133840266059SGregory Neil Shapiro###################################################################
133940266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
134040266059SGregory Neil Shapirodnl input: <Domain> FullAddress
134140266059SGregory Neil Shapiro###################################################################
134240266059SGregory Neil Shapiro
134340266059SGregory Neil ShapiroSLDAPMailertable
134440266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
134540266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
134640266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
134740266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
134840266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
134940266059SGregory Neil Shapiro`dnl')
135040266059SGregory Neil Shapiro
1351c2aa98e2SPeter Wemm###################################################################
1352c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry		###
135306f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1354c2aa98e2SPeter Wemm###################################################################
1355c2aa98e2SPeter Wemm
135606f25ae9SGregory Neil ShapiroSMailertable=90
135706f25ae9SGregory Neil Shapirodnl shift and check
135806f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1359c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
136006f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
136106f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
136206f25ae9SGregory Neil ShapiroR$* < . $+ > $*		$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
136306f25ae9SGregory Neil Shapirodnl is $2 always empty?
1364c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
136506f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
136606f25ae9SGregory Neil Shapirodnl return full address
1367c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1368c2aa98e2SPeter Wemm`dnl')
1369c2aa98e2SPeter Wemm
1370c2aa98e2SPeter Wemm###################################################################
1371c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
137206f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
137306f25ae9SGregory Neil Shapirodnl	<> address				-> address
137406f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1375a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
137606f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
137706f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
137806f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
137906f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
138006f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1381c2aa98e2SPeter Wemm###################################################################
1382c2aa98e2SPeter Wemm
138306f25ae9SGregory Neil ShapiroSMailerToTriple=95
1384c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
138506f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $*	$#error $@ $1.$2.$3 $: $4
1386a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1387a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1388c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
138940266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
139040266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
139140266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1392c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1393c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1394c2aa98e2SPeter Wemm
1395c2aa98e2SPeter Wemm###################################################################
1396c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
139706f25ae9SGregory Neil Shapirodnl input: <user> address
139806f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
139906f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
140006f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
140106f25ae9SGregory Neil Shapirodnl <> user				-> local user user
140206f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
140306f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
140406f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1405c2aa98e2SPeter Wemm###################################################################
1406c2aa98e2SPeter Wemm
1407c2aa98e2SPeter WemmSCanonLocal
14082e43090eSPeter Wemm# strip local host from routed addresses
140906f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
141006f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
14112e43090eSPeter Wemm
1412c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1413c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1414c2aa98e2SPeter Wemm
1415c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1416c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1417c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1418c2aa98e2SPeter Wemm
1419c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1420c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1421c2aa98e2SPeter Wemm
1422c2aa98e2SPeter Wemm# handle local:user syntax
1423c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1424c2aa98e2SPeter WemmR< $+ > $*			$#_LOCAL_ $@ $2    $: $1
1425c2aa98e2SPeter Wemm
1426c2aa98e2SPeter Wemm###################################################################
1427c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1428c2aa98e2SPeter Wemm###################################################################
1429c2aa98e2SPeter Wemm
143006f25ae9SGregory Neil ShapiroSMasqHdr=93
1431c2aa98e2SPeter Wemm
143206f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1433c2aa98e2SPeter Wemm# handle generics database
1434c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
143506f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1436c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1437c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1438c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
143906f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
144006f25ae9SGregory Neil Shapirodnl ignore the first case for now
144106f25ae9SGregory Neil Shapirodnl if it has the mark look up full address
144240266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
144306f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
144406f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
1445d39bd2c1SGregory Neil Shapirodnl no match, try user+detail@domain:
1446d39bd2c1SGregory Neil Shapirodnl look up user+*@domain and user@domain
144706f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
144806f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
144906f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
145006f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
145106f25ae9SGregory Neil Shapirodnl no match, remove mark
145206f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
145306f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
145406f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
145506f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
145606f25ae9SGregory Neil Shapirodnl no match, try local part
1457c2aa98e2SPeter WemmR< > $+ < @ $+ >	$: < $(generics $1 $: $) > $1 < @ $2 >
145806f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ >	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
145906f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ >	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
146006f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
146106f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1462c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1463c2aa98e2SPeter Wemm`dnl')
1464c2aa98e2SPeter Wemm
146506f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
146606f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
146706f25ae9SGregory Neil Shapiro
146840266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1469c2aa98e2SPeter Wemm# special case the users that should be exposed
1470c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1471c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1472c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1473c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1474c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1475c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1476c2aa98e2SPeter Wemm
1477c2aa98e2SPeter Wemm# handle domain-specific masquerading
1478c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1479c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1480c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1481c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1482c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1483c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1484c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1485c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
148640266059SGregory Neil Shapirodnl', `dnl no masquerading
148740266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
148840266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1489c2aa98e2SPeter Wemm
1490c2aa98e2SPeter Wemm###################################################################
1491c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1492c2aa98e2SPeter Wemm###################################################################
1493c2aa98e2SPeter Wemm
149406f25ae9SGregory Neil ShapiroSMasqEnv=94
1495c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
149606f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1497c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1498c2aa98e2SPeter Wemm
1499c2aa98e2SPeter Wemm###################################################################
1500c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1501c2aa98e2SPeter Wemm###################################################################
1502c2aa98e2SPeter Wemm
150306f25ae9SGregory Neil ShapiroSParseLocal=98
150406f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1505c2aa98e2SPeter Wemm
150606f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
150740266059SGregory Neil Shapiro######################################################################
150840266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
150940266059SGregory Neil Shapiro###
151040266059SGregory Neil Shapiro###	Parameters:
151140266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
151240266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
151340266059SGregory Neil Shapiro###		<$3> -- +detail information
151440266059SGregory Neil Shapiro###
151540266059SGregory Neil Shapiro###	Returns:
151640266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
151740266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
151840266059SGregory Neil Shapiro######################################################################
151940266059SGregory Neil Shapiro
152006f25ae9SGregory Neil ShapiroSLDAPExpand
152106f25ae9SGregory Neil Shapiro# do the LDAP lookups
152240266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
152306f25ae9SGregory Neil Shapiro
1524e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1525e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1526e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1527e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1528e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
15295b0945b5SGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: _TMPFMSG_(`OPM')')
1530e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1531e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1532605302a5SGregory Neil Shapiro
1533d39bd2c1SGregory Neil Shapiro# if mailRoutingAddress and local or non-existent mailHost,
153406f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
153540266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
153640266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
153740266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
153840266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
153940266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
154006f25ae9SGregory Neil Shapiro
154194c01205SGregory Neil Shapiro
154206f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
154306f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
154440266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
154540266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
154640266059SGregory Neil Shapiro# check mailertable for host, relay from there
154740266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
154840266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
154940266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
155040266059SGregory Neil Shapiro# check mailertable for host, relay from there
155140266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
155240266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
155306f25ae9SGregory Neil Shapiro
155406f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
155506f25ae9SGregory Neil Shapiro# return original address
155640266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
155706f25ae9SGregory Neil Shapiro
155894c01205SGregory Neil Shapiro
155906f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
156006f25ae9SGregory Neil Shapiro# relay to mailHost with original address
156140266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
156240266059SGregory Neil Shapiro# check mailertable for host, relay from there
156340266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
156440266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
156506f25ae9SGregory Neil Shapiro
156640266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
156740266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
156840266059SGregory Neil Shapiro# try without +detail
156940266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
157040266059SGregory Neil Shapiro
15719bd497b8SGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `
15729bd497b8SGregory Neil Shapiro# pretend we did the @domain lookup
15739bd497b8SGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
157440266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
157506f25ae9SGregory Neil Shapiro# try @domain
157640266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
157740266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1578e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
157906f25ae9SGregory Neil Shapiro
158006f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
158106f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
158206f25ae9SGregory Neil Shapiro# user does not exist
158340266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
158440266059SGregory Neil Shapiro# only give error for envelope recipient
158540266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1586e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1587e92d3f3fSGregory Neil Shapiro# and the sender too
1588e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
158940266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
159006f25ae9SGregory Neil Shapiro`dnl
159106f25ae9SGregory Neil Shapiro# return the original address
1592ba00ec3dSGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')
1593ba00ec3dSGregory Neil Shapiro')
1594ba00ec3dSGregory Neil Shapiro
159506f25ae9SGregory Neil Shapiro
159606f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
159706f25ae9SGregory Neil Shapiro')')
159840266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1599c2aa98e2SPeter Wemm######################################################################
160040266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1601c2aa98e2SPeter Wemm###
1602c2aa98e2SPeter Wemm###	Parameters:
1603c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1604c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
160506f25ae9SGregory Neil Shapirodnl			must not be empty
160640266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
160706f25ae9SGregory Neil Shapiro###			! does lookup only with tag
160806f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
160940266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
161006f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
161106f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1612c2aa98e2SPeter Wemm######################################################################
1613c2aa98e2SPeter Wemm
161440266059SGregory Neil ShapiroSD
161506f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
161606f25ae9SGregory Neil Shapirodnl look up with tag (in front, no delimiter here)
161740266059SGregory Neil Shapirodnl    2    3  4    5
161840266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
161906f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
162006f25ae9SGregory Neil Shapirodnl look up without tag?
162140266059SGregory Neil Shapirodnl   1    2      3    4
162240266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
162340266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: look up .rest
162440266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
162540266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
162640266059SGregory Neil Shapirodnl   1  2    3    4  5    6
162740266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
162840266059SGregory Neil Shapirodnl   1  2    3      4    5
162940266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
163040266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
163140266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
163240266059SGregory Neil Shapirodnl      1    2    3  4    5
163340266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
163440266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
163540266059SGregory Neil Shapirodnl    1  2     3    4  5    6
163640266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
163740266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
163840266059SGregory Neil Shapiro`dnl not found: IPv6 net
163940266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
164040266059SGregory Neil Shapirodnl    1   2     3    4  5    6
164140266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
164240266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
164306f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
164440266059SGregory Neil Shapirodnl   1  2    3    4  5    6
164540266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
164640266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl look up Tag:
164740266059SGregory Neil Shapirodnl   1    2      3    4
164840266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
164940266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
165040266059SGregory Neil Shapirodnl   1    2    3  4    5
165140266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
165240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
165340266059SGregory Neil Shapirodnl            2    3    4  5    6
165440266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
165540266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
165640266059SGregory Neil Shapirodnl    2    3    4  5    6
165740266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1658c2aa98e2SPeter Wemm
1659c2aa98e2SPeter Wemm######################################################################
166040266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1661c2aa98e2SPeter Wemm###
1662c2aa98e2SPeter Wemm###	Parameters:
1663c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1664c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
166506f25ae9SGregory Neil Shapirodnl			must not be empty
166640266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
166706f25ae9SGregory Neil Shapiro###			! does lookup only with tag
166806f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
166940266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
167006f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
167106f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1672c2aa98e2SPeter Wemm######################################################################
1673c2aa98e2SPeter Wemm
167440266059SGregory Neil ShapiroSA
167506f25ae9SGregory Neil Shapirodnl look up with tag
167640266059SGregory Neil Shapirodnl    2    3  4    5
167740266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
167806f25ae9SGregory Neil Shapirodnl look up without tag
167940266059SGregory Neil Shapirodnl   1    2      3    4
168040266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
168140266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
168240266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
168340266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
168440266059SGregory Neil Shapirodnl      1    2    3  4    5
168540266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
168640266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
168740266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
168840266059SGregory Neil Shapirodnl   1   2    3    4  5    6
168940266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
169040266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
169106f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
169240266059SGregory Neil Shapirodnl   1  2    3    4  5    6
169340266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
169406f25ae9SGregory Neil Shapirodnl no match: return default
169540266059SGregory Neil Shapirodnl   1    2    3  4    5
169640266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
169740266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
169840266059SGregory Neil Shapirodnl            2    3    4  5    6
169940266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
170006f25ae9SGregory Neil Shapirodnl match: return result
170140266059SGregory Neil Shapirodnl    2    3    4  5    6
170240266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
170340266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
170440266059SGregory Neil Shapirodivert(0)
1705c2aa98e2SPeter Wemm######################################################################
1706065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1707065a643dSPeter Wemm###			relay checking.  Route address syntax is
1708065a643dSPeter Wemm###			crudely converted into a %-hack address.
1709065a643dSPeter Wemm###
1710065a643dSPeter Wemm###	Parameters:
1711065a643dSPeter Wemm###		$1 -- full recipient address
1712065a643dSPeter Wemm###
1713065a643dSPeter Wemm###	Returns:
1714065a643dSPeter Wemm###		parsed address, not in source route form
171506f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
171606f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1717065a643dSPeter Wemm######################################################################
1718065a643dSPeter Wemm
1719065a643dSPeter WemmSCanonAddr
172006f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
172106f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1722065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1723065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1724065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
172506f25ae9SGregory Neil Shapirodnl')
1726065a643dSPeter Wemm
1727065a643dSPeter Wemm######################################################################
1728c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1729c2aa98e2SPeter Wemm###			$* $=m or the access database.
1730c2aa98e2SPeter Wemm###			Check user portion for host separators.
1731c2aa98e2SPeter Wemm###
1732c2aa98e2SPeter Wemm###	Parameters:
1733c2aa98e2SPeter Wemm###		$1 -- full recipient address
1734c2aa98e2SPeter Wemm###
1735c2aa98e2SPeter Wemm###	Returns:
1736c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1737c2aa98e2SPeter Wemm######################################################################
1738c2aa98e2SPeter Wemm
1739c2aa98e2SPeter WemmSParseRecipient
174006f25ae9SGregory Neil Shapirodnl mark and canonify address
1741065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
174206f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1743c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
174406f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1745c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1746c2aa98e2SPeter Wemm
1747c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1748c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
174906f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1750c2aa98e2SPeter WemmR<?> $*				$@ $1
1751c2aa98e2SPeter Wemm
175240266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
175306f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1754c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1755c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1756c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
175706f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
175806f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
175940266059SGregory Neil Shapiro
176040266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
176140266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
17625b0945b5SGregory Neil Shapirodnl other To: entries: blocklist recipient; generic entries?
176340266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1764c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1765c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
176606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
176706f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1768065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1769c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
177006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
177140266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1772c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1773065a643dSPeter Wemm
177406f25ae9SGregory Neil Shapiro
177540266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
177640266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
177740266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1778e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
177940266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
178040266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
178140266059SGregory Neil Shapirodnl no: put old <NO> mark back
178240266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
178340266059SGregory Neil Shapiro
178440266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1785c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
178640266059SGregory Neil Shapirodnl something else
178740266059SGregory Neil ShapiroR<$+> $*			$@ $2
1788c2aa98e2SPeter Wemm
178906f25ae9SGregory Neil Shapiro
1790c2aa98e2SPeter Wemm######################################################################
1791c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1792c2aa98e2SPeter Wemm######################################################################
1793c2aa98e2SPeter Wemm
1794e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1795e92d3f3fSGregory Neil ShapiroScheck_relay
1796e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1797e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1798e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1799e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1800e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1801e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1802e92d3f3fSGregory Neil Shapirodnl')
1803e92d3f3fSGregory Neil Shapiro
1804c2aa98e2SPeter WemmSLocal_check_relay
180506f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1806e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1807e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1808c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1809c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1810c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1811c2aa98e2SPeter Wemm
1812c2aa98e2SPeter WemmSBasic_check_relay
1813c2aa98e2SPeter Wemm# check for deferred delivery mode
181494c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1815c2aa98e2SPeter WemmR< d > $*		$@ deferred
1816c2aa98e2SPeter WemmR< $* > $*		$: $2
1817c2aa98e2SPeter Wemm
181806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
181942e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
182040266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
182142e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
182213bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
182313bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
182413bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
182540266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
182640266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
182740266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
182840266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
182942e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1830e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
183140266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1832e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
183306f25ae9SGregory Neil Shapirodnl error tag
183442e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
183542e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
18365b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: _TMPFMSG_(`CR')', `dnl')
183706f25ae9SGregory Neil Shapirodnl generic error from access map
183842e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1839c2aa98e2SPeter Wemm
1840c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
184106f25ae9SGregory Neil Shapiro# DNS based IP address spam list
184240266059SGregory Neil Shapirodnl workspace: ignored...
1843c2aa98e2SPeter WemmR$*			$: $&{client_addr}
184406f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
184506f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
184694c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1847c2aa98e2SPeter Wemm`dnl')
1848e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1849e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1850e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1851e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1852e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1853e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1854e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1855e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
18566f9c8e5bSGregory Neil Shapiroundivert(8)dnl LOCAL_DNSBL
1857d0cef73dSGregory Neil Shapiroifdef(`_REQUIRE_RDNS_', `dnl
1858d0cef73dSGregory Neil ShapiroR$*			$: $&{client_addr} $| $&{client_resolve}
1859d0cef73dSGregory Neil ShapiroR$=R $*			$@ RELAY		We relay for these
1860d0cef73dSGregory Neil ShapiroR$* $| OK		$@ OK			Resolves.
1861d0cef73dSGregory Neil ShapiroR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1862d0cef73dSGregory Neil ShapiroR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1863d0cef73dSGregory Neil ShapiroR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1864d0cef73dSGregory Neil Shapiro', `dnl')
1865c2aa98e2SPeter Wemm
1866c2aa98e2SPeter Wemm######################################################################
1867c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1868c2aa98e2SPeter Wemm######################################################################
1869c2aa98e2SPeter Wemm
1870c2aa98e2SPeter WemmSLocal_check_mail
187106f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1872c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1873c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1874c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1875c2aa98e2SPeter Wemm
1876c2aa98e2SPeter WemmSBasic_check_mail
1877c2aa98e2SPeter Wemm# check for deferred delivery mode
187894c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1879c2aa98e2SPeter WemmR< d > $*		$@ deferred
1880c2aa98e2SPeter WemmR< $* > $*		$: $2
1881c2aa98e2SPeter Wemm
188206f25ae9SGregory Neil Shapiro# authenticated?
188306f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
188406f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
188506f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
188606f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
188706f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
188806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
188906f25ae9SGregory Neil Shapiro
189006f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
189106f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
189206f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
189306f25ae9SGregory Neil Shapirodnl do some additional checks
189406f25ae9SGregory Neil Shapirodnl no user@host
189506f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
189606f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
189706f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
189806f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
189906f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
190006f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
190106f25ae9SGregory Neil ShapiroR$+			$: <?> $1
190206f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
190306f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
190406f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
190506f25ae9SGregory Neil Shapirodnl prepend daemon_flags
190606f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
190706f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
190806f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
190906f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
191006f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
191106f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
191206f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
191306f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
191406f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
191506f25ae9SGregory Neil Shapirodnl remove daemon_flags
191606f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
191706f25ae9SGregory Neil Shapiro# handle case of @localhost on address
191806f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
191906f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
192006f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
1921da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] >
1922da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] >
1923da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:::1] >
1924da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:::1] >
192506f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
192606f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
192706f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
192806f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
192906f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
193006f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
193106f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
193206f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
193306f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
193406f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
193506f25ae9SGregory Neil Shapirodnl	or:    <address>
193606f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
193706f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
193840266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
193906f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
194006f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
194106f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
194206f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
194306f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
194406f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1945065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1946c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1947959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
194806f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
194994c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1950959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1951c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
195240266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
195306f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
195406f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
195506f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
195640266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
195706f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1958c2aa98e2SPeter Wemm
195906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
196006f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
196106f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
196240266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
196340266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
196406f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
196506f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
196606f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
196706f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
196806f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
196906f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
197006f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
197106f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1972c2aa98e2SPeter Wemm# retransform for further use
197306f25ae9SGregory Neil Shapirodnl required form:
197406f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
197506f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
197606f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
197706f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
197806f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1979c2aa98e2SPeter Wemm
1980c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1981c2aa98e2SPeter Wemm# handle case of no @domain on address
198206f25ae9SGregory Neil Shapirodnl prepend daemon_flags
198306f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
198406f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
198540266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
198606f25ae9SGregory Neil Shapirodnl remove daemon_flags
198706f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
198813bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1989959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
199040266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1991c2aa98e2SPeter Wemm							...remote is not')
1992c2aa98e2SPeter Wemm# check results
199306f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1994d0cef73dSGregory Neil ShapiroR<$={ResOk}> $*		$: @ $2		domain ok
199506f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
199640266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
199706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
199840266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1999c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
2000e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
2001e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
200206f25ae9SGregory Neil Shapirodnl error tag
200306f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
200406f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
20055b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`CM')', `dnl')
200606f25ae9SGregory Neil Shapirodnl generic error from access map
200706f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
2008c2aa98e2SPeter Wemm`dnl')
2009d0cef73dSGregory Neil Shapirodnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
2010d0cef73dSGregory Neil Shapiro
2011d0cef73dSGregory Neil Shapiroifdef(`_BADMX_CHK_', `dnl
2012d0cef73dSGregory Neil ShapiroR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
2013d0cef73dSGregory Neil ShapiroR$* $| $#$*		$#$2
2014d0cef73dSGregory Neil Shapiro
2015d0cef73dSGregory Neil ShapiroSBadMX
2016d0cef73dSGregory Neil Shapiro# Look up MX records and ferret away a copy of the original address.
2017d0cef73dSGregory Neil Shapiro# input: domain part of address to check
2018d0cef73dSGregory Neil ShapiroR$+				$:<MX><$1><:$(mxlist $1$):><:>
2019d0cef73dSGregory Neil Shapiro# workspace: <MX><domain><: mxlist-result $><:>
2020d0cef73dSGregory Neil ShapiroR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
2021d0cef73dSGregory Neil Shapiro# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
2022d0cef73dSGregory Neil Shapiro# Recursively run badmx check on each mx.
2023d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
2024d0cef73dSGregory Neil Shapiro# See if any of them fail.
2025e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
2026d0cef73dSGregory Neil Shapiro# Reverse the mxlists so we can use the same argument order again.
2027d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2028d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
2029d0cef73dSGregory Neil Shapiro
2030d0cef73dSGregory Neil Shapiro# Reverse the lists so we can use the same argument order again.
2031d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2032d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
2033d0cef73dSGregory Neil Shapiro
2034e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
2035d0cef73dSGregory Neil Shapiro`dnl')
2036d0cef73dSGregory Neil Shapiro
2037c2aa98e2SPeter Wemm
2038c2aa98e2SPeter Wemm######################################################################
2039c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
2040c2aa98e2SPeter Wemm######################################################################
2041c2aa98e2SPeter Wemm
2042c2aa98e2SPeter WemmSLocal_check_rcpt
204306f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
2044c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
2045c2aa98e2SPeter WemmR$* $| $#$*		$#$2
2046c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
2047c2aa98e2SPeter Wemm
2048c2aa98e2SPeter WemmSBasic_check_rcpt
204940266059SGregory Neil Shapiro# empty address?
205040266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
205140266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
2052c2aa98e2SPeter Wemm# check for deferred delivery mode
205394c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
2054c2aa98e2SPeter WemmR< d > $*		$@ deferred
2055c2aa98e2SPeter WemmR< $* > $*		$: $2
2056c2aa98e2SPeter Wemm
205706f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
205840266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
205940266059SGregory Neil Shapirodnl it is not activated.
206040266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
206140266059SGregory Neil Shapirodnl available down below; look for the same macro.
206240266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
206340266059SGregory Neil Shapirodnl canonicalization.
206440266059SGregory Neil Shapiro# require fully qualified domain part?
206540266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
206606f25ae9SGregory Neil ShapiroR$+			$: <?> $1
206706f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
206806f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
206940266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
207013bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
207106f25ae9SGregory Neil Shapirodnl prepend daemon_flags
207240266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
207306f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
2074af9557fdSGregory Neil Shapirodnl _r_equire qual.rcpt: ok
2075a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
207606f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
2077a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
207806f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
207906f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
208040266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
208106f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
208206f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
208306f25ae9SGregory Neil Shapiro
208440266059SGregory Neil Shapirodnl ##################################################################
208540266059SGregory Neil Shapirodnl call subroutines for recipient and relay
208640266059SGregory Neil Shapirodnl possible returns from subroutines:
208740266059SGregory Neil Shapirodnl $#TEMP	temporary failure
208840266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
208940266059SGregory Neil Shapirodnl $#other	stop processing
209040266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
209140266059SGregory Neil Shapirodnl other	otherwise
209240266059SGregory Neil Shapiro######################################################################
209340266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
209440266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
209540266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
209640266059SGregory Neil Shapirodnl error or ok (stop)
209740266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
209840266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
209940266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
210040266059SGregory Neil Shapirodnl something else: call check sender (relay)
210140266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
210240266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
210340266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
210440266059SGregory Neil Shapirodnl temporary failure? return that
210540266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
210640266059SGregory Neil Shapirodnl error or ok (stop)
210740266059SGregory Neil ShapiroR$* $| $#$*		$#$2
210840266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
210940266059SGregory Neil Shapirodnl something else: return previous temp failure
211040266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
211140266059SGregory Neil Shapiro# anything else is bogus
211240266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
211340266059SGregory Neil Shapirodivert(0)
211440266059SGregory Neil Shapiro
211540266059SGregory Neil Shapiro######################################################################
211640266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
211740266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
211840266059SGregory Neil Shapirodnl output: see explanation at call
211940266059SGregory Neil Shapiro######################################################################
212040266059SGregory Neil ShapiroSRcpt_ok
2121c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2122065a643dSPeter WemmR$*			$: $>CanonAddr $1
2123c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2124c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2125c2aa98e2SPeter Wemm
2126065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2127065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2128065a643dSPeter Wemm# unlimited bestmx
2129065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2130065a643dSPeter Wemm`dnl
2131065a643dSPeter Wemm# limit bestmx to $=B
21322e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
213340266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2134065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2135065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2136065a643dSPeter Wemm
21375b0945b5SGregory Neil Shapiroifdef(`_BLOCKLIST_RCPT_',`dnl
213806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21395b0945b5SGregory Neil Shapiro# blocklist local users or any host from receiving mail
2140c2aa98e2SPeter WemmR$*			$: <?> $1
214106f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
214206f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
214340266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
214440266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
214506f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
214606f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
214706f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
214806f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
214906f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
215006f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
215140266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
215240266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
215340266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
215440266059SGregory Neil Shapirodnl that would make a lot of things easier.
215506f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
215640266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
215740266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
215840266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
215940266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
216006f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
216106f25ae9SGregory Neil Shapirodnl as generic error message...
216206f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
216306f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
216406f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
216506f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
216640266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
216706f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2168e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
216906f25ae9SGregory Neil Shapirodnl error tag
217006f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
217106f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
21725b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: _TMPFMSG_(`ROK1')', `dnl')
217306f25ae9SGregory Neil Shapirodnl generic error from access map
217406f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
217506f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2176c2aa98e2SPeter Wemm
217740266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
217840266059SGregory Neil Shapiro# authenticated via TLS?
217940266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
218006f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
218106f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
218206f25ae9SGregory Neil Shapiro
218340266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
218440266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
218540266059SGregory Neil ShapiroR$* $| $# $*		$# $2
218640266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
218740266059SGregory Neil ShapiroR$* $| NO		$: $1
218840266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
218940266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
219006f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
219106f25ae9SGregory Neil ShapiroR$* $|			$: $1
219206f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
219306f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
219440266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
219540266059SGregory Neil Shapirodnl remove ${auth_type}
219606f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2197193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
219806f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2199193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2200193538b7SGregory Neil ShapiroR$* ! $*		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2201da7d7b9cSGregory Neil Shapiroifelse(defn(`_NO_PERCENTHACK_'), `r',
2202da7d7b9cSGregory Neil Shapiro`R$* % $* < @ $* >	$: <REMOTE> $1 < @ PERCENT_HACK >
2203da7d7b9cSGregory Neil ShapiroR$* % $*		$: <REMOTE> $1 < @ PERCENT_HACK >', `dnl')
2204c2aa98e2SPeter Wemm# anything terminating locally is ok
2205c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
220640266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
220740266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2208c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
220940266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
221006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
22119bd497b8SGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
22129bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
22139bd497b8SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
22149bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
221506f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
221606f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
221740266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
221806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2219e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2220e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2221e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2222e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2223e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
222406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
222506f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
222640266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
22275b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`ROK2')', `dnl')
2228c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2229c2aa98e2SPeter Wemm
223006f25ae9SGregory Neil Shapiro
2231c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2232c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
223306f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
223406f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2235e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
223640266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2237065a643dSPeter WemmR< : $* : > $*		$: $2',
2238c2aa98e2SPeter Wemm`dnl')
2239c2aa98e2SPeter Wemm
2240c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2241c2aa98e2SPeter WemmR$*			$: <?> $1
2242065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2243c2aa98e2SPeter Wemm# local user is ok
224406f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
224506f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
224606f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
224706f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
224806f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
224940266059SGregory Neil ShapiroR<?> postmaster		$@ OK
225006f25ae9SGregory Neil Shapiro# require qualified recipient?
225106f25ae9SGregory Neil Shapirodnl prepend daemon_flags
225206f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
225306f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
225406f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
225506f25ae9SGregory Neil Shapirodnl r flag? add client_name
225606f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
225706f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
225806f25ae9SGregory Neil Shapiro# no qualified recipient required
225940266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
226006f25ae9SGregory Neil Shapirodnl client_name is empty
226140266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
226206f25ae9SGregory Neil Shapirodnl client_name is local
226340266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
226406f25ae9SGregory Neil Shapirodnl client_name is not local
226506f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
226606f25ae9SGregory Neil Shapirodnl no qualified recipient required
226740266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
226806f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2269c2aa98e2SPeter WemmR<$+> $*		$: $2
227006f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2271c2aa98e2SPeter Wemm
227240266059SGregory Neil Shapiro######################################################################
227340266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
227440266059SGregory Neil Shapirodnl input: ignored
227540266059SGregory Neil Shapirodnl output: see explanation at call
227640266059SGregory Neil Shapiro######################################################################
227740266059SGregory Neil ShapiroSRelay_ok
2278c2aa98e2SPeter Wemm# anything originating locally is ok
2279c2aa98e2SPeter Wemm# check IP address
2280c2aa98e2SPeter WemmR$*			$: $&{client_addr}
228140266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
228240266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
228313bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
2284da7d7b9cSGregory Neil ShapiroRIPv6:0:0:0:0:0:0:0:1	$@ RELAY		originated locally
2285da7d7b9cSGregory Neil Shapirodnl if compiled with IPV6_FULL=0
228613bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
228740266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
228806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
228940266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
229040266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY		relayable IP address
2291959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2292959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2293959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2294959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2295959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2296959366dcSGregory Neil ShapiroR<REJECT> $*		$@ REJECT		rejected IP address')
22975b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl')
2298c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2299c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
230040266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2301c2aa98e2SPeter Wemm
230206f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
230306f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
230406f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
230506f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
230606f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
230706f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
230806f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
230940266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2310c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
231106f25ae9SGregory Neil Shapiro# check whether local FROM is ok
231240266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
231306f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2314605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
231540266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
23165b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK2')', `dnl')
231740266059SGregory Neil Shapiro', `dnl
231840266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
231940266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
232006f25ae9SGregory Neil Shapiro')',
232106f25ae9SGregory Neil Shapiro`dnl')
232206f25ae9SGregory Neil Shapirodnl')', `dnl')
232340266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
232440266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
232540266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
232606f25ae9SGregory Neil Shapiro
232706f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
232806f25ae9SGregory Neil Shapirodnl input: ignored
232906f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2330e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
233106f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
233206f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
233306f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
233440266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
233506f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
233613bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
233713bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
233813bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
233913bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
234013bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
234140266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
234240266059SGregory Neil Shapiro# pass to name server to make hostname canonical
234340266059SGregory Neil ShapiroR<@> $* $=P		$:<?>  $1 $2
234440266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
234540266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
234640266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
234706f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
234840266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
234940266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
235006f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
235140266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
235206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235306f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
235406f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
235540266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
235606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235740266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
235806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
235940266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
23605b0945b5SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK3')', `dnl')
236106f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
236240266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
236306f25ae9SGregory Neil Shapirodivert(0)
236406f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
236506f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
236606f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
236706f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
236806f25ae9SGregory Neil ShapiroSFullAddr
236906f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
237006f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
237106f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2372c2aa98e2SPeter Wemm
2373a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
237413bd1963SGregory Neil Shapiro# authenticated?
237513bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
237613bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
237713bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
237813bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
237913bd1963SGregory Neil Shapirodnl return result from checkrcpt
2380a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
238113bd1963SGregory Neil ShapiroR$*			$# $1
238213bd1963SGregory Neil Shapiro
2383a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
238413bd1963SGregory Neil Shapiro# authenticated?
238513bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
238613bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
238713bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
238813bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
238913bd1963SGregory Neil Shapirodnl return result from friend/hater check
2390a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
239113bd1963SGregory Neil ShapiroR$*			$@ $1
239213bd1963SGregory Neil Shapiro
239306f25ae9SGregory Neil Shapiro# call all necessary rulesets
239406f25ae9SGregory Neil ShapiroScheck_rcpt
239506f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
239606f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
239706f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
239813bd1963SGregory Neil Shapiro
239906f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
240006f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
240113bd1963SGregory Neil Shapirodnl on error (or discard) stop now
240213bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
240313bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
240413bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2405a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
240606f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
240706f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
240806f25ae9SGregory Neil Shapiro`dnl look up user@ and user@address
240906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
241006f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
241106f25ae9SGregory Neil Shapiro')')dnl
241206f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
24135b0945b5SGregory Neil Shapirodnl this code has been copied from BLOCKLIST... etc
241406f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
241540266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
241640266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
241706f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
241840266059SGregory Neil Shapiro# look up the addresses only with Spam tag
241940266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
242006f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
242106f25ae9SGregory Neil Shapirodnl', `dnl')
242206f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
242306f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
242406f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
242513bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
242606f25ae9SGregory Neil Shapiro')', `dnl')
2427a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
242806f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
242906f25ae9SGregory Neil Shapiro`dnl')
243006f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
243106f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
243240266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2433a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
243406f25ae9SGregory Neil Shapirodnl',`dnl')
2435d0cef73dSGregory Neil Shapiro
243606f25ae9SGregory Neil Shapirodnl run further checks: check_mail
243706f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
243840266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
243940266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
244040266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2441605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
244206f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
244306f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2444605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
244506f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
244606f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
244706f25ae9SGregory Neil Shapiro', `dnl')
244840266059SGregory Neil Shapiro
2449d0cef73dSGregory Neil Shapiroifdef(`_BLOCK_BAD_HELO_', `dnl
2450d0cef73dSGregory Neil ShapiroR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2451d0cef73dSGregory Neil Shapirodnl Bypass the test for users who have authenticated.
2452d0cef73dSGregory Neil ShapiroR$* $| <$+>		$: $1				skip if auth
2453d0cef73dSGregory Neil ShapiroR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2454d0cef73dSGregory Neil Shapirodnl Bypass for local clients -- IP address starts with $=R
2455d0cef73dSGregory Neil ShapiroR$* $| <$=R $*> [$*]	$: $1				skip if local client
2456d0cef73dSGregory Neil Shapirodnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2457d0cef73dSGregory Neil ShapiroR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2458d0cef73dSGregory Neil Shapirodnl Reject our IP - assumes "[ip]" is in class $=w
2459d0cef73dSGregory Neil ShapiroR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2460d0cef73dSGregory Neil Shapirodnl Reject our hostname
2461d0cef73dSGregory Neil ShapiroR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2462d0cef73dSGregory Neil Shapirodnl Pass anything else with a "." in the domain parameter
2463d0cef73dSGregory Neil ShapiroR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
24645dd76dd0SGregory Neil Shapirodnl Pass IPv6: address literals
24655dd76dd0SGregory Neil ShapiroR$* $| <$*> [IPv6:$+]	$: $1				qualified domain ok
2466d0cef73dSGregory Neil Shapirodnl Reject if there was no "." or only an initial or final "."
2467d0cef73dSGregory Neil ShapiroR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2468d0cef73dSGregory Neil Shapirodnl Clean up the workspace
2469d0cef73dSGregory Neil ShapiroR$* $| $*		$: $1
2470d0cef73dSGregory Neil Shapiro', `dnl')
2471d0cef73dSGregory Neil Shapiro
247240266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
247340266059SGregory Neil Shapiro######################################################################
247440266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
247540266059SGregory Neil Shapiro###
247640266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
247740266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
247840266059SGregory Neil Shapiro###
247940266059SGregory Neil Shapiro###	Parameters:
248040266059SGregory Neil Shapiro###		<$1> -- key
248140266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
248240266059SGregory Neil Shapirodnl			must not be empty
248340266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
248440266059SGregory Neil Shapiro###			! does lookup only with tag
248540266059SGregory Neil Shapiro###			+ does lookup with and without tag
248640266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
248740266059SGregory Neil Shapirodnl returns:		<default> <passthru>
248840266059SGregory Neil Shapirodnl			<result> <passthru>
248940266059SGregory Neil Shapiro######################################################################
249040266059SGregory Neil Shapiro
249140266059SGregory Neil ShapiroSF
249240266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
249340266059SGregory Neil Shapirodnl full lookup
249440266059SGregory Neil Shapirodnl    2    3  4    5
249540266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
249640266059SGregory Neil Shapirodnl no match, try without tag
249740266059SGregory Neil Shapirodnl   1    2      3    4
249840266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
249940266059SGregory Neil Shapirodnl no match, +detail: try +*
250040266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
250140266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
250240266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
250340266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
250440266059SGregory Neil Shapirodnl   1    2    3    4      5    6
250540266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
250640266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
250740266059SGregory Neil Shapirodnl no match, +detail: try without +detail
250840266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
250940266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
251040266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
251140266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
251240266059SGregory Neil Shapirodnl   1    2    3    4      5    6
251340266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
251440266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
251540266059SGregory Neil Shapirodnl no match, return <default> <passthru>
251640266059SGregory Neil Shapirodnl   1    2    3  4    5
251740266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
251840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
251940266059SGregory Neil Shapirodnl            2    3  4    5
252040266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
252140266059SGregory Neil Shapirodnl match, return <match> <passthru>
252240266059SGregory Neil Shapirodnl    2    3  4    5
252340266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
252440266059SGregory Neil Shapiro
252540266059SGregory Neil Shapiro######################################################################
252640266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
252740266059SGregory Neil Shapiro###
252840266059SGregory Neil Shapiro###	Parameters:
252940266059SGregory Neil Shapiro###		<$1> -- key
253040266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
253140266059SGregory Neil Shapirodnl			must not be empty
253240266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
253340266059SGregory Neil Shapiro###			! does lookup only with tag
253440266059SGregory Neil Shapiro###			+ does lookup with and without tag
253540266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
253640266059SGregory Neil Shapirodnl returns:		<default> <passthru>
253740266059SGregory Neil Shapirodnl			<result> <passthru>
253840266059SGregory Neil Shapiro######################################################################
253940266059SGregory Neil Shapiro
254040266059SGregory Neil ShapiroSE
254140266059SGregory Neil Shapirodnl    2    3  4    5
254240266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
254340266059SGregory Neil Shapirodnl no match, try without tag
254440266059SGregory Neil Shapirodnl   1    2      3    4
254540266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
254640266059SGregory Neil Shapirodnl no match, return default passthru
254740266059SGregory Neil Shapirodnl   1    2    3  4    5
254840266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
254940266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
255040266059SGregory Neil Shapirodnl            2    3  4    5
255140266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
255240266059SGregory Neil Shapirodnl match, return <match> <passthru>
255340266059SGregory Neil Shapirodnl    2    3  4    5
255440266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
255540266059SGregory Neil Shapiro
255640266059SGregory Neil Shapiro######################################################################
255740266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
255840266059SGregory Neil Shapiro###
255940266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
256040266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
256140266059SGregory Neil Shapiro###
256240266059SGregory Neil Shapiro###	Parameters:
256340266059SGregory Neil Shapiro###		<$1> -- key (user@)
256440266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
256540266059SGregory Neil Shapirodnl			must not be empty
256640266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
256740266059SGregory Neil Shapiro###			! does lookup only with tag
256840266059SGregory Neil Shapiro###			+ does lookup with and without tag
256940266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
257040266059SGregory Neil Shapirodnl returns:		<default> <passthru>
257140266059SGregory Neil Shapirodnl			<result> <passthru>
257240266059SGregory Neil Shapiro######################################################################
257340266059SGregory Neil Shapiro
257440266059SGregory Neil ShapiroSU
257540266059SGregory Neil Shapirodnl user lookups are always with trailing @
257640266059SGregory Neil Shapirodnl    2    3  4    5
257740266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
257840266059SGregory Neil Shapirodnl no match, try without tag
257940266059SGregory Neil Shapirodnl   1    2      3    4
258040266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
258140266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
258240266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
258340266059SGregory Neil Shapirodnl no match, +detail: try +*
258440266059SGregory Neil Shapirodnl   1    2      3    4  5    6
258540266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
258640266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
258740266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
258840266059SGregory Neil Shapirodnl   1    2      3      4    5
258940266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
259040266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
259140266059SGregory Neil Shapirodnl no match, +detail: try without +detail
259240266059SGregory Neil Shapirodnl   1    2      3    4  5    6
259340266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
259440266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
259540266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
259640266059SGregory Neil Shapirodnl   1    2      3      4    5
259740266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
259840266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
259940266059SGregory Neil Shapirodnl no match, return <default> <passthru>
260040266059SGregory Neil Shapirodnl   1    2    3  4    5
260140266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
260240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
260340266059SGregory Neil Shapirodnl            2    3  4    5
260440266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
260540266059SGregory Neil Shapirodnl match, return <match> <passthru>
260640266059SGregory Neil Shapirodnl    2    3  4    5
260740266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
260840266059SGregory Neil Shapiro
260906f25ae9SGregory Neil Shapiro######################################################################
261006f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
261106f25ae9SGregory Neil Shapiro###	Parameters:
261206f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
261306f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
2614d39bd2c1SGregory Neil Shapirodnl	avoid erroneous matches (with error messages?)
261506f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
261606f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
2617d39bd2c1SGregory Neil Shapirodnl	to avoid erroneous matches (first rule: D: if there
261806f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
261906f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
262006f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
262106f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
262206f25ae9SGregory Neil Shapiro###	<+ TAG>	look up with and w/o tag
262306f25ae9SGregory Neil Shapiro###	<! TAG>	look up with tag
262406f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
262506f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
262606f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
262740266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
262806f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
262906f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
263006f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
263106f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
263206f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
263306f25ae9SGregory Neil Shapiro######################################################################
263406f25ae9SGregory Neil Shapiro
263506f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
263606f25ae9SGregory Neil Shapirodnl if A is activated: add it
2637e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
263806f25ae9SGregory Neil ShapiroSSearchList
263940266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
264040266059SGregory Neil Shapirodnl       2       3    4
2641e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
264240266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
264340266059SGregory Neil Shapirodnl no match and nothing left: return
264440266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
264540266059SGregory Neil Shapirodnl no match but something left: continue
264640266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
264740266059SGregory Neil Shapirodnl match: return
264840266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
264906f25ae9SGregory Neil Shapirodnl return result from recursive invocation
265040266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
265140266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
265240266059SGregory Neil Shapirodivert(0)
265306f25ae9SGregory Neil Shapiro
265440266059SGregory Neil Shapiro######################################################################
265540266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
265640266059SGregory Neil Shapiro###
265740266059SGregory Neil Shapiro###	Parameters:
265840266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
265940266059SGregory Neil Shapiro######################################################################
266040266059SGregory Neil Shapiro
266140266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
266240266059SGregory Neil ShapiroSLocal_trust_auth
266306f25ae9SGregory Neil ShapiroStrust_auth
266406f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
266506f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
266606f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
266706f25ae9SGregory Neil Shapirodnl seems to be useful...
266806f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
266906f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
267006f25ae9SGregory Neil Shapirodnl call user supplied code
2671a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
267206f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
267306f25ae9SGregory Neil Shapirodnl default: error
267406f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
267506f25ae9SGregory Neil Shapiro
267640266059SGregory Neil Shapiro######################################################################
267740266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
267840266059SGregory Neil Shapiro###
267940266059SGregory Neil Shapiro###	Parameters:
268040266059SGregory Neil Shapiro###		$1: ${auth_type}
268140266059SGregory Neil Shapiro######################################################################
268240266059SGregory Neil ShapiroSLocal_Relay_Auth
268306f25ae9SGregory Neil Shapiro
268440266059SGregory Neil Shapiro######################################################################
268540266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
268640266059SGregory Neil Shapiro###	(done in server)
268740266059SGregory Neil Shapiro######################################################################
268840266059SGregory Neil ShapiroSsrv_features
268940266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
269040266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
269140266059SGregory Neil ShapiroR$* $| $#$*		$#$2
269240266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2693e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
269440266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
269540266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
269640266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
269706f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
269840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
269940266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2700e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
270106f25ae9SGregory Neil Shapiro
270240266059SGregory Neil Shapiro######################################################################
27032fb4f839SGregory Neil Shapiro###  clt_features: which features to use with a server?
27042fb4f839SGregory Neil Shapiro###	(done in client)
27052fb4f839SGregory Neil Shapiro######################################################################
27062fb4f839SGregory Neil ShapiroSclt_features
27072fb4f839SGregory Neil Shapiroifdef(`_LOCAL_CLT_FEATURES_', `dnl
27082fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"Local_clt_features" $1
27092fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
27102fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
27112fb4f839SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2712d39bd2c1SGregory Neil Shapirodnl the servername can have a trailing dot from canonification
2713d39bd2c1SGregory Neil ShapiroR$* .		$1
2714d39bd2c1SGregory Neil ShapiroR$+		$: $>D <$1> <?> <! CLT_FEAT_TAG> <>
27152fb4f839SGregory Neil ShapiroR<?>$*		$: <$(access CLT_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
27162fb4f839SGregory Neil ShapiroR<?>$*		$@ OK
27172fb4f839SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27182fb4f839SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
27192fb4f839SGregory Neil ShapiroR<$+>$*		$# $1')
27202fb4f839SGregory Neil Shapiro
27212fb4f839SGregory Neil Shapiro######################################################################
272240266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
272340266059SGregory Neil Shapiro###	(done in client)
272440266059SGregory Neil Shapiro######################################################################
272506f25ae9SGregory Neil ShapiroStry_tls
272640266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
272740266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
272840266059SGregory Neil ShapiroR$* $| $#$*		$#$2
272940266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2730e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
273140266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
273240266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
273340266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
273406f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
273540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
27365b0945b5SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl')
2737e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
273806f25ae9SGregory Neil Shapiro
27392fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
27402fb4f839SGregory Neil ShapiroSTLS_NameInList
27412fb4f839SGregory Neil ShapiroR$* :$&{TLS_Name}: $*	$@ ok
27422fb4f839SGregory Neil ShapiroR$*			$@ $1
27432fb4f839SGregory Neil Shapiro
27442fb4f839SGregory Neil Shapirodnl check SAN for STS
27452fb4f839SGregory Neil ShapiroSSTS_SAN
27462fb4f839SGregory Neil Shapiroifdef(`_STS_SAN', `dnl
27472fb4f839SGregory Neil ShapiroR$*			$: $&{server_name}
27482fb4f839SGregory Neil Shapirodnl exact match
27492fb4f839SGregory Neil ShapiroR$={cert_altnames}	$@ ok
27502fb4f839SGregory Neil Shapiro# strip only one level (no recursion!)
27512fb4f839SGregory Neil ShapiroR$-.$+			$: $2
27522fb4f839SGregory Neil Shapirodnl wildcard: *. or just .?
27532fb4f839SGregory Neil ShapiroR *.$={cert_altnames}	$@ ok
27542fb4f839SGregory Neil Shapirodnl R .$={cert_altnames}	$@ ok
27552fb4f839SGregory Neil Shapirodnl always temporary error? make it an option (of the feature)?
27562fb4f839SGregory Neil ShapiroR$*			$#error $@ 4.7.0 $: 450 $&{server_name} not listed in SANs', `dnl')
27572fb4f839SGregory Neil Shapiro
27582fb4f839SGregory Neil Shapirodnl input: ${verify}
27592fb4f839SGregory Neil Shapirodnl output: $# error ... (from TLS_connection)
27602fb4f839SGregory Neil Shapirodnl  everything else: ok
27612fb4f839SGregory Neil ShapiroSSTS_secure
27622fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
27632fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
27642fb4f839SGregory Neil ShapiroR $| $*		$@ ok
27652fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
27662fb4f839SGregory Neil ShapiroR$*@$+ $| $*	$2 $| $3
27672fb4f839SGregory Neil ShapiroR$+. $| $*	$1 $| $2
27682fb4f839SGregory Neil ShapiroR$+ $| $*	$: $(sts $1 $: none $) $| $2
27692fb4f839SGregory Neil ShapiroR$* <TMPF> $| $*	$#error $@ 4.7.0 $: 450 STS lookup temp fail
27702fb4f839SGregory Neil Shapirodnl check whether connection is "secure"
27712fb4f839SGregory Neil Shapirodnl always temporary error? make it an option (of the feature)?
27722fb4f839SGregory Neil ShapiroR$* secure $* $| $*	$@ $>"TLS_connection" $3 $| <TEMP+VERIFY:128>
27732fb4f839SGregory Neil ShapiroR$* $| $*	$: $2
27742fb4f839SGregory Neil Shapiro
27752fb4f839SGregory Neil Shapirodnl check STS policy: secure and match? if so, check list
27762fb4f839SGregory Neil ShapiroSSTS_Check
27772fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
27782fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
27792fb4f839SGregory Neil ShapiroR $| $*		$@ ok
27802fb4f839SGregory Neil Shapiro# use the original argument for the test, not {rcpt_addr}
27812fb4f839SGregory Neil ShapiroR$* $| $*	$: $2 $| $2
27822fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
27832fb4f839SGregory Neil ShapiroR$*@$+ $| $*	$2 $| $3
27842fb4f839SGregory Neil ShapiroR$+. $| $*	$1 $| $2
27852fb4f839SGregory Neil ShapiroR$* $| $*	$: $(sts $1 $: none $) $| mark
27862fb4f839SGregory Neil ShapiroR$* <TMPF> $| $*	$#error $@ 4.7.0 $: 450 STS lookup temp fail
27872fb4f839SGregory Neil Shapirodnl STS check only for "secure"
27882fb4f839SGregory Neil Shapirodnl do this only if {sts_sni} is set?
27892fb4f839SGregory Neil Shapirodnl workspace: result of sts lookup $| mark
27902fb4f839SGregory Neil ShapiroR$* secure $* $| mark	$: $2 $| trmatch
27912fb4f839SGregory Neil Shapirodnl not "secure": no check
27922fb4f839SGregory Neil ShapiroR$* $| mark	$@ ok
27932fb4f839SGregory Neil Shapirodnl remove servername=hostname, keep match=
27942fb4f839SGregory Neil ShapiroR$* servername=hostname $| trmatch	$: $1 $| trmatch
27952fb4f839SGregory Neil Shapirodnl extra list of matches, i.e., remove match=
27962fb4f839SGregory Neil ShapiroR$+ $| trmatch				$: : $(stsxmatch $1 $: : $)
27972fb4f839SGregory Neil Shapirodnl no match= data
27982fb4f839SGregory Neil ShapiroR$* $| trmatch		$@ $>STS_SAN
27992fb4f839SGregory Neil Shapirodnl Remove trailing dots from each entry in the list;
28002fb4f839SGregory Neil Shapirodnl those should not be there, but better safe than sorry.
28012fb4f839SGregory Neil ShapiroR$*:$+.:$*	$1:$2:$3
28022fb4f839SGregory Neil ShapiroR:$+:		$: $(macro {TLS_Name} $@ $&{server_name} $) $>TLS_NameInList :$1:
28032fb4f839SGregory Neil ShapiroR$* ok		$@ $>STS_SAN
28042fb4f839SGregory Neil ShapiroR$*		$: $1 $| $&{server_name}
28052fb4f839SGregory Neil ShapiroR:$* $| $-.$+	$: $(macro {TLS_Name} $@ .$3 $) $>TLS_NameInList :$1
28062fb4f839SGregory Neil ShapiroR$* ok		$@ $>STS_SAN
28072fb4f839SGregory Neil ShapiroR:$*:		$#error $@ 4.7.0 $: 450 $&{server_name} not found in " "$1', `dnl')
28082fb4f839SGregory Neil Shapiro
2809d39bd2c1SGregory Neil Shapiroifdef(`TLS_PERM_ERR', `dnl
2810d39bd2c1SGregory Neil Shapirodefine(`TLS_DSNCODE', `5.7.0')dnl
2811d39bd2c1SGregory Neil Shapirodefine(`TLS_ERRCODE', `554')',`dnl
2812d39bd2c1SGregory Neil Shapirodefine(`TLS_DSNCODE', `4.7.0')dnl
2813d39bd2c1SGregory Neil Shapirodefine(`TLS_ERRCODE', `454')')dnl
2814d39bd2c1SGregory Neil Shapirodefine(`SW_MSG', `TLS handshake failed.')dnl
2815d39bd2c1SGregory Neil Shapirodefine(`DANE_MSG', `DANE check failed.')dnl
2816d39bd2c1SGregory Neil Shapirodefine(`DANE_TEMP_MSG', `DANE check failed temporarily.')dnl
2817d39bd2c1SGregory Neil Shapirodefine(`DANE_NOTLS_MSG', `DANE: missing STARTTLS.')dnl
2818d39bd2c1SGregory Neil Shapirodefine(`PROT_MSG', `STARTTLS failed.')dnl
2819d39bd2c1SGregory Neil Shapirodefine(`CNF_MSG', `STARTTLS temporarily not possible.')dnl
2820d39bd2c1SGregory Neil Shapiro
282140266059SGregory Neil Shapiro######################################################################
282240266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
282340266059SGregory Neil Shapiro###	(done in client, per recipient)
282440266059SGregory Neil Shapirodnl called from deliver() before RCPT command
282540266059SGregory Neil Shapiro###
282640266059SGregory Neil Shapiro###	Parameters:
282740266059SGregory Neil Shapiro###		$1: recipient
282840266059SGregory Neil Shapiro######################################################################
282940266059SGregory Neil ShapiroStls_rcpt
283040266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
283140266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
283240266059SGregory Neil ShapiroR$* $| $#$*		$#$2
283340266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
28342fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
28352fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"STS_Check" $1
28362fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
28372fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2838e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
283940266059SGregory Neil Shapirodnl store name of other side
284040266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
284140266059SGregory Neil Shapirodnl canonify recipient address
284240266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
284340266059SGregory Neil Shapirodnl strip trailing dots
284440266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
284540266059SGregory Neil Shapirodnl full address?
284640266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
284740266059SGregory Neil Shapirodnl only localpart?
284840266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
284940266059SGregory Neil Shapirodnl look it up
285040266059SGregory Neil Shapirodnl also look up a default value via E:
285140266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
2852d39bd2c1SGregory Neil Shapirodnl no applicable requirements; trigger an error on DANE_FAIL
2853d39bd2c1SGregory Neil Shapirodnl note: this allows to disable DANE per RCPT.
2854d39bd2c1SGregory Neil ShapiroR$* $| <?>	$: $1 $| $&{verify} $| <?>
2855d39bd2c1SGregory Neil ShapiroR$* $| DANE_FAIL $| <?>	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
2856d39bd2c1SGregory Neil ShapiroR$* $| DANE_NOTLS $| <?>	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_NOTLS_MSG"
2857d39bd2c1SGregory Neil ShapiroR$* $| DANE_TEMP $| <?>	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_TEMP_MSG"
285840266059SGregory Neil Shapirodnl found nothing: stop here
285940266059SGregory Neil ShapiroR$* $| <?>	$@ OK
286040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
28615b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TR')', `dnl')
286240266059SGregory Neil Shapirodnl use the generic routine (for now)
2863d39bd2c1SGregory Neil ShapiroR$* $| <$+>		$@ $>"TLS_connection" $&{verify} $| <$2>', `dnl
2864d39bd2c1SGregory Neil ShapiroR$*			$: $1 $| $&{verify}
2865d39bd2c1SGregory Neil ShapiroR$* $| DANE_NOTLS	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_NOTLS_MSG"
2866d39bd2c1SGregory Neil ShapiroR$* $| DANE_TEMP	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_TEMP_MSG"
2867d39bd2c1SGregory Neil ShapiroR$* $| DANE_FAIL	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"')
286840266059SGregory Neil Shapiro
286940266059SGregory Neil Shapiro######################################################################
287040266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
287140266059SGregory Neil Shapiro###	(done in server)
287240266059SGregory Neil Shapiro###
287340266059SGregory Neil Shapiro###	Parameters:
287440266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
287540266059SGregory Neil Shapiro######################################################################
287606f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
287706f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
287806f25ae9SGregory Neil ShapiroStls_client
287940266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
2880e3793f76SGregory Neil ShapiroR$*			$: $1 <?> $>"Local_tls_client" $1
2881e3793f76SGregory Neil ShapiroR$* <?> $#$*		$#$2
2882e3793f76SGregory Neil ShapiroR$* <?> $*		$: $1', `dnl')
288306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
288440266059SGregory Neil Shapirodnl store name of other side
28859bd497b8SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
288606f25ae9SGregory Neil Shapirodnl ignore second arg for now
288706f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
288806f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
288906f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
289040266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
289140266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
289206f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
289306f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
289440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
28955b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TC')', `dnl')
289640266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
289740266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
289806f25ae9SGregory Neil Shapiro
289940266059SGregory Neil Shapiro######################################################################
290040266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
290140266059SGregory Neil Shapiro###	(done in client)
290240266059SGregory Neil Shapiro###
290340266059SGregory Neil Shapiro###	Parameter:
290440266059SGregory Neil Shapiro###		${verify}
290540266059SGregory Neil Shapiro######################################################################
290606f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
290706f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
290806f25ae9SGregory Neil ShapiroStls_server
290940266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
291040266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
291140266059SGregory Neil ShapiroR$* $| $#$*		$#$2
291240266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
29135b0945b5SGregory Neil Shapiroifdef(`_TLS_FAILURES_',`dnl
29145b0945b5SGregory Neil ShapiroR$*		$: $(macro {saved_verify} $@ $1 $) $1')
29152fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
29162fb4f839SGregory Neil ShapiroR$*			$: $1 $| $>"STS_secure" $1
29172fb4f839SGregory Neil ShapiroR$* $| $#$*		$#$2
29182fb4f839SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
291906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
292040266059SGregory Neil Shapirodnl store name of other side
292140266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
292240266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
292340266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
292406f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
292506f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
292640266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
29275b0945b5SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`TS')', `dnl')
292840266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
292940266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
293006f25ae9SGregory Neil Shapiro
293140266059SGregory Neil Shapiro######################################################################
293240266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
293340266059SGregory Neil Shapiro###
293440266059SGregory Neil Shapiro###	Parameters:
293506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
293640266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
293740266059SGregory Neil Shapiro###		${verify}')
293840266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
293940266059SGregory Neil Shapirodnl	syntax for Requirement:
294040266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
294140266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
294240266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
294340266059SGregory Neil Shapiro######################################################################
294440266059SGregory Neil ShapiroSTLS_connection
29452fb4f839SGregory Neil Shapiroifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl', `dnl use default error
294640266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
29472fb4f839SGregory Neil ShapiroRSOFTWARE	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE SW_MSG"
2948d39bd2c1SGregory Neil Shapirodnl RDANE_FAIL	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
29492fb4f839SGregory Neil ShapiroRPROTOCOL	$#error $@ TLS_DSNCODE $: "TLS_ERRCODE PROT_MSG"
29502fb4f839SGregory Neil ShapiroRCONFIG		$#error $@ TLS_DSNCODE $: "TLS_ERRCODE CNF_MSG"
2951d39bd2c1SGregory Neil Shapirodnl RDANE_TEMP	$#error $@ 4.7.0 $: "454 DANE_TEMP_MSG"
295240266059SGregory Neil Shapirodivert(-1)')
295306f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
295440266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
295506f25ae9SGregory Neil Shapirodnl remove optional <>
295606f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
295740266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
295840266059SGregory Neil Shapiro# create the appropriate error codes
295906f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2960e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2961e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
296206f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
29632fb4f839SGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <TLS_ERRCODE:TLS_DSNCODE> <$2 $3>
296440266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
29652fb4f839SGregory Neil Shapirodefine(`TLS_ERRORS', `dnl
29662fb4f839SGregory Neil ShapiroR`'$1 $| <$-:$+> $`'*		$`'#error $`'@ $`'2 $: $`'1 " $2"
29672fb4f839SGregory Neil Shapirodnl no <reply:dns> i.e. no requirements in the access map
29682fb4f839SGregory Neil Shapirodnl use default error
29692fb4f839SGregory Neil ShapiroR`'$1 $| $`'*		$`'#error $`'@ TLS_DSNCODE $: "TLS_ERRCODE $2"')dnl
297040266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
29712fb4f839SGregory Neil ShapiroTLS_ERRORS(SOFTWARE,SW_MSG)
29724e4196cbSGregory Neil Shapiro# deal with TLS protocol errors: abort
29732fb4f839SGregory Neil ShapiroTLS_ERRORS(PROTOCOL,PROT_MSG)
2974d39bd2c1SGregory Neil Shapirodnl # deal with DANE errors: abort
2975d39bd2c1SGregory Neil Shapirodnl TLS_ERRORS(DANE_FAIL,DANE_MSG)
29762fb4f839SGregory Neil Shapiro# deal with CONFIG (tls_clt_features) errors: abort
29772fb4f839SGregory Neil ShapiroTLS_ERRORS(CONFIG,CNF_MSG)
2978d39bd2c1SGregory Neil Shapirodnl # deal with DANE tempfail: abort
2979d39bd2c1SGregory Neil Shapirodnl TLS_ERRORS(DANE_TEMP,DANE_TEMP_MSG)
298040266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
298140266059SGregory Neil Shapirodnl separate optional requirements
298240266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2983e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
298440266059SGregory Neil Shapirodnl separate optional requirements
2985e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
298606f25ae9SGregory Neil Shapirodnl some other value in access map: accept
298706f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
298806f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
298906f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
299006f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
299140266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
299206f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
29935b0945b5SGregory Neil ShapiroR<$*><VERIFY> <> $={TlsVerified}	$@ OK
299440266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
299540266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
29965b0945b5SGregory Neil ShapiroR<$*><VERIFY> <$+> $={TlsVerified}	$: <$1> <REQ:0> <$2>
299706f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
29985b0945b5SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> $={TlsVerified}	$: <$1> <REQ:$2> <$3>
299906f25ae9SGregory Neil Shapirodnl just some level of encryption required
300040266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
300140266059SGregory Neil Shapirodnl workspace:
30025b0945b5SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!~ $={TlsVerified})
300340266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
300440266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
300540266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
300640266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
300740266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
300840266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
300940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
30105b0945b5SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> CLEAR	$#error $@ $2 $: $1 " STARTTLS disabled locally"
301106f25ae9SGregory Neil Shapirodnl some other value for ${verify}
301240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
301340266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
301440266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
301506f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
301640266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
301740266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
301840266059SGregory Neil Shapirodnl strength requirements fulfilled
301940266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
302040266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
302140266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
302240266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
302340266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
302440266059SGregory Neil Shapirodnl workspace:
302540266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
302640266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
302740266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
302840266059SGregory Neil Shapirodnl continue: check  extensions
302940266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
303040266059SGregory Neil Shapirodnl split extensions into own list
303140266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
303240266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
303340266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
303406f25ae9SGregory Neil Shapiro
303540266059SGregory Neil Shapiro######################################################################
303640266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
303740266059SGregory Neil Shapiro###
303840266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
303940266059SGregory Neil Shapiro###		$-: SMTP reply code
304040266059SGregory Neil Shapiro###		$+: Enhanced Status Code
304140266059SGregory Neil Shapirodnl  further requirements for this ruleset:
304240266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
304340266059SGregory Neil Shapirodnl
304440266059SGregory Neil Shapirodnl	right now this is only a logical AND
304540266059SGregory Neil Shapirodnl	i.e. all requirements must be true
304640266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
304740266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
304840266059SGregory Neil Shapirodnl	operations (no precedences etc)?
304940266059SGregory Neil Shapiro######################################################################
305040266059SGregory Neil ShapiroSTLS_req
305140266059SGregory Neil Shapirodnl no additional requirements: ok
305240266059SGregory Neil ShapiroR $| $+		$@ OK
305340266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
305440266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
30555b0945b5SGregory Neil Shapiroifdef(`_FFR_TLS_ALTNAMES', `dnl
30565b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $2 $| <$3>
30575b0945b5SGregory Neil ShapiroR<CN:$-.$+> $* $| <$+>			$: <CN:*.$2> $3 $| <$4>
30585b0945b5SGregory Neil ShapiroR<CN:$={cert_altnames}> $* $| <$+>	$@ $>"TLS_req" $3 $| <$3>
30595b0945b5SGregory Neil ShapiroR<CN:$*> $* $| <$+>			$: <CN:$&{TLS_Name}> $2 $| <$3>', `dnl')
306040266059SGregory Neil Shapirodnl match, check rest
306140266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
306240266059SGregory Neil Shapirodnl CN does not match
306340266059SGregory Neil Shapirodnl  1   2      3  4
306440266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
306540266059SGregory Neil Shapirodnl cert subject
306640266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
306740266059SGregory Neil Shapirodnl CS does not match
306840266059SGregory Neil Shapirodnl  1   2      3  4
306913bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
307040266059SGregory Neil Shapirodnl match, check rest
307140266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
307240266059SGregory Neil Shapirodnl CI does not match
307340266059SGregory Neil Shapirodnl  1   2      3  4
307413bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
30755b0945b5SGregory Neil Shapirodnl
30765b0945b5SGregory Neil ShapiroR<CITag:$-> $* $| <$+>	$: <$(access $1:$&{cert_issuer} $: ? $)> $2 $| <$3>
30775b0945b5SGregory Neil ShapiroR<?> $* $| <$-:$+>	$#error $@ $3 $: $2 " Cert Issuer " $&{cert_issuer} " not acceptable"
30785b0945b5SGregory Neil ShapiroR<OK> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
307940266059SGregory Neil Shapirodnl return from recursive call
308040266059SGregory Neil ShapiroROK			$@ OK
308140266059SGregory Neil Shapiro
308240266059SGregory Neil Shapiro######################################################################
308340266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
308440266059SGregory Neil Shapiro###
308540266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
308640266059SGregory Neil Shapiro######################################################################
308706f25ae9SGregory Neil ShapiroSmax
308806f25ae9SGregory Neil ShapiroR:		$: 0
308906f25ae9SGregory Neil ShapiroR:$-		$: $1
309006f25ae9SGregory Neil ShapiroR$-:		$: $1
309106f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
309206f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
309340266059SGregory Neil ShapiroR$-:$-:$-	$: $2
309440266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
309540266059SGregory Neil Shapirodivert(0)
309606f25ae9SGregory Neil Shapiro
30972fb4f839SGregory Neil Shapirodnl this must also be activated without _TLS_SESSION_FEATURES_
30982fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
30992fb4f839SGregory Neil Shapirodnl caller preserves workspace
31002fb4f839SGregory Neil ShapiroSSet_SNI
31012fb4f839SGregory Neil ShapiroR$*		$: <$&{rcpt_addr}>
31022fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
31032fb4f839SGregory Neil ShapiroR<>		$@ ""
31042fb4f839SGregory Neil Shapirodnl canonify to extract domain part?
31052fb4f839SGregory Neil ShapiroR<$*@$+>	$2
31062fb4f839SGregory Neil ShapiroR$+.		$1
31072fb4f839SGregory Neil ShapiroR$+		$: $(sts $1 $: none $)
31082fb4f839SGregory Neil ShapiroR$* <TMPF>	$#error $@ 4.7.0 $: 450 STS lookup temp fail
31092fb4f839SGregory Neil ShapiroRnone		$@ ""
31102fb4f839SGregory Neil Shapirodnl get servername=sni and store it in {sts_sni}
31112fb4f839SGregory Neil Shapirodnl stsxsni extracts the value of servername= (sni)
31122fb4f839SGregory Neil Shapirodnl stsxsni2 extracts servername=sni so it can be returned to the caller
31132fb4f839SGregory Neil ShapiroR$* secure $*	$: $(stsxsni $2 $: : $) $| sts=secure; $(stsxsni2 $2 $: : $)
31142fb4f839SGregory Neil Shapirodnl store {server_addr} as sni if there was a match
31152fb4f839SGregory Neil Shapirodnl Note: this implies that only servername=hostname (literally!)
31162fb4f839SGregory Neil Shapirodnl is only ever returned.
31172fb4f839SGregory Neil ShapiroR$+: $| $+ :	$: $(macro {sts_sni} $@ $&{server_name} $) set $| $2
31182fb4f839SGregory Neil ShapiroR$* $| $*	$@ $2
31192fb4f839SGregory Neil ShapiroR$*		$@ ""
31202fb4f839SGregory Neil Shapirodnl', `dnl')
31212fb4f839SGregory Neil Shapiro
3122da7d7b9cSGregory Neil Shapiroifdef(`_TLS_SESSION_FEATURES_', `dnl
31232fb4f839SGregory Neil Shapirodefine(`_NEED_TLS_CLT_FEATURES')
3124da7d7b9cSGregory Neil ShapiroStls_srv_features
3125da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3126da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Srv_Features> <$2>
3127da7d7b9cSGregory Neil ShapiroR<?> <$*>		$: $>A <$1> <?> <! TLS_Srv_Features> <$1>
3128da7d7b9cSGregory Neil ShapiroR<?> <$*>		$@ ""
3129da7d7b9cSGregory Neil ShapiroR<$+> <$*>		$@ $1
3130da7d7b9cSGregory Neil Shapiro', `dnl
3131da7d7b9cSGregory Neil ShapiroR$*		$@ ""')
31322fb4f839SGregory Neil Shapiro', `dnl
31332fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_',`define(`_NEED_TLS_CLT_FEATURES')')dnl
31342fb4f839SGregory Neil Shapiro')dnl
3135da7d7b9cSGregory Neil Shapiro
31362fb4f839SGregory Neil Shapiroifdef(`_NEED_TLS_CLT_FEATURES', `dnl
3137da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
31382fb4f839SGregory Neil ShapiroStls_clt_feat_acc
3139da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Clt_Features> <$2>
3140da7d7b9cSGregory Neil ShapiroR<?> <$*>		$: $>A <$1> <?> <! TLS_Clt_Features> <$1>
3141da7d7b9cSGregory Neil ShapiroR<?> <$*>		$@ ""
31422fb4f839SGregory Neil ShapiroR<$+> <$*>		$@ $1')
31432fb4f839SGregory Neil Shapiro
31442fb4f839SGregory Neil ShapiroSDANE_disabled
31452fb4f839SGregory Neil Shapirodnl Note: most of this is handled in the binary.
31462fb4f839SGregory Neil Shapirodnl input: access map lookup for tls_clt_features
31472fb4f839SGregory Neil Shapirodnl output:
31482fb4f839SGregory Neil Shapirodnl <>: disabled
31492fb4f839SGregory Neil Shapirodnl <DANE>: enabled
31502fb4f839SGregory Neil ShapiroR$+	$: < $(stsxnodaneflag $1 $: NOFLAGS $) >
31512fb4f839SGregory Neil ShapiroR<$* @>	$@ <>
31522fb4f839SGregory Neil ShapiroR$*	$: < $&{sts_sni} >
31532fb4f839SGregory Neil ShapiroR<>	$@ <>
31542fb4f839SGregory Neil Shapiro# check this too?
31552fb4f839SGregory Neil Shapiro# R$*		$: $&{client_flags}
31562fb4f839SGregory Neil Shapiro# R$* DD $*	$@ <>
31572fb4f839SGregory Neil ShapiroR$*	$@ <DANE>
31582fb4f839SGregory Neil Shapiro
31592fb4f839SGregory Neil ShapiroSSTS_disabled
31602fb4f839SGregory Neil Shapirodnl input: ignored
31612fb4f839SGregory Neil Shapirodnl output:
31622fb4f839SGregory Neil Shapirodnl <>: disabled
31632fb4f839SGregory Neil Shapirodnl <STS>: enabled
31642fb4f839SGregory Neil ShapiroR$*		$: $&{client_flags}
31652fb4f839SGregory Neil ShapiroR$* MM $*	$@ <>
31662fb4f839SGregory Neil Shapirodnl
31672fb4f839SGregory Neil ShapiroR$*		$: $&{rcpt_addr} $| $1
31682fb4f839SGregory Neil Shapiro# no {rcpt_addr}, no STS check
31692fb4f839SGregory Neil ShapiroR $| $*		$@ <>
31702fb4f839SGregory Neil ShapiroR$*		$@ <STS>
31712fb4f839SGregory Neil Shapiro
31722fb4f839SGregory Neil ShapiroStls_clt_features
31732fb4f839SGregory Neil Shapirodnl host $| ip
31742fb4f839SGregory Neil ShapiroR$*			$: $1 $| <>
31752fb4f839SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
31762fb4f839SGregory Neil ShapiroR$* $| <>		$: $1 $| $>"tls_clt_feat_acc" $1
31772fb4f839SGregory Neil ShapiroR$* $| $* $| $*		$: $1 $| $2 $| <$3>', `dnl')
31782fb4f839SGregory Neil Shapiroifdef(`_MTA_STS_', `dnl
31792fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty>
31802fb4f839SGregory Neil ShapiroR$* $| $* $| <$*>	$: $1 $| $2 $| <$3> $| $>"STS_disabled" sts
31812fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| STS_disabled result
31822fb4f839SGregory Neil Shapirodnl disable STS check? return access result
31832fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| <>	$@ $3
31842fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| STS_disabled result
31852fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| $*		$: $1 $| $2 $| <$3> $| $>"DANE_disabled" $3
31862fb4f839SGregory Neil Shapirodnl DANE enabled: return access result; take care of empty return
31872fb4f839SGregory Neil ShapiroR$* $| $* $| <$+> $| <DANE>		$@ $3
31882fb4f839SGregory Neil ShapiroR$* $| $* $| <> $| <DANE>		$@ ""
31892fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| <DANE_disabled result>
31902fb4f839SGregory Neil ShapiroR$* $| $* $| <$*> $| <$*>	$: $1 $| $2 $| <$3> $| $>"Set_SNI" $1
31912fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty> $| sni result
31922fb4f839SGregory Neil Shapirodnl return sni result if not empty but acc is
31932fb4f839SGregory Neil ShapiroR$* $| $* $| <""> $| $+		$@ $3
31942fb4f839SGregory Neil Shapirodnl return acc + sni result if not empty
31952fb4f839SGregory Neil ShapiroR$* $| $* $| <$+;> $| $+		$@ $3 ; $4
31962fb4f839SGregory Neil Shapirodnl return acc + sni result if not empty
31972fb4f839SGregory Neil ShapiroR$* $| $* $| <$+> $| $+		$@ $3 ; $4
31982fb4f839SGregory Neil Shapirodnl return sni result if not empty
31992fb4f839SGregory Neil ShapiroR$* $| $* $| <> $| $+		$@ $3
32002fb4f839SGregory Neil Shapirodnl remove sni result
32012fb4f839SGregory Neil ShapiroR$* $| $* $| $* $| $*		$: $1 $| $2 $| $3
32022fb4f839SGregory Neil Shapiro', `dnl')
32032fb4f839SGregory Neil Shapirodnl host $| ip $| <acc result - might be empty>
32042fb4f839SGregory Neil ShapiroR$* $| $* $| <"">	$@ ""
32052fb4f839SGregory Neil ShapiroR$* $| $* $| <$+>	$@ $3
3206da7d7b9cSGregory Neil ShapiroR$*			$@ ""')
3207da7d7b9cSGregory Neil Shapiro
320840266059SGregory Neil Shapiro######################################################################
320940266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
321040266059SGregory Neil Shapiro###
321140266059SGregory Neil Shapiro###	Parameters:
321240266059SGregory Neil Shapiro###		none
321340266059SGregory Neil Shapiro######################################################################
321440266059SGregory Neil ShapiroSRelayTLS
321506f25ae9SGregory Neil Shapiro# authenticated?
321606f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
321706f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
321813bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
321906f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
322006f25ae9SGregory Neil Shapirodnl but anyway).
322106f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
322206f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
322306f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
322406f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
322506f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
322606f25ae9SGregory Neil Shapirodnl cert subject.
322706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
322840266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
32295b0945b5SGregory Neil ShapiroR<?> $={TlsVerified}	$: OK		authenticated: continue
323040266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
323106f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
323240266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
323340266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
323440266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
323506f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
323640266059SGregory Neil ShapiroRRELAY			$# RELAY
323706f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
323840266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
323940266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
324040266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
324140266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
324240266059SGregory Neil ShapiroR$*			$: NO', `dnl')
324340266059SGregory Neil Shapiro
324440266059SGregory Neil Shapiro######################################################################
324540266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
324640266059SGregory Neil Shapiro###
324740266059SGregory Neil Shapiro###	Parameters:
324840266059SGregory Neil Shapiro###		$1: {server_name}
324940266059SGregory Neil Shapiro###		$2: {server_addr}
325040266059SGregory Neil Shapirodnl	both are currently ignored
325140266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
325240266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
325340266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
325440266059SGregory Neil Shapiro######################################################################
325540266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
325640266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
325740266059SGregory Neil Shapirodnl (which may be considered a good thing).
325840266059SGregory Neil ShapiroSauthinfo
325940266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
326040266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
326140266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
326240266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
326340266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
326440266059SGregory Neil ShapiroR<$*>		$# $1
326540266059SGregory Neil Shapirodnl', `dnl
326640266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
326740266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
326840266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
326940266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
327040266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
327140266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
327240266059SGregory Neil Shapirodnl', `dnl')')
327306f25ae9SGregory Neil Shapiro
3274e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
3275e92d3f3fSGregory Neil Shapiro######################################################################
3276e92d3f3fSGregory Neil Shapiro###  RateControl:
3277e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3278e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3279e92d3f3fSGregory Neil Shapiro######################################################################
3280e92d3f3fSGregory Neil ShapiroSRateControl
3281e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3282e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3283e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3284e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
3285e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3286e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3287e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
32885b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`RC')', `dnl')
3289e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3290e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3291ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
3292e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
3293ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
3294e92d3f3fSGregory Neil Shapiro')')
3295e92d3f3fSGregory Neil Shapiro
3296e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
3297e92d3f3fSGregory Neil Shapiro######################################################################
3298e92d3f3fSGregory Neil Shapiro###  ConnControl:
3299e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3300e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3301e92d3f3fSGregory Neil Shapiro######################################################################
3302e92d3f3fSGregory Neil ShapiroSConnControl
3303e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3304e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3305e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3306e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
3307e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3308e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3309e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
33105b0945b5SGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: _TMPFMSG_(`CC')', `dnl')
3311e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3312e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3313ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
3314e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
3315ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
3316e92d3f3fSGregory Neil Shapiro')')
3317e92d3f3fSGregory Neil Shapiro
331806f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
331906f25ae9SGregory Neil Shapiro#
332006f25ae9SGregory Neil Shapiro######################################################################
332106f25ae9SGregory Neil Shapiro######################################################################
332206f25ae9SGregory Neil Shapiro#####
332306f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
332406f25ae9SGregory Neil Shapiro#####
332506f25ae9SGregory Neil Shapiro######################################################################
332606f25ae9SGregory Neil Shapiro######################################################################
332740266059SGregory Neil Shapiro_MAIL_FILTERS_
3328c2aa98e2SPeter Wemm#
3329c2aa98e2SPeter Wemm######################################################################
3330c2aa98e2SPeter Wemm######################################################################
3331c2aa98e2SPeter Wemm#####
3332c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
3333c2aa98e2SPeter Wemm#####
3334c2aa98e2SPeter Wemm######################################################################
3335c2aa98e2SPeter Wemm######################################################################
333606f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
333742e5d165SGregory Neil Shapiro
33382fb4f839SGregory Neil Shapiro
33392fb4f839SGregory Neil Shapirodnl Helper ruleset for -bt mode to invoke rulesets
33402fb4f839SGregory Neil Shapirodnl which take two arguments separated by $|
33412fb4f839SGregory Neil Shapirodnl For example:
33422fb4f839SGregory Neil Shapirodnl Start,check_relay host.name $| I.P.V.4
33432fb4f839SGregory Neil Shapirodnl SStart
33442fb4f839SGregory Neil Shapirodnl R$* $$| $*		$: $1 $| $2
3345