xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision da7d7b9c)
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
16406f25ae9SGregory Neil Shapiroifdef(`_BLACKLIST_RCPT_',`dnl
16506f25ae9SGregory Neil Shapiro# possible access_db RHS for spam friends/haters
16606f25ae9SGregory Neil ShapiroC{SpamTag}SPAMFRIEND SPAMHATER')')',
167c2aa98e2SPeter Wemm`dnl')
168c2aa98e2SPeter Wemm
16940266059SGregory Neil Shapirodnl mark for "domain is ok" (resolved or accepted anyway)
17040266059SGregory Neil Shapirodefine(`_RES_OK_', `OKR')dnl
171c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',`dnl',`dnl
172c2aa98e2SPeter Wemm# Resolve map (to check if a host exists in check_mail)
17340266059SGregory Neil ShapiroKresolve host -a<_RES_OK_> -T<TEMP>')
17440266059SGregory Neil ShapiroC{ResOk}_RES_OK_
175c2aa98e2SPeter Wemm
17613058a91SGregory Neil Shapiroifdef(`_NEED_MACRO_MAP_', `dnl
17713058a91SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
17813058a91SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
17913058a91SGregory Neil ShapiroKmacro macro')', `dnl')
18042e5d165SGregory Neil Shapiro
181c2aa98e2SPeter Wemmifdef(`confCR_FILE', `dnl
18242e5d165SGregory Neil Shapiro# Hosts for which relaying is permitted ($=R)
183c2aa98e2SPeter WemmFR`'confCR_FILE',
184c2aa98e2SPeter Wemm`dnl')
185c2aa98e2SPeter Wemm
18640266059SGregory Neil Shapirodefine(`TLS_SRV_TAG', `"TLS_Srv"')dnl
18740266059SGregory Neil Shapirodefine(`TLS_CLT_TAG', `"TLS_Clt"')dnl
18840266059SGregory Neil Shapirodefine(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl
18940266059SGregory Neil Shapirodefine(`TLS_TRY_TAG', `"Try_TLS"')dnl
19040266059SGregory Neil Shapirodefine(`SRV_FEAT_TAG', `"Srv_Features"')dnl
19106f25ae9SGregory Neil Shapirodnl this may be useful in other contexts too
19206f25ae9SGregory Neil Shapiroifdef(`_ARITH_MAP_', `', `# arithmetic map
19306f25ae9SGregory Neil Shapirodefine(`_ARITH_MAP_', `1')dnl
19406f25ae9SGregory Neil ShapiroKarith arith')
19506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
19640266059SGregory Neil Shapiroifdef(`_MACRO_MAP_', `', `# macro storage map
19740266059SGregory Neil Shapirodefine(`_MACRO_MAP_', `1')dnl
19840266059SGregory Neil ShapiroKmacro macro')
19940266059SGregory Neil Shapiro# possible values for TLS_connection in access map
200e92d3f3fSGregory Neil ShapiroC{Tls}VERIFY ENCR', `dnl')
20106f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
20206f25ae9SGregory Neil Shapiro# extract relevant part from cert issuer
20306f25ae9SGregory Neil ShapiroKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
20406f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
20506f25ae9SGregory Neil Shapiro# extract relevant part from cert subject
20606f25ae9SGregory Neil ShapiroKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
20706f25ae9SGregory Neil Shapiro
20840266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
209fabecb74SGregory Neil Shapiro# who I send unqualified names to if `FEATURE(stickyhost)' is used
21013bd1963SGregory Neil Shapiro# (null means deliver locally)
21140266059SGregory Neil ShapiroDR`'LOCAL_RELAY')
212c2aa98e2SPeter Wemm
21340266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
21413bd1963SGregory Neil Shapiro# who gets all local email traffic
215fabecb74SGregory Neil Shapiro# ($R has precedence for unqualified names if `FEATURE(stickyhost)' is used)
21640266059SGregory Neil ShapiroDH`'MAIL_HUB')
217c2aa98e2SPeter Wemm
218c2aa98e2SPeter Wemm# dequoting map
21940266059SGregory Neil ShapiroKdequote dequote`'ifdef(`confDEQUOTE_OPTS', ` confDEQUOTE_OPTS', `')
220c2aa98e2SPeter Wemm
221c2aa98e2SPeter Wemmdivert(0)dnl	# end of nullclient diversion
222c2aa98e2SPeter Wemm# class E: names that should be exposed as from this host, even if we masquerade
22306f25ae9SGregory Neil Shapiro# class L: names that should be delivered locally, even if we have a relay
224c2aa98e2SPeter Wemm# class M: domains that should be converted to $M
22506f25ae9SGregory Neil Shapiro# class N: domains that should not be converted to $M
226c2aa98e2SPeter Wemm#CL root
227c2aa98e2SPeter Wemmundivert(5)dnl
22806f25ae9SGregory Neil Shapiroifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
229c2aa98e2SPeter Wemm
23040266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
231c2aa98e2SPeter Wemm# who I masquerade as (null for no masquerading) (see also $=M)
23240266059SGregory Neil ShapiroDM`'MASQUERADE_NAME')
233c2aa98e2SPeter Wemm
234c2aa98e2SPeter Wemm# my name for error messages
235c2aa98e2SPeter Wemmifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
236c2aa98e2SPeter Wemm
23706f25ae9SGregory Neil Shapiroundivert(6)dnl LOCAL_CONFIG
238c2aa98e2SPeter Wemminclude(_CF_DIR_`m4/version.m4')
239c2aa98e2SPeter Wemm
240c2aa98e2SPeter Wemm###############
241c2aa98e2SPeter Wemm#   Options   #
242c2aa98e2SPeter Wemm###############
24340266059SGregory Neil Shapiroifdef(`confAUTO_REBUILD',
24440266059SGregory Neil Shapiro`errprint(WARNING: `confAUTO_REBUILD' is no longer valid.
24540266059SGregory Neil Shapiro	There was a potential for a denial of service attack if this is set.
24640266059SGregory Neil Shapiro)')dnl
247c2aa98e2SPeter Wemm
248c2aa98e2SPeter Wemm# strip message body to 7 bits on input?
24906f25ae9SGregory Neil Shapiro_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
250c2aa98e2SPeter Wemm
251c2aa98e2SPeter Wemm# 8-bit data handling
2528774250cSGregory Neil Shapiro_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
253c2aa98e2SPeter Wemm
254c2aa98e2SPeter Wemm# wait for alias file rebuild (default units: minutes)
25506f25ae9SGregory Neil Shapiro_OPTION(AliasWait, `confALIAS_WAIT', `5m')
256c2aa98e2SPeter Wemm
257c2aa98e2SPeter Wemm# location of alias file
25806f25ae9SGregory Neil Shapiro_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
25906f25ae9SGregory Neil Shapiro
260c2aa98e2SPeter Wemm# minimum number of free blocks on filesystem
26106f25ae9SGregory Neil Shapiro_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
262c2aa98e2SPeter Wemm
263c2aa98e2SPeter Wemm# maximum message size
264e92d3f3fSGregory Neil Shapiro_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0')
265c2aa98e2SPeter Wemm
266c2aa98e2SPeter Wemm# substitution for space (blank) characters
26706f25ae9SGregory Neil Shapiro_OPTION(BlankSub, `confBLANK_SUB', `_')
268c2aa98e2SPeter Wemm
269c2aa98e2SPeter Wemm# avoid connecting to "expensive" mailers on initial submission?
27006f25ae9SGregory Neil Shapiro_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
271c2aa98e2SPeter Wemm
272c2aa98e2SPeter Wemm# checkpoint queue runs after every N successful deliveries
27306f25ae9SGregory Neil Shapiro_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
274c2aa98e2SPeter Wemm
275c2aa98e2SPeter Wemm# default delivery mode
27606f25ae9SGregory Neil Shapiro_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
277c2aa98e2SPeter Wemm
278c2aa98e2SPeter Wemm# error message header/file
27906f25ae9SGregory Neil Shapiro_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
280c2aa98e2SPeter Wemm
281c2aa98e2SPeter Wemm# error mode
28206f25ae9SGregory Neil Shapiro_OPTION(ErrorMode, `confERROR_MODE', `print')
283c2aa98e2SPeter Wemm
284c2aa98e2SPeter Wemm# save Unix-style "From_" lines at top of header?
28506f25ae9SGregory Neil Shapiro_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
286c2aa98e2SPeter Wemm
28740266059SGregory Neil Shapiro# queue file mode (qf files)
28840266059SGregory Neil Shapiro_OPTION(QueueFileMode, `confQUEUE_FILE_MODE', `0600')
28940266059SGregory Neil Shapiro
290c2aa98e2SPeter Wemm# temporary file mode
29106f25ae9SGregory Neil Shapiro_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
292c2aa98e2SPeter Wemm
293c2aa98e2SPeter Wemm# match recipients against GECOS field?
29406f25ae9SGregory Neil Shapiro_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
295c2aa98e2SPeter Wemm
296c2aa98e2SPeter Wemm# maximum hop count
29740266059SGregory Neil Shapiro_OPTION(MaxHopCount, `confMAX_HOP', `25')
298c2aa98e2SPeter Wemm
299c2aa98e2SPeter Wemm# location of help file
30006f25ae9SGregory Neil ShapiroO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
301c2aa98e2SPeter Wemm
302c2aa98e2SPeter Wemm# ignore dots as terminators in incoming messages?
30306f25ae9SGregory Neil Shapiro_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
304c2aa98e2SPeter Wemm
305c2aa98e2SPeter Wemm# name resolver options
30606f25ae9SGregory Neil Shapiro_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
307c2aa98e2SPeter Wemm
308c2aa98e2SPeter Wemm# deliver MIME-encapsulated error messages?
30906f25ae9SGregory Neil Shapiro_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
310c2aa98e2SPeter Wemm
311c2aa98e2SPeter Wemm# Forward file search path
31206f25ae9SGregory Neil Shapiro_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
313c2aa98e2SPeter Wemm
314c2aa98e2SPeter Wemm# open connection cache size
31506f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
316c2aa98e2SPeter Wemm
317c2aa98e2SPeter Wemm# open connection cache timeout
31806f25ae9SGregory Neil Shapiro_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
319c2aa98e2SPeter Wemm
320c2aa98e2SPeter Wemm# persistent host status directory
32106f25ae9SGregory Neil Shapiro_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
322c2aa98e2SPeter Wemm
323c2aa98e2SPeter Wemm# single thread deliveries (requires HostStatusDirectory)?
32406f25ae9SGregory Neil Shapiro_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
325c2aa98e2SPeter Wemm
326c2aa98e2SPeter Wemm# use Errors-To: header?
32706f25ae9SGregory Neil Shapiro_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
328c2aa98e2SPeter Wemm
329da7d7b9cSGregory Neil Shapiro# use compressed IPv6 address format?
330da7d7b9cSGregory Neil Shapiro_OPTION(UseCompressedIPv6Addresses, `confUSE_COMPRESSED_IPV6_ADDRESSES', `')
331da7d7b9cSGregory Neil Shapiro
332c2aa98e2SPeter Wemm# log level
33306f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
334c2aa98e2SPeter Wemm
335c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
33606f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
337c2aa98e2SPeter Wemm
338c2aa98e2SPeter Wemm# verify RHS in newaliases?
33906f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
340c2aa98e2SPeter Wemm
341c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
34206f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
343c2aa98e2SPeter Wemm
344c2aa98e2SPeter Wemm# SMTP daemon options
34506f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
346605302a5SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
347605302a5SGregory Neil Shapiro	Use `DAEMON_OPTIONS()'; see cf/README.
34806f25ae9SGregory Neil Shapiro)'dnl
34906f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
35042e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
35140266059SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
35240266059SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
35306f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
35406f25ae9SGregory Neil Shapiro
35506f25ae9SGregory Neil Shapiro# SMTP client options
35640266059SGregory Neil Shapiroifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
35740266059SGregory Neil Shapiro`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
35840266059SGregory Neil Shapiro)'dnl
35940266059SGregory Neil Shapiro`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
36040266059SGregory Neil Shapiroifelse(defn(`_CPO_'), `',
36140266059SGregory Neil Shapiro`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
36240266059SGregory Neil Shapiro
36340266059SGregory Neil Shapiro# Modifiers to `define' {daemon_flags} for direct submissions
36440266059SGregory Neil Shapiro_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
36540266059SGregory Neil Shapiro
36640266059SGregory Neil Shapiro# Use as mail submission program? See sendmail/SECURITY
36740266059SGregory Neil Shapiro_OPTION(UseMSP, `confUSE_MSP', `')
368c2aa98e2SPeter Wemm
369c2aa98e2SPeter Wemm# privacy flags
37006f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
371c2aa98e2SPeter Wemm
372c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
37306f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
374c2aa98e2SPeter Wemm
375c2aa98e2SPeter Wemm# slope of queue-only function
37606f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
377c2aa98e2SPeter Wemm
37840266059SGregory Neil Shapiro# limit on number of concurrent queue runners
37940266059SGregory Neil Shapiro_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
38040266059SGregory Neil Shapiro
38140266059SGregory Neil Shapiro# maximum number of queue-runners per queue-grouping with multiple queues
38240266059SGregory Neil Shapiro_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
38340266059SGregory Neil Shapiro
38440266059SGregory Neil Shapiro# priority of queue runners (nice(3))
38540266059SGregory Neil Shapiro_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
38640266059SGregory Neil Shapiro
38740266059SGregory Neil Shapiro# shall we sort the queue by hostname first?
38840266059SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
38940266059SGregory Neil Shapiro
39040266059SGregory Neil Shapiro# minimum time in queue before retry
39140266059SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
39240266059SGregory Neil Shapiro
393da7d7b9cSGregory Neil Shapiro# maximum time in queue before retry (if > 0; only for exponential delay)
394da7d7b9cSGregory Neil Shapiro_OPTION(MaxQueueAge, `confMAX_QUEUE_AGE', `')
395da7d7b9cSGregory Neil Shapiro
39640266059SGregory Neil Shapiro# how many jobs can you process in the queue?
3974e4196cbSGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
39840266059SGregory Neil Shapiro
39940266059SGregory Neil Shapiro# perform initial split of envelope without checking MX records
40040266059SGregory Neil Shapiro_OPTION(FastSplit, `confFAST_SPLIT', `1')
40140266059SGregory Neil Shapiro
402c2aa98e2SPeter Wemm# queue directory
40306f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
404c2aa98e2SPeter Wemm
405d0cef73dSGregory Neil Shapiro# key for shared memory; 0 to turn off, -1 to auto-select
40640266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
40740266059SGregory Neil Shapiro
408d0cef73dSGregory Neil Shapiro# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
409d0cef73dSGregory Neil Shapiro_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
410605302a5SGregory Neil Shapiro
411c2aa98e2SPeter Wemm# timeouts (many of these)
41206f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
41306f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
41440266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
41506f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
41606f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
41706f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
41806f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
41906f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
42006f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
42106f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
42206f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
42306f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
42406f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
42506f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
42606f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
42706f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
42806f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
42906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
43206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
433e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
43506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
438e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
44006f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
44106f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
44206f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
44306f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
44406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
44506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
44640266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
44740266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
44840266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
44940266059SGregory Neil Shapiro
45040266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
45140266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
452c2aa98e2SPeter Wemm
453c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
45406f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
455c2aa98e2SPeter Wemm
456c2aa98e2SPeter Wemm# queue up everything before forking?
45706f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
458c2aa98e2SPeter Wemm
459c2aa98e2SPeter Wemm# status file
460d0cef73dSGregory Neil Shapiro_OPTION(StatusFile, `STATUS_FILE')
461c2aa98e2SPeter Wemm
462c2aa98e2SPeter Wemm# time zone handling:
463c2aa98e2SPeter Wemm#  if undefined, use system default
464c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
465c2aa98e2SPeter Wemm#  if defined and non-null, use that info
466c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
467c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
468c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
469c2aa98e2SPeter Wemm
470c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
47106f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
472c2aa98e2SPeter Wemm
473c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
47406f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
475c2aa98e2SPeter Wemm
476c2aa98e2SPeter Wemm# fallback MX host
47706f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
478c2aa98e2SPeter Wemm
479e92d3f3fSGregory Neil Shapiro# fallback smart host
480e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
481e92d3f3fSGregory Neil Shapiro
482c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
48306f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
484c2aa98e2SPeter Wemm
485c2aa98e2SPeter Wemm# load average at which we just queue messages
48606f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
487c2aa98e2SPeter Wemm
488c2aa98e2SPeter Wemm# load average at which we refuse connections
48906f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
490c2aa98e2SPeter Wemm
491e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
492e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
493e92d3f3fSGregory Neil Shapiro
49440266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
49540266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
49640266059SGregory Neil Shapiro
497c2aa98e2SPeter Wemm# maximum number of children we allow at one time
498739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
499c2aa98e2SPeter Wemm
500c2aa98e2SPeter Wemm# maximum number of new connections per second
501193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
502c2aa98e2SPeter Wemm
503e92d3f3fSGregory Neil Shapiro# Width of the window
504e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
505e92d3f3fSGregory Neil Shapiro
506c2aa98e2SPeter Wemm# work recipient factor
50706f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
508c2aa98e2SPeter Wemm
509c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
51006f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
511c2aa98e2SPeter Wemm
512c2aa98e2SPeter Wemm# work class factor
51306f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
514c2aa98e2SPeter Wemm
515c2aa98e2SPeter Wemm# work time factor
51606f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
517c2aa98e2SPeter Wemm
518c2aa98e2SPeter Wemm# default character set
519b6bacd31SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
520c2aa98e2SPeter Wemm
52140266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
52206f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
523c2aa98e2SPeter Wemm
524c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
52506f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
526c2aa98e2SPeter Wemm
527c2aa98e2SPeter Wemm# dialup line delay on connection failure
5284e4196cbSGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `0s')
529c2aa98e2SPeter Wemm
530c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
5314e4196cbSGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
532c2aa98e2SPeter Wemm
533c2aa98e2SPeter Wemm# chrooted environment for writing to files
5344e4196cbSGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
535c2aa98e2SPeter Wemm
536c2aa98e2SPeter Wemm# are colons OK in addresses?
53706f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
538c2aa98e2SPeter Wemm
539c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
54006f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
541c2aa98e2SPeter Wemm
542c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
54306f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
544c2aa98e2SPeter Wemm
545c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
54606f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
547c2aa98e2SPeter Wemm
548c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
54906f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
550c2aa98e2SPeter Wemm
551c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
55206f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
553c2aa98e2SPeter Wemm
554c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
55506f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
556c2aa98e2SPeter Wemm
557c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
55806f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
559c2aa98e2SPeter Wemm
560c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
56106f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
562c2aa98e2SPeter Wemm
563c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
56440266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
56506f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
56640266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
56740266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
56840266059SGregory Neil Shapiro')')
569c2aa98e2SPeter Wemm
570c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
57106f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
57206f25ae9SGregory Neil Shapiro
573d0cef73dSGregory Neil Shapiro# issue temporary errors (4xy) instead of permanent errors (5xy)?
574d0cef73dSGregory Neil Shapiro_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
575d0cef73dSGregory Neil Shapiro
57606f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
57706f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
578c2aa98e2SPeter Wemm
579c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
58006f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
581c2aa98e2SPeter Wemm
582c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
583e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
584c2aa98e2SPeter Wemm
58540266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
58640266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
587e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
58840266059SGregory Neil Shapiro
5899bd497b8SGregory Neil Shapiro
590c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
59106f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
592c2aa98e2SPeter Wemm
59306f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
59406f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
59506f25ae9SGregory Neil Shapiro
59606f25ae9SGregory Neil Shapiro# override connection address (for testing)
59706f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
59806f25ae9SGregory Neil Shapiro
59906f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
60006f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
60106f25ae9SGregory Neil Shapiro
60206f25ae9SGregory Neil Shapiro# Control socket for daemon management
60306f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
60406f25ae9SGregory Neil Shapiro
60506f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
606e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
60706f25ae9SGregory Neil Shapiro
60806f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
60906f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
61006f25ae9SGregory Neil Shapiro
61106f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
61206f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
61306f25ae9SGregory Neil Shapiro
61406f25ae9SGregory Neil Shapiro# location of pid file
61506f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
61606f25ae9SGregory Neil Shapiro
61706f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
61806f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
61906f25ae9SGregory Neil Shapiro
62006f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
62106f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
62206f25ae9SGregory Neil Shapiro
62306f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
62406f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
62506f25ae9SGregory Neil Shapiro
62640266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
62740266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
62840266059SGregory Neil Shapiro
629e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
630e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
631e92d3f3fSGregory Neil Shapiro
63206f25ae9SGregory Neil Shapiro# list of authentication mechanisms
63340266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
63406f25ae9SGregory Neil Shapiro
635e92d3f3fSGregory Neil Shapiro# Authentication realm
636e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
637e92d3f3fSGregory Neil Shapiro
63806f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
63906f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
64006f25ae9SGregory Neil Shapiro
64106f25ae9SGregory Neil Shapiro# SMTP AUTH flags
64206f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
64306f25ae9SGregory Neil Shapiro
64440266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
64540266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
64640266059SGregory Neil Shapiro
64740266059SGregory Neil Shapiro# SMTP STARTTLS server options
64840266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
64940266059SGregory Neil Shapiro
650da7d7b9cSGregory Neil Shapiro# SSL cipherlist
651da7d7b9cSGregory Neil Shapiro_OPTION(CipherList, `confCIPHER_LIST', `')
652da7d7b9cSGregory Neil Shapiro# server side SSL options
653da7d7b9cSGregory Neil Shapiro_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `')
654da7d7b9cSGregory Neil Shapiro# client side SSL options
655da7d7b9cSGregory Neil Shapiro_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `')
6569bd497b8SGregory Neil Shapiro
65706f25ae9SGregory Neil Shapiro# Input mail filters
65806f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
65906f25ae9SGregory Neil Shapiro
660739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
66106f25ae9SGregory Neil Shapiro# Milter options
66240266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
66306f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
66406f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
66506f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
666323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
667d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
668d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
669d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
67006f25ae9SGregory Neil Shapiro
67106f25ae9SGregory Neil Shapiro# CA directory
67213bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
67306f25ae9SGregory Neil Shapiro# CA file
67413bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
67506f25ae9SGregory Neil Shapiro# Server Cert
67606f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
67706f25ae9SGregory Neil Shapiro# Server private key
67806f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
67906f25ae9SGregory Neil Shapiro# Client Cert
68006f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
68106f25ae9SGregory Neil Shapiro# Client private key
68206f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
683e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
684e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
68506f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
68606f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
68706f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
68806f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
689da7d7b9cSGregory Neil Shapiro# fingerprint algorithm (digest) to use for the presented cert
690da7d7b9cSGregory Neil Shapiro_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `')
69106f25ae9SGregory Neil Shapiro
692d0cef73dSGregory Neil Shapiro# Maximum number of "useless" commands before slowing down
693d0cef73dSGregory Neil Shapiro_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
694d0cef73dSGregory Neil Shapiro
695d0cef73dSGregory Neil Shapiro# Name to use for EHLO (defaults to $j)
696d0cef73dSGregory Neil Shapiro_OPTION(HeloName, `confHELO_NAME')
697d0cef73dSGregory Neil Shapiro
698da7d7b9cSGregory Neil Shapiroifdef(`_NEED_SMTPOPMODES_', `dnl
699da7d7b9cSGregory Neil Shapiro# SMTP operation modes
700da7d7b9cSGregory Neil ShapiroC{SMTPOpModes} s d D')
701da7d7b9cSGregory Neil Shapiro
70240266059SGregory Neil Shapiro############################
70340266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
70440266059SGregory Neil Shapiro############################
70540266059SGregory Neil Shapiro_QUEUE_GROUP_
706065a643dSPeter Wemm
707c2aa98e2SPeter Wemm###########################
708c2aa98e2SPeter Wemm#   Message precedences   #
709c2aa98e2SPeter Wemm###########################
710c2aa98e2SPeter Wemm
711c2aa98e2SPeter WemmPfirst-class=0
712c2aa98e2SPeter WemmPspecial-delivery=100
713c2aa98e2SPeter WemmPlist=-30
714c2aa98e2SPeter WemmPbulk=-60
715c2aa98e2SPeter WemmPjunk=-100
716c2aa98e2SPeter Wemm
717c2aa98e2SPeter Wemm#####################
718c2aa98e2SPeter Wemm#   Trusted users   #
719c2aa98e2SPeter Wemm#####################
720c2aa98e2SPeter Wemm
721c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
72206f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
723c2aa98e2SPeter WemmTroot
724c2aa98e2SPeter WemmTdaemon
725c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
726c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
727c2aa98e2SPeter Wemm
728c2aa98e2SPeter Wemm#########################
729c2aa98e2SPeter Wemm#   Format of headers   #
730c2aa98e2SPeter Wemm#########################
731c2aa98e2SPeter Wemm
732c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
733e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
734c2aa98e2SPeter WemmH?P?Return-Path: <$g>
735c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
736c2aa98e2SPeter WemmH?D?Resent-Date: $a
737c2aa98e2SPeter WemmH?D?Date: $a
738c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
739c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
740c2aa98e2SPeter WemmH?x?Full-Name: $x
741c2aa98e2SPeter Wemm# HPosted-Date: $a
742c2aa98e2SPeter Wemm# H?l?Received-Date: $b
743e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
744e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
74506f25ae9SGregory Neil Shapiro
746c2aa98e2SPeter Wemm#
747c2aa98e2SPeter Wemm######################################################################
748c2aa98e2SPeter Wemm######################################################################
749c2aa98e2SPeter Wemm#####
750c2aa98e2SPeter Wemm#####			REWRITING RULES
751c2aa98e2SPeter Wemm#####
752c2aa98e2SPeter Wemm######################################################################
753c2aa98e2SPeter Wemm######################################################################
754c2aa98e2SPeter Wemm
755c2aa98e2SPeter Wemm############################################
756c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
757c2aa98e2SPeter Wemm############################################
75806f25ae9SGregory Neil ShapiroScanonify=3
759c2aa98e2SPeter Wemm
760c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
761c2aa98e2SPeter WemmR$@			$@ <@>
762c2aa98e2SPeter Wemm
763c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
764c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
765c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
766c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
76740266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
768c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
769c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
770c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
771c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
772c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
773c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
774193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
775c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
776c2aa98e2SPeter Wemm
777c2aa98e2SPeter Wemm# null input now results from list:; syntax
778c2aa98e2SPeter WemmR$@			$@ :; <@>
779c2aa98e2SPeter Wemm
780c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
781c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
782c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
783c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
784c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
785c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
786c2aa98e2SPeter Wemm
78706f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
788c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
789c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
790c2aa98e2SPeter Wemm
791c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
79240266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
79340266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
79440266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
79506f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
79606f25ae9SGregory Neil Shapirodnl',`dnl
79706f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
79806f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
79940266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
80040266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
80106f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
80206f25ae9SGregory Neil Shapirodnl')
803c2aa98e2SPeter Wemm
804c2aa98e2SPeter Wemm# find focus for list syntax
80506f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
806c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
807c2aa98e2SPeter Wemm
808c2aa98e2SPeter Wemm# find focus for @ syntax addresses
809c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
810c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
81106f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
812c2aa98e2SPeter Wemm
81340266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
81440266059SGregory Neil Shapirodnl # do some sanity checking
81540266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
816c2aa98e2SPeter Wemm
817c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
818c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
81906f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
82006f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
82106f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
822c2aa98e2SPeter Wemm')
823c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
824c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
82506f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
82606f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
827c2aa98e2SPeter Wemm',
828c2aa98e2SPeter Wemm	`dnl')
829da7d7b9cSGregory Neil Shapiroifdef(`_NO_PERCENTHACK_', `dnl',
830da7d7b9cSGregory Neil Shapiro`# if we have % signs, take the rightmost one
831c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
832c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
833da7d7b9cSGregory Neil Shapiro')
83406f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
835c2aa98e2SPeter Wemm
836c2aa98e2SPeter Wemm# else we must be a local name
83706f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
838c2aa98e2SPeter Wemm
839c2aa98e2SPeter Wemm
840c2aa98e2SPeter Wemm################################################
841c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
842c2aa98e2SPeter Wemm################################################
843c2aa98e2SPeter Wemm
84406f25ae9SGregory Neil ShapiroSCanonify2=96
845c2aa98e2SPeter Wemm
846c2aa98e2SPeter Wemm# handle special cases for local names
847c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
848c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
849c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
850c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
85106f25ae9SGregory Neil Shapiro
85240266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
85340266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
854c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
855c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
856c2aa98e2SPeter Wemm
85706f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
858c2aa98e2SPeter Wemm# look up domains in the domain table
859c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
860c2aa98e2SPeter Wemm
86106f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
862c2aa98e2SPeter Wemm
86306f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
864c2aa98e2SPeter Wemm# handle BITNET mapping
865c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
866c2aa98e2SPeter Wemm
86706f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
868c2aa98e2SPeter Wemm# handle UUCP mapping
869c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
870c2aa98e2SPeter Wemm
871c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
872c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
873c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
874c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
875c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
876c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
877c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
878c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
879c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
880c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
881c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
882c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
883c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
884c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
885c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
886c2aa98e2SPeter Wemm
887c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
888c2aa98e2SPeter Wemm# try UUCP traffic as a local address
889c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
890c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
891c2aa98e2SPeter Wemm')')
89206f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
89306f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
89406f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
89506f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
89606f25ae9SGregory Neil Shapirodnl which daemon flags are set?
89706f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
89806f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
89906f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
90006f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
90106f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
90206f25ae9SGregory Neil Shapirodnl do not canonify unless:
90306f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
90406f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
90506f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
90606f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
90706f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
90806f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
90906f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
91006f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
91106f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
91206f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
91306f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
91406f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
91506f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
91606f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
91706f25ae9SGregory Neil Shapirodnl then $- does not work.
91806f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
91906f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
92006f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
92106f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
922193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
923193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
924193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
92506f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
92640266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
92740266059SGregory Neil Shapiro# do not canonify header addresses
92840266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
92940266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
93040266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
931c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
93206f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
93306f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
93406f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
935c2aa98e2SPeter Wemm
936c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
937c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
938c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
939c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
940c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
94106f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
94206f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
94306f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
94406f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
94506f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
94606f25ae9SGregory Neil Shapiro`dnl')
94740266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
94840266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
94940266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
95040266059SGregory Neil Shapiro`R$* < @ $* $=G > $* 	$: $1 < @ $2 $3 . > $4',
95140266059SGregory Neil Shapiro`R$* < @ $=G > $* 	$: $1 < @ $2 . > $3')',
95240266059SGregory Neil Shapiro`dnl')
95306f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
95406f25ae9SGregory Neil Shapirodnl by one of the rules before
955c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
956c2aa98e2SPeter Wemm
957c2aa98e2SPeter Wemm
958c2aa98e2SPeter Wemm##################################################
959c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
960c2aa98e2SPeter Wemm##################################################
96106f25ae9SGregory Neil ShapiroSfinal=4
962c2aa98e2SPeter Wemm
963193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
964c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
965c2aa98e2SPeter Wemm
966c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
967c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
968c2aa98e2SPeter Wemm
96906f25ae9SGregory Neil Shapiro# eliminate internal code
970c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
971c2aa98e2SPeter Wemm
972c2aa98e2SPeter Wemm# externalize local domain info
973c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
974c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
975c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
976c2aa98e2SPeter Wemm
977c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
978c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
979c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
980c2aa98e2SPeter Wemm
981c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
982c2aa98e2SPeter Wemm`# put DECnet back in :: form
983c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
984c2aa98e2SPeter Wemm	`dnl')
985c2aa98e2SPeter Wemm# delete duplicate local names
986c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
987c2aa98e2SPeter Wemm
988c2aa98e2SPeter Wemm
989c2aa98e2SPeter Wemm
990c2aa98e2SPeter Wemm##############################################################
991c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
992c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
993c2aa98e2SPeter Wemm##############################################################
994c2aa98e2SPeter Wemm
99506f25ae9SGregory Neil ShapiroSRecurse=97
99606f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
99706f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
998c2aa98e2SPeter Wemm
999c2aa98e2SPeter Wemm
1000c2aa98e2SPeter Wemm######################################
1001c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
1002c2aa98e2SPeter Wemm######################################
1003c2aa98e2SPeter Wemm
100406f25ae9SGregory Neil ShapiroSparse=0
1005c2aa98e2SPeter Wemm
1006c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
1007c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
100806f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
1009c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
1010c2aa98e2SPeter Wemm
1011c2aa98e2SPeter Wemm#
1012c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
1013c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
1014c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
1015c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
1016c2aa98e2SPeter Wemm#
1017c2aa98e2SPeter Wemm
1018c2aa98e2SPeter WemmSParse0
1019c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
102040266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
102106f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
102240266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
102340266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
1024c2aa98e2SPeter WemmR$*			$: <> $1
102540266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
102640266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
102740266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
102840266059SGregory Neil Shapirodnl but no a@[b]c
102940266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
1030c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
103140266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1032c2aa98e2SPeter WemmR<> $*			$1
103340266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
103440266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
103540266059SGregory Neil Shapirodnl no a@b@
103640266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
103740266059SGregory Neil Shapirodnl no a@b@c
103840266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
103906f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
104040266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
104140266059SGregory Neil Shapiro
104240266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
104340266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
104440266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
104540266059SGregory Neil Shapirodnl', `dnl')
1046c2aa98e2SPeter Wemm
1047c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
104806f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
104906f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1050c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
105140266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
105206f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1053c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
105440266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1055c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
105606f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1057c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1058c2aa98e2SPeter Wemm
1059da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1060da7d7b9cSGregory Neil ShapiroR$+			$: $>ParseBcc $1', `dnl')
1061da7d7b9cSGregory Neil Shapiroifdef(`_PREFIX_MOD_', `dnl
1062da7d7b9cSGregory Neil Shapirodnl do this only for addr_type=e r?
1063da7d7b9cSGregory Neil ShapiroR _PREFIX_MOD_ $+	$: $1 $(macro {rcpt_flags} $@ _PREFIX_FLAGS_ $)
1064da7d7b9cSGregory Neil Shapiro')dnl
1065da7d7b9cSGregory Neil Shapiro
1066c2aa98e2SPeter Wemm#
1067c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1068c2aa98e2SPeter Wemm#
1069c2aa98e2SPeter Wemm
1070c2aa98e2SPeter WemmSParse1
107106f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
107206f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
107340266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
107440266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1075c2aa98e2SPeter Wemm`dnl')
1076c2aa98e2SPeter Wemm
107706f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
107806f25ae9SGregory Neil Shapiro`# handle numeric address spec
107906f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
108006f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
10815ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
108206f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
108306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
108406f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
108506f25ae9SGregory Neil Shapiro	`dnl')
108606f25ae9SGregory Neil Shapiro
108706f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1088c2aa98e2SPeter Wemm# handle virtual users
108940266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
109040266059SGregory Neil Shapirodnl this is not a documented option
109140266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
109240266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
109340266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
109440266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
109540266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
109640266059SGregory Neil ShapiroR$+ < @ $+ > 			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
109740266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
109840266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
109940266059SGregory Neil Shapiro`dnl')
110006f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
110140266059SGregory Neil Shapirodnl input: <!> local<@domain>
110206f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
110306f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
110406f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
110540266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
110606f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
110740266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
110840266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
110940266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
111040266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
111140266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1112c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
111340266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
111440266059SGregory Neil Shapirodnl user+detail: try user@domain
1115c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
111640266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
111706f25ae9SGregory Neil Shapirodnl try default entry: @domain
111840266059SGregory Neil Shapirodnl ++@domain
111940266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
112006f25ae9SGregory Neil Shapirodnl +*@domain
112140266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
112206f25ae9SGregory Neil Shapirodnl @domain if +detail exists
112394c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
112494c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
112594c01205SGregory Neil Shapirodnl without +detail
1126c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
112740266059SGregory Neil Shapirodnl no match
1128c2aa98e2SPeter WemmR<@> $+			$: $1
112940266059SGregory Neil Shapirodnl remove mark
113006f25ae9SGregory Neil ShapiroR<!> $+			$: $1
113106f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1132c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
113340266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
113440266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
113540266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
113640266059SGregory Neil Shapiro# it is the same: stop now
113740266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
113840266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $* 			$: < $1 > $2 < @ $3 >
113940266059SGregory Neil Shapirodnl', `dnl')
114013058a91SGregory Neil Shapirodnl this is not a documented option
114113058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11428774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11438774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11448774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11458774250cSGregory Neil Shapirodnl', `dnl')
1146c2aa98e2SPeter Wemm
1147c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1148c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
114906f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
115042e5d165SGregory Neil Shapiro
115142e5d165SGregory Neil Shapiro
1152c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1153c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
115406f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
115506f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1156c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1157c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1158c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1159c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1160c2aa98e2SPeter Wemm
116106f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1162c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1163c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1164c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1165c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
116606f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
116706f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
116806f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1169c2aa98e2SPeter Wemm`dnl')
117006f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1171c2aa98e2SPeter Wemm
1172c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1173c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1174c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
117506f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1176c2aa98e2SPeter Wemm	`dnl')
1177c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
117806f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1179c2aa98e2SPeter Wemm	`dnl')
1180c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
118106f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1182c2aa98e2SPeter Wemm	`dnl')')
1183c2aa98e2SPeter Wemm
1184c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1185c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
118606f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1187c2aa98e2SPeter Wemm	`dnl')
1188c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
118906f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1190c2aa98e2SPeter Wemm	`dnl')
1191c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1192c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1193c2aa98e2SPeter Wemm	`dnl')
1194c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1195c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1196c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
119706f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1198c2aa98e2SPeter Wemm	`dnl')')
1199c2aa98e2SPeter Wemm
1200c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1201c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
120206f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1203c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1204c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1205c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1206c2aa98e2SPeter Wemm	`dnl')')
1207c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1208c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
120906f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1210c2aa98e2SPeter Wemm	`dnl')
1211c2aa98e2SPeter Wemm
1212c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1213c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1214c2aa98e2SPeter Wemmundivert(1)', `dnl')
1215c2aa98e2SPeter Wemm
1216c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
121706f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1218c2aa98e2SPeter Wemm
1219c2aa98e2SPeter Wemm# deal with other remote names
1220c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1221c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
122240266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1223c2aa98e2SPeter Wemm
1224c2aa98e2SPeter Wemm# handle locally delivered names
1225c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1226c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1227c2aa98e2SPeter Wemm
1228da7d7b9cSGregory Neil Shapiroifdef(`_ADD_BCC_', `dnl
1229da7d7b9cSGregory Neil ShapiroSParseBcc
1230da7d7b9cSGregory Neil ShapiroR$+			$: $&{addr_type} $| $&A $| $1
1231da7d7b9cSGregory Neil ShapiroRe b $| $+ $| $+	$>MailerToTriple < $1 > $2	copy?
1232da7d7b9cSGregory Neil ShapiroR$* $| $* $| $+		$@ $3				no copy
1233da7d7b9cSGregory Neil Shapiro')
1234da7d7b9cSGregory Neil Shapiro
1235c2aa98e2SPeter Wemm###########################################################################
1236c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1237c2aa98e2SPeter Wemm###########################################################################
1238c2aa98e2SPeter Wemm
123906f25ae9SGregory Neil ShapiroSLocal_localaddr
124006f25ae9SGregory Neil ShapiroSlocaladdr=5
124106f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
124240266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
124306f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
124406f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1245c2aa98e2SPeter Wemm
124640266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
124740266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
124840266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
124940266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
125040266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
125140266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12526a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
125340266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
125440266059SGregory Neil Shapiro')dnl
125540266059SGregory Neil Shapiro
125640266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
125742e5d165SGregory Neil Shapiro# Preserve host in a macro
125842e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
125942e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1260c2aa98e2SPeter Wemm
126140266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
126242e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
126342e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
126442e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
126542e5d165SGregory Neil Shapiro')
1266c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1267c2aa98e2SPeter WemmR$+			$: <> $1
1268c2aa98e2SPeter Wemm
1269c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1270c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
127140266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
127242e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
127342e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
127442e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
127542e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
127606f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
127740266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
127840266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
127940266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
128040266059SGregory Neil Shapirodnl')
1281c2aa98e2SPeter Wemm
128240266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
128340266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
128440266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
128540266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
128640266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
128740266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
128806f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
128940266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
129040266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
129106f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
129206f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1293c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
129442e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1295c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
12962e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
129740266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
129840266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
12992e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
130042e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
130106f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
130206f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
130340266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
130440266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
130540266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
130640266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
130740266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
130840266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
130906f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1310c2aa98e2SPeter Wemm
131106f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
131240266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
131340266059SGregory Neil Shapiro###################################################################
131440266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
131540266059SGregory Neil Shapirodnl input: <Domain> FullAddress
131640266059SGregory Neil Shapiro###################################################################
131740266059SGregory Neil Shapiro
131840266059SGregory Neil ShapiroSLDAPMailertable
131940266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
132040266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
132140266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
132240266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
132340266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
132440266059SGregory Neil Shapiro`dnl')
132540266059SGregory Neil Shapiro
1326c2aa98e2SPeter Wemm###################################################################
1327c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
132806f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1329c2aa98e2SPeter Wemm###################################################################
1330c2aa98e2SPeter Wemm
133106f25ae9SGregory Neil ShapiroSMailertable=90
133206f25ae9SGregory Neil Shapirodnl shift and check
133306f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1334c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
133506f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
133606f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
133706f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
133806f25ae9SGregory Neil Shapirodnl is $2 always empty?
1339c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
134006f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
134106f25ae9SGregory Neil Shapirodnl return full address
1342c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1343c2aa98e2SPeter Wemm`dnl')
1344c2aa98e2SPeter Wemm
1345c2aa98e2SPeter Wemm###################################################################
1346c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
134706f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
134806f25ae9SGregory Neil Shapirodnl	<> address				-> address
134906f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1350a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
135106f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
135206f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
135306f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
135406f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
135506f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1356c2aa98e2SPeter Wemm###################################################################
1357c2aa98e2SPeter Wemm
135806f25ae9SGregory Neil ShapiroSMailerToTriple=95
1359c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
136006f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1361a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1362a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1363c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
136440266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
136540266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
136640266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1367c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1368c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1369c2aa98e2SPeter Wemm
1370c2aa98e2SPeter Wemm###################################################################
1371c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
137206f25ae9SGregory Neil Shapirodnl input: <user> address
137306f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
137406f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
137506f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
137606f25ae9SGregory Neil Shapirodnl <> user				-> local user user
137706f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
137806f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
137906f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1380c2aa98e2SPeter Wemm###################################################################
1381c2aa98e2SPeter Wemm
1382c2aa98e2SPeter WemmSCanonLocal
13832e43090eSPeter Wemm# strip local host from routed addresses
138406f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
138506f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
13862e43090eSPeter Wemm
1387c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1388c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1389c2aa98e2SPeter Wemm
1390c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1391c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1392c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1393c2aa98e2SPeter Wemm
1394c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1395c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1396c2aa98e2SPeter Wemm
1397c2aa98e2SPeter Wemm# handle local:user syntax
1398c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1399c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1400c2aa98e2SPeter Wemm
1401c2aa98e2SPeter Wemm###################################################################
1402c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1403c2aa98e2SPeter Wemm###################################################################
1404c2aa98e2SPeter Wemm
140506f25ae9SGregory Neil ShapiroSMasqHdr=93
1406c2aa98e2SPeter Wemm
140706f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1408c2aa98e2SPeter Wemm# handle generics database
1409c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
141006f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1411c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1412c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1413c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
141406f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
141506f25ae9SGregory Neil Shapirodnl ignore the first case for now
141606f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
141740266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
141806f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
141906f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
142006f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
142106f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
142206f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
142306f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
142406f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
142506f25ae9SGregory Neil Shapirodnl no match, remove mark
142606f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
142706f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
142806f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
142906f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
143006f25ae9SGregory Neil Shapirodnl no match, try local part
1431c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
143206f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
143306f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
143406f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
143506f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1436c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1437c2aa98e2SPeter Wemm`dnl')
1438c2aa98e2SPeter Wemm
143906f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
144006f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
144106f25ae9SGregory Neil Shapiro
144240266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1443c2aa98e2SPeter Wemm# special case the users that should be exposed
1444c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1445c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1446c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1447c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1448c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1449c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1450c2aa98e2SPeter Wemm
1451c2aa98e2SPeter Wemm# handle domain-specific masquerading
1452c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1453c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1454c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1455c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1456c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1457c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1458c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1459c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
146040266059SGregory Neil Shapirodnl', `dnl no masquerading
146140266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
146240266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1463c2aa98e2SPeter Wemm
1464c2aa98e2SPeter Wemm###################################################################
1465c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1466c2aa98e2SPeter Wemm###################################################################
1467c2aa98e2SPeter Wemm
146806f25ae9SGregory Neil ShapiroSMasqEnv=94
1469c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
147006f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1471c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1472c2aa98e2SPeter Wemm
1473c2aa98e2SPeter Wemm###################################################################
1474c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1475c2aa98e2SPeter Wemm###################################################################
1476c2aa98e2SPeter Wemm
147706f25ae9SGregory Neil ShapiroSParseLocal=98
147806f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1479c2aa98e2SPeter Wemm
148006f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
148140266059SGregory Neil Shapiro######################################################################
148240266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
148340266059SGregory Neil Shapiro###
148440266059SGregory Neil Shapiro###	Parameters:
148540266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
148640266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
148740266059SGregory Neil Shapiro###		<$3> -- +detail information
148840266059SGregory Neil Shapiro###
148940266059SGregory Neil Shapiro###	Returns:
149040266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
149140266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
149240266059SGregory Neil Shapiro######################################################################
149340266059SGregory Neil Shapiro
149406f25ae9SGregory Neil ShapiroSLDAPExpand
149506f25ae9SGregory Neil Shapiro# do the LDAP lookups
149640266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
149706f25ae9SGregory Neil Shapiro
1498e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1499e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1500e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1501e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1502e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
1503e92d3f3fSGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."')
1504e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1505e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1506605302a5SGregory Neil Shapiro
150706f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
150806f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
150940266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
151040266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
151140266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
151240266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
151340266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
151406f25ae9SGregory Neil Shapiro
151594c01205SGregory Neil Shapiro
151606f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
151706f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
151840266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
151940266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
152040266059SGregory Neil Shapiro# check mailertable for host, relay from there
152140266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
152240266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
152340266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
152440266059SGregory Neil Shapiro# check mailertable for host, relay from there
152540266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
152640266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
152706f25ae9SGregory Neil Shapiro
152806f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
152906f25ae9SGregory Neil Shapiro# return original address
153040266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
153106f25ae9SGregory Neil Shapiro
153294c01205SGregory Neil Shapiro
153306f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
153406f25ae9SGregory Neil Shapiro# relay to mailHost with original address
153540266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
153640266059SGregory Neil Shapiro# check mailertable for host, relay from there
153740266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
153840266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
153906f25ae9SGregory Neil Shapiro
154040266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
154140266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
154240266059SGregory Neil Shapiro# try without +detail
154340266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
154440266059SGregory Neil Shapiro
15459bd497b8SGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `
15469bd497b8SGregory Neil Shapiro# pretend we did the @domain lookup
15479bd497b8SGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
154840266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
154906f25ae9SGregory Neil Shapiro# try @domain
155040266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
155140266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1552e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
155306f25ae9SGregory Neil Shapiro
155406f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
155506f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
155606f25ae9SGregory Neil Shapiro# user does not exist
155740266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
155840266059SGregory Neil Shapiro# only give error for envelope recipient
155940266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1560e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1561e92d3f3fSGregory Neil Shapiro# and the sender too
1562e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
156340266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
156406f25ae9SGregory Neil Shapiro`dnl
156506f25ae9SGregory Neil Shapiro# return the original address
1566ba00ec3dSGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')
1567ba00ec3dSGregory Neil Shapiro')
1568ba00ec3dSGregory Neil Shapiro
156906f25ae9SGregory Neil Shapiro
157006f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
157106f25ae9SGregory Neil Shapiro')')
157240266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1573c2aa98e2SPeter Wemm######################################################################
157440266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1575c2aa98e2SPeter Wemm###
1576c2aa98e2SPeter Wemm###	Parameters:
1577c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1578c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
157906f25ae9SGregory Neil Shapirodnl			must not be empty
158040266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
158106f25ae9SGregory Neil Shapiro###			! does lookup only with tag
158206f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
158340266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
158406f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
158506f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1586c2aa98e2SPeter Wemm######################################################################
1587c2aa98e2SPeter Wemm
158840266059SGregory Neil ShapiroSD
158906f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
159006f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
159140266059SGregory Neil Shapirodnl    2    3  4    5
159240266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
159306f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
159406f25ae9SGregory Neil Shapirodnl lookup without tag?
159540266059SGregory Neil Shapirodnl   1    2      3    4
159640266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
159740266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
159840266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
159940266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
160040266059SGregory Neil Shapirodnl   1  2    3    4  5    6
160140266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
160240266059SGregory Neil Shapirodnl   1  2    3      4    5
160340266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
160440266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
160540266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
160640266059SGregory Neil Shapirodnl      1    2    3  4    5
160740266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
160840266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
160940266059SGregory Neil Shapirodnl    1  2     3    4  5    6
161040266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
161140266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
161240266059SGregory Neil Shapiro`dnl not found: IPv6 net
161340266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
161440266059SGregory Neil Shapirodnl    1   2     3    4  5    6
161540266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
161640266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
161706f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
161840266059SGregory Neil Shapirodnl   1  2    3    4  5    6
161940266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
162040266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
162140266059SGregory Neil Shapirodnl   1    2      3    4
162240266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
162340266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
162440266059SGregory Neil Shapirodnl   1    2    3  4    5
162540266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
162640266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
162740266059SGregory Neil Shapirodnl            2    3    4  5    6
162840266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
162940266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
163040266059SGregory Neil Shapirodnl    2    3    4  5    6
163140266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1632c2aa98e2SPeter Wemm
1633c2aa98e2SPeter Wemm######################################################################
163440266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1635c2aa98e2SPeter Wemm###
1636c2aa98e2SPeter Wemm###	Parameters:
1637c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1638c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
163906f25ae9SGregory Neil Shapirodnl			must not be empty
164040266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
164106f25ae9SGregory Neil Shapiro###			! does lookup only with tag
164206f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
164340266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
164406f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
164506f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1646c2aa98e2SPeter Wemm######################################################################
1647c2aa98e2SPeter Wemm
164840266059SGregory Neil ShapiroSA
164906f25ae9SGregory Neil Shapirodnl lookup with tag
165040266059SGregory Neil Shapirodnl    2    3  4    5
165140266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
165206f25ae9SGregory Neil Shapirodnl lookup without tag
165340266059SGregory Neil Shapirodnl   1    2      3    4
165440266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
165540266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
165640266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
165740266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
165840266059SGregory Neil Shapirodnl      1    2    3  4    5
165940266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
166040266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
166140266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
166240266059SGregory Neil Shapirodnl   1   2    3    4  5    6
166340266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
166440266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
166506f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
166640266059SGregory Neil Shapirodnl   1  2    3    4  5    6
166740266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
166806f25ae9SGregory Neil Shapirodnl no match: return default
166940266059SGregory Neil Shapirodnl   1    2    3  4    5
167040266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
167140266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
167240266059SGregory Neil Shapirodnl            2    3    4  5    6
167340266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
167406f25ae9SGregory Neil Shapirodnl match: return result
167540266059SGregory Neil Shapirodnl    2    3    4  5    6
167640266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
167740266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
167840266059SGregory Neil Shapirodivert(0)
1679c2aa98e2SPeter Wemm######################################################################
1680065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1681065a643dSPeter Wemm###			relay checking.  Route address syntax is
1682065a643dSPeter Wemm###			crudely converted into a %-hack address.
1683065a643dSPeter Wemm###
1684065a643dSPeter Wemm###	Parameters:
1685065a643dSPeter Wemm###		$1 -- full recipient address
1686065a643dSPeter Wemm###
1687065a643dSPeter Wemm###	Returns:
1688065a643dSPeter Wemm###		parsed address, not in source route form
168906f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
169006f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1691065a643dSPeter Wemm######################################################################
1692065a643dSPeter Wemm
1693065a643dSPeter WemmSCanonAddr
169406f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
169506f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1696065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1697065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1698065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
169906f25ae9SGregory Neil Shapirodnl')
1700065a643dSPeter Wemm
1701065a643dSPeter Wemm######################################################################
1702c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1703c2aa98e2SPeter Wemm###			$* $=m or the access database.
1704c2aa98e2SPeter Wemm###			Check user portion for host separators.
1705c2aa98e2SPeter Wemm###
1706c2aa98e2SPeter Wemm###	Parameters:
1707c2aa98e2SPeter Wemm###		$1 -- full recipient address
1708c2aa98e2SPeter Wemm###
1709c2aa98e2SPeter Wemm###	Returns:
1710c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1711c2aa98e2SPeter Wemm######################################################################
1712c2aa98e2SPeter Wemm
1713c2aa98e2SPeter WemmSParseRecipient
171406f25ae9SGregory Neil Shapirodnl mark and canonify address
1715065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
171606f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1717c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
171806f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1719c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1720c2aa98e2SPeter Wemm
1721c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1722c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
172306f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1724c2aa98e2SPeter WemmR<?> $*				$@ $1
1725c2aa98e2SPeter Wemm
172640266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
172706f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1728c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1729c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1730c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
173106f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
173206f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
173340266059SGregory Neil Shapiro
173440266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
173540266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
173640266059SGregory Neil Shapirodnl other To: entries: blacklist recipient; generic entries?
173740266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1738c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1739c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
174006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
174106f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1742065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1743c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
174406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
174540266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1746c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1747065a643dSPeter Wemm
174806f25ae9SGregory Neil Shapiro
174940266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
175040266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
175140266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1752e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
175340266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
175440266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
175540266059SGregory Neil Shapirodnl no: put old <NO> mark back
175640266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
175740266059SGregory Neil Shapiro
175840266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1759c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
176040266059SGregory Neil Shapirodnl something else
176140266059SGregory Neil ShapiroR<$+> $*			$@ $2
1762c2aa98e2SPeter Wemm
176306f25ae9SGregory Neil Shapiro
1764c2aa98e2SPeter Wemm######################################################################
1765c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1766c2aa98e2SPeter Wemm######################################################################
1767c2aa98e2SPeter Wemm
1768e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1769e92d3f3fSGregory Neil ShapiroScheck_relay
1770e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1771e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1772e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1773e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1774e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1775e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1776e92d3f3fSGregory Neil Shapirodnl')
1777e92d3f3fSGregory Neil Shapiro
1778c2aa98e2SPeter WemmSLocal_check_relay
177906f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1780e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1781e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1782c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1783c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1784c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1785c2aa98e2SPeter Wemm
1786c2aa98e2SPeter WemmSBasic_check_relay
1787c2aa98e2SPeter Wemm# check for deferred delivery mode
178894c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1789c2aa98e2SPeter WemmR< d > $*		$@ deferred
1790c2aa98e2SPeter WemmR< $* > $*		$: $2
1791c2aa98e2SPeter Wemm
179206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
179342e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
179440266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
179542e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
179613bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
179713bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
179813bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
179940266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
180040266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
180140266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
180240266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
180342e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1804e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
180540266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1806e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
180706f25ae9SGregory Neil Shapirodnl error tag
180842e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
180942e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
181040266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
181106f25ae9SGregory Neil Shapirodnl generic error from access map
181242e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1813c2aa98e2SPeter Wemm
1814c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
181506f25ae9SGregory Neil Shapiro# DNS based IP address spam list
181640266059SGregory Neil Shapirodnl workspace: ignored...
1817c2aa98e2SPeter WemmR$*			$: $&{client_addr}
181806f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
181906f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
182094c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1821c2aa98e2SPeter Wemm`dnl')
1822e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1823e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1824e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1825e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1826e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1827e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1828e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1829e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
18306f9c8e5bSGregory Neil Shapiroundivert(8)dnl LOCAL_DNSBL
1831d0cef73dSGregory Neil Shapiroifdef(`_REQUIRE_RDNS_', `dnl
1832d0cef73dSGregory Neil ShapiroR$*			$: $&{client_addr} $| $&{client_resolve}
1833d0cef73dSGregory Neil ShapiroR$=R $*			$@ RELAY		We relay for these
1834d0cef73dSGregory Neil ShapiroR$* $| OK		$@ OK			Resolves.
1835d0cef73dSGregory Neil ShapiroR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1836d0cef73dSGregory Neil ShapiroR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1837d0cef73dSGregory Neil ShapiroR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1838d0cef73dSGregory Neil Shapiro', `dnl')
1839c2aa98e2SPeter Wemm
1840c2aa98e2SPeter Wemm######################################################################
1841c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1842c2aa98e2SPeter Wemm######################################################################
1843c2aa98e2SPeter Wemm
1844c2aa98e2SPeter WemmSLocal_check_mail
184506f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1846c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1847c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1848c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1849c2aa98e2SPeter Wemm
1850c2aa98e2SPeter WemmSBasic_check_mail
1851c2aa98e2SPeter Wemm# check for deferred delivery mode
185294c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1853c2aa98e2SPeter WemmR< d > $*		$@ deferred
1854c2aa98e2SPeter WemmR< $* > $*		$: $2
1855c2aa98e2SPeter Wemm
185606f25ae9SGregory Neil Shapiro# authenticated?
185706f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
185806f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
185906f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
186006f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
186106f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
186206f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
186306f25ae9SGregory Neil Shapiro
186406f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
186506f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
186606f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
186706f25ae9SGregory Neil Shapirodnl do some additional checks
186806f25ae9SGregory Neil Shapirodnl no user@host
186906f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
187006f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
187106f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
187206f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
187306f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
187406f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
187506f25ae9SGregory Neil ShapiroR$+			$: <?> $1
187606f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
187706f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
187806f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
187906f25ae9SGregory Neil Shapirodnl prepend daemon_flags
188006f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
188106f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
188206f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
188306f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
188406f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
188506f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
188606f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
188706f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
188806f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
188906f25ae9SGregory Neil Shapirodnl remove daemon_flags
189006f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
189106f25ae9SGregory Neil Shapiro# handle case of @localhost on address
189206f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
189306f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
189406f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
1895da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] >
1896da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] >
1897da7d7b9cSGregory Neil ShapiroR<@> < $* @ [IPv6:::1] >
1898da7d7b9cSGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [IPv6:::1] >
189906f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
190006f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
190106f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
190206f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
190306f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
190406f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
190506f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
190606f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
190706f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
190806f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
190906f25ae9SGregory Neil Shapirodnl	or:    <address>
191006f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
191106f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
191240266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
191306f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
191406f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
191506f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
191606f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
191706f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
191806f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1919065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1920c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1921959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
192206f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
192394c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1924959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1925c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
192640266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
192706f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
192806f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
192906f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
193040266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
193106f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1932c2aa98e2SPeter Wemm
193306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
193406f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
193506f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
193640266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
193740266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
193806f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
193906f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
194006f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
194106f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
194206f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
194306f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
194406f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
194506f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1946c2aa98e2SPeter Wemm# retransform for further use
194706f25ae9SGregory Neil Shapirodnl required form:
194806f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
194906f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
195006f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
195106f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
195206f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1953c2aa98e2SPeter Wemm
1954c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1955c2aa98e2SPeter Wemm# handle case of no @domain on address
195606f25ae9SGregory Neil Shapirodnl prepend daemon_flags
195706f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
195806f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
195940266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
196006f25ae9SGregory Neil Shapirodnl remove daemon_flags
196106f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
196213bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1963959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
196440266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1965c2aa98e2SPeter Wemm							...remote is not')
1966c2aa98e2SPeter Wemm# check results
196706f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1968d0cef73dSGregory Neil ShapiroR<$={ResOk}> $*		$: @ $2		domain ok
196906f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
197040266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
197106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
197240266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1973c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
1974e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
1975e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
197606f25ae9SGregory Neil Shapirodnl error tag
197706f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
197806f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
197940266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
198006f25ae9SGregory Neil Shapirodnl generic error from access map
198106f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1982c2aa98e2SPeter Wemm`dnl')
1983d0cef73dSGregory Neil Shapirodnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
1984d0cef73dSGregory Neil Shapiro
1985d0cef73dSGregory Neil Shapiroifdef(`_BADMX_CHK_', `dnl
1986d0cef73dSGregory Neil ShapiroR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
1987d0cef73dSGregory Neil ShapiroR$* $| $#$*		$#$2
1988d0cef73dSGregory Neil Shapiro
1989d0cef73dSGregory Neil ShapiroSBadMX
1990d0cef73dSGregory Neil Shapiro# Look up MX records and ferret away a copy of the original address.
1991d0cef73dSGregory Neil Shapiro# input: domain part of address to check
1992d0cef73dSGregory Neil ShapiroR$+				$:<MX><$1><:$(mxlist $1$):><:>
1993d0cef73dSGregory Neil Shapiro# workspace: <MX><domain><: mxlist-result $><:>
1994d0cef73dSGregory Neil ShapiroR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
1995d0cef73dSGregory Neil Shapiro# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
1996d0cef73dSGregory Neil Shapiro# Recursively run badmx check on each mx.
1997d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
1998d0cef73dSGregory Neil Shapiro# See if any of them fail.
1999e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
2000d0cef73dSGregory Neil Shapiro# Reverse the mxlists so we can use the same argument order again.
2001d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2002d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
2003d0cef73dSGregory Neil Shapiro
2004d0cef73dSGregory Neil Shapiro# Reverse the lists so we can use the same argument order again.
2005d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
2006d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
2007d0cef73dSGregory Neil Shapiro
2008e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
2009d0cef73dSGregory Neil Shapiro`dnl')
2010d0cef73dSGregory Neil Shapiro
2011c2aa98e2SPeter Wemm
2012c2aa98e2SPeter Wemm######################################################################
2013c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
2014c2aa98e2SPeter Wemm######################################################################
2015c2aa98e2SPeter Wemm
2016c2aa98e2SPeter WemmSLocal_check_rcpt
201706f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
2018c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
2019c2aa98e2SPeter WemmR$* $| $#$*		$#$2
2020c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
2021c2aa98e2SPeter Wemm
2022c2aa98e2SPeter WemmSBasic_check_rcpt
202340266059SGregory Neil Shapiro# empty address?
202440266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
202540266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
2026c2aa98e2SPeter Wemm# check for deferred delivery mode
202794c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
2028c2aa98e2SPeter WemmR< d > $*		$@ deferred
2029c2aa98e2SPeter WemmR< $* > $*		$: $2
2030c2aa98e2SPeter Wemm
203106f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
203240266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
203340266059SGregory Neil Shapirodnl it is not activated.
203440266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
203540266059SGregory Neil Shapirodnl available down below; look for the same macro.
203640266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
203740266059SGregory Neil Shapirodnl canonicalization.
203840266059SGregory Neil Shapiro# require fully qualified domain part?
203940266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
204006f25ae9SGregory Neil ShapiroR$+			$: <?> $1
204106f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
204206f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
204340266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
204413bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
204506f25ae9SGregory Neil Shapirodnl prepend daemon_flags
204640266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
204706f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
2048af9557fdSGregory Neil Shapirodnl _r_equire qual.rcpt: ok
2049a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
205006f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
2051a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
205206f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
205306f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
205440266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
205506f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
205606f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
205706f25ae9SGregory Neil Shapiro
205840266059SGregory Neil Shapirodnl ##################################################################
205940266059SGregory Neil Shapirodnl call subroutines for recipient and relay
206040266059SGregory Neil Shapirodnl possible returns from subroutines:
206140266059SGregory Neil Shapirodnl $#TEMP	temporary failure
206240266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
206340266059SGregory Neil Shapirodnl $#other	stop processing
206440266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
206540266059SGregory Neil Shapirodnl other	otherwise
206640266059SGregory Neil Shapiro######################################################################
206740266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
206840266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
206940266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
207040266059SGregory Neil Shapirodnl error or ok (stop)
207140266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
207240266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
207340266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
207440266059SGregory Neil Shapirodnl something else: call check sender (relay)
207540266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
207640266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
207740266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
207840266059SGregory Neil Shapirodnl temporary failure? return that
207940266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
208040266059SGregory Neil Shapirodnl error or ok (stop)
208140266059SGregory Neil ShapiroR$* $| $#$*		$#$2
208240266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
208340266059SGregory Neil Shapirodnl something else: return previous temp failure
208440266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
208540266059SGregory Neil Shapiro# anything else is bogus
208640266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
208740266059SGregory Neil Shapirodivert(0)
208840266059SGregory Neil Shapiro
208940266059SGregory Neil Shapiro######################################################################
209040266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
209140266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
209240266059SGregory Neil Shapirodnl output: see explanation at call
209340266059SGregory Neil Shapiro######################################################################
209440266059SGregory Neil ShapiroSRcpt_ok
2095c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2096065a643dSPeter WemmR$*			$: $>CanonAddr $1
2097c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2098c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2099c2aa98e2SPeter Wemm
2100065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2101065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2102065a643dSPeter Wemm# unlimited bestmx
2103065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2104065a643dSPeter Wemm`dnl
2105065a643dSPeter Wemm# limit bestmx to $=B
21062e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
210740266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2108065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2109065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2110065a643dSPeter Wemm
2111c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
211206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2113c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
2114c2aa98e2SPeter WemmR$*			$: <?> $1
211506f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
211606f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
211740266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
211840266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
211906f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
212006f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
212106f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
212206f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
212306f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
212406f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
212540266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
212640266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
212740266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
212840266059SGregory Neil Shapirodnl that would make a lot of things easier.
212906f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
213040266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
213140266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
213240266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
213340266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
213406f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
213506f25ae9SGregory Neil Shapirodnl as generic error message...
213606f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
213706f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
213806f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
213906f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
214040266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
214106f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2142e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
214306f25ae9SGregory Neil Shapirodnl error tag
214406f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
214506f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
214640266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
214706f25ae9SGregory Neil Shapirodnl generic error from access map
214806f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
214906f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2150c2aa98e2SPeter Wemm
215140266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
215240266059SGregory Neil Shapiro# authenticated via TLS?
215340266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
215406f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
215506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
215606f25ae9SGregory Neil Shapiro
215740266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
215840266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
215940266059SGregory Neil ShapiroR$* $| $# $*		$# $2
216040266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
216140266059SGregory Neil ShapiroR$* $| NO		$: $1
216240266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
216340266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
216406f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
216506f25ae9SGregory Neil ShapiroR$* $|			$: $1
216606f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
216706f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
216840266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
216940266059SGregory Neil Shapirodnl remove ${auth_type}
217006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2171193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
217206f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2173193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2174193538b7SGregory Neil ShapiroR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2175da7d7b9cSGregory Neil Shapiroifelse(defn(`_NO_PERCENTHACK_'), `r',
2176da7d7b9cSGregory Neil Shapiro`R$* % $* < @ $* >	$: <REMOTE> $1 < @ PERCENT_HACK >
2177da7d7b9cSGregory Neil ShapiroR$* % $* 		$: <REMOTE> $1 < @ PERCENT_HACK >', `dnl')
2178c2aa98e2SPeter Wemm# anything terminating locally is ok
2179c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
218040266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
218140266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2182c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
218340266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
218406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21859bd497b8SGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
21869bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
21879bd497b8SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
21889bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
218906f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
219006f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
219140266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
219206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2193e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2194e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2195e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2196e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2197e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
219806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
219906f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
220040266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
220140266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2202c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2203c2aa98e2SPeter Wemm
220406f25ae9SGregory Neil Shapiro
2205c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2206c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
220706f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
220806f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2209e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
221040266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2211065a643dSPeter WemmR< : $* : > $*		$: $2',
2212c2aa98e2SPeter Wemm`dnl')
2213c2aa98e2SPeter Wemm
2214c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2215c2aa98e2SPeter WemmR$*			$: <?> $1
2216065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2217c2aa98e2SPeter Wemm# local user is ok
221806f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
221906f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
222006f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
222106f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
222206f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
222340266059SGregory Neil ShapiroR<?> postmaster		$@ OK
222406f25ae9SGregory Neil Shapiro# require qualified recipient?
222506f25ae9SGregory Neil Shapirodnl prepend daemon_flags
222606f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
222706f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
222806f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
222906f25ae9SGregory Neil Shapirodnl r flag? add client_name
223006f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
223106f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
223206f25ae9SGregory Neil Shapiro# no qualified recipient required
223340266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
223406f25ae9SGregory Neil Shapirodnl client_name is empty
223540266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
223606f25ae9SGregory Neil Shapirodnl client_name is local
223740266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
223806f25ae9SGregory Neil Shapirodnl client_name is not local
223906f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
224006f25ae9SGregory Neil Shapirodnl no qualified recipient required
224140266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
224206f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2243c2aa98e2SPeter WemmR<$+> $*		$: $2
224406f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2245c2aa98e2SPeter Wemm
224640266059SGregory Neil Shapiro######################################################################
224740266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
224840266059SGregory Neil Shapirodnl input: ignored
224940266059SGregory Neil Shapirodnl output: see explanation at call
225040266059SGregory Neil Shapiro######################################################################
225140266059SGregory Neil ShapiroSRelay_ok
2252c2aa98e2SPeter Wemm# anything originating locally is ok
2253c2aa98e2SPeter Wemm# check IP address
2254c2aa98e2SPeter WemmR$*			$: $&{client_addr}
225540266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
225640266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
225713bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
2258da7d7b9cSGregory Neil ShapiroRIPv6:0:0:0:0:0:0:0:1	$@ RELAY		originated locally
2259da7d7b9cSGregory Neil Shapirodnl if compiled with IPV6_FULL=0
226013bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
226140266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
226206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
226340266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
226440266059SGregory Neil ShapiroR<RELAY> $* 		$@ RELAY		relayable IP address
2265959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2266959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2267959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2268959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2269959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2270959366dcSGregory Neil ShapiroR<REJECT> $* 		$@ REJECT		rejected IP address')
227140266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2272c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2273c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
227440266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2275c2aa98e2SPeter Wemm
227606f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
227706f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
227806f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
227906f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
228006f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
228106f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
228206f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
228340266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2284c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
228506f25ae9SGregory Neil Shapiro# check whether local FROM is ok
228640266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
228706f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2288605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
228940266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
229040266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
229140266059SGregory Neil Shapiro', `dnl
229240266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
229340266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
229406f25ae9SGregory Neil Shapiro')',
229506f25ae9SGregory Neil Shapiro`dnl')
229606f25ae9SGregory Neil Shapirodnl')', `dnl')
229740266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
229840266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
229940266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
230006f25ae9SGregory Neil Shapiro
230106f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
230206f25ae9SGregory Neil Shapirodnl input: ignored
230306f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2304e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
230506f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
230606f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
230706f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
230840266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
230906f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
231013bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
231113bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
231213bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
231313bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
231413bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
231540266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
231640266059SGregory Neil Shapiro# pass to name server to make hostname canonical
231740266059SGregory Neil ShapiroR<@> $* $=P 		$:<?>  $1 $2
231840266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
231940266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
232040266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
232106f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
232240266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
232340266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
232406f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
232540266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
232606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
232706f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
232806f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
232940266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
233006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
233140266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
233206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
233340266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
233440266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
233506f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
233640266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
233706f25ae9SGregory Neil Shapirodivert(0)
233806f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
233906f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
234006f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
234106f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
234206f25ae9SGregory Neil ShapiroSFullAddr
234306f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
234406f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
234506f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2346c2aa98e2SPeter Wemm
2347a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
234813bd1963SGregory Neil Shapiro# authenticated?
234913bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
235013bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
235113bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
235213bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
235313bd1963SGregory Neil Shapirodnl return result from checkrcpt
2354a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
235513bd1963SGregory Neil ShapiroR$*			$# $1
235613bd1963SGregory Neil Shapiro
2357a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
235813bd1963SGregory Neil Shapiro# authenticated?
235913bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
236013bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
236113bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
236213bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
236313bd1963SGregory Neil Shapirodnl return result from friend/hater check
2364a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
236513bd1963SGregory Neil ShapiroR$*			$@ $1
236613bd1963SGregory Neil Shapiro
236706f25ae9SGregory Neil Shapiro# call all necessary rulesets
236806f25ae9SGregory Neil ShapiroScheck_rcpt
236906f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
237006f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
237106f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
237213bd1963SGregory Neil Shapiro
237306f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
237406f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
237513bd1963SGregory Neil Shapirodnl on error (or discard) stop now
237613bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
237713bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
237813bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2379a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
238006f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
238106f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
238206f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
238306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
238406f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
238506f25ae9SGregory Neil Shapiro')')dnl
238606f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
238706f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
238806f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
238940266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
239040266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
239106f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
239240266059SGregory Neil Shapiro# lookup the addresses only with Spam tag
239340266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
239406f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
239506f25ae9SGregory Neil Shapirodnl', `dnl')
239606f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
239706f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
239806f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
239913bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
240006f25ae9SGregory Neil Shapiro')', `dnl')
2401a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
240206f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
240306f25ae9SGregory Neil Shapiro`dnl')
240406f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
240506f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
240640266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2407a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
240806f25ae9SGregory Neil Shapirodnl',`dnl')
2409d0cef73dSGregory Neil Shapiro
241006f25ae9SGregory Neil Shapirodnl run further checks: check_mail
241106f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
241240266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
241340266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
241440266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2415605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
241606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
241706f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2418605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
241906f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
242006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
242106f25ae9SGregory Neil Shapiro', `dnl')
242240266059SGregory Neil Shapiro
2423d0cef73dSGregory Neil Shapiroifdef(`_BLOCK_BAD_HELO_', `dnl
2424d0cef73dSGregory Neil ShapiroR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2425d0cef73dSGregory Neil Shapirodnl Bypass the test for users who have authenticated.
2426d0cef73dSGregory Neil ShapiroR$* $| <$+>		$: $1				skip if auth
2427d0cef73dSGregory Neil ShapiroR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2428d0cef73dSGregory Neil Shapirodnl Bypass for local clients -- IP address starts with $=R
2429d0cef73dSGregory Neil ShapiroR$* $| <$=R $*> [$*]	$: $1				skip if local client
2430d0cef73dSGregory Neil Shapirodnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2431d0cef73dSGregory Neil ShapiroR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2432d0cef73dSGregory Neil Shapirodnl Reject our IP - assumes "[ip]" is in class $=w
2433d0cef73dSGregory Neil ShapiroR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2434d0cef73dSGregory Neil Shapirodnl Reject our hostname
2435d0cef73dSGregory Neil ShapiroR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2436d0cef73dSGregory Neil Shapirodnl Pass anything else with a "." in the domain parameter
2437d0cef73dSGregory Neil ShapiroR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
24385dd76dd0SGregory Neil Shapirodnl Pass IPv6: address literals
24395dd76dd0SGregory Neil ShapiroR$* $| <$*> [IPv6:$+]	$: $1				qualified domain ok
2440d0cef73dSGregory Neil Shapirodnl Reject if there was no "." or only an initial or final "."
2441d0cef73dSGregory Neil ShapiroR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2442d0cef73dSGregory Neil Shapirodnl Clean up the workspace
2443d0cef73dSGregory Neil ShapiroR$* $| $*		$: $1
2444d0cef73dSGregory Neil Shapiro', `dnl')
2445d0cef73dSGregory Neil Shapiro
244640266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
244740266059SGregory Neil Shapiro######################################################################
244840266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
244940266059SGregory Neil Shapiro###
245040266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
245140266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
245240266059SGregory Neil Shapiro###
245340266059SGregory Neil Shapiro###	Parameters:
245440266059SGregory Neil Shapiro###		<$1> -- key
245540266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
245640266059SGregory Neil Shapirodnl			must not be empty
245740266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
245840266059SGregory Neil Shapiro###			! does lookup only with tag
245940266059SGregory Neil Shapiro###			+ does lookup with and without tag
246040266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
246140266059SGregory Neil Shapirodnl returns:		<default> <passthru>
246240266059SGregory Neil Shapirodnl 			<result> <passthru>
246340266059SGregory Neil Shapiro######################################################################
246440266059SGregory Neil Shapiro
246540266059SGregory Neil ShapiroSF
246640266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
246740266059SGregory Neil Shapirodnl full lookup
246840266059SGregory Neil Shapirodnl    2    3  4    5
246940266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
247040266059SGregory Neil Shapirodnl no match, try without tag
247140266059SGregory Neil Shapirodnl   1    2      3    4
247240266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
247340266059SGregory Neil Shapirodnl no match, +detail: try +*
247440266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
247540266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
247640266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
247740266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
247840266059SGregory Neil Shapirodnl   1    2    3    4      5    6
247940266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
248040266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
248140266059SGregory Neil Shapirodnl no match, +detail: try without +detail
248240266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
248340266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
248440266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
248540266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
248640266059SGregory Neil Shapirodnl   1    2    3    4      5    6
248740266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
248840266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
248940266059SGregory Neil Shapirodnl no match, return <default> <passthru>
249040266059SGregory Neil Shapirodnl   1    2    3  4    5
249140266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
249240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
249340266059SGregory Neil Shapirodnl            2    3  4    5
249440266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
249540266059SGregory Neil Shapirodnl match, return <match> <passthru>
249640266059SGregory Neil Shapirodnl    2    3  4    5
249740266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
249840266059SGregory Neil Shapiro
249940266059SGregory Neil Shapiro######################################################################
250040266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
250140266059SGregory Neil Shapiro###
250240266059SGregory Neil Shapiro###	Parameters:
250340266059SGregory Neil Shapiro###		<$1> -- key
250440266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
250540266059SGregory Neil Shapirodnl			must not be empty
250640266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
250740266059SGregory Neil Shapiro###			! does lookup only with tag
250840266059SGregory Neil Shapiro###			+ does lookup with and without tag
250940266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
251040266059SGregory Neil Shapirodnl returns:		<default> <passthru>
251140266059SGregory Neil Shapirodnl 			<result> <passthru>
251240266059SGregory Neil Shapiro######################################################################
251340266059SGregory Neil Shapiro
251440266059SGregory Neil ShapiroSE
251540266059SGregory Neil Shapirodnl    2    3  4    5
251640266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
251740266059SGregory Neil Shapirodnl no match, try without tag
251840266059SGregory Neil Shapirodnl   1    2      3    4
251940266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
252040266059SGregory Neil Shapirodnl no match, return default passthru
252140266059SGregory Neil Shapirodnl   1    2    3  4    5
252240266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
252340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
252440266059SGregory Neil Shapirodnl            2    3  4    5
252540266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
252640266059SGregory Neil Shapirodnl match, return <match> <passthru>
252740266059SGregory Neil Shapirodnl    2    3  4    5
252840266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
252940266059SGregory Neil Shapiro
253040266059SGregory Neil Shapiro######################################################################
253140266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
253240266059SGregory Neil Shapiro###
253340266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
253440266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
253540266059SGregory Neil Shapiro###
253640266059SGregory Neil Shapiro###	Parameters:
253740266059SGregory Neil Shapiro###		<$1> -- key (user@)
253840266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
253940266059SGregory Neil Shapirodnl			must not be empty
254040266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
254140266059SGregory Neil Shapiro###			! does lookup only with tag
254240266059SGregory Neil Shapiro###			+ does lookup with and without tag
254340266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
254440266059SGregory Neil Shapirodnl returns:		<default> <passthru>
254540266059SGregory Neil Shapirodnl 			<result> <passthru>
254640266059SGregory Neil Shapiro######################################################################
254740266059SGregory Neil Shapiro
254840266059SGregory Neil ShapiroSU
254940266059SGregory Neil Shapirodnl user lookups are always with trailing @
255040266059SGregory Neil Shapirodnl    2    3  4    5
255140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
255240266059SGregory Neil Shapirodnl no match, try without tag
255340266059SGregory Neil Shapirodnl   1    2      3    4
255440266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
255540266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
255640266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
255740266059SGregory Neil Shapirodnl no match, +detail: try +*
255840266059SGregory Neil Shapirodnl   1    2      3    4  5    6
255940266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
256040266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
256140266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
256240266059SGregory Neil Shapirodnl   1    2      3      4    5
256340266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
256440266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
256540266059SGregory Neil Shapirodnl no match, +detail: try without +detail
256640266059SGregory Neil Shapirodnl   1    2      3    4  5    6
256740266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
256840266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
256940266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
257040266059SGregory Neil Shapirodnl   1    2      3      4    5
257140266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
257240266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
257340266059SGregory Neil Shapirodnl no match, return <default> <passthru>
257440266059SGregory Neil Shapirodnl   1    2    3  4    5
257540266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
257640266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
257740266059SGregory Neil Shapirodnl            2    3  4    5
257840266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
257940266059SGregory Neil Shapirodnl match, return <match> <passthru>
258040266059SGregory Neil Shapirodnl    2    3  4    5
258140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
258240266059SGregory Neil Shapiro
258306f25ae9SGregory Neil Shapiro######################################################################
258406f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
258506f25ae9SGregory Neil Shapiro###	Parameters:
258606f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
258706f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
258806f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
258906f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
259006f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
259140266059SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: D: if there
259206f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
259306f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
259406f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
259506f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
259606f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
259706f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
259806f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
259906f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
260006f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
260140266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
260206f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
260306f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
260406f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
260506f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
260606f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
260706f25ae9SGregory Neil Shapiro######################################################################
260806f25ae9SGregory Neil Shapiro
260906f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
261006f25ae9SGregory Neil Shapirodnl if A is activated: add it
2611e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
261206f25ae9SGregory Neil ShapiroSSearchList
261340266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
261440266059SGregory Neil Shapirodnl       2       3    4
2615e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
261640266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
261740266059SGregory Neil Shapirodnl no match and nothing left: return
261840266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
261940266059SGregory Neil Shapirodnl no match but something left: continue
262040266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
262140266059SGregory Neil Shapirodnl match: return
262240266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
262306f25ae9SGregory Neil Shapirodnl return result from recursive invocation
262440266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
262540266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
262640266059SGregory Neil Shapirodivert(0)
262706f25ae9SGregory Neil Shapiro
262840266059SGregory Neil Shapiro######################################################################
262940266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
263040266059SGregory Neil Shapiro###
263140266059SGregory Neil Shapiro###	Parameters:
263240266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
263340266059SGregory Neil Shapiro######################################################################
263440266059SGregory Neil Shapiro
263540266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
263640266059SGregory Neil ShapiroSLocal_trust_auth
263706f25ae9SGregory Neil ShapiroStrust_auth
263806f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
263906f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
264006f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
264106f25ae9SGregory Neil Shapirodnl seems to be useful...
264206f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
264306f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
264406f25ae9SGregory Neil Shapirodnl call user supplied code
2645a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
264606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
264706f25ae9SGregory Neil Shapirodnl default: error
264806f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
264906f25ae9SGregory Neil Shapiro
265040266059SGregory Neil Shapiro######################################################################
265140266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
265240266059SGregory Neil Shapiro###
265340266059SGregory Neil Shapiro###	Parameters:
265440266059SGregory Neil Shapiro###		$1: ${auth_type}
265540266059SGregory Neil Shapiro######################################################################
265640266059SGregory Neil ShapiroSLocal_Relay_Auth
265706f25ae9SGregory Neil Shapiro
265840266059SGregory Neil Shapiro######################################################################
265940266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
266040266059SGregory Neil Shapiro###	(done in server)
266140266059SGregory Neil Shapiro######################################################################
266240266059SGregory Neil ShapiroSsrv_features
266340266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
266440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
266540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
266640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2667e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
266840266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
266940266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
267040266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
267106f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
267240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
267340266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2674e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
267506f25ae9SGregory Neil Shapiro
267640266059SGregory Neil Shapiro######################################################################
267740266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
267840266059SGregory Neil Shapiro###	(done in client)
267940266059SGregory Neil Shapiro######################################################################
268006f25ae9SGregory Neil ShapiroStry_tls
268140266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
268240266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
268340266059SGregory Neil ShapiroR$* $| $#$*		$#$2
268440266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2685e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
268640266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
268740266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
268840266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
268906f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
269040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
269140266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2692e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
269306f25ae9SGregory Neil Shapiro
269440266059SGregory Neil Shapiro######################################################################
269540266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
269640266059SGregory Neil Shapiro###	(done in client, per recipient)
269740266059SGregory Neil Shapirodnl called from deliver() before RCPT command
269840266059SGregory Neil Shapiro###
269940266059SGregory Neil Shapiro###	Parameters:
270040266059SGregory Neil Shapiro###		$1: recipient
270140266059SGregory Neil Shapiro######################################################################
270240266059SGregory Neil ShapiroStls_rcpt
270340266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
270440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
270540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
270640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2707e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
270840266059SGregory Neil Shapirodnl store name of other side
270940266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
271040266059SGregory Neil Shapirodnl canonify recipient address
271140266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
271240266059SGregory Neil Shapirodnl strip trailing dots
271340266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
271440266059SGregory Neil Shapirodnl full address?
271540266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
271640266059SGregory Neil Shapirodnl only localpart?
271740266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
271840266059SGregory Neil Shapirodnl look it up
271940266059SGregory Neil Shapirodnl also look up a default value via E:
272040266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
272140266059SGregory Neil Shapirodnl found nothing: stop here
272240266059SGregory Neil ShapiroR$* $| <?>	$@ OK
272340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
272440266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
272540266059SGregory Neil Shapirodnl use the generic routine (for now)
272640266059SGregory Neil ShapiroR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
272740266059SGregory Neil Shapiro
272840266059SGregory Neil Shapiro######################################################################
272940266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
273040266059SGregory Neil Shapiro###	(done in server)
273140266059SGregory Neil Shapiro###
273240266059SGregory Neil Shapiro###	Parameters:
273340266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
273440266059SGregory Neil Shapiro######################################################################
273506f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
273606f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
273706f25ae9SGregory Neil ShapiroStls_client
273840266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
2739e3793f76SGregory Neil ShapiroR$*			$: $1 <?> $>"Local_tls_client" $1
2740e3793f76SGregory Neil ShapiroR$* <?> $#$*		$#$2
2741e3793f76SGregory Neil ShapiroR$* <?> $*		$: $1', `dnl')
274206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
274340266059SGregory Neil Shapirodnl store name of other side
27449bd497b8SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
274506f25ae9SGregory Neil Shapirodnl ignore second arg for now
274606f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
274706f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
274806f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
274940266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
275040266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
275106f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
275206f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
275340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
275440266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
275540266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
275640266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
275706f25ae9SGregory Neil Shapiro
275840266059SGregory Neil Shapiro######################################################################
275940266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
276040266059SGregory Neil Shapiro###	(done in client)
276140266059SGregory Neil Shapiro###
276240266059SGregory Neil Shapiro###	Parameter:
276340266059SGregory Neil Shapiro###		${verify}
276440266059SGregory Neil Shapiro######################################################################
276506f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
276606f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
276706f25ae9SGregory Neil ShapiroStls_server
276840266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
276940266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
277040266059SGregory Neil ShapiroR$* $| $#$*		$#$2
277140266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
277206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
277340266059SGregory Neil Shapirodnl store name of other side
277440266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
277540266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
277640266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
277706f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
277806f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
277940266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
278040266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
278140266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
278240266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
278306f25ae9SGregory Neil Shapiro
278440266059SGregory Neil Shapiro######################################################################
278540266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
278640266059SGregory Neil Shapiro###
278740266059SGregory Neil Shapiro###	Parameters:
278806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
278940266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
279040266059SGregory Neil Shapiro###		${verify}')
279140266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
279240266059SGregory Neil Shapirodnl	syntax for Requirement:
279340266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
279440266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
279540266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
279640266059SGregory Neil Shapiro######################################################################
279740266059SGregory Neil ShapiroSTLS_connection
279840266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
279940266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
280040266059SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
280140266059SGregory Neil Shapirodivert(-1)')
280206f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
280340266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
280406f25ae9SGregory Neil Shapirodnl remove optional <>
280506f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
280640266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
280740266059SGregory Neil Shapiro# create the appropriate error codes
280806f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2809e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2810e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
281106f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
2812e92d3f3fSGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
281340266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
281440266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
281506f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
281606f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
281706f25ae9SGregory Neil Shapirodnl use default error
281806f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
28194e4196cbSGregory Neil Shapiro# deal with TLS protocol errors: abort
28204e4196cbSGregory Neil ShapiroRPROTOCOL $| <$-:$+> $* 	$#error $@ $2 $: $1 " STARTTLS failed."
28214e4196cbSGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
28224e4196cbSGregory Neil Shapirodnl use default error
28234e4196cbSGregory Neil ShapiroRPROTOCOL $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
282440266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
282540266059SGregory Neil Shapirodnl separate optional requirements
282640266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2827e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
282840266059SGregory Neil Shapirodnl separate optional requirements
2829e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
283006f25ae9SGregory Neil Shapirodnl some other value in access map: accept
283106f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
283206f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
283306f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
283406f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
283540266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
283606f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
283740266059SGregory Neil ShapiroR<$*><VERIFY> <> OK		$@ OK
283840266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
283940266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
284040266059SGregory Neil ShapiroR<$*><VERIFY> <$+> OK		$: <$1> <REQ:0> <$2>
284106f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
284240266059SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> OK	$: <$1> <REQ:$2> <$3>
284306f25ae9SGregory Neil Shapirodnl just some level of encryption required
284440266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
284540266059SGregory Neil Shapirodnl workspace:
284640266059SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!= OK)
284740266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
284840266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
284940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
285040266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
285140266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
285240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
285340266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
285406f25ae9SGregory Neil Shapirodnl some other value for ${verify}
285540266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
285640266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
285740266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
285806f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
285940266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
286040266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
286140266059SGregory Neil Shapirodnl strength requirements fulfilled
286240266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
286340266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
286440266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
286540266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
286640266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
286740266059SGregory Neil Shapirodnl workspace:
286840266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
286940266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
287040266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
287140266059SGregory Neil Shapirodnl continue: check  extensions
287240266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
287340266059SGregory Neil Shapirodnl split extensions into own list
287440266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
287540266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
287640266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
287706f25ae9SGregory Neil Shapiro
287840266059SGregory Neil Shapiro######################################################################
287940266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
288040266059SGregory Neil Shapiro###
288140266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
288240266059SGregory Neil Shapiro###		$-: SMTP reply code
288340266059SGregory Neil Shapiro###		$+: Enhanced Status Code
288440266059SGregory Neil Shapirodnl  further requirements for this ruleset:
288540266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
288640266059SGregory Neil Shapirodnl
288740266059SGregory Neil Shapirodnl	currently only CN[:common_name] is implemented
288840266059SGregory Neil Shapirodnl	right now this is only a logical AND
288940266059SGregory Neil Shapirodnl	i.e. all requirements must be true
289040266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
289140266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
289240266059SGregory Neil Shapirodnl	operations (no precedences etc)?
289340266059SGregory Neil Shapiro######################################################################
289440266059SGregory Neil ShapiroSTLS_req
289540266059SGregory Neil Shapirodnl no additional requirements: ok
289640266059SGregory Neil ShapiroR $| $+		$@ OK
289740266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
289840266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
289940266059SGregory Neil Shapirodnl match, check rest
290040266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
290140266059SGregory Neil Shapirodnl CN does not match
290240266059SGregory Neil Shapirodnl  1   2      3  4
290340266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
290440266059SGregory Neil Shapirodnl cert subject
290540266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
290640266059SGregory Neil Shapirodnl CS does not match
290740266059SGregory Neil Shapirodnl  1   2      3  4
290813bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
290940266059SGregory Neil Shapirodnl match, check rest
291040266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
291140266059SGregory Neil Shapirodnl CI does not match
291240266059SGregory Neil Shapirodnl  1   2      3  4
291313bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
291440266059SGregory Neil Shapirodnl return from recursive call
291540266059SGregory Neil ShapiroROK			$@ OK
291640266059SGregory Neil Shapiro
291740266059SGregory Neil Shapiro######################################################################
291840266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
291940266059SGregory Neil Shapiro###
292040266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
292140266059SGregory Neil Shapiro######################################################################
292206f25ae9SGregory Neil ShapiroSmax
292306f25ae9SGregory Neil ShapiroR:		$: 0
292406f25ae9SGregory Neil ShapiroR:$-		$: $1
292506f25ae9SGregory Neil ShapiroR$-:		$: $1
292606f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
292706f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
292840266059SGregory Neil ShapiroR$-:$-:$-	$: $2
292940266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
293040266059SGregory Neil Shapirodivert(0)
293106f25ae9SGregory Neil Shapiro
2932da7d7b9cSGregory Neil Shapiroifdef(`_TLS_SESSION_FEATURES_', `dnl
2933da7d7b9cSGregory Neil ShapiroStls_srv_features
2934da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2935da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Srv_Features> <$2>
2936da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$: $>A <$1> <?> <! TLS_Srv_Features> <$1>
2937da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$@ ""
2938da7d7b9cSGregory Neil ShapiroR<$+> <$*> 		$@ $1
2939da7d7b9cSGregory Neil Shapiro', `dnl
2940da7d7b9cSGregory Neil ShapiroR$* 		$@ ""')
2941da7d7b9cSGregory Neil Shapiro
2942da7d7b9cSGregory Neil ShapiroStls_clt_features
2943da7d7b9cSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2944da7d7b9cSGregory Neil ShapiroR$* $| $*		$: $>D <$1> <?> <! TLS_Clt_Features> <$2>
2945da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$: $>A <$1> <?> <! TLS_Clt_Features> <$1>
2946da7d7b9cSGregory Neil ShapiroR<?> <$*> 		$@ ""
2947da7d7b9cSGregory Neil ShapiroR<$+> <$*> 		$@ $1
2948da7d7b9cSGregory Neil Shapiro', `dnl
2949da7d7b9cSGregory Neil ShapiroR$* 		$@ ""')
2950da7d7b9cSGregory Neil Shapiro')
2951da7d7b9cSGregory Neil Shapiro
295240266059SGregory Neil Shapiro######################################################################
295340266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
295440266059SGregory Neil Shapiro###
295540266059SGregory Neil Shapiro###	Parameters:
295640266059SGregory Neil Shapiro###		none
295740266059SGregory Neil Shapiro######################################################################
295840266059SGregory Neil ShapiroSRelayTLS
295906f25ae9SGregory Neil Shapiro# authenticated?
296006f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
296106f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
296213bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
296306f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
296406f25ae9SGregory Neil Shapirodnl but anyway).
296506f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
296606f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
296706f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
296806f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
296906f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
297006f25ae9SGregory Neil Shapirodnl cert subject.
297106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
297240266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
297340266059SGregory Neil ShapiroR<?> OK			$: OK		authenticated: continue
297440266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
297506f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
297640266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
297740266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
297840266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
297906f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
298040266059SGregory Neil ShapiroRRELAY			$# RELAY
298106f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
298240266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
298340266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
298440266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
298540266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
298640266059SGregory Neil ShapiroR$*			$: NO', `dnl')
298740266059SGregory Neil Shapiro
298840266059SGregory Neil Shapiro######################################################################
298940266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
299040266059SGregory Neil Shapiro###
299140266059SGregory Neil Shapiro###	Parameters:
299240266059SGregory Neil Shapiro###		$1: {server_name}
299340266059SGregory Neil Shapiro###		$2: {server_addr}
299440266059SGregory Neil Shapirodnl	both are currently ignored
299540266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
299640266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
299740266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
299840266059SGregory Neil Shapiro######################################################################
299940266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
300040266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
300140266059SGregory Neil Shapirodnl (which may be considered a good thing).
300240266059SGregory Neil ShapiroSauthinfo
300340266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
300440266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
300540266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
300640266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
300740266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
300840266059SGregory Neil ShapiroR<$*>		$# $1
300940266059SGregory Neil Shapirodnl', `dnl
301040266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
301140266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
301240266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
301340266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
301440266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
301540266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
301640266059SGregory Neil Shapirodnl', `dnl')')
301706f25ae9SGregory Neil Shapiro
3018e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
3019e92d3f3fSGregory Neil Shapiro######################################################################
3020e92d3f3fSGregory Neil Shapiro###  RateControl:
3021e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3022e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3023e92d3f3fSGregory Neil Shapiro######################################################################
3024e92d3f3fSGregory Neil ShapiroSRateControl
3025e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3026e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3027e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3028e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
3029e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3030e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3031e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
3032e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
3033e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3034e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3035ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
3036e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
3037ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
3038e92d3f3fSGregory Neil Shapiro')')
3039e92d3f3fSGregory Neil Shapiro
3040e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
3041e92d3f3fSGregory Neil Shapiro######################################################################
3042e92d3f3fSGregory Neil Shapiro###  ConnControl:
3043e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
3044e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
3045e92d3f3fSGregory Neil Shapiro######################################################################
3046e92d3f3fSGregory Neil ShapiroSConnControl
3047e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
3048e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
3049e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
3050e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
3051e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
3052e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
3053e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
3054e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
3055e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
3056e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
3057ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
3058e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
3059ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
3060e92d3f3fSGregory Neil Shapiro')')
3061e92d3f3fSGregory Neil Shapiro
306206f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
306306f25ae9SGregory Neil Shapiro#
306406f25ae9SGregory Neil Shapiro######################################################################
306506f25ae9SGregory Neil Shapiro######################################################################
306606f25ae9SGregory Neil Shapiro#####
306706f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
306806f25ae9SGregory Neil Shapiro#####
306906f25ae9SGregory Neil Shapiro######################################################################
307006f25ae9SGregory Neil Shapiro######################################################################
307140266059SGregory Neil Shapiro_MAIL_FILTERS_
3072c2aa98e2SPeter Wemm#
3073c2aa98e2SPeter Wemm######################################################################
3074c2aa98e2SPeter Wemm######################################################################
3075c2aa98e2SPeter Wemm#####
3076c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
3077c2aa98e2SPeter Wemm#####
3078c2aa98e2SPeter Wemm######################################################################
3079c2aa98e2SPeter Wemm######################################################################
308006f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
308142e5d165SGregory Neil Shapiro
3082