xref: /freebsd/contrib/sendmail/cf/m4/proto.m4 (revision e92d3f3f)
1c2aa98e2SPeter Wemmdivert(-1)
2c2aa98e2SPeter Wemm#
3323f6dcbSGregory Neil Shapiro# Copyright (c) 1998-2004 Sendmail, 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
16e92d3f3fSGregory Neil ShapiroVERSIONID(`$Id: proto.m4,v 8.710 2004/07/27 17:32:48 ca Exp $')
17c2aa98e2SPeter Wemm
1806f25ae9SGregory Neil Shapiro# level CF_LEVEL config file format
1906f25ae9SGregory Neil ShapiroV`'CF_LEVEL/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?
39140266059SGregory Neil Shapiro_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `10000')
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
39940266059SGregory Neil Shapiro# key for shared memory; 0 to turn off
40040266059SGregory Neil Shapiro_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
40140266059SGregory Neil Shapiro
402605302a5SGregory Neil Shapiroifdef(`confSHARED_MEMORY_KEY_FILE', `dnl
403605302a5SGregory Neil Shapiro# file to store key for shared memory (if SharedMemoryKey = -1)
404605302a5SGregory Neil ShapiroO SharedMemoryKeyFile=confSHARED_MEMORY_KEY_FILE')
405605302a5SGregory Neil Shapiro
406c2aa98e2SPeter Wemm# timeouts (many of these)
40706f25ae9SGregory Neil Shapiro_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
40806f25ae9SGregory Neil Shapiro_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
40940266059SGregory Neil Shapiro_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
41006f25ae9SGregory Neil Shapiro_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
41106f25ae9SGregory Neil Shapiro_OPTION(Timeout.helo, `confTO_HELO', `5m')
41206f25ae9SGregory Neil Shapiro_OPTION(Timeout.mail, `confTO_MAIL', `10m')
41306f25ae9SGregory Neil Shapiro_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
41406f25ae9SGregory Neil Shapiro_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
41506f25ae9SGregory Neil Shapiro_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
41606f25ae9SGregory Neil Shapiro_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
41706f25ae9SGregory Neil Shapiro_OPTION(Timeout.rset, `confTO_RSET', `5m')
41806f25ae9SGregory Neil Shapiro_OPTION(Timeout.quit, `confTO_QUIT', `2m')
41906f25ae9SGregory Neil Shapiro_OPTION(Timeout.misc, `confTO_MISC', `2m')
42006f25ae9SGregory Neil Shapiro_OPTION(Timeout.command, `confTO_COMMAND', `1h')
42106f25ae9SGregory Neil Shapiro_OPTION(Timeout.ident, `confTO_IDENT', `5s')
42206f25ae9SGregory Neil Shapiro_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
42306f25ae9SGregory Neil Shapiro_OPTION(Timeout.control, `confTO_CONTROL', `2m')
42406f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
42506f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
42606f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
42706f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
428e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
42906f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
43006f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
43106f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
43206f25ae9SGregory Neil Shapiro_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
433e92d3f3fSGregory Neil Shapiro_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
43406f25ae9SGregory Neil Shapiro_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
43506f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
43606f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
43706f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
43806f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
43906f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
44006f25ae9SGregory Neil Shapiro_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
44140266059SGregory Neil Shapiro_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
44240266059SGregory Neil Shapiro_OPTION(Timeout.auth, `confTO_AUTH', `10m')
44340266059SGregory Neil Shapiro_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
44440266059SGregory Neil Shapiro
44540266059SGregory Neil Shapiro# time for DeliverBy; extension disabled if less than 0
44640266059SGregory Neil Shapiro_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
447c2aa98e2SPeter Wemm
448c2aa98e2SPeter Wemm# should we not prune routes in route-addr syntax addresses?
44906f25ae9SGregory Neil Shapiro_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
450c2aa98e2SPeter Wemm
451c2aa98e2SPeter Wemm# queue up everything before forking?
45206f25ae9SGregory Neil Shapiro_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
453c2aa98e2SPeter Wemm
454c2aa98e2SPeter Wemm# status file
45506f25ae9SGregory Neil ShapiroO StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', `MAIL_SETTINGS_DIR`'statistics')
456c2aa98e2SPeter Wemm
457c2aa98e2SPeter Wemm# time zone handling:
458c2aa98e2SPeter Wemm#  if undefined, use system default
459c2aa98e2SPeter Wemm#  if defined but null, use TZ envariable passed in
460c2aa98e2SPeter Wemm#  if defined and non-null, use that info
461c2aa98e2SPeter Wemmifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
462c2aa98e2SPeter Wemm	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
463c2aa98e2SPeter Wemm	`O TimeZoneSpec=confTIME_ZONE')
464c2aa98e2SPeter Wemm
465c2aa98e2SPeter Wemm# default UID (can be username or userid:groupid)
46606f25ae9SGregory Neil Shapiro_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
467c2aa98e2SPeter Wemm
468c2aa98e2SPeter Wemm# list of locations of user database file (null means no lookup)
46906f25ae9SGregory Neil Shapiro_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
470c2aa98e2SPeter Wemm
471c2aa98e2SPeter Wemm# fallback MX host
47206f25ae9SGregory Neil Shapiro_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
473c2aa98e2SPeter Wemm
474e92d3f3fSGregory Neil Shapiro# fallback smart host
475e92d3f3fSGregory Neil Shapiro_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
476e92d3f3fSGregory Neil Shapiro
477c2aa98e2SPeter Wemm# if we are the best MX host for a site, try it directly instead of config err
47806f25ae9SGregory Neil Shapiro_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
479c2aa98e2SPeter Wemm
480c2aa98e2SPeter Wemm# load average at which we just queue messages
48106f25ae9SGregory Neil Shapiro_OPTION(QueueLA, `confQUEUE_LA', `8')
482c2aa98e2SPeter Wemm
483c2aa98e2SPeter Wemm# load average at which we refuse connections
48406f25ae9SGregory Neil Shapiro_OPTION(RefuseLA, `confREFUSE_LA', `12')
485c2aa98e2SPeter Wemm
486e92d3f3fSGregory Neil Shapiro# log interval when refusing connections for this long
487e92d3f3fSGregory Neil Shapiro_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
488e92d3f3fSGregory Neil Shapiro
48940266059SGregory Neil Shapiro# load average at which we delay connections; 0 means no limit
49040266059SGregory Neil Shapiro_OPTION(DelayLA, `confDELAY_LA', `0')
49140266059SGregory Neil Shapiro
492c2aa98e2SPeter Wemm# maximum number of children we allow at one time
493739ac4d4SGregory Neil Shapiro_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
494c2aa98e2SPeter Wemm
495c2aa98e2SPeter Wemm# maximum number of new connections per second
496193538b7SGregory Neil Shapiro_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
497c2aa98e2SPeter Wemm
498e92d3f3fSGregory Neil Shapiro# Width of the window
499e92d3f3fSGregory Neil Shapiro_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
500e92d3f3fSGregory Neil Shapiro
501c2aa98e2SPeter Wemm# work recipient factor
50206f25ae9SGregory Neil Shapiro_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
503c2aa98e2SPeter Wemm
504c2aa98e2SPeter Wemm# deliver each queued job in a separate process?
50506f25ae9SGregory Neil Shapiro_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
506c2aa98e2SPeter Wemm
507c2aa98e2SPeter Wemm# work class factor
50806f25ae9SGregory Neil Shapiro_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
509c2aa98e2SPeter Wemm
510c2aa98e2SPeter Wemm# work time factor
51106f25ae9SGregory Neil Shapiro_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
512c2aa98e2SPeter Wemm
513c2aa98e2SPeter Wemm# default character set
51406f25ae9SGregory Neil Shapiro_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `iso-8859-1')
515c2aa98e2SPeter Wemm
51640266059SGregory Neil Shapiro# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
51706f25ae9SGregory Neil Shapiro_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
518c2aa98e2SPeter Wemm
519c2aa98e2SPeter Wemm# hosts file (normally /etc/hosts)
52006f25ae9SGregory Neil Shapiro_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
521c2aa98e2SPeter Wemm
522c2aa98e2SPeter Wemm# dialup line delay on connection failure
52306f25ae9SGregory Neil Shapiro_OPTION(DialDelay, `confDIAL_DELAY', `10s')
524c2aa98e2SPeter Wemm
525c2aa98e2SPeter Wemm# action to take if there are no recipients in the message
52606f25ae9SGregory Neil Shapiro_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `add-to-undisclosed')
527c2aa98e2SPeter Wemm
528c2aa98e2SPeter Wemm# chrooted environment for writing to files
52906f25ae9SGregory Neil Shapiro_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `/arch')
530c2aa98e2SPeter Wemm
531c2aa98e2SPeter Wemm# are colons OK in addresses?
53206f25ae9SGregory Neil Shapiro_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
533c2aa98e2SPeter Wemm
534c2aa98e2SPeter Wemm# shall I avoid expanding CNAMEs (violates protocols)?
53506f25ae9SGregory Neil Shapiro_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
536c2aa98e2SPeter Wemm
537c2aa98e2SPeter Wemm# SMTP initial login message (old $e macro)
53806f25ae9SGregory Neil Shapiro_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
539c2aa98e2SPeter Wemm
540c2aa98e2SPeter Wemm# UNIX initial From header format (old $l macro)
54106f25ae9SGregory Neil Shapiro_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
542c2aa98e2SPeter Wemm
543c2aa98e2SPeter Wemm# From: lines that have embedded newlines are unwrapped onto one line
54406f25ae9SGregory Neil Shapiro_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
545c2aa98e2SPeter Wemm
546c2aa98e2SPeter Wemm# Allow HELO SMTP command that does not `include' a host name
54706f25ae9SGregory Neil Shapiro_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
548c2aa98e2SPeter Wemm
549c2aa98e2SPeter Wemm# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
55006f25ae9SGregory Neil Shapiro_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
551c2aa98e2SPeter Wemm
552c2aa98e2SPeter Wemm# delimiter (operator) characters (old $o macro)
55306f25ae9SGregory Neil Shapiro_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
554c2aa98e2SPeter Wemm
555c2aa98e2SPeter Wemm# shall I avoid calling initgroups(3) because of high NIS costs?
55606f25ae9SGregory Neil Shapiro_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
557c2aa98e2SPeter Wemm
558c2aa98e2SPeter Wemm# are group-writable `:include:' and .forward files (un)trustworthy?
55940266059SGregory Neil Shapiro# True (the default) means they are not trustworthy.
56006f25ae9SGregory Neil Shapiro_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
56140266059SGregory Neil Shapiroifdef(`confUNSAFE_GROUP_WRITES',
56240266059SGregory Neil Shapiro`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
56340266059SGregory Neil Shapiro')')
564c2aa98e2SPeter Wemm
565c2aa98e2SPeter Wemm# where do errors that occur when sending errors get sent?
56606f25ae9SGregory Neil Shapiro_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
56706f25ae9SGregory Neil Shapiro
56806f25ae9SGregory Neil Shapiro# where to save bounces if all else fails
56906f25ae9SGregory Neil Shapiro_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
570c2aa98e2SPeter Wemm
571c2aa98e2SPeter Wemm# what user id do we assume for the majority of the processing?
57206f25ae9SGregory Neil Shapiro_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
573c2aa98e2SPeter Wemm
574c2aa98e2SPeter Wemm# maximum number of recipients per SMTP envelope
575e92d3f3fSGregory Neil Shapiro_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
576c2aa98e2SPeter Wemm
57740266059SGregory Neil Shapiro# limit the rate recipients per SMTP envelope are accepted
57840266059SGregory Neil Shapiro# once the threshold number of recipients have been rejected
579e92d3f3fSGregory Neil Shapiro_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
58040266059SGregory Neil Shapiro
581c2aa98e2SPeter Wemm# shall we get local names from our installed interfaces?
58206f25ae9SGregory Neil Shapiro_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
583c2aa98e2SPeter Wemm
58406f25ae9SGregory Neil Shapiro# Return-Receipt-To: header implies DSN request
58506f25ae9SGregory Neil Shapiro_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
58606f25ae9SGregory Neil Shapiro
58706f25ae9SGregory Neil Shapiro# override connection address (for testing)
58806f25ae9SGregory Neil Shapiro_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
58906f25ae9SGregory Neil Shapiro
59006f25ae9SGregory Neil Shapiro# Trusted user for file ownership and starting the daemon
59106f25ae9SGregory Neil Shapiro_OPTION(TrustedUser, `confTRUSTED_USER', `root')
59206f25ae9SGregory Neil Shapiro
59306f25ae9SGregory Neil Shapiro# Control socket for daemon management
59406f25ae9SGregory Neil Shapiro_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
59506f25ae9SGregory Neil Shapiro
59606f25ae9SGregory Neil Shapiro# Maximum MIME header length to protect MUAs
597e92d3f3fSGregory Neil Shapiro_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0')
59806f25ae9SGregory Neil Shapiro
59906f25ae9SGregory Neil Shapiro# Maximum length of the sum of all headers
60006f25ae9SGregory Neil Shapiro_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
60106f25ae9SGregory Neil Shapiro
60206f25ae9SGregory Neil Shapiro# Maximum depth of alias recursion
60306f25ae9SGregory Neil Shapiro_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
60406f25ae9SGregory Neil Shapiro
60506f25ae9SGregory Neil Shapiro# location of pid file
60606f25ae9SGregory Neil Shapiro_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
60706f25ae9SGregory Neil Shapiro
60806f25ae9SGregory Neil Shapiro# Prefix string for the process title shown on 'ps' listings
60906f25ae9SGregory Neil Shapiro_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
61006f25ae9SGregory Neil Shapiro
61106f25ae9SGregory Neil Shapiro# Data file (df) memory-buffer file maximum size
61206f25ae9SGregory Neil Shapiro_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
61306f25ae9SGregory Neil Shapiro
61406f25ae9SGregory Neil Shapiro# Transcript file (xf) memory-buffer file maximum size
61506f25ae9SGregory Neil Shapiro_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
61606f25ae9SGregory Neil Shapiro
61740266059SGregory Neil Shapiro# lookup type to find information about local mailboxes
61840266059SGregory Neil Shapiro_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
61940266059SGregory Neil Shapiro
620e92d3f3fSGregory Neil Shapiro# override compile time flag REQUIRES_DIR_FSYNC
621e92d3f3fSGregory Neil Shapiro_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
622e92d3f3fSGregory Neil Shapiro
62306f25ae9SGregory Neil Shapiro# list of authentication mechanisms
62440266059SGregory Neil Shapiro_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
62506f25ae9SGregory Neil Shapiro
626e92d3f3fSGregory Neil Shapiro# Authentication realm
627e92d3f3fSGregory Neil Shapiro_OPTION(AuthRealm, `confAUTH_REALM', `')
628e92d3f3fSGregory Neil Shapiro
62906f25ae9SGregory Neil Shapiro# default authentication information for outgoing connections
63006f25ae9SGregory Neil Shapiro_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
63106f25ae9SGregory Neil Shapiro
63206f25ae9SGregory Neil Shapiro# SMTP AUTH flags
63306f25ae9SGregory Neil Shapiro_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
63406f25ae9SGregory Neil Shapiro
63540266059SGregory Neil Shapiro# SMTP AUTH maximum encryption strength
63640266059SGregory Neil Shapiro_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
63740266059SGregory Neil Shapiro
63840266059SGregory Neil Shapiro# SMTP STARTTLS server options
63940266059SGregory Neil Shapiro_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
64040266059SGregory Neil Shapiro
64106f25ae9SGregory Neil Shapiro# Input mail filters
64206f25ae9SGregory Neil Shapiro_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
64306f25ae9SGregory Neil Shapiro
644739ac4d4SGregory Neil Shapiroifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
64506f25ae9SGregory Neil Shapiro# Milter options
64640266059SGregory Neil Shapiro_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
64706f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
64806f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
64906f25ae9SGregory Neil Shapiro_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
650323f6dcbSGregory Neil Shapiro_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
651e92d3f3fSGregory Neil Shapiro_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')')
65206f25ae9SGregory Neil Shapiro
65306f25ae9SGregory Neil Shapiro# CA directory
65413bd1963SGregory Neil Shapiro_OPTION(CACertPath, `confCACERT_PATH', `')
65506f25ae9SGregory Neil Shapiro# CA file
65613bd1963SGregory Neil Shapiro_OPTION(CACertFile, `confCACERT', `')
65706f25ae9SGregory Neil Shapiro# Server Cert
65806f25ae9SGregory Neil Shapiro_OPTION(ServerCertFile, `confSERVER_CERT', `')
65906f25ae9SGregory Neil Shapiro# Server private key
66006f25ae9SGregory Neil Shapiro_OPTION(ServerKeyFile, `confSERVER_KEY', `')
66106f25ae9SGregory Neil Shapiro# Client Cert
66206f25ae9SGregory Neil Shapiro_OPTION(ClientCertFile, `confCLIENT_CERT', `')
66306f25ae9SGregory Neil Shapiro# Client private key
66406f25ae9SGregory Neil Shapiro_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
665e92d3f3fSGregory Neil Shapiro# File containing certificate revocation lists
666e92d3f3fSGregory Neil Shapiro_OPTION(CRLFile, `confCRL', `')
66706f25ae9SGregory Neil Shapiro# DHParameters (only required if DSA/DH is used)
66806f25ae9SGregory Neil Shapiro_OPTION(DHParameters, `confDH_PARAMETERS', `')
66906f25ae9SGregory Neil Shapiro# Random data source (required for systems without /dev/urandom under OpenSSL)
67006f25ae9SGregory Neil Shapiro_OPTION(RandFile, `confRAND_FILE', `')
67106f25ae9SGregory Neil Shapiro
67240266059SGregory Neil Shapiro############################
67340266059SGregory Neil Shapiro`# QUEUE GROUP DEFINITIONS  #'
67440266059SGregory Neil Shapiro############################
67540266059SGregory Neil Shapiro_QUEUE_GROUP_
676065a643dSPeter Wemm
677c2aa98e2SPeter Wemm###########################
678c2aa98e2SPeter Wemm#   Message precedences   #
679c2aa98e2SPeter Wemm###########################
680c2aa98e2SPeter Wemm
681c2aa98e2SPeter WemmPfirst-class=0
682c2aa98e2SPeter WemmPspecial-delivery=100
683c2aa98e2SPeter WemmPlist=-30
684c2aa98e2SPeter WemmPbulk=-60
685c2aa98e2SPeter WemmPjunk=-100
686c2aa98e2SPeter Wemm
687c2aa98e2SPeter Wemm#####################
688c2aa98e2SPeter Wemm#   Trusted users   #
689c2aa98e2SPeter Wemm#####################
690c2aa98e2SPeter Wemm
691c2aa98e2SPeter Wemm# this is equivalent to setting class "t"
69206f25ae9SGregory Neil Shapiroifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
693c2aa98e2SPeter WemmTroot
694c2aa98e2SPeter WemmTdaemon
695c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl', `Tuucp')
696c2aa98e2SPeter Wemmifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
697c2aa98e2SPeter Wemm
698c2aa98e2SPeter Wemm#########################
699c2aa98e2SPeter Wemm#   Format of headers   #
700c2aa98e2SPeter Wemm#########################
701c2aa98e2SPeter Wemm
702c2aa98e2SPeter Wemmifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
703e92d3f3fSGregory Neil Shapiroifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
704c2aa98e2SPeter WemmH?P?Return-Path: <$g>
705c2aa98e2SPeter WemmHReceived: confRECEIVED_HEADER
706c2aa98e2SPeter WemmH?D?Resent-Date: $a
707c2aa98e2SPeter WemmH?D?Date: $a
708c2aa98e2SPeter WemmH?F?Resent-From: confFROM_HEADER
709c2aa98e2SPeter WemmH?F?From: confFROM_HEADER
710c2aa98e2SPeter WemmH?x?Full-Name: $x
711c2aa98e2SPeter Wemm# HPosted-Date: $a
712c2aa98e2SPeter Wemm# H?l?Received-Date: $b
713e92d3f3fSGregory Neil ShapiroH?M?Resent-Message-Id: confMESSAGEID_HEADER
714e92d3f3fSGregory Neil ShapiroH?M?Message-Id: confMESSAGEID_HEADER
71506f25ae9SGregory Neil Shapiro
716c2aa98e2SPeter Wemm#
717c2aa98e2SPeter Wemm######################################################################
718c2aa98e2SPeter Wemm######################################################################
719c2aa98e2SPeter Wemm#####
720c2aa98e2SPeter Wemm#####			REWRITING RULES
721c2aa98e2SPeter Wemm#####
722c2aa98e2SPeter Wemm######################################################################
723c2aa98e2SPeter Wemm######################################################################
724c2aa98e2SPeter Wemm
725c2aa98e2SPeter Wemm############################################
726c2aa98e2SPeter Wemm###  Ruleset 3 -- Name Canonicalization  ###
727c2aa98e2SPeter Wemm############################################
72806f25ae9SGregory Neil ShapiroScanonify=3
729c2aa98e2SPeter Wemm
730c2aa98e2SPeter Wemm# handle null input (translate to <@> special case)
731c2aa98e2SPeter WemmR$@			$@ <@>
732c2aa98e2SPeter Wemm
733c2aa98e2SPeter Wemm# strip group: syntax (not inside angle brackets!) and trailing semicolon
734c2aa98e2SPeter WemmR$*			$: $1 <@>			mark addresses
735c2aa98e2SPeter WemmR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
736c2aa98e2SPeter WemmR@ $* <@>		$: @ $1				unmark @host:...
73740266059SGregory Neil ShapiroR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
738c2aa98e2SPeter WemmR$* :: $* <@>		$: $1 :: $2			unmark node::addr
739c2aa98e2SPeter WemmR:`include': $* <@>	$: :`include': $1			unmark :`include':...
740c2aa98e2SPeter WemmR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
741c2aa98e2SPeter WemmR$* : $* <@>		$: $2				strip colon if marked
742c2aa98e2SPeter WemmR$* <@>			$: $1				unmark
743c2aa98e2SPeter WemmR$* ;			   $1				strip trailing semi
744193538b7SGregory Neil ShapiroR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
745c2aa98e2SPeter WemmR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
746c2aa98e2SPeter Wemm
747c2aa98e2SPeter Wemm# null input now results from list:; syntax
748c2aa98e2SPeter WemmR$@			$@ :; <@>
749c2aa98e2SPeter Wemm
750c2aa98e2SPeter Wemm# strip angle brackets -- note RFC733 heuristic to get innermost item
751c2aa98e2SPeter WemmR$*			$: < $1 >			housekeeping <>
752c2aa98e2SPeter WemmR$+ < $* >		   < $2 >			strip excess on left
753c2aa98e2SPeter WemmR< $* > $+		   < $1 >			strip excess on right
754c2aa98e2SPeter WemmR<>			$@ < @ >			MAIL FROM:<> case
755c2aa98e2SPeter WemmR< $+ >			$: $1				remove housekeeping <>
756c2aa98e2SPeter Wemm
75706f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
758c2aa98e2SPeter Wemm# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
759c2aa98e2SPeter WemmR@ $+ , $+		@ $1 : $2			change all "," to ":"
760c2aa98e2SPeter Wemm
761c2aa98e2SPeter Wemm# localize and dispose of route-based addresses
76240266059SGregory Neil Shapirodnl XXX: IPv6 colon conflict
76340266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
76440266059SGregory Neil Shapiro`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
76506f25ae9SGregory Neil ShapiroR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
76606f25ae9SGregory Neil Shapirodnl',`dnl
76706f25ae9SGregory Neil Shapiro# strip route address <@a,@b,@c:user@d> -> <user@d>
76806f25ae9SGregory Neil ShapiroR@ $+ , $+		$2
76940266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
77040266059SGregory Neil Shapiro`R@ [ $* ] : $+		$2')
77106f25ae9SGregory Neil ShapiroR@ $+ : $+		$2
77206f25ae9SGregory Neil Shapirodnl')
773c2aa98e2SPeter Wemm
774c2aa98e2SPeter Wemm# find focus for list syntax
77506f25ae9SGregory Neil ShapiroR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
776c2aa98e2SPeter WemmR $+ : $* ;		$@ $1 : $2;			list syntax
777c2aa98e2SPeter Wemm
778c2aa98e2SPeter Wemm# find focus for @ syntax addresses
779c2aa98e2SPeter WemmR$+ @ $+		$: $1 < @ $2 >			focus on domain
780c2aa98e2SPeter WemmR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
78106f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
782c2aa98e2SPeter Wemm
78340266059SGregory Neil Shapirodnl This is flagged as an error in S0; no need to silently fix it here.
78440266059SGregory Neil Shapirodnl # do some sanity checking
78540266059SGregory Neil Shapirodnl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
786c2aa98e2SPeter Wemm
787c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
788c2aa98e2SPeter Wemm`# convert old-style addresses to a domain-based address
78906f25ae9SGregory Neil ShapiroR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
79006f25ae9SGregory Neil ShapiroR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
79106f25ae9SGregory Neil ShapiroR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
792c2aa98e2SPeter Wemm')
793c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
794c2aa98e2SPeter Wemm`# convert node::user addresses into a domain-based address
79506f25ae9SGregory Neil ShapiroR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
79606f25ae9SGregory Neil ShapiroR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
797c2aa98e2SPeter Wemm',
798c2aa98e2SPeter Wemm	`dnl')
799c2aa98e2SPeter Wemm# if we have % signs, take the rightmost one
800c2aa98e2SPeter WemmR$* % $*		$1 @ $2				First make them all @s.
801c2aa98e2SPeter WemmR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
80206f25ae9SGregory Neil ShapiroR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
803c2aa98e2SPeter Wemm
804c2aa98e2SPeter Wemm# else we must be a local name
80506f25ae9SGregory Neil ShapiroR$*			$@ $>Canonify2 $1
806c2aa98e2SPeter Wemm
807c2aa98e2SPeter Wemm
808c2aa98e2SPeter Wemm################################################
809c2aa98e2SPeter Wemm###  Ruleset 96 -- bottom half of ruleset 3  ###
810c2aa98e2SPeter Wemm################################################
811c2aa98e2SPeter Wemm
81206f25ae9SGregory Neil ShapiroSCanonify2=96
813c2aa98e2SPeter Wemm
814c2aa98e2SPeter Wemm# handle special cases for local names
815c2aa98e2SPeter WemmR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
816c2aa98e2SPeter WemmR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
817c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
818c2aa98e2SPeter Wemm`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
81906f25ae9SGregory Neil Shapiro
82040266059SGregory Neil Shapiro# check for IPv4/IPv6 domain literal
82140266059SGregory Neil ShapiroR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
822c2aa98e2SPeter WemmR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
823c2aa98e2SPeter WemmR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
824c2aa98e2SPeter Wemm
82506f25ae9SGregory Neil Shapiroifdef(`_DOMAIN_TABLE_', `dnl
826c2aa98e2SPeter Wemm# look up domains in the domain table
827c2aa98e2SPeter WemmR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
828c2aa98e2SPeter Wemm
82906f25ae9SGregory Neil Shapiroundivert(2)dnl LOCAL_RULE_3
830c2aa98e2SPeter Wemm
83106f25ae9SGregory Neil Shapiroifdef(`_BITDOMAIN_TABLE_', `dnl
832c2aa98e2SPeter Wemm# handle BITNET mapping
833c2aa98e2SPeter WemmR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
834c2aa98e2SPeter Wemm
83506f25ae9SGregory Neil Shapiroifdef(`_UUDOMAIN_TABLE_', `dnl
836c2aa98e2SPeter Wemm# handle UUCP mapping
837c2aa98e2SPeter WemmR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
838c2aa98e2SPeter Wemm
839c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
840c2aa98e2SPeter Wemm`ifdef(`UUCP_RELAY',
841c2aa98e2SPeter Wemm`# pass UUCP addresses straight through
842c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
843c2aa98e2SPeter Wemm`# if really UUCP, handle it immediately
844c2aa98e2SPeter Wemmifdef(`_CLASS_U_',
845c2aa98e2SPeter Wemm`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
846c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
847c2aa98e2SPeter Wemm`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
848c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
849c2aa98e2SPeter Wemm`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
850c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
851c2aa98e2SPeter Wemm`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
852c2aa98e2SPeter Wemmifdef(`_CLASS_Y_',
853c2aa98e2SPeter Wemm`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
854c2aa98e2SPeter Wemm
855c2aa98e2SPeter Wemmifdef(`_NO_CANONIFY_', `dnl', `dnl
856c2aa98e2SPeter Wemm# try UUCP traffic as a local address
857c2aa98e2SPeter WemmR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
858c2aa98e2SPeter WemmR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
859c2aa98e2SPeter Wemm')')
86006f25ae9SGregory Neil Shapiro# hostnames ending in class P are always canonical
86106f25ae9SGregory Neil ShapiroR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
86206f25ae9SGregory Neil Shapirodnl apply the next rule only for hostnames not in class P
86306f25ae9SGregory Neil Shapirodnl this even works for phrases in class P since . is in class P
86406f25ae9SGregory Neil Shapirodnl which daemon flags are set?
86506f25ae9SGregory Neil ShapiroR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
86606f25ae9SGregory Neil Shapirodnl the other rules in this section only apply if the hostname
86706f25ae9SGregory Neil Shapirodnl does not end in class P hence no further checks are done here
86806f25ae9SGregory Neil Shapirodnl if this ever changes make sure the lookups are "protected" again!
86906f25ae9SGregory Neil Shapiroifdef(`_NO_CANONIFY_', `dnl
87006f25ae9SGregory Neil Shapirodnl do not canonify unless:
87106f25ae9SGregory Neil Shapirodnl domain ends in class {Canonify} (this does not work if the intersection
87206f25ae9SGregory Neil Shapirodnl	with class P is non-empty)
87306f25ae9SGregory Neil Shapirodnl or {daemon_flags} has c set
87406f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if in class {Canonify}
87506f25ae9SGregory Neil ShapiroR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
87606f25ae9SGregory Neil Shapiro# pass to name server to make hostname canonical if requested
87706f25ae9SGregory Neil ShapiroR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
87806f25ae9SGregory Neil Shapirodnl trailing dot? -> do not apply _CANONIFY_HOSTS_
87906f25ae9SGregory Neil ShapiroR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
88006f25ae9SGregory Neil Shapiro# add a trailing dot to qualified hostnames so other rules will work
88106f25ae9SGregory Neil ShapiroR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
88206f25ae9SGregory Neil Shapiroifdef(`_CANONIFY_HOSTS_', `dnl
88306f25ae9SGregory Neil Shapirodnl this should only apply to unqualified hostnames
88406f25ae9SGregory Neil Shapirodnl but if a valid character inside an unqualified hostname is an OperatorChar
88506f25ae9SGregory Neil Shapirodnl then $- does not work.
88606f25ae9SGregory Neil Shapiro# lookup unqualified hostnames
88706f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
88806f25ae9SGregory Neil Shapirodnl _NO_CANONIFY_ is not set: canonify unless:
88906f25ae9SGregory Neil Shapirodnl {daemon_flags} contains CC (do not canonify)
890193538b7SGregory Neil Shapirodnl but add a trailing dot to qualified hostnames so other rules will work
891193538b7SGregory Neil Shapirodnl should we do this for every hostname: even unqualified?
892193538b7SGregory Neil ShapiroR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
89306f25ae9SGregory Neil ShapiroR$* CC $* $| $*			$: $3
89440266059SGregory Neil Shapiroifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
89540266059SGregory Neil Shapiro# do not canonify header addresses
89640266059SGregory Neil ShapiroR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
89740266059SGregory Neil ShapiroR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
89840266059SGregory Neil ShapiroR$* h $* $| $*			$: $3', `dnl')
899c2aa98e2SPeter Wemm# pass to name server to make hostname canonical
90006f25ae9SGregory Neil ShapiroR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
90106f25ae9SGregory Neil Shapirodnl remove {daemon_flags} for other cases
90206f25ae9SGregory Neil ShapiroR$* $| $*			$: $2
903c2aa98e2SPeter Wemm
904c2aa98e2SPeter Wemm# local host aliases and pseudo-domains are always canonical
905c2aa98e2SPeter WemmR$* < @ $=w > $*		$: $1 < @ $2 . > $3
906c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
907c2aa98e2SPeter Wemm`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
908c2aa98e2SPeter Wemm`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
90906f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
91006f25ae9SGregory Neil Shapirodnl virtual hosts are also canonical
91106f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
91206f25ae9SGregory Neil Shapiro`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
91306f25ae9SGregory Neil Shapiro`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
91406f25ae9SGregory Neil Shapiro`dnl')
91540266059SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
91640266059SGregory Neil Shapirodnl hosts for genericstable are also canonical
91740266059SGregory Neil Shapiroifdef(`_GENERICS_ENTIRE_DOMAIN_',
91840266059SGregory Neil Shapiro`R$* < @ $* $=G > $* 	$: $1 < @ $2 $3 . > $4',
91940266059SGregory Neil Shapiro`R$* < @ $=G > $* 	$: $1 < @ $2 . > $3')',
92040266059SGregory Neil Shapiro`dnl')
92106f25ae9SGregory Neil Shapirodnl remove superfluous dots (maybe repeatedly) which may have been added
92206f25ae9SGregory Neil Shapirodnl by one of the rules before
923c2aa98e2SPeter WemmR$* < @ $* . . > $*		$1 < @ $2 . > $3
924c2aa98e2SPeter Wemm
925c2aa98e2SPeter Wemm
926c2aa98e2SPeter Wemm##################################################
927c2aa98e2SPeter Wemm###  Ruleset 4 -- Final Output Post-rewriting  ###
928c2aa98e2SPeter Wemm##################################################
92906f25ae9SGregory Neil ShapiroSfinal=4
930c2aa98e2SPeter Wemm
931193538b7SGregory Neil ShapiroR$+ :; <@>		$@ $1 :				handle <list:;>
932c2aa98e2SPeter WemmR$* <@>			$@				handle <> and list:;
933c2aa98e2SPeter Wemm
934c2aa98e2SPeter Wemm# strip trailing dot off possibly canonical name
935c2aa98e2SPeter WemmR$* < @ $+ . > $*	$1 < @ $2 > $3
936c2aa98e2SPeter Wemm
93706f25ae9SGregory Neil Shapiro# eliminate internal code
938c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$1 < @ $j > $2
939c2aa98e2SPeter Wemm
940c2aa98e2SPeter Wemm# externalize local domain info
941c2aa98e2SPeter WemmR$* < $+ > $*		$1 $2 $3			defocus
942c2aa98e2SPeter WemmR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
943c2aa98e2SPeter WemmR@ $*			$@ @ $1				... and exit
944c2aa98e2SPeter Wemm
945c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
946c2aa98e2SPeter Wemm`# UUCP must always be presented in old form
947c2aa98e2SPeter WemmR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
948c2aa98e2SPeter Wemm
949c2aa98e2SPeter Wemmifdef(`_USE_DECNET_SYNTAX_',
950c2aa98e2SPeter Wemm`# put DECnet back in :: form
951c2aa98e2SPeter WemmR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
952c2aa98e2SPeter Wemm	`dnl')
953c2aa98e2SPeter Wemm# delete duplicate local names
954c2aa98e2SPeter WemmR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
955c2aa98e2SPeter Wemm
956c2aa98e2SPeter Wemm
957c2aa98e2SPeter Wemm
958c2aa98e2SPeter Wemm##############################################################
959c2aa98e2SPeter Wemm###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
960c2aa98e2SPeter Wemm###		   (used for recursive calls)		   ###
961c2aa98e2SPeter Wemm##############################################################
962c2aa98e2SPeter Wemm
96306f25ae9SGregory Neil ShapiroSRecurse=97
96406f25ae9SGregory Neil ShapiroR$*			$: $>canonify $1
96506f25ae9SGregory Neil ShapiroR$*			$@ $>parse $1
966c2aa98e2SPeter Wemm
967c2aa98e2SPeter Wemm
968c2aa98e2SPeter Wemm######################################
969c2aa98e2SPeter Wemm###   Ruleset 0 -- Parse Address   ###
970c2aa98e2SPeter Wemm######################################
971c2aa98e2SPeter Wemm
97206f25ae9SGregory Neil ShapiroSparse=0
973c2aa98e2SPeter Wemm
974c2aa98e2SPeter WemmR$*			$: $>Parse0 $1		initial parsing
975c2aa98e2SPeter WemmR<@>			$#_LOCAL_ $: <@>		special case error msgs
97606f25ae9SGregory Neil ShapiroR$*			$: $>ParseLocal $1	handle local hacks
977c2aa98e2SPeter WemmR$*			$: $>Parse1 $1		final parsing
978c2aa98e2SPeter Wemm
979c2aa98e2SPeter Wemm#
980c2aa98e2SPeter Wemm#  Parse0 -- do initial syntax checking and eliminate local addresses.
981c2aa98e2SPeter Wemm#	This should either return with the (possibly modified) input
982c2aa98e2SPeter Wemm#	or return with a #error mailer.  It should not return with a
983c2aa98e2SPeter Wemm#	#mailer other than the #error mailer.
984c2aa98e2SPeter Wemm#
985c2aa98e2SPeter Wemm
986c2aa98e2SPeter WemmSParse0
987c2aa98e2SPeter WemmR<@>			$@ <@>			special case error msgs
98840266059SGregory Neil ShapiroR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
98906f25ae9SGregory Neil ShapiroR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
99040266059SGregory Neil ShapiroR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
99140266059SGregory Neil ShapiroR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
992c2aa98e2SPeter WemmR$*			$: <> $1
99340266059SGregory Neil Shapirodnl allow tricks like [host1]:[host2]
99440266059SGregory Neil ShapiroR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
99540266059SGregory Neil ShapiroR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
99640266059SGregory Neil Shapirodnl but no a@[b]c
99740266059SGregory Neil ShapiroR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
998c2aa98e2SPeter WemmR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
99940266059SGregory Neil ShapiroR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
1000c2aa98e2SPeter WemmR<> $*			$1
100140266059SGregory Neil ShapiroR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
100240266059SGregory Neil ShapiroR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
100340266059SGregory Neil Shapirodnl no a@b@
100440266059SGregory Neil ShapiroR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
100540266059SGregory Neil Shapirodnl no a@b@c
100640266059SGregory Neil ShapiroR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
100706f25ae9SGregory Neil Shapirodnl comma only allowed before @; this check is not complete
100840266059SGregory Neil ShapiroR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
100940266059SGregory Neil Shapiro
101040266059SGregory Neil Shapiroifdef(`_STRICT_RFC821_', `# more RFC 821 checks
101140266059SGregory Neil ShapiroR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
101240266059SGregory Neil ShapiroR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
101340266059SGregory Neil Shapirodnl', `dnl')
1014c2aa98e2SPeter Wemm
1015c2aa98e2SPeter Wemm# now delete the local info -- note $=O to find characters that cause forwarding
101606f25ae9SGregory Neil ShapiroR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
101706f25ae9SGregory Neil ShapiroR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
1018c2aa98e2SPeter WemmR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
101940266059SGregory Neil ShapiroR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
102006f25ae9SGregory Neil ShapiroR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
1021c2aa98e2SPeter WemmR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
102240266059SGregory Neil ShapiroR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
1023c2aa98e2SPeter WemmR$* $=O $* < @ *LOCAL* >
102406f25ae9SGregory Neil Shapiro			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
1025c2aa98e2SPeter WemmR$* < @ *LOCAL* >	$: $1
1026c2aa98e2SPeter Wemm
1027c2aa98e2SPeter Wemm#
1028c2aa98e2SPeter Wemm#  Parse1 -- the bottom half of ruleset 0.
1029c2aa98e2SPeter Wemm#
1030c2aa98e2SPeter Wemm
1031c2aa98e2SPeter WemmSParse1
103206f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
103306f25ae9SGregory Neil Shapiro# handle LDAP routing for hosts in $={LDAPRoute}
103440266059SGregory Neil ShapiroR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
103540266059SGregory Neil ShapiroR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
1036c2aa98e2SPeter Wemm`dnl')
1037c2aa98e2SPeter Wemm
103806f25ae9SGregory Neil Shapiroifdef(`_MAILER_smtp_',
103906f25ae9SGregory Neil Shapiro`# handle numeric address spec
104006f25ae9SGregory Neil Shapirodnl there is no check whether this is really an IP number
104106f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
10425ef517c0SGregory Neil ShapiroR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
104306f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
104406f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
104506f25ae9SGregory Neil ShapiroR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
104606f25ae9SGregory Neil Shapiro	`dnl')
104706f25ae9SGregory Neil Shapiro
104806f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_TABLE_', `dnl
1049c2aa98e2SPeter Wemm# handle virtual users
105040266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
105140266059SGregory Neil Shapirodnl this is not a documented option
105240266059SGregory Neil Shapirodnl it stops looping in virtusertable mapping if input and output
105340266059SGregory Neil Shapirodnl are identical, i.e., if address A is mapped to A.
105440266059SGregory Neil Shapirodnl it does not deal with multi-level recursion
105540266059SGregory Neil Shapiro# handle full domains in RHS of virtusertable
105640266059SGregory Neil ShapiroR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
105740266059SGregory Neil ShapiroR$+ < @ $+ > 			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
105840266059SGregory Neil ShapiroR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
105940266059SGregory Neil ShapiroR<?> $+ $| $*			$: $1',
106040266059SGregory Neil Shapiro`dnl')
106106f25ae9SGregory Neil ShapiroR$+			$: <!> $1		Mark for lookup
106240266059SGregory Neil Shapirodnl input: <!> local<@domain>
106306f25ae9SGregory Neil Shapiroifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
106406f25ae9SGregory Neil Shapiro`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
106506f25ae9SGregory Neil Shapiro`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
106640266059SGregory Neil Shapirodnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
106706f25ae9SGregory Neil ShapiroR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
106840266059SGregory Neil Shapirodnl if <@> local<@domain>: no match but try lookup
106940266059SGregory Neil Shapirodnl user+detail: try user++@domain if detail not empty
107040266059SGregory Neil ShapiroR<@> $+ + $+ < @ $* . >
107140266059SGregory Neil Shapiro			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
107240266059SGregory Neil Shapirodnl user+detail: try user+*@domain
1073c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
107440266059SGregory Neil Shapiro			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
107540266059SGregory Neil Shapirodnl user+detail: try user@domain
1076c2aa98e2SPeter WemmR<@> $+ + $* < @ $* . >
107740266059SGregory Neil Shapiro			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
107806f25ae9SGregory Neil Shapirodnl try default entry: @domain
107940266059SGregory Neil Shapirodnl ++@domain
108040266059SGregory Neil ShapiroR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
108106f25ae9SGregory Neil Shapirodnl +*@domain
108240266059SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
108306f25ae9SGregory Neil Shapirodnl @domain if +detail exists
108494c01205SGregory Neil Shapirodnl if no match, change marker to prevent a second @domain lookup
108594c01205SGregory Neil ShapiroR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
108694c01205SGregory Neil Shapirodnl without +detail
1087c2aa98e2SPeter WemmR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
108840266059SGregory Neil Shapirodnl no match
1089c2aa98e2SPeter WemmR<@> $+			$: $1
109040266059SGregory Neil Shapirodnl remove mark
109106f25ae9SGregory Neil ShapiroR<!> $+			$: $1
109206f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1093c2aa98e2SPeter WemmR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
109440266059SGregory Neil Shapiroifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
109540266059SGregory Neil Shapiro# check virtuser input address against output address, if same, skip recursion
109640266059SGregory Neil ShapiroR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
109740266059SGregory Neil Shapiro# it is the same: stop now
109840266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
109940266059SGregory Neil ShapiroR< $+ > $+ < @ $+ > $| $* 			$: < $1 > $2 < @ $3 >
110040266059SGregory Neil Shapirodnl', `dnl')
110113058a91SGregory Neil Shapirodnl this is not a documented option
110213058a91SGregory Neil Shapirodnl it performs no looping at all for virtusertable
11038774250cSGregory Neil Shapiroifdef(`_NO_VIRTUSER_RECURSION_',
11048774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11058774250cSGregory Neil Shapiro`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11068774250cSGregory Neil Shapirodnl', `dnl')
1107c2aa98e2SPeter Wemm
1108c2aa98e2SPeter Wemm# short circuit local delivery so forwarded email works
1109c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `dnl
111006f25ae9SGregory Neil ShapiroR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
111142e5d165SGregory Neil Shapiro
111242e5d165SGregory Neil Shapiro
1113c2aa98e2SPeter Wemmifdef(`_STICKY_LOCAL_DOMAIN_',
1114c2aa98e2SPeter Wemm`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
111506f25ae9SGregory Neil ShapiroR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
111606f25ae9SGregory Neil Shapirodnl $H empty (but @$=w.)
1117c2aa98e2SPeter WemmR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
1118c2aa98e2SPeter WemmR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
1119c2aa98e2SPeter Wemm`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
1120c2aa98e2SPeter WemmR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
1121c2aa98e2SPeter Wemm
112206f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
1123c2aa98e2SPeter Wemm# not local -- try mailer table lookup
1124c2aa98e2SPeter WemmR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
1125c2aa98e2SPeter WemmR< $+ . > $*		$: < $1 > $2			strip trailing dot
1126c2aa98e2SPeter WemmR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
112706f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
112806f25ae9SGregory Neil ShapiroR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
112906f25ae9SGregory Neil ShapiroR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
1130c2aa98e2SPeter Wemm`dnl')
113106f25ae9SGregory Neil Shapiroundivert(4)dnl UUCP rules from `MAILER(uucp)'
1132c2aa98e2SPeter Wemm
1133c2aa98e2SPeter Wemmifdef(`_NO_UUCP_', `dnl',
1134c2aa98e2SPeter Wemm`# resolve remotely connected UUCP links (if any)
1135c2aa98e2SPeter Wemmifdef(`_CLASS_V_',
113606f25ae9SGregory Neil Shapiro`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
1137c2aa98e2SPeter Wemm	`dnl')
1138c2aa98e2SPeter Wemmifdef(`_CLASS_W_',
113906f25ae9SGregory Neil Shapiro`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
1140c2aa98e2SPeter Wemm	`dnl')
1141c2aa98e2SPeter Wemmifdef(`_CLASS_X_',
114206f25ae9SGregory Neil Shapiro`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
1143c2aa98e2SPeter Wemm	`dnl')')
1144c2aa98e2SPeter Wemm
1145c2aa98e2SPeter Wemm# resolve fake top level domains by forwarding to other hosts
1146c2aa98e2SPeter Wemmifdef(`BITNET_RELAY',
114706f25ae9SGregory Neil Shapiro`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
1148c2aa98e2SPeter Wemm	`dnl')
1149c2aa98e2SPeter Wemmifdef(`DECNET_RELAY',
115006f25ae9SGregory Neil Shapiro`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
1151c2aa98e2SPeter Wemm	`dnl')
1152c2aa98e2SPeter Wemmifdef(`_MAILER_pop_',
1153c2aa98e2SPeter Wemm`R$+ < @ POP. >		$#pop $: $1			user@POP',
1154c2aa98e2SPeter Wemm	`dnl')
1155c2aa98e2SPeter Wemmifdef(`_MAILER_fax_',
1156c2aa98e2SPeter Wemm`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
1157c2aa98e2SPeter Wemm`ifdef(`FAX_RELAY',
115806f25ae9SGregory Neil Shapiro`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
1159c2aa98e2SPeter Wemm	`dnl')')
1160c2aa98e2SPeter Wemm
1161c2aa98e2SPeter Wemmifdef(`UUCP_RELAY',
1162c2aa98e2SPeter Wemm`# forward non-local UUCP traffic to our UUCP relay
116306f25ae9SGregory Neil ShapiroR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
1164c2aa98e2SPeter Wemm`ifdef(`_MAILER_uucp_',
1165c2aa98e2SPeter Wemm`# forward other UUCP traffic straight to UUCP
1166c2aa98e2SPeter WemmR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
1167c2aa98e2SPeter Wemm	`dnl')')
1168c2aa98e2SPeter Wemmifdef(`_MAILER_usenet_', `
1169c2aa98e2SPeter Wemm# addresses sent to net.group.USENET will get forwarded to a newsgroup
117006f25ae9SGregory Neil ShapiroR$+ . USENET		$#usenet $@ usenet $: $1',
1171c2aa98e2SPeter Wemm	`dnl')
1172c2aa98e2SPeter Wemm
1173c2aa98e2SPeter Wemmifdef(`_LOCAL_RULES_',
1174c2aa98e2SPeter Wemm`# figure out what should stay in our local mail system
1175c2aa98e2SPeter Wemmundivert(1)', `dnl')
1176c2aa98e2SPeter Wemm
1177c2aa98e2SPeter Wemm# pass names that still have a host to a smarthost (if defined)
117806f25ae9SGregory Neil ShapiroR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
1179c2aa98e2SPeter Wemm
1180c2aa98e2SPeter Wemm# deal with other remote names
1181c2aa98e2SPeter Wemmifdef(`_MAILER_smtp_',
1182c2aa98e2SPeter Wemm`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
118340266059SGregory Neil Shapiro`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
1184c2aa98e2SPeter Wemm
1185c2aa98e2SPeter Wemm# handle locally delivered names
1186c2aa98e2SPeter WemmR$=L			$#_LOCAL_ $: @ $1		special local names
1187c2aa98e2SPeter WemmR$+			$#_LOCAL_ $: $1			regular local names
1188c2aa98e2SPeter Wemm
1189c2aa98e2SPeter Wemm###########################################################################
1190c2aa98e2SPeter Wemm###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
1191c2aa98e2SPeter Wemm###########################################################################
1192c2aa98e2SPeter Wemm
119306f25ae9SGregory Neil ShapiroSLocal_localaddr
119406f25ae9SGregory Neil ShapiroSlocaladdr=5
119506f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>"Local_localaddr" $1
119640266059SGregory Neil ShapiroR$+ $| $#ok		$@ $1			no change
119706f25ae9SGregory Neil ShapiroR$+ $| $#$*		$#$2
119806f25ae9SGregory Neil ShapiroR$+ $| $*		$: $1
1199c2aa98e2SPeter Wemm
120040266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
120140266059SGregory Neil Shapiro# Preserve rcpt_host in {Host}
120240266059SGregory Neil ShapiroR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
120340266059SGregory Neil ShapiroR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
120440266059SGregory Neil ShapiroR$+ $| $| $+		$: $1			h not set, {Host} set
120540266059SGregory Neil ShapiroR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12066a2f2ff3SGregory Neil ShapiroR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
120740266059SGregory Neil ShapiroR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
120840266059SGregory Neil Shapiro')dnl
120940266059SGregory Neil Shapiro
121040266059SGregory Neil Shapiroifdef(`_FFR_5_', `dnl
121142e5d165SGregory Neil Shapiro# Preserve host in a macro
121242e5d165SGregory Neil ShapiroR$+			$: $(macro {LocalAddrHost} $) $1
121342e5d165SGregory Neil ShapiroR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
1214c2aa98e2SPeter Wemm
121540266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
121642e5d165SGregory Neil Shapiro# deal with plussed users so aliases work nicely
121742e5d165SGregory Neil ShapiroR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
121842e5d165SGregory Neil ShapiroR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
121942e5d165SGregory Neil Shapiro')
1220c2aa98e2SPeter Wemm# prepend an empty "forward host" on the front
1221c2aa98e2SPeter WemmR$+			$: <> $1
1222c2aa98e2SPeter Wemm
1223c2aa98e2SPeter Wemmifdef(`LUSER_RELAY', `dnl
1224c2aa98e2SPeter Wemm# send unrecognized local users to a relay host
122540266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
122642e5d165SGregory Neil ShapiroR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
122742e5d165SGregory Neil ShapiroR< > $+			$: < ? $L > < > $(user $1 $)	look up user
122842e5d165SGregory Neil ShapiroR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
122942e5d165SGregory Neil ShapiroR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
123006f25ae9SGregory Neil ShapiroR< > $+ 		$: < $L > $(user $1 $)		look up user
123140266059SGregory Neil ShapiroR< $* > $+ <>		$: < > $2			found; strip $L')
123240266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
123340266059SGregory Neil ShapiroR< $+ > $+		$: < $1 > $2 $&{Host}')
123440266059SGregory Neil Shapirodnl')
1235c2aa98e2SPeter Wemm
123640266059SGregory Neil Shapiroifdef(`MAIL_HUB', `dnl
123740266059SGregory Neil ShapiroR< > $+			$: < $H > $1			try hub', `dnl')
123840266059SGregory Neil Shapiroifdef(`LOCAL_RELAY', `dnl
123940266059SGregory Neil ShapiroR< > $+			$: < $R > $1			try relay', `dnl')
124040266059SGregory Neil Shapiroifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
124140266059SGregory Neil ShapiroR< > $+			$@ $1', `dnl
124206f25ae9SGregory Neil ShapiroR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
124340266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
124440266059SGregory Neil ShapiroR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
124506f25ae9SGregory Neil ShapiroR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
124606f25ae9SGregory Neil ShapiroR< > < $+ <> $* >	$: < > < $1 >			else discard
1247c2aa98e2SPeter WemmR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
124842e5d165SGregory Neil ShapiroR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
1249c2aa98e2SPeter WemmR< > < $+ >		$@ $1				no +detail
12502e43090eSPeter WemmR$+			$: $1 <> $&h			add +detail back in
125140266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
125240266059SGregory Neil ShapiroR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
12532e43090eSPeter WemmR$+ <> + $*		$: $1 + $2			check whether +detail
125442e5d165SGregory Neil ShapiroR$+ <> $*		$: $1				else discard')
125506f25ae9SGregory Neil ShapiroR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
125606f25ae9SGregory Neil ShapiroR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
125740266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
125840266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
125940266059SGregory Neil ShapiroR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
126040266059SGregory Neil ShapiroR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
126140266059SGregory Neil Shapiroifdef(`_PRESERVE_LUSER_HOST_', `dnl
126240266059SGregory Neil ShapiroR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
126306f25ae9SGregory Neil ShapiroR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
1264c2aa98e2SPeter Wemm
126506f25ae9SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
126640266059SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
126740266059SGregory Neil Shapiro###################################################################
126840266059SGregory Neil Shapiro###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
126940266059SGregory Neil Shapirodnl input: <Domain> FullAddress
127040266059SGregory Neil Shapiro###################################################################
127140266059SGregory Neil Shapiro
127240266059SGregory Neil ShapiroSLDAPMailertable
127340266059SGregory Neil ShapiroR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
127440266059SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
127540266059SGregory Neil ShapiroR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
127640266059SGregory Neil ShapiroR< $+ > $#$*		$#$2					found
127740266059SGregory Neil ShapiroR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
127840266059SGregory Neil Shapiro`dnl')
127940266059SGregory Neil Shapiro
1280c2aa98e2SPeter Wemm###################################################################
1281c2aa98e2SPeter Wemm###  Ruleset 90 -- try domain part of mailertable entry 	###
128206f25ae9SGregory Neil Shapirodnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
1283c2aa98e2SPeter Wemm###################################################################
1284c2aa98e2SPeter Wemm
128506f25ae9SGregory Neil ShapiroSMailertable=90
128606f25ae9SGregory Neil Shapirodnl shift and check
128706f25ae9SGregory Neil Shapirodnl %2 is not documented in cf/README
1288c2aa98e2SPeter WemmR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
128906f25ae9SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
129006f25ae9SGregory Neil ShapiroR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
129106f25ae9SGregory Neil ShapiroR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
129206f25ae9SGregory Neil Shapirodnl is $2 always empty?
1293c2aa98e2SPeter WemmR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
129406f25ae9SGregory Neil ShapiroR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
129506f25ae9SGregory Neil Shapirodnl return full address
1296c2aa98e2SPeter WemmR< $* > $*		$@ $2				no mailertable match',
1297c2aa98e2SPeter Wemm`dnl')
1298c2aa98e2SPeter Wemm
1299c2aa98e2SPeter Wemm###################################################################
1300c2aa98e2SPeter Wemm###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
130106f25ae9SGregory Neil Shapirodnl input: in general: <[mailer:]host> lp<@domain>rest
130206f25ae9SGregory Neil Shapirodnl	<> address				-> address
130306f25ae9SGregory Neil Shapirodnl	<error:d.s.n:text>			-> error
1304a7ec597cSGregory Neil Shapirodnl	<error:keyword:text>			-> error
130506f25ae9SGregory Neil Shapirodnl	<error:text>				-> error
130606f25ae9SGregory Neil Shapirodnl	<mailer:user@host> lp<@domain>rest	-> mailer host user
130706f25ae9SGregory Neil Shapirodnl	<mailer:host> address			-> mailer host address
130806f25ae9SGregory Neil Shapirodnl	<localdomain> address			-> address
130906f25ae9SGregory Neil Shapirodnl	<host> address				-> relay host address
1310c2aa98e2SPeter Wemm###################################################################
1311c2aa98e2SPeter Wemm
131206f25ae9SGregory Neil ShapiroSMailerToTriple=95
1313c2aa98e2SPeter WemmR< > $*				$@ $1			strip off null relay
131406f25ae9SGregory Neil ShapiroR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
1315a7ec597cSGregory Neil ShapiroR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
1316a7ec597cSGregory Neil ShapiroR< error : $+ > $*		$#error $: $1
1317c2aa98e2SPeter WemmR< local : $* > $*		$>CanonLocal < $1 > $2
131840266059SGregory Neil Shapirodnl it is $~[ instead of $- to avoid matches on IPv6 addresses
131940266059SGregory Neil ShapiroR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
132040266059SGregory Neil ShapiroR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
1321c2aa98e2SPeter WemmR< $=w > $*			$@ $2			delete local host
1322c2aa98e2SPeter WemmR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
1323c2aa98e2SPeter Wemm
1324c2aa98e2SPeter Wemm###################################################################
1325c2aa98e2SPeter Wemm###  Ruleset CanonLocal -- canonify local: syntax		###
132606f25ae9SGregory Neil Shapirodnl input: <user> address
132706f25ae9SGregory Neil Shapirodnl <x> <@host> : rest			-> Recurse rest
132806f25ae9SGregory Neil Shapirodnl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
132906f25ae9SGregory Neil Shapirodnl <> user <@host> rest		-> local user@host user
133006f25ae9SGregory Neil Shapirodnl <> user				-> local user user
133106f25ae9SGregory Neil Shapirodnl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
133206f25ae9SGregory Neil Shapirodnl <user> lp <@host> rest		-> local lp@host user
133306f25ae9SGregory Neil Shapirodnl <user> lp				-> local lp user
1334c2aa98e2SPeter Wemm###################################################################
1335c2aa98e2SPeter Wemm
1336c2aa98e2SPeter WemmSCanonLocal
13372e43090eSPeter Wemm# strip local host from routed addresses
133806f25ae9SGregory Neil ShapiroR< $* > < @ $+ > : $+		$@ $>Recurse $3
133906f25ae9SGregory Neil ShapiroR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
13402e43090eSPeter Wemm
1341c2aa98e2SPeter Wemm# strip trailing dot from any host name that may appear
1342c2aa98e2SPeter WemmR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
1343c2aa98e2SPeter Wemm
1344c2aa98e2SPeter Wemm# handle local: syntax -- use old user, either with or without host
1345c2aa98e2SPeter WemmR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
1346c2aa98e2SPeter WemmR< > $+				$#_LOCAL_ $@ $1    $: $1
1347c2aa98e2SPeter Wemm
1348c2aa98e2SPeter Wemm# handle local:user@host syntax -- ignore host part
1349c2aa98e2SPeter WemmR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
1350c2aa98e2SPeter Wemm
1351c2aa98e2SPeter Wemm# handle local:user syntax
1352c2aa98e2SPeter WemmR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
1353c2aa98e2SPeter WemmR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
1354c2aa98e2SPeter Wemm
1355c2aa98e2SPeter Wemm###################################################################
1356c2aa98e2SPeter Wemm###  Ruleset 93 -- convert header names to masqueraded form	###
1357c2aa98e2SPeter Wemm###################################################################
1358c2aa98e2SPeter Wemm
135906f25ae9SGregory Neil ShapiroSMasqHdr=93
1360c2aa98e2SPeter Wemm
136106f25ae9SGregory Neil Shapiroifdef(`_GENERICS_TABLE_', `dnl
1362c2aa98e2SPeter Wemm# handle generics database
1363c2aa98e2SPeter Wemmifdef(`_GENERICS_ENTIRE_DOMAIN_',
136406f25ae9SGregory Neil Shapirodnl if generics should be applied add a @ as mark
1365c2aa98e2SPeter Wemm`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
1366c2aa98e2SPeter Wemm`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
1367c2aa98e2SPeter WemmR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
136806f25ae9SGregory Neil Shapirodnl workspace: either user<@domain> or <user@domain> user <@domain> @
136906f25ae9SGregory Neil Shapirodnl ignore the first case for now
137006f25ae9SGregory Neil Shapirodnl if it has the mark lookup full address
137140266059SGregory Neil Shapirodnl broken: %1 is full address not just detail
137206f25ae9SGregory Neil ShapiroR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
137306f25ae9SGregory Neil Shapirodnl workspace: ... or <match|@user@domain> user <@domain>
137406f25ae9SGregory Neil Shapirodnl no match, try user+detail@domain
137506f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
137606f25ae9SGregory Neil Shapiro		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
137706f25ae9SGregory Neil ShapiroR<@$+ + $* @ $+> $+ < @ $+ >
137806f25ae9SGregory Neil Shapiro		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
137906f25ae9SGregory Neil Shapirodnl no match, remove mark
138006f25ae9SGregory Neil ShapiroR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
138106f25ae9SGregory Neil Shapirodnl no match, try @domain for exceptions
138206f25ae9SGregory Neil ShapiroR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
138306f25ae9SGregory Neil Shapirodnl workspace: ... or <match> user <@domain>
138406f25ae9SGregory Neil Shapirodnl no match, try local part
1385c2aa98e2SPeter WemmR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
138606f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
138706f25ae9SGregory Neil ShapiroR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
138806f25ae9SGregory Neil ShapiroR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
138906f25ae9SGregory Neil ShapiroR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
1390c2aa98e2SPeter WemmR< > $*			$: $1				not found',
1391c2aa98e2SPeter Wemm`dnl')
1392c2aa98e2SPeter Wemm
139306f25ae9SGregory Neil Shapiro# do not masquerade anything in class N
139406f25ae9SGregory Neil ShapiroR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
139506f25ae9SGregory Neil Shapiro
139640266059SGregory Neil Shapiroifdef(`MASQUERADE_NAME', `dnl
1397c2aa98e2SPeter Wemm# special case the users that should be exposed
1398c2aa98e2SPeter WemmR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
1399c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1400c2aa98e2SPeter Wemm`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
1401c2aa98e2SPeter Wemm`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
1402c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1403c2aa98e2SPeter Wemm`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
1404c2aa98e2SPeter Wemm
1405c2aa98e2SPeter Wemm# handle domain-specific masquerading
1406c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
1407c2aa98e2SPeter Wemm`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
1408c2aa98e2SPeter Wemm`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
1409c2aa98e2SPeter Wemmifdef(`_LIMITED_MASQUERADE_', `dnl',
1410c2aa98e2SPeter Wemm`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
1411c2aa98e2SPeter WemmR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
1412c2aa98e2SPeter WemmR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
1413c2aa98e2SPeter WemmR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
141440266059SGregory Neil Shapirodnl', `dnl no masquerading
141540266059SGregory Neil Shapirodnl just fix *LOCAL* leftovers
141640266059SGregory Neil ShapiroR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
1417c2aa98e2SPeter Wemm
1418c2aa98e2SPeter Wemm###################################################################
1419c2aa98e2SPeter Wemm###  Ruleset 94 -- convert envelope names to masqueraded form	###
1420c2aa98e2SPeter Wemm###################################################################
1421c2aa98e2SPeter Wemm
142206f25ae9SGregory Neil ShapiroSMasqEnv=94
1423c2aa98e2SPeter Wemmifdef(`_MASQUERADE_ENVELOPE_',
142406f25ae9SGregory Neil Shapiro`R$+			$@ $>MasqHdr $1',
1425c2aa98e2SPeter Wemm`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
1426c2aa98e2SPeter Wemm
1427c2aa98e2SPeter Wemm###################################################################
1428c2aa98e2SPeter Wemm###  Ruleset 98 -- local part of ruleset zero (can be null)	###
1429c2aa98e2SPeter Wemm###################################################################
1430c2aa98e2SPeter Wemm
143106f25ae9SGregory Neil ShapiroSParseLocal=98
143206f25ae9SGregory Neil Shapiroundivert(3)dnl LOCAL_RULE_0
1433c2aa98e2SPeter Wemm
143406f25ae9SGregory Neil Shapiroifdef(`_LDAP_ROUTING_', `dnl
143540266059SGregory Neil Shapiro######################################################################
143640266059SGregory Neil Shapiro###  LDAPExpand: Expand address using LDAP routing
143740266059SGregory Neil Shapiro###
143840266059SGregory Neil Shapiro###	Parameters:
143940266059SGregory Neil Shapiro###		<$1> -- parsed address (user < @ domain . >) (pass through)
144040266059SGregory Neil Shapiro###		<$2> -- RFC822 address (user @ domain) (used for lookup)
144140266059SGregory Neil Shapiro###		<$3> -- +detail information
144240266059SGregory Neil Shapiro###
144340266059SGregory Neil Shapiro###	Returns:
144440266059SGregory Neil Shapiro###		Mailer triplet ($#mailer $@ host $: address)
144540266059SGregory Neil Shapiro###		Parsed address (user < @ domain . >)
144640266059SGregory Neil Shapiro######################################################################
144740266059SGregory Neil Shapiro
1448e92d3f3fSGregory Neil Shapiro# SMTP operation modes
1449e92d3f3fSGregory Neil ShapiroC{SMTPOpModes} s d D
1450e92d3f3fSGregory Neil Shapiro
145106f25ae9SGregory Neil ShapiroSLDAPExpand
145206f25ae9SGregory Neil Shapiro# do the LDAP lookups
145340266059SGregory Neil ShapiroR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
145406f25ae9SGregory Neil Shapiro
1455e92d3f3fSGregory Neil Shapiro# look for temporary failures and...
1456e92d3f3fSGregory Neil ShapiroR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1457e92d3f3fSGregory Neil ShapiroR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
1458e92d3f3fSGregory Neil Shapiroifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
1459e92d3f3fSGregory Neil Shapiro# ... temp fail RCPT SMTP commands
1460e92d3f3fSGregory Neil ShapiroR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."')
1461e92d3f3fSGregory Neil Shapiro# ... return original address for MTA to queue up
1462e92d3f3fSGregory Neil ShapiroR$* $| TMPF <$*> $| $+			$@ $3
1463605302a5SGregory Neil Shapiro
146406f25ae9SGregory Neil Shapiro# if mailRoutingAddress and local or non-existant mailHost,
146506f25ae9SGregory Neil Shapiro# return the new mailRoutingAddress
146640266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
146740266059SGregory Neil ShapiroR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
146840266059SGregory Neil ShapiroR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
146940266059SGregory Neil ShapiroR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
147040266059SGregory Neil ShapiroR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
147106f25ae9SGregory Neil Shapiro
147294c01205SGregory Neil Shapiro
147306f25ae9SGregory Neil Shapiro# if mailRoutingAddress and non-local mailHost,
147406f25ae9SGregory Neil Shapiro# relay to mailHost with new mailRoutingAddress
147540266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
147640266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
147740266059SGregory Neil Shapiro# check mailertable for host, relay from there
147840266059SGregory Neil ShapiroR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
147940266059SGregory Neil Shapiro`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
148040266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
148140266059SGregory Neil Shapiro# check mailertable for host, relay from there
148240266059SGregory Neil ShapiroR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
148340266059SGregory Neil Shapiro`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
148406f25ae9SGregory Neil Shapiro
148506f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and local mailHost,
148606f25ae9SGregory Neil Shapiro# return original address
148740266059SGregory Neil ShapiroR<> <$=w> <$+> <$+> <$*>	$@ $2
148806f25ae9SGregory Neil Shapiro
148994c01205SGregory Neil Shapiro
149006f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and non-local mailHost,
149106f25ae9SGregory Neil Shapiro# relay to mailHost with original address
149240266059SGregory Neil Shapiroifdef(`_MAILER_TABLE_', `dnl
149340266059SGregory Neil Shapiro# check mailertable for host, relay from there
149440266059SGregory Neil ShapiroR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
149540266059SGregory Neil Shapiro`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
149606f25ae9SGregory Neil Shapiro
149740266059SGregory Neil Shapiroifdef(`_LDAP_ROUTE_DETAIL_',
149840266059SGregory Neil Shapiro`# if no mailRoutingAddress and no mailHost,
149940266059SGregory Neil Shapiro# try without +detail
150040266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
150140266059SGregory Neil Shapiro
1502e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_ROUTE_NODOMAIN_', `dnl', `
150340266059SGregory Neil Shapiro# if still no mailRoutingAddress and no mailHost,
150406f25ae9SGregory Neil Shapiro# try @domain
150540266059SGregory Neil Shapiroifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
150640266059SGregory Neil ShapiroR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
1507e92d3f3fSGregory Neil ShapiroR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
150806f25ae9SGregory Neil Shapiro
150906f25ae9SGregory Neil Shapiro# if no mailRoutingAddress and no mailHost and this was a domain attempt,
151006f25ae9SGregory Neil Shapiroifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
151106f25ae9SGregory Neil Shapiro# user does not exist
151240266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
151340266059SGregory Neil Shapiro# only give error for envelope recipient
151440266059SGregory Neil ShapiroR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
1515e92d3f3fSGregory Neil Shapiroifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
1516e92d3f3fSGregory Neil Shapiro# and the sender too
1517e92d3f3fSGregory Neil ShapiroR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
151840266059SGregory Neil ShapiroR<?> <$*> <$+>			$@ $2',
151906f25ae9SGregory Neil Shapiro`dnl
152006f25ae9SGregory Neil Shapiro# return the original address
152140266059SGregory Neil ShapiroR<> <> <$+> <@ $+> <$*>		$@ $1')',
152206f25ae9SGregory Neil Shapiro`dnl')
152306f25ae9SGregory Neil Shapiro
152406f25ae9SGregory Neil Shapiroifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
152506f25ae9SGregory Neil Shapiro')')
152640266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
1527c2aa98e2SPeter Wemm######################################################################
152840266059SGregory Neil Shapiro###  D: LookUpDomain -- search for domain in access database
1529c2aa98e2SPeter Wemm###
1530c2aa98e2SPeter Wemm###	Parameters:
1531c2aa98e2SPeter Wemm###		<$1> -- key (domain name)
1532c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
153306f25ae9SGregory Neil Shapirodnl			must not be empty
153440266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
153506f25ae9SGregory Neil Shapiro###			! does lookup only with tag
153606f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
153740266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
153806f25ae9SGregory Neil Shapirodnl returns:		<default> <passthru>
153906f25ae9SGregory Neil Shapirodnl 			<result> <passthru>
1540c2aa98e2SPeter Wemm######################################################################
1541c2aa98e2SPeter Wemm
154240266059SGregory Neil ShapiroSD
154306f25ae9SGregory Neil Shapirodnl workspace <key> <default> <passthru> <mark>
154406f25ae9SGregory Neil Shapirodnl lookup with tag (in front, no delimiter here)
154540266059SGregory Neil Shapirodnl    2    3  4    5
154640266059SGregory Neil ShapiroR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
154706f25ae9SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
154806f25ae9SGregory Neil Shapirodnl lookup without tag?
154940266059SGregory Neil Shapirodnl   1    2      3    4
155040266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
155140266059SGregory Neil Shapiroifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
155240266059SGregory Neil Shapirodnl XXX apply this also to IP addresses?
155340266059SGregory Neil Shapirodnl currently it works the wrong way round for [1.2.3.4]
155440266059SGregory Neil Shapirodnl   1  2    3    4  5    6
155540266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
155640266059SGregory Neil Shapirodnl   1  2    3      4    5
155740266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
155840266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
155940266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
156040266059SGregory Neil Shapirodnl      1    2    3  4    5
156140266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
156240266059SGregory Neil Shapirodnl not found: IPv4 net (no check is done whether it is an IP number!)
156340266059SGregory Neil Shapirodnl    1  2     3    4  5    6
156440266059SGregory Neil ShapiroR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
156540266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
156640266059SGregory Neil Shapiro`dnl not found: IPv6 net
156740266059SGregory Neil Shapirodnl (could be merged with previous rule if we have a class containing .:)
156840266059SGregory Neil Shapirodnl    1   2     3    4  5    6
156940266059SGregory Neil ShapiroR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
157040266059SGregory Neil ShapiroR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
157106f25ae9SGregory Neil Shapirodnl not found, but subdomain: try again
157240266059SGregory Neil Shapirodnl   1  2    3    4  5    6
157340266059SGregory Neil ShapiroR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
157440266059SGregory Neil Shapiroifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
157540266059SGregory Neil Shapirodnl   1    2      3    4
157640266059SGregory Neil ShapiroR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
157740266059SGregory Neil Shapirodnl not found, no subdomain: return <default> and <passthru>
157840266059SGregory Neil Shapirodnl   1    2    3  4    5
157940266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
158040266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
158140266059SGregory Neil Shapirodnl            2    3    4  5    6
158240266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
158340266059SGregory Neil Shapirodnl return <result of lookup> and <passthru>
158440266059SGregory Neil Shapirodnl    2    3    4  5    6
158540266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
1586c2aa98e2SPeter Wemm
1587c2aa98e2SPeter Wemm######################################################################
158840266059SGregory Neil Shapiro###  A: LookUpAddress -- search for host address in access database
1589c2aa98e2SPeter Wemm###
1590c2aa98e2SPeter Wemm###	Parameters:
1591c2aa98e2SPeter Wemm###		<$1> -- key (dot quadded host address)
1592c2aa98e2SPeter Wemm###		<$2> -- default (what to return if not found in db)
159306f25ae9SGregory Neil Shapirodnl			must not be empty
159440266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
159506f25ae9SGregory Neil Shapiro###			! does lookup only with tag
159606f25ae9SGregory Neil Shapiro###			+ does lookup with and without tag
159740266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed through)
159806f25ae9SGregory Neil Shapirodnl	returns:	<default> <passthru>
159906f25ae9SGregory Neil Shapirodnl			<result> <passthru>
1600c2aa98e2SPeter Wemm######################################################################
1601c2aa98e2SPeter Wemm
160240266059SGregory Neil ShapiroSA
160306f25ae9SGregory Neil Shapirodnl lookup with tag
160440266059SGregory Neil Shapirodnl    2    3  4    5
160540266059SGregory Neil ShapiroR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
160606f25ae9SGregory Neil Shapirodnl lookup without tag
160740266059SGregory Neil Shapirodnl   1    2      3    4
160840266059SGregory Neil ShapiroR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
160940266059SGregory Neil Shapirodnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
161040266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
161140266059SGregory Neil Shapirodnl found SKIP: return <default> and <passthru>
161240266059SGregory Neil Shapirodnl      1    2    3  4    5
161340266059SGregory Neil ShapiroR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
161440266059SGregory Neil Shapiroifdef(`NO_NETINET6', `dnl',
161540266059SGregory Neil Shapiro`dnl no match; IPv6: remove last part
161640266059SGregory Neil Shapirodnl   1   2    3    4  5    6
161740266059SGregory Neil ShapiroR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
161840266059SGregory Neil ShapiroR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
161906f25ae9SGregory Neil Shapirodnl no match; IPv4: remove last part
162040266059SGregory Neil Shapirodnl   1  2    3    4  5    6
162140266059SGregory Neil ShapiroR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
162206f25ae9SGregory Neil Shapirodnl no match: return default
162340266059SGregory Neil Shapirodnl   1    2    3  4    5
162440266059SGregory Neil ShapiroR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
162540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
162640266059SGregory Neil Shapirodnl            2    3    4  5    6
162740266059SGregory Neil ShapiroR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
162806f25ae9SGregory Neil Shapirodnl match: return result
162940266059SGregory Neil Shapirodnl    2    3    4  5    6
163040266059SGregory Neil ShapiroR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
163140266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
163240266059SGregory Neil Shapirodivert(0)
1633c2aa98e2SPeter Wemm######################################################################
1634065a643dSPeter Wemm###  CanonAddr --	Convert an address into a standard form for
1635065a643dSPeter Wemm###			relay checking.  Route address syntax is
1636065a643dSPeter Wemm###			crudely converted into a %-hack address.
1637065a643dSPeter Wemm###
1638065a643dSPeter Wemm###	Parameters:
1639065a643dSPeter Wemm###		$1 -- full recipient address
1640065a643dSPeter Wemm###
1641065a643dSPeter Wemm###	Returns:
1642065a643dSPeter Wemm###		parsed address, not in source route form
164306f25ae9SGregory Neil Shapirodnl		user%host%host<@domain>
164406f25ae9SGregory Neil Shapirodnl		host!user<@domain>
1645065a643dSPeter Wemm######################################################################
1646065a643dSPeter Wemm
1647065a643dSPeter WemmSCanonAddr
164806f25ae9SGregory Neil ShapiroR$*			$: $>Parse0 $>canonify $1	make domain canonical
164906f25ae9SGregory Neil Shapiroifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
1650065a643dSPeter WemmR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
1651065a643dSPeter WemmR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
1652065a643dSPeter WemmR$* < @ $+ > : $*	$3 $1 < @ $2 >
165306f25ae9SGregory Neil Shapirodnl')
1654065a643dSPeter Wemm
1655065a643dSPeter Wemm######################################################################
1656c2aa98e2SPeter Wemm###  ParseRecipient --	Strip off hosts in $=R as well as possibly
1657c2aa98e2SPeter Wemm###			$* $=m or the access database.
1658c2aa98e2SPeter Wemm###			Check user portion for host separators.
1659c2aa98e2SPeter Wemm###
1660c2aa98e2SPeter Wemm###	Parameters:
1661c2aa98e2SPeter Wemm###		$1 -- full recipient address
1662c2aa98e2SPeter Wemm###
1663c2aa98e2SPeter Wemm###	Returns:
1664c2aa98e2SPeter Wemm###		parsed, non-local-relaying address
1665c2aa98e2SPeter Wemm######################################################################
1666c2aa98e2SPeter Wemm
1667c2aa98e2SPeter WemmSParseRecipient
166806f25ae9SGregory Neil Shapirodnl mark and canonify address
1669065a643dSPeter WemmR$*				$: <?> $>CanonAddr $1
167006f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain[.]>
1671c2aa98e2SPeter WemmR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
167206f25ae9SGregory Neil Shapirodnl workspace: <?> localpart<@domain>
1673c2aa98e2SPeter WemmR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
1674c2aa98e2SPeter Wemm
1675c2aa98e2SPeter Wemm# if no $=O character, no host in the user portion, we are done
1676c2aa98e2SPeter WemmR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
167706f25ae9SGregory Neil Shapirodnl no $=O in localpart: return
1678c2aa98e2SPeter WemmR<?> $*				$@ $1
1679c2aa98e2SPeter Wemm
168040266059SGregory Neil Shapirodnl workspace: <NO> localpart<@domain>, where localpart contains $=O
168106f25ae9SGregory Neil Shapirodnl mark everything which has an "authorized" domain with <RELAY>
1682c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
1683c2aa98e2SPeter Wemm# if we relay, check username portion for user%host so host can be checked also
1684c2aa98e2SPeter WemmR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
168506f25ae9SGregory Neil Shapirodnl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
168606f25ae9SGregory Neil Shapirodnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
168740266059SGregory Neil Shapiro
168840266059SGregory Neil Shapirodnl what if access map returns something else than RELAY?
168940266059SGregory Neil Shapirodnl we are only interested in RELAY entries...
169040266059SGregory Neil Shapirodnl other To: entries: blacklist recipient; generic entries?
169140266059SGregory Neil Shapirodnl if it is an error we probably do not want to relay anyway
1692c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
1693c2aa98e2SPeter Wemm`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
169406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
169506f25ae9SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
1696065a643dSPeter WemmR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
1697c2aa98e2SPeter Wemm`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
169806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
169940266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
1700c2aa98e2SPeter WemmR<$+> <$+>			$: <$1> $2',`dnl')')
1701065a643dSPeter Wemm
170206f25ae9SGregory Neil Shapiro
170340266059SGregory Neil Shapiroifdef(`_RELAY_MX_SERVED_', `dnl
170440266059SGregory Neil Shapirodnl do "we" ($=w) act as backup MX server for the destination domain?
170540266059SGregory Neil ShapiroR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
1706e92d3f3fSGregory Neil ShapiroR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
170740266059SGregory Neil Shapirodnl yes: mark it as <RELAY>
170840266059SGregory Neil ShapiroR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
170940266059SGregory Neil Shapirodnl no: put old <NO> mark back
171040266059SGregory Neil ShapiroR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
171140266059SGregory Neil Shapiro
171240266059SGregory Neil Shapirodnl do we relay to this recipient domain?
1713c2aa98e2SPeter WemmR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
171440266059SGregory Neil Shapirodnl something else
171540266059SGregory Neil ShapiroR<$+> $*			$@ $2
1716c2aa98e2SPeter Wemm
171706f25ae9SGregory Neil Shapiro
1718c2aa98e2SPeter Wemm######################################################################
1719c2aa98e2SPeter Wemm###  check_relay -- check hostname/address on SMTP startup
1720c2aa98e2SPeter Wemm######################################################################
1721c2aa98e2SPeter Wemm
1722e92d3f3fSGregory Neil Shapiroifdef(`_CONTROL_IMMEDIATE_',`dnl
1723e92d3f3fSGregory Neil ShapiroScheck_relay
1724e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
1725e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1726e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy', `dnl')
1727e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
1728e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1729e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy', `dnl')
1730e92d3f3fSGregory Neil Shapirodnl')
1731e92d3f3fSGregory Neil Shapiro
1732c2aa98e2SPeter WemmSLocal_check_relay
173306f25ae9SGregory Neil ShapiroScheck`'_U_`'relay
1734e92d3f3fSGregory Neil Shapiroifdef(`_USE_CLIENT_PTR_',`dnl
1735e92d3f3fSGregory Neil ShapiroR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
1736c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_relay" $1
1737c2aa98e2SPeter WemmR$* $| $* $| $#$*	$#$3
1738c2aa98e2SPeter WemmR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
1739c2aa98e2SPeter Wemm
1740c2aa98e2SPeter WemmSBasic_check_relay
1741c2aa98e2SPeter Wemm# check for deferred delivery mode
174294c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1743c2aa98e2SPeter WemmR< d > $*		$@ deferred
1744c2aa98e2SPeter WemmR< $* > $*		$: $2
1745c2aa98e2SPeter Wemm
174606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
174742e5d165SGregory Neil Shapirodnl workspace: {client_name} $| {client_addr}
174840266059SGregory Neil ShapiroR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
174942e5d165SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
175013bd1963SGregory Neil Shapirodnl OR $| $+ if client_name is empty
175113bd1963SGregory Neil ShapiroR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
175213bd1963SGregory Neil Shapirodnl workspace: <result-of-lookup> <{client_addr}>
175340266059SGregory Neil ShapiroR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
175440266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>)
175540266059SGregory Neil ShapiroR<?> <$*>		$: OK				found nothing
175640266059SGregory Neil Shapirodnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
175742e5d165SGregory Neil ShapiroR<$={Accept}> <$*>	$@ $1				return value of lookup
1758e92d3f3fSGregory Neil ShapiroR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
175940266059SGregory Neil ShapiroR<DISCARD> <$*>		$#discard $: discard
1760e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
176106f25ae9SGregory Neil Shapirodnl error tag
176242e5d165SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
176342e5d165SGregory Neil ShapiroR<ERROR:$+> <$*>		$#error $: $1
176440266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
176506f25ae9SGregory Neil Shapirodnl generic error from access map
176642e5d165SGregory Neil ShapiroR<$+> <$*>		$#error $: $1', `dnl')
1767c2aa98e2SPeter Wemm
1768c2aa98e2SPeter Wemmifdef(`_RBL_',`dnl
176906f25ae9SGregory Neil Shapiro# DNS based IP address spam list
177040266059SGregory Neil Shapirodnl workspace: ignored...
1771c2aa98e2SPeter WemmR$*			$: $&{client_addr}
177206f25ae9SGregory Neil ShapiroR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
177306f25ae9SGregory Neil ShapiroR<?>OK			$: OKSOFAR
177494c01205SGregory Neil ShapiroR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
1775c2aa98e2SPeter Wemm`dnl')
1776e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
1777e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
1778e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1779e92d3f3fSGregory Neil ShapiroR$*		$: $>"RateControl" dummy')', `dnl')
1780e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
1781e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
1782e92d3f3fSGregory Neil Shapirodnl workspace: ignored...
1783e92d3f3fSGregory Neil ShapiroR$*		$: $>"ConnControl" dummy')', `dnl')
178406f25ae9SGregory Neil Shapiroundivert(8)
1785c2aa98e2SPeter Wemm
1786c2aa98e2SPeter Wemm######################################################################
1787c2aa98e2SPeter Wemm###  check_mail -- check SMTP ``MAIL FROM:'' command argument
1788c2aa98e2SPeter Wemm######################################################################
1789c2aa98e2SPeter Wemm
1790c2aa98e2SPeter WemmSLocal_check_mail
179106f25ae9SGregory Neil ShapiroScheck`'_U_`'mail
1792c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_mail" $1
1793c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1794c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_mail" $1
1795c2aa98e2SPeter Wemm
1796c2aa98e2SPeter WemmSBasic_check_mail
1797c2aa98e2SPeter Wemm# check for deferred delivery mode
179894c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1799c2aa98e2SPeter WemmR< d > $*		$@ deferred
1800c2aa98e2SPeter WemmR< $* > $*		$: $2
1801c2aa98e2SPeter Wemm
180206f25ae9SGregory Neil Shapiro# authenticated?
180306f25ae9SGregory Neil Shapirodnl done first: we can require authentication for every mail transaction
180406f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM: (sender)
180506f25ae9SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
180606f25ae9SGregory Neil ShapiroR$* $| $#$+		$#$2
180706f25ae9SGregory Neil Shapirodnl undo damage: remove result of tls_client call
180806f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
180906f25ae9SGregory Neil Shapiro
181006f25ae9SGregory Neil Shapirodnl workspace: address as given by MAIL FROM:
181106f25ae9SGregory Neil ShapiroR<>			$@ <OK>			we MUST accept <> (RFC 1123)
181206f25ae9SGregory Neil Shapiroifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
181306f25ae9SGregory Neil Shapirodnl do some additional checks
181406f25ae9SGregory Neil Shapirodnl no user@host
181506f25ae9SGregory Neil Shapirodnl no user@localhost (if nonlocal sender)
181606f25ae9SGregory Neil Shapirodnl this is a pretty simple canonification, it will not catch every case
181706f25ae9SGregory Neil Shapirodnl just make sure the address has <> around it (which is required by
181806f25ae9SGregory Neil Shapirodnl the RFC anyway, maybe we should complain if they are missing...)
181906f25ae9SGregory Neil Shapirodnl dirty trick: if it is user@host, just add a dot: user@host. this will
182006f25ae9SGregory Neil Shapirodnl not be modified by host lookups.
182106f25ae9SGregory Neil ShapiroR$+			$: <?> $1
182206f25ae9SGregory Neil ShapiroR<?><$+>		$: <@> <$1>
182306f25ae9SGregory Neil ShapiroR<?>$+			$: <@> <$1>
182406f25ae9SGregory Neil Shapirodnl workspace: <@> <address>
182506f25ae9SGregory Neil Shapirodnl prepend daemon_flags
182606f25ae9SGregory Neil ShapiroR$*			$: $&{daemon_flags} $| $1
182706f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
182806f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
182906f25ae9SGregory Neil ShapiroR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
183006f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
183106f25ae9SGregory Neil ShapiroR$* u $* $| <@> < $* >	$: <?> < $3 >
183206f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
183306f25ae9SGregory Neil Shapirodnl        or:                    <? ${client_name} > <address>
183406f25ae9SGregory Neil Shapirodnl        or:                    <?> <address>
183506f25ae9SGregory Neil Shapirodnl remove daemon_flags
183606f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
183706f25ae9SGregory Neil Shapiro# handle case of @localhost on address
183806f25ae9SGregory Neil ShapiroR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
183906f25ae9SGregory Neil ShapiroR<@> < $* @ [127.0.0.1] >
184006f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
184106f25ae9SGregory Neil ShapiroR<@> < $* @ localhost.$m >
184206f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.$m >
184306f25ae9SGregory Neil Shapiroifdef(`_NO_UUCP_', `dnl',
184406f25ae9SGregory Neil Shapiro`R<@> < $* @ localhost.UUCP >
184506f25ae9SGregory Neil Shapiro			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
184606f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
184706f25ae9SGregory Neil Shapirodnl	or:    <@> <address>
184806f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
184906f25ae9SGregory Neil ShapiroR<@> $*			$: $1			no localhost as domain
185006f25ae9SGregory Neil Shapirodnl workspace: < ? $&{client_name} > <user@localhost|host>
185106f25ae9SGregory Neil Shapirodnl	or:    <address>
185206f25ae9SGregory Neil Shapirodnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
185306f25ae9SGregory Neil ShapiroR<? $=w> $*		$: $2			local client: ok
185440266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
185506f25ae9SGregory Neil Shapirodnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
185606f25ae9SGregory Neil ShapiroR<?> $*			$: $1')
185706f25ae9SGregory Neil Shapirodnl workspace: address (or <address>)
185806f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
185906f25ae9SGregory Neil Shapirodnl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
186006f25ae9SGregory Neil Shapirodnl there is nothing behind the <@host> so no trailing $* needed
1861065a643dSPeter WemmR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
1862c2aa98e2SPeter Wemm# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
1863959366dcSGregory Neil ShapiroR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
186406f25ae9SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ? or OK
186594c01205SGregory Neil Shapirodnl A sender address with my local host name ($j) is safe
1866959366dcSGregory Neil ShapiroR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
1867c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
186840266059SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
186906f25ae9SGregory Neil Shapiro`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
187006f25ae9SGregory Neil ShapiroR<? $* <$->> $* < @ $+ >
187106f25ae9SGregory Neil Shapiro			$: <$2> $3 < @ $4 >')
187240266059SGregory Neil Shapirodnl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
187306f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1874c2aa98e2SPeter Wemm
187506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
187606f25ae9SGregory Neil Shapiro# check sender address: user@address, user@, address
187706f25ae9SGregory Neil Shapirodnl should we remove +ext from user?
187840266059SGregory Neil Shapirodnl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
187940266059SGregory Neil ShapiroR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
188006f25ae9SGregory Neil ShapiroR<$+> $+		$: @<$1> <$2> $| <U:$2@>
188106f25ae9SGregory Neil Shapirodnl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
188206f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
188306f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
188406f25ae9SGregory Neil ShapiroR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
188506f25ae9SGregory Neil Shapirodnl workspace: <@><mark> <CanonicalAddress> $| <result>
188606f25ae9SGregory Neil ShapiroR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
188706f25ae9SGregory Neil Shapirodnl workspace: <result> <mark> <CanonicalAddress>
1888c2aa98e2SPeter Wemm# retransform for further use
188906f25ae9SGregory Neil Shapirodnl required form:
189006f25ae9SGregory Neil Shapirodnl <ResultOfLookup|mark> CanonicalAddress
189106f25ae9SGregory Neil ShapiroR<?> <$+> <$*>		$: <$1> $2	no match
189206f25ae9SGregory Neil ShapiroR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
189306f25ae9SGregory Neil Shapirodnl workspace <ResultOfLookup|mark> CanonicalAddress
189406f25ae9SGregory Neil Shapirodnl mark is ? iff the address is user (wo @domain)
1895c2aa98e2SPeter Wemm
1896c2aa98e2SPeter Wemmifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
1897c2aa98e2SPeter Wemm# handle case of no @domain on address
189806f25ae9SGregory Neil Shapirodnl prepend daemon_flags
189906f25ae9SGregory Neil ShapiroR<?> $*			$: $&{daemon_flags} $| <?> $1
190006f25ae9SGregory Neil Shapirodnl accept unqualified sender: change mark to avoid test
190140266059SGregory Neil ShapiroR$* u $* $| <?> $*	$: <_RES_OK_> $3
190206f25ae9SGregory Neil Shapirodnl remove daemon_flags
190306f25ae9SGregory Neil ShapiroR$* $| $*		$: $2
190413bd1963SGregory Neil ShapiroR<?> $*			$: < ? $&{client_addr} > $1
1905959366dcSGregory Neil ShapiroR<?> $*			$@ <_RES_OK_>			...local unqualed ok
190640266059SGregory Neil ShapiroR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
1907c2aa98e2SPeter Wemm							...remote is not')
1908c2aa98e2SPeter Wemm# check results
190906f25ae9SGregory Neil ShapiroR<?> $*			$: @ $1		mark address: nothing known about it
191040266059SGregory Neil ShapiroR<$={ResOk}> $*		$@ <_RES_OK_>	domain ok: stop
191106f25ae9SGregory Neil ShapiroR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
191240266059SGregory Neil ShapiroR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
191306f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
191440266059SGregory Neil ShapiroR<$={Accept}> $*	$# $1		accept from access map
1915c2aa98e2SPeter WemmR<DISCARD> $*		$#discard $: discard
1916e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
1917e92d3f3fSGregory Neil ShapiroR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
191806f25ae9SGregory Neil Shapirodnl error tag
191906f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
192006f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
192140266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
192206f25ae9SGregory Neil Shapirodnl generic error from access map
192306f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db',
1924c2aa98e2SPeter Wemm`dnl')
1925c2aa98e2SPeter Wemm
1926c2aa98e2SPeter Wemm######################################################################
1927c2aa98e2SPeter Wemm###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
1928c2aa98e2SPeter Wemm######################################################################
1929c2aa98e2SPeter Wemm
1930c2aa98e2SPeter WemmSLocal_check_rcpt
193106f25ae9SGregory Neil ShapiroScheck`'_U_`'rcpt
1932c2aa98e2SPeter WemmR$*			$: $1 $| $>"Local_check_rcpt" $1
1933c2aa98e2SPeter WemmR$* $| $#$*		$#$2
1934c2aa98e2SPeter WemmR$* $| $*		$@ $>"Basic_check_rcpt" $1
1935c2aa98e2SPeter Wemm
1936c2aa98e2SPeter WemmSBasic_check_rcpt
193740266059SGregory Neil Shapiro# empty address?
193840266059SGregory Neil ShapiroR<>			$#error $@ nouser $: "553 User address required"
193940266059SGregory Neil ShapiroR$@			$#error $@ nouser $: "553 User address required"
1940c2aa98e2SPeter Wemm# check for deferred delivery mode
194194c01205SGregory Neil ShapiroR$*			$: < $&{deliveryMode} > $1
1942c2aa98e2SPeter WemmR< d > $*		$@ deferred
1943c2aa98e2SPeter WemmR< $* > $*		$: $2
1944c2aa98e2SPeter Wemm
194506f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
194640266059SGregory Neil Shapirodnl this code checks for user@host where host is not a FQHN.
194740266059SGregory Neil Shapirodnl it is not activated.
194840266059SGregory Neil Shapirodnl notice: code to check for a recipient without a domain name is
194940266059SGregory Neil Shapirodnl available down below; look for the same macro.
195040266059SGregory Neil Shapirodnl this check is done here because the name might be qualified by the
195140266059SGregory Neil Shapirodnl canonicalization.
195240266059SGregory Neil Shapiro# require fully qualified domain part?
195340266059SGregory Neil Shapirodnl very simple canonification: make sure the address is in < >
195406f25ae9SGregory Neil ShapiroR$+			$: <?> $1
195506f25ae9SGregory Neil ShapiroR<?> <$+>		$: <@> <$1>
195606f25ae9SGregory Neil ShapiroR<?> $+			$: <@> <$1>
195740266059SGregory Neil ShapiroR<@> < postmaster >	$: postmaster
195813bd1963SGregory Neil ShapiroR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
195906f25ae9SGregory Neil Shapirodnl prepend daemon_flags
196040266059SGregory Neil ShapiroR<@> $*			$: $&{daemon_flags} $| <@> $1
196106f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <@> <address>
1962a7ec597cSGregory Neil Shapirodnl 'r'equire qual.rcpt: ok
1963a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
196406f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
1965a7ec597cSGregory Neil ShapiroR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
196606f25ae9SGregory Neil ShapiroR<?> < $* >		$: <$1>
196706f25ae9SGregory Neil ShapiroR<? $=w> < $* >		$: <$1>
196840266059SGregory Neil ShapiroR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
196906f25ae9SGregory Neil Shapirodnl remove daemon_flags for other cases
197006f25ae9SGregory Neil ShapiroR$* $| <@> $*		$: $2', `dnl')
197106f25ae9SGregory Neil Shapiro
197240266059SGregory Neil Shapirodnl ##################################################################
197340266059SGregory Neil Shapirodnl call subroutines for recipient and relay
197440266059SGregory Neil Shapirodnl possible returns from subroutines:
197540266059SGregory Neil Shapirodnl $#TEMP	temporary failure
197640266059SGregory Neil Shapirodnl $#error	permanent failure (or temporary if from access map)
197740266059SGregory Neil Shapirodnl $#other	stop processing
197840266059SGregory Neil Shapirodnl RELAY	RELAYing allowed
197940266059SGregory Neil Shapirodnl other	otherwise
198040266059SGregory Neil Shapiro######################################################################
198140266059SGregory Neil ShapiroR$*			$: $1 $| @ $>"Rcpt_ok" $1
198240266059SGregory Neil Shapirodnl temporary failure? remove mark @ and remember
198340266059SGregory Neil ShapiroR$* $| @ $#TEMP $+	$: $1 $| T $2
198440266059SGregory Neil Shapirodnl error or ok (stop)
198540266059SGregory Neil ShapiroR$* $| @ $#$*		$#$2
198640266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
198740266059SGregory Neil ShapiroR$* $| @ RELAY		$@ RELAY
198840266059SGregory Neil Shapirodnl something else: call check sender (relay)
198940266059SGregory Neil ShapiroR$* $| @ $*		$: O $| $>"Relay_ok" $1
199040266059SGregory Neil Shapirodnl temporary failure: call check sender (relay)
199140266059SGregory Neil ShapiroR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
199240266059SGregory Neil Shapirodnl temporary failure? return that
199340266059SGregory Neil ShapiroR$* $| $#TEMP $+	$#error $2
199440266059SGregory Neil Shapirodnl error or ok (stop)
199540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
199640266059SGregory Neil ShapiroR$* $| RELAY		$@ RELAY
199740266059SGregory Neil Shapirodnl something else: return previous temp failure
199840266059SGregory Neil ShapiroR T $+ $| $*		$#error $1
199940266059SGregory Neil Shapiro# anything else is bogus
200040266059SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: confRELAY_MSG
200140266059SGregory Neil Shapirodivert(0)
200240266059SGregory Neil Shapiro
200340266059SGregory Neil Shapiro######################################################################
200440266059SGregory Neil Shapiro### Rcpt_ok: is the recipient ok?
200540266059SGregory Neil Shapirodnl input: recipient address (RCPT TO)
200640266059SGregory Neil Shapirodnl output: see explanation at call
200740266059SGregory Neil Shapiro######################################################################
200840266059SGregory Neil ShapiroSRcpt_ok
2009c2aa98e2SPeter Wemmifdef(`_LOOSE_RELAY_CHECK_',`dnl
2010065a643dSPeter WemmR$*			$: $>CanonAddr $1
2011c2aa98e2SPeter WemmR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
2012c2aa98e2SPeter Wemm`R$*			$: $>ParseRecipient $1		strip relayable hosts')
2013c2aa98e2SPeter Wemm
2014065a643dSPeter Wemmifdef(`_BESTMX_IS_LOCAL_',`dnl
2015065a643dSPeter Wemmifelse(_BESTMX_IS_LOCAL_, `', `dnl
2016065a643dSPeter Wemm# unlimited bestmx
2017065a643dSPeter WemmR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
2018065a643dSPeter Wemm`dnl
2019065a643dSPeter Wemm# limit bestmx to $=B
20202e43090eSPeter WemmR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
202140266059SGregory Neil ShapiroR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
2022065a643dSPeter WemmR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
2023065a643dSPeter WemmR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
2024065a643dSPeter Wemm
2025c2aa98e2SPeter Wemmifdef(`_BLACKLIST_RCPT_',`dnl
202606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2027c2aa98e2SPeter Wemm# blacklist local users or any host from receiving mail
2028c2aa98e2SPeter WemmR$*			$: <?> $1
202906f25ae9SGregory Neil Shapirodnl user is now tagged with @ to be consistent with check_mail
203006f25ae9SGregory Neil Shapirodnl and to distinguish users from hosts (com would be host, com@ would be user)
203140266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
203240266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
203306f25ae9SGregory Neil ShapiroR<?> $+			$: <> <$1> $| <U:$1@>
203406f25ae9SGregory Neil Shapirodnl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
203506f25ae9SGregory Neil Shapirodnl will only return user<@domain when "reversing" the args
203606f25ae9SGregory Neil ShapiroR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
203706f25ae9SGregory Neil ShapiroR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
203806f25ae9SGregory Neil ShapiroR<?> <$*>		$: @ $1		mark address as no match
203940266059SGregory Neil Shapirodnl we may have to filter here because otherwise some RHSs
204040266059SGregory Neil Shapirodnl would be interpreted as generic error messages...
204140266059SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
204240266059SGregory Neil Shapirodnl that would make a lot of things easier.
204306f25ae9SGregory Neil ShapiroR<$={Accept}> <$*>	$: @ $2		mark address as no match
204440266059SGregory Neil Shapiroifdef(`_ACCESS_SKIP_', `dnl
204540266059SGregory Neil ShapiroR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
204640266059SGregory Neil Shapiroifdef(`_DELAY_COMPAT_8_10_',`dnl
204740266059SGregory Neil Shapirodnl compatility with 8.11/8.10:
204806f25ae9SGregory Neil Shapirodnl we have to filter these because otherwise they would be interpreted
204906f25ae9SGregory Neil Shapirodnl as generic error message...
205006f25ae9SGregory Neil Shapirodnl error messages should be "tagged" by prefixing them with error: !
205106f25ae9SGregory Neil Shapirodnl that would make a lot of things easier.
205206f25ae9SGregory Neil Shapirodnl maybe we should stop checks already here (if SPAM_xyx)?
205306f25ae9SGregory Neil ShapiroR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
205440266059SGregory Neil ShapiroR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
205506f25ae9SGregory Neil ShapiroR<DISCARD> $*		$#discard $: discard
2056e92d3f3fSGregory Neil ShapiroR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
205706f25ae9SGregory Neil Shapirodnl error tag
205806f25ae9SGregory Neil ShapiroR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
205906f25ae9SGregory Neil ShapiroR<ERROR:$+> $*		$#error $: $1
206040266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
206106f25ae9SGregory Neil Shapirodnl generic error from access map
206206f25ae9SGregory Neil ShapiroR<$+> $*		$#error $: $1		error from access db
206306f25ae9SGregory Neil ShapiroR@ $*			$1		remove mark', `dnl')', `dnl')
2064c2aa98e2SPeter Wemm
206540266059SGregory Neil Shapiroifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
206640266059SGregory Neil Shapiro# authenticated via TLS?
206740266059SGregory Neil ShapiroR$*			$: $1 $| $>RelayTLS	client authenticated?
206806f25ae9SGregory Neil ShapiroR$* $| $# $+		$# $2			error/ok?
206906f25ae9SGregory Neil ShapiroR$* $| $*		$: $1			no
207006f25ae9SGregory Neil Shapiro
207140266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
207240266059SGregory Neil Shapirodnl workspace: localpart<@domain> $| result of Local_Relay_Auth
207340266059SGregory Neil ShapiroR$* $| $# $*		$# $2
207440266059SGregory Neil Shapirodnl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
207540266059SGregory Neil ShapiroR$* $| NO		$: $1
207640266059SGregory Neil ShapiroR$* $| $*		$: $1 $| $&{auth_type}
207740266059SGregory Neil Shapirodnl workspace: localpart<@domain> [ $| ${auth_type} ]
207806f25ae9SGregory Neil Shapirodnl empty ${auth_type}?
207906f25ae9SGregory Neil ShapiroR$* $|			$: $1
208006f25ae9SGregory Neil Shapirodnl mechanism ${auth_type} accepted?
208106f25ae9SGregory Neil Shapirodnl use $# to override further tests (delay_checks): see check_rcpt below
208240266059SGregory Neil ShapiroR$* $| $={TrustAuthMech}	$# RELAY
208340266059SGregory Neil Shapirodnl remove ${auth_type}
208406f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
2085193538b7SGregory Neil Shapirodnl workspace: localpart<@domain> | localpart
208606f25ae9SGregory Neil Shapiroifelse(defn(`_NO_UUCP_'), `r',
2087193538b7SGregory Neil Shapiro`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
2088193538b7SGregory Neil ShapiroR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
2089c2aa98e2SPeter Wemm# anything terminating locally is ok
2090c2aa98e2SPeter Wemmifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
209140266059SGregory Neil ShapiroR$+ < @ $* $=m >	$@ RELAY', `dnl')
209240266059SGregory Neil ShapiroR$+ < @ $=w >		$@ RELAY
2093c2aa98e2SPeter Wemmifdef(`_RELAY_HOSTS_ONLY_',
209440266059SGregory Neil Shapiro`R$+ < @ $=R >		$@ RELAY
209506f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
209606f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>
209706f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
209806f25ae9SGregory Neil ShapiroR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
209940266059SGregory Neil Shapiro`R$+ < @ $* $=R >	$@ RELAY
210006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2101e92d3f3fSGregory Neil Shapiroifdef(`_RELAY_FULL_ADDR_', `dnl
2102e92d3f3fSGregory Neil ShapiroR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
2103e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
2104e92d3f3fSGregory Neil ShapiroR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
2105e92d3f3fSGregory Neil Shapiro`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
210606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
210706f25ae9SGregory Neil Shapirodnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
210840266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
210940266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2110c2aa98e2SPeter WemmR<$*> <$*>		$: $2',`dnl')
2111c2aa98e2SPeter Wemm
211206f25ae9SGregory Neil Shapiro
2113c2aa98e2SPeter Wemmifdef(`_RELAY_MX_SERVED_', `dnl
2114c2aa98e2SPeter Wemm# allow relaying for hosts which we MX serve
211506f25ae9SGregory Neil ShapiroR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
211606f25ae9SGregory Neil Shapirodnl this must not necessarily happen if the client is checked first...
2117e92d3f3fSGregory Neil ShapiroR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
211840266059SGregory Neil ShapiroR<$* : $=w . : $*> $*	$@ RELAY
2119065a643dSPeter WemmR< : $* : > $*		$: $2',
2120c2aa98e2SPeter Wemm`dnl')
2121c2aa98e2SPeter Wemm
2122c2aa98e2SPeter Wemm# check for local user (i.e. unqualified address)
2123c2aa98e2SPeter WemmR$*			$: <?> $1
2124065a643dSPeter WemmR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
2125c2aa98e2SPeter Wemm# local user is ok
212606f25ae9SGregory Neil Shapirodnl is it really? the standard requires user@domain, not just user
212706f25ae9SGregory Neil Shapirodnl but we should accept it anyway (maybe making it an option:
212806f25ae9SGregory Neil Shapirodnl RequireFQDN ?)
212906f25ae9SGregory Neil Shapirodnl postmaster must be accepted without domain (DRUMS)
213006f25ae9SGregory Neil Shapiroifdef(`_REQUIRE_QUAL_RCPT_', `dnl
213140266059SGregory Neil ShapiroR<?> postmaster		$@ OK
213206f25ae9SGregory Neil Shapiro# require qualified recipient?
213306f25ae9SGregory Neil Shapirodnl prepend daemon_flags
213406f25ae9SGregory Neil ShapiroR<?> $+			$: $&{daemon_flags} $| <?> $1
213506f25ae9SGregory Neil Shapirodnl workspace: ${daemon_flags} $| <?> localpart
213606f25ae9SGregory Neil Shapirodnl do not allow these at all or only from local systems?
213706f25ae9SGregory Neil Shapirodnl r flag? add client_name
213806f25ae9SGregory Neil ShapiroR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
213906f25ae9SGregory Neil Shapirodnl no r flag: relay to local user (only local part)
214006f25ae9SGregory Neil Shapiro# no qualified recipient required
214140266059SGregory Neil ShapiroR$* $| <?> $+		$@ RELAY
214206f25ae9SGregory Neil Shapirodnl client_name is empty
214340266059SGregory Neil ShapiroR<?> <?> $+		$@ RELAY
214406f25ae9SGregory Neil Shapirodnl client_name is local
214540266059SGregory Neil ShapiroR<? $=w> <?> $+		$@ RELAY
214606f25ae9SGregory Neil Shapirodnl client_name is not local
214706f25ae9SGregory Neil ShapiroR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
214806f25ae9SGregory Neil Shapirodnl no qualified recipient required
214940266059SGregory Neil ShapiroR<?> $+			$@ RELAY')
215006f25ae9SGregory Neil Shapirodnl it is a remote user: remove mark and then check client
2151c2aa98e2SPeter WemmR<$+> $*		$: $2
215206f25ae9SGregory Neil Shapirodnl currently the recipient address is not used below
2153c2aa98e2SPeter Wemm
215440266059SGregory Neil Shapiro######################################################################
215540266059SGregory Neil Shapiro### Relay_ok: is the relay/sender ok?
215640266059SGregory Neil Shapirodnl input: ignored
215740266059SGregory Neil Shapirodnl output: see explanation at call
215840266059SGregory Neil Shapiro######################################################################
215940266059SGregory Neil ShapiroSRelay_ok
2160c2aa98e2SPeter Wemm# anything originating locally is ok
2161c2aa98e2SPeter Wemm# check IP address
2162c2aa98e2SPeter WemmR$*			$: $&{client_addr}
216340266059SGregory Neil ShapiroR$@			$@ RELAY		originated locally
216440266059SGregory Neil ShapiroR0			$@ RELAY		originated locally
216513bd1963SGregory Neil ShapiroR127.0.0.1		$@ RELAY		originated locally
216613bd1963SGregory Neil ShapiroRIPv6:::1		$@ RELAY		originated locally
216740266059SGregory Neil ShapiroR$=R $*			$@ RELAY		relayable IP address
216806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
216940266059SGregory Neil ShapiroR$*			$: $>A <$1> <?> <+ Connect> <$1>
217040266059SGregory Neil ShapiroR<RELAY> $* 		$@ RELAY		relayable IP address
2171959366dcSGregory Neil Shapiroifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
2172959366dcSGregory Neil Shapirodnl this will cause rejections in cases like:
2173959366dcSGregory Neil Shapirodnl Connect:My.Host.Domain	RELAY
2174959366dcSGregory Neil Shapirodnl Connect:My.Net		REJECT
2175959366dcSGregory Neil Shapirodnl since in check_relay client_name is checked before client_addr
2176959366dcSGregory Neil ShapiroR<REJECT> $* 		$@ REJECT		rejected IP address')
217740266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2178c2aa98e2SPeter WemmR<$*> <$*>		$: $2', `dnl')
2179c2aa98e2SPeter WemmR$*			$: [ $1 ]		put brackets around it...
218040266059SGregory Neil ShapiroR$=w			$@ RELAY		... and see if it is local
2181c2aa98e2SPeter Wemm
218206f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
218306f25ae9SGregory Neil Shapiroifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
218406f25ae9SGregory Neil Shapiroifdef(`_RELAY_MAIL_FROM_', `dnl
218506f25ae9SGregory Neil Shapirodnl input: {client_addr} or something "broken"
218606f25ae9SGregory Neil Shapirodnl just throw the input away; we do not need it.
218706f25ae9SGregory Neil Shapiro# check whether FROM is allowed to use system as relay
218806f25ae9SGregory Neil ShapiroR$*			$: <?> $>CanonAddr $&f
218940266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
2190c2aa98e2SPeter Wemmifdef(`_RELAY_LOCAL_FROM_', `dnl
219106f25ae9SGregory Neil Shapiro# check whether local FROM is ok
219240266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
219306f25ae9SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_', `dnl
2194605302a5SGregory Neil ShapiroR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
219540266059SGregory Neil ShapiroR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
219640266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
219740266059SGregory Neil Shapiro', `dnl
219840266059SGregory Neil Shapiroifdef(`_RELAY_DB_FROM_DOMAIN_',
219940266059SGregory Neil Shapiro`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
220006f25ae9SGregory Neil Shapiro')',
220106f25ae9SGregory Neil Shapiro`dnl')
220206f25ae9SGregory Neil Shapirodnl')', `dnl')
220340266059SGregory Neil Shapirodnl notice: the rulesets above do not leave a unique workspace behind.
220440266059SGregory Neil Shapirodnl it does not matter in this case because the following rule ignores
220540266059SGregory Neil Shapirodnl the input. otherwise these rules must "clean up" the workspace.
220606f25ae9SGregory Neil Shapiro
220706f25ae9SGregory Neil Shapiro# check client name: first: did it resolve?
220806f25ae9SGregory Neil Shapirodnl input: ignored
220906f25ae9SGregory Neil ShapiroR$*			$: < $&{client_resolve} >
2210e92d3f3fSGregory Neil ShapiroR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
221106f25ae9SGregory Neil ShapiroR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
221206f25ae9SGregory Neil ShapiroR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
221306f25ae9SGregory Neil Shapirodnl ${client_resolve} should be OK, so go ahead
221440266059SGregory Neil ShapiroR$*			$: <@> $&{client_name}
221506f25ae9SGregory Neil Shapirodnl should not be necessary since it has been done for client_addr already
221613bd1963SGregory Neil Shapirodnl this rule actually may cause a problem if {client_name} resolves to ""
221713bd1963SGregory Neil Shapirodnl however, this should not happen since the forward lookup should fail
221813bd1963SGregory Neil Shapirodnl and {client_resolve} should be TEMP or FAIL.
221913bd1963SGregory Neil Shapirodnl nevertheless, removing the rule doesn't hurt.
222013bd1963SGregory Neil Shapirodnl R<@>			$@ RELAY
222140266059SGregory Neil Shapirodnl workspace: <@> ${client_name} (not empty)
222240266059SGregory Neil Shapiro# pass to name server to make hostname canonical
222340266059SGregory Neil ShapiroR<@> $* $=P 		$:<?>  $1 $2
222440266059SGregory Neil ShapiroR<@> $+			$:<?>  $[ $1 $]
222540266059SGregory Neil Shapirodnl workspace: <?> ${client_name} (canonified)
222640266059SGregory Neil ShapiroR$* .			$1			strip trailing dots
222706f25ae9SGregory Neil Shapiroifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
222840266059SGregory Neil ShapiroR<?> $* $=m		$@ RELAY', `dnl')
222940266059SGregory Neil ShapiroR<?> $=w		$@ RELAY
223006f25ae9SGregory Neil Shapiroifdef(`_RELAY_HOSTS_ONLY_',
223140266059SGregory Neil Shapiro`R<?> $=R		$@ RELAY
223206f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
223306f25ae9SGregory Neil ShapiroR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
223406f25ae9SGregory Neil ShapiroR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
223540266059SGregory Neil Shapiro`R<?> $* $=R			$@ RELAY
223606f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
223740266059SGregory Neil ShapiroR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
223806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
223940266059SGregory Neil ShapiroR<RELAY> $*		$@ RELAY
224040266059SGregory Neil Shapiroifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
224106f25ae9SGregory Neil ShapiroR<$*> <$*>		$: $2',`dnl')
224240266059SGregory Neil Shapirodnl end of _PROMISCUOUS_RELAY_
224306f25ae9SGregory Neil Shapirodivert(0)
224406f25ae9SGregory Neil Shapiroifdef(`_DELAY_CHECKS_',`dnl
224506f25ae9SGregory Neil Shapiro# turn a canonical address in the form user<@domain>
224606f25ae9SGregory Neil Shapiro# qualify unqual. addresses with $j
224706f25ae9SGregory Neil Shapirodnl it might have been only user (without <@domain>)
224806f25ae9SGregory Neil ShapiroSFullAddr
224906f25ae9SGregory Neil ShapiroR$* <@ $+ . >		$1 <@ $2 >
225006f25ae9SGregory Neil ShapiroR$* <@ $* >		$@ $1 <@ $2 >
225106f25ae9SGregory Neil ShapiroR$+			$@ $1 <@ $j >
2252c2aa98e2SPeter Wemm
2253a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt
225413bd1963SGregory Neil Shapiro# authenticated?
225513bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
225613bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if checkrcpt returns $#
225713bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
225813bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
225913bd1963SGregory Neil Shapirodnl return result from checkrcpt
2260a7ec597cSGregory Neil ShapiroR$* $| $*		$# $1
226113bd1963SGregory Neil ShapiroR$*			$# $1
226213bd1963SGregory Neil Shapiro
2263a7ec597cSGregory Neil ShapiroSDelay_TLS_Clt2
226413bd1963SGregory Neil Shapiro# authenticated?
226513bd1963SGregory Neil Shapirodnl code repeated here from Basic_check_mail
226613bd1963SGregory Neil Shapirodnl only called from check_rcpt in delay mode if stopping due to Friend/Hater
226713bd1963SGregory Neil ShapiroR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
226813bd1963SGregory Neil ShapiroR$* $| $#$+		$#$2
226913bd1963SGregory Neil Shapirodnl return result from friend/hater check
2270a7ec597cSGregory Neil ShapiroR$* $| $*		$@ $1
227113bd1963SGregory Neil ShapiroR$*			$@ $1
227213bd1963SGregory Neil Shapiro
227306f25ae9SGregory Neil Shapiro# call all necessary rulesets
227406f25ae9SGregory Neil ShapiroScheck_rcpt
227506f25ae9SGregory Neil Shapirodnl this test should be in the Basic_check_rcpt ruleset
227606f25ae9SGregory Neil Shapirodnl which is the correct DSN code?
227706f25ae9SGregory Neil Shapiro# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
227813bd1963SGregory Neil Shapiro
227906f25ae9SGregory Neil ShapiroR$+			$: $1 $| $>checkrcpt $1
228006f25ae9SGregory Neil Shapirodnl now we can simply stop checks by returning "$# xyz" instead of just "ok"
228113bd1963SGregory Neil Shapirodnl on error (or discard) stop now
228213bd1963SGregory Neil ShapiroR$+ $| $#error $*	$#error $2
228313bd1963SGregory Neil ShapiroR$+ $| $#discard $*	$#discard $2
228413bd1963SGregory Neil Shapirodnl otherwise call tls_client; see above
2285a7ec597cSGregory Neil ShapiroR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
228606f25ae9SGregory Neil ShapiroR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
228706f25ae9SGregory Neil Shapiroifdef(`_SPAM_FH_',
228806f25ae9SGregory Neil Shapiro`dnl lookup user@ and user@address
228906f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `',
229006f25ae9SGregory Neil Shapiro`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
229106f25ae9SGregory Neil Shapiro')')dnl
229206f25ae9SGregory Neil Shapirodnl one of the next two rules is supposed to match
229306f25ae9SGregory Neil Shapirodnl this code has been copied from BLACKLIST... etc
229406f25ae9SGregory Neil Shapirodnl and simplified by omitting some < >.
229540266059SGregory Neil ShapiroR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
229640266059SGregory Neil ShapiroR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
229706f25ae9SGregory Neil Shapirodnl R<?>		$@ something_is_very_wrong_here
229840266059SGregory Neil Shapiro# lookup the addresses only with Spam tag
229940266059SGregory Neil ShapiroR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
230006f25ae9SGregory Neil ShapiroR<@> $* $| $*		$: $2 $1		reverse result
230106f25ae9SGregory Neil Shapirodnl', `dnl')
230206f25ae9SGregory Neil Shapiroifdef(`_SPAM_FRIEND_',
230306f25ae9SGregory Neil Shapiro`# is the recipient a spam friend?
230406f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
230513bd1963SGregory Neil Shapiro	`errprint(`*** ERROR: define either Hater or Friend -- not both.
230606f25ae9SGregory Neil Shapiro')', `dnl')
2307a7ec597cSGregory Neil ShapiroR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
230806f25ae9SGregory Neil ShapiroR<$*> $+		$: $2',
230906f25ae9SGregory Neil Shapiro`dnl')
231006f25ae9SGregory Neil Shapiroifdef(`_SPAM_HATER_',
231106f25ae9SGregory Neil Shapiro`# is the recipient no spam hater?
231240266059SGregory Neil ShapiroR<HATER> $+		$: $1			spam hater: continue checks
2313a7ec597cSGregory Neil ShapiroR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
231406f25ae9SGregory Neil Shapirodnl',`dnl')
231506f25ae9SGregory Neil Shapirodnl run further checks: check_mail
231606f25ae9SGregory Neil Shapirodnl should we "clean up" $&f?
231740266059SGregory Neil Shapiroifdef(`_FFR_MAIL_MACRO',
231840266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail $&{mail_from}',
231940266059SGregory Neil Shapiro`R$*			$: $1 $| $>checkmail <$&f>')
2320605302a5SGregory Neil Shapirodnl recipient (canonical format) $| result of checkmail
232106f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
232206f25ae9SGregory Neil Shapirodnl run further checks: check_relay
2323605302a5SGregory Neil ShapiroR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
232406f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
232506f25ae9SGregory Neil ShapiroR$* $| $*		$: $1
232606f25ae9SGregory Neil Shapiro', `dnl')
232740266059SGregory Neil Shapiro
232840266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
232940266059SGregory Neil Shapiro######################################################################
233040266059SGregory Neil Shapiro###  F: LookUpFull -- search for an entry in access database
233140266059SGregory Neil Shapiro###
233240266059SGregory Neil Shapiro###	lookup of full key (which should be an address) and
233340266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
233440266059SGregory Neil Shapiro###
233540266059SGregory Neil Shapiro###	Parameters:
233640266059SGregory Neil Shapiro###		<$1> -- key
233740266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
233840266059SGregory Neil Shapirodnl			must not be empty
233940266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
234040266059SGregory Neil Shapiro###			! does lookup only with tag
234140266059SGregory Neil Shapiro###			+ does lookup with and without tag
234240266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
234340266059SGregory Neil Shapirodnl returns:		<default> <passthru>
234440266059SGregory Neil Shapirodnl 			<result> <passthru>
234540266059SGregory Neil Shapiro######################################################################
234640266059SGregory Neil Shapiro
234740266059SGregory Neil ShapiroSF
234840266059SGregory Neil Shapirodnl workspace: <key> <def> <o tag> <thru>
234940266059SGregory Neil Shapirodnl full lookup
235040266059SGregory Neil Shapirodnl    2    3  4    5
235140266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
235240266059SGregory Neil Shapirodnl no match, try without tag
235340266059SGregory Neil Shapirodnl   1    2      3    4
235440266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
235540266059SGregory Neil Shapirodnl no match, +detail: try +*
235640266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
235740266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
235840266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
235940266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
236040266059SGregory Neil Shapirodnl   1    2    3    4      5    6
236140266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
236240266059SGregory Neil Shapiro			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
236340266059SGregory Neil Shapirodnl no match, +detail: try without +detail
236440266059SGregory Neil Shapirodnl   1    2    3    4    5  6    7
236540266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
236640266059SGregory Neil Shapiro			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
236740266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
236840266059SGregory Neil Shapirodnl   1    2    3    4      5    6
236940266059SGregory Neil ShapiroR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
237040266059SGregory Neil Shapiro			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
237140266059SGregory Neil Shapirodnl no match, return <default> <passthru>
237240266059SGregory Neil Shapirodnl   1    2    3  4    5
237340266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
237440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
237540266059SGregory Neil Shapirodnl            2    3  4    5
237640266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
237740266059SGregory Neil Shapirodnl match, return <match> <passthru>
237840266059SGregory Neil Shapirodnl    2    3  4    5
237940266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
238040266059SGregory Neil Shapiro
238140266059SGregory Neil Shapiro######################################################################
238240266059SGregory Neil Shapiro###  E: LookUpExact -- search for an entry in access database
238340266059SGregory Neil Shapiro###
238440266059SGregory Neil Shapiro###	Parameters:
238540266059SGregory Neil Shapiro###		<$1> -- key
238640266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
238740266059SGregory Neil Shapirodnl			must not be empty
238840266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
238940266059SGregory Neil Shapiro###			! does lookup only with tag
239040266059SGregory Neil Shapiro###			+ does lookup with and without tag
239140266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
239240266059SGregory Neil Shapirodnl returns:		<default> <passthru>
239340266059SGregory Neil Shapirodnl 			<result> <passthru>
239440266059SGregory Neil Shapiro######################################################################
239540266059SGregory Neil Shapiro
239640266059SGregory Neil ShapiroSE
239740266059SGregory Neil Shapirodnl    2    3  4    5
239840266059SGregory Neil ShapiroR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
239940266059SGregory Neil Shapirodnl no match, try without tag
240040266059SGregory Neil Shapirodnl   1    2      3    4
240140266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
240240266059SGregory Neil Shapirodnl no match, return default passthru
240340266059SGregory Neil Shapirodnl   1    2    3  4    5
240440266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
240540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
240640266059SGregory Neil Shapirodnl            2    3  4    5
240740266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
240840266059SGregory Neil Shapirodnl match, return <match> <passthru>
240940266059SGregory Neil Shapirodnl    2    3  4    5
241040266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
241140266059SGregory Neil Shapiro
241240266059SGregory Neil Shapiro######################################################################
241340266059SGregory Neil Shapiro###  U: LookUpUser -- search for an entry in access database
241440266059SGregory Neil Shapiro###
241540266059SGregory Neil Shapiro###	lookup of key (which should be a local part) and
241640266059SGregory Neil Shapiro###	variations if +detail exists: +* and without +detail
241740266059SGregory Neil Shapiro###
241840266059SGregory Neil Shapiro###	Parameters:
241940266059SGregory Neil Shapiro###		<$1> -- key (user@)
242040266059SGregory Neil Shapiro###		<$2> -- default (what to return if not found in db)
242140266059SGregory Neil Shapirodnl			must not be empty
242240266059SGregory Neil Shapiro###		<$3> -- mark (must be <(!|+) single-token>)
242340266059SGregory Neil Shapiro###			! does lookup only with tag
242440266059SGregory Neil Shapiro###			+ does lookup with and without tag
242540266059SGregory Neil Shapiro###		<$4> -- passthru (additional data passed unchanged through)
242640266059SGregory Neil Shapirodnl returns:		<default> <passthru>
242740266059SGregory Neil Shapirodnl 			<result> <passthru>
242840266059SGregory Neil Shapiro######################################################################
242940266059SGregory Neil Shapiro
243040266059SGregory Neil ShapiroSU
243140266059SGregory Neil Shapirodnl user lookups are always with trailing @
243240266059SGregory Neil Shapirodnl    2    3  4    5
243340266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
243440266059SGregory Neil Shapirodnl no match, try without tag
243540266059SGregory Neil Shapirodnl   1    2      3    4
243640266059SGregory Neil ShapiroR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
243740266059SGregory Neil Shapirodnl do not remove the @ from the lookup:
243840266059SGregory Neil Shapirodnl it is part of the +detail@ which is omitted for the lookup
243940266059SGregory Neil Shapirodnl no match, +detail: try +*
244040266059SGregory Neil Shapirodnl   1    2      3    4  5    6
244140266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
244240266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
244340266059SGregory Neil Shapirodnl no match, +detail: try +* without tag
244440266059SGregory Neil Shapirodnl   1    2      3      4    5
244540266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
244640266059SGregory Neil Shapiro			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
244740266059SGregory Neil Shapirodnl no match, +detail: try without +detail
244840266059SGregory Neil Shapirodnl   1    2      3    4  5    6
244940266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <$- $-> <$*>
245040266059SGregory Neil Shapiro			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
245140266059SGregory Neil Shapirodnl no match, +detail: try without +detail and without tag
245240266059SGregory Neil Shapirodnl   1    2      3      4    5
245340266059SGregory Neil ShapiroR<?> <$+ + $* @> <$*> <+ $-> <$*>
245440266059SGregory Neil Shapiro			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
245540266059SGregory Neil Shapirodnl no match, return <default> <passthru>
245640266059SGregory Neil Shapirodnl   1    2    3  4    5
245740266059SGregory Neil ShapiroR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
245840266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
245940266059SGregory Neil Shapirodnl            2    3  4    5
246040266059SGregory Neil ShapiroR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
246140266059SGregory Neil Shapirodnl match, return <match> <passthru>
246240266059SGregory Neil Shapirodnl    2    3  4    5
246340266059SGregory Neil ShapiroR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
246440266059SGregory Neil Shapiro
246506f25ae9SGregory Neil Shapiro######################################################################
246606f25ae9SGregory Neil Shapiro###  SearchList: search a list of items in the access map
246706f25ae9SGregory Neil Shapiro###	Parameters:
246806f25ae9SGregory Neil Shapiro###		<exact tag> $| <mark:address> <mark:address> ... <>
246906f25ae9SGregory Neil Shapirodnl	maybe we should have a @ (again) in front of the mark to
247006f25ae9SGregory Neil Shapirodnl	avoid errorneous matches (with error messages?)
247106f25ae9SGregory Neil Shapirodnl	if we can make sure that tag is always a single token
247206f25ae9SGregory Neil Shapirodnl	then we can omit the delimiter $|, otherwise we need it
247340266059SGregory Neil Shapirodnl	to avoid errorneous matchs (first rule: D: if there
247406f25ae9SGregory Neil Shapirodnl	is that mark somewhere in the list, it will be taken).
247506f25ae9SGregory Neil Shapirodnl	moreover, we can do some tricks to enforce lookup with
247606f25ae9SGregory Neil Shapirodnl	the tag only, e.g.:
247706f25ae9SGregory Neil Shapiro###	where "exact" is either "+" or "!":
247806f25ae9SGregory Neil Shapiro###	<+ TAG>	lookup with and w/o tag
247906f25ae9SGregory Neil Shapiro###	<! TAG>	lookup with tag
248006f25ae9SGregory Neil Shapirodnl	Warning: + and ! should be in OperatorChars (otherwise there must be
248106f25ae9SGregory Neil Shapirodnl		a blank between them and the tag.
248206f25ae9SGregory Neil Shapiro###	possible values for "mark" are:
248340266059SGregory Neil Shapiro###		D: recursive host lookup (LookUpDomain)
248406f25ae9SGregory Neil Shapirodnl		A: recursive address lookup (LookUpAddress) [not yet required]
248506f25ae9SGregory Neil Shapiro###		E: exact lookup, no modifications
248606f25ae9SGregory Neil Shapiro###		F: full lookup, try user+ext@domain and user@domain
248706f25ae9SGregory Neil Shapiro###		U: user lookup, try user+ext and user (input must have trailing @)
248806f25ae9SGregory Neil Shapiro###	return: <RHS of lookup> or <?> (not found)
248906f25ae9SGregory Neil Shapiro######################################################################
249006f25ae9SGregory Neil Shapiro
249106f25ae9SGregory Neil Shapiro# class with valid marks for SearchList
249206f25ae9SGregory Neil Shapirodnl if A is activated: add it
2493e92d3f3fSGregory Neil ShapiroC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
249406f25ae9SGregory Neil ShapiroSSearchList
249540266059SGregory Neil Shapiro# just call the ruleset with the name of the tag... nice trick...
249640266059SGregory Neil Shapirodnl       2       3    4
2497e92d3f3fSGregory Neil ShapiroR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
249840266059SGregory Neil Shapirodnl workspace: <o tag> $| <rest> $| <result of lookup> <>
249940266059SGregory Neil Shapirodnl no match and nothing left: return
250040266059SGregory Neil ShapiroR<$+> $| <> $| <?> <>		$@ <?>
250140266059SGregory Neil Shapirodnl no match but something left: continue
250240266059SGregory Neil ShapiroR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
250340266059SGregory Neil Shapirodnl match: return
250440266059SGregory Neil ShapiroR<$+> $| <$*> $| <$+> <>	$@ <$3>
250506f25ae9SGregory Neil Shapirodnl return result from recursive invocation
250640266059SGregory Neil ShapiroR<$+> $| <$+>			$@ <$2>
250740266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
250840266059SGregory Neil Shapirodivert(0)
250906f25ae9SGregory Neil Shapiro
251040266059SGregory Neil Shapiro######################################################################
251140266059SGregory Neil Shapiro###  trust_auth: is user trusted to authenticate as someone else?
251240266059SGregory Neil Shapiro###
251340266059SGregory Neil Shapiro###	Parameters:
251440266059SGregory Neil Shapiro###		$1: AUTH= parameter from MAIL command
251540266059SGregory Neil Shapiro######################################################################
251640266059SGregory Neil Shapiro
251740266059SGregory Neil Shapirodnl empty ruleset definition so it can be called
251840266059SGregory Neil ShapiroSLocal_trust_auth
251906f25ae9SGregory Neil ShapiroStrust_auth
252006f25ae9SGregory Neil ShapiroR$*			$: $&{auth_type} $| $1
252106f25ae9SGregory Neil Shapiro# required by RFC 2554 section 4.
252206f25ae9SGregory Neil ShapiroR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
252306f25ae9SGregory Neil Shapirodnl seems to be useful...
252406f25ae9SGregory Neil ShapiroR$* $| $&{auth_authen}		$@ identical
252506f25ae9SGregory Neil ShapiroR$* $| <$&{auth_authen}>	$@ identical
252606f25ae9SGregory Neil Shapirodnl call user supplied code
2527a7ec597cSGregory Neil ShapiroR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
252806f25ae9SGregory Neil ShapiroR$* $| $#$*		$#$2
252906f25ae9SGregory Neil Shapirodnl default: error
253006f25ae9SGregory Neil ShapiroR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
253106f25ae9SGregory Neil Shapiro
253240266059SGregory Neil Shapiro######################################################################
253340266059SGregory Neil Shapiro###  Relay_Auth: allow relaying based on authentication?
253440266059SGregory Neil Shapiro###
253540266059SGregory Neil Shapiro###	Parameters:
253640266059SGregory Neil Shapiro###		$1: ${auth_type}
253740266059SGregory Neil Shapiro######################################################################
253840266059SGregory Neil ShapiroSLocal_Relay_Auth
253906f25ae9SGregory Neil Shapiro
254040266059SGregory Neil Shapiro######################################################################
254140266059SGregory Neil Shapiro###  srv_features: which features to offer to a client?
254240266059SGregory Neil Shapiro###	(done in server)
254340266059SGregory Neil Shapiro######################################################################
254440266059SGregory Neil ShapiroSsrv_features
254540266059SGregory Neil Shapiroifdef(`_LOCAL_SRV_FEATURES_', `dnl
254640266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_srv_features" $1
254740266059SGregory Neil ShapiroR$* $| $#$*		$#$2
254840266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2549e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
255040266059SGregory Neil ShapiroR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
255140266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
255240266059SGregory Neil ShapiroR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
255306f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
255440266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
255540266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#temp', `dnl')
2556e92d3f3fSGregory Neil ShapiroR<$+>$*		$# $1')
255706f25ae9SGregory Neil Shapiro
255840266059SGregory Neil Shapiro######################################################################
255940266059SGregory Neil Shapiro###  try_tls: try to use STARTTLS?
256040266059SGregory Neil Shapiro###	(done in client)
256140266059SGregory Neil Shapiro######################################################################
256206f25ae9SGregory Neil ShapiroStry_tls
256340266059SGregory Neil Shapiroifdef(`_LOCAL_TRY_TLS_', `dnl
256440266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_try_tls" $1
256540266059SGregory Neil ShapiroR$* $| $#$*		$#$2
256640266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2567e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
256840266059SGregory Neil ShapiroR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
256940266059SGregory Neil ShapiroR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
257040266059SGregory Neil ShapiroR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
257106f25ae9SGregory Neil ShapiroR<?>$*		$@ OK
257240266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
257340266059SGregory Neil ShapiroR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2574e92d3f3fSGregory Neil ShapiroR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
257506f25ae9SGregory Neil Shapiro
257640266059SGregory Neil Shapiro######################################################################
257740266059SGregory Neil Shapiro###  tls_rcpt: is connection with server "good" enough?
257840266059SGregory Neil Shapiro###	(done in client, per recipient)
257940266059SGregory Neil Shapirodnl called from deliver() before RCPT command
258040266059SGregory Neil Shapiro###
258140266059SGregory Neil Shapiro###	Parameters:
258240266059SGregory Neil Shapiro###		$1: recipient
258340266059SGregory Neil Shapiro######################################################################
258440266059SGregory Neil ShapiroStls_rcpt
258540266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_RCPT_', `dnl
258640266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_rcpt" $1
258740266059SGregory Neil ShapiroR$* $| $#$*		$#$2
258840266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
2589e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
259040266059SGregory Neil Shapirodnl store name of other side
259140266059SGregory Neil ShapiroR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
259240266059SGregory Neil Shapirodnl canonify recipient address
259340266059SGregory Neil ShapiroR$+			$: <?> $>CanonAddr $1
259440266059SGregory Neil Shapirodnl strip trailing dots
259540266059SGregory Neil ShapiroR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
259640266059SGregory Neil Shapirodnl full address?
259740266059SGregory Neil ShapiroR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
259840266059SGregory Neil Shapirodnl only localpart?
259940266059SGregory Neil ShapiroR<?> $+			$: $1 $| <U:$1@> <E:>
260040266059SGregory Neil Shapirodnl look it up
260140266059SGregory Neil Shapirodnl also look up a default value via E:
260240266059SGregory Neil ShapiroR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
260340266059SGregory Neil Shapirodnl found nothing: stop here
260440266059SGregory Neil ShapiroR$* $| <?>	$@ OK
260540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
260640266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
260740266059SGregory Neil Shapirodnl use the generic routine (for now)
260840266059SGregory Neil ShapiroR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
260940266059SGregory Neil Shapiro
261040266059SGregory Neil Shapiro######################################################################
261140266059SGregory Neil Shapiro###  tls_client: is connection with client "good" enough?
261240266059SGregory Neil Shapiro###	(done in server)
261340266059SGregory Neil Shapiro###
261440266059SGregory Neil Shapiro###	Parameters:
261540266059SGregory Neil Shapiro###		${verify} $| (MAIL|STARTTLS)
261640266059SGregory Neil Shapiro######################################################################
261706f25ae9SGregory Neil Shapirodnl MAIL: called from check_mail
261806f25ae9SGregory Neil Shapirodnl STARTTLS: called from smtp() after STARTTLS has been accepted
261906f25ae9SGregory Neil ShapiroStls_client
262040266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_CLIENT_', `dnl
262140266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_client" $1
262240266059SGregory Neil ShapiroR$* $| $#$*		$#$2
262340266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
262406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
262540266059SGregory Neil Shapirodnl store name of other side
262640266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
262706f25ae9SGregory Neil Shapirodnl ignore second arg for now
262806f25ae9SGregory Neil Shapirodnl maybe use it to distinguish permanent/temporary error?
262906f25ae9SGregory Neil Shapirodnl if MAIL: permanent (STARTTLS has not been offered)
263006f25ae9SGregory Neil Shapirodnl if STARTTLS: temporary (offered but maybe failed)
263140266059SGregory Neil ShapiroR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
263240266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
263306f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_CLT_TAG
263406f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
263540266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
263640266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
263740266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
263840266059SGregory Neil ShapiroR$* $| $*	$@ $>"TLS_connection" $1')
263906f25ae9SGregory Neil Shapiro
264040266059SGregory Neil Shapiro######################################################################
264140266059SGregory Neil Shapiro###  tls_server: is connection with server "good" enough?
264240266059SGregory Neil Shapiro###	(done in client)
264340266059SGregory Neil Shapiro###
264440266059SGregory Neil Shapiro###	Parameter:
264540266059SGregory Neil Shapiro###		${verify}
264640266059SGregory Neil Shapiro######################################################################
264706f25ae9SGregory Neil Shapirodnl i.e. has the server been authenticated and is encryption active?
264806f25ae9SGregory Neil Shapirodnl called from deliver() after STARTTLS command
264906f25ae9SGregory Neil ShapiroStls_server
265040266059SGregory Neil Shapiroifdef(`_LOCAL_TLS_SERVER_', `dnl
265140266059SGregory Neil ShapiroR$*			$: $1 $| $>"Local_tls_server" $1
265240266059SGregory Neil ShapiroR$* $| $#$*		$#$2
265340266059SGregory Neil ShapiroR$* $| $*		$: $1', `dnl')
265406f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
265540266059SGregory Neil Shapirodnl store name of other side
265640266059SGregory Neil ShapiroR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
265740266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
265840266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
265906f25ae9SGregory Neil Shapirodnl do a default lookup: just TLS_SRV_TAG
266006f25ae9SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
266140266059SGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
266240266059SGregory Neil ShapiroR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
266340266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1', `dnl
266440266059SGregory Neil ShapiroR$*		$@ $>"TLS_connection" $1')
266506f25ae9SGregory Neil Shapiro
266640266059SGregory Neil Shapiro######################################################################
266740266059SGregory Neil Shapiro###  TLS_connection: is TLS connection "good" enough?
266840266059SGregory Neil Shapiro###
266940266059SGregory Neil Shapiro###	Parameters:
267006f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
267140266059SGregory Neil Shapiro###		${verify} $| <Requirement> [<>]', `dnl
267240266059SGregory Neil Shapiro###		${verify}')
267340266059SGregory Neil Shapiro###		Requirement: RHS from access map, may be ? for none.
267440266059SGregory Neil Shapirodnl	syntax for Requirement:
267540266059SGregory Neil Shapirodnl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
267640266059SGregory Neil Shapirodnl	extensions: could be a list of further requirements
267740266059SGregory Neil Shapirodnl		for now: CN:string	{cn_subject} == string
267840266059SGregory Neil Shapiro######################################################################
267940266059SGregory Neil ShapiroSTLS_connection
268040266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
268140266059SGregory Neil Shapirodnl deal with TLS handshake failures: abort
268240266059SGregory Neil ShapiroRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
268340266059SGregory Neil Shapirodivert(-1)')
268406f25ae9SGregory Neil Shapirodnl common ruleset for tls_{client|server}
268540266059SGregory Neil Shapirodnl input: ${verify} $| <ResultOfLookup> [<>]
268606f25ae9SGregory Neil Shapirodnl remove optional <>
268706f25ae9SGregory Neil ShapiroR$* $| <$*>$*			$: $1 $| <$2>
268840266059SGregory Neil Shapirodnl workspace: ${verify} $| <ResultOfLookup>
268940266059SGregory Neil Shapiro# create the appropriate error codes
269006f25ae9SGregory Neil Shapirodnl permanent or temporary error?
2691e92d3f3fSGregory Neil ShapiroR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
2692e92d3f3fSGregory Neil ShapiroR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
269306f25ae9SGregory Neil Shapirodnl default case depends on TLS_PERM_ERR
2694e92d3f3fSGregory Neil ShapiroR$* $| <$={Tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
269540266059SGregory Neil Shapirodnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
269640266059SGregory Neil Shapiro# deal with TLS handshake failures: abort
269706f25ae9SGregory Neil ShapiroRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
269806f25ae9SGregory Neil Shapirodnl no <reply:dns> i.e. not requirements in the access map
269906f25ae9SGregory Neil Shapirodnl use default error
270006f25ae9SGregory Neil ShapiroRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
270140266059SGregory Neil ShapiroR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
270240266059SGregory Neil Shapirodnl separate optional requirements
270340266059SGregory Neil ShapiroR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
2704e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
270540266059SGregory Neil Shapirodnl separate optional requirements
2706e92d3f3fSGregory Neil ShapiroR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
270706f25ae9SGregory Neil Shapirodnl some other value in access map: accept
270806f25ae9SGregory Neil Shapirodnl this also allows to override the default case (if used)
270906f25ae9SGregory Neil ShapiroR$* $| $*			$@ OK
271006f25ae9SGregory Neil Shapiro# authentication required: give appropriate error
271106f25ae9SGregory Neil Shapiro# other side did authenticate (via STARTTLS)
271240266059SGregory Neil Shapirodnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
271306f25ae9SGregory Neil Shapirodnl only verification required and it succeeded
271440266059SGregory Neil ShapiroR<$*><VERIFY> <> OK		$@ OK
271540266059SGregory Neil Shapirodnl verification required and it succeeded but extensions are given
271640266059SGregory Neil Shapirodnl change it to <SMTP:ESC> <REQ:0>  <extensions>
271740266059SGregory Neil ShapiroR<$*><VERIFY> <$+> OK		$: <$1> <REQ:0> <$2>
271806f25ae9SGregory Neil Shapirodnl verification required + some level of encryption
271940266059SGregory Neil ShapiroR<$*><VERIFY:$-> <$*> OK	$: <$1> <REQ:$2> <$3>
272006f25ae9SGregory Neil Shapirodnl just some level of encryption required
272140266059SGregory Neil ShapiroR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
272240266059SGregory Neil Shapirodnl workspace:
272340266059SGregory Neil Shapirodnl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!= OK)
272440266059SGregory Neil Shapirodnl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
272540266059SGregory Neil Shapirodnl verification required but ${verify} is not set (case 1.)
272640266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
272740266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
272840266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
272940266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
273040266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
273106f25ae9SGregory Neil Shapirodnl some other value for ${verify}
273240266059SGregory Neil ShapiroR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
273340266059SGregory Neil Shapirodnl some level of encryption required: get the maximum level (case 2.)
273440266059SGregory Neil ShapiroR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
273506f25ae9SGregory Neil Shapirodnl compare required bits with actual bits
273640266059SGregory Neil ShapiroR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
273740266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
273840266059SGregory Neil Shapirodnl strength requirements fulfilled
273940266059SGregory Neil Shapirodnl TLS Additional Requirements Separator
274040266059SGregory Neil Shapirodnl this should be something which does not appear in the extensions itself
274140266059SGregory Neil Shapirodnl @ could be part of a CN, DN, etc...
274240266059SGregory Neil Shapirodnl use < > ? those are encoded in CN, DN, ...
274340266059SGregory Neil Shapirodefine(`_TLS_ARS_', `++')dnl
274440266059SGregory Neil Shapirodnl workspace:
274540266059SGregory Neil Shapirodnl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
274640266059SGregory Neil ShapiroR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
274740266059SGregory Neil Shapirodnl workspace: <SMTP:ESC _TLS_ARS_ extensions>
274840266059SGregory Neil Shapirodnl continue: check  extensions
274940266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ >			$@ OK
275040266059SGregory Neil Shapirodnl split extensions into own list
275140266059SGregory Neil ShapiroR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
275240266059SGregory Neil ShapiroR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
275340266059SGregory Neil ShapiroR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
275406f25ae9SGregory Neil Shapiro
275540266059SGregory Neil Shapiro######################################################################
275640266059SGregory Neil Shapiro###  TLS_req: check additional TLS requirements
275740266059SGregory Neil Shapiro###
275840266059SGregory Neil Shapiro###	Parameters: [<list> <of> <req>] $| <$-:$+>
275940266059SGregory Neil Shapiro###		$-: SMTP reply code
276040266059SGregory Neil Shapiro###		$+: Enhanced Status Code
276140266059SGregory Neil Shapirodnl  further requirements for this ruleset:
276240266059SGregory Neil Shapirodnl	name of "other side" is stored is {TLS_name} (client/server_name)
276340266059SGregory Neil Shapirodnl
276440266059SGregory Neil Shapirodnl	currently only CN[:common_name] is implemented
276540266059SGregory Neil Shapirodnl	right now this is only a logical AND
276640266059SGregory Neil Shapirodnl	i.e. all requirements must be true
276740266059SGregory Neil Shapirodnl	how about an OR? CN must be X or CN must be Y or ..
276840266059SGregory Neil Shapirodnl	use a macro to compute this as a trivial sequential
276940266059SGregory Neil Shapirodnl	operations (no precedences etc)?
277040266059SGregory Neil Shapiro######################################################################
277140266059SGregory Neil ShapiroSTLS_req
277240266059SGregory Neil Shapirodnl no additional requirements: ok
277340266059SGregory Neil ShapiroR $| $+		$@ OK
277440266059SGregory Neil Shapirodnl require CN: but no CN specified: use name of other side
277540266059SGregory Neil ShapiroR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
277640266059SGregory Neil Shapirodnl match, check rest
277740266059SGregory Neil ShapiroR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
277840266059SGregory Neil Shapirodnl CN does not match
277940266059SGregory Neil Shapirodnl  1   2      3  4
278040266059SGregory Neil ShapiroR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
278140266059SGregory Neil Shapirodnl cert subject
278240266059SGregory Neil ShapiroR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
278340266059SGregory Neil Shapirodnl CS does not match
278440266059SGregory Neil Shapirodnl  1   2      3  4
278513bd1963SGregory Neil ShapiroR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
278640266059SGregory Neil Shapirodnl match, check rest
278740266059SGregory Neil ShapiroR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
278840266059SGregory Neil Shapirodnl CI does not match
278940266059SGregory Neil Shapirodnl  1   2      3  4
279013bd1963SGregory Neil ShapiroR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
279140266059SGregory Neil Shapirodnl return from recursive call
279240266059SGregory Neil ShapiroROK			$@ OK
279340266059SGregory Neil Shapiro
279440266059SGregory Neil Shapiro######################################################################
279540266059SGregory Neil Shapiro###  max: return the maximum of two values separated by :
279640266059SGregory Neil Shapiro###
279740266059SGregory Neil Shapiro###	Parameters: [$-]:[$-]
279840266059SGregory Neil Shapiro######################################################################
279906f25ae9SGregory Neil ShapiroSmax
280006f25ae9SGregory Neil ShapiroR:		$: 0
280106f25ae9SGregory Neil ShapiroR:$-		$: $1
280206f25ae9SGregory Neil ShapiroR$-:		$: $1
280306f25ae9SGregory Neil ShapiroR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
280406f25ae9SGregory Neil ShapiroRTRUE:$-:$-	$: $2
280540266059SGregory Neil ShapiroR$-:$-:$-	$: $2
280640266059SGregory Neil Shapirodnl endif _ACCESS_TABLE_
280740266059SGregory Neil Shapirodivert(0)
280806f25ae9SGregory Neil Shapiro
280940266059SGregory Neil Shapiro######################################################################
281040266059SGregory Neil Shapiro###  RelayTLS: allow relaying based on TLS authentication
281140266059SGregory Neil Shapiro###
281240266059SGregory Neil Shapiro###	Parameters:
281340266059SGregory Neil Shapiro###		none
281440266059SGregory Neil Shapiro######################################################################
281540266059SGregory Neil ShapiroSRelayTLS
281606f25ae9SGregory Neil Shapiro# authenticated?
281706f25ae9SGregory Neil Shapirodnl we do not allow relaying for anyone who can present a cert
281806f25ae9SGregory Neil Shapirodnl signed by a "trusted" CA. For example, even if we put verisigns
281913bd1963SGregory Neil Shapirodnl CA in CertPath so we can authenticate users, we do not allow
282006f25ae9SGregory Neil Shapirodnl them to abuse our server (they might be easier to get hold of,
282106f25ae9SGregory Neil Shapirodnl but anyway).
282206f25ae9SGregory Neil Shapirodnl so here is the trick: if the verification succeeded
282306f25ae9SGregory Neil Shapirodnl we look up the cert issuer in the access map
282406f25ae9SGregory Neil Shapirodnl (maybe after extracting a part with a regular expression)
282506f25ae9SGregory Neil Shapirodnl if this returns RELAY we relay without further questions
282606f25ae9SGregory Neil Shapirodnl if it returns SUBJECT we perform a similar check on the
282706f25ae9SGregory Neil Shapirodnl cert subject.
282806f25ae9SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
282940266059SGregory Neil ShapiroR$*			$: <?> $&{verify}
283040266059SGregory Neil ShapiroR<?> OK			$: OK		authenticated: continue
283140266059SGregory Neil ShapiroR<?> $*			$@ NO		not authenticated
283206f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_ISSUER_', `dnl
283340266059SGregory Neil ShapiroR$*			$: $(CERTIssuer $&{cert_issuer} $)',
283440266059SGregory Neil Shapiro`R$*			$: $&{cert_issuer}')
283540266059SGregory Neil ShapiroR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
283606f25ae9SGregory Neil Shapirodnl use $# to stop further checks (delay_check)
283740266059SGregory Neil ShapiroRRELAY			$# RELAY
283806f25ae9SGregory Neil Shapiroifdef(`_CERT_REGEX_SUBJECT_', `dnl
283940266059SGregory Neil ShapiroRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
284040266059SGregory Neil Shapiro`RSUBJECT		$: <@> $&{cert_subject}')
284140266059SGregory Neil ShapiroR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
284240266059SGregory Neil ShapiroR<@> RELAY		$# RELAY
284340266059SGregory Neil ShapiroR$*			$: NO', `dnl')
284440266059SGregory Neil Shapiro
284540266059SGregory Neil Shapiro######################################################################
284640266059SGregory Neil Shapiro###  authinfo: lookup authinfo in the access map
284740266059SGregory Neil Shapiro###
284840266059SGregory Neil Shapiro###	Parameters:
284940266059SGregory Neil Shapiro###		$1: {server_name}
285040266059SGregory Neil Shapiro###		$2: {server_addr}
285140266059SGregory Neil Shapirodnl	both are currently ignored
285240266059SGregory Neil Shapirodnl if it should be done via another map, we either need to restrict
285340266059SGregory Neil Shapirodnl functionality (it calls D and A) or copy those rulesets (or add another
285440266059SGregory Neil Shapirodnl parameter which I want to avoid, it's quite complex already)
285540266059SGregory Neil Shapiro######################################################################
285640266059SGregory Neil Shapirodnl omit this ruleset if neither is defined?
285740266059SGregory Neil Shapirodnl it causes DefaultAuthInfo to be ignored
285840266059SGregory Neil Shapirodnl (which may be considered a good thing).
285940266059SGregory Neil ShapiroSauthinfo
286040266059SGregory Neil Shapiroifdef(`_AUTHINFO_TABLE_', `dnl
286140266059SGregory Neil ShapiroR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
286240266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
286340266059SGregory Neil ShapiroR<?>		$: <$(authinfo AuthInfo: $: ? $)>
286440266059SGregory Neil ShapiroR<?>		$@ no				no authinfo available
286540266059SGregory Neil ShapiroR<$*>		$# $1
286640266059SGregory Neil Shapirodnl', `dnl
286740266059SGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
286840266059SGregory Neil ShapiroR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
286940266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
287040266059SGregory Neil ShapiroR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
287140266059SGregory Neil ShapiroR$* $| <?>$*	$@ no				no authinfo available
287240266059SGregory Neil ShapiroR$* $| <$*> <>	$# $2
287340266059SGregory Neil Shapirodnl', `dnl')')
287406f25ae9SGregory Neil Shapiro
2875e92d3f3fSGregory Neil Shapiroifdef(`_RATE_CONTROL_',`dnl
2876e92d3f3fSGregory Neil Shapiro######################################################################
2877e92d3f3fSGregory Neil Shapiro###  RateControl:
2878e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
2879e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
2880e92d3f3fSGregory Neil Shapiro######################################################################
2881e92d3f3fSGregory Neil ShapiroSRateControl
2882e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2883e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
2884e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
2885e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientRate> $| $1 <>
2886e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
2887e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
2888e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
2889e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2890e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
2891e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
2892e92d3f3fSGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $&{client_rate} $@ $1 $)
2893e92d3f3fSGregory Neil Shapirodnl log this? Connection rate $&{client_rate} exceeds limit $1.
2894e92d3f3fSGregory Neil ShapiroR<$+> $| FALSE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
2895e92d3f3fSGregory Neil Shapiro')')
2896e92d3f3fSGregory Neil Shapiro
2897e92d3f3fSGregory Neil Shapiroifdef(`_CONN_CONTROL_',`dnl
2898e92d3f3fSGregory Neil Shapiro######################################################################
2899e92d3f3fSGregory Neil Shapiro###  ConnControl:
2900e92d3f3fSGregory Neil Shapiro###	Parameters:	ignored
2901e92d3f3fSGregory Neil Shapiro###	return: $#error or OK
2902e92d3f3fSGregory Neil Shapiro######################################################################
2903e92d3f3fSGregory Neil ShapiroSConnControl
2904e92d3f3fSGregory Neil Shapiroifdef(`_ACCESS_TABLE_', `dnl
2905e92d3f3fSGregory Neil ShapiroR$*		$: <A:$&{client_addr}> <E:>
2906e92d3f3fSGregory Neil Shapirodnl also look up a default value via E:
2907e92d3f3fSGregory Neil ShapiroR$+		$: $>SearchList <! ClientConn> $| $1 <>
2908e92d3f3fSGregory Neil Shapirodnl found nothing: stop here
2909e92d3f3fSGregory Neil ShapiroR<?>		$@ OK
2910e92d3f3fSGregory Neil Shapiroifdef(`_ATMPF_', `dnl tempfail?
2911e92d3f3fSGregory Neil ShapiroR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
2912e92d3f3fSGregory Neil Shapirodnl use the generic routine (for now)
2913e92d3f3fSGregory Neil ShapiroR<0>		$@ OK		no limit
2914e92d3f3fSGregory Neil ShapiroR<$+>		$: <$1> $| $(arith l $@ $&{client_connections} $@ $1 $)
2915e92d3f3fSGregory Neil Shapirodnl log this: Open connections $&{client_connections} exceeds limit $1.
2916e92d3f3fSGregory Neil ShapiroR<$+> $| FALSE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
2917e92d3f3fSGregory Neil Shapiro')')
2918e92d3f3fSGregory Neil Shapiro
291906f25ae9SGregory Neil Shapiroundivert(9)dnl LOCAL_RULESETS
292006f25ae9SGregory Neil Shapiro#
292106f25ae9SGregory Neil Shapiro######################################################################
292206f25ae9SGregory Neil Shapiro######################################################################
292306f25ae9SGregory Neil Shapiro#####
292406f25ae9SGregory Neil Shapiro`#####			MAIL FILTER DEFINITIONS'
292506f25ae9SGregory Neil Shapiro#####
292606f25ae9SGregory Neil Shapiro######################################################################
292706f25ae9SGregory Neil Shapiro######################################################################
292840266059SGregory Neil Shapiro_MAIL_FILTERS_
2929c2aa98e2SPeter Wemm#
2930c2aa98e2SPeter Wemm######################################################################
2931c2aa98e2SPeter Wemm######################################################################
2932c2aa98e2SPeter Wemm#####
2933c2aa98e2SPeter Wemm`#####			MAILER DEFINITIONS'
2934c2aa98e2SPeter Wemm#####
2935c2aa98e2SPeter Wemm######################################################################
2936c2aa98e2SPeter Wemm######################################################################
293706f25ae9SGregory Neil Shapiroundivert(7)dnl MAILER_DEFINITIONS
293842e5d165SGregory Neil Shapiro
2939