xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision 4313cc83)
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)
152c2aa98e2SPeter WemmCO @ % 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
329c2aa98e2SPeter Wemm# log level
33006f25ae9SGregory Neil Shapiro_OPTION(LogLevel, `confLOG_LEVEL', `10')
331c2aa98e2SPeter Wemm
332c2aa98e2SPeter Wemm# send to me too, even in an alias expansion?
33306f25ae9SGregory Neil Shapiro_OPTION(MeToo, `confME_TOO', `True')
334c2aa98e2SPeter Wemm
335c2aa98e2SPeter Wemm# verify RHS in newaliases?
33606f25ae9SGregory Neil Shapiro_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
337c2aa98e2SPeter Wemm
338c2aa98e2SPeter Wemm# default messages to old style headers if no special punctuation?
33906f25ae9SGregory Neil Shapiro_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
340c2aa98e2SPeter Wemm
341c2aa98e2SPeter Wemm# SMTP daemon options
34206f25ae9SGregory Neil Shapiroifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
343605302a5SGregory Neil Shapiro`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
344605302a5SGregory Neil Shapiro	Use `DAEMON_OPTIONS()'; see cf/README.
34506f25ae9SGregory Neil Shapiro)'dnl
34606f25ae9SGregory Neil Shapiro`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
34742e5d165SGregory Neil Shapiroifelse(defn(`_DPO_'), `',
34840266059SGregory Neil Shapiro`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
34940266059SGregory Neil ShapiroO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
35006f25ae9SGregory Neil Shapiroifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
35106f25ae9SGregory Neil Shapiro
35206f25ae9SGregory Neil Shapiro# SMTP client options
35340266059SGregory Neil Shapiroifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
35440266059SGregory Neil Shapiro`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
35540266059SGregory Neil Shapiro)'dnl
35640266059SGregory Neil Shapiro`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
35740266059SGregory Neil Shapiroifelse(defn(`_CPO_'), `',
35840266059SGregory Neil Shapiro`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
35940266059SGregory Neil Shapiro
36040266059SGregory Neil Shapiro# Modifiers to `define' {daemon_flags} for direct submissions
36140266059SGregory Neil Shapiro_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
36240266059SGregory Neil Shapiro
36340266059SGregory Neil Shapiro# Use as mail submission program? See sendmail/SECURITY
36440266059SGregory Neil Shapiro_OPTION(UseMSP, `confUSE_MSP', `')
365c2aa98e2SPeter Wemm
366c2aa98e2SPeter Wemm# privacy flags
36706f25ae9SGregory Neil Shapiro_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
368c2aa98e2SPeter Wemm
369c2aa98e2SPeter Wemm# who (if anyone) should get extra copies of error messages
37006f25ae9SGregory Neil Shapiro_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
371c2aa98e2SPeter Wemm
372c2aa98e2SPeter Wemm# slope of queue-only function
37306f25ae9SGregory Neil Shapiro_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
374c2aa98e2SPeter Wemm
37540266059SGregory Neil Shapiro# limit on number of concurrent queue runners
37640266059SGregory Neil Shapiro_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
37740266059SGregory Neil Shapiro
37840266059SGregory Neil Shapiro# maximum number of queue-runners per queue-grouping with multiple queues
37940266059SGregory Neil Shapiro_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
38040266059SGregory Neil Shapiro
38140266059SGregory Neil Shapiro# priority of queue runners (nice(3))
38240266059SGregory Neil Shapiro_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
38340266059SGregory Neil Shapiro
38440266059SGregory Neil Shapiro# shall we sort the queue by hostname first?
38540266059SGregory Neil Shapiro_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
38640266059SGregory Neil Shapiro
38740266059SGregory Neil Shapiro# minimum time in queue before retry
38840266059SGregory Neil Shapiro_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
38940266059SGregory Neil Shapiro
39040266059SGregory Neil Shapiro# how many jobs can you process in the queue?
3914e4196cbSGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
39240266059SGregory Neil Shapiro
39340266059SGregory Neil Shapiro# perform initial split of envelope without checking MX records
39440266059SGregory Neil Shapiro_OPTION(FastSplit, `confFAST_SPLIT', `1')
39540266059SGregory Neil Shapiro
396c2aa98e2SPeter Wemm# queue directory
39706f25ae9SGregory Neil ShapiroO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
398c2aa98e2SPeter Wemm
399d0cef73dSGregory Neil Shapiro# key for shared memory; 0 to turn off, -1 to auto-select
40040266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
40140266059SGregory Neil Shapiro
402d0cef73dSGregory Neil Shapiro# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
403d0cef73dSGregory Neil Shapiro_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
404605302a5SGregory Neil Shapiro
405c2aa98e2SPeter Wemm# timeouts (many of these)
40606f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
40706f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
40840266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
40906f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
41006f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
41106f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
41206f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
41306f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
41406f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
41506f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
41606f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
41706f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
41806f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
41906f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
42006f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
42106f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
42206f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
42306f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
42406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
42506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
42606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
427e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
42806f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
42906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
432e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
43306f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
43506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
43806f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
44040266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
44140266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
44240266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
44340266059SGregory Neil Shapiro
44440266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
44540266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
446c2aa98e2SPeter Wemm
447c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
44806f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
449c2aa98e2SPeter Wemm
450c2aa98e2SPeter Wemm# queue up everything before forking?
45106f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
452c2aa98e2SPeter Wemm
453c2aa98e2SPeter Wemm# status file
454d0cef73dSGregory Neil Shapiro_OPTION(StatusFile, `STATUS_FILE')
455c2aa98e2SPeter Wemm
456c2aa98e2SPeter Wemm# time zone handling:
457c2aa98e2SPeter Wemm#  if undefined, use system default
458c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
459c2aa98e2SPeter Wemm#  if defined and non-null, use that info
460c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
461c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
462c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
463c2aa98e2SPeter Wemm
464c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
46506f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
466c2aa98e2SPeter Wemm
467c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
46806f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
469c2aa98e2SPeter Wemm
470c2aa98e2SPeter Wemm# fallback MX host
47106f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
472c2aa98e2SPeter Wemm
473e92d3f3fSGregory Neil Shapiro# fallback smart host
474e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
475e92d3f3fSGregory Neil Shapiro
476c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
47706f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
478c2aa98e2SPeter Wemm
479c2aa98e2SPeter Wemm# load average at which we just queue messages
48006f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
481c2aa98e2SPeter Wemm
482c2aa98e2SPeter Wemm# load average at which we refuse connections
48306f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
484c2aa98e2SPeter Wemm
485e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
486e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
487e92d3f3fSGregory Neil Shapiro
48840266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
48940266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
49040266059SGregory Neil Shapiro
491c2aa98e2SPeter Wemm# maximum number of children we allow at one time
492739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
493c2aa98e2SPeter Wemm
494c2aa98e2SPeter Wemm# maximum number of new connections per second
495193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
496c2aa98e2SPeter Wemm
497e92d3f3fSGregory Neil Shapiro# Width of the window
498e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
499e92d3f3fSGregory Neil Shapiro
500c2aa98e2SPeter Wemm# work recipient factor
50106f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
502c2aa98e2SPeter Wemm
503c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
50406f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
505c2aa98e2SPeter Wemm
506c2aa98e2SPeter Wemm# work class factor
50706f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
508c2aa98e2SPeter Wemm
509c2aa98e2SPeter Wemm# work time factor
51006f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
511c2aa98e2SPeter Wemm
512c2aa98e2SPeter Wemm# default character set
513b6bacd31SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
514c2aa98e2SPeter Wemm
51540266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
51606f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
517c2aa98e2SPeter Wemm
518c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
51906f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
520c2aa98e2SPeter Wemm
521c2aa98e2SPeter Wemm# dialup line delay on connection failure
5224e4196cbSGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `0s')
523c2aa98e2SPeter Wemm
524c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
5254e4196cbSGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
526c2aa98e2SPeter Wemm
527c2aa98e2SPeter Wemm# chrooted environment for writing to files
5284e4196cbSGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
529c2aa98e2SPeter Wemm
530c2aa98e2SPeter Wemm# are colons OK in addresses?
53106f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
532c2aa98e2SPeter Wemm
533c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
53406f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
535c2aa98e2SPeter Wemm
536c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
53706f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
538c2aa98e2SPeter Wemm
539c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
54006f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
541c2aa98e2SPeter Wemm
542c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
54306f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
544c2aa98e2SPeter Wemm
545c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
54606f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
547c2aa98e2SPeter Wemm
548c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
54906f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
550c2aa98e2SPeter Wemm
551c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
55206f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
553c2aa98e2SPeter Wemm
554c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
55506f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
556c2aa98e2SPeter Wemm
557c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
55840266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
55906f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
56040266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
56140266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
56240266059SGregory Neil Shapiro')')
563c2aa98e2SPeter Wemm
564c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
56506f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
56606f25ae9SGregory Neil Shapiro
567d0cef73dSGregory Neil Shapiro# issue temporary errors (4xy) instead of permanent errors (5xy)?
568d0cef73dSGregory Neil Shapiro_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
569d0cef73dSGregory Neil Shapiro
57006f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
57106f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
572c2aa98e2SPeter Wemm
573c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
57406f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
575c2aa98e2SPeter Wemm
576c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
577e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
578c2aa98e2SPeter Wemm
57940266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
58040266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
581e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
58240266059SGregory Neil Shapiro
5839bd497b8SGregory Neil Shapiro
584c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
58506f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
586c2aa98e2SPeter Wemm
58706f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
58806f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
58906f25ae9SGregory Neil Shapiro
59006f25ae9SGregory Neil Shapiro# override connection address (for testing)
59106f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
59206f25ae9SGregory Neil Shapiro
59306f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
59406f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
59506f25ae9SGregory Neil Shapiro
59606f25ae9SGregory Neil Shapiro# Control socket for daemon management
59706f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
59806f25ae9SGregory Neil Shapiro
59906f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
600e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
60106f25ae9SGregory Neil Shapiro
60206f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
60306f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
60406f25ae9SGregory Neil Shapiro
60506f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
60606f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
60706f25ae9SGregory Neil Shapiro
60806f25ae9SGregory Neil Shapiro# location of pid file
60906f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
61006f25ae9SGregory Neil Shapiro
61106f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
61206f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
61306f25ae9SGregory Neil Shapiro
61406f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
61506f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
61606f25ae9SGregory Neil Shapiro
61706f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
61806f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
61906f25ae9SGregory Neil Shapiro
62040266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
62140266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
62240266059SGregory Neil Shapiro
623e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
624e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
625e92d3f3fSGregory Neil Shapiro
62606f25ae9SGregory Neil Shapiro# list of authentication mechanisms
62740266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
62806f25ae9SGregory Neil Shapiro
629e92d3f3fSGregory Neil Shapiro# Authentication realm
630e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
631e92d3f3fSGregory Neil Shapiro
63206f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
63306f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
63406f25ae9SGregory Neil Shapiro
63506f25ae9SGregory Neil Shapiro# SMTP AUTH flags
63606f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
63706f25ae9SGregory Neil Shapiro
63840266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
63940266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
64040266059SGregory Neil Shapiro
64140266059SGregory Neil Shapiro# SMTP STARTTLS server options
64240266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
64340266059SGregory Neil Shapiro
6449bd497b8SGregory Neil Shapiro
64506f25ae9SGregory Neil Shapiro# Input mail filters
64606f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
64706f25ae9SGregory Neil Shapiro
648739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
64906f25ae9SGregory Neil Shapiro# Milter options
65040266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
65106f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
65206f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
65306f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
654323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
655d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
656d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
657d0cef73dSGregory Neil Shapiro_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
65806f25ae9SGregory Neil Shapiro
65906f25ae9SGregory Neil Shapiro# CA directory
66013bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
66106f25ae9SGregory Neil Shapiro# CA file
66213bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
66306f25ae9SGregory Neil Shapiro# Server Cert
66406f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
66506f25ae9SGregory Neil Shapiro# Server private key
66606f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
66706f25ae9SGregory Neil Shapiro# Client Cert
66806f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
66906f25ae9SGregory Neil Shapiro# Client private key
67006f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
671e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
672e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
67306f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
67406f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
67506f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
67606f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
67706f25ae9SGregory Neil Shapiro
678d0cef73dSGregory Neil Shapiro# Maximum number of "useless" commands before slowing down
679d0cef73dSGregory Neil Shapiro_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
680d0cef73dSGregory Neil Shapiro
681d0cef73dSGregory Neil Shapiro# Name to use for EHLO (defaults to $j)
682d0cef73dSGregory Neil Shapiro_OPTION(HeloName, `confHELO_NAME')
683d0cef73dSGregory Neil Shapiro
68440266059SGregory Neil Shapiro############################
68540266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
68640266059SGregory Neil Shapiro############################
68740266059SGregory Neil Shapiro_QUEUE_GROUP_
688065a643dSPeter Wemm
689c2aa98e2SPeter Wemm###########################
690c2aa98e2SPeter Wemm#   Message precedences   #
691c2aa98e2SPeter Wemm###########################
692c2aa98e2SPeter Wemm
693c2aa98e2SPeter WemmPfirst-class=0
694c2aa98e2SPeter WemmPspecial-delivery=100
695c2aa98e2SPeter WemmPlist=-30
696c2aa98e2SPeter WemmPbulk=-60
697c2aa98e2SPeter WemmPjunk=-100
698c2aa98e2SPeter Wemm
699c2aa98e2SPeter Wemm#####################
700c2aa98e2SPeter Wemm#   Trusted users   #
701c2aa98e2SPeter Wemm#####################
702c2aa98e2SPeter Wemm
703c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
70406f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
705c2aa98e2SPeter WemmTroot
706c2aa98e2SPeter WemmTdaemon
707c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
708c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
709c2aa98e2SPeter Wemm
710c2aa98e2SPeter Wemm#########################
711c2aa98e2SPeter Wemm#   Format of headers   #
712c2aa98e2SPeter Wemm#########################
713c2aa98e2SPeter Wemm
714c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
715e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
716c2aa98e2SPeter WemmH?P?Return-Path: <$g>
717c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
718c2aa98e2SPeter WemmH?D?Resent-Date: $a
719c2aa98e2SPeter WemmH?D?Date: $a
720c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
721c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
722c2aa98e2SPeter WemmH?x?Full-Name: $x
723c2aa98e2SPeter Wemm# HPosted-Date: $a
724c2aa98e2SPeter Wemm# H?l?Received-Date: $b
725e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
726e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
72706f25ae9SGregory Neil Shapiro
728c2aa98e2SPeter Wemm#
729c2aa98e2SPeter Wemm######################################################################
730c2aa98e2SPeter Wemm######################################################################
731c2aa98e2SPeter Wemm#####
732c2aa98e2SPeter Wemm#####			REWRITING RULES
733c2aa98e2SPeter Wemm#####
734c2aa98e2SPeter Wemm######################################################################
735c2aa98e2SPeter Wemm######################################################################
736c2aa98e2SPeter Wemm
737c2aa98e2SPeter Wemm############################################
738c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
739c2aa98e2SPeter Wemm############################################
74006f25ae9SGregory Neil ShapiroScanonify=3
741c2aa98e2SPeter Wemm
742c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
743c2aa98e2SPeter WemmR$@			$@ <@>
744c2aa98e2SPeter Wemm
745c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
746c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
747c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
748c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
74940266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
750c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
751c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
752c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
753c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
754c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
755c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
756193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
757c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
758c2aa98e2SPeter Wemm
759c2aa98e2SPeter Wemm# null input now results from list:; syntax
760c2aa98e2SPeter WemmR$@			$@ :; <@>
761c2aa98e2SPeter Wemm
762c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
763c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
764c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
765c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
766c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
767c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
768c2aa98e2SPeter Wemm
76906f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
770c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
771c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
772c2aa98e2SPeter Wemm
773c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
77440266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
77540266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
77640266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
77706f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
77806f25ae9SGregory Neil Shapirodnl',`dnl
77906f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
78006f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
78140266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
78240266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
78306f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
78406f25ae9SGregory Neil Shapirodnl')
785c2aa98e2SPeter Wemm
786c2aa98e2SPeter Wemm# find focus for list syntax
78706f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
788c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
789c2aa98e2SPeter Wemm
790c2aa98e2SPeter Wemm# find focus for @ syntax addresses
791c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
792c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
79306f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
794c2aa98e2SPeter Wemm
79540266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
79640266059SGregory Neil Shapirodnl # do some sanity checking
79740266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
798c2aa98e2SPeter Wemm
799c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
800c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
80106f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
80206f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
80306f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
804c2aa98e2SPeter Wemm')
805c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
806c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
80706f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
80806f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
809c2aa98e2SPeter Wemm',
810c2aa98e2SPeter Wemm	`dnl')
811c2aa98e2SPeter Wemm# if we have % signs, take the rightmost one
812c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
813c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
81406f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
815c2aa98e2SPeter Wemm
816c2aa98e2SPeter Wemm# else we must be a local name
81706f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
818c2aa98e2SPeter Wemm
819c2aa98e2SPeter Wemm
820c2aa98e2SPeter Wemm################################################
821c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
822c2aa98e2SPeter Wemm################################################
823c2aa98e2SPeter Wemm
82406f25ae9SGregory Neil ShapiroSCanonify2=96
825c2aa98e2SPeter Wemm
826c2aa98e2SPeter Wemm# handle special cases for local names
827c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
828c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
829c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
830c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
83106f25ae9SGregory Neil Shapiro
83240266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
83340266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
834c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
835c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
836c2aa98e2SPeter Wemm
83706f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
838c2aa98e2SPeter Wemm# look up domains in the domain table
839c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
840c2aa98e2SPeter Wemm
84106f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
842c2aa98e2SPeter Wemm
84306f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
844c2aa98e2SPeter Wemm# handle BITNET mapping
845c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
846c2aa98e2SPeter Wemm
84706f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
848c2aa98e2SPeter Wemm# handle UUCP mapping
849c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
850c2aa98e2SPeter Wemm
851c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
852c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
853c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
854c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
855c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
856c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
857c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
858c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
859c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
860c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
861c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
862c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
863c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
864c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
865c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
866c2aa98e2SPeter Wemm
867c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
868c2aa98e2SPeter Wemm# try UUCP traffic as a local address
869c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
870c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
871c2aa98e2SPeter Wemm')')
87206f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
87306f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
87406f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
87506f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
87606f25ae9SGregory Neil Shapirodnl which daemon flags are set?
87706f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
87806f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
87906f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
88006f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
88106f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
88206f25ae9SGregory Neil Shapirodnl do not canonify unless:
88306f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
88406f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
88506f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
88606f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
88706f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
88806f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
88906f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
89006f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
89106f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
89206f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
89306f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
89406f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
89506f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
89606f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
89706f25ae9SGregory Neil Shapirodnl then $- does not work.
89806f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
89906f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
90006f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
90106f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
902193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
903193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
904193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
90506f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
90640266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
90740266059SGregory Neil Shapiro# do not canonify header addresses
90840266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
90940266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
91040266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
911c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
91206f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
91306f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
91406f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
915c2aa98e2SPeter Wemm
916c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
917c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
918c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
919c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
920c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
92106f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
92206f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
92306f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
92406f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
92506f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
92606f25ae9SGregory Neil Shapiro`dnl')
92740266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
92840266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
92940266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
93040266059SGregory Neil Shapiro`R$* < @ $* $=G > $* 	$: $1 < @ $2 $3 . > $4',
93140266059SGregory Neil Shapiro`R$* < @ $=G > $* 	$: $1 < @ $2 . > $3')',
93240266059SGregory Neil Shapiro`dnl')
93306f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
93406f25ae9SGregory Neil Shapirodnl by one of the rules before
935c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
936c2aa98e2SPeter Wemm
937c2aa98e2SPeter Wemm
938c2aa98e2SPeter Wemm##################################################
939c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
940c2aa98e2SPeter Wemm##################################################
94106f25ae9SGregory Neil ShapiroSfinal=4
942c2aa98e2SPeter Wemm
943193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
944c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
945c2aa98e2SPeter Wemm
946c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
947c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
948c2aa98e2SPeter Wemm
94906f25ae9SGregory Neil Shapiro# eliminate internal code
950c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
951c2aa98e2SPeter Wemm
952c2aa98e2SPeter Wemm# externalize local domain info
953c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
954c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
955c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
956c2aa98e2SPeter Wemm
957c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
958c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
959c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
960c2aa98e2SPeter Wemm
961c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
962c2aa98e2SPeter Wemm`# put DECnet back in :: form
963c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
964c2aa98e2SPeter Wemm	`dnl')
965c2aa98e2SPeter Wemm# delete duplicate local names
966c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
967c2aa98e2SPeter Wemm
968c2aa98e2SPeter Wemm
969c2aa98e2SPeter Wemm
970c2aa98e2SPeter Wemm##############################################################
971c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
972c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
973c2aa98e2SPeter Wemm##############################################################
974c2aa98e2SPeter Wemm
97506f25ae9SGregory Neil ShapiroSRecurse=97
97606f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
97706f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
978c2aa98e2SPeter Wemm
979c2aa98e2SPeter Wemm
980c2aa98e2SPeter Wemm######################################
981c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
982c2aa98e2SPeter Wemm######################################
983c2aa98e2SPeter Wemm
98406f25ae9SGregory Neil ShapiroSparse=0
985c2aa98e2SPeter Wemm
986c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
987c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
98806f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
989c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
990c2aa98e2SPeter Wemm
991c2aa98e2SPeter Wemm#
992c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
993c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
994c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
995c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
996c2aa98e2SPeter Wemm#
997c2aa98e2SPeter Wemm
998c2aa98e2SPeter WemmSParse0
999c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
100040266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
100106f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
100240266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
100340266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
1004c2aa98e2SPeter WemmR$*			$: <> $1
100540266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
100640266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
100740266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
100840266059SGregory Neil Shapirodnl but no a@[b]c
100940266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
1010c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
101140266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1012c2aa98e2SPeter WemmR<> $*			$1
101340266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
101440266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
101540266059SGregory Neil Shapirodnl no a@b@
101640266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
101740266059SGregory Neil Shapirodnl no a@b@c
101840266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
101906f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
102040266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
102140266059SGregory Neil Shapiro
102240266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
102340266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
102440266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
102540266059SGregory Neil Shapirodnl', `dnl')
1026c2aa98e2SPeter Wemm
1027c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
102806f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
102906f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1030c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
103140266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
103206f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1033c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
103440266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1035c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
103606f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1037c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1038c2aa98e2SPeter Wemm
1039c2aa98e2SPeter Wemm#
1040c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1041c2aa98e2SPeter Wemm#
1042c2aa98e2SPeter Wemm
1043c2aa98e2SPeter WemmSParse1
104406f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
104506f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
104640266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
104740266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1048c2aa98e2SPeter Wemm`dnl')
1049c2aa98e2SPeter Wemm
105006f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
105106f25ae9SGregory Neil Shapiro`# handle numeric address spec
105206f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
105306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
10545ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
105506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
105606f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
105706f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
105806f25ae9SGregory Neil Shapiro	`dnl')
105906f25ae9SGregory Neil Shapiro
106006f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1061c2aa98e2SPeter Wemm# handle virtual users
106240266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
106340266059SGregory Neil Shapirodnl this is not a documented option
106440266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
106540266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
106640266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
106740266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
106840266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
106940266059SGregory Neil ShapiroR$+ < @ $+ > 			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
107040266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
107140266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
107240266059SGregory Neil Shapiro`dnl')
107306f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
107440266059SGregory Neil Shapirodnl input: <!> local<@domain>
107506f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
107606f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
107706f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
107840266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
107906f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
108040266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
108140266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
108240266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
108340266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
108440266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1085c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
108640266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
108740266059SGregory Neil Shapirodnl user+detail: try user@domain
1088c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
108940266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
109006f25ae9SGregory Neil Shapirodnl try default entry: @domain
109140266059SGregory Neil Shapirodnl ++@domain
109240266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
109306f25ae9SGregory Neil Shapirodnl +*@domain
109440266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
109506f25ae9SGregory Neil Shapirodnl @domain if +detail exists
109694c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
109794c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
109894c01205SGregory Neil Shapirodnl without +detail
1099c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
110040266059SGregory Neil Shapirodnl no match
1101c2aa98e2SPeter WemmR<@> $+			$: $1
110240266059SGregory Neil Shapirodnl remove mark
110306f25ae9SGregory Neil ShapiroR<!> $+			$: $1
110406f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1105c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
110640266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
110740266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
110840266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
110940266059SGregory Neil Shapiro# it is the same: stop now
111040266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
111140266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $* 			$: < $1 > $2 < @ $3 >
111240266059SGregory Neil Shapirodnl', `dnl')
111313058a91SGregory Neil Shapirodnl this is not a documented option
111413058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11158774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11168774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11178774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11188774250cSGregory Neil Shapirodnl', `dnl')
1119c2aa98e2SPeter Wemm
1120c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1121c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
112206f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
112342e5d165SGregory Neil Shapiro
112442e5d165SGregory Neil Shapiro
1125c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1126c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
112706f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
112806f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1129c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1130c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1131c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1132c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1133c2aa98e2SPeter Wemm
113406f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1135c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1136c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1137c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1138c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
113906f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
114006f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
114106f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1142c2aa98e2SPeter Wemm`dnl')
114306f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1144c2aa98e2SPeter Wemm
1145c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1146c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1147c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
114806f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1149c2aa98e2SPeter Wemm	`dnl')
1150c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
115106f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1152c2aa98e2SPeter Wemm	`dnl')
1153c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
115406f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1155c2aa98e2SPeter Wemm	`dnl')')
1156c2aa98e2SPeter Wemm
1157c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1158c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
115906f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1160c2aa98e2SPeter Wemm	`dnl')
1161c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
116206f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1163c2aa98e2SPeter Wemm	`dnl')
1164c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1165c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1166c2aa98e2SPeter Wemm	`dnl')
1167c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1168c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1169c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
117006f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1171c2aa98e2SPeter Wemm	`dnl')')
1172c2aa98e2SPeter Wemm
1173c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1174c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
117506f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1176c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1177c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1178c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1179c2aa98e2SPeter Wemm	`dnl')')
1180c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1181c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
118206f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1183c2aa98e2SPeter Wemm	`dnl')
1184c2aa98e2SPeter Wemm
1185c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1186c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1187c2aa98e2SPeter Wemmundivert(1)', `dnl')
1188c2aa98e2SPeter Wemm
1189c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
119006f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1191c2aa98e2SPeter Wemm
1192c2aa98e2SPeter Wemm# deal with other remote names
1193c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1194c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
119540266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1196c2aa98e2SPeter Wemm
1197c2aa98e2SPeter Wemm# handle locally delivered names
1198c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1199c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1200c2aa98e2SPeter Wemm
1201c2aa98e2SPeter Wemm###########################################################################
1202c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1203c2aa98e2SPeter Wemm###########################################################################
1204c2aa98e2SPeter Wemm
120506f25ae9SGregory Neil ShapiroSLocal_localaddr
120606f25ae9SGregory Neil ShapiroSlocaladdr=5
120706f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
120840266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
120906f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
121006f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1211c2aa98e2SPeter Wemm
121240266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
121340266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
121440266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
121540266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
121640266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
121740266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12186a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
121940266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
122040266059SGregory Neil Shapiro')dnl
122140266059SGregory Neil Shapiro
122240266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
122342e5d165SGregory Neil Shapiro# Preserve host in a macro
122442e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
122542e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1226c2aa98e2SPeter Wemm
122740266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
122842e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
122942e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
123042e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
123142e5d165SGregory Neil Shapiro')
1232c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1233c2aa98e2SPeter WemmR$+			$: <> $1
1234c2aa98e2SPeter Wemm
1235c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1236c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
123740266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
123842e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
123942e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
124042e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
124142e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
124206f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
124340266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
124440266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
124540266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
124640266059SGregory Neil Shapirodnl')
1247c2aa98e2SPeter Wemm
124840266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
124940266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
125040266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
125140266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
125240266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
125340266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
125406f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
125540266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
125640266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
125706f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
125806f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1259c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
126042e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1261c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
12622e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
126340266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
126440266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
12652e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
126642e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
126706f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
126806f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
126940266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
127040266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
127140266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
127240266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
127340266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
127440266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
127506f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1276c2aa98e2SPeter Wemm
127706f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
127840266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
127940266059SGregory Neil Shapiro###################################################################
128040266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
128140266059SGregory Neil Shapirodnl input: <Domain> FullAddress
128240266059SGregory Neil Shapiro###################################################################
128340266059SGregory Neil Shapiro
128440266059SGregory Neil ShapiroSLDAPMailertable
128540266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
128640266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
128740266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
128840266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
128940266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
129040266059SGregory Neil Shapiro`dnl')
129140266059SGregory Neil Shapiro
1292c2aa98e2SPeter Wemm###################################################################
1293c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
129406f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1295c2aa98e2SPeter Wemm###################################################################
1296c2aa98e2SPeter Wemm
129706f25ae9SGregory Neil ShapiroSMailertable=90
129806f25ae9SGregory Neil Shapirodnl shift and check
129906f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1300c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
130106f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
130206f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
130306f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
130406f25ae9SGregory Neil Shapirodnl is $2 always empty?
1305c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
130606f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
130706f25ae9SGregory Neil Shapirodnl return full address
1308c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1309c2aa98e2SPeter Wemm`dnl')
1310c2aa98e2SPeter Wemm
1311c2aa98e2SPeter Wemm###################################################################
1312c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
131306f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
131406f25ae9SGregory Neil Shapirodnl	<> address				-> address
131506f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1316a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
131706f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
131806f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
131906f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
132006f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
132106f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1322c2aa98e2SPeter Wemm###################################################################
1323c2aa98e2SPeter Wemm
132406f25ae9SGregory Neil ShapiroSMailerToTriple=95
1325c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
132606f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1327a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1328a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1329c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
133040266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
133140266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
133240266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1333c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1334c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1335c2aa98e2SPeter Wemm
1336c2aa98e2SPeter Wemm###################################################################
1337c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
133806f25ae9SGregory Neil Shapirodnl input: <user> address
133906f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
134006f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
134106f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
134206f25ae9SGregory Neil Shapirodnl <> user				-> local user user
134306f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
134406f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
134506f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1346c2aa98e2SPeter Wemm###################################################################
1347c2aa98e2SPeter Wemm
1348c2aa98e2SPeter WemmSCanonLocal
13492e43090eSPeter Wemm# strip local host from routed addresses
135006f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
135106f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
13522e43090eSPeter Wemm
1353c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1354c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1355c2aa98e2SPeter Wemm
1356c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1357c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1358c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1359c2aa98e2SPeter Wemm
1360c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1361c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1362c2aa98e2SPeter Wemm
1363c2aa98e2SPeter Wemm# handle local:user syntax
1364c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1365c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1366c2aa98e2SPeter Wemm
1367c2aa98e2SPeter Wemm###################################################################
1368c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1369c2aa98e2SPeter Wemm###################################################################
1370c2aa98e2SPeter Wemm
137106f25ae9SGregory Neil ShapiroSMasqHdr=93
1372c2aa98e2SPeter Wemm
137306f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1374c2aa98e2SPeter Wemm# handle generics database
1375c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
137606f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1377c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1378c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1379c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
138006f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
138106f25ae9SGregory Neil Shapirodnl ignore the first case for now
138206f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
138340266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
138406f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
138506f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
138606f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
138706f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
138806f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
138906f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
139006f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
139106f25ae9SGregory Neil Shapirodnl no match, remove mark
139206f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
139306f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
139406f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
139506f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
139606f25ae9SGregory Neil Shapirodnl no match, try local part
1397c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
139806f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
139906f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
140006f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
140106f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1402c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1403c2aa98e2SPeter Wemm`dnl')
1404c2aa98e2SPeter Wemm
140506f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
140606f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
140706f25ae9SGregory Neil Shapiro
140840266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1409c2aa98e2SPeter Wemm# special case the users that should be exposed
1410c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1411c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1412c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1413c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1414c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1415c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1416c2aa98e2SPeter Wemm
1417c2aa98e2SPeter Wemm# handle domain-specific masquerading
1418c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1419c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1420c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1421c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1422c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1423c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1424c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1425c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
142640266059SGregory Neil Shapirodnl', `dnl no masquerading
142740266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
142840266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1429c2aa98e2SPeter Wemm
1430c2aa98e2SPeter Wemm###################################################################
1431c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1432c2aa98e2SPeter Wemm###################################################################
1433c2aa98e2SPeter Wemm
143406f25ae9SGregory Neil ShapiroSMasqEnv=94
1435c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
143606f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1437c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1438c2aa98e2SPeter Wemm
1439c2aa98e2SPeter Wemm###################################################################
1440c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1441c2aa98e2SPeter Wemm###################################################################
1442c2aa98e2SPeter Wemm
144306f25ae9SGregory Neil ShapiroSParseLocal=98
144406f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1445c2aa98e2SPeter Wemm
144606f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
144740266059SGregory Neil Shapiro######################################################################
144840266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
144940266059SGregory Neil Shapiro###
145040266059SGregory Neil Shapiro###	Parameters:
145140266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
145240266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
145340266059SGregory Neil Shapiro###		<$3> -- +detail information
145440266059SGregory Neil Shapiro###
145540266059SGregory Neil Shapiro###	Returns:
145640266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
145740266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
145840266059SGregory Neil Shapiro######################################################################
145940266059SGregory Neil Shapiro
1460e92d3f3fSGregory Neil Shapiro# SMTP operation modes
1461e92d3f3fSGregory Neil ShapiroC{SMTPOpModes} s d D
1462e92d3f3fSGregory Neil Shapiro
146306f25ae9SGregory Neil ShapiroSLDAPExpand
146406f25ae9SGregory Neil Shapiro# do the LDAP lookups
146540266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
146606f25ae9SGregory Neil Shapiro
1467e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1468e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1469e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1470e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1471e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
1472e92d3f3fSGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."')
1473e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1474e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1475605302a5SGregory Neil Shapiro
147606f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
147706f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
147840266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
147940266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
148040266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
148140266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
148240266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
148306f25ae9SGregory Neil Shapiro
148494c01205SGregory Neil Shapiro
148506f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
148606f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
148740266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
148840266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
148940266059SGregory Neil Shapiro# check mailertable for host, relay from there
149040266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
149140266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
149240266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
149340266059SGregory Neil Shapiro# check mailertable for host, relay from there
149440266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
149540266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
149606f25ae9SGregory Neil Shapiro
149706f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
149806f25ae9SGregory Neil Shapiro# return original address
149940266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
150006f25ae9SGregory Neil Shapiro
150194c01205SGregory Neil Shapiro
150206f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
150306f25ae9SGregory Neil Shapiro# relay to mailHost with original address
150440266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
150540266059SGregory Neil Shapiro# check mailertable for host, relay from there
150640266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
150740266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
150806f25ae9SGregory Neil Shapiro
150940266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
151040266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
151140266059SGregory Neil Shapiro# try without +detail
151240266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
151340266059SGregory Neil Shapiro
15149bd497b8SGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `
15159bd497b8SGregory Neil Shapiro# pretend we did the @domain lookup
15169bd497b8SGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
151740266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
151806f25ae9SGregory Neil Shapiro# try @domain
151940266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
152040266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1521e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
152206f25ae9SGregory Neil Shapiro
152306f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
152406f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
152506f25ae9SGregory Neil Shapiro# user does not exist
152640266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
152740266059SGregory Neil Shapiro# only give error for envelope recipient
152840266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1529e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1530e92d3f3fSGregory Neil Shapiro# and the sender too
1531e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
153240266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
153306f25ae9SGregory Neil Shapiro`dnl
153406f25ae9SGregory Neil Shapiro# return the original address
1535ba00ec3dSGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')
1536ba00ec3dSGregory Neil Shapiro')
1537ba00ec3dSGregory Neil Shapiro
153806f25ae9SGregory Neil Shapiro
153906f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
154006f25ae9SGregory Neil Shapiro')')
154140266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1542c2aa98e2SPeter Wemm######################################################################
154340266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1544c2aa98e2SPeter Wemm###
1545c2aa98e2SPeter Wemm###	Parameters:
1546c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1547c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
154806f25ae9SGregory Neil Shapirodnl			must not be empty
154940266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
155006f25ae9SGregory Neil Shapiro###			! does lookup only with tag
155106f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
155240266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
155306f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
155406f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1555c2aa98e2SPeter Wemm######################################################################
1556c2aa98e2SPeter Wemm
155740266059SGregory Neil ShapiroSD
155806f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
155906f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
156040266059SGregory Neil Shapirodnl    2    3  4    5
156140266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
156206f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
156306f25ae9SGregory Neil Shapirodnl lookup without tag?
156440266059SGregory Neil Shapirodnl   1    2      3    4
156540266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
156640266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
156740266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
156840266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
156940266059SGregory Neil Shapirodnl   1  2    3    4  5    6
157040266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
157140266059SGregory Neil Shapirodnl   1  2    3      4    5
157240266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
157340266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
157440266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
157540266059SGregory Neil Shapirodnl      1    2    3  4    5
157640266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
157740266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
157840266059SGregory Neil Shapirodnl    1  2     3    4  5    6
157940266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
158040266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
158140266059SGregory Neil Shapiro`dnl not found: IPv6 net
158240266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
158340266059SGregory Neil Shapirodnl    1   2     3    4  5    6
158440266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
158540266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
158606f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
158740266059SGregory Neil Shapirodnl   1  2    3    4  5    6
158840266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
158940266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
159040266059SGregory Neil Shapirodnl   1    2      3    4
159140266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
159240266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
159340266059SGregory Neil Shapirodnl   1    2    3  4    5
159440266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
159540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
159640266059SGregory Neil Shapirodnl            2    3    4  5    6
159740266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
159840266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
159940266059SGregory Neil Shapirodnl    2    3    4  5    6
160040266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1601c2aa98e2SPeter Wemm
1602c2aa98e2SPeter Wemm######################################################################
160340266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1604c2aa98e2SPeter Wemm###
1605c2aa98e2SPeter Wemm###	Parameters:
1606c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1607c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
160806f25ae9SGregory Neil Shapirodnl			must not be empty
160940266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
161006f25ae9SGregory Neil Shapiro###			! does lookup only with tag
161106f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
161240266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
161306f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
161406f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1615c2aa98e2SPeter Wemm######################################################################
1616c2aa98e2SPeter Wemm
161740266059SGregory Neil ShapiroSA
161806f25ae9SGregory Neil Shapirodnl lookup with tag
161940266059SGregory Neil Shapirodnl    2    3  4    5
162040266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
162106f25ae9SGregory Neil Shapirodnl lookup without tag
162240266059SGregory Neil Shapirodnl   1    2      3    4
162340266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
162440266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
162540266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
162640266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
162740266059SGregory Neil Shapirodnl      1    2    3  4    5
162840266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
162940266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
163040266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
163140266059SGregory Neil Shapirodnl   1   2    3    4  5    6
163240266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
163340266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
163406f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
163540266059SGregory Neil Shapirodnl   1  2    3    4  5    6
163640266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
163706f25ae9SGregory Neil Shapirodnl no match: return default
163840266059SGregory Neil Shapirodnl   1    2    3  4    5
163940266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
164040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
164140266059SGregory Neil Shapirodnl            2    3    4  5    6
164240266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
164306f25ae9SGregory Neil Shapirodnl match: return result
164440266059SGregory Neil Shapirodnl    2    3    4  5    6
164540266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
164640266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
164740266059SGregory Neil Shapirodivert(0)
1648c2aa98e2SPeter Wemm######################################################################
1649065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1650065a643dSPeter Wemm###			relay checking.  Route address syntax is
1651065a643dSPeter Wemm###			crudely converted into a %-hack address.
1652065a643dSPeter Wemm###
1653065a643dSPeter Wemm###	Parameters:
1654065a643dSPeter Wemm###		$1 -- full recipient address
1655065a643dSPeter Wemm###
1656065a643dSPeter Wemm###	Returns:
1657065a643dSPeter Wemm###		parsed address, not in source route form
165806f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
165906f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1660065a643dSPeter Wemm######################################################################
1661065a643dSPeter Wemm
1662065a643dSPeter WemmSCanonAddr
166306f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
166406f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1665065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1666065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1667065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
166806f25ae9SGregory Neil Shapirodnl')
1669065a643dSPeter Wemm
1670065a643dSPeter Wemm######################################################################
1671c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1672c2aa98e2SPeter Wemm###			$* $=m or the access database.
1673c2aa98e2SPeter Wemm###			Check user portion for host separators.
1674c2aa98e2SPeter Wemm###
1675c2aa98e2SPeter Wemm###	Parameters:
1676c2aa98e2SPeter Wemm###		$1 -- full recipient address
1677c2aa98e2SPeter Wemm###
1678c2aa98e2SPeter Wemm###	Returns:
1679c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1680c2aa98e2SPeter Wemm######################################################################
1681c2aa98e2SPeter Wemm
1682c2aa98e2SPeter WemmSParseRecipient
168306f25ae9SGregory Neil Shapirodnl mark and canonify address
1684065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
168506f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1686c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
168706f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1688c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1689c2aa98e2SPeter Wemm
1690c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1691c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
169206f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1693c2aa98e2SPeter WemmR<?> $*				$@ $1
1694c2aa98e2SPeter Wemm
169540266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
169606f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1697c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1698c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1699c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
170006f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
170106f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
170240266059SGregory Neil Shapiro
170340266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
170440266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
170540266059SGregory Neil Shapirodnl other To: entries: blacklist recipient; generic entries?
170640266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1707c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1708c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
170906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
171006f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1711065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1712c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
171306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
171440266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1715c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1716065a643dSPeter Wemm
171706f25ae9SGregory Neil Shapiro
171840266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
171940266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
172040266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1721e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
172240266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
172340266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
172440266059SGregory Neil Shapirodnl no: put old <NO> mark back
172540266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
172640266059SGregory Neil Shapiro
172740266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1728c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
172940266059SGregory Neil Shapirodnl something else
173040266059SGregory Neil ShapiroR<$+> $*			$@ $2
1731c2aa98e2SPeter Wemm
173206f25ae9SGregory Neil Shapiro
1733c2aa98e2SPeter Wemm######################################################################
1734c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1735c2aa98e2SPeter Wemm######################################################################
1736c2aa98e2SPeter Wemm
1737e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1738e92d3f3fSGregory Neil ShapiroScheck_relay
1739e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1740e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1741e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1742e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1743e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1744e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1745e92d3f3fSGregory Neil Shapirodnl')
1746e92d3f3fSGregory Neil Shapiro
1747c2aa98e2SPeter WemmSLocal_check_relay
174806f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1749e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1750e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1751c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1752c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1753c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1754c2aa98e2SPeter Wemm
1755c2aa98e2SPeter WemmSBasic_check_relay
1756c2aa98e2SPeter Wemm# check for deferred delivery mode
175794c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1758c2aa98e2SPeter WemmR< d > $*		$@ deferred
1759c2aa98e2SPeter WemmR< $* > $*		$: $2
1760c2aa98e2SPeter Wemm
176106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
176242e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
176340266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
176442e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
176513bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
176613bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
176713bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
176840266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
176940266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
177040266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
177140266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
177242e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1773e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
177440266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1775e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
177606f25ae9SGregory Neil Shapirodnl error tag
177742e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
177842e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
177940266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
178006f25ae9SGregory Neil Shapirodnl generic error from access map
178142e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1782c2aa98e2SPeter Wemm
1783c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
178406f25ae9SGregory Neil Shapiro# DNS based IP address spam list
178540266059SGregory Neil Shapirodnl workspace: ignored...
1786c2aa98e2SPeter WemmR$*			$: $&{client_addr}
178706f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
178806f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
178994c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1790c2aa98e2SPeter Wemm`dnl')
1791e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1792e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1793e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1794e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1795e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1796e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1797e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1798e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
17996f9c8e5bSGregory Neil Shapiroundivert(8)dnl LOCAL_DNSBL
1800d0cef73dSGregory Neil Shapiroifdef(`_REQUIRE_RDNS_', `dnl
1801d0cef73dSGregory Neil ShapiroR$*			$: $&{client_addr} $| $&{client_resolve}
1802d0cef73dSGregory Neil ShapiroR$=R $*			$@ RELAY		We relay for these
1803d0cef73dSGregory Neil ShapiroR$* $| OK		$@ OK			Resolves.
1804d0cef73dSGregory Neil ShapiroR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1805d0cef73dSGregory Neil ShapiroR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1806d0cef73dSGregory Neil ShapiroR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1807d0cef73dSGregory Neil Shapiro', `dnl')
1808c2aa98e2SPeter Wemm
1809c2aa98e2SPeter Wemm######################################################################
1810c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1811c2aa98e2SPeter Wemm######################################################################
1812c2aa98e2SPeter Wemm
1813c2aa98e2SPeter WemmSLocal_check_mail
181406f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1815c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1816c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1817c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1818c2aa98e2SPeter Wemm
1819c2aa98e2SPeter WemmSBasic_check_mail
1820c2aa98e2SPeter Wemm# check for deferred delivery mode
182194c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1822c2aa98e2SPeter WemmR< d > $*		$@ deferred
1823c2aa98e2SPeter WemmR< $* > $*		$: $2
1824c2aa98e2SPeter Wemm
182506f25ae9SGregory Neil Shapiro# authenticated?
182606f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
182706f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
182806f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
182906f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
183006f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
183106f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
183206f25ae9SGregory Neil Shapiro
183306f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
183406f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
183506f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
183606f25ae9SGregory Neil Shapirodnl do some additional checks
183706f25ae9SGregory Neil Shapirodnl no user@host
183806f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
183906f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
184006f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
184106f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
184206f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
184306f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
184406f25ae9SGregory Neil ShapiroR$+			$: <?> $1
184506f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
184606f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
184706f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
184806f25ae9SGregory Neil Shapirodnl prepend daemon_flags
184906f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
185006f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
185106f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
185206f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
185306f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
185406f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
185506f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
185606f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
185706f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
185806f25ae9SGregory Neil Shapirodnl remove daemon_flags
185906f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
186006f25ae9SGregory Neil Shapiro# handle case of @localhost on address
186106f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
186206f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
186306f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
186406f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
186506f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
186606f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
186706f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
186806f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
186906f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
187006f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
187106f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
187206f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
187306f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
187406f25ae9SGregory Neil Shapirodnl	or:    <address>
187506f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
187606f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
187740266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
187806f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
187906f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
188006f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
188106f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
188206f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
188306f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1884065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1885c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1886959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
188706f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
188894c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1889959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1890c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
189140266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
189206f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
189306f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
189406f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
189540266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
189606f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1897c2aa98e2SPeter Wemm
189806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
189906f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
190006f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
190140266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
190240266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
190306f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
190406f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
190506f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
190606f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
190706f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
190806f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
190906f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
191006f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1911c2aa98e2SPeter Wemm# retransform for further use
191206f25ae9SGregory Neil Shapirodnl required form:
191306f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
191406f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
191506f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
191606f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
191706f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1918c2aa98e2SPeter Wemm
1919c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1920c2aa98e2SPeter Wemm# handle case of no @domain on address
192106f25ae9SGregory Neil Shapirodnl prepend daemon_flags
192206f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
192306f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
192440266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
192506f25ae9SGregory Neil Shapirodnl remove daemon_flags
192606f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
192713bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1928959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
192940266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1930c2aa98e2SPeter Wemm							...remote is not')
1931c2aa98e2SPeter Wemm# check results
193206f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
1933d0cef73dSGregory Neil ShapiroR<$={ResOk}> $*		$: @ $2		domain ok
193406f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
193540266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
193606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
193740266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1938c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
1939e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
1940e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
194106f25ae9SGregory Neil Shapirodnl error tag
194206f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
194306f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
194440266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
194506f25ae9SGregory Neil Shapirodnl generic error from access map
194606f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1947c2aa98e2SPeter Wemm`dnl')
1948d0cef73dSGregory Neil Shapirodnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
1949d0cef73dSGregory Neil Shapiro
1950d0cef73dSGregory Neil Shapiroifdef(`_BADMX_CHK_', `dnl
1951d0cef73dSGregory Neil ShapiroR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
1952d0cef73dSGregory Neil ShapiroR$* $| $#$*		$#$2
1953d0cef73dSGregory Neil Shapiro
1954d0cef73dSGregory Neil ShapiroSBadMX
1955d0cef73dSGregory Neil Shapiro# Look up MX records and ferret away a copy of the original address.
1956d0cef73dSGregory Neil Shapiro# input: domain part of address to check
1957d0cef73dSGregory Neil ShapiroR$+				$:<MX><$1><:$(mxlist $1$):><:>
1958d0cef73dSGregory Neil Shapiro# workspace: <MX><domain><: mxlist-result $><:>
1959d0cef73dSGregory Neil ShapiroR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
1960d0cef73dSGregory Neil Shapiro# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
1961d0cef73dSGregory Neil Shapiro# Recursively run badmx check on each mx.
1962d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
1963d0cef73dSGregory Neil Shapiro# See if any of them fail.
1964e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
1965d0cef73dSGregory Neil Shapiro# Reverse the mxlists so we can use the same argument order again.
1966d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
1967d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
1968d0cef73dSGregory Neil Shapiro
1969d0cef73dSGregory Neil Shapiro# Reverse the lists so we can use the same argument order again.
1970d0cef73dSGregory Neil ShapiroR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
1971d0cef73dSGregory Neil ShapiroR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
1972d0cef73dSGregory Neil Shapiro
1973e3793f76SGregory Neil ShapiroR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
1974d0cef73dSGregory Neil Shapiro`dnl')
1975d0cef73dSGregory Neil Shapiro
1976c2aa98e2SPeter Wemm
1977c2aa98e2SPeter Wemm######################################################################
1978c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
1979c2aa98e2SPeter Wemm######################################################################
1980c2aa98e2SPeter Wemm
1981c2aa98e2SPeter WemmSLocal_check_rcpt
198206f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
1983c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
1984c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1985c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
1986c2aa98e2SPeter Wemm
1987c2aa98e2SPeter WemmSBasic_check_rcpt
198840266059SGregory Neil Shapiro# empty address?
198940266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
199040266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
1991c2aa98e2SPeter Wemm# check for deferred delivery mode
199294c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1993c2aa98e2SPeter WemmR< d > $*		$@ deferred
1994c2aa98e2SPeter WemmR< $* > $*		$: $2
1995c2aa98e2SPeter Wemm
199606f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
199740266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
199840266059SGregory Neil Shapirodnl it is not activated.
199940266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
200040266059SGregory Neil Shapirodnl available down below; look for the same macro.
200140266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
200240266059SGregory Neil Shapirodnl canonicalization.
200340266059SGregory Neil Shapiro# require fully qualified domain part?
200440266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
200506f25ae9SGregory Neil ShapiroR$+			$: <?> $1
200606f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
200706f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
200840266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
200913bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
201006f25ae9SGregory Neil Shapirodnl prepend daemon_flags
201140266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
201206f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
2013af9557fdSGregory Neil Shapirodnl _r_equire qual.rcpt: ok
2014a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
201506f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
2016a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
201706f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
201806f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
201940266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
202006f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
202106f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
202206f25ae9SGregory Neil Shapiro
202340266059SGregory Neil Shapirodnl ##################################################################
202440266059SGregory Neil Shapirodnl call subroutines for recipient and relay
202540266059SGregory Neil Shapirodnl possible returns from subroutines:
202640266059SGregory Neil Shapirodnl $#TEMP	temporary failure
202740266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
202840266059SGregory Neil Shapirodnl $#other	stop processing
202940266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
203040266059SGregory Neil Shapirodnl other	otherwise
203140266059SGregory Neil Shapiro######################################################################
203240266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
203340266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
203440266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
203540266059SGregory Neil Shapirodnl error or ok (stop)
203640266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
203740266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
203840266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
203940266059SGregory Neil Shapirodnl something else: call check sender (relay)
204040266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
204140266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
204240266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
204340266059SGregory Neil Shapirodnl temporary failure? return that
204440266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
204540266059SGregory Neil Shapirodnl error or ok (stop)
204640266059SGregory Neil ShapiroR$* $| $#$*		$#$2
204740266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
204840266059SGregory Neil Shapirodnl something else: return previous temp failure
204940266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
205040266059SGregory Neil Shapiro# anything else is bogus
205140266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
205240266059SGregory Neil Shapirodivert(0)
205340266059SGregory Neil Shapiro
205440266059SGregory Neil Shapiro######################################################################
205540266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
205640266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
205740266059SGregory Neil Shapirodnl output: see explanation at call
205840266059SGregory Neil Shapiro######################################################################
205940266059SGregory Neil ShapiroSRcpt_ok
2060c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2061065a643dSPeter WemmR$*			$: $>CanonAddr $1
2062c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2063c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2064c2aa98e2SPeter Wemm
2065065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2066065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2067065a643dSPeter Wemm# unlimited bestmx
2068065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2069065a643dSPeter Wemm`dnl
2070065a643dSPeter Wemm# limit bestmx to $=B
20712e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
207240266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2073065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2074065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2075065a643dSPeter Wemm
2076c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
207706f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2078c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
2079c2aa98e2SPeter WemmR$*			$: <?> $1
208006f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
208106f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
208240266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
208340266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
208406f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
208506f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
208606f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
208706f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
208806f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
208906f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
209040266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
209140266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
209240266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
209340266059SGregory Neil Shapirodnl that would make a lot of things easier.
209406f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
209540266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
209640266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
209740266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
209840266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
209906f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
210006f25ae9SGregory Neil Shapirodnl as generic error message...
210106f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
210206f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
210306f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
210406f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
210540266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
210606f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2107e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
210806f25ae9SGregory Neil Shapirodnl error tag
210906f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
211006f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
211140266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
211206f25ae9SGregory Neil Shapirodnl generic error from access map
211306f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
211406f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2115c2aa98e2SPeter Wemm
211640266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
211740266059SGregory Neil Shapiro# authenticated via TLS?
211840266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
211906f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
212006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
212106f25ae9SGregory Neil Shapiro
212240266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
212340266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
212440266059SGregory Neil ShapiroR$* $| $# $*		$# $2
212540266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
212640266059SGregory Neil ShapiroR$* $| NO		$: $1
212740266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
212840266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
212906f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
213006f25ae9SGregory Neil ShapiroR$* $|			$: $1
213106f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
213206f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
213340266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
213440266059SGregory Neil Shapirodnl remove ${auth_type}
213506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2136193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
213706f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2138193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2139193538b7SGregory Neil ShapiroR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2140c2aa98e2SPeter Wemm# anything terminating locally is ok
2141c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
214240266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
214340266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2144c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
214540266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
214606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
21479bd497b8SGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
21489bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
21499bd497b8SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
21509bd497b8SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
215106f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
215206f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
215340266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
215406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2155e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2156e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2157e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2158e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2159e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
216006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
216106f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
216240266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
216340266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2164c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2165c2aa98e2SPeter Wemm
216606f25ae9SGregory Neil Shapiro
2167c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2168c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
216906f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
217006f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2171e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
217240266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2173065a643dSPeter WemmR< : $* : > $*		$: $2',
2174c2aa98e2SPeter Wemm`dnl')
2175c2aa98e2SPeter Wemm
2176c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2177c2aa98e2SPeter WemmR$*			$: <?> $1
2178065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2179c2aa98e2SPeter Wemm# local user is ok
218006f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
218106f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
218206f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
218306f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
218406f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
218540266059SGregory Neil ShapiroR<?> postmaster		$@ OK
218606f25ae9SGregory Neil Shapiro# require qualified recipient?
218706f25ae9SGregory Neil Shapirodnl prepend daemon_flags
218806f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
218906f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
219006f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
219106f25ae9SGregory Neil Shapirodnl r flag? add client_name
219206f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
219306f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
219406f25ae9SGregory Neil Shapiro# no qualified recipient required
219540266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
219606f25ae9SGregory Neil Shapirodnl client_name is empty
219740266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
219806f25ae9SGregory Neil Shapirodnl client_name is local
219940266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
220006f25ae9SGregory Neil Shapirodnl client_name is not local
220106f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
220206f25ae9SGregory Neil Shapirodnl no qualified recipient required
220340266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
220406f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2205c2aa98e2SPeter WemmR<$+> $*		$: $2
220606f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2207c2aa98e2SPeter Wemm
220840266059SGregory Neil Shapiro######################################################################
220940266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
221040266059SGregory Neil Shapirodnl input: ignored
221140266059SGregory Neil Shapirodnl output: see explanation at call
221240266059SGregory Neil Shapiro######################################################################
221340266059SGregory Neil ShapiroSRelay_ok
2214c2aa98e2SPeter Wemm# anything originating locally is ok
2215c2aa98e2SPeter Wemm# check IP address
2216c2aa98e2SPeter WemmR$*			$: $&{client_addr}
221740266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
221840266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
221913bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
222013bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
222140266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
222206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
222340266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
222440266059SGregory Neil ShapiroR<RELAY> $* 		$@ RELAY		relayable IP address
2225959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2226959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2227959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2228959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2229959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2230959366dcSGregory Neil ShapiroR<REJECT> $* 		$@ REJECT		rejected IP address')
223140266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2232c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2233c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
223440266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2235c2aa98e2SPeter Wemm
223606f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
223706f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
223806f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
223906f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
224006f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
224106f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
224206f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
224340266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2244c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
224506f25ae9SGregory Neil Shapiro# check whether local FROM is ok
224640266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
224706f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2248605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
224940266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
225040266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
225140266059SGregory Neil Shapiro', `dnl
225240266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
225340266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
225406f25ae9SGregory Neil Shapiro')',
225506f25ae9SGregory Neil Shapiro`dnl')
225606f25ae9SGregory Neil Shapirodnl')', `dnl')
225740266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
225840266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
225940266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
226006f25ae9SGregory Neil Shapiro
226106f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
226206f25ae9SGregory Neil Shapirodnl input: ignored
226306f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2264e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
226506f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
226606f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
226706f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
226840266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
226906f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
227013bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
227113bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
227213bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
227313bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
227413bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
227540266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
227640266059SGregory Neil Shapiro# pass to name server to make hostname canonical
227740266059SGregory Neil ShapiroR<@> $* $=P 		$:<?>  $1 $2
227840266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
227940266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
228040266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
228106f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
228240266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
228340266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
228406f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
228540266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
228606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
228706f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
228806f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
228940266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
229006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
229140266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
229206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
229340266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
229440266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
229506f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
229640266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
229706f25ae9SGregory Neil Shapirodivert(0)
229806f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
229906f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
230006f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
230106f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
230206f25ae9SGregory Neil ShapiroSFullAddr
230306f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
230406f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
230506f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2306c2aa98e2SPeter Wemm
2307a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
230813bd1963SGregory Neil Shapiro# authenticated?
230913bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
231013bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
231113bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
231213bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
231313bd1963SGregory Neil Shapirodnl return result from checkrcpt
2314a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
231513bd1963SGregory Neil ShapiroR$*			$# $1
231613bd1963SGregory Neil Shapiro
2317a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
231813bd1963SGregory Neil Shapiro# authenticated?
231913bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
232013bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
232113bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
232213bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
232313bd1963SGregory Neil Shapirodnl return result from friend/hater check
2324a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
232513bd1963SGregory Neil ShapiroR$*			$@ $1
232613bd1963SGregory Neil Shapiro
232706f25ae9SGregory Neil Shapiro# call all necessary rulesets
232806f25ae9SGregory Neil ShapiroScheck_rcpt
232906f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
233006f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
233106f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
233213bd1963SGregory Neil Shapiro
233306f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
233406f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
233513bd1963SGregory Neil Shapirodnl on error (or discard) stop now
233613bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
233713bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
233813bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2339a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
234006f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
234106f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
234206f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
234306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
234406f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
234506f25ae9SGregory Neil Shapiro')')dnl
234606f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
234706f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
234806f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
234940266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
235040266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
235106f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
235240266059SGregory Neil Shapiro# lookup the addresses only with Spam tag
235340266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
235406f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
235506f25ae9SGregory Neil Shapirodnl', `dnl')
235606f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
235706f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
235806f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
235913bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
236006f25ae9SGregory Neil Shapiro')', `dnl')
2361a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
236206f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
236306f25ae9SGregory Neil Shapiro`dnl')
236406f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
236506f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
236640266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2367a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
236806f25ae9SGregory Neil Shapirodnl',`dnl')
2369d0cef73dSGregory Neil Shapiro
237006f25ae9SGregory Neil Shapirodnl run further checks: check_mail
237106f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
237240266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
237340266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
237440266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2375605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
237606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
237706f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2378605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
237906f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
238006f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
238106f25ae9SGregory Neil Shapiro', `dnl')
238240266059SGregory Neil Shapiro
2383d0cef73dSGregory Neil Shapiroifdef(`_BLOCK_BAD_HELO_', `dnl
2384d0cef73dSGregory Neil ShapiroR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2385d0cef73dSGregory Neil Shapirodnl Bypass the test for users who have authenticated.
2386d0cef73dSGregory Neil ShapiroR$* $| <$+>		$: $1				skip if auth
2387d0cef73dSGregory Neil ShapiroR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2388d0cef73dSGregory Neil Shapirodnl Bypass for local clients -- IP address starts with $=R
2389d0cef73dSGregory Neil ShapiroR$* $| <$=R $*> [$*]	$: $1				skip if local client
2390d0cef73dSGregory Neil Shapirodnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2391d0cef73dSGregory Neil ShapiroR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2392d0cef73dSGregory Neil Shapirodnl Reject our IP - assumes "[ip]" is in class $=w
2393d0cef73dSGregory Neil ShapiroR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2394d0cef73dSGregory Neil Shapirodnl Reject our hostname
2395d0cef73dSGregory Neil ShapiroR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2396d0cef73dSGregory Neil Shapirodnl Pass anything else with a "." in the domain parameter
2397d0cef73dSGregory Neil ShapiroR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
23985dd76dd0SGregory Neil Shapirodnl Pass IPv6: address literals
23995dd76dd0SGregory Neil ShapiroR$* $| <$*> [IPv6:$+]	$: $1				qualified domain ok
2400d0cef73dSGregory Neil Shapirodnl Reject if there was no "." or only an initial or final "."
2401d0cef73dSGregory Neil ShapiroR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2402d0cef73dSGregory Neil Shapirodnl Clean up the workspace
2403d0cef73dSGregory Neil ShapiroR$* $| $*		$: $1
2404d0cef73dSGregory Neil Shapiro', `dnl')
2405d0cef73dSGregory Neil Shapiro
240640266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
240740266059SGregory Neil Shapiro######################################################################
240840266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
240940266059SGregory Neil Shapiro###
241040266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
241140266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
241240266059SGregory Neil Shapiro###
241340266059SGregory Neil Shapiro###	Parameters:
241440266059SGregory Neil Shapiro###		<$1> -- key
241540266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
241640266059SGregory Neil Shapirodnl			must not be empty
241740266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
241840266059SGregory Neil Shapiro###			! does lookup only with tag
241940266059SGregory Neil Shapiro###			+ does lookup with and without tag
242040266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
242140266059SGregory Neil Shapirodnl returns:		<default> <passthru>
242240266059SGregory Neil Shapirodnl 			<result> <passthru>
242340266059SGregory Neil Shapiro######################################################################
242440266059SGregory Neil Shapiro
242540266059SGregory Neil ShapiroSF
242640266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
242740266059SGregory Neil Shapirodnl full lookup
242840266059SGregory Neil Shapirodnl    2    3  4    5
242940266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
243040266059SGregory Neil Shapirodnl no match, try without tag
243140266059SGregory Neil Shapirodnl   1    2      3    4
243240266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
243340266059SGregory Neil Shapirodnl no match, +detail: try +*
243440266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
243540266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
243640266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
243740266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
243840266059SGregory Neil Shapirodnl   1    2    3    4      5    6
243940266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
244040266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
244140266059SGregory Neil Shapirodnl no match, +detail: try without +detail
244240266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
244340266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
244440266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
244540266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
244640266059SGregory Neil Shapirodnl   1    2    3    4      5    6
244740266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
244840266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
244940266059SGregory Neil Shapirodnl no match, return <default> <passthru>
245040266059SGregory Neil Shapirodnl   1    2    3  4    5
245140266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
245240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
245340266059SGregory Neil Shapirodnl            2    3  4    5
245440266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
245540266059SGregory Neil Shapirodnl match, return <match> <passthru>
245640266059SGregory Neil Shapirodnl    2    3  4    5
245740266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
245840266059SGregory Neil Shapiro
245940266059SGregory Neil Shapiro######################################################################
246040266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
246140266059SGregory Neil Shapiro###
246240266059SGregory Neil Shapiro###	Parameters:
246340266059SGregory Neil Shapiro###		<$1> -- key
246440266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
246540266059SGregory Neil Shapirodnl			must not be empty
246640266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
246740266059SGregory Neil Shapiro###			! does lookup only with tag
246840266059SGregory Neil Shapiro###			+ does lookup with and without tag
246940266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
247040266059SGregory Neil Shapirodnl returns:		<default> <passthru>
247140266059SGregory Neil Shapirodnl 			<result> <passthru>
247240266059SGregory Neil Shapiro######################################################################
247340266059SGregory Neil Shapiro
247440266059SGregory Neil ShapiroSE
247540266059SGregory Neil Shapirodnl    2    3  4    5
247640266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
247740266059SGregory Neil Shapirodnl no match, try without tag
247840266059SGregory Neil Shapirodnl   1    2      3    4
247940266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
248040266059SGregory Neil Shapirodnl no match, return default passthru
248140266059SGregory Neil Shapirodnl   1    2    3  4    5
248240266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
248340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
248440266059SGregory Neil Shapirodnl            2    3  4    5
248540266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
248640266059SGregory Neil Shapirodnl match, return <match> <passthru>
248740266059SGregory Neil Shapirodnl    2    3  4    5
248840266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
248940266059SGregory Neil Shapiro
249040266059SGregory Neil Shapiro######################################################################
249140266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
249240266059SGregory Neil Shapiro###
249340266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
249440266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
249540266059SGregory Neil Shapiro###
249640266059SGregory Neil Shapiro###	Parameters:
249740266059SGregory Neil Shapiro###		<$1> -- key (user@)
249840266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
249940266059SGregory Neil Shapirodnl			must not be empty
250040266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
250140266059SGregory Neil Shapiro###			! does lookup only with tag
250240266059SGregory Neil Shapiro###			+ does lookup with and without tag
250340266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
250440266059SGregory Neil Shapirodnl returns:		<default> <passthru>
250540266059SGregory Neil Shapirodnl 			<result> <passthru>
250640266059SGregory Neil Shapiro######################################################################
250740266059SGregory Neil Shapiro
250840266059SGregory Neil ShapiroSU
250940266059SGregory Neil Shapirodnl user lookups are always with trailing @
251040266059SGregory Neil Shapirodnl    2    3  4    5
251140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
251240266059SGregory Neil Shapirodnl no match, try without tag
251340266059SGregory Neil Shapirodnl   1    2      3    4
251440266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
251540266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
251640266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
251740266059SGregory Neil Shapirodnl no match, +detail: try +*
251840266059SGregory Neil Shapirodnl   1    2      3    4  5    6
251940266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
252040266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
252140266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
252240266059SGregory Neil Shapirodnl   1    2      3      4    5
252340266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
252440266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
252540266059SGregory Neil Shapirodnl no match, +detail: try without +detail
252640266059SGregory Neil Shapirodnl   1    2      3    4  5    6
252740266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
252840266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
252940266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
253040266059SGregory Neil Shapirodnl   1    2      3      4    5
253140266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
253240266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
253340266059SGregory Neil Shapirodnl no match, return <default> <passthru>
253440266059SGregory Neil Shapirodnl   1    2    3  4    5
253540266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
253640266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
253740266059SGregory Neil Shapirodnl            2    3  4    5
253840266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
253940266059SGregory Neil Shapirodnl match, return <match> <passthru>
254040266059SGregory Neil Shapirodnl    2    3  4    5
254140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
254240266059SGregory Neil Shapiro
254306f25ae9SGregory Neil Shapiro######################################################################
254406f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
254506f25ae9SGregory Neil Shapiro###	Parameters:
254606f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
254706f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
254806f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
254906f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
255006f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
255140266059SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: D: if there
255206f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
255306f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
255406f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
255506f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
255606f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
255706f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
255806f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
255906f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
256006f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
256140266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
256206f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
256306f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
256406f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
256506f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
256606f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
256706f25ae9SGregory Neil Shapiro######################################################################
256806f25ae9SGregory Neil Shapiro
256906f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
257006f25ae9SGregory Neil Shapirodnl if A is activated: add it
2571e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
257206f25ae9SGregory Neil ShapiroSSearchList
257340266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
257440266059SGregory Neil Shapirodnl       2       3    4
2575e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
257640266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
257740266059SGregory Neil Shapirodnl no match and nothing left: return
257840266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
257940266059SGregory Neil Shapirodnl no match but something left: continue
258040266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
258140266059SGregory Neil Shapirodnl match: return
258240266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
258306f25ae9SGregory Neil Shapirodnl return result from recursive invocation
258440266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
258540266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
258640266059SGregory Neil Shapirodivert(0)
258706f25ae9SGregory Neil Shapiro
258840266059SGregory Neil Shapiro######################################################################
258940266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
259040266059SGregory Neil Shapiro###
259140266059SGregory Neil Shapiro###	Parameters:
259240266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
259340266059SGregory Neil Shapiro######################################################################
259440266059SGregory Neil Shapiro
259540266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
259640266059SGregory Neil ShapiroSLocal_trust_auth
259706f25ae9SGregory Neil ShapiroStrust_auth
259806f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
259906f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
260006f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
260106f25ae9SGregory Neil Shapirodnl seems to be useful...
260206f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
260306f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
260406f25ae9SGregory Neil Shapirodnl call user supplied code
2605a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
260606f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
260706f25ae9SGregory Neil Shapirodnl default: error
260806f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
260906f25ae9SGregory Neil Shapiro
261040266059SGregory Neil Shapiro######################################################################
261140266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
261240266059SGregory Neil Shapiro###
261340266059SGregory Neil Shapiro###	Parameters:
261440266059SGregory Neil Shapiro###		$1: ${auth_type}
261540266059SGregory Neil Shapiro######################################################################
261640266059SGregory Neil ShapiroSLocal_Relay_Auth
261706f25ae9SGregory Neil Shapiro
261840266059SGregory Neil Shapiro######################################################################
261940266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
262040266059SGregory Neil Shapiro###	(done in server)
262140266059SGregory Neil Shapiro######################################################################
262240266059SGregory Neil ShapiroSsrv_features
262340266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
262440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
262540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
262640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2627e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
262840266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
262940266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
263040266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
263106f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
263240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
263340266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2634e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
263506f25ae9SGregory Neil Shapiro
263640266059SGregory Neil Shapiro######################################################################
263740266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
263840266059SGregory Neil Shapiro###	(done in client)
263940266059SGregory Neil Shapiro######################################################################
264006f25ae9SGregory Neil ShapiroStry_tls
264140266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
264240266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
264340266059SGregory Neil ShapiroR$* $| $#$*		$#$2
264440266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2645e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
264640266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
264740266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
264840266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
264906f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
265040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
265140266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2652e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
265306f25ae9SGregory Neil Shapiro
265440266059SGregory Neil Shapiro######################################################################
265540266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
265640266059SGregory Neil Shapiro###	(done in client, per recipient)
265740266059SGregory Neil Shapirodnl called from deliver() before RCPT command
265840266059SGregory Neil Shapiro###
265940266059SGregory Neil Shapiro###	Parameters:
266040266059SGregory Neil Shapiro###		$1: recipient
266140266059SGregory Neil Shapiro######################################################################
266240266059SGregory Neil ShapiroStls_rcpt
266340266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
266440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
266540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
266640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2667e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
266840266059SGregory Neil Shapirodnl store name of other side
266940266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
267040266059SGregory Neil Shapirodnl canonify recipient address
267140266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
267240266059SGregory Neil Shapirodnl strip trailing dots
267340266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
267440266059SGregory Neil Shapirodnl full address?
267540266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
267640266059SGregory Neil Shapirodnl only localpart?
267740266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
267840266059SGregory Neil Shapirodnl look it up
267940266059SGregory Neil Shapirodnl also look up a default value via E:
268040266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
268140266059SGregory Neil Shapirodnl found nothing: stop here
268240266059SGregory Neil ShapiroR$* $| <?>	$@ OK
268340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
268440266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
268540266059SGregory Neil Shapirodnl use the generic routine (for now)
268640266059SGregory Neil ShapiroR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
268740266059SGregory Neil Shapiro
268840266059SGregory Neil Shapiro######################################################################
268940266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
269040266059SGregory Neil Shapiro###	(done in server)
269140266059SGregory Neil Shapiro###
269240266059SGregory Neil Shapiro###	Parameters:
269340266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
269440266059SGregory Neil Shapiro######################################################################
269506f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
269606f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
269706f25ae9SGregory Neil ShapiroStls_client
269840266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
2699e3793f76SGregory Neil ShapiroR$*			$: $1 <?> $>"Local_tls_client" $1
2700e3793f76SGregory Neil ShapiroR$* <?> $#$*		$#$2
2701e3793f76SGregory Neil ShapiroR$* <?> $*		$: $1', `dnl')
270206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
270340266059SGregory Neil Shapirodnl store name of other side
27049bd497b8SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
270506f25ae9SGregory Neil Shapirodnl ignore second arg for now
270606f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
270706f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
270806f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
270940266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
271040266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
271106f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
271206f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
271340266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
271440266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
271540266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
271640266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
271706f25ae9SGregory Neil Shapiro
271840266059SGregory Neil Shapiro######################################################################
271940266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
272040266059SGregory Neil Shapiro###	(done in client)
272140266059SGregory Neil Shapiro###
272240266059SGregory Neil Shapiro###	Parameter:
272340266059SGregory Neil Shapiro###		${verify}
272440266059SGregory Neil Shapiro######################################################################
272506f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
272606f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
272706f25ae9SGregory Neil ShapiroStls_server
272840266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
272940266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
273040266059SGregory Neil ShapiroR$* $| $#$*		$#$2
273140266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
273206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
273340266059SGregory Neil Shapirodnl store name of other side
273440266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
273540266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
273640266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
273706f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
273806f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
273940266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
274040266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
274140266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
274240266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
274306f25ae9SGregory Neil Shapiro
274440266059SGregory Neil Shapiro######################################################################
274540266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
274640266059SGregory Neil Shapiro###
274740266059SGregory Neil Shapiro###	Parameters:
274806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
274940266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
275040266059SGregory Neil Shapiro###		${verify}')
275140266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
275240266059SGregory Neil Shapirodnl	syntax for Requirement:
275340266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
275440266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
275540266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
275640266059SGregory Neil Shapiro######################################################################
275740266059SGregory Neil ShapiroSTLS_connection
275840266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
275940266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
276040266059SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
276140266059SGregory Neil Shapirodivert(-1)')
276206f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
276340266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
276406f25ae9SGregory Neil Shapirodnl remove optional <>
276506f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
276640266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
276740266059SGregory Neil Shapiro# create the appropriate error codes
276806f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2769e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2770e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
277106f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
2772e92d3f3fSGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
277340266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
277440266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
277506f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
277606f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
277706f25ae9SGregory Neil Shapirodnl use default error
277806f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
27794e4196cbSGregory Neil Shapiro# deal with TLS protocol errors: abort
27804e4196cbSGregory Neil ShapiroRPROTOCOL $| <$-:$+> $* 	$#error $@ $2 $: $1 " STARTTLS failed."
27814e4196cbSGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
27824e4196cbSGregory Neil Shapirodnl use default error
27834e4196cbSGregory Neil ShapiroRPROTOCOL $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
278440266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
278540266059SGregory Neil Shapirodnl separate optional requirements
278640266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2787e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
278840266059SGregory Neil Shapirodnl separate optional requirements
2789e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
279006f25ae9SGregory Neil Shapirodnl some other value in access map: accept
279106f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
279206f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
279306f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
279406f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
279540266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
279606f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
279740266059SGregory Neil ShapiroR<$*><VERIFY> <> OK		$@ OK
279840266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
279940266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
280040266059SGregory Neil ShapiroR<$*><VERIFY> <$+> OK		$: <$1> <REQ:0> <$2>
280106f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
280240266059SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> OK	$: <$1> <REQ:$2> <$3>
280306f25ae9SGregory Neil Shapirodnl just some level of encryption required
280440266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
280540266059SGregory Neil Shapirodnl workspace:
280640266059SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!= OK)
280740266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
280840266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
280940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
281040266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
281140266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
281240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
281340266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
281406f25ae9SGregory Neil Shapirodnl some other value for ${verify}
281540266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
281640266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
281740266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
281806f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
281940266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
282040266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
282140266059SGregory Neil Shapirodnl strength requirements fulfilled
282240266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
282340266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
282440266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
282540266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
282640266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
282740266059SGregory Neil Shapirodnl workspace:
282840266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
282940266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
283040266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
283140266059SGregory Neil Shapirodnl continue: check  extensions
283240266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
283340266059SGregory Neil Shapirodnl split extensions into own list
283440266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
283540266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
283640266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
283706f25ae9SGregory Neil Shapiro
283840266059SGregory Neil Shapiro######################################################################
283940266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
284040266059SGregory Neil Shapiro###
284140266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
284240266059SGregory Neil Shapiro###		$-: SMTP reply code
284340266059SGregory Neil Shapiro###		$+: Enhanced Status Code
284440266059SGregory Neil Shapirodnl  further requirements for this ruleset:
284540266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
284640266059SGregory Neil Shapirodnl
284740266059SGregory Neil Shapirodnl	currently only CN[:common_name] is implemented
284840266059SGregory Neil Shapirodnl	right now this is only a logical AND
284940266059SGregory Neil Shapirodnl	i.e. all requirements must be true
285040266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
285140266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
285240266059SGregory Neil Shapirodnl	operations (no precedences etc)?
285340266059SGregory Neil Shapiro######################################################################
285440266059SGregory Neil ShapiroSTLS_req
285540266059SGregory Neil Shapirodnl no additional requirements: ok
285640266059SGregory Neil ShapiroR $| $+		$@ OK
285740266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
285840266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
285940266059SGregory Neil Shapirodnl match, check rest
286040266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
286140266059SGregory Neil Shapirodnl CN does not match
286240266059SGregory Neil Shapirodnl  1   2      3  4
286340266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
286440266059SGregory Neil Shapirodnl cert subject
286540266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
286640266059SGregory Neil Shapirodnl CS does not match
286740266059SGregory Neil Shapirodnl  1   2      3  4
286813bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
286940266059SGregory Neil Shapirodnl match, check rest
287040266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
287140266059SGregory Neil Shapirodnl CI does not match
287240266059SGregory Neil Shapirodnl  1   2      3  4
287313bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
287440266059SGregory Neil Shapirodnl return from recursive call
287540266059SGregory Neil ShapiroROK			$@ OK
287640266059SGregory Neil Shapiro
287740266059SGregory Neil Shapiro######################################################################
287840266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
287940266059SGregory Neil Shapiro###
288040266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
288140266059SGregory Neil Shapiro######################################################################
288206f25ae9SGregory Neil ShapiroSmax
288306f25ae9SGregory Neil ShapiroR:		$: 0
288406f25ae9SGregory Neil ShapiroR:$-		$: $1
288506f25ae9SGregory Neil ShapiroR$-:		$: $1
288606f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
288706f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
288840266059SGregory Neil ShapiroR$-:$-:$-	$: $2
288940266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
289040266059SGregory Neil Shapirodivert(0)
289106f25ae9SGregory Neil Shapiro
289240266059SGregory Neil Shapiro######################################################################
289340266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
289440266059SGregory Neil Shapiro###
289540266059SGregory Neil Shapiro###	Parameters:
289640266059SGregory Neil Shapiro###		none
289740266059SGregory Neil Shapiro######################################################################
289840266059SGregory Neil ShapiroSRelayTLS
289906f25ae9SGregory Neil Shapiro# authenticated?
290006f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
290106f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
290213bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
290306f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
290406f25ae9SGregory Neil Shapirodnl but anyway).
290506f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
290606f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
290706f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
290806f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
290906f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
291006f25ae9SGregory Neil Shapirodnl cert subject.
291106f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
291240266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
291340266059SGregory Neil ShapiroR<?> OK			$: OK		authenticated: continue
291440266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
291506f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
291640266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
291740266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
291840266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
291906f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
292040266059SGregory Neil ShapiroRRELAY			$# RELAY
292106f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
292240266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
292340266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
292440266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
292540266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
292640266059SGregory Neil ShapiroR$*			$: NO', `dnl')
292740266059SGregory Neil Shapiro
292840266059SGregory Neil Shapiro######################################################################
292940266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
293040266059SGregory Neil Shapiro###
293140266059SGregory Neil Shapiro###	Parameters:
293240266059SGregory Neil Shapiro###		$1: {server_name}
293340266059SGregory Neil Shapiro###		$2: {server_addr}
293440266059SGregory Neil Shapirodnl	both are currently ignored
293540266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
293640266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
293740266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
293840266059SGregory Neil Shapiro######################################################################
293940266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
294040266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
294140266059SGregory Neil Shapirodnl (which may be considered a good thing).
294240266059SGregory Neil ShapiroSauthinfo
294340266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
294440266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
294540266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
294640266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
294740266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
294840266059SGregory Neil ShapiroR<$*>		$# $1
294940266059SGregory Neil Shapirodnl', `dnl
295040266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
295140266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
295240266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
295340266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
295440266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
295540266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
295640266059SGregory Neil Shapirodnl', `dnl')')
295706f25ae9SGregory Neil Shapiro
2958e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
2959e92d3f3fSGregory Neil Shapiro######################################################################
2960e92d3f3fSGregory Neil Shapiro###  RateControl:
2961e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
2962e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
2963e92d3f3fSGregory Neil Shapiro######################################################################
2964e92d3f3fSGregory Neil ShapiroSRateControl
2965e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2966e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
2967e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
2968e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
2969e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
2970e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
2971e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
2972e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2973e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
2974e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
2975ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
2976e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
2977ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
2978e92d3f3fSGregory Neil Shapiro')')
2979e92d3f3fSGregory Neil Shapiro
2980e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
2981e92d3f3fSGregory Neil Shapiro######################################################################
2982e92d3f3fSGregory Neil Shapiro###  ConnControl:
2983e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
2984e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
2985e92d3f3fSGregory Neil Shapiro######################################################################
2986e92d3f3fSGregory Neil ShapiroSConnControl
2987e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2988e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
2989e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
2990e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
2991e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
2992e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
2993e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
2994e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2995e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
2996e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
2997ffb83623SGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
2998e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
2999ffb83623SGregory Neil ShapiroR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
3000e92d3f3fSGregory Neil Shapiro')')
3001e92d3f3fSGregory Neil Shapiro
300206f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
300306f25ae9SGregory Neil Shapiro#
300406f25ae9SGregory Neil Shapiro######################################################################
300506f25ae9SGregory Neil Shapiro######################################################################
300606f25ae9SGregory Neil Shapiro#####
300706f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
300806f25ae9SGregory Neil Shapiro#####
300906f25ae9SGregory Neil Shapiro######################################################################
301006f25ae9SGregory Neil Shapiro######################################################################
301140266059SGregory Neil Shapiro_MAIL_FILTERS_
3012c2aa98e2SPeter Wemm#
3013c2aa98e2SPeter Wemm######################################################################
3014c2aa98e2SPeter Wemm######################################################################
3015c2aa98e2SPeter Wemm#####
3016c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
3017c2aa98e2SPeter Wemm#####
3018c2aa98e2SPeter Wemm######################################################################
3019c2aa98e2SPeter Wemm######################################################################
302006f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
302142e5d165SGregory Neil Shapiro
3022