xref: /illumos-gate/usr/src/cmd/sendmail/cf/m4/proto.m4 (revision e9af4bc0)
17c478bd9Sstevel@tonic-gatedivert(-1)
27c478bd9Sstevel@tonic-gate#
3*e9af4bc0SJohn Beck# Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers.
47c478bd9Sstevel@tonic-gate#	All rights reserved.
57c478bd9Sstevel@tonic-gate# Copyright (c) 1983, 1995 Eric P. Allman.  All rights reserved.
67c478bd9Sstevel@tonic-gate# Copyright (c) 1988, 1993
77c478bd9Sstevel@tonic-gate#	The Regents of the University of California.  All rights reserved.
87c478bd9Sstevel@tonic-gate#
97c478bd9Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
107c478bd9Sstevel@tonic-gate# Use is subject to license terms.
117c478bd9Sstevel@tonic-gate#
127c478bd9Sstevel@tonic-gate# By using this file, you agree to the terms and conditions set
137c478bd9Sstevel@tonic-gate# forth in the LICENSE file which can be found at the top level of
147c478bd9Sstevel@tonic-gate# the sendmail distribution.
157c478bd9Sstevel@tonic-gate#
167c478bd9Sstevel@tonic-gate#
177c478bd9Sstevel@tonic-gatedivert(0)
187c478bd9Sstevel@tonic-gate
19*e9af4bc0SJohn BeckVERSIONID(`$Id: proto.m4,v 8.741 2009/12/11 00:04:53 ca Exp $')
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gate# level CF_LEVEL config file format
227c478bd9Sstevel@tonic-gateV`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Sun')
237c478bd9Sstevel@tonic-gatedivert(-1)
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gatednl if MAILER(`local') not defined: do it ourself; be nice
267c478bd9Sstevel@tonic-gatednl maybe we should issue a warning?
277c478bd9Sstevel@tonic-gateifdef(`_MAILER_local_',`', `MAILER(local)')
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate# do some sanity checking
307c478bd9Sstevel@tonic-gateifdef(`__OSTYPE__',,
317c478bd9Sstevel@tonic-gate	`errprint(`*** ERROR: No system type defined (use OSTYPE macro)
327c478bd9Sstevel@tonic-gate')')
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate# pick our default mailers
357c478bd9Sstevel@tonic-gateifdef(`confSMTP_MAILER',, `define(`confSMTP_MAILER', `esmtp')')
367c478bd9Sstevel@tonic-gateifdef(`confLOCAL_MAILER',, `define(`confLOCAL_MAILER', `local')')
377c478bd9Sstevel@tonic-gateifdef(`confRELAY_MAILER',,
387c478bd9Sstevel@tonic-gate	`define(`confRELAY_MAILER',
397c478bd9Sstevel@tonic-gate		`ifdef(`_MAILER_smtp_', `relay',
407c478bd9Sstevel@tonic-gate			`ifdef(`_MAILER_uucp', `uucp-new', `unknown')')')')
417c478bd9Sstevel@tonic-gateifdef(`confUUCP_MAILER',, `define(`confUUCP_MAILER', `uucp-old')')
427c478bd9Sstevel@tonic-gatedefine(`_SMTP_', `confSMTP_MAILER')dnl		for readability only
437c478bd9Sstevel@tonic-gatedefine(`_LOCAL_', `confLOCAL_MAILER')dnl	for readability only
447c478bd9Sstevel@tonic-gatedefine(`_RELAY_', `confRELAY_MAILER')dnl	for readability only
457c478bd9Sstevel@tonic-gatedefine(`_UUCP_', `confUUCP_MAILER')dnl		for readability only
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate# back compatibility with old config files
487c478bd9Sstevel@tonic-gateifdef(`confDEF_GROUP_ID',
497c478bd9Sstevel@tonic-gate`errprint(`*** confDEF_GROUP_ID is obsolete.
507c478bd9Sstevel@tonic-gate    Use confDEF_USER_ID with a colon in the value instead.
517c478bd9Sstevel@tonic-gate')')
527c478bd9Sstevel@tonic-gateifdef(`confREAD_TIMEOUT',
537c478bd9Sstevel@tonic-gate`errprint(`*** confREAD_TIMEOUT is obsolete.
547c478bd9Sstevel@tonic-gate    Use individual confTO_<timeout> parameters instead.
557c478bd9Sstevel@tonic-gate')')
567c478bd9Sstevel@tonic-gateifdef(`confMESSAGE_TIMEOUT',
577c478bd9Sstevel@tonic-gate	`define(`_ARG_', index(confMESSAGE_TIMEOUT, /))
587c478bd9Sstevel@tonic-gate	 ifelse(_ARG_, -1,
597c478bd9Sstevel@tonic-gate		`define(`confTO_QUEUERETURN', confMESSAGE_TIMEOUT)',
607c478bd9Sstevel@tonic-gate		`define(`confTO_QUEUERETURN',
617c478bd9Sstevel@tonic-gate			substr(confMESSAGE_TIMEOUT, 0, _ARG_))
627c478bd9Sstevel@tonic-gate		 define(`confTO_QUEUEWARN',
637c478bd9Sstevel@tonic-gate			substr(confMESSAGE_TIMEOUT, eval(_ARG_+1)))')')
647c478bd9Sstevel@tonic-gateifdef(`confMIN_FREE_BLOCKS', `ifelse(index(confMIN_FREE_BLOCKS, /), -1,,
657c478bd9Sstevel@tonic-gate`errprint(`*** compound confMIN_FREE_BLOCKS is obsolete.
667c478bd9Sstevel@tonic-gate    Use confMAX_MESSAGE_SIZE for the second part of the value.
677c478bd9Sstevel@tonic-gate')')')
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate# Sanity check on ldap_routing feature
717c478bd9Sstevel@tonic-gate# If the user doesn't specify a new map, they better have given as a
727c478bd9Sstevel@tonic-gate# default LDAP specification which has the LDAP base (and most likely the host)
737c478bd9Sstevel@tonic-gateifdef(`confLDAP_DEFAULT_SPEC',, `ifdef(`_LDAP_ROUTING_WARN_', `errprint(`
747c478bd9Sstevel@tonic-gateWARNING: Using default FEATURE(ldap_routing) map definition(s)
757c478bd9Sstevel@tonic-gatewithout setting confLDAP_DEFAULT_SPEC option.
767c478bd9Sstevel@tonic-gate')')')dnl
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate# clean option definitions below....
797c478bd9Sstevel@tonic-gatedefine(`_OPTION', `ifdef(`$2', `O $1`'ifelse(defn(`$2'), `',, `=$2')', `#O $1`'ifelse(`$3', `',,`=$3')')')dnl
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gatednl required to "rename" the check_* rulesets...
827c478bd9Sstevel@tonic-gatedefine(`_U_',ifdef(`_DELAY_CHECKS_',`',`_'))
837c478bd9Sstevel@tonic-gatednl default relaying denied message
847c478bd9Sstevel@tonic-gateifdef(`confRELAY_MSG', `', `define(`confRELAY_MSG',
857c478bd9Sstevel@tonic-gateifdef(`_USE_AUTH_', `"550 Relaying denied. Proper authentication required."', `"550 Relaying denied"'))')
867c478bd9Sstevel@tonic-gateifdef(`confRCPTREJ_MSG', `', `define(`confRCPTREJ_MSG', `"550 Mailbox disabled for this recipient"')')
877c478bd9Sstevel@tonic-gatedefine(`_CODE553', `553')
887c478bd9Sstevel@tonic-gatedivert(0)dnl
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate# override file safeties - setting this option compromises system security,
917c478bd9Sstevel@tonic-gate# addressing the actual file configuration problem is preferred
927c478bd9Sstevel@tonic-gate# need to set this before any file actions are encountered in the cf file
937c478bd9Sstevel@tonic-gate_OPTION(DontBlameSendmail, `confDONT_BLAME_SENDMAIL', `safe')
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate# default LDAP map specification
967c478bd9Sstevel@tonic-gate# need to set this now before any LDAP maps are defined
977c478bd9Sstevel@tonic-gate_OPTION(LDAPDefaultSpec, `confLDAP_DEFAULT_SPEC', `-h localhost')
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate##################
1007c478bd9Sstevel@tonic-gate#   local info   #
1017c478bd9Sstevel@tonic-gate##################
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate# my LDAP cluster
1047c478bd9Sstevel@tonic-gate# need to set this before any LDAP lookups are done (including classes)
1057c478bd9Sstevel@tonic-gateifdef(`confLDAP_CLUSTER', `D{sendmailMTACluster}`'confLDAP_CLUSTER', `#D{sendmailMTACluster}$m')
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gateCwlocalhost
1087c478bd9Sstevel@tonic-gateifdef(`USE_CW_FILE',
1097c478bd9Sstevel@tonic-gate`# file containing names of hosts for which we receive email
1107c478bd9Sstevel@tonic-gateFw`'confCW_FILE',
1117c478bd9Sstevel@tonic-gate	`dnl')
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate# my official domain name
1147c478bd9Sstevel@tonic-gate# ... `define' this only if sendmail cannot automatically determine your domain
1157c478bd9Sstevel@tonic-gateifdef(`confDOMAIN_NAME', `Dj`'confDOMAIN_NAME', `#Dj$w.Foo.COM')
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate# host/domain names ending with a token in class P are canonical
1187c478bd9Sstevel@tonic-gateCP.
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gateifdef(`UUCP_RELAY',
1217c478bd9Sstevel@tonic-gate`# UUCP relay host
1227c478bd9Sstevel@tonic-gateDY`'UUCP_RELAY
1237c478bd9Sstevel@tonic-gateCPUUCP
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate')dnl
1267c478bd9Sstevel@tonic-gateifdef(`BITNET_RELAY',
1277c478bd9Sstevel@tonic-gate`#  BITNET relay host
1287c478bd9Sstevel@tonic-gateDB`'BITNET_RELAY
1297c478bd9Sstevel@tonic-gateCPBITNET
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate')dnl
1327c478bd9Sstevel@tonic-gateifdef(`DECNET_RELAY',
1337c478bd9Sstevel@tonic-gate`define(`_USE_DECNET_SYNTAX_', 1)dnl
1347c478bd9Sstevel@tonic-gate# DECnet relay host
1357c478bd9Sstevel@tonic-gateDC`'DECNET_RELAY
1367c478bd9Sstevel@tonic-gateCPDECNET
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate')dnl
1397c478bd9Sstevel@tonic-gateifdef(`FAX_RELAY',
1407c478bd9Sstevel@tonic-gate`# FAX relay host
1417c478bd9Sstevel@tonic-gateDF`'FAX_RELAY
1427c478bd9Sstevel@tonic-gateCPFAX
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate')dnl
1457c478bd9Sstevel@tonic-gate# "Smart" relay host (may be null)
1467c478bd9Sstevel@tonic-gateDS`'ifdef(`SMART_HOST', `SMART_HOST')
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gateifdef(`LUSER_RELAY', `dnl
1497c478bd9Sstevel@tonic-gate# place to which unknown users should be forwarded
1507c478bd9Sstevel@tonic-gateKuser user -m -a<>
1517c478bd9Sstevel@tonic-gateDL`'LUSER_RELAY',
1527c478bd9Sstevel@tonic-gate`dnl')
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate# operators that cannot be in local usernames (i.e., network indicators)
1557c478bd9Sstevel@tonic-gateCO @ % ifdef(`_NO_UUCP_', `', `!')
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate# a class with just dot (for identifying canonical names)
1587c478bd9Sstevel@tonic-gateC..
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate# a class with just a left bracket (for identifying domain literals)
1617c478bd9Sstevel@tonic-gateC[[
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
1647c478bd9Sstevel@tonic-gate# access_db acceptance class
1657c478bd9Sstevel@tonic-gateC{Accept}OK RELAY
1667c478bd9Sstevel@tonic-gateifdef(`_DELAY_COMPAT_8_10_',`dnl
1677c478bd9Sstevel@tonic-gateifdef(`_BLACKLIST_RCPT_',`dnl
1687c478bd9Sstevel@tonic-gate# possible access_db RHS for spam friends/haters
1697c478bd9Sstevel@tonic-gateC{SpamTag}SPAMFRIEND SPAMHATER')')',
1707c478bd9Sstevel@tonic-gate`dnl')
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gatednl mark for "domain is ok" (resolved or accepted anyway)
1737c478bd9Sstevel@tonic-gatedefine(`_RES_OK_', `OKR')dnl
1747c478bd9Sstevel@tonic-gateifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',`dnl',`dnl
1757c478bd9Sstevel@tonic-gate# Resolve map (to check if a host exists in check_mail)
1767c478bd9Sstevel@tonic-gateKresolve host -a<_RES_OK_> -T<TEMP>')
1777c478bd9Sstevel@tonic-gateC{ResOk}_RES_OK_
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gateifdef(`_NEED_MACRO_MAP_', `dnl
1807c478bd9Sstevel@tonic-gateifdef(`_MACRO_MAP_', `', `# macro storage map
1817c478bd9Sstevel@tonic-gatedefine(`_MACRO_MAP_', `1')dnl
1827c478bd9Sstevel@tonic-gateKmacro macro')', `dnl')
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gateifdef(`confCR_FILE', `dnl
1857c478bd9Sstevel@tonic-gate# Hosts for which relaying is permitted ($=R)
1867c478bd9Sstevel@tonic-gateFR`'confCR_FILE',
1877c478bd9Sstevel@tonic-gate`dnl')
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gatedefine(`TLS_SRV_TAG', `"TLS_Srv"')dnl
1907c478bd9Sstevel@tonic-gatedefine(`TLS_CLT_TAG', `"TLS_Clt"')dnl
1917c478bd9Sstevel@tonic-gatedefine(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl
1927c478bd9Sstevel@tonic-gatedefine(`TLS_TRY_TAG', `"Try_TLS"')dnl
1937c478bd9Sstevel@tonic-gatedefine(`SRV_FEAT_TAG', `"Srv_Features"')dnl
1947c478bd9Sstevel@tonic-gatednl this may be useful in other contexts too
1957c478bd9Sstevel@tonic-gateifdef(`_ARITH_MAP_', `', `# arithmetic map
1967c478bd9Sstevel@tonic-gatedefine(`_ARITH_MAP_', `1')dnl
1977c478bd9Sstevel@tonic-gateKarith arith')
1987c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
1997c478bd9Sstevel@tonic-gateifdef(`_MACRO_MAP_', `', `# macro storage map
2007c478bd9Sstevel@tonic-gatedefine(`_MACRO_MAP_', `1')dnl
2017c478bd9Sstevel@tonic-gateKmacro macro')
2027c478bd9Sstevel@tonic-gate# possible values for TLS_connection in access map
2037c478bd9Sstevel@tonic-gateC{Tls}VERIFY ENCR', `dnl')
2047c478bd9Sstevel@tonic-gateifdef(`_CERT_REGEX_ISSUER_', `dnl
2057c478bd9Sstevel@tonic-gate# extract relevant part from cert issuer
2067c478bd9Sstevel@tonic-gateKCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
2077c478bd9Sstevel@tonic-gateifdef(`_CERT_REGEX_SUBJECT_', `dnl
2087c478bd9Sstevel@tonic-gate# extract relevant part from cert subject
2097c478bd9Sstevel@tonic-gateKCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gateifdef(`LOCAL_RELAY', `dnl
2127c478bd9Sstevel@tonic-gate# who I send unqualified names to if `FEATURE(stickyhost)' is used
2137c478bd9Sstevel@tonic-gate# (null means deliver locally)
2147c478bd9Sstevel@tonic-gateDR`'LOCAL_RELAY')
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gateifdef(`MAIL_HUB', `dnl
2177c478bd9Sstevel@tonic-gate# who gets all local email traffic
2187c478bd9Sstevel@tonic-gate# ($R has precedence for unqualified names if `FEATURE(stickyhost)' is used)
2197c478bd9Sstevel@tonic-gateDH`'MAIL_HUB')
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate# dequoting map
2227c478bd9Sstevel@tonic-gateKdequote dequote`'ifdef(`confDEQUOTE_OPTS', ` confDEQUOTE_OPTS', `')
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gatedivert(0)dnl	# end of nullclient diversion
2257c478bd9Sstevel@tonic-gate# class E: names that should be exposed as from this host, even if we masquerade
2267c478bd9Sstevel@tonic-gate# class L: names that should be delivered locally, even if we have a relay
2277c478bd9Sstevel@tonic-gate# class M: domains that should be converted to $M
2287c478bd9Sstevel@tonic-gate# class N: domains that should not be converted to $M
2297c478bd9Sstevel@tonic-gate#CL root
2307c478bd9Sstevel@tonic-gateundivert(5)dnl
2317c478bd9Sstevel@tonic-gateifdef(`_VIRTHOSTS_', `CR$={VirtHost}', `dnl')
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gateifdef(`MASQUERADE_NAME', `dnl
2347c478bd9Sstevel@tonic-gate# who I masquerade as (null for no masquerading) (see also $=M)
2357c478bd9Sstevel@tonic-gateDM`'MASQUERADE_NAME')
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate# my name for error messages
2387c478bd9Sstevel@tonic-gateifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gateundivert(6)dnl LOCAL_CONFIG
2417c478bd9Sstevel@tonic-gateinclude(_CF_DIR_`m4/version.m4')
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate###############
2447c478bd9Sstevel@tonic-gate#   Options   #
2457c478bd9Sstevel@tonic-gate###############
2467c478bd9Sstevel@tonic-gateifdef(`confAUTO_REBUILD',
2477c478bd9Sstevel@tonic-gate`errprint(WARNING: `confAUTO_REBUILD' is no longer valid.
2487c478bd9Sstevel@tonic-gate	There was a potential for a denial of service attack if this is set.
2497c478bd9Sstevel@tonic-gate)')dnl
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate# strip message body to 7 bits on input?
2527c478bd9Sstevel@tonic-gate_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate# 8-bit data handling
2557c478bd9Sstevel@tonic-gate_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate# wait for alias file rebuild (default units: minutes)
2587c478bd9Sstevel@tonic-gate_OPTION(AliasWait, `confALIAS_WAIT', `5m')
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate# location of alias file
2617c478bd9Sstevel@tonic-gate_OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate# minimum number of free blocks on filesystem
2647c478bd9Sstevel@tonic-gate_OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100')
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate# maximum message size
2677c478bd9Sstevel@tonic-gate_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0')
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate# substitution for space (blank) characters
2707c478bd9Sstevel@tonic-gate_OPTION(BlankSub, `confBLANK_SUB', `_')
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate# avoid connecting to "expensive" mailers on initial submission?
2737c478bd9Sstevel@tonic-gate_OPTION(HoldExpensive, `confCON_EXPENSIVE', `False')
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate# checkpoint queue runs after every N successful deliveries
2767c478bd9Sstevel@tonic-gate_OPTION(CheckpointInterval, `confCHECKPOINT_INTERVAL', `10')
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate# default delivery mode
2797c478bd9Sstevel@tonic-gate_OPTION(DeliveryMode, `confDELIVERY_MODE', `background')
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate# error message header/file
2827c478bd9Sstevel@tonic-gate_OPTION(ErrorHeader, `confERROR_MESSAGE', `MAIL_SETTINGS_DIR`'error-header')
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate# error mode
2857c478bd9Sstevel@tonic-gate_OPTION(ErrorMode, `confERROR_MODE', `print')
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate# save Unix-style "From_" lines at top of header?
2887c478bd9Sstevel@tonic-gate_OPTION(SaveFromLine, `confSAVE_FROM_LINES', `False')
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate# queue file mode (qf files)
2917c478bd9Sstevel@tonic-gate_OPTION(QueueFileMode, `confQUEUE_FILE_MODE', `0600')
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate# temporary file mode
2947c478bd9Sstevel@tonic-gate_OPTION(TempFileMode, `confTEMP_FILE_MODE', `0600')
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate# match recipients against GECOS field?
2977c478bd9Sstevel@tonic-gate_OPTION(MatchGECOS, `confMATCH_GECOS', `False')
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate# maximum hop count
3007c478bd9Sstevel@tonic-gate_OPTION(MaxHopCount, `confMAX_HOP', `25')
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate# location of help file
3037c478bd9Sstevel@tonic-gateO HelpFile=ifdef(`HELP_FILE', HELP_FILE, `MAIL_SETTINGS_DIR`'helpfile')
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate# ignore dots as terminators in incoming messages?
3067c478bd9Sstevel@tonic-gate_OPTION(IgnoreDots, `confIGNORE_DOTS', `False')
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate# name resolver options
3097c478bd9Sstevel@tonic-gate_OPTION(ResolverOptions, `confBIND_OPTS', `+AAONLY')
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate# deliver MIME-encapsulated error messages?
3127c478bd9Sstevel@tonic-gate_OPTION(SendMimeErrors, `confMIME_FORMAT_ERRORS', `True')
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate# Forward file search path
3157c478bd9Sstevel@tonic-gate_OPTION(ForwardPath, `confFORWARD_PATH', `/var/forward/$u:$z/.forward.$w:$z/.forward')
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate# open connection cache size
3187c478bd9Sstevel@tonic-gate_OPTION(ConnectionCacheSize, `confMCI_CACHE_SIZE', `2')
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate# open connection cache timeout
3217c478bd9Sstevel@tonic-gate_OPTION(ConnectionCacheTimeout, `confMCI_CACHE_TIMEOUT', `5m')
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate# persistent host status directory
3247c478bd9Sstevel@tonic-gate_OPTION(HostStatusDirectory, `confHOST_STATUS_DIRECTORY', `.hoststat')
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate# single thread deliveries (requires HostStatusDirectory)?
3277c478bd9Sstevel@tonic-gate_OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False')
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate# use Errors-To: header?
3307c478bd9Sstevel@tonic-gate_OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False')
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate# log level
3337c478bd9Sstevel@tonic-gate_OPTION(LogLevel, `confLOG_LEVEL', `10')
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate# send to me too, even in an alias expansion?
3367c478bd9Sstevel@tonic-gate_OPTION(MeToo, `confME_TOO', `True')
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate# verify RHS in newaliases?
3397c478bd9Sstevel@tonic-gate_OPTION(CheckAliases, `confCHECK_ALIASES', `False')
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate# default messages to old style headers if no special punctuation?
3427c478bd9Sstevel@tonic-gate_OPTION(OldStyleHeaders, `confOLD_STYLE_HEADERS', `False')
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate# SMTP daemon options
3457c478bd9Sstevel@tonic-gateifelse(defn(`confDAEMON_OPTIONS'), `', `dnl',
3467c478bd9Sstevel@tonic-gate`errprint(WARNING: `confDAEMON_OPTIONS' is no longer valid.
3477c478bd9Sstevel@tonic-gate	Use `DAEMON_OPTIONS()'; see cf/README.
3487c478bd9Sstevel@tonic-gate)'dnl
3497c478bd9Sstevel@tonic-gate`DAEMON_OPTIONS(`confDAEMON_OPTIONS')')
3507c478bd9Sstevel@tonic-gateifelse(defn(`_DPO_'), `',
3517c478bd9Sstevel@tonic-gate`ifdef(`_NETINET6_', `O DaemonPortOptions=Name=MTA-v4, Family=inet
3527c478bd9Sstevel@tonic-gateO DaemonPortOptions=Name=MTA-v6, Family=inet6',`O DaemonPortOptions=Name=MTA')', `_DPO_')
3537c478bd9Sstevel@tonic-gateifdef(`_NO_MSA_', `dnl', `O DaemonPortOptions=Port=587, Name=MSA, M=E')
3547c478bd9Sstevel@tonic-gate
3557c478bd9Sstevel@tonic-gate# SMTP client options
3567c478bd9Sstevel@tonic-gateifelse(defn(`confCLIENT_OPTIONS'), `', `dnl',
3577c478bd9Sstevel@tonic-gate`errprint(WARNING: `confCLIENT_OPTIONS' is no longer valid.  See cf/README for more information.
3587c478bd9Sstevel@tonic-gate)'dnl
3597c478bd9Sstevel@tonic-gate`CLIENT_OPTIONS(`confCLIENT_OPTIONS')')
3607c478bd9Sstevel@tonic-gateifelse(defn(`_CPO_'), `',
3617c478bd9Sstevel@tonic-gate`#O ClientPortOptions=Family=inet, Address=0.0.0.0', `_CPO_')
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate# Modifiers to `define' {daemon_flags} for direct submissions
3647c478bd9Sstevel@tonic-gate_OPTION(DirectSubmissionModifiers, `confDIRECT_SUBMISSION_MODIFIERS', `')
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate# Use as mail submission program? See sendmail/SECURITY
3677c478bd9Sstevel@tonic-gate_OPTION(UseMSP, `confUSE_MSP', `')
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate# privacy flags
3707c478bd9Sstevel@tonic-gate_OPTION(PrivacyOptions, `confPRIVACY_FLAGS', `authwarnings')
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate# who (if anyone) should get extra copies of error messages
3737c478bd9Sstevel@tonic-gate_OPTION(PostmasterCopy, `confCOPY_ERRORS_TO', `Postmaster')
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate# slope of queue-only function
3767c478bd9Sstevel@tonic-gate_OPTION(QueueFactor, `confQUEUE_FACTOR', `600000')
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate# limit on number of concurrent queue runners
3797c478bd9Sstevel@tonic-gate_OPTION(MaxQueueChildren, `confMAX_QUEUE_CHILDREN', `')
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate# maximum number of queue-runners per queue-grouping with multiple queues
3827c478bd9Sstevel@tonic-gate_OPTION(MaxRunnersPerQueue, `confMAX_RUNNERS_PER_QUEUE', `1')
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate# priority of queue runners (nice(3))
3857c478bd9Sstevel@tonic-gate_OPTION(NiceQueueRun, `confNICE_QUEUE_RUN', `')
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate# shall we sort the queue by hostname first?
3887c478bd9Sstevel@tonic-gate_OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority')
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate# minimum time in queue before retry
3917c478bd9Sstevel@tonic-gate_OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m')
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate# how many jobs can you process in the queue?
39449218d4fSjbeck_OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0')
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate# perform initial split of envelope without checking MX records
3977c478bd9Sstevel@tonic-gate_OPTION(FastSplit, `confFAST_SPLIT', `1')
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate# queue directory
4007c478bd9Sstevel@tonic-gateO QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
4017c478bd9Sstevel@tonic-gate
402058561cbSjbeck# key for shared memory; 0 to turn off, -1 to auto-select
4037c478bd9Sstevel@tonic-gate_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
4047c478bd9Sstevel@tonic-gate
405058561cbSjbeck# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
406058561cbSjbeck_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate# timeouts (many of these)
4097c478bd9Sstevel@tonic-gate_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
4107c478bd9Sstevel@tonic-gate_OPTION(Timeout.connect, `confTO_CONNECT', `5m')
4117c478bd9Sstevel@tonic-gate_OPTION(Timeout.aconnect, `confTO_ACONNECT', `0s')
4127c478bd9Sstevel@tonic-gate_OPTION(Timeout.iconnect, `confTO_ICONNECT', `5m')
4137c478bd9Sstevel@tonic-gate_OPTION(Timeout.helo, `confTO_HELO', `5m')
4147c478bd9Sstevel@tonic-gate_OPTION(Timeout.mail, `confTO_MAIL', `10m')
4157c478bd9Sstevel@tonic-gate_OPTION(Timeout.rcpt, `confTO_RCPT', `1h')
4167c478bd9Sstevel@tonic-gate_OPTION(Timeout.datainit, `confTO_DATAINIT', `5m')
4177c478bd9Sstevel@tonic-gate_OPTION(Timeout.datablock, `confTO_DATABLOCK', `1h')
4187c478bd9Sstevel@tonic-gate_OPTION(Timeout.datafinal, `confTO_DATAFINAL', `1h')
4197c478bd9Sstevel@tonic-gate_OPTION(Timeout.rset, `confTO_RSET', `5m')
4207c478bd9Sstevel@tonic-gate_OPTION(Timeout.quit, `confTO_QUIT', `2m')
4217c478bd9Sstevel@tonic-gate_OPTION(Timeout.misc, `confTO_MISC', `2m')
4227c478bd9Sstevel@tonic-gate_OPTION(Timeout.command, `confTO_COMMAND', `1h')
4237c478bd9Sstevel@tonic-gate_OPTION(Timeout.ident, `confTO_IDENT', `5s')
4247c478bd9Sstevel@tonic-gate_OPTION(Timeout.fileopen, `confTO_FILEOPEN', `60s')
4257c478bd9Sstevel@tonic-gate_OPTION(Timeout.control, `confTO_CONTROL', `2m')
4267c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d')
4277c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d')
4287c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d')
4297c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d')
4307c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d')
4317c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h')
4327c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h')
4337c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h')
4347c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h')
4357c478bd9Sstevel@tonic-gate_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h')
4367c478bd9Sstevel@tonic-gate_OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m')
4377c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s')
4387c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s')
4397c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retrans.normal, `confTO_RESOLVER_RETRANS_NORMAL', `5s')
4407c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retry, `confTO_RESOLVER_RETRY', `4')
4417c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retry.first, `confTO_RESOLVER_RETRY_FIRST', `4')
4427c478bd9Sstevel@tonic-gate_OPTION(Timeout.resolver.retry.normal, `confTO_RESOLVER_RETRY_NORMAL', `4')
4437c478bd9Sstevel@tonic-gate_OPTION(Timeout.lhlo, `confTO_LHLO', `2m')
4447c478bd9Sstevel@tonic-gate_OPTION(Timeout.auth, `confTO_AUTH', `10m')
4457c478bd9Sstevel@tonic-gate_OPTION(Timeout.starttls, `confTO_STARTTLS', `1h')
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate# time for DeliverBy; extension disabled if less than 0
4487c478bd9Sstevel@tonic-gate_OPTION(DeliverByMin, `confDELIVER_BY_MIN', `0')
4497c478bd9Sstevel@tonic-gate
4507c478bd9Sstevel@tonic-gate# should we not prune routes in route-addr syntax addresses?
4517c478bd9Sstevel@tonic-gate_OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate# queue up everything before forking?
4547c478bd9Sstevel@tonic-gate_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate# status file
457058561cbSjbeck_OPTION(StatusFile, `STATUS_FILE')
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate# time zone handling:
4607c478bd9Sstevel@tonic-gate#  if undefined, use system default
4617c478bd9Sstevel@tonic-gate#  if defined but null, use TZ envariable passed in
4627c478bd9Sstevel@tonic-gate#  if defined and non-null, use that info
4637c478bd9Sstevel@tonic-gateifelse(confTIME_ZONE, `USE_SYSTEM', `#O TimeZoneSpec=',
4647c478bd9Sstevel@tonic-gate	confTIME_ZONE, `USE_TZ', `O TimeZoneSpec=',
4657c478bd9Sstevel@tonic-gate	`O TimeZoneSpec=confTIME_ZONE')
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate# default UID (can be username or userid:groupid)
4687c478bd9Sstevel@tonic-gate_OPTION(DefaultUser, `confDEF_USER_ID', `mailnull')
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate# list of locations of user database file (null means no lookup)
4717c478bd9Sstevel@tonic-gate_OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb')
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate# fallback MX host
4747c478bd9Sstevel@tonic-gate_OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net')
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gate# fallback smart host
4777c478bd9Sstevel@tonic-gate_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net')
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate# if we are the best MX host for a site, try it directly instead of config err
4807c478bd9Sstevel@tonic-gate_OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False')
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate# load average at which we just queue messages
4837c478bd9Sstevel@tonic-gate_OPTION(QueueLA, `confQUEUE_LA', `8')
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate# load average at which we refuse connections
4867c478bd9Sstevel@tonic-gate_OPTION(RefuseLA, `confREFUSE_LA', `12')
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate# log interval when refusing connections for this long
4897c478bd9Sstevel@tonic-gate_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h')
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate# load average at which we delay connections; 0 means no limit
4927c478bd9Sstevel@tonic-gate_OPTION(DelayLA, `confDELAY_LA', `0')
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate# maximum number of children we allow at one time
4957c478bd9Sstevel@tonic-gate_OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate# maximum number of new connections per second
4987c478bd9Sstevel@tonic-gate_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate# Width of the window
5017c478bd9Sstevel@tonic-gate_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate# work recipient factor
5047c478bd9Sstevel@tonic-gate_OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000')
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate# deliver each queued job in a separate process?
5077c478bd9Sstevel@tonic-gate_OPTION(ForkEachJob, `confSEPARATE_PROC', `False')
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate# work class factor
5107c478bd9Sstevel@tonic-gate_OPTION(ClassFactor, `confWORK_CLASS_FACTOR', `1800')
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate# work time factor
5137c478bd9Sstevel@tonic-gate_OPTION(RetryFactor, `confWORK_TIME_FACTOR', `90000')
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate# default character set
5167c478bd9Sstevel@tonic-gate_OPTION(DefaultCharSet, `confDEF_CHAR_SET', `unknown-8bit')
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate# service switch file (name hardwired on Solaris, Ultrix, OSF/1, others)
5197c478bd9Sstevel@tonic-gate_OPTION(ServiceSwitchFile, `confSERVICE_SWITCH_FILE', `MAIL_SETTINGS_DIR`'service.switch')
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate# hosts file (normally /etc/hosts)
5227c478bd9Sstevel@tonic-gate_OPTION(HostsFile, `confHOSTS_FILE', `/etc/hosts')
5237c478bd9Sstevel@tonic-gate
5247c478bd9Sstevel@tonic-gate# dialup line delay on connection failure
52549218d4fSjbeck_OPTION(DialDelay, `confDIAL_DELAY', `0s')
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate# action to take if there are no recipients in the message
52849218d4fSjbeck_OPTION(NoRecipientAction, `confNO_RCPT_ACTION', `none')
5297c478bd9Sstevel@tonic-gate
5307c478bd9Sstevel@tonic-gate# chrooted environment for writing to files
53149218d4fSjbeck_OPTION(SafeFileEnvironment, `confSAFE_FILE_ENV', `')
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate# are colons OK in addresses?
5347c478bd9Sstevel@tonic-gate_OPTION(ColonOkInAddr, `confCOLON_OK_IN_ADDR', `True')
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate# shall I avoid expanding CNAMEs (violates protocols)?
5377c478bd9Sstevel@tonic-gate_OPTION(DontExpandCnames, `confDONT_EXPAND_CNAMES', `False')
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate# SMTP initial login message (old $e macro)
5407c478bd9Sstevel@tonic-gate_OPTION(SmtpGreetingMessage, `confSMTP_LOGIN_MSG', `$j Sendmail $v ready at $b')
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate# UNIX initial From header format (old $l macro)
5437c478bd9Sstevel@tonic-gate_OPTION(UnixFromLine, `confFROM_LINE', `From $g $d')
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate# From: lines that have embedded newlines are unwrapped onto one line
5467c478bd9Sstevel@tonic-gate_OPTION(SingleLineFromHeader, `confSINGLE_LINE_FROM_HEADER', `False')
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate# Allow HELO SMTP command that does not `include' a host name
5497c478bd9Sstevel@tonic-gate_OPTION(AllowBogusHELO, `confALLOW_BOGUS_HELO', `False')
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate# Characters to be quoted in a full name phrase (@,;:\()[] are automatic)
5527c478bd9Sstevel@tonic-gate_OPTION(MustQuoteChars, `confMUST_QUOTE_CHARS', `.')
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate# delimiter (operator) characters (old $o macro)
5557c478bd9Sstevel@tonic-gate_OPTION(OperatorChars, `confOPERATORS', `.:@[]')
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate# shall I avoid calling initgroups(3) because of high NIS costs?
5587c478bd9Sstevel@tonic-gate_OPTION(DontInitGroups, `confDONT_INIT_GROUPS', `False')
5597c478bd9Sstevel@tonic-gate
5607c478bd9Sstevel@tonic-gate# are group-writable `:include:' and .forward files (un)trustworthy?
5617c478bd9Sstevel@tonic-gate# True (the default) means they are not trustworthy.
5627c478bd9Sstevel@tonic-gate_OPTION(UnsafeGroupWrites, `confUNSAFE_GROUP_WRITES', `True')
5637c478bd9Sstevel@tonic-gateifdef(`confUNSAFE_GROUP_WRITES',
5647c478bd9Sstevel@tonic-gate`errprint(`WARNING: confUNSAFE_GROUP_WRITES is deprecated; use confDONT_BLAME_SENDMAIL.
5657c478bd9Sstevel@tonic-gate')')
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate# where do errors that occur when sending errors get sent?
5687c478bd9Sstevel@tonic-gate_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
5697c478bd9Sstevel@tonic-gate
5704aac33d3Sjbeck# issue temporary errors (4xy) instead of permanent errors (5xy)?
5714aac33d3Sjbeck_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
5724aac33d3Sjbeck
5737c478bd9Sstevel@tonic-gate# where to save bounces if all else fails
5747c478bd9Sstevel@tonic-gate_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
5757c478bd9Sstevel@tonic-gate
5767c478bd9Sstevel@tonic-gate# what user id do we assume for the majority of the processing?
5777c478bd9Sstevel@tonic-gate_OPTION(RunAsUser, `confRUN_AS_USER', `sendmail')
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate# maximum number of recipients per SMTP envelope
5807c478bd9Sstevel@tonic-gate_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0')
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate# limit the rate recipients per SMTP envelope are accepted
5837c478bd9Sstevel@tonic-gate# once the threshold number of recipients have been rejected
5847c478bd9Sstevel@tonic-gate_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0')
5857c478bd9Sstevel@tonic-gate
586*e9af4bc0SJohn Beck
5877c478bd9Sstevel@tonic-gate# shall we get local names from our installed interfaces?
5887c478bd9Sstevel@tonic-gate_OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False')
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate# Return-Receipt-To: header implies DSN request
5917c478bd9Sstevel@tonic-gate_OPTION(RrtImpliesDsn, `confRRT_IMPLIES_DSN', `False')
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate# override connection address (for testing)
5947c478bd9Sstevel@tonic-gate_OPTION(ConnectOnlyTo, `confCONNECT_ONLY_TO', `0.0.0.0')
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate# Trusted user for file ownership and starting the daemon
5977c478bd9Sstevel@tonic-gate_OPTION(TrustedUser, `confTRUSTED_USER', `root')
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate# Control socket for daemon management
6007c478bd9Sstevel@tonic-gate_OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control')
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate# Maximum MIME header length to protect MUAs
6037c478bd9Sstevel@tonic-gate_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `2048/1024')
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate# Maximum length of the sum of all headers
6067c478bd9Sstevel@tonic-gate_OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768')
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate# Maximum depth of alias recursion
6097c478bd9Sstevel@tonic-gate_OPTION(MaxAliasRecursion, `confMAX_ALIAS_RECURSION', `10')
6107c478bd9Sstevel@tonic-gate
6117c478bd9Sstevel@tonic-gate# location of pid file
6127c478bd9Sstevel@tonic-gate_OPTION(PidFile, `confPID_FILE', `/var/run/sendmail.pid')
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate# Prefix string for the process title shown on 'ps' listings
6157c478bd9Sstevel@tonic-gate_OPTION(ProcessTitlePrefix, `confPROCESS_TITLE_PREFIX', `prefix')
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate# Data file (df) memory-buffer file maximum size
6187c478bd9Sstevel@tonic-gate_OPTION(DataFileBufferSize, `confDF_BUFFER_SIZE', `4096')
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate# Transcript file (xf) memory-buffer file maximum size
6217c478bd9Sstevel@tonic-gate_OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096')
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate# lookup type to find information about local mailboxes
6247c478bd9Sstevel@tonic-gate_OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw')
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate# override compile time flag REQUIRES_DIR_FSYNC
6277c478bd9Sstevel@tonic-gate_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true')
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate# list of authentication mechanisms
6307c478bd9Sstevel@tonic-gate_OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5')
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate# Authentication realm
6337c478bd9Sstevel@tonic-gate_OPTION(AuthRealm, `confAUTH_REALM', `')
6347c478bd9Sstevel@tonic-gate
6357c478bd9Sstevel@tonic-gate# default authentication information for outgoing connections
6367c478bd9Sstevel@tonic-gate_OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info')
6377c478bd9Sstevel@tonic-gate
6387c478bd9Sstevel@tonic-gate# SMTP AUTH flags
6397c478bd9Sstevel@tonic-gate_OPTION(AuthOptions, `confAUTH_OPTIONS', `')
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate# SMTP AUTH maximum encryption strength
6427c478bd9Sstevel@tonic-gate_OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `')
6437c478bd9Sstevel@tonic-gate
6447c478bd9Sstevel@tonic-gate# SMTP STARTTLS server options
6457c478bd9Sstevel@tonic-gate_OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `')
6467c478bd9Sstevel@tonic-gate
647*e9af4bc0SJohn Beck
6487c478bd9Sstevel@tonic-gate# Input mail filters
6497c478bd9Sstevel@tonic-gate_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gateifelse(len(X`'_MAIL_FILTERS_DEF), `1', `dnl', `dnl
6527c478bd9Sstevel@tonic-gate# Milter options
6537c478bd9Sstevel@tonic-gate_OPTION(Milter.LogLevel, `confMILTER_LOG_LEVEL', `')
6547c478bd9Sstevel@tonic-gate_OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
6557c478bd9Sstevel@tonic-gate_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
6567c478bd9Sstevel@tonic-gate_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
6577c478bd9Sstevel@tonic-gate_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
6584aac33d3Sjbeck_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
6594aac33d3Sjbeck_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
6604aac33d3Sjbeck_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
6617c478bd9Sstevel@tonic-gate
6627c478bd9Sstevel@tonic-gate# CA directory
6637c478bd9Sstevel@tonic-gate_OPTION(CACertPath, `confCACERT_PATH', `')
6647c478bd9Sstevel@tonic-gate# CA file
6657c478bd9Sstevel@tonic-gate_OPTION(CACertFile, `confCACERT', `')
6667c478bd9Sstevel@tonic-gate# Server Cert
6677c478bd9Sstevel@tonic-gate_OPTION(ServerCertFile, `confSERVER_CERT', `')
6687c478bd9Sstevel@tonic-gate# Server private key
6697c478bd9Sstevel@tonic-gate_OPTION(ServerKeyFile, `confSERVER_KEY', `')
6707c478bd9Sstevel@tonic-gate# Client Cert
6717c478bd9Sstevel@tonic-gate_OPTION(ClientCertFile, `confCLIENT_CERT', `')
6727c478bd9Sstevel@tonic-gate# Client private key
6737c478bd9Sstevel@tonic-gate_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
6747c478bd9Sstevel@tonic-gate# File containing certificate revocation lists
6757c478bd9Sstevel@tonic-gate_OPTION(CRLFile, `confCRL', `')
6767c478bd9Sstevel@tonic-gate# DHParameters (only required if DSA/DH is used)
6777c478bd9Sstevel@tonic-gate_OPTION(DHParameters, `confDH_PARAMETERS', `')
6787c478bd9Sstevel@tonic-gate# Random data source (required for systems without /dev/urandom under OpenSSL)
6797c478bd9Sstevel@tonic-gate_OPTION(RandFile, `confRAND_FILE', `')
6807c478bd9Sstevel@tonic-gate
681058561cbSjbeck# Maximum number of "useless" commands before slowing down
682058561cbSjbeck_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
683058561cbSjbeck
684058561cbSjbeck# Name to use for EHLO (defaults to $j)
685058561cbSjbeck_OPTION(HeloName, `confHELO_NAME')
686058561cbSjbeck
6877c478bd9Sstevel@tonic-gate############################
6887c478bd9Sstevel@tonic-gate`# QUEUE GROUP DEFINITIONS  #'
6897c478bd9Sstevel@tonic-gate############################
6907c478bd9Sstevel@tonic-gate_QUEUE_GROUP_
6917c478bd9Sstevel@tonic-gate
6927c478bd9Sstevel@tonic-gate###########################
6937c478bd9Sstevel@tonic-gate#   Message precedences   #
6947c478bd9Sstevel@tonic-gate###########################
6957c478bd9Sstevel@tonic-gate
6967c478bd9Sstevel@tonic-gatePfirst-class=0
6977c478bd9Sstevel@tonic-gatePspecial-delivery=100
6987c478bd9Sstevel@tonic-gatePlist=-30
6997c478bd9Sstevel@tonic-gatePbulk=-60
7007c478bd9Sstevel@tonic-gatePjunk=-100
7017c478bd9Sstevel@tonic-gate
7027c478bd9Sstevel@tonic-gate#####################
7037c478bd9Sstevel@tonic-gate#   Trusted users   #
7047c478bd9Sstevel@tonic-gate#####################
7057c478bd9Sstevel@tonic-gate
7067c478bd9Sstevel@tonic-gate# this is equivalent to setting class "t"
7077c478bd9Sstevel@tonic-gateifdef(`_USE_CT_FILE_', `', `#')Ft`'ifdef(`confCT_FILE', confCT_FILE, `MAIL_SETTINGS_DIR`'trusted-users')
7087c478bd9Sstevel@tonic-gateTroot
7097c478bd9Sstevel@tonic-gateTdaemon
7107c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl', `Tuucp')
7117c478bd9Sstevel@tonic-gateifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl')
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate#########################
7147c478bd9Sstevel@tonic-gate#   Format of headers   #
7157c478bd9Sstevel@tonic-gate#########################
7167c478bd9Sstevel@tonic-gate
7177c478bd9Sstevel@tonic-gateifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl
7187c478bd9Sstevel@tonic-gateifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl
7197c478bd9Sstevel@tonic-gateH?P?Return-Path: <$g>
7207c478bd9Sstevel@tonic-gateHReceived: confRECEIVED_HEADER
7217c478bd9Sstevel@tonic-gateH?D?Resent-Date: $a
7227c478bd9Sstevel@tonic-gateH?D?Date: $a
7237c478bd9Sstevel@tonic-gateH?F?Resent-From: confFROM_HEADER
7247c478bd9Sstevel@tonic-gateH?F?From: confFROM_HEADER
7257c478bd9Sstevel@tonic-gateH?x?Full-Name: $x
7267c478bd9Sstevel@tonic-gate# HPosted-Date: $a
7277c478bd9Sstevel@tonic-gate# H?l?Received-Date: $b
7287c478bd9Sstevel@tonic-gateH?M?Resent-Message-Id: confMESSAGEID_HEADER
7297c478bd9Sstevel@tonic-gateH?M?Message-Id: confMESSAGEID_HEADER
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate#
7327c478bd9Sstevel@tonic-gate######################################################################
7337c478bd9Sstevel@tonic-gate######################################################################
7347c478bd9Sstevel@tonic-gate#####
7357c478bd9Sstevel@tonic-gate#####			REWRITING RULES
7367c478bd9Sstevel@tonic-gate#####
7377c478bd9Sstevel@tonic-gate######################################################################
7387c478bd9Sstevel@tonic-gate######################################################################
7397c478bd9Sstevel@tonic-gate
7407c478bd9Sstevel@tonic-gate############################################
7417c478bd9Sstevel@tonic-gate###  Ruleset 3 -- Name Canonicalization  ###
7427c478bd9Sstevel@tonic-gate############################################
7437c478bd9Sstevel@tonic-gateScanonify=3
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate# handle null input (translate to <@> special case)
7467c478bd9Sstevel@tonic-gateR$@			$@ <@>
7477c478bd9Sstevel@tonic-gate
7487c478bd9Sstevel@tonic-gate# strip group: syntax (not inside angle brackets!) and trailing semicolon
7497c478bd9Sstevel@tonic-gateR$*			$: $1 <@>			mark addresses
7507c478bd9Sstevel@tonic-gateR$* < $* > $* <@>	$: $1 < $2 > $3			unmark <addr>
7517c478bd9Sstevel@tonic-gateR@ $* <@>		$: @ $1				unmark @host:...
7527c478bd9Sstevel@tonic-gateR$* [ IPv6 : $+ ] <@>	$: $1 [ IPv6 : $2 ]		unmark IPv6 addr
7537c478bd9Sstevel@tonic-gateR$* :: $* <@>		$: $1 :: $2			unmark node::addr
7547c478bd9Sstevel@tonic-gateR:`include': $* <@>	$: :`include': $1			unmark :`include':...
7557c478bd9Sstevel@tonic-gateR$* : $* [ $* ]		$: $1 : $2 [ $3 ] <@>		remark if leading colon
7567c478bd9Sstevel@tonic-gateR$* : $* <@>		$: $2				strip colon if marked
7577c478bd9Sstevel@tonic-gateR$* <@>			$: $1				unmark
7587c478bd9Sstevel@tonic-gateR$* ;			   $1				strip trailing semi
7597c478bd9Sstevel@tonic-gateR$* < $+ :; > $*	$@ $2 :; <@>			catch <list:;>
7607c478bd9Sstevel@tonic-gateR$* < $* ; >		   $1 < $2 >			bogus bracketed semi
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate# null input now results from list:; syntax
7637c478bd9Sstevel@tonic-gateR$@			$@ :; <@>
7647c478bd9Sstevel@tonic-gate
7657c478bd9Sstevel@tonic-gate# strip angle brackets -- note RFC733 heuristic to get innermost item
7667c478bd9Sstevel@tonic-gateR$*			$: < $1 >			housekeeping <>
7677c478bd9Sstevel@tonic-gateR$+ < $* >		   < $2 >			strip excess on left
7687c478bd9Sstevel@tonic-gateR< $* > $+		   < $1 >			strip excess on right
7697c478bd9Sstevel@tonic-gateR<>			$@ < @ >			MAIL FROM:<> case
7707c478bd9Sstevel@tonic-gateR< $+ >			$: $1				remove housekeeping <>
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gateifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
7737c478bd9Sstevel@tonic-gate# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
7747c478bd9Sstevel@tonic-gateR@ $+ , $+		@ $1 : $2			change all "," to ":"
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate# localize and dispose of route-based addresses
7777c478bd9Sstevel@tonic-gatednl XXX: IPv6 colon conflict
7787c478bd9Sstevel@tonic-gateifdef(`NO_NETINET6', `dnl',
7797c478bd9Sstevel@tonic-gate`R@ [$+] : $+		$@ $>Canonify2 < @ [$1] > : $2	handle <route-addr>')
7807c478bd9Sstevel@tonic-gateR@ $+ : $+		$@ $>Canonify2 < @$1 > : $2	handle <route-addr>
7817c478bd9Sstevel@tonic-gatednl',`dnl
7827c478bd9Sstevel@tonic-gate# strip route address <@a,@b,@c:user@d> -> <user@d>
7837c478bd9Sstevel@tonic-gateR@ $+ , $+		$2
7847c478bd9Sstevel@tonic-gateifdef(`NO_NETINET6', `dnl',
7857c478bd9Sstevel@tonic-gate`R@ [ $* ] : $+		$2')
7867c478bd9Sstevel@tonic-gateR@ $+ : $+		$2
7877c478bd9Sstevel@tonic-gatednl')
7887c478bd9Sstevel@tonic-gate
7897c478bd9Sstevel@tonic-gate# find focus for list syntax
7907c478bd9Sstevel@tonic-gateR $+ : $* ; @ $+	$@ $>Canonify2 $1 : $2 ; < @ $3 >	list syntax
7917c478bd9Sstevel@tonic-gateR $+ : $* ;		$@ $1 : $2;			list syntax
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate# find focus for @ syntax addresses
7947c478bd9Sstevel@tonic-gateR$+ @ $+		$: $1 < @ $2 >			focus on domain
7957c478bd9Sstevel@tonic-gateR$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
7967c478bd9Sstevel@tonic-gateR$+ < @ $+ >		$@ $>Canonify2 $1 < @ $2 >	already canonical
7977c478bd9Sstevel@tonic-gate
7987c478bd9Sstevel@tonic-gatednl This is flagged as an error in S0; no need to silently fix it here.
7997c478bd9Sstevel@tonic-gatednl # do some sanity checking
8007c478bd9Sstevel@tonic-gatednl R$* < @ $~[ $* : $* > $*	$1 < @ $2 $3 > $4	nix colons in addrs
8017c478bd9Sstevel@tonic-gate
8027c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
8037c478bd9Sstevel@tonic-gate`# convert old-style addresses to a domain-based address
8047c478bd9Sstevel@tonic-gateR$- ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	resolve uucp names
8057c478bd9Sstevel@tonic-gateR$+ . $- ! $+		$@ $>Canonify2 $3 < @ $1 . $2 >		domain uucps
8067c478bd9Sstevel@tonic-gateR$+ ! $+		$@ $>Canonify2 $2 < @ $1 .UUCP >	uucp subdomains
8077c478bd9Sstevel@tonic-gate')
8087c478bd9Sstevel@tonic-gateifdef(`_USE_DECNET_SYNTAX_',
8097c478bd9Sstevel@tonic-gate`# convert node::user addresses into a domain-based address
8107c478bd9Sstevel@tonic-gateR$- :: $+		$@ $>Canonify2 $2 < @ $1 .DECNET >	resolve DECnet names
8117c478bd9Sstevel@tonic-gateR$- . $- :: $+		$@ $>Canonify2 $3 < @ $1.$2 .DECNET >	numeric DECnet addr
8127c478bd9Sstevel@tonic-gate',
8137c478bd9Sstevel@tonic-gate	`dnl')
8147c478bd9Sstevel@tonic-gate# if we have % signs, take the rightmost one
8157c478bd9Sstevel@tonic-gateR$* % $*		$1 @ $2				First make them all @s.
8167c478bd9Sstevel@tonic-gateR$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
8177c478bd9Sstevel@tonic-gateR$* @ $*		$@ $>Canonify2 $1 < @ $2 >	Insert < > and finish
8187c478bd9Sstevel@tonic-gate
8197c478bd9Sstevel@tonic-gate# else we must be a local name
8207c478bd9Sstevel@tonic-gateR$*			$@ $>Canonify2 $1
8217c478bd9Sstevel@tonic-gate
8227c478bd9Sstevel@tonic-gate
8237c478bd9Sstevel@tonic-gate################################################
8247c478bd9Sstevel@tonic-gate###  Ruleset 96 -- bottom half of ruleset 3  ###
8257c478bd9Sstevel@tonic-gate################################################
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gateSCanonify2=96
8287c478bd9Sstevel@tonic-gate
8297c478bd9Sstevel@tonic-gate# handle special cases for local names
8307c478bd9Sstevel@tonic-gateR$* < @ localhost > $*		$: $1 < @ $j . > $2		no domain at all
8317c478bd9Sstevel@tonic-gateR$* < @ localhost . $m > $*	$: $1 < @ $j . > $2		local domain
8327c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
8337c478bd9Sstevel@tonic-gate`R$* < @ localhost . UUCP > $*	$: $1 < @ $j . > $2		.UUCP domain')
8347c478bd9Sstevel@tonic-gate
8357c478bd9Sstevel@tonic-gate# check for IPv4/IPv6 domain literal
8367c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] > $*		$: $1 < @@ [ $2 ] > $3		mark [addr]
8377c478bd9Sstevel@tonic-gateR$* < @@ $=w > $*		$: $1 < @ $j . > $3		self-literal
8387c478bd9Sstevel@tonic-gateR$* < @@ $+ > $*		$@ $1 < @ $2 > $3		canon IP addr
8397c478bd9Sstevel@tonic-gate
8407c478bd9Sstevel@tonic-gateifdef(`_DOMAIN_TABLE_', `dnl
8417c478bd9Sstevel@tonic-gate# look up domains in the domain table
8427c478bd9Sstevel@tonic-gateR$* < @ $+ > $* 		$: $1 < @ $(domaintable $2 $) > $3', `dnl')
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gateundivert(2)dnl LOCAL_RULE_3
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gateifdef(`_BITDOMAIN_TABLE_', `dnl
8477c478bd9Sstevel@tonic-gate# handle BITNET mapping
8487c478bd9Sstevel@tonic-gateR$* < @ $+ .BITNET > $*		$: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3', `dnl')
8497c478bd9Sstevel@tonic-gate
8507c478bd9Sstevel@tonic-gateifdef(`_UUDOMAIN_TABLE_', `dnl
8517c478bd9Sstevel@tonic-gate# handle UUCP mapping
8527c478bd9Sstevel@tonic-gateR$* < @ $+ .UUCP > $*		$: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3', `dnl')
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
8557c478bd9Sstevel@tonic-gate`ifdef(`UUCP_RELAY',
8567c478bd9Sstevel@tonic-gate`# pass UUCP addresses straight through
8577c478bd9Sstevel@tonic-gateR$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP . > $3',
8587c478bd9Sstevel@tonic-gate`# if really UUCP, handle it immediately
8597c478bd9Sstevel@tonic-gateifdef(`_CLASS_U_',
8607c478bd9Sstevel@tonic-gate`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
8617c478bd9Sstevel@tonic-gateifdef(`_CLASS_V_',
8627c478bd9Sstevel@tonic-gate`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
8637c478bd9Sstevel@tonic-gateifdef(`_CLASS_W_',
8647c478bd9Sstevel@tonic-gate`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
8657c478bd9Sstevel@tonic-gateifdef(`_CLASS_X_',
8667c478bd9Sstevel@tonic-gate`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
8677c478bd9Sstevel@tonic-gateifdef(`_CLASS_Y_',
8687c478bd9Sstevel@tonic-gate`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP . > $3', `dnl')
8697c478bd9Sstevel@tonic-gate
8707c478bd9Sstevel@tonic-gateifdef(`_NO_CANONIFY_', `dnl', `dnl
8717c478bd9Sstevel@tonic-gate# try UUCP traffic as a local address
8727c478bd9Sstevel@tonic-gateR$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP . > $3
8737c478bd9Sstevel@tonic-gateR$* < @ $+ . . UUCP . > $*	$@ $1 < @ $2 . > $3')
8747c478bd9Sstevel@tonic-gate')')
8757c478bd9Sstevel@tonic-gate# hostnames ending in class P are always canonical
8767c478bd9Sstevel@tonic-gateR$* < @ $* $=P > $*		$: $1 < @ $2 $3 . > $4
8777c478bd9Sstevel@tonic-gatednl apply the next rule only for hostnames not in class P
8787c478bd9Sstevel@tonic-gatednl this even works for phrases in class P since . is in class P
8797c478bd9Sstevel@tonic-gatednl which daemon flags are set?
8807c478bd9Sstevel@tonic-gateR$* < @ $* $~P > $*		$: $&{daemon_flags} $| $1 < @ $2 $3 > $4
8817c478bd9Sstevel@tonic-gatednl the other rules in this section only apply if the hostname
8827c478bd9Sstevel@tonic-gatednl does not end in class P hence no further checks are done here
8837c478bd9Sstevel@tonic-gatednl if this ever changes make sure the lookups are "protected" again!
8847c478bd9Sstevel@tonic-gateifdef(`_NO_CANONIFY_', `dnl
8857c478bd9Sstevel@tonic-gatednl do not canonify unless:
8867c478bd9Sstevel@tonic-gatednl domain ends in class {Canonify} (this does not work if the intersection
8877c478bd9Sstevel@tonic-gatednl	with class P is non-empty)
8887c478bd9Sstevel@tonic-gatednl or {daemon_flags} has c set
8897c478bd9Sstevel@tonic-gate# pass to name server to make hostname canonical if in class {Canonify}
8907c478bd9Sstevel@tonic-gateR$* $| $* < @ $* $={Canonify} > $*	$: $2 < @ $[ $3 $4 $] > $5
8917c478bd9Sstevel@tonic-gate# pass to name server to make hostname canonical if requested
8927c478bd9Sstevel@tonic-gateR$* c $* $| $* < @ $* > $*	$: $3 < @ $[ $4 $] > $5
8937c478bd9Sstevel@tonic-gatednl trailing dot? -> do not apply _CANONIFY_HOSTS_
8947c478bd9Sstevel@tonic-gateR$* $| $* < @ $+ . > $*		$: $2 < @ $3 . > $4
8957c478bd9Sstevel@tonic-gate# add a trailing dot to qualified hostnames so other rules will work
8967c478bd9Sstevel@tonic-gateR$* $| $* < @ $+.$+ > $*	$: $2 < @ $3.$4 . > $5
8977c478bd9Sstevel@tonic-gateifdef(`_CANONIFY_HOSTS_', `dnl
8987c478bd9Sstevel@tonic-gatednl this should only apply to unqualified hostnames
8997c478bd9Sstevel@tonic-gatednl but if a valid character inside an unqualified hostname is an OperatorChar
9007c478bd9Sstevel@tonic-gatednl then $- does not work.
9017c478bd9Sstevel@tonic-gate# lookup unqualified hostnames
9027c478bd9Sstevel@tonic-gateR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
9037c478bd9Sstevel@tonic-gatednl _NO_CANONIFY_ is not set: canonify unless:
9047c478bd9Sstevel@tonic-gatednl {daemon_flags} contains CC (do not canonify)
9057c478bd9Sstevel@tonic-gatednl but add a trailing dot to qualified hostnames so other rules will work
9067c478bd9Sstevel@tonic-gatednl should we do this for every hostname: even unqualified?
9077c478bd9Sstevel@tonic-gateR$* CC $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
9087c478bd9Sstevel@tonic-gateR$* CC $* $| $*			$: $3
9097c478bd9Sstevel@tonic-gateifdef(`_FFR_NOCANONIFY_HEADERS', `dnl
9107c478bd9Sstevel@tonic-gate# do not canonify header addresses
9117c478bd9Sstevel@tonic-gateR$* $| $* < @ $* $~P > $*	$: $&{addr_type} $| $2 < @ $3 $4 > $5
9127c478bd9Sstevel@tonic-gateR$* h $* $| $* < @ $+.$+ > $*	$: $3 < @ $4.$5 . > $6
9137c478bd9Sstevel@tonic-gateR$* h $* $| $*			$: $3', `dnl')
9147c478bd9Sstevel@tonic-gate# pass to name server to make hostname canonical
9157c478bd9Sstevel@tonic-gateR$* $| $* < @ $* > $*		$: $2 < @ $[ $3 $] > $4')
9167c478bd9Sstevel@tonic-gatednl remove {daemon_flags} for other cases
9177c478bd9Sstevel@tonic-gateR$* $| $*			$: $2
9187c478bd9Sstevel@tonic-gate
9197c478bd9Sstevel@tonic-gate# local host aliases and pseudo-domains are always canonical
9207c478bd9Sstevel@tonic-gateR$* < @ $=w > $*		$: $1 < @ $2 . > $3
9217c478bd9Sstevel@tonic-gateifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
9227c478bd9Sstevel@tonic-gate`R$* < @ $* $=M > $*		$: $1 < @ $2 $3 . > $4',
9237c478bd9Sstevel@tonic-gate`R$* < @ $=M > $*		$: $1 < @ $2 . > $3')
9247c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_TABLE_', `dnl
9257c478bd9Sstevel@tonic-gatednl virtual hosts are also canonical
9267c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
9277c478bd9Sstevel@tonic-gate`R$* < @ $* $={VirtHost} > $* 	$: $1 < @ $2 $3 . > $4',
9287c478bd9Sstevel@tonic-gate`R$* < @ $={VirtHost} > $* 	$: $1 < @ $2 . > $3')',
9297c478bd9Sstevel@tonic-gate`dnl')
9307c478bd9Sstevel@tonic-gateifdef(`_GENERICS_TABLE_', `dnl
9317c478bd9Sstevel@tonic-gatednl hosts for genericstable are also canonical
9327c478bd9Sstevel@tonic-gateifdef(`_GENERICS_ENTIRE_DOMAIN_',
9337c478bd9Sstevel@tonic-gate`R$* < @ $* $=G > $* 	$: $1 < @ $2 $3 . > $4',
9347c478bd9Sstevel@tonic-gate`R$* < @ $=G > $* 	$: $1 < @ $2 . > $3')',
9357c478bd9Sstevel@tonic-gate`dnl')
9367c478bd9Sstevel@tonic-gatednl remove superfluous dots (maybe repeatedly) which may have been added
9377c478bd9Sstevel@tonic-gatednl by one of the rules before
9387c478bd9Sstevel@tonic-gateR$* < @ $* . . > $*		$1 < @ $2 . > $3
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate
9417c478bd9Sstevel@tonic-gate##################################################
9427c478bd9Sstevel@tonic-gate###  Ruleset 4 -- Final Output Post-rewriting  ###
9437c478bd9Sstevel@tonic-gate##################################################
9447c478bd9Sstevel@tonic-gateSfinal=4
9457c478bd9Sstevel@tonic-gate
9467c478bd9Sstevel@tonic-gateR$+ :; <@>		$@ $1 :				handle <list:;>
9477c478bd9Sstevel@tonic-gateR$* <@>			$@				handle <> and list:;
9487c478bd9Sstevel@tonic-gate
9497c478bd9Sstevel@tonic-gate# strip trailing dot off possibly canonical name
9507c478bd9Sstevel@tonic-gateR$* < @ $+ . > $*	$1 < @ $2 > $3
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate# eliminate internal code
9537c478bd9Sstevel@tonic-gateR$* < @ *LOCAL* > $*	$1 < @ $j > $2
9547c478bd9Sstevel@tonic-gate
9557c478bd9Sstevel@tonic-gate# externalize local domain info
9567c478bd9Sstevel@tonic-gateR$* < $+ > $*		$1 $2 $3			defocus
9577c478bd9Sstevel@tonic-gateR@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
9587c478bd9Sstevel@tonic-gateR@ $*			$@ @ $1				... and exit
9597c478bd9Sstevel@tonic-gate
9607c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
9617c478bd9Sstevel@tonic-gate`# UUCP must always be presented in old form
9627c478bd9Sstevel@tonic-gateR$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u')
9637c478bd9Sstevel@tonic-gate
9647c478bd9Sstevel@tonic-gateifdef(`_USE_DECNET_SYNTAX_',
9657c478bd9Sstevel@tonic-gate`# put DECnet back in :: form
9667c478bd9Sstevel@tonic-gateR$+ @ $+ . DECNET	$2 :: $1			u@h.DECNET => h::u',
9677c478bd9Sstevel@tonic-gate	`dnl')
9687c478bd9Sstevel@tonic-gate# delete duplicate local names
9697c478bd9Sstevel@tonic-gateR$+ % $=w @ $=w		$1 @ $2				u%host@host => u@host
9707c478bd9Sstevel@tonic-gate
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate
9737c478bd9Sstevel@tonic-gate##############################################################
9747c478bd9Sstevel@tonic-gate###   Ruleset 97 -- recanonicalize and call ruleset zero   ###
9757c478bd9Sstevel@tonic-gate###		   (used for recursive calls)		   ###
9767c478bd9Sstevel@tonic-gate##############################################################
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gateSRecurse=97
9797c478bd9Sstevel@tonic-gateR$*			$: $>canonify $1
9807c478bd9Sstevel@tonic-gateR$*			$@ $>parse $1
9817c478bd9Sstevel@tonic-gate
9827c478bd9Sstevel@tonic-gate
9837c478bd9Sstevel@tonic-gate######################################
9847c478bd9Sstevel@tonic-gate###   Ruleset 0 -- Parse Address   ###
9857c478bd9Sstevel@tonic-gate######################################
9867c478bd9Sstevel@tonic-gate
9877c478bd9Sstevel@tonic-gateSparse=0
9887c478bd9Sstevel@tonic-gate
9897c478bd9Sstevel@tonic-gateR$*			$: $>Parse0 $1		initial parsing
9907c478bd9Sstevel@tonic-gateR<@>			$#_LOCAL_ $: <@>		special case error msgs
9917c478bd9Sstevel@tonic-gateR$*			$: $>ParseLocal $1	handle local hacks
9927c478bd9Sstevel@tonic-gateR$*			$: $>Parse1 $1		final parsing
9937c478bd9Sstevel@tonic-gate
9947c478bd9Sstevel@tonic-gate#
9957c478bd9Sstevel@tonic-gate#  Parse0 -- do initial syntax checking and eliminate local addresses.
9967c478bd9Sstevel@tonic-gate#	This should either return with the (possibly modified) input
9977c478bd9Sstevel@tonic-gate#	or return with a #error mailer.  It should not return with a
9987c478bd9Sstevel@tonic-gate#	#mailer other than the #error mailer.
9997c478bd9Sstevel@tonic-gate#
10007c478bd9Sstevel@tonic-gate
10017c478bd9Sstevel@tonic-gateSParse0
10027c478bd9Sstevel@tonic-gateR<@>			$@ <@>			special case error msgs
10037c478bd9Sstevel@tonic-gateR$* : $* ; <@>		$#error $@ 5.1.3 $: "_CODE553 List:; syntax illegal for recipient addresses"
10047c478bd9Sstevel@tonic-gateR@ <@ $* >		< @ $1 >		catch "@@host" bogosity
10057c478bd9Sstevel@tonic-gateR<@ $+>			$#error $@ 5.1.3 $: "_CODE553 User address required"
10067c478bd9Sstevel@tonic-gateR$+ <@>			$#error $@ 5.1.3 $: "_CODE553 Hostname required"
10077c478bd9Sstevel@tonic-gateR$*			$: <> $1
10087c478bd9Sstevel@tonic-gatednl allow tricks like [host1]:[host2]
10097c478bd9Sstevel@tonic-gateR<> $* < @ [ $* ] : $+ > $*	$1 < @ [ $2 ] : $3 > $4
10107c478bd9Sstevel@tonic-gateR<> $* < @ [ $* ] , $+ > $*	$1 < @ [ $2 ] , $3 > $4
10117c478bd9Sstevel@tonic-gatednl but no a@[b]c
10127c478bd9Sstevel@tonic-gateR<> $* < @ [ $* ] $+ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid address"
10137c478bd9Sstevel@tonic-gateR<> $* < @ [ $+ ] > $*		$1 < @ [ $2 ] > $3
10147c478bd9Sstevel@tonic-gateR<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "_CODE553 Colon illegal in host name part"
10157c478bd9Sstevel@tonic-gateR<> $*			$1
10167c478bd9Sstevel@tonic-gateR$* < @ . $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
10177c478bd9Sstevel@tonic-gateR$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid host name"
10187c478bd9Sstevel@tonic-gatednl no a@b@
10197c478bd9Sstevel@tonic-gateR$* < @ $* @ > $*	$#error $@ 5.1.2 $: "_CODE553 Invalid route address"
10207c478bd9Sstevel@tonic-gatednl no a@b@c
10217c478bd9Sstevel@tonic-gateR$* @ $* < @ $* > $*	$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
10227c478bd9Sstevel@tonic-gatednl comma only allowed before @; this check is not complete
10237c478bd9Sstevel@tonic-gateR$* , $~O $*		$#error $@ 5.1.3 $: "_CODE553 Invalid route address"
10247c478bd9Sstevel@tonic-gate
10257c478bd9Sstevel@tonic-gateifdef(`_STRICT_RFC821_', `# more RFC 821 checks
10267c478bd9Sstevel@tonic-gateR$* . < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not end with a dot"
10277c478bd9Sstevel@tonic-gateR. $* < @ $* > $*	$#error $@ 5.1.2 $: "_CODE553 Local part must not begin with a dot"
10287c478bd9Sstevel@tonic-gatednl', `dnl')
10297c478bd9Sstevel@tonic-gate
10307c478bd9Sstevel@tonic-gate# now delete the local info -- note $=O to find characters that cause forwarding
10317c478bd9Sstevel@tonic-gateR$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
10327c478bd9Sstevel@tonic-gateR< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
10337c478bd9Sstevel@tonic-gateR$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
10347c478bd9Sstevel@tonic-gateR< @ $+ >		$#error $@ 5.1.3 $: "_CODE553 User address required"
10357c478bd9Sstevel@tonic-gateR$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
10367c478bd9Sstevel@tonic-gateR$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
10377c478bd9Sstevel@tonic-gateR< @ *LOCAL* >		$#error $@ 5.1.3 $: "_CODE553 User address required"
10387c478bd9Sstevel@tonic-gateR$* $=O $* < @ *LOCAL* >
10397c478bd9Sstevel@tonic-gate			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
10407c478bd9Sstevel@tonic-gateR$* < @ *LOCAL* >	$: $1
10417c478bd9Sstevel@tonic-gate
10427c478bd9Sstevel@tonic-gate#
10437c478bd9Sstevel@tonic-gate#  Parse1 -- the bottom half of ruleset 0.
10447c478bd9Sstevel@tonic-gate#
10457c478bd9Sstevel@tonic-gate
10467c478bd9Sstevel@tonic-gateSParse1
10477c478bd9Sstevel@tonic-gateifdef(`_LDAP_ROUTING_', `dnl
10487c478bd9Sstevel@tonic-gate# handle LDAP routing for hosts in $={LDAPRoute}
10497c478bd9Sstevel@tonic-gateR$+ < @ $={LDAPRoute} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $2> <>
10507c478bd9Sstevel@tonic-gateR$+ < @ $={LDAPRouteEquiv} . >	$: $>LDAPExpand <$1 < @ $2 . >> <$1 @ $M> <>',
10517c478bd9Sstevel@tonic-gate`dnl')
10527c478bd9Sstevel@tonic-gate
10537c478bd9Sstevel@tonic-gateifdef(`_MAILER_smtp_',
10547c478bd9Sstevel@tonic-gate`# handle numeric address spec
10557c478bd9Sstevel@tonic-gatednl there is no check whether this is really an IP number
10567c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] > $*	$: $>ParseLocal $1 < @ [ $2 ] > $3	numeric internet spec
10577c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] > $*	$: $1 < @ [ $2 ] : $S > $3	Add smart host to path
10587c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] : > $*		$#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3	no smarthost: send
10597c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] : $- : $*> $*	$#$3 $@ $4 $: $1 < @ [$2] > $5	smarthost with mailer
10607c478bd9Sstevel@tonic-gateR$* < @ [ $+ ] : $+ > $*	$#_SMTP_ $@ $3 $: $1 < @ [$2] > $4	smarthost without mailer',
10617c478bd9Sstevel@tonic-gate	`dnl')
10627c478bd9Sstevel@tonic-gate
10637c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_TABLE_', `dnl
10647c478bd9Sstevel@tonic-gate# handle virtual users
10657c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
10667c478bd9Sstevel@tonic-gatednl this is not a documented option
10677c478bd9Sstevel@tonic-gatednl it stops looping in virtusertable mapping if input and output
10687c478bd9Sstevel@tonic-gatednl are identical, i.e., if address A is mapped to A.
10697c478bd9Sstevel@tonic-gatednl it does not deal with multi-level recursion
10707c478bd9Sstevel@tonic-gate# handle full domains in RHS of virtusertable
10717c478bd9Sstevel@tonic-gateR$+ < @ $+ >			$: $(macro {RecipientAddress} $) $1 < @ $2 >
10727c478bd9Sstevel@tonic-gateR$+ < @ $+ > 			$: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
10737c478bd9Sstevel@tonic-gateR<?> $+ $| $+			$: $1 $(macro {RecipientAddress} $@ $2 $)
10747c478bd9Sstevel@tonic-gateR<?> $+ $| $*			$: $1',
10757c478bd9Sstevel@tonic-gate`dnl')
10767c478bd9Sstevel@tonic-gateR$+			$: <!> $1		Mark for lookup
10777c478bd9Sstevel@tonic-gatednl input: <!> local<@domain>
10787c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
10797c478bd9Sstevel@tonic-gate`R<!> $+ < @ $* $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
10807c478bd9Sstevel@tonic-gate`R<!> $+ < @ $={VirtHost} . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
10817c478bd9Sstevel@tonic-gatednl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
10827c478bd9Sstevel@tonic-gateR<!> $+ < @ $=w . > 	$: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
10837c478bd9Sstevel@tonic-gatednl if <@> local<@domain>: no match but try lookup
10847c478bd9Sstevel@tonic-gatednl user+detail: try user++@domain if detail not empty
10857c478bd9Sstevel@tonic-gateR<@> $+ + $+ < @ $* . >
10867c478bd9Sstevel@tonic-gate			$: < $(virtuser $1 + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
10877c478bd9Sstevel@tonic-gatednl user+detail: try user+*@domain
10887c478bd9Sstevel@tonic-gateR<@> $+ + $* < @ $* . >
10897c478bd9Sstevel@tonic-gate			$: < $(virtuser $1 + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
10907c478bd9Sstevel@tonic-gatednl user+detail: try user@domain
10917c478bd9Sstevel@tonic-gateR<@> $+ + $* < @ $* . >
10927c478bd9Sstevel@tonic-gate			$: < $(virtuser $1 @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
10937c478bd9Sstevel@tonic-gatednl try default entry: @domain
10947c478bd9Sstevel@tonic-gatednl ++@domain
10957c478bd9Sstevel@tonic-gateR<@> $+ + $+ < @ $+ . >	$: < $(virtuser + + @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
10967c478bd9Sstevel@tonic-gatednl +*@domain
10977c478bd9Sstevel@tonic-gateR<@> $+ + $* < @ $+ . >	$: < $(virtuser + * @ $3 $@ $1 $@ $2 $@ +$2 $: @ $) > $1 + $2 < @ $3 . >
10987c478bd9Sstevel@tonic-gatednl @domain if +detail exists
10997c478bd9Sstevel@tonic-gatednl if no match, change marker to prevent a second @domain lookup
11007c478bd9Sstevel@tonic-gateR<@> $+ + $* < @ $+ . >	$: < $(virtuser @ $3 $@ $1 $@ $2 $@ +$2 $: ! $) > $1 + $2 < @ $3 . >
11017c478bd9Sstevel@tonic-gatednl without +detail
11027c478bd9Sstevel@tonic-gateR<@> $+ < @ $+ . >	$: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
11037c478bd9Sstevel@tonic-gatednl no match
11047c478bd9Sstevel@tonic-gateR<@> $+			$: $1
11057c478bd9Sstevel@tonic-gatednl remove mark
11067c478bd9Sstevel@tonic-gateR<!> $+			$: $1
11077c478bd9Sstevel@tonic-gateR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
11087c478bd9Sstevel@tonic-gateR< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
11097c478bd9Sstevel@tonic-gateifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
11107c478bd9Sstevel@tonic-gate# check virtuser input address against output address, if same, skip recursion
11117c478bd9Sstevel@tonic-gateR< $+ > $+ < @ $+ >				$: < $1 > $2 < @ $3 > $| $1
11127c478bd9Sstevel@tonic-gate# it is the same: stop now
11137c478bd9Sstevel@tonic-gateR< $+ > $+ < @ $+ > $| $&{RecipientAddress}	$: $>ParseLocal $>Parse0 $>canonify $1
11147c478bd9Sstevel@tonic-gateR< $+ > $+ < @ $+ > $| $* 			$: < $1 > $2 < @ $3 >
11157c478bd9Sstevel@tonic-gatednl', `dnl')
11167c478bd9Sstevel@tonic-gatednl this is not a documented option
11177c478bd9Sstevel@tonic-gatednl it performs no looping at all for virtusertable
11187c478bd9Sstevel@tonic-gateifdef(`_NO_VIRTUSER_RECURSION_',
11197c478bd9Sstevel@tonic-gate`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
11207c478bd9Sstevel@tonic-gate`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
11217c478bd9Sstevel@tonic-gatednl', `dnl')
11227c478bd9Sstevel@tonic-gate
11237c478bd9Sstevel@tonic-gate# short circuit local delivery so forwarded email works
11247c478bd9Sstevel@tonic-gateifdef(`_MAILER_usenet_', `dnl
11257c478bd9Sstevel@tonic-gateR$+ . USENET < @ $=w . >	$#usenet $@ usenet $: $1	handle usenet specially', `dnl')
11267c478bd9Sstevel@tonic-gate
11277c478bd9Sstevel@tonic-gate
11287c478bd9Sstevel@tonic-gateifdef(`_STICKY_LOCAL_DOMAIN_',
11297c478bd9Sstevel@tonic-gate`R$+ < @ $=w . >		$: < $H > $1 < @ $2 . >		first try hub
11307c478bd9Sstevel@tonic-gateR< $+ > $+ < $+ >	$>MailerToTriple < $1 > $2 < $3 >	yep ....
11317c478bd9Sstevel@tonic-gatednl $H empty (but @$=w.)
11327c478bd9Sstevel@tonic-gateR< > $+ + $* < $+ >	$#_LOCAL_ $: $1 + $2		plussed name?
11337c478bd9Sstevel@tonic-gateR< > $+ < $+ >		$#_LOCAL_ $: @ $1			nope, local address',
11347c478bd9Sstevel@tonic-gate`R$=L < @ $=w . >	$#_LOCAL_ $: @ $1			special local names
11357c478bd9Sstevel@tonic-gateR$+ < @ $=w . >		$#_LOCAL_ $: $1			regular local name')
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gateifdef(`_MAILER_TABLE_', `dnl
11387c478bd9Sstevel@tonic-gate# not local -- try mailer table lookup
11397c478bd9Sstevel@tonic-gateR$* <@ $+ > $*		$: < $2 > $1 < @ $2 > $3	extract host name
11407c478bd9Sstevel@tonic-gateR< $+ . > $*		$: < $1 > $2			strip trailing dot
11417c478bd9Sstevel@tonic-gateR< $+ > $*		$: < $(mailertable $1 $) > $2	lookup
11427c478bd9Sstevel@tonic-gatednl it is $~[ instead of $- to avoid matches on IPv6 addresses
11437c478bd9Sstevel@tonic-gateR< $~[ : $* > $* 	$>MailerToTriple < $1 : $2 > $3		check -- resolved?
11447c478bd9Sstevel@tonic-gateR< $+ > $*		$: $>Mailertable <$1> $2		try domain',
11457c478bd9Sstevel@tonic-gate`dnl')
11467c478bd9Sstevel@tonic-gateundivert(4)dnl UUCP rules from `MAILER(uucp)'
11477c478bd9Sstevel@tonic-gate
11487c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
11497c478bd9Sstevel@tonic-gate`# resolve remotely connected UUCP links (if any)
11507c478bd9Sstevel@tonic-gateifdef(`_CLASS_V_',
11517c478bd9Sstevel@tonic-gate`R$* < @ $=V . UUCP . > $*		$: $>MailerToTriple < $V > $1 <@$2.UUCP.> $3',
11527c478bd9Sstevel@tonic-gate	`dnl')
11537c478bd9Sstevel@tonic-gateifdef(`_CLASS_W_',
11547c478bd9Sstevel@tonic-gate`R$* < @ $=W . UUCP . > $*		$: $>MailerToTriple < $W > $1 <@$2.UUCP.> $3',
11557c478bd9Sstevel@tonic-gate	`dnl')
11567c478bd9Sstevel@tonic-gateifdef(`_CLASS_X_',
11577c478bd9Sstevel@tonic-gate`R$* < @ $=X . UUCP . > $*		$: $>MailerToTriple < $X > $1 <@$2.UUCP.> $3',
11587c478bd9Sstevel@tonic-gate	`dnl')')
11597c478bd9Sstevel@tonic-gate
11607c478bd9Sstevel@tonic-gate# resolve fake top level domains by forwarding to other hosts
11617c478bd9Sstevel@tonic-gateifdef(`BITNET_RELAY',
11627c478bd9Sstevel@tonic-gate`R$*<@$+.BITNET.>$*	$: $>MailerToTriple < $B > $1 <@$2.BITNET.> $3	user@host.BITNET',
11637c478bd9Sstevel@tonic-gate	`dnl')
11647c478bd9Sstevel@tonic-gateifdef(`DECNET_RELAY',
11657c478bd9Sstevel@tonic-gate`R$*<@$+.DECNET.>$*	$: $>MailerToTriple < $C > $1 <@$2.DECNET.> $3	user@host.DECNET',
11667c478bd9Sstevel@tonic-gate	`dnl')
11677c478bd9Sstevel@tonic-gateifdef(`_MAILER_pop_',
11687c478bd9Sstevel@tonic-gate`R$+ < @ POP. >		$#pop $: $1			user@POP',
11697c478bd9Sstevel@tonic-gate	`dnl')
11707c478bd9Sstevel@tonic-gateifdef(`_MAILER_fax_',
11717c478bd9Sstevel@tonic-gate`R$+ < @ $+ .FAX. >	$#fax $@ $2 $: $1		user@host.FAX',
11727c478bd9Sstevel@tonic-gate`ifdef(`FAX_RELAY',
11737c478bd9Sstevel@tonic-gate`R$*<@$+.FAX.>$*		$: $>MailerToTriple < $F > $1 <@$2.FAX.> $3	user@host.FAX',
11747c478bd9Sstevel@tonic-gate	`dnl')')
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gateifdef(`UUCP_RELAY',
11777c478bd9Sstevel@tonic-gate`# forward non-local UUCP traffic to our UUCP relay
11787c478bd9Sstevel@tonic-gateR$*<@$*.UUCP.>$*		$: $>MailerToTriple < $Y > $1 <@$2.UUCP.> $3	uucp mail',
11797c478bd9Sstevel@tonic-gate`ifdef(`_MAILER_uucp_',
11807c478bd9Sstevel@tonic-gate`# forward other UUCP traffic straight to UUCP
11817c478bd9Sstevel@tonic-gateR$* < @ $+ .UUCP. > $*		$#_UUCP_ $@ $2 $: $1 < @ $2 .UUCP. > $3	user@host.UUCP',
11827c478bd9Sstevel@tonic-gate	`dnl')')
11837c478bd9Sstevel@tonic-gateifdef(`_MAILER_usenet_', `
11847c478bd9Sstevel@tonic-gate# addresses sent to net.group.USENET will get forwarded to a newsgroup
11857c478bd9Sstevel@tonic-gateR$+ . USENET		$#usenet $@ usenet $: $1',
11867c478bd9Sstevel@tonic-gate	`dnl')
11877c478bd9Sstevel@tonic-gate
11887c478bd9Sstevel@tonic-gateifdef(`_LOCAL_RULES_',
11897c478bd9Sstevel@tonic-gate`# figure out what should stay in our local mail system
11907c478bd9Sstevel@tonic-gateundivert(1)', `dnl')
11917c478bd9Sstevel@tonic-gate
11927c478bd9Sstevel@tonic-gate# pass names that still have a host to a smarthost (if defined)
11937c478bd9Sstevel@tonic-gateR$* < @ $* > $*		$: $>MailerToTriple < $S > $1 < @ $2 > $3	glue on smarthost name
11947c478bd9Sstevel@tonic-gate
11957c478bd9Sstevel@tonic-gate# deal with other remote names
11967c478bd9Sstevel@tonic-gateifdef(`_MAILER_smtp_',
11977c478bd9Sstevel@tonic-gate`R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
11987c478bd9Sstevel@tonic-gate`R$* < @$* > $*		$#error $@ 5.1.2 $: "_CODE553 Unrecognized host name " $2')
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate# handle locally delivered names
12017c478bd9Sstevel@tonic-gateR$=L			$#_LOCAL_ $: @ $1		special local names
12027c478bd9Sstevel@tonic-gateR$+			$#_LOCAL_ $: $1			regular local names
12037c478bd9Sstevel@tonic-gate
12047c478bd9Sstevel@tonic-gate###########################################################################
12057c478bd9Sstevel@tonic-gate###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
12067c478bd9Sstevel@tonic-gate###########################################################################
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gateSLocal_localaddr
12097c478bd9Sstevel@tonic-gateSlocaladdr=5
12107c478bd9Sstevel@tonic-gateR$+			$: $1 $| $>"Local_localaddr" $1
12117c478bd9Sstevel@tonic-gateR$+ $| $#ok		$@ $1			no change
12127c478bd9Sstevel@tonic-gateR$+ $| $#$*		$#$2
12137c478bd9Sstevel@tonic-gateR$+ $| $*		$: $1
12147c478bd9Sstevel@tonic-gate
12157c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12167c478bd9Sstevel@tonic-gate# Preserve rcpt_host in {Host}
12177c478bd9Sstevel@tonic-gateR$+			$: $1 $| $&h $| $&{Host}	check h and {Host}
12187c478bd9Sstevel@tonic-gateR$+ $| $|		$: $(macro {Host} $@ $) $1	no h or {Host}
12197c478bd9Sstevel@tonic-gateR$+ $| $| $+		$: $1			h not set, {Host} set
12207c478bd9Sstevel@tonic-gateR$+ $| +$* $| $*	$: $1			h is +detail, {Host} set
12217c478bd9Sstevel@tonic-gateR$+ $| $* @ $+ $| $*	$: $(macro {Host} $@ @$3 $) $1	set {Host} to host in h
12227c478bd9Sstevel@tonic-gateR$+ $| $+ $| $*		$: $(macro {Host} $@ @$2 $) $1	set {Host} to h
12237c478bd9Sstevel@tonic-gate')dnl
12247c478bd9Sstevel@tonic-gate
12257c478bd9Sstevel@tonic-gateifdef(`_FFR_5_', `dnl
12267c478bd9Sstevel@tonic-gate# Preserve host in a macro
12277c478bd9Sstevel@tonic-gateR$+			$: $(macro {LocalAddrHost} $) $1
12287c478bd9Sstevel@tonic-gateR$+ @ $+		$: $(macro {LocalAddrHost} $@ @ $2 $) $1')
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `', `dnl
12317c478bd9Sstevel@tonic-gate# deal with plussed users so aliases work nicely
12327c478bd9Sstevel@tonic-gateR$+ + *			$#_LOCAL_ $@ $&h $: $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
12337c478bd9Sstevel@tonic-gateR$+ + $*		$#_LOCAL_ $@ + $2 $: $1 + *`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')
12347c478bd9Sstevel@tonic-gate')
12357c478bd9Sstevel@tonic-gate# prepend an empty "forward host" on the front
12367c478bd9Sstevel@tonic-gateR$+			$: <> $1
12377c478bd9Sstevel@tonic-gate
12387c478bd9Sstevel@tonic-gateifdef(`LUSER_RELAY', `dnl
12397c478bd9Sstevel@tonic-gate# send unrecognized local users to a relay host
12407c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
12417c478bd9Sstevel@tonic-gateR< > $+ + $*		$: < ? $L > <+ $2> $(user $1 $)	look up user+
12427c478bd9Sstevel@tonic-gateR< > $+			$: < ? $L > < > $(user $1 $)	look up user
12437c478bd9Sstevel@tonic-gateR< ? $* > < $* > $+ <>	$: < > $3 $2			found; strip $L
12447c478bd9Sstevel@tonic-gateR< ? $* > < $* > $+	$: < $1 > $3 $2			not found', `
12457c478bd9Sstevel@tonic-gateR< > $+ 		$: < $L > $(user $1 $)		look up user
12467c478bd9Sstevel@tonic-gateR< $* > $+ <>		$: < > $2			found; strip $L')
12477c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12487c478bd9Sstevel@tonic-gateR< $+ > $+		$: < $1 > $2 $&{Host}')
12497c478bd9Sstevel@tonic-gatednl')
12507c478bd9Sstevel@tonic-gate
12517c478bd9Sstevel@tonic-gateifdef(`MAIL_HUB', `dnl
12527c478bd9Sstevel@tonic-gateR< > $+			$: < $H > $1			try hub', `dnl')
12537c478bd9Sstevel@tonic-gateifdef(`LOCAL_RELAY', `dnl
12547c478bd9Sstevel@tonic-gateR< > $+			$: < $R > $1			try relay', `dnl')
12557c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LOCAL_PLUS_DETAIL_', `dnl
12567c478bd9Sstevel@tonic-gateR< > $+			$@ $1', `dnl
12577c478bd9Sstevel@tonic-gateR< > $+			$: < > < $1 <> $&h >		nope, restore +detail
12587c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12597c478bd9Sstevel@tonic-gateR< > < $+ @ $+ <> + $* >	$: < > < $1 + $3 @ $2 >	check whether +detail')
12607c478bd9Sstevel@tonic-gateR< > < $+ <> + $* >	$: < > < $1 + $2 >		check whether +detail
12617c478bd9Sstevel@tonic-gateR< > < $+ <> $* >	$: < > < $1 >			else discard
12627c478bd9Sstevel@tonic-gateR< > < $+ + $* > $*	   < > < $1 > + $2 $3		find the user part
12637c478bd9Sstevel@tonic-gateR< > < $+ > + $*	$#_LOCAL_ $@ $2 $: @ $1`'ifdef(`_FFR_5_', ` $&{LocalAddrHost}')		strip the extra +
12647c478bd9Sstevel@tonic-gateR< > < $+ >		$@ $1				no +detail
12657c478bd9Sstevel@tonic-gateR$+			$: $1 <> $&h			add +detail back in
12667c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12677c478bd9Sstevel@tonic-gateR$+ @ $+ <> + $*	$: $1 + $3 @ $2			check whether +detail')
12687c478bd9Sstevel@tonic-gateR$+ <> + $*		$: $1 + $2			check whether +detail
12697c478bd9Sstevel@tonic-gateR$+ <> $*		$: $1				else discard')
12707c478bd9Sstevel@tonic-gateR< local : $* > $*	$: $>MailerToTriple < local : $1 > $2	no host extension
12717c478bd9Sstevel@tonic-gateR< error : $* > $*	$: $>MailerToTriple < error : $1 > $2	no host extension
12727c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12737c478bd9Sstevel@tonic-gatednl it is $~[ instead of $- to avoid matches on IPv6 addresses
12747c478bd9Sstevel@tonic-gateR< $~[ : $+ > $+ @ $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $4 >')
12757c478bd9Sstevel@tonic-gateR< $~[ : $+ > $+	$: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
12767c478bd9Sstevel@tonic-gateifdef(`_PRESERVE_LUSER_HOST_', `dnl
12777c478bd9Sstevel@tonic-gateR< $+ > $+ @ $+		$@ $>MailerToTriple < $1 > $2 < @ $3 >')
12787c478bd9Sstevel@tonic-gateR< $+ > $+		$@ $>MailerToTriple < $1 > $2 < @ $1 >
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gateifdef(`_MAILER_TABLE_', `dnl
12817c478bd9Sstevel@tonic-gateifdef(`_LDAP_ROUTING_', `dnl
12827c478bd9Sstevel@tonic-gate###################################################################
12837c478bd9Sstevel@tonic-gate###  Ruleset LDAPMailertable -- mailertable lookup for LDAP     ###
12847c478bd9Sstevel@tonic-gatednl input: <Domain> FullAddress
12857c478bd9Sstevel@tonic-gate###################################################################
12867c478bd9Sstevel@tonic-gate
12877c478bd9Sstevel@tonic-gateSLDAPMailertable
12887c478bd9Sstevel@tonic-gateR< $+ > $*		$: < $(mailertable $1 $) > $2		lookup
12897c478bd9Sstevel@tonic-gateR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		check resolved?
12907c478bd9Sstevel@tonic-gateR< $+ > $*		$: < $1 > $>Mailertable <$1> $2		try domain
12917c478bd9Sstevel@tonic-gateR< $+ > $#$*		$#$2					found
12927c478bd9Sstevel@tonic-gateR< $+ > $*		$#_RELAY_ $@ $1 $: $2			not found, direct relay',
12937c478bd9Sstevel@tonic-gate`dnl')
12947c478bd9Sstevel@tonic-gate
12957c478bd9Sstevel@tonic-gate###################################################################
12967c478bd9Sstevel@tonic-gate###  Ruleset 90 -- try domain part of mailertable entry 	###
12977c478bd9Sstevel@tonic-gatednl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
12987c478bd9Sstevel@tonic-gate###################################################################
12997c478bd9Sstevel@tonic-gate
13007c478bd9Sstevel@tonic-gateSMailertable=90
13017c478bd9Sstevel@tonic-gatednl shift and check
13027c478bd9Sstevel@tonic-gatednl %2 is not documented in cf/README
13037c478bd9Sstevel@tonic-gateR$* <$- . $+ > $*	$: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
13047c478bd9Sstevel@tonic-gatednl it is $~[ instead of $- to avoid matches on IPv6 addresses
13057c478bd9Sstevel@tonic-gateR$* <$~[ : $* > $*	$>MailerToTriple < $2 : $3 > $4		check -- resolved?
13067c478bd9Sstevel@tonic-gateR$* < . $+ > $* 	$@ $>Mailertable $1 . <$2> $3		no -- strip & try again
13077c478bd9Sstevel@tonic-gatednl is $2 always empty?
13087c478bd9Sstevel@tonic-gateR$* < $* > $*		$: < $(mailertable . $@ $1$2 $) > $3	try "."
13097c478bd9Sstevel@tonic-gateR< $~[ : $* > $*	$>MailerToTriple < $1 : $2 > $3		"." found?
13107c478bd9Sstevel@tonic-gatednl return full address
13117c478bd9Sstevel@tonic-gateR< $* > $*		$@ $2				no mailertable match',
13127c478bd9Sstevel@tonic-gate`dnl')
13137c478bd9Sstevel@tonic-gate
13147c478bd9Sstevel@tonic-gate###################################################################
13157c478bd9Sstevel@tonic-gate###  Ruleset 95 -- canonify mailer:[user@]host syntax to triple	###
13167c478bd9Sstevel@tonic-gatednl input: in general: <[mailer:]host> lp<@domain>rest
13177c478bd9Sstevel@tonic-gatednl	<> address				-> address
13187c478bd9Sstevel@tonic-gatednl	<error:d.s.n:text>			-> error
13197c478bd9Sstevel@tonic-gatednl	<error:keyword:text>			-> error
13207c478bd9Sstevel@tonic-gatednl	<error:text>				-> error
13217c478bd9Sstevel@tonic-gatednl	<mailer:user@host> lp<@domain>rest	-> mailer host user
13227c478bd9Sstevel@tonic-gatednl	<mailer:host> address			-> mailer host address
13237c478bd9Sstevel@tonic-gatednl	<localdomain> address			-> address
13247c478bd9Sstevel@tonic-gatednl	<host> address				-> relay host address
13257c478bd9Sstevel@tonic-gate###################################################################
13267c478bd9Sstevel@tonic-gate
13277c478bd9Sstevel@tonic-gateSMailerToTriple=95
13287c478bd9Sstevel@tonic-gateR< > $*				$@ $1			strip off null relay
13297c478bd9Sstevel@tonic-gateR< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
13307c478bd9Sstevel@tonic-gateR< error : $- : $+ > $*		$#error $@ $(dequote $1 $) $: $2
13317c478bd9Sstevel@tonic-gateR< error : $+ > $*		$#error $: $1
13327c478bd9Sstevel@tonic-gateR< local : $* > $*		$>CanonLocal < $1 > $2
13337c478bd9Sstevel@tonic-gatednl it is $~[ instead of $- to avoid matches on IPv6 addresses
13347c478bd9Sstevel@tonic-gateR< $~[ : $+ @ $+ > $*<$*>$*	$# $1 $@ $3 $: $2<@$3>	use literal user
13357c478bd9Sstevel@tonic-gateR< $~[ : $+ > $*		$# $1 $@ $2 $: $3	try qualified mailer
13367c478bd9Sstevel@tonic-gateR< $=w > $*			$@ $2			delete local host
13377c478bd9Sstevel@tonic-gateR< $+ > $*			$#_RELAY_ $@ $1 $: $2	use unqualified mailer
13387c478bd9Sstevel@tonic-gate
13397c478bd9Sstevel@tonic-gate###################################################################
13407c478bd9Sstevel@tonic-gate###  Ruleset CanonLocal -- canonify local: syntax		###
13417c478bd9Sstevel@tonic-gatednl input: <user> address
13427c478bd9Sstevel@tonic-gatednl <x> <@host> : rest			-> Recurse rest
13437c478bd9Sstevel@tonic-gatednl <x> p1 $=O p2 <@host>		-> Recurse p1 $=O p2
13447c478bd9Sstevel@tonic-gatednl <> user <@host> rest		-> local user@host user
13457c478bd9Sstevel@tonic-gatednl <> user				-> local user user
13467c478bd9Sstevel@tonic-gatednl <user@host> lp <@domain> rest	-> <user> lp <@host> [cont]
13477c478bd9Sstevel@tonic-gatednl <user> lp <@host> rest		-> local lp@host user
13487c478bd9Sstevel@tonic-gatednl <user> lp				-> local lp user
13497c478bd9Sstevel@tonic-gate###################################################################
13507c478bd9Sstevel@tonic-gate
13517c478bd9Sstevel@tonic-gateSCanonLocal
13527c478bd9Sstevel@tonic-gate# strip local host from routed addresses
13537c478bd9Sstevel@tonic-gateR< $* > < @ $+ > : $+		$@ $>Recurse $3
13547c478bd9Sstevel@tonic-gateR< $* > $+ $=O $+ < @ $+ >	$@ $>Recurse $2 $3 $4
13557c478bd9Sstevel@tonic-gate
13567c478bd9Sstevel@tonic-gate# strip trailing dot from any host name that may appear
13577c478bd9Sstevel@tonic-gateR< $* > $* < @ $* . >		$: < $1 > $2 < @ $3 >
13587c478bd9Sstevel@tonic-gate
13597c478bd9Sstevel@tonic-gate# handle local: syntax -- use old user, either with or without host
13607c478bd9Sstevel@tonic-gateR< > $* < @ $* > $*		$#_LOCAL_ $@ $1@$2 $: $1
13617c478bd9Sstevel@tonic-gateR< > $+				$#_LOCAL_ $@ $1    $: $1
13627c478bd9Sstevel@tonic-gate
13637c478bd9Sstevel@tonic-gate# handle local:user@host syntax -- ignore host part
13647c478bd9Sstevel@tonic-gateR< $+ @ $+ > $* < @ $* >	$: < $1 > $3 < @ $4 >
13657c478bd9Sstevel@tonic-gate
13667c478bd9Sstevel@tonic-gate# handle local:user syntax
13677c478bd9Sstevel@tonic-gateR< $+ > $* <@ $* > $*		$#_LOCAL_ $@ $2@$3 $: $1
13687c478bd9Sstevel@tonic-gateR< $+ > $* 			$#_LOCAL_ $@ $2    $: $1
13697c478bd9Sstevel@tonic-gate
13707c478bd9Sstevel@tonic-gate###################################################################
13717c478bd9Sstevel@tonic-gate###  Ruleset 93 -- convert header names to masqueraded form	###
13727c478bd9Sstevel@tonic-gate###################################################################
13737c478bd9Sstevel@tonic-gate
13747c478bd9Sstevel@tonic-gateSMasqHdr=93
13757c478bd9Sstevel@tonic-gate
13767c478bd9Sstevel@tonic-gateifdef(`_GENERICS_TABLE_', `dnl
13777c478bd9Sstevel@tonic-gate# handle generics database
13787c478bd9Sstevel@tonic-gateifdef(`_GENERICS_ENTIRE_DOMAIN_',
13797c478bd9Sstevel@tonic-gatednl if generics should be applied add a @ as mark
13807c478bd9Sstevel@tonic-gate`R$+ < @ $* $=G . >	$: < $1@$2$3 > $1 < @ $2$3 . > @	mark',
13817c478bd9Sstevel@tonic-gate`R$+ < @ $=G . >	$: < $1@$2 > $1 < @ $2 . > @	mark')
13827c478bd9Sstevel@tonic-gateR$+ < @ *LOCAL* >	$: < $1@$j > $1 < @ *LOCAL* > @	mark
13837c478bd9Sstevel@tonic-gatednl workspace: either user<@domain> or <user@domain> user <@domain> @
13847c478bd9Sstevel@tonic-gatednl ignore the first case for now
13857c478bd9Sstevel@tonic-gatednl if it has the mark lookup full address
13867c478bd9Sstevel@tonic-gatednl broken: %1 is full address not just detail
13877c478bd9Sstevel@tonic-gateR< $+ > $+ < $* > @	$: < $(generics $1 $: @ $1 $) > $2 < $3 >
13887c478bd9Sstevel@tonic-gatednl workspace: ... or <match|@user@domain> user <@domain>
13897c478bd9Sstevel@tonic-gatednl no match, try user+detail@domain
13907c478bd9Sstevel@tonic-gateR<@$+ + $* @ $+> $+ < @ $+ >
13917c478bd9Sstevel@tonic-gate		$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) >  $4 < @ $5 >
13927c478bd9Sstevel@tonic-gateR<@$+ + $* @ $+> $+ < @ $+ >
13937c478bd9Sstevel@tonic-gate		$: < $(generics $1@$3 $: $) > $4 < @ $5 >
13947c478bd9Sstevel@tonic-gatednl no match, remove mark
13957c478bd9Sstevel@tonic-gateR<@$+ > $+ < @ $+ >	$: < > $2 < @ $3 >
13967c478bd9Sstevel@tonic-gatednl no match, try @domain for exceptions
13977c478bd9Sstevel@tonic-gateR< > $+ < @ $+ . >	$: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
13987c478bd9Sstevel@tonic-gatednl workspace: ... or <match> user <@domain>
13997c478bd9Sstevel@tonic-gatednl no match, try local part
14007c478bd9Sstevel@tonic-gateR< > $+ < @ $+ > 	$: < $(generics $1 $: $) > $1 < @ $2 >
14017c478bd9Sstevel@tonic-gateR< > $+ + $* < @ $+ > 	$: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
14027c478bd9Sstevel@tonic-gateR< > $+ + $* < @ $+ > 	$: < $(generics $1 $: $) > $1 + $2 < @ $3 >
14037c478bd9Sstevel@tonic-gateR< $* @ $* > $* < $* >	$@ $>canonify $1 @ $2		found qualified
14047c478bd9Sstevel@tonic-gateR< $+ > $* < $* >	$: $>canonify $1 @ *LOCAL*	found unqualified
14057c478bd9Sstevel@tonic-gateR< > $*			$: $1				not found',
14067c478bd9Sstevel@tonic-gate`dnl')
14077c478bd9Sstevel@tonic-gate
14087c478bd9Sstevel@tonic-gate# do not masquerade anything in class N
14097c478bd9Sstevel@tonic-gateR$* < @ $* $=N . >	$@ $1 < @ $2 $3 . >
14107c478bd9Sstevel@tonic-gate
14117c478bd9Sstevel@tonic-gateifdef(`MASQUERADE_NAME', `dnl
14127c478bd9Sstevel@tonic-gate# special case the users that should be exposed
14137c478bd9Sstevel@tonic-gateR$=E < @ *LOCAL* >	$@ $1 < @ $j . >		leave exposed
14147c478bd9Sstevel@tonic-gateifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
14157c478bd9Sstevel@tonic-gate`R$=E < @ $* $=M . >	$@ $1 < @ $2 $3 . >',
14167c478bd9Sstevel@tonic-gate`R$=E < @ $=M . >	$@ $1 < @ $2 . >')
14177c478bd9Sstevel@tonic-gateifdef(`_LIMITED_MASQUERADE_', `dnl',
14187c478bd9Sstevel@tonic-gate`R$=E < @ $=w . >	$@ $1 < @ $2 . >')
14197c478bd9Sstevel@tonic-gate
14207c478bd9Sstevel@tonic-gate# handle domain-specific masquerading
14217c478bd9Sstevel@tonic-gateifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
14227c478bd9Sstevel@tonic-gate`R$* < @ $* $=M . > $*	$: $1 < @ $2 $3 . @ $M > $4	convert masqueraded doms',
14237c478bd9Sstevel@tonic-gate`R$* < @ $=M . > $*	$: $1 < @ $2 . @ $M > $3	convert masqueraded doms')
14247c478bd9Sstevel@tonic-gateifdef(`_LIMITED_MASQUERADE_', `dnl',
14257c478bd9Sstevel@tonic-gate`R$* < @ $=w . > $*	$: $1 < @ $2 . @ $M > $3')
14267c478bd9Sstevel@tonic-gateR$* < @ *LOCAL* > $*	$: $1 < @ $j . @ $M > $2
14277c478bd9Sstevel@tonic-gateR$* < @ $+ @ > $*	$: $1 < @ $2 > $3		$M is null
14287c478bd9Sstevel@tonic-gateR$* < @ $+ @ $+ > $*	$: $1 < @ $3 . > $4		$M is not null
14297c478bd9Sstevel@tonic-gatednl', `dnl no masquerading
14307c478bd9Sstevel@tonic-gatednl just fix *LOCAL* leftovers
14317c478bd9Sstevel@tonic-gateR$* < @ *LOCAL* >	$@ $1 < @ $j . >')
14327c478bd9Sstevel@tonic-gate
14337c478bd9Sstevel@tonic-gate###################################################################
14347c478bd9Sstevel@tonic-gate###  Ruleset 94 -- convert envelope names to masqueraded form	###
14357c478bd9Sstevel@tonic-gate###################################################################
14367c478bd9Sstevel@tonic-gate
14377c478bd9Sstevel@tonic-gateSMasqEnv=94
14387c478bd9Sstevel@tonic-gateifdef(`_MASQUERADE_ENVELOPE_',
14397c478bd9Sstevel@tonic-gate`R$+			$@ $>MasqHdr $1',
14407c478bd9Sstevel@tonic-gate`R$* < @ *LOCAL* > $*	$: $1 < @ $j . > $2')
14417c478bd9Sstevel@tonic-gate
14427c478bd9Sstevel@tonic-gate###################################################################
14437c478bd9Sstevel@tonic-gate###  Ruleset 98 -- local part of ruleset zero (can be null)	###
14447c478bd9Sstevel@tonic-gate###################################################################
14457c478bd9Sstevel@tonic-gate
14467c478bd9Sstevel@tonic-gateSParseLocal=98
14477c478bd9Sstevel@tonic-gateundivert(3)dnl LOCAL_RULE_0
14487c478bd9Sstevel@tonic-gate
14497c478bd9Sstevel@tonic-gateifdef(`_LDAP_ROUTING_', `dnl
14507c478bd9Sstevel@tonic-gate######################################################################
14517c478bd9Sstevel@tonic-gate###  LDAPExpand: Expand address using LDAP routing
14527c478bd9Sstevel@tonic-gate###
14537c478bd9Sstevel@tonic-gate###	Parameters:
14547c478bd9Sstevel@tonic-gate###		<$1> -- parsed address (user < @ domain . >) (pass through)
14557c478bd9Sstevel@tonic-gate###		<$2> -- RFC822 address (user @ domain) (used for lookup)
14567c478bd9Sstevel@tonic-gate###		<$3> -- +detail information
14577c478bd9Sstevel@tonic-gate###
14587c478bd9Sstevel@tonic-gate###	Returns:
14597c478bd9Sstevel@tonic-gate###		Mailer triplet ($#mailer $@ host $: address)
14607c478bd9Sstevel@tonic-gate###		Parsed address (user < @ domain . >)
14617c478bd9Sstevel@tonic-gate######################################################################
14627c478bd9Sstevel@tonic-gate
14637c478bd9Sstevel@tonic-gate# SMTP operation modes
14647c478bd9Sstevel@tonic-gateC{SMTPOpModes} s d D
14657c478bd9Sstevel@tonic-gate
14667c478bd9Sstevel@tonic-gateSLDAPExpand
14677c478bd9Sstevel@tonic-gate# do the LDAP lookups
14687c478bd9Sstevel@tonic-gateR<$+><$+><$*>	$: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3>
14697c478bd9Sstevel@tonic-gate
14707c478bd9Sstevel@tonic-gate# look for temporary failures and...
14717c478bd9Sstevel@tonic-gateR<$* <TMPF>> <$*> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
14727c478bd9Sstevel@tonic-gateR<$*> <$* <TMPF>> <$+> <$+> <$*>	$: $&{opMode} $| TMPF <$&{addr_type}> $| $3
14737c478bd9Sstevel@tonic-gateifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
14747c478bd9Sstevel@tonic-gate# ... temp fail RCPT SMTP commands
14757c478bd9Sstevel@tonic-gateR$={SMTPOpModes} $| TMPF <e r> $| $+	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."')
14767c478bd9Sstevel@tonic-gate# ... return original address for MTA to queue up
14777c478bd9Sstevel@tonic-gateR$* $| TMPF <$*> $| $+			$@ $3
14787c478bd9Sstevel@tonic-gate
14797c478bd9Sstevel@tonic-gate# if mailRoutingAddress and local or non-existant mailHost,
14807c478bd9Sstevel@tonic-gate# return the new mailRoutingAddress
14817c478bd9Sstevel@tonic-gateifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
14827c478bd9Sstevel@tonic-gateR<$+@$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $6 @ $2
14837c478bd9Sstevel@tonic-gateR<$+@$+> <> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1 $5 @ $2')
14847c478bd9Sstevel@tonic-gateR<$+> <$=w> <$+> <$+> <$*>	$@ $>Parse0 $>canonify $1
14857c478bd9Sstevel@tonic-gateR<$+> <> <$+> <$+> <$*>		$@ $>Parse0 $>canonify $1
14867c478bd9Sstevel@tonic-gate
14877c478bd9Sstevel@tonic-gate
14887c478bd9Sstevel@tonic-gate# if mailRoutingAddress and non-local mailHost,
14897c478bd9Sstevel@tonic-gate# relay to mailHost with new mailRoutingAddress
14907c478bd9Sstevel@tonic-gateifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
14917c478bd9Sstevel@tonic-gateifdef(`_MAILER_TABLE_', `dnl
14927c478bd9Sstevel@tonic-gate# check mailertable for host, relay from there
14937c478bd9Sstevel@tonic-gateR<$+@$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$3> $>canonify $1 $6 @ $2',
14947c478bd9Sstevel@tonic-gate`R<$+@$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $3 $: $>canonify $1 $6 @ $2')')
14957c478bd9Sstevel@tonic-gateifdef(`_MAILER_TABLE_', `dnl
14967c478bd9Sstevel@tonic-gate# check mailertable for host, relay from there
14977c478bd9Sstevel@tonic-gateR<$+> <$+> <$+> <$+> <$*>	$>LDAPMailertable <$2> $>canonify $1',
14987c478bd9Sstevel@tonic-gate`R<$+> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $2 $: $>canonify $1')
14997c478bd9Sstevel@tonic-gate
15007c478bd9Sstevel@tonic-gate# if no mailRoutingAddress and local mailHost,
15017c478bd9Sstevel@tonic-gate# return original address
15027c478bd9Sstevel@tonic-gateR<> <$=w> <$+> <$+> <$*>	$@ $2
15037c478bd9Sstevel@tonic-gate
15047c478bd9Sstevel@tonic-gate
15057c478bd9Sstevel@tonic-gate# if no mailRoutingAddress and non-local mailHost,
15067c478bd9Sstevel@tonic-gate# relay to mailHost with original address
15077c478bd9Sstevel@tonic-gateifdef(`_MAILER_TABLE_', `dnl
15087c478bd9Sstevel@tonic-gate# check mailertable for host, relay from there
15097c478bd9Sstevel@tonic-gateR<> <$+> <$+> <$+> <$*>		$>LDAPMailertable <$1> $2',
15107c478bd9Sstevel@tonic-gate`R<> <$+> <$+> <$+> <$*>	$#_RELAY_ $@ $1 $: $2')
15117c478bd9Sstevel@tonic-gate
15127c478bd9Sstevel@tonic-gateifdef(`_LDAP_ROUTE_DETAIL_',
15137c478bd9Sstevel@tonic-gate`# if no mailRoutingAddress and no mailHost,
15147c478bd9Sstevel@tonic-gate# try without +detail
15157c478bd9Sstevel@tonic-gateR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl
15167c478bd9Sstevel@tonic-gate
1517*e9af4bc0SJohn Beckifdef(`_LDAP_ROUTE_NODOMAIN_', `
1518*e9af4bc0SJohn Beck# pretend we did the @domain lookup
1519*e9af4bc0SJohn BeckR<> <> <$+> <$+ @ $+> <$*>	$: <> <> <$1> <@ $3> <$4>', `
15207c478bd9Sstevel@tonic-gate# if still no mailRoutingAddress and no mailHost,
15217c478bd9Sstevel@tonic-gate# try @domain
15227c478bd9Sstevel@tonic-gateifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
15237c478bd9Sstevel@tonic-gateR<> <> <$+> <$+ + $* @ $+> <>	$@ $>LDAPExpand <$1> <@ $4> <+$3>')
15247c478bd9Sstevel@tonic-gateR<> <> <$+> <$+ @ $+> <$*>	$@ $>LDAPExpand <$1> <@ $3> <$4>')
15257c478bd9Sstevel@tonic-gate
15267c478bd9Sstevel@tonic-gate# if no mailRoutingAddress and no mailHost and this was a domain attempt,
15277c478bd9Sstevel@tonic-gateifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl
15287c478bd9Sstevel@tonic-gate# user does not exist
15297c478bd9Sstevel@tonic-gateR<> <> <$+> <@ $+> <$*>		$: <?> < $&{addr_type} > < $1 >
15307c478bd9Sstevel@tonic-gate# only give error for envelope recipient
15317c478bd9Sstevel@tonic-gateR<?> <e r> <$+>			$#error $@ nouser $: "550 User unknown"
15327c478bd9Sstevel@tonic-gateifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl
15337c478bd9Sstevel@tonic-gate# and the sender too
15347c478bd9Sstevel@tonic-gateR<?> <e s> <$+>			$#error $@ nouser $: "550 User unknown"')
15357c478bd9Sstevel@tonic-gateR<?> <$*> <$+>			$@ $2',
15367c478bd9Sstevel@tonic-gate`dnl
15377c478bd9Sstevel@tonic-gate# return the original address
15387c478bd9Sstevel@tonic-gateR<> <> <$+> <@ $+> <$*>		$@ $1')',
15397c478bd9Sstevel@tonic-gate`dnl')
15407c478bd9Sstevel@tonic-gate
15417c478bd9Sstevel@tonic-gateifelse(substr(confDELIVERY_MODE,0,1), `d', `errprint(`WARNING: Antispam rules not available in deferred delivery mode.
15427c478bd9Sstevel@tonic-gate')')
15437c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
15447c478bd9Sstevel@tonic-gate######################################################################
15457c478bd9Sstevel@tonic-gate###  D: LookUpDomain -- search for domain in access database
15467c478bd9Sstevel@tonic-gate###
15477c478bd9Sstevel@tonic-gate###	Parameters:
15487c478bd9Sstevel@tonic-gate###		<$1> -- key (domain name)
15497c478bd9Sstevel@tonic-gate###		<$2> -- default (what to return if not found in db)
15507c478bd9Sstevel@tonic-gatednl			must not be empty
15517c478bd9Sstevel@tonic-gate###		<$3> -- mark (must be <(!|+) single-token>)
15527c478bd9Sstevel@tonic-gate###			! does lookup only with tag
15537c478bd9Sstevel@tonic-gate###			+ does lookup with and without tag
15547c478bd9Sstevel@tonic-gate###		<$4> -- passthru (additional data passed unchanged through)
15557c478bd9Sstevel@tonic-gatednl returns:		<default> <passthru>
15567c478bd9Sstevel@tonic-gatednl 			<result> <passthru>
15577c478bd9Sstevel@tonic-gate######################################################################
15587c478bd9Sstevel@tonic-gate
15597c478bd9Sstevel@tonic-gateSD
15607c478bd9Sstevel@tonic-gatednl workspace <key> <default> <passthru> <mark>
15617c478bd9Sstevel@tonic-gatednl lookup with tag (in front, no delimiter here)
15627c478bd9Sstevel@tonic-gatednl    2    3  4    5
15637c478bd9Sstevel@tonic-gateR<$*> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
15647c478bd9Sstevel@tonic-gatednl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
15657c478bd9Sstevel@tonic-gatednl lookup without tag?
15667c478bd9Sstevel@tonic-gatednl   1    2      3    4
15677c478bd9Sstevel@tonic-gateR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
15687c478bd9Sstevel@tonic-gateifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
15697c478bd9Sstevel@tonic-gatednl XXX apply this also to IP addresses?
15707c478bd9Sstevel@tonic-gatednl currently it works the wrong way round for [1.2.3.4]
15717c478bd9Sstevel@tonic-gatednl   1  2    3    4  5    6
15727c478bd9Sstevel@tonic-gateR<?> <$+.$+> <$+> <$- $-> <$*>	$: < $(access $5`'_TAG_DELIM_`'.$2 $: ? $) > <$1.$2> <$3> <$4 $5> <$6>
15737c478bd9Sstevel@tonic-gatednl   1  2    3      4    5
15747c478bd9Sstevel@tonic-gateR<?> <$+.$+> <$+> <+ $-> <$*>	$: < $(access .$2 $: ? $) > <$1.$2> <$3> <+ $4> <$5>', `dnl')
15757c478bd9Sstevel@tonic-gateifdef(`_ACCESS_SKIP_', `dnl
15767c478bd9Sstevel@tonic-gatednl found SKIP: return <default> and <passthru>
15777c478bd9Sstevel@tonic-gatednl      1    2    3  4    5
15787c478bd9Sstevel@tonic-gateR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
15797c478bd9Sstevel@tonic-gatednl not found: IPv4 net (no check is done whether it is an IP number!)
15807c478bd9Sstevel@tonic-gatednl    1  2     3    4  5    6
15817c478bd9Sstevel@tonic-gateR<?> <[$+.$-]> <$+> <$- $-> <$*>	$@ $>D <[$1]> <$3> <$4 $5> <$6>
15827c478bd9Sstevel@tonic-gateifdef(`NO_NETINET6', `dnl',
15837c478bd9Sstevel@tonic-gate`dnl not found: IPv6 net
15847c478bd9Sstevel@tonic-gatednl (could be merged with previous rule if we have a class containing .:)
15857c478bd9Sstevel@tonic-gatednl    1   2     3    4  5    6
15867c478bd9Sstevel@tonic-gateR<?> <[$+::$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>
15877c478bd9Sstevel@tonic-gateR<?> <[$+:$-]> <$+> <$- $-> <$*>	$: $>D <[$1]> <$3> <$4 $5> <$6>')
15887c478bd9Sstevel@tonic-gatednl not found, but subdomain: try again
15897c478bd9Sstevel@tonic-gatednl   1  2    3    4  5    6
15907c478bd9Sstevel@tonic-gateR<?> <$+.$+> <$+> <$- $-> <$*>	$@ $>D <$2> <$3> <$4 $5> <$6>
15917c478bd9Sstevel@tonic-gateifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
15927c478bd9Sstevel@tonic-gatednl   1    2      3    4
15937c478bd9Sstevel@tonic-gateR<?> <$+> <$+> <! $-> <$*>	$: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
15947c478bd9Sstevel@tonic-gatednl not found, no subdomain: return <default> and <passthru>
15957c478bd9Sstevel@tonic-gatednl   1    2    3  4    5
15967c478bd9Sstevel@tonic-gateR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
15977c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
15987c478bd9Sstevel@tonic-gatednl            2    3    4  5    6
15997c478bd9Sstevel@tonic-gateR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
16007c478bd9Sstevel@tonic-gatednl return <result of lookup> and <passthru>
16017c478bd9Sstevel@tonic-gatednl    2    3    4  5    6
16027c478bd9Sstevel@tonic-gateR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
16037c478bd9Sstevel@tonic-gate
16047c478bd9Sstevel@tonic-gate######################################################################
16057c478bd9Sstevel@tonic-gate###  A: LookUpAddress -- search for host address in access database
16067c478bd9Sstevel@tonic-gate###
16077c478bd9Sstevel@tonic-gate###	Parameters:
16087c478bd9Sstevel@tonic-gate###		<$1> -- key (dot quadded host address)
16097c478bd9Sstevel@tonic-gate###		<$2> -- default (what to return if not found in db)
16107c478bd9Sstevel@tonic-gatednl			must not be empty
16117c478bd9Sstevel@tonic-gate###		<$3> -- mark (must be <(!|+) single-token>)
16127c478bd9Sstevel@tonic-gate###			! does lookup only with tag
16137c478bd9Sstevel@tonic-gate###			+ does lookup with and without tag
16147c478bd9Sstevel@tonic-gate###		<$4> -- passthru (additional data passed through)
16157c478bd9Sstevel@tonic-gatednl	returns:	<default> <passthru>
16167c478bd9Sstevel@tonic-gatednl			<result> <passthru>
16177c478bd9Sstevel@tonic-gate######################################################################
16187c478bd9Sstevel@tonic-gate
16197c478bd9Sstevel@tonic-gateSA
16207c478bd9Sstevel@tonic-gatednl lookup with tag
16217c478bd9Sstevel@tonic-gatednl    2    3  4    5
16227c478bd9Sstevel@tonic-gateR<$+> <$+> <$- $-> <$*>		$: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
16237c478bd9Sstevel@tonic-gatednl lookup without tag
16247c478bd9Sstevel@tonic-gatednl   1    2      3    4
16257c478bd9Sstevel@tonic-gateR<?> <$+> <$+> <+ $-> <$*>	$: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
16267c478bd9Sstevel@tonic-gatednl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
16277c478bd9Sstevel@tonic-gateifdef(`_ACCESS_SKIP_', `dnl
16287c478bd9Sstevel@tonic-gatednl found SKIP: return <default> and <passthru>
16297c478bd9Sstevel@tonic-gatednl      1    2    3  4    5
16307c478bd9Sstevel@tonic-gateR<SKIP> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>', `dnl')
16317c478bd9Sstevel@tonic-gateifdef(`NO_NETINET6', `dnl',
16327c478bd9Sstevel@tonic-gate`dnl no match; IPv6: remove last part
16337c478bd9Sstevel@tonic-gatednl   1   2    3    4  5    6
16347c478bd9Sstevel@tonic-gateR<?> <$+::$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
16357c478bd9Sstevel@tonic-gateR<?> <$+:$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>')
16367c478bd9Sstevel@tonic-gatednl no match; IPv4: remove last part
16377c478bd9Sstevel@tonic-gatednl   1  2    3    4  5    6
16387c478bd9Sstevel@tonic-gateR<?> <$+.$-> <$+> <$- $-> <$*>		$@ $>A <$1> <$3> <$4 $5> <$6>
16397c478bd9Sstevel@tonic-gatednl no match: return default
16407c478bd9Sstevel@tonic-gatednl   1    2    3  4    5
16417c478bd9Sstevel@tonic-gateR<?> <$+> <$+> <$- $-> <$*>	$@ <$2> <$5>
16427c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
16437c478bd9Sstevel@tonic-gatednl            2    3    4  5    6
16447c478bd9Sstevel@tonic-gateR<$* _ATMPF_> <$+> <$+> <$- $-> <$*>	$@ <_ATMPF_> <$6>', `dnl')
16457c478bd9Sstevel@tonic-gatednl match: return result
16467c478bd9Sstevel@tonic-gatednl    2    3    4  5    6
16477c478bd9Sstevel@tonic-gateR<$*> <$+> <$+> <$- $-> <$*>	$@ <$1> <$6>
16487c478bd9Sstevel@tonic-gatednl endif _ACCESS_TABLE_
16497c478bd9Sstevel@tonic-gatedivert(0)
16507c478bd9Sstevel@tonic-gate######################################################################
16517c478bd9Sstevel@tonic-gate###  CanonAddr --	Convert an address into a standard form for
16527c478bd9Sstevel@tonic-gate###			relay checking.  Route address syntax is
16537c478bd9Sstevel@tonic-gate###			crudely converted into a %-hack address.
16547c478bd9Sstevel@tonic-gate###
16557c478bd9Sstevel@tonic-gate###	Parameters:
16567c478bd9Sstevel@tonic-gate###		$1 -- full recipient address
16577c478bd9Sstevel@tonic-gate###
16587c478bd9Sstevel@tonic-gate###	Returns:
16597c478bd9Sstevel@tonic-gate###		parsed address, not in source route form
16607c478bd9Sstevel@tonic-gatednl		user%host%host<@domain>
16617c478bd9Sstevel@tonic-gatednl		host!user<@domain>
16627c478bd9Sstevel@tonic-gate######################################################################
16637c478bd9Sstevel@tonic-gate
16647c478bd9Sstevel@tonic-gateSCanonAddr
16657c478bd9Sstevel@tonic-gateR$*			$: $>Parse0 $>canonify $1	make domain canonical
16667c478bd9Sstevel@tonic-gateifdef(`_USE_DEPRECATED_ROUTE_ADDR_',`dnl
16677c478bd9Sstevel@tonic-gateR< @ $+ > : $* @ $*	< @ $1 > : $2 % $3	change @ to % in src route
16687c478bd9Sstevel@tonic-gateR$* < @ $+ > : $* : $*	$3 $1 < @ $2 > : $4	change to % hack.
16697c478bd9Sstevel@tonic-gateR$* < @ $+ > : $*	$3 $1 < @ $2 >
16707c478bd9Sstevel@tonic-gatednl')
16717c478bd9Sstevel@tonic-gate
16727c478bd9Sstevel@tonic-gate######################################################################
16737c478bd9Sstevel@tonic-gate###  ParseRecipient --	Strip off hosts in $=R as well as possibly
16747c478bd9Sstevel@tonic-gate###			$* $=m or the access database.
16757c478bd9Sstevel@tonic-gate###			Check user portion for host separators.
16767c478bd9Sstevel@tonic-gate###
16777c478bd9Sstevel@tonic-gate###	Parameters:
16787c478bd9Sstevel@tonic-gate###		$1 -- full recipient address
16797c478bd9Sstevel@tonic-gate###
16807c478bd9Sstevel@tonic-gate###	Returns:
16817c478bd9Sstevel@tonic-gate###		parsed, non-local-relaying address
16827c478bd9Sstevel@tonic-gate######################################################################
16837c478bd9Sstevel@tonic-gate
16847c478bd9Sstevel@tonic-gateSParseRecipient
16857c478bd9Sstevel@tonic-gatednl mark and canonify address
16867c478bd9Sstevel@tonic-gateR$*				$: <?> $>CanonAddr $1
16877c478bd9Sstevel@tonic-gatednl workspace: <?> localpart<@domain[.]>
16887c478bd9Sstevel@tonic-gateR<?> $* < @ $* . >		<?> $1 < @ $2 >			strip trailing dots
16897c478bd9Sstevel@tonic-gatednl workspace: <?> localpart<@domain>
16907c478bd9Sstevel@tonic-gateR<?> $- < @ $* >		$: <?> $(dequote $1 $) < @ $2 >	dequote local part
16917c478bd9Sstevel@tonic-gate
16927c478bd9Sstevel@tonic-gate# if no $=O character, no host in the user portion, we are done
16937c478bd9Sstevel@tonic-gateR<?> $* $=O $* < @ $* >		$: <NO> $1 $2 $3 < @ $4>
16947c478bd9Sstevel@tonic-gatednl no $=O in localpart: return
16957c478bd9Sstevel@tonic-gateR<?> $*				$@ $1
16967c478bd9Sstevel@tonic-gate
16977c478bd9Sstevel@tonic-gatednl workspace: <NO> localpart<@domain>, where localpart contains $=O
16987c478bd9Sstevel@tonic-gatednl mark everything which has an "authorized" domain with <RELAY>
16997c478bd9Sstevel@tonic-gateifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
17007c478bd9Sstevel@tonic-gate# if we relay, check username portion for user%host so host can be checked also
17017c478bd9Sstevel@tonic-gateR<NO> $* < @ $* $=m >		$: <RELAY> $1 < @ $2 $3 >', `dnl')
17027c478bd9Sstevel@tonic-gatednl workspace: <(NO|RELAY)> localpart<@domain>, where localpart contains $=O
17037c478bd9Sstevel@tonic-gatednl if mark is <NO> then change it to <RELAY> if domain is "authorized"
17047c478bd9Sstevel@tonic-gate
17057c478bd9Sstevel@tonic-gatednl what if access map returns something else than RELAY?
17067c478bd9Sstevel@tonic-gatednl we are only interested in RELAY entries...
17077c478bd9Sstevel@tonic-gatednl other To: entries: blacklist recipient; generic entries?
17087c478bd9Sstevel@tonic-gatednl if it is an error we probably do not want to relay anyway
17097c478bd9Sstevel@tonic-gateifdef(`_RELAY_HOSTS_ONLY_',
17107c478bd9Sstevel@tonic-gate`R<NO> $* < @ $=R >		$: <RELAY> $1 < @ $2 >
17117c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
17127c478bd9Sstevel@tonic-gateR<NO> $* < @ $+ >		$: <$(access To:$2 $: NO $)> $1 < @ $2 >
17137c478bd9Sstevel@tonic-gateR<NO> $* < @ $+ >		$: <$(access $2 $: NO $)> $1 < @ $2 >',`dnl')',
17147c478bd9Sstevel@tonic-gate`R<NO> $* < @ $* $=R >		$: <RELAY> $1 < @ $2 $3 >
17157c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
17167c478bd9Sstevel@tonic-gateR<NO> $* < @ $+ >		$: $>D <$2> <NO> <+ To> <$1 < @ $2 >>
17177c478bd9Sstevel@tonic-gateR<$+> <$+>			$: <$1> $2',`dnl')')
17187c478bd9Sstevel@tonic-gate
17197c478bd9Sstevel@tonic-gate
17207c478bd9Sstevel@tonic-gateifdef(`_RELAY_MX_SERVED_', `dnl
17217c478bd9Sstevel@tonic-gatednl do "we" ($=w) act as backup MX server for the destination domain?
17227c478bd9Sstevel@tonic-gateR<NO> $* < @ $+ >		$: <MX> < : $(mxserved $2 $) : > < $1 < @$2 > >
17237c478bd9Sstevel@tonic-gateR<MX> < : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
17247c478bd9Sstevel@tonic-gatednl yes: mark it as <RELAY>
17257c478bd9Sstevel@tonic-gateR<MX> < $* : $=w. : $* > < $+ >	$: <RELAY> $4
17267c478bd9Sstevel@tonic-gatednl no: put old <NO> mark back
17277c478bd9Sstevel@tonic-gateR<MX> < : $* : > < $+ >		$: <NO> $2', `dnl')
17287c478bd9Sstevel@tonic-gate
17297c478bd9Sstevel@tonic-gatednl do we relay to this recipient domain?
17307c478bd9Sstevel@tonic-gateR<RELAY> $* < @ $* >		$@ $>ParseRecipient $1
17317c478bd9Sstevel@tonic-gatednl something else
17327c478bd9Sstevel@tonic-gateR<$+> $*			$@ $2
17337c478bd9Sstevel@tonic-gate
17347c478bd9Sstevel@tonic-gate
17357c478bd9Sstevel@tonic-gate######################################################################
17367c478bd9Sstevel@tonic-gate###  check_relay -- check hostname/address on SMTP startup
17377c478bd9Sstevel@tonic-gate######################################################################
17387c478bd9Sstevel@tonic-gate
17397c478bd9Sstevel@tonic-gateifdef(`_CONTROL_IMMEDIATE_',`dnl
17407c478bd9Sstevel@tonic-gateScheck_relay
17417c478bd9Sstevel@tonic-gateifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl
17427c478bd9Sstevel@tonic-gatednl workspace: ignored...
17437c478bd9Sstevel@tonic-gateR$*		$: $>"RateControl" dummy', `dnl')
17447c478bd9Sstevel@tonic-gateifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl
17457c478bd9Sstevel@tonic-gatednl workspace: ignored...
17467c478bd9Sstevel@tonic-gateR$*		$: $>"ConnControl" dummy', `dnl')
17477c478bd9Sstevel@tonic-gatednl')
17487c478bd9Sstevel@tonic-gate
17497c478bd9Sstevel@tonic-gateSLocal_check_relay
17507c478bd9Sstevel@tonic-gateScheck`'_U_`'relay
17517c478bd9Sstevel@tonic-gateifdef(`_USE_CLIENT_PTR_',`dnl
17527c478bd9Sstevel@tonic-gateR$* $| $*		$: $&{client_ptr} $| $2', `dnl')
17537c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_check_relay" $1
17547c478bd9Sstevel@tonic-gateR$* $| $* $| $#$*	$#$3
17557c478bd9Sstevel@tonic-gateR$* $| $* $| $*		$@ $>"Basic_check_relay" $1 $| $2
17567c478bd9Sstevel@tonic-gate
17577c478bd9Sstevel@tonic-gateSBasic_check_relay
17587c478bd9Sstevel@tonic-gate# check for deferred delivery mode
17597c478bd9Sstevel@tonic-gateR$*			$: < $&{deliveryMode} > $1
17607c478bd9Sstevel@tonic-gateR< d > $*		$@ deferred
17617c478bd9Sstevel@tonic-gateR< $* > $*		$: $2
17627c478bd9Sstevel@tonic-gate
17637c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
17647c478bd9Sstevel@tonic-gatednl workspace: {client_name} $| {client_addr}
17657c478bd9Sstevel@tonic-gateR$+ $| $+		$: $>D < $1 > <?> <+ Connect> < $2 >
17667c478bd9Sstevel@tonic-gatednl workspace: <result-of-lookup> <{client_addr}>
17677c478bd9Sstevel@tonic-gatednl OR $| $+ if client_name is empty
17687c478bd9Sstevel@tonic-gateR   $| $+		$: $>A < $1 > <?> <+ Connect> <>	empty client_name
17697c478bd9Sstevel@tonic-gatednl workspace: <result-of-lookup> <{client_addr}>
17707c478bd9Sstevel@tonic-gateR<?> <$+>		$: $>A < $1 > <?> <+ Connect> <>	no: another lookup
17717c478bd9Sstevel@tonic-gatednl workspace: <result-of-lookup> (<>|<{client_addr}>)
17727c478bd9Sstevel@tonic-gateR<?> <$*>		$: OK				found nothing
17737c478bd9Sstevel@tonic-gatednl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
17747c478bd9Sstevel@tonic-gateR<$={Accept}> <$*>	$@ $1				return value of lookup
17757c478bd9Sstevel@tonic-gateR<REJECT> <$*>		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
17767c478bd9Sstevel@tonic-gateR<DISCARD> <$*>		$#discard $: discard
17777c478bd9Sstevel@tonic-gateR<QUARANTINE:$+> <$*>	$#error $@ quarantine $: $1
17787c478bd9Sstevel@tonic-gatednl error tag
17797c478bd9Sstevel@tonic-gateR<ERROR:$-.$-.$-:$+> <$*>	$#error $@ $1.$2.$3 $: $4
17807c478bd9Sstevel@tonic-gateR<ERROR:$+> <$*>		$#error $: $1
17817c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<$* _ATMPF_> <$*>		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
17827c478bd9Sstevel@tonic-gatednl generic error from access map
17837c478bd9Sstevel@tonic-gateR<$+> <$*>		$#error $: $1', `dnl')
17847c478bd9Sstevel@tonic-gate
17857c478bd9Sstevel@tonic-gateifdef(`_RBL_',`dnl
17867c478bd9Sstevel@tonic-gate# DNS based IP address spam list
17877c478bd9Sstevel@tonic-gatednl workspace: ignored...
17887c478bd9Sstevel@tonic-gateR$*			$: $&{client_addr}
17897c478bd9Sstevel@tonic-gateR$-.$-.$-.$-		$: <?> $(host $4.$3.$2.$1._RBL_. $: OK $)
17907c478bd9Sstevel@tonic-gateR<?>OK			$: OKSOFAR
17917c478bd9Sstevel@tonic-gateR<?>$+			$#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"',
17927c478bd9Sstevel@tonic-gate`dnl')
17937c478bd9Sstevel@tonic-gateifdef(`_RATE_CONTROL_',`dnl
17947c478bd9Sstevel@tonic-gateifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl
17957c478bd9Sstevel@tonic-gatednl workspace: ignored...
17967c478bd9Sstevel@tonic-gateR$*		$: $>"RateControl" dummy')', `dnl')
17977c478bd9Sstevel@tonic-gateifdef(`_CONN_CONTROL_',`dnl
17987c478bd9Sstevel@tonic-gateifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
17997c478bd9Sstevel@tonic-gatednl workspace: ignored...
18007c478bd9Sstevel@tonic-gateR$*		$: $>"ConnControl" dummy')', `dnl')
18017c478bd9Sstevel@tonic-gateundivert(8)
1802058561cbSjbeckifdef(`_REQUIRE_RDNS_', `dnl
1803058561cbSjbeckR$*			$: $&{client_addr} $| $&{client_resolve}
1804058561cbSjbeckR$=R $*			$@ RELAY		We relay for these
1805058561cbSjbeckR$* $| OK		$@ OK			Resolves.
1806058561cbSjbeckR$* $| FAIL		$#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
1807058561cbSjbeckR$* $| TEMP		$#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
1808058561cbSjbeckR$* $| FORGED		$#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
1809058561cbSjbeck', `dnl')
18107c478bd9Sstevel@tonic-gate
18117c478bd9Sstevel@tonic-gate######################################################################
18127c478bd9Sstevel@tonic-gate###  check_mail -- check SMTP ``MAIL FROM:'' command argument
18137c478bd9Sstevel@tonic-gate######################################################################
18147c478bd9Sstevel@tonic-gate
18157c478bd9Sstevel@tonic-gateSLocal_check_mail
18167c478bd9Sstevel@tonic-gateScheck`'_U_`'mail
18177c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_check_mail" $1
18187c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
18197c478bd9Sstevel@tonic-gateR$* $| $*		$@ $>"Basic_check_mail" $1
18207c478bd9Sstevel@tonic-gate
18217c478bd9Sstevel@tonic-gateSBasic_check_mail
18227c478bd9Sstevel@tonic-gate# check for deferred delivery mode
18237c478bd9Sstevel@tonic-gateR$*			$: < $&{deliveryMode} > $1
18247c478bd9Sstevel@tonic-gateR< d > $*		$@ deferred
18257c478bd9Sstevel@tonic-gateR< $* > $*		$: $2
18267c478bd9Sstevel@tonic-gate
18277c478bd9Sstevel@tonic-gate# authenticated?
18287c478bd9Sstevel@tonic-gatednl done first: we can require authentication for every mail transaction
18297c478bd9Sstevel@tonic-gatednl workspace: address as given by MAIL FROM: (sender)
18307c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
18317c478bd9Sstevel@tonic-gateR$* $| $#$+		$#$2
18327c478bd9Sstevel@tonic-gatednl undo damage: remove result of tls_client call
18337c478bd9Sstevel@tonic-gateR$* $| $*		$: $1
18347c478bd9Sstevel@tonic-gate
18357c478bd9Sstevel@tonic-gatednl workspace: address as given by MAIL FROM:
18367c478bd9Sstevel@tonic-gateR<>			$@ <OK>			we MUST accept <> (RFC 1123)
18377c478bd9Sstevel@tonic-gateifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
18387c478bd9Sstevel@tonic-gatednl do some additional checks
18397c478bd9Sstevel@tonic-gatednl no user@host
18407c478bd9Sstevel@tonic-gatednl no user@localhost (if nonlocal sender)
18417c478bd9Sstevel@tonic-gatednl this is a pretty simple canonification, it will not catch every case
18427c478bd9Sstevel@tonic-gatednl just make sure the address has <> around it (which is required by
18437c478bd9Sstevel@tonic-gatednl the RFC anyway, maybe we should complain if they are missing...)
18447c478bd9Sstevel@tonic-gatednl dirty trick: if it is user@host, just add a dot: user@host. this will
18457c478bd9Sstevel@tonic-gatednl not be modified by host lookups.
18467c478bd9Sstevel@tonic-gateR$+			$: <?> $1
18477c478bd9Sstevel@tonic-gateR<?><$+>		$: <@> <$1>
18487c478bd9Sstevel@tonic-gateR<?>$+			$: <@> <$1>
18497c478bd9Sstevel@tonic-gatednl workspace: <@> <address>
18507c478bd9Sstevel@tonic-gatednl prepend daemon_flags
18517c478bd9Sstevel@tonic-gateR$*			$: $&{daemon_flags} $| $1
18527c478bd9Sstevel@tonic-gatednl workspace: ${daemon_flags} $| <@> <address>
18537c478bd9Sstevel@tonic-gatednl do not allow these at all or only from local systems?
18547c478bd9Sstevel@tonic-gateR$* f $* $| <@> < $* @ $- >	$: < ? $&{client_name} > < $3 @ $4 >
18557c478bd9Sstevel@tonic-gatednl accept unqualified sender: change mark to avoid test
18567c478bd9Sstevel@tonic-gateR$* u $* $| <@> < $* >	$: <?> < $3 >
18577c478bd9Sstevel@tonic-gatednl workspace: ${daemon_flags} $| <@> <address>
18587c478bd9Sstevel@tonic-gatednl        or:                    <? ${client_name} > <address>
18597c478bd9Sstevel@tonic-gatednl        or:                    <?> <address>
18607c478bd9Sstevel@tonic-gatednl remove daemon_flags
18617c478bd9Sstevel@tonic-gateR$* $| $*		$: $2
18627c478bd9Sstevel@tonic-gate# handle case of @localhost on address
18637c478bd9Sstevel@tonic-gateR<@> < $* @ localhost >	$: < ? $&{client_name} > < $1 @ localhost >
18647c478bd9Sstevel@tonic-gateR<@> < $* @ [127.0.0.1] >
18657c478bd9Sstevel@tonic-gate			$: < ? $&{client_name} > < $1 @ [127.0.0.1] >
18667c478bd9Sstevel@tonic-gateR<@> < $* @ localhost.$m >
18677c478bd9Sstevel@tonic-gate			$: < ? $&{client_name} > < $1 @ localhost.$m >
18687c478bd9Sstevel@tonic-gateifdef(`_NO_UUCP_', `dnl',
18697c478bd9Sstevel@tonic-gate`R<@> < $* @ localhost.UUCP >
18707c478bd9Sstevel@tonic-gate			$: < ? $&{client_name} > < $1 @ localhost.UUCP >')
18717c478bd9Sstevel@tonic-gatednl workspace: < ? $&{client_name} > <user@localhost|host>
18727c478bd9Sstevel@tonic-gatednl	or:    <@> <address>
18737c478bd9Sstevel@tonic-gatednl	or:    <?> <address>	(thanks to u in ${daemon_flags})
18747c478bd9Sstevel@tonic-gateR<@> $*			$: $1			no localhost as domain
18757c478bd9Sstevel@tonic-gatednl workspace: < ? $&{client_name} > <user@localhost|host>
18767c478bd9Sstevel@tonic-gatednl	or:    <address>
18777c478bd9Sstevel@tonic-gatednl	or:    <?> <address>	(thanks to u in ${daemon_flags})
18787c478bd9Sstevel@tonic-gateR<? $=w> $*		$: $2			local client: ok
18797c478bd9Sstevel@tonic-gateR<? $+> <$+>		$#error $@ 5.5.4 $: "_CODE553 Real domain name required for sender address"
18807c478bd9Sstevel@tonic-gatednl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
18817c478bd9Sstevel@tonic-gateR<?> $*			$: $1')
18827c478bd9Sstevel@tonic-gatednl workspace: address (or <address>)
18837c478bd9Sstevel@tonic-gateR$*			$: <?> $>CanonAddr $1		canonify sender address and mark it
18847c478bd9Sstevel@tonic-gatednl workspace: <?> CanonicalAddress (i.e. address in canonical form localpart<@host>)
18857c478bd9Sstevel@tonic-gatednl there is nothing behind the <@host> so no trailing $* needed
18867c478bd9Sstevel@tonic-gateR<?> $* < @ $+ . >	<?> $1 < @ $2 >			strip trailing dots
18877c478bd9Sstevel@tonic-gate# handle non-DNS hostnames (*.bitnet, *.decnet, *.uucp, etc)
18887c478bd9Sstevel@tonic-gateR<?> $* < @ $* $=P >	$: <_RES_OK_> $1 < @ $2 $3 >
18897c478bd9Sstevel@tonic-gatednl workspace <mark> CanonicalAddress	where mark is ? or OK
18907c478bd9Sstevel@tonic-gatednl A sender address with my local host name ($j) is safe
18917c478bd9Sstevel@tonic-gateR<?> $* < @ $j >	$: <_RES_OK_> $1 < @ $j >
18927c478bd9Sstevel@tonic-gateifdef(`_ACCEPT_UNRESOLVABLE_DOMAINS_',
18937c478bd9Sstevel@tonic-gate`R<?> $* < @ $+ >	$: <_RES_OK_> $1 < @ $2 >		... unresolvable OK',
18947c478bd9Sstevel@tonic-gate`R<?> $* < @ $+ >	$: <? $(resolve $2 $: $2 <PERM> $) > $1 < @ $2 >
18957c478bd9Sstevel@tonic-gateR<? $* <$->> $* < @ $+ >
18967c478bd9Sstevel@tonic-gate			$: <$2> $3 < @ $4 >')
18977c478bd9Sstevel@tonic-gatednl workspace <mark> CanonicalAddress	where mark is ?, _RES_OK_, PERM, TEMP
18987c478bd9Sstevel@tonic-gatednl mark is ? iff the address is user (wo @domain)
18997c478bd9Sstevel@tonic-gate
19007c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
19017c478bd9Sstevel@tonic-gate# check sender address: user@address, user@, address
19027c478bd9Sstevel@tonic-gatednl should we remove +ext from user?
19037c478bd9Sstevel@tonic-gatednl workspace: <mark> CanonicalAddress where mark is: ?, _RES_OK_, PERM, TEMP
19047c478bd9Sstevel@tonic-gateR<$+> $+ < @ $* >	$: @<$1> <$2 < @ $3 >> $| <F:$2@$3> <U:$2@> <D:$3>
19057c478bd9Sstevel@tonic-gateR<$+> $+		$: @<$1> <$2> $| <U:$2@>
19067c478bd9Sstevel@tonic-gatednl workspace: @<mark> <CanonicalAddress> $| <@type:address> ....
19077c478bd9Sstevel@tonic-gatednl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
19087c478bd9Sstevel@tonic-gatednl will only return user<@domain when "reversing" the args
19097c478bd9Sstevel@tonic-gateR@ <$+> <$*> $| <$+>	$: <@> <$1> <$2> $| $>SearchList <+ From> $| <$3> <>
19107c478bd9Sstevel@tonic-gatednl workspace: <@><mark> <CanonicalAddress> $| <result>
19117c478bd9Sstevel@tonic-gateR<@> <$+> <$*> $| <$*>	$: <$3> <$1> <$2>		reverse result
19127c478bd9Sstevel@tonic-gatednl workspace: <result> <mark> <CanonicalAddress>
19137c478bd9Sstevel@tonic-gate# retransform for further use
19147c478bd9Sstevel@tonic-gatednl required form:
19157c478bd9Sstevel@tonic-gatednl <ResultOfLookup|mark> CanonicalAddress
19167c478bd9Sstevel@tonic-gateR<?> <$+> <$*>		$: <$1> $2	no match
19177c478bd9Sstevel@tonic-gateR<$+> <$+> <$*>		$: <$1> $3	relevant result, keep it', `dnl')
19187c478bd9Sstevel@tonic-gatednl workspace <ResultOfLookup|mark> CanonicalAddress
19197c478bd9Sstevel@tonic-gatednl mark is ? iff the address is user (wo @domain)
19207c478bd9Sstevel@tonic-gate
19217c478bd9Sstevel@tonic-gateifdef(`_ACCEPT_UNQUALIFIED_SENDERS_',`dnl',`dnl
19227c478bd9Sstevel@tonic-gate# handle case of no @domain on address
19237c478bd9Sstevel@tonic-gatednl prepend daemon_flags
19247c478bd9Sstevel@tonic-gateR<?> $*			$: $&{daemon_flags} $| <?> $1
19257c478bd9Sstevel@tonic-gatednl accept unqualified sender: change mark to avoid test
19267c478bd9Sstevel@tonic-gateR$* u $* $| <?> $*	$: <_RES_OK_> $3
19277c478bd9Sstevel@tonic-gatednl remove daemon_flags
19287c478bd9Sstevel@tonic-gateR$* $| $*		$: $2
19297c478bd9Sstevel@tonic-gateR<?> $*			$: < ? $&{client_addr} > $1
19307c478bd9Sstevel@tonic-gateR<?> $*			$@ <_RES_OK_>			...local unqualed ok
19317c478bd9Sstevel@tonic-gateR<? $+> $*		$#error $@ 5.5.4 $: "_CODE553 Domain name required for sender address " $&f
19327c478bd9Sstevel@tonic-gate							...remote is not')
19337c478bd9Sstevel@tonic-gate# check results
19347c478bd9Sstevel@tonic-gateR<?> $*			$: @ $1		mark address: nothing known about it
1935058561cbSjbeckR<$={ResOk}> $*		$: @ $2		domain ok
19367c478bd9Sstevel@tonic-gateR<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
19377c478bd9Sstevel@tonic-gateR<PERM> $*		$#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
19387c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
19397c478bd9Sstevel@tonic-gateR<$={Accept}> $*	$# $1		accept from access map
19407c478bd9Sstevel@tonic-gateR<DISCARD> $*		$#discard $: discard
19417c478bd9Sstevel@tonic-gateR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
19427c478bd9Sstevel@tonic-gateR<REJECT> $*		$#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"')
19437c478bd9Sstevel@tonic-gatednl error tag
19447c478bd9Sstevel@tonic-gateR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
19457c478bd9Sstevel@tonic-gateR<ERROR:$+> $*		$#error $: $1
19467c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
19477c478bd9Sstevel@tonic-gatednl generic error from access map
19487c478bd9Sstevel@tonic-gateR<$+> $*		$#error $: $1		error from access db',
19497c478bd9Sstevel@tonic-gate`dnl')
1950058561cbSjbeckdnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
1951058561cbSjbeck
1952058561cbSjbeckifdef(`_BADMX_CHK_', `dnl
1953058561cbSjbeckR@ $*<@$+>$*		$: $1<@$2>$3 $| $>BadMX $2
1954058561cbSjbeckR$* $| $#$*		$#$2
1955058561cbSjbeck
1956058561cbSjbeckSBadMX
1957058561cbSjbeck# Look up MX records and ferret away a copy of the original address.
1958058561cbSjbeck# input: domain part of address to check
1959058561cbSjbeckR$+				$:<MX><$1><:$(mxlist $1$):><:>
1960058561cbSjbeck# workspace: <MX><domain><: mxlist-result $><:>
1961058561cbSjbeckR<MX><$+><:$*<TEMP>:><$*>	$#error $@ 4.1.2 $: "450 MX lookup failure for "$1
1962058561cbSjbeck# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
1963058561cbSjbeck# Recursively run badmx check on each mx.
1964058561cbSjbeckR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><: $4 $(badmx $2 $):>
1965058561cbSjbeck# See if any of them fail.
1966d4660949SjbeckR<MX><$*><$*><$*<BADMX>:$*>	$#error $@ 5.1.2 $:"550 Illegal MX record for host "$1
1967058561cbSjbeck# Reverse the mxlists so we can use the same argument order again.
1968058561cbSjbeckR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
1969058561cbSjbeckR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(dnsA $2 $) :>
1970058561cbSjbeck
1971058561cbSjbeck# Reverse the lists so we can use the same argument order again.
1972058561cbSjbeckR<MX><$*><$*><$*>		$:<MX><$1><$3><$2>
1973058561cbSjbeckR<MX><$*><:$+:$*><:$*>		<MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
1974058561cbSjbeck
1975d4660949SjbeckR<MX><$*><$*><$*<BADMXIP>:$*>	$#error $@ 5.1.2 $:"550 Invalid MX record for host "$1',
1976058561cbSjbeck`dnl')
1977058561cbSjbeck
19787c478bd9Sstevel@tonic-gate
19797c478bd9Sstevel@tonic-gate######################################################################
19807c478bd9Sstevel@tonic-gate###  check_rcpt -- check SMTP ``RCPT TO:'' command argument
19817c478bd9Sstevel@tonic-gate######################################################################
19827c478bd9Sstevel@tonic-gate
19837c478bd9Sstevel@tonic-gateSLocal_check_rcpt
19847c478bd9Sstevel@tonic-gateScheck`'_U_`'rcpt
19857c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_check_rcpt" $1
19867c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
19877c478bd9Sstevel@tonic-gateR$* $| $*		$@ $>"Basic_check_rcpt" $1
19887c478bd9Sstevel@tonic-gate
19897c478bd9Sstevel@tonic-gateSBasic_check_rcpt
19907c478bd9Sstevel@tonic-gate# empty address?
19917c478bd9Sstevel@tonic-gateR<>			$#error $@ nouser $: "553 User address required"
19927c478bd9Sstevel@tonic-gateR$@			$#error $@ nouser $: "553 User address required"
19937c478bd9Sstevel@tonic-gate# check for deferred delivery mode
19947c478bd9Sstevel@tonic-gateR$*			$: < $&{deliveryMode} > $1
19957c478bd9Sstevel@tonic-gateR< d > $*		$@ deferred
19967c478bd9Sstevel@tonic-gateR< $* > $*		$: $2
19977c478bd9Sstevel@tonic-gate
19987c478bd9Sstevel@tonic-gateifdef(`_REQUIRE_QUAL_RCPT_', `dnl
19997c478bd9Sstevel@tonic-gatednl this code checks for user@host where host is not a FQHN.
20007c478bd9Sstevel@tonic-gatednl it is not activated.
20017c478bd9Sstevel@tonic-gatednl notice: code to check for a recipient without a domain name is
20027c478bd9Sstevel@tonic-gatednl available down below; look for the same macro.
20037c478bd9Sstevel@tonic-gatednl this check is done here because the name might be qualified by the
20047c478bd9Sstevel@tonic-gatednl canonicalization.
20057c478bd9Sstevel@tonic-gate# require fully qualified domain part?
20067c478bd9Sstevel@tonic-gatednl very simple canonification: make sure the address is in < >
20077c478bd9Sstevel@tonic-gateR$+			$: <?> $1
20087c478bd9Sstevel@tonic-gateR<?> <$+>		$: <@> <$1>
20097c478bd9Sstevel@tonic-gateR<?> $+			$: <@> <$1>
20107c478bd9Sstevel@tonic-gateR<@> < postmaster >	$: postmaster
20117c478bd9Sstevel@tonic-gateR<@> < $* @ $+ . $+ >	$: < $1 @ $2 . $3 >
20127c478bd9Sstevel@tonic-gatednl prepend daemon_flags
20137c478bd9Sstevel@tonic-gateR<@> $*			$: $&{daemon_flags} $| <@> $1
20147c478bd9Sstevel@tonic-gatednl workspace: ${daemon_flags} $| <@> <address>
20153ee0e492Sjbeckdnl _r_equire qual.rcpt: ok
20167c478bd9Sstevel@tonic-gateR$* r $* $| <@> < $+ @ $+ >	$: < $3 @ $4 >
20177c478bd9Sstevel@tonic-gatednl do not allow these at all or only from local systems?
20187c478bd9Sstevel@tonic-gateR$* r $* $| <@> < $* >	$: < ? $&{client_name} > < $3 >
20197c478bd9Sstevel@tonic-gateR<?> < $* >		$: <$1>
20207c478bd9Sstevel@tonic-gateR<? $=w> < $* >		$: <$1>
20217c478bd9Sstevel@tonic-gateR<? $+> <$+>		$#error $@ 5.5.4 $: "553 Fully qualified domain name required"
20227c478bd9Sstevel@tonic-gatednl remove daemon_flags for other cases
20237c478bd9Sstevel@tonic-gateR$* $| <@> $*		$: $2', `dnl')
20247c478bd9Sstevel@tonic-gate
20257c478bd9Sstevel@tonic-gatednl ##################################################################
20267c478bd9Sstevel@tonic-gatednl call subroutines for recipient and relay
20277c478bd9Sstevel@tonic-gatednl possible returns from subroutines:
20287c478bd9Sstevel@tonic-gatednl $#TEMP	temporary failure
20297c478bd9Sstevel@tonic-gatednl $#error	permanent failure (or temporary if from access map)
20307c478bd9Sstevel@tonic-gatednl $#other	stop processing
20317c478bd9Sstevel@tonic-gatednl RELAY	RELAYing allowed
20327c478bd9Sstevel@tonic-gatednl other	otherwise
20337c478bd9Sstevel@tonic-gate######################################################################
20347c478bd9Sstevel@tonic-gateR$*			$: $1 $| @ $>"Rcpt_ok" $1
20357c478bd9Sstevel@tonic-gatednl temporary failure? remove mark @ and remember
20367c478bd9Sstevel@tonic-gateR$* $| @ $#TEMP $+	$: $1 $| T $2
20377c478bd9Sstevel@tonic-gatednl error or ok (stop)
20387c478bd9Sstevel@tonic-gateR$* $| @ $#$*		$#$2
20397c478bd9Sstevel@tonic-gateifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
20407c478bd9Sstevel@tonic-gateR$* $| @ RELAY		$@ RELAY
20417c478bd9Sstevel@tonic-gatednl something else: call check sender (relay)
20427c478bd9Sstevel@tonic-gateR$* $| @ $*		$: O $| $>"Relay_ok" $1
20437c478bd9Sstevel@tonic-gatednl temporary failure: call check sender (relay)
20447c478bd9Sstevel@tonic-gateR$* $| T $+		$: T $2 $| $>"Relay_ok" $1
20457c478bd9Sstevel@tonic-gatednl temporary failure? return that
20467c478bd9Sstevel@tonic-gateR$* $| $#TEMP $+	$#error $2
20477c478bd9Sstevel@tonic-gatednl error or ok (stop)
20487c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
20497c478bd9Sstevel@tonic-gateR$* $| RELAY		$@ RELAY
20507c478bd9Sstevel@tonic-gatednl something else: return previous temp failure
20517c478bd9Sstevel@tonic-gateR T $+ $| $*		$#error $1
20527c478bd9Sstevel@tonic-gate# anything else is bogus
20537c478bd9Sstevel@tonic-gateR$*			$#error $@ 5.7.1 $: confRELAY_MSG
20547c478bd9Sstevel@tonic-gatedivert(0)
20557c478bd9Sstevel@tonic-gate
20567c478bd9Sstevel@tonic-gate######################################################################
20577c478bd9Sstevel@tonic-gate### Rcpt_ok: is the recipient ok?
20587c478bd9Sstevel@tonic-gatednl input: recipient address (RCPT TO)
20597c478bd9Sstevel@tonic-gatednl output: see explanation at call
20607c478bd9Sstevel@tonic-gate######################################################################
20617c478bd9Sstevel@tonic-gateSRcpt_ok
20627c478bd9Sstevel@tonic-gateifdef(`_LOOSE_RELAY_CHECK_',`dnl
20637c478bd9Sstevel@tonic-gateR$*			$: $>CanonAddr $1
20647c478bd9Sstevel@tonic-gateR$* < @ $* . >		$1 < @ $2 >			strip trailing dots',
20657c478bd9Sstevel@tonic-gate`R$*			$: $>ParseRecipient $1		strip relayable hosts')
20667c478bd9Sstevel@tonic-gate
20677c478bd9Sstevel@tonic-gateifdef(`_BESTMX_IS_LOCAL_',`dnl
20687c478bd9Sstevel@tonic-gateifelse(_BESTMX_IS_LOCAL_, `', `dnl
20697c478bd9Sstevel@tonic-gate# unlimited bestmx
20707c478bd9Sstevel@tonic-gateR$* < @ $* > $*			$: $1 < @ $2 @@ $(bestmx $2 $) > $3',
20717c478bd9Sstevel@tonic-gate`dnl
20727c478bd9Sstevel@tonic-gate# limit bestmx to $=B
20737c478bd9Sstevel@tonic-gateR$* < @ $* $=B > $*		$: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4')
20747c478bd9Sstevel@tonic-gateR$* $=O $* < @ $* @@ $=w . > $*	$@ $>"Rcpt_ok" $1 $2 $3
20757c478bd9Sstevel@tonic-gateR$* < @ $* @@ $=w . > $*	$: $1 < @ $3 > $4
20767c478bd9Sstevel@tonic-gateR$* < @ $* @@ $* > $*		$: $1 < @ $2 > $4')
20777c478bd9Sstevel@tonic-gate
20787c478bd9Sstevel@tonic-gateifdef(`_BLACKLIST_RCPT_',`dnl
20797c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
20807c478bd9Sstevel@tonic-gate# blacklist local users or any host from receiving mail
20817c478bd9Sstevel@tonic-gateR$*			$: <?> $1
20827c478bd9Sstevel@tonic-gatednl user is now tagged with @ to be consistent with check_mail
20837c478bd9Sstevel@tonic-gatednl and to distinguish users from hosts (com would be host, com@ would be user)
20847c478bd9Sstevel@tonic-gateR<?> $+ < @ $=w >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <U:$1@> <D:$2>
20857c478bd9Sstevel@tonic-gateR<?> $+ < @ $* >	$: <> <$1 < @ $2 >> $| <F:$1@$2> <D:$2>
20867c478bd9Sstevel@tonic-gateR<?> $+			$: <> <$1> $| <U:$1@>
20877c478bd9Sstevel@tonic-gatednl $| is used as delimiter, otherwise false matches may occur: <user<@domain>>
20887c478bd9Sstevel@tonic-gatednl will only return user<@domain when "reversing" the args
20897c478bd9Sstevel@tonic-gateR<> <$*> $| <$+>	$: <@> <$1> $| $>SearchList <+ To> $| <$2> <>
20907c478bd9Sstevel@tonic-gateR<@> <$*> $| <$*>	$: <$2> <$1>		reverse result
20917c478bd9Sstevel@tonic-gateR<?> <$*>		$: @ $1		mark address as no match
20927c478bd9Sstevel@tonic-gatednl we may have to filter here because otherwise some RHSs
20937c478bd9Sstevel@tonic-gatednl would be interpreted as generic error messages...
20947c478bd9Sstevel@tonic-gatednl error messages should be "tagged" by prefixing them with error: !
20957c478bd9Sstevel@tonic-gatednl that would make a lot of things easier.
20967c478bd9Sstevel@tonic-gateR<$={Accept}> <$*>	$: @ $2		mark address as no match
20977c478bd9Sstevel@tonic-gateifdef(`_ACCESS_SKIP_', `dnl
20987c478bd9Sstevel@tonic-gateR<SKIP> <$*>		$: @ $1		mark address as no match', `dnl')
20997c478bd9Sstevel@tonic-gateifdef(`_DELAY_COMPAT_8_10_',`dnl
21007c478bd9Sstevel@tonic-gatednl compatility with 8.11/8.10:
21017c478bd9Sstevel@tonic-gatednl we have to filter these because otherwise they would be interpreted
21027c478bd9Sstevel@tonic-gatednl as generic error message...
21037c478bd9Sstevel@tonic-gatednl error messages should be "tagged" by prefixing them with error: !
21047c478bd9Sstevel@tonic-gatednl that would make a lot of things easier.
21057c478bd9Sstevel@tonic-gatednl maybe we should stop checks already here (if SPAM_xyx)?
21067c478bd9Sstevel@tonic-gateR<$={SpamTag}> <$*>	$: @ $2		mark address as no match')
21077c478bd9Sstevel@tonic-gateR<REJECT> $*		$#error $@ 5.2.1 $: confRCPTREJ_MSG
21087c478bd9Sstevel@tonic-gateR<DISCARD> $*		$#discard $: discard
21097c478bd9Sstevel@tonic-gateR<QUARANTINE:$+> $*	$#error $@ quarantine $: $1
21107c478bd9Sstevel@tonic-gatednl error tag
21117c478bd9Sstevel@tonic-gateR<ERROR:$-.$-.$-:$+> $*		$#error $@ $1.$2.$3 $: $4
21127c478bd9Sstevel@tonic-gateR<ERROR:$+> $*		$#error $: $1
21137c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<_ATMPF_> $*		$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
21147c478bd9Sstevel@tonic-gatednl generic error from access map
21157c478bd9Sstevel@tonic-gateR<$+> $*		$#error $: $1		error from access db
21167c478bd9Sstevel@tonic-gateR@ $*			$1		remove mark', `dnl')', `dnl')
21177c478bd9Sstevel@tonic-gate
21187c478bd9Sstevel@tonic-gateifdef(`_PROMISCUOUS_RELAY_', `divert(-1)', `dnl')
21197c478bd9Sstevel@tonic-gate# authenticated via TLS?
21207c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>RelayTLS	client authenticated?
21217c478bd9Sstevel@tonic-gateR$* $| $# $+		$# $2			error/ok?
21227c478bd9Sstevel@tonic-gateR$* $| $*		$: $1			no
21237c478bd9Sstevel@tonic-gate
21247c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_Relay_Auth" $&{auth_type}
21257c478bd9Sstevel@tonic-gatednl workspace: localpart<@domain> $| result of Local_Relay_Auth
21267c478bd9Sstevel@tonic-gateR$* $| $# $*		$# $2
21277c478bd9Sstevel@tonic-gatednl if Local_Relay_Auth returns NO then do not check $={TrustAuthMech}
21287c478bd9Sstevel@tonic-gateR$* $| NO		$: $1
21297c478bd9Sstevel@tonic-gateR$* $| $*		$: $1 $| $&{auth_type}
21307c478bd9Sstevel@tonic-gatednl workspace: localpart<@domain> [ $| ${auth_type} ]
21317c478bd9Sstevel@tonic-gatednl empty ${auth_type}?
21327c478bd9Sstevel@tonic-gateR$* $|			$: $1
21337c478bd9Sstevel@tonic-gatednl mechanism ${auth_type} accepted?
21347c478bd9Sstevel@tonic-gatednl use $# to override further tests (delay_checks): see check_rcpt below
21357c478bd9Sstevel@tonic-gateR$* $| $={TrustAuthMech}	$# RELAY
21367c478bd9Sstevel@tonic-gatednl remove ${auth_type}
21377c478bd9Sstevel@tonic-gateR$* $| $*		$: $1
21387c478bd9Sstevel@tonic-gatednl workspace: localpart<@domain> | localpart
21397c478bd9Sstevel@tonic-gateifelse(defn(`_NO_UUCP_'), `r',
21407c478bd9Sstevel@tonic-gate`R$* ! $* < @ $* >	$: <REMOTE> $2 < @ BANG_PATH >
21417c478bd9Sstevel@tonic-gateR$* ! $* 		$: <REMOTE> $2 < @ BANG_PATH >', `dnl')
21427c478bd9Sstevel@tonic-gate# anything terminating locally is ok
21437c478bd9Sstevel@tonic-gateifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
21447c478bd9Sstevel@tonic-gateR$+ < @ $* $=m >	$@ RELAY', `dnl')
21457c478bd9Sstevel@tonic-gateR$+ < @ $=w >		$@ RELAY
21467c478bd9Sstevel@tonic-gateifdef(`_RELAY_HOSTS_ONLY_',
21477c478bd9Sstevel@tonic-gate`R$+ < @ $=R >		$@ RELAY
21487c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
2149*e9af4bc0SJohn Beckifdef(`_RELAY_FULL_ADDR_', `dnl
2150*e9af4bc0SJohn BeckR$+ < @ $+ >		$: <$(access To:$1@$2 $: ? $)> <$1 < @ $2 >>
2151*e9af4bc0SJohn BeckR<?> <$+ < @ $+ >>	$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>',`
2152*e9af4bc0SJohn BeckR$+ < @ $+ >		$: <$(access To:$2 $: ? $)> <$1 < @ $2 >>')
21537c478bd9Sstevel@tonic-gatednl workspace: <Result-of-lookup | ?> <localpart<@domain>>
21547c478bd9Sstevel@tonic-gateR<?> <$+ < @ $+ >>	$: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')',
21557c478bd9Sstevel@tonic-gate`R$+ < @ $* $=R >	$@ RELAY
21567c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
21577c478bd9Sstevel@tonic-gateifdef(`_RELAY_FULL_ADDR_', `dnl
21587c478bd9Sstevel@tonic-gateR$+ < @ $+ >		$: $1 < @ $2 > $| $>SearchList <+ To> $| <F:$1@$2> <D:$2> <F:$1@> <>
21597c478bd9Sstevel@tonic-gateR$+ < @ $+ > $| <$*>	$: <$3> <$1 <@ $2>>
21607c478bd9Sstevel@tonic-gateR$+ < @ $+ > $| $*	$: <$3> <$1 <@ $2>>',
21617c478bd9Sstevel@tonic-gate`R$+ < @ $+ >		$: $>D <$2> <?> <+ To> <$1 < @ $2 >>')')')
21627c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
21637c478bd9Sstevel@tonic-gatednl workspace: <Result-of-lookup | ?> <localpart<@domain>>
21647c478bd9Sstevel@tonic-gateR<RELAY> $*		$@ RELAY
21657c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
21667c478bd9Sstevel@tonic-gateR<$*> <$*>		$: $2',`dnl')
21677c478bd9Sstevel@tonic-gate
21687c478bd9Sstevel@tonic-gate
21697c478bd9Sstevel@tonic-gateifdef(`_RELAY_MX_SERVED_', `dnl
21707c478bd9Sstevel@tonic-gate# allow relaying for hosts which we MX serve
21717c478bd9Sstevel@tonic-gateR$+ < @ $+ >		$: < : $(mxserved $2 $) : > $1 < @ $2 >
21727c478bd9Sstevel@tonic-gatednl this must not necessarily happen if the client is checked first...
21737c478bd9Sstevel@tonic-gateR< : $* <TEMP> : > $*	$#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1
21747c478bd9Sstevel@tonic-gateR<$* : $=w . : $*> $*	$@ RELAY
21757c478bd9Sstevel@tonic-gateR< : $* : > $*		$: $2',
21767c478bd9Sstevel@tonic-gate`dnl')
21777c478bd9Sstevel@tonic-gate
21787c478bd9Sstevel@tonic-gate# check for local user (i.e. unqualified address)
21797c478bd9Sstevel@tonic-gateR$*			$: <?> $1
21807c478bd9Sstevel@tonic-gateR<?> $* < @ $+ >	$: <REMOTE> $1 < @ $2 >
21817c478bd9Sstevel@tonic-gate# local user is ok
21827c478bd9Sstevel@tonic-gatednl is it really? the standard requires user@domain, not just user
21837c478bd9Sstevel@tonic-gatednl but we should accept it anyway (maybe making it an option:
21847c478bd9Sstevel@tonic-gatednl RequireFQDN ?)
21857c478bd9Sstevel@tonic-gatednl postmaster must be accepted without domain (DRUMS)
21867c478bd9Sstevel@tonic-gateifdef(`_REQUIRE_QUAL_RCPT_', `dnl
21877c478bd9Sstevel@tonic-gateR<?> postmaster		$@ OK
21887c478bd9Sstevel@tonic-gate# require qualified recipient?
21897c478bd9Sstevel@tonic-gatednl prepend daemon_flags
21907c478bd9Sstevel@tonic-gateR<?> $+			$: $&{daemon_flags} $| <?> $1
21917c478bd9Sstevel@tonic-gatednl workspace: ${daemon_flags} $| <?> localpart
21927c478bd9Sstevel@tonic-gatednl do not allow these at all or only from local systems?
21937c478bd9Sstevel@tonic-gatednl r flag? add client_name
21947c478bd9Sstevel@tonic-gateR$* r $* $| <?> $+	$: < ? $&{client_name} > <?> $3
21957c478bd9Sstevel@tonic-gatednl no r flag: relay to local user (only local part)
21967c478bd9Sstevel@tonic-gate# no qualified recipient required
21977c478bd9Sstevel@tonic-gateR$* $| <?> $+		$@ RELAY
21987c478bd9Sstevel@tonic-gatednl client_name is empty
21997c478bd9Sstevel@tonic-gateR<?> <?> $+		$@ RELAY
22007c478bd9Sstevel@tonic-gatednl client_name is local
22017c478bd9Sstevel@tonic-gateR<? $=w> <?> $+		$@ RELAY
22027c478bd9Sstevel@tonic-gatednl client_name is not local
22037c478bd9Sstevel@tonic-gateR<? $+> $+		$#error $@ 5.5.4 $: "553 Domain name required"', `dnl
22047c478bd9Sstevel@tonic-gatednl no qualified recipient required
22057c478bd9Sstevel@tonic-gateR<?> $+			$@ RELAY')
22067c478bd9Sstevel@tonic-gatednl it is a remote user: remove mark and then check client
22077c478bd9Sstevel@tonic-gateR<$+> $*		$: $2
22087c478bd9Sstevel@tonic-gatednl currently the recipient address is not used below
22097c478bd9Sstevel@tonic-gate
22107c478bd9Sstevel@tonic-gate######################################################################
22117c478bd9Sstevel@tonic-gate### Relay_ok: is the relay/sender ok?
22127c478bd9Sstevel@tonic-gatednl input: ignored
22137c478bd9Sstevel@tonic-gatednl output: see explanation at call
22147c478bd9Sstevel@tonic-gate######################################################################
22157c478bd9Sstevel@tonic-gateSRelay_ok
22167c478bd9Sstevel@tonic-gate# anything originating locally is ok
22177c478bd9Sstevel@tonic-gate# check IP address
22187c478bd9Sstevel@tonic-gateR$*			$: $&{client_addr}
22197c478bd9Sstevel@tonic-gateR$@			$@ RELAY		originated locally
22207c478bd9Sstevel@tonic-gateR0			$@ RELAY		originated locally
22217c478bd9Sstevel@tonic-gateR127.0.0.1		$@ RELAY		originated locally
22227c478bd9Sstevel@tonic-gateRIPv6:::1		$@ RELAY		originated locally
22237c478bd9Sstevel@tonic-gateR$=R $*			$@ RELAY		relayable IP address
22247c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
22257c478bd9Sstevel@tonic-gateR$*			$: $>A <$1> <?> <+ Connect> <$1>
22267c478bd9Sstevel@tonic-gateR<RELAY> $* 		$@ RELAY		relayable IP address
22277c478bd9Sstevel@tonic-gateifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
22287c478bd9Sstevel@tonic-gatednl this will cause rejections in cases like:
22297c478bd9Sstevel@tonic-gatednl Connect:My.Host.Domain	RELAY
22307c478bd9Sstevel@tonic-gatednl Connect:My.Net		REJECT
22317c478bd9Sstevel@tonic-gatednl since in check_relay client_name is checked before client_addr
22327c478bd9Sstevel@tonic-gateR<REJECT> $* 		$@ REJECT		rejected IP address')
22337c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<_ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
22347c478bd9Sstevel@tonic-gateR<$*> <$*>		$: $2', `dnl')
22357c478bd9Sstevel@tonic-gateR$*			$: [ $1 ]		put brackets around it...
22367c478bd9Sstevel@tonic-gateR$=w			$@ RELAY		... and see if it is local
22377c478bd9Sstevel@tonic-gate
22387c478bd9Sstevel@tonic-gateifdef(`_RELAY_DB_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
22397c478bd9Sstevel@tonic-gateifdef(`_RELAY_LOCAL_FROM_', `define(`_RELAY_MAIL_FROM_', `1')')dnl
22407c478bd9Sstevel@tonic-gateifdef(`_RELAY_MAIL_FROM_', `dnl
22417c478bd9Sstevel@tonic-gatednl input: {client_addr} or something "broken"
22427c478bd9Sstevel@tonic-gatednl just throw the input away; we do not need it.
22437c478bd9Sstevel@tonic-gate# check whether FROM is allowed to use system as relay
22447c478bd9Sstevel@tonic-gateR$*			$: <?> $>CanonAddr $&f
22457c478bd9Sstevel@tonic-gateR<?> $+ < @ $+ . >	<?> $1 < @ $2 >		remove trailing dot
22467c478bd9Sstevel@tonic-gateifdef(`_RELAY_LOCAL_FROM_', `dnl
22477c478bd9Sstevel@tonic-gate# check whether local FROM is ok
22487c478bd9Sstevel@tonic-gateR<?> $+ < @ $=w >	$@ RELAY		FROM local', `dnl')
22497c478bd9Sstevel@tonic-gateifdef(`_RELAY_DB_FROM_', `dnl
22507c478bd9Sstevel@tonic-gateR<?> $+ < @ $+ >	$: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
22517c478bd9Sstevel@tonic-gateR<@> <RELAY>		$@ RELAY		RELAY FROM sender ok
22527c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<@> <_ATMPF_>		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
22537c478bd9Sstevel@tonic-gate', `dnl
22547c478bd9Sstevel@tonic-gateifdef(`_RELAY_DB_FROM_DOMAIN_',
22557c478bd9Sstevel@tonic-gate`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
22567c478bd9Sstevel@tonic-gate')',
22577c478bd9Sstevel@tonic-gate`dnl')
22587c478bd9Sstevel@tonic-gatednl')', `dnl')
22597c478bd9Sstevel@tonic-gatednl notice: the rulesets above do not leave a unique workspace behind.
22607c478bd9Sstevel@tonic-gatednl it does not matter in this case because the following rule ignores
22617c478bd9Sstevel@tonic-gatednl the input. otherwise these rules must "clean up" the workspace.
22627c478bd9Sstevel@tonic-gate
22637c478bd9Sstevel@tonic-gate# check client name: first: did it resolve?
22647c478bd9Sstevel@tonic-gatednl input: ignored
22657c478bd9Sstevel@tonic-gateR$*			$: < $&{client_resolve} >
22667c478bd9Sstevel@tonic-gateR<TEMP>			$#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr}
22677c478bd9Sstevel@tonic-gateR<FORGED>		$#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name}
22687c478bd9Sstevel@tonic-gateR<FAIL>			$#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
22697c478bd9Sstevel@tonic-gatednl ${client_resolve} should be OK, so go ahead
22707c478bd9Sstevel@tonic-gateR$*			$: <@> $&{client_name}
22717c478bd9Sstevel@tonic-gatednl should not be necessary since it has been done for client_addr already
22727c478bd9Sstevel@tonic-gatednl this rule actually may cause a problem if {client_name} resolves to ""
22737c478bd9Sstevel@tonic-gatednl however, this should not happen since the forward lookup should fail
22747c478bd9Sstevel@tonic-gatednl and {client_resolve} should be TEMP or FAIL.
22757c478bd9Sstevel@tonic-gatednl nevertheless, removing the rule doesn't hurt.
22767c478bd9Sstevel@tonic-gatednl R<@>			$@ RELAY
22777c478bd9Sstevel@tonic-gatednl workspace: <@> ${client_name} (not empty)
22787c478bd9Sstevel@tonic-gate# pass to name server to make hostname canonical
22797c478bd9Sstevel@tonic-gateR<@> $* $=P 		$:<?>  $1 $2
22807c478bd9Sstevel@tonic-gateR<@> $+			$:<?>  $[ $1 $]
22817c478bd9Sstevel@tonic-gatednl workspace: <?> ${client_name} (canonified)
22827c478bd9Sstevel@tonic-gateR$* .			$1			strip trailing dots
22837c478bd9Sstevel@tonic-gateifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
22847c478bd9Sstevel@tonic-gateR<?> $* $=m		$@ RELAY', `dnl')
22857c478bd9Sstevel@tonic-gateR<?> $=w		$@ RELAY
22867c478bd9Sstevel@tonic-gateifdef(`_RELAY_HOSTS_ONLY_',
22877c478bd9Sstevel@tonic-gate`R<?> $=R		$@ RELAY
22887c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
22897c478bd9Sstevel@tonic-gateR<?> $*			$: <$(access Connect:$1 $: ? $)> <$1>
22907c478bd9Sstevel@tonic-gateR<?> <$*>		$: <$(access $1 $: ? $)> <$1>',`dnl')',
22917c478bd9Sstevel@tonic-gate`R<?> $* $=R			$@ RELAY
22927c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
22937c478bd9Sstevel@tonic-gateR<?> $*			$: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
22947c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
22957c478bd9Sstevel@tonic-gateR<RELAY> $*		$@ RELAY
22967c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `R<$* _ATMPF_> $*		$#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
22977c478bd9Sstevel@tonic-gateR<$*> <$*>		$: $2',`dnl')
22987c478bd9Sstevel@tonic-gatednl end of _PROMISCUOUS_RELAY_
22997c478bd9Sstevel@tonic-gatedivert(0)
23007c478bd9Sstevel@tonic-gateifdef(`_DELAY_CHECKS_',`dnl
23017c478bd9Sstevel@tonic-gate# turn a canonical address in the form user<@domain>
23027c478bd9Sstevel@tonic-gate# qualify unqual. addresses with $j
23037c478bd9Sstevel@tonic-gatednl it might have been only user (without <@domain>)
23047c478bd9Sstevel@tonic-gateSFullAddr
23057c478bd9Sstevel@tonic-gateR$* <@ $+ . >		$1 <@ $2 >
23067c478bd9Sstevel@tonic-gateR$* <@ $* >		$@ $1 <@ $2 >
23077c478bd9Sstevel@tonic-gateR$+			$@ $1 <@ $j >
23087c478bd9Sstevel@tonic-gate
23097c478bd9Sstevel@tonic-gateSDelay_TLS_Clt
23107c478bd9Sstevel@tonic-gate# authenticated?
23117c478bd9Sstevel@tonic-gatednl code repeated here from Basic_check_mail
23127c478bd9Sstevel@tonic-gatednl only called from check_rcpt in delay mode if checkrcpt returns $#
23137c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
23147c478bd9Sstevel@tonic-gateR$* $| $#$+		$#$2
23157c478bd9Sstevel@tonic-gatednl return result from checkrcpt
23167c478bd9Sstevel@tonic-gateR$* $| $*		$# $1
23177c478bd9Sstevel@tonic-gateR$*			$# $1
23187c478bd9Sstevel@tonic-gate
23197c478bd9Sstevel@tonic-gateSDelay_TLS_Clt2
23207c478bd9Sstevel@tonic-gate# authenticated?
23217c478bd9Sstevel@tonic-gatednl code repeated here from Basic_check_mail
23227c478bd9Sstevel@tonic-gatednl only called from check_rcpt in delay mode if stopping due to Friend/Hater
23237c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"tls_client" $&{verify} $| MAIL
23247c478bd9Sstevel@tonic-gateR$* $| $#$+		$#$2
23257c478bd9Sstevel@tonic-gatednl return result from friend/hater check
23267c478bd9Sstevel@tonic-gateR$* $| $*		$@ $1
23277c478bd9Sstevel@tonic-gateR$*			$@ $1
23287c478bd9Sstevel@tonic-gate
23297c478bd9Sstevel@tonic-gate# call all necessary rulesets
23307c478bd9Sstevel@tonic-gateScheck_rcpt
23317c478bd9Sstevel@tonic-gatednl this test should be in the Basic_check_rcpt ruleset
23327c478bd9Sstevel@tonic-gatednl which is the correct DSN code?
23337c478bd9Sstevel@tonic-gate# R$@			$#error $@ 5.1.3 $: "553 Recipient address required"
23347c478bd9Sstevel@tonic-gate
23357c478bd9Sstevel@tonic-gateR$+			$: $1 $| $>checkrcpt $1
23367c478bd9Sstevel@tonic-gatednl now we can simply stop checks by returning "$# xyz" instead of just "ok"
23377c478bd9Sstevel@tonic-gatednl on error (or discard) stop now
23387c478bd9Sstevel@tonic-gateR$+ $| $#error $*	$#error $2
23397c478bd9Sstevel@tonic-gateR$+ $| $#discard $*	$#discard $2
23407c478bd9Sstevel@tonic-gatednl otherwise call tls_client; see above
23417c478bd9Sstevel@tonic-gateR$+ $| $#$*		$@ $>"Delay_TLS_Clt" $2
23427c478bd9Sstevel@tonic-gateR$+ $| $*		$: <?> $>FullAddr $>CanonAddr $1
23437c478bd9Sstevel@tonic-gateifdef(`_SPAM_FH_',
23447c478bd9Sstevel@tonic-gate`dnl lookup user@ and user@address
23457c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `',
23467c478bd9Sstevel@tonic-gate`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
23477c478bd9Sstevel@tonic-gate')')dnl
23487c478bd9Sstevel@tonic-gatednl one of the next two rules is supposed to match
23497c478bd9Sstevel@tonic-gatednl this code has been copied from BLACKLIST... etc
23507c478bd9Sstevel@tonic-gatednl and simplified by omitting some < >.
23517c478bd9Sstevel@tonic-gateR<?> $+ < @ $=w >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
23527c478bd9Sstevel@tonic-gateR<?> $+ < @ $* >	$: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
23537c478bd9Sstevel@tonic-gatednl R<?>		$@ something_is_very_wrong_here
23547c478bd9Sstevel@tonic-gate# lookup the addresses only with Spam tag
23557c478bd9Sstevel@tonic-gateR<> $* $| <$+>		$: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
23567c478bd9Sstevel@tonic-gateR<@> $* $| $*		$: $2 $1		reverse result
23577c478bd9Sstevel@tonic-gatednl', `dnl')
23587c478bd9Sstevel@tonic-gateifdef(`_SPAM_FRIEND_',
23597c478bd9Sstevel@tonic-gate`# is the recipient a spam friend?
23607c478bd9Sstevel@tonic-gateifdef(`_SPAM_HATER_',
23617c478bd9Sstevel@tonic-gate	`errprint(`*** ERROR: define either Hater or Friend -- not both.
23627c478bd9Sstevel@tonic-gate')', `dnl')
23637c478bd9Sstevel@tonic-gateR<FRIEND> $+		$@ $>"Delay_TLS_Clt2" SPAMFRIEND
23647c478bd9Sstevel@tonic-gateR<$*> $+		$: $2',
23657c478bd9Sstevel@tonic-gate`dnl')
23667c478bd9Sstevel@tonic-gateifdef(`_SPAM_HATER_',
23677c478bd9Sstevel@tonic-gate`# is the recipient no spam hater?
23687c478bd9Sstevel@tonic-gateR<HATER> $+		$: $1			spam hater: continue checks
23697c478bd9Sstevel@tonic-gateR<$*> $+		$@ $>"Delay_TLS_Clt2" NOSPAMHATER	everyone else: stop
23707c478bd9Sstevel@tonic-gatednl',`dnl')
2371058561cbSjbeck
23727c478bd9Sstevel@tonic-gatednl run further checks: check_mail
23737c478bd9Sstevel@tonic-gatednl should we "clean up" $&f?
23747c478bd9Sstevel@tonic-gateifdef(`_FFR_MAIL_MACRO',
23757c478bd9Sstevel@tonic-gate`R$*			$: $1 $| $>checkmail $&{mail_from}',
23767c478bd9Sstevel@tonic-gate`R$*			$: $1 $| $>checkmail <$&f>')
23777c478bd9Sstevel@tonic-gatednl recipient (canonical format) $| result of checkmail
23787c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
23797c478bd9Sstevel@tonic-gatednl run further checks: check_relay
23807c478bd9Sstevel@tonic-gateR$* $| $*		$: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
23817c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
23827c478bd9Sstevel@tonic-gateR$* $| $*		$: $1
23837c478bd9Sstevel@tonic-gate', `dnl')
23847c478bd9Sstevel@tonic-gate
2385058561cbSjbeckifdef(`_BLOCK_BAD_HELO_', `dnl
2386058561cbSjbeckR$*			$: $1 $| <$&{auth_authen}>	Get auth info
2387058561cbSjbeckdnl Bypass the test for users who have authenticated.
2388058561cbSjbeckR$* $| <$+>		$: $1				skip if auth
2389058561cbSjbeckR$* $| <$*>		$: $1 $| <$&{client_addr}> [$&s]	Get connection info
2390058561cbSjbeckdnl Bypass for local clients -- IP address starts with $=R
2391058561cbSjbeckR$* $| <$=R $*> [$*]	$: $1				skip if local client
2392058561cbSjbeckdnl Bypass a "sendmail -bs" session, which use 0 for client ip address
2393058561cbSjbeckR$* $| <0> [$*]		$: $1				skip if sendmail -bs
2394058561cbSjbeckdnl Reject our IP - assumes "[ip]" is in class $=w
2395058561cbSjbeckR$* $| <$*> $=w		$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2396058561cbSjbeckdnl Reject our hostname
2397058561cbSjbeckR$* $| <$*> [$=w]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2398058561cbSjbeckdnl Pass anything else with a "." in the domain parameter
2399058561cbSjbeckR$* $| <$*> [$+.$+]	$: $1				qualified domain ok
2400058561cbSjbeckdnl Reject if there was no "." or only an initial or final "."
2401058561cbSjbeckR$* $| <$*> [$*]	$#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
2402058561cbSjbeckdnl Clean up the workspace
2403058561cbSjbeckR$* $| $*		$: $1
2404058561cbSjbeck', `dnl')
2405058561cbSjbeck
24067c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
24077c478bd9Sstevel@tonic-gate######################################################################
24087c478bd9Sstevel@tonic-gate###  F: LookUpFull -- search for an entry in access database
24097c478bd9Sstevel@tonic-gate###
24107c478bd9Sstevel@tonic-gate###	lookup of full key (which should be an address) and
24117c478bd9Sstevel@tonic-gate###	variations if +detail exists: +* and without +detail
24127c478bd9Sstevel@tonic-gate###
24137c478bd9Sstevel@tonic-gate###	Parameters:
24147c478bd9Sstevel@tonic-gate###		<$1> -- key
24157c478bd9Sstevel@tonic-gate###		<$2> -- default (what to return if not found in db)
24167c478bd9Sstevel@tonic-gatednl			must not be empty
24177c478bd9Sstevel@tonic-gate###		<$3> -- mark (must be <(!|+) single-token>)
24187c478bd9Sstevel@tonic-gate###			! does lookup only with tag
24197c478bd9Sstevel@tonic-gate###			+ does lookup with and without tag
24207c478bd9Sstevel@tonic-gate###		<$4> -- passthru (additional data passed unchanged through)
24217c478bd9Sstevel@tonic-gatednl returns:		<default> <passthru>
24227c478bd9Sstevel@tonic-gatednl 			<result> <passthru>
24237c478bd9Sstevel@tonic-gate######################################################################
24247c478bd9Sstevel@tonic-gate
24257c478bd9Sstevel@tonic-gateSF
24267c478bd9Sstevel@tonic-gatednl workspace: <key> <def> <o tag> <thru>
24277c478bd9Sstevel@tonic-gatednl full lookup
24287c478bd9Sstevel@tonic-gatednl    2    3  4    5
24297c478bd9Sstevel@tonic-gateR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
24307c478bd9Sstevel@tonic-gatednl no match, try without tag
24317c478bd9Sstevel@tonic-gatednl   1    2      3    4
24327c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
24337c478bd9Sstevel@tonic-gatednl no match, +detail: try +*
24347c478bd9Sstevel@tonic-gatednl   1    2    3    4    5  6    7
24357c478bd9Sstevel@tonic-gateR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
24367c478bd9Sstevel@tonic-gate			$: <$(access $6`'_TAG_DELIM_`'$1+*@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
24377c478bd9Sstevel@tonic-gatednl no match, +detail: try +* without tag
24387c478bd9Sstevel@tonic-gatednl   1    2    3    4      5    6
24397c478bd9Sstevel@tonic-gateR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
24407c478bd9Sstevel@tonic-gate			$: <$(access $1+*@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
24417c478bd9Sstevel@tonic-gatednl no match, +detail: try without +detail
24427c478bd9Sstevel@tonic-gatednl   1    2    3    4    5  6    7
24437c478bd9Sstevel@tonic-gateR<?> <$+ + $* @ $+> <$*> <$- $-> <$*>
24447c478bd9Sstevel@tonic-gate			$: <$(access $6`'_TAG_DELIM_`'$1@$3 $: ? $)> <$1+$2@$3> <$4> <$5 $6> <$7>
24457c478bd9Sstevel@tonic-gatednl no match, +detail: try without +detail and without tag
24467c478bd9Sstevel@tonic-gatednl   1    2    3    4      5    6
24477c478bd9Sstevel@tonic-gateR<?> <$+ + $* @ $+> <$*> <+ $-> <$*>
24487c478bd9Sstevel@tonic-gate			$: <$(access $1@$3 $: ? $)> <$1+$2@$3> <$4> <+ $5> <$6>
24497c478bd9Sstevel@tonic-gatednl no match, return <default> <passthru>
24507c478bd9Sstevel@tonic-gatednl   1    2    3  4    5
24517c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
24527c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
24537c478bd9Sstevel@tonic-gatednl            2    3  4    5
24547c478bd9Sstevel@tonic-gateR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
24557c478bd9Sstevel@tonic-gatednl match, return <match> <passthru>
24567c478bd9Sstevel@tonic-gatednl    2    3  4    5
24577c478bd9Sstevel@tonic-gateR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
24587c478bd9Sstevel@tonic-gate
24597c478bd9Sstevel@tonic-gate######################################################################
24607c478bd9Sstevel@tonic-gate###  E: LookUpExact -- search for an entry in access database
24617c478bd9Sstevel@tonic-gate###
24627c478bd9Sstevel@tonic-gate###	Parameters:
24637c478bd9Sstevel@tonic-gate###		<$1> -- key
24647c478bd9Sstevel@tonic-gate###		<$2> -- default (what to return if not found in db)
24657c478bd9Sstevel@tonic-gatednl			must not be empty
24667c478bd9Sstevel@tonic-gate###		<$3> -- mark (must be <(!|+) single-token>)
24677c478bd9Sstevel@tonic-gate###			! does lookup only with tag
24687c478bd9Sstevel@tonic-gate###			+ does lookup with and without tag
24697c478bd9Sstevel@tonic-gate###		<$4> -- passthru (additional data passed unchanged through)
24707c478bd9Sstevel@tonic-gatednl returns:		<default> <passthru>
24717c478bd9Sstevel@tonic-gatednl 			<result> <passthru>
24727c478bd9Sstevel@tonic-gate######################################################################
24737c478bd9Sstevel@tonic-gate
24747c478bd9Sstevel@tonic-gateSE
24757c478bd9Sstevel@tonic-gatednl    2    3  4    5
24767c478bd9Sstevel@tonic-gateR<$*> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
24777c478bd9Sstevel@tonic-gatednl no match, try without tag
24787c478bd9Sstevel@tonic-gatednl   1    2      3    4
24797c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
24807c478bd9Sstevel@tonic-gatednl no match, return default passthru
24817c478bd9Sstevel@tonic-gatednl   1    2    3  4    5
24827c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
24837c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
24847c478bd9Sstevel@tonic-gatednl            2    3  4    5
24857c478bd9Sstevel@tonic-gateR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
24867c478bd9Sstevel@tonic-gatednl match, return <match> <passthru>
24877c478bd9Sstevel@tonic-gatednl    2    3  4    5
24887c478bd9Sstevel@tonic-gateR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
24897c478bd9Sstevel@tonic-gate
24907c478bd9Sstevel@tonic-gate######################################################################
24917c478bd9Sstevel@tonic-gate###  U: LookUpUser -- search for an entry in access database
24927c478bd9Sstevel@tonic-gate###
24937c478bd9Sstevel@tonic-gate###	lookup of key (which should be a local part) and
24947c478bd9Sstevel@tonic-gate###	variations if +detail exists: +* and without +detail
24957c478bd9Sstevel@tonic-gate###
24967c478bd9Sstevel@tonic-gate###	Parameters:
24977c478bd9Sstevel@tonic-gate###		<$1> -- key (user@)
24987c478bd9Sstevel@tonic-gate###		<$2> -- default (what to return if not found in db)
24997c478bd9Sstevel@tonic-gatednl			must not be empty
25007c478bd9Sstevel@tonic-gate###		<$3> -- mark (must be <(!|+) single-token>)
25017c478bd9Sstevel@tonic-gate###			! does lookup only with tag
25027c478bd9Sstevel@tonic-gate###			+ does lookup with and without tag
25037c478bd9Sstevel@tonic-gate###		<$4> -- passthru (additional data passed unchanged through)
25047c478bd9Sstevel@tonic-gatednl returns:		<default> <passthru>
25057c478bd9Sstevel@tonic-gatednl 			<result> <passthru>
25067c478bd9Sstevel@tonic-gate######################################################################
25077c478bd9Sstevel@tonic-gate
25087c478bd9Sstevel@tonic-gateSU
25097c478bd9Sstevel@tonic-gatednl user lookups are always with trailing @
25107c478bd9Sstevel@tonic-gatednl    2    3  4    5
25117c478bd9Sstevel@tonic-gateR<$+> <$*> <$- $-> <$*>		$: <$(access $4`'_TAG_DELIM_`'$1 $: ? $)> <$1> <$2> <$3 $4> <$5>
25127c478bd9Sstevel@tonic-gatednl no match, try without tag
25137c478bd9Sstevel@tonic-gatednl   1    2      3    4
25147c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <+ $-> <$*>	$: <$(access $1 $: ? $)> <$1> <$2> <+ $3> <$4>
25157c478bd9Sstevel@tonic-gatednl do not remove the @ from the lookup:
25167c478bd9Sstevel@tonic-gatednl it is part of the +detail@ which is omitted for the lookup
25177c478bd9Sstevel@tonic-gatednl no match, +detail: try +*
25187c478bd9Sstevel@tonic-gatednl   1    2      3    4  5    6
25197c478bd9Sstevel@tonic-gateR<?> <$+ + $* @> <$*> <$- $-> <$*>
25207c478bd9Sstevel@tonic-gate			$: <$(access $5`'_TAG_DELIM_`'$1+*@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
25217c478bd9Sstevel@tonic-gatednl no match, +detail: try +* without tag
25227c478bd9Sstevel@tonic-gatednl   1    2      3      4    5
25237c478bd9Sstevel@tonic-gateR<?> <$+ + $* @> <$*> <+ $-> <$*>
25247c478bd9Sstevel@tonic-gate			$: <$(access $1+*@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
25257c478bd9Sstevel@tonic-gatednl no match, +detail: try without +detail
25267c478bd9Sstevel@tonic-gatednl   1    2      3    4  5    6
25277c478bd9Sstevel@tonic-gateR<?> <$+ + $* @> <$*> <$- $-> <$*>
25287c478bd9Sstevel@tonic-gate			$: <$(access $5`'_TAG_DELIM_`'$1@ $: ? $)> <$1+$2@> <$3> <$4 $5> <$6>
25297c478bd9Sstevel@tonic-gatednl no match, +detail: try without +detail and without tag
25307c478bd9Sstevel@tonic-gatednl   1    2      3      4    5
25317c478bd9Sstevel@tonic-gateR<?> <$+ + $* @> <$*> <+ $-> <$*>
25327c478bd9Sstevel@tonic-gate			$: <$(access $1@ $: ? $)> <$1+$2@> <$3> <+ $4> <$5>
25337c478bd9Sstevel@tonic-gatednl no match, return <default> <passthru>
25347c478bd9Sstevel@tonic-gatednl   1    2    3  4    5
25357c478bd9Sstevel@tonic-gateR<?> <$+> <$*> <$- $-> <$*>	$@ <$2> <$5>
25367c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
25377c478bd9Sstevel@tonic-gatednl            2    3  4    5
25387c478bd9Sstevel@tonic-gateR<$+ _ATMPF_> <$*> <$- $-> <$*>	$@ <_ATMPF_> <$5>', `dnl')
25397c478bd9Sstevel@tonic-gatednl match, return <match> <passthru>
25407c478bd9Sstevel@tonic-gatednl    2    3  4    5
25417c478bd9Sstevel@tonic-gateR<$+> <$*> <$- $-> <$*>		$@ <$1> <$5>
25427c478bd9Sstevel@tonic-gate
25437c478bd9Sstevel@tonic-gate######################################################################
25447c478bd9Sstevel@tonic-gate###  SearchList: search a list of items in the access map
25457c478bd9Sstevel@tonic-gate###	Parameters:
25467c478bd9Sstevel@tonic-gate###		<exact tag> $| <mark:address> <mark:address> ... <>
25477c478bd9Sstevel@tonic-gatednl	maybe we should have a @ (again) in front of the mark to
25487c478bd9Sstevel@tonic-gatednl	avoid errorneous matches (with error messages?)
25497c478bd9Sstevel@tonic-gatednl	if we can make sure that tag is always a single token
25507c478bd9Sstevel@tonic-gatednl	then we can omit the delimiter $|, otherwise we need it
25517c478bd9Sstevel@tonic-gatednl	to avoid errorneous matchs (first rule: D: if there
25527c478bd9Sstevel@tonic-gatednl	is that mark somewhere in the list, it will be taken).
25537c478bd9Sstevel@tonic-gatednl	moreover, we can do some tricks to enforce lookup with
25547c478bd9Sstevel@tonic-gatednl	the tag only, e.g.:
25557c478bd9Sstevel@tonic-gate###	where "exact" is either "+" or "!":
25567c478bd9Sstevel@tonic-gate###	<+ TAG>	lookup with and w/o tag
25577c478bd9Sstevel@tonic-gate###	<! TAG>	lookup with tag
25587c478bd9Sstevel@tonic-gatednl	Warning: + and ! should be in OperatorChars (otherwise there must be
25597c478bd9Sstevel@tonic-gatednl		a blank between them and the tag.
25607c478bd9Sstevel@tonic-gate###	possible values for "mark" are:
25617c478bd9Sstevel@tonic-gate###		D: recursive host lookup (LookUpDomain)
25627c478bd9Sstevel@tonic-gatednl		A: recursive address lookup (LookUpAddress) [not yet required]
25637c478bd9Sstevel@tonic-gate###		E: exact lookup, no modifications
25647c478bd9Sstevel@tonic-gate###		F: full lookup, try user+ext@domain and user@domain
25657c478bd9Sstevel@tonic-gate###		U: user lookup, try user+ext and user (input must have trailing @)
25667c478bd9Sstevel@tonic-gate###	return: <RHS of lookup> or <?> (not found)
25677c478bd9Sstevel@tonic-gate######################################################################
25687c478bd9Sstevel@tonic-gate
25697c478bd9Sstevel@tonic-gate# class with valid marks for SearchList
25707c478bd9Sstevel@tonic-gatednl if A is activated: add it
25717c478bd9Sstevel@tonic-gateC{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A')
25727c478bd9Sstevel@tonic-gateSSearchList
25737c478bd9Sstevel@tonic-gate# just call the ruleset with the name of the tag... nice trick...
25747c478bd9Sstevel@tonic-gatednl       2       3    4
25757c478bd9Sstevel@tonic-gateR<$+> $| <$={Src}:$*> <$*>	$: <$1> $| <$4> $| $>$2 <$3> <?> <$1> <>
25767c478bd9Sstevel@tonic-gatednl workspace: <o tag> $| <rest> $| <result of lookup> <>
25777c478bd9Sstevel@tonic-gatednl no match and nothing left: return
25787c478bd9Sstevel@tonic-gateR<$+> $| <> $| <?> <>		$@ <?>
25797c478bd9Sstevel@tonic-gatednl no match but something left: continue
25807c478bd9Sstevel@tonic-gateR<$+> $| <$+> $| <?> <>		$@ $>SearchList <$1> $| <$2>
25817c478bd9Sstevel@tonic-gatednl match: return
25827c478bd9Sstevel@tonic-gateR<$+> $| <$*> $| <$+> <>	$@ <$3>
25837c478bd9Sstevel@tonic-gatednl return result from recursive invocation
25847c478bd9Sstevel@tonic-gateR<$+> $| <$+>			$@ <$2>
25857c478bd9Sstevel@tonic-gatednl endif _ACCESS_TABLE_
25867c478bd9Sstevel@tonic-gatedivert(0)
25877c478bd9Sstevel@tonic-gate
25887c478bd9Sstevel@tonic-gate######################################################################
25897c478bd9Sstevel@tonic-gate###  trust_auth: is user trusted to authenticate as someone else?
25907c478bd9Sstevel@tonic-gate###
25917c478bd9Sstevel@tonic-gate###	Parameters:
25927c478bd9Sstevel@tonic-gate###		$1: AUTH= parameter from MAIL command
25937c478bd9Sstevel@tonic-gate######################################################################
25947c478bd9Sstevel@tonic-gate
25957c478bd9Sstevel@tonic-gatednl empty ruleset definition so it can be called
25967c478bd9Sstevel@tonic-gateSLocal_trust_auth
25977c478bd9Sstevel@tonic-gateStrust_auth
25987c478bd9Sstevel@tonic-gateR$*			$: $&{auth_type} $| $1
25997c478bd9Sstevel@tonic-gate# required by RFC 2554 section 4.
26007c478bd9Sstevel@tonic-gateR$@ $| $*		$#error $@ 5.7.1 $: "550 not authenticated"
26017c478bd9Sstevel@tonic-gatednl seems to be useful...
26027c478bd9Sstevel@tonic-gateR$* $| $&{auth_authen}		$@ identical
26037c478bd9Sstevel@tonic-gateR$* $| <$&{auth_authen}>	$@ identical
26047c478bd9Sstevel@tonic-gatednl call user supplied code
26057c478bd9Sstevel@tonic-gateR$* $| $*		$: $1 $| $>"Local_trust_auth" $2
26067c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
26077c478bd9Sstevel@tonic-gatednl default: error
26087c478bd9Sstevel@tonic-gateR$*			$#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{auth_author}
26097c478bd9Sstevel@tonic-gate
26107c478bd9Sstevel@tonic-gate######################################################################
26117c478bd9Sstevel@tonic-gate###  Relay_Auth: allow relaying based on authentication?
26127c478bd9Sstevel@tonic-gate###
26137c478bd9Sstevel@tonic-gate###	Parameters:
26147c478bd9Sstevel@tonic-gate###		$1: ${auth_type}
26157c478bd9Sstevel@tonic-gate######################################################################
26167c478bd9Sstevel@tonic-gateSLocal_Relay_Auth
26177c478bd9Sstevel@tonic-gate
26187c478bd9Sstevel@tonic-gate######################################################################
26197c478bd9Sstevel@tonic-gate###  srv_features: which features to offer to a client?
26207c478bd9Sstevel@tonic-gate###	(done in server)
26217c478bd9Sstevel@tonic-gate######################################################################
26227c478bd9Sstevel@tonic-gateSsrv_features
26237c478bd9Sstevel@tonic-gateifdef(`_LOCAL_SRV_FEATURES_', `dnl
26247c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_srv_features" $1
26257c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
26267c478bd9Sstevel@tonic-gateR$* $| $*		$: $1', `dnl')
26277c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
26287c478bd9Sstevel@tonic-gateR$*		$: $>D <$&{client_name}> <?> <! SRV_FEAT_TAG> <>
26297c478bd9Sstevel@tonic-gateR<?>$*		$: $>A <$&{client_addr}> <?> <! SRV_FEAT_TAG> <>
26307c478bd9Sstevel@tonic-gateR<?>$*		$: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
26317c478bd9Sstevel@tonic-gateR<?>$*		$@ OK
26327c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
26337c478bd9Sstevel@tonic-gateR<$* _ATMPF_>$*	$#temp', `dnl')
26347c478bd9Sstevel@tonic-gateR<$+>$*		$# $1')
26357c478bd9Sstevel@tonic-gate
26367c478bd9Sstevel@tonic-gate######################################################################
26377c478bd9Sstevel@tonic-gate###  try_tls: try to use STARTTLS?
26387c478bd9Sstevel@tonic-gate###	(done in client)
26397c478bd9Sstevel@tonic-gate######################################################################
26407c478bd9Sstevel@tonic-gateStry_tls
26417c478bd9Sstevel@tonic-gateifdef(`_LOCAL_TRY_TLS_', `dnl
26427c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_try_tls" $1
26437c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
26447c478bd9Sstevel@tonic-gateR$* $| $*		$: $1', `dnl')
26457c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
26467c478bd9Sstevel@tonic-gateR$*		$: $>D <$&{server_name}> <?> <! TLS_TRY_TAG> <>
26477c478bd9Sstevel@tonic-gateR<?>$*		$: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
26487c478bd9Sstevel@tonic-gateR<?>$*		$: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)>
26497c478bd9Sstevel@tonic-gateR<?>$*		$@ OK
26507c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
26517c478bd9Sstevel@tonic-gateR<$* _ATMPF_>$*	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
26527c478bd9Sstevel@tonic-gateR<NO>$*		$#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
26537c478bd9Sstevel@tonic-gate
26547c478bd9Sstevel@tonic-gate######################################################################
26557c478bd9Sstevel@tonic-gate###  tls_rcpt: is connection with server "good" enough?
26567c478bd9Sstevel@tonic-gate###	(done in client, per recipient)
26577c478bd9Sstevel@tonic-gatednl called from deliver() before RCPT command
26587c478bd9Sstevel@tonic-gate###
26597c478bd9Sstevel@tonic-gate###	Parameters:
26607c478bd9Sstevel@tonic-gate###		$1: recipient
26617c478bd9Sstevel@tonic-gate######################################################################
26627c478bd9Sstevel@tonic-gateStls_rcpt
26637c478bd9Sstevel@tonic-gateifdef(`_LOCAL_TLS_RCPT_', `dnl
26647c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_tls_rcpt" $1
26657c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
26667c478bd9Sstevel@tonic-gateR$* $| $*		$: $1', `dnl')
26677c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
26687c478bd9Sstevel@tonic-gatednl store name of other side
26697c478bd9Sstevel@tonic-gateR$*			$: $(macro {TLS_Name} $@ $&{server_name} $) $1
26707c478bd9Sstevel@tonic-gatednl canonify recipient address
26717c478bd9Sstevel@tonic-gateR$+			$: <?> $>CanonAddr $1
26727c478bd9Sstevel@tonic-gatednl strip trailing dots
26737c478bd9Sstevel@tonic-gateR<?> $+ < @ $+ . >	<?> $1 <@ $2 >
26747c478bd9Sstevel@tonic-gatednl full address?
26757c478bd9Sstevel@tonic-gateR<?> $+ < @ $+ >	$: $1 <@ $2 > $| <F:$1@$2> <U:$1@> <D:$2> <E:>
26767c478bd9Sstevel@tonic-gatednl only localpart?
26777c478bd9Sstevel@tonic-gateR<?> $+			$: $1 $| <U:$1@> <E:>
26787c478bd9Sstevel@tonic-gatednl look it up
26797c478bd9Sstevel@tonic-gatednl also look up a default value via E:
26807c478bd9Sstevel@tonic-gateR$* $| $+	$: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
26817c478bd9Sstevel@tonic-gatednl found nothing: stop here
26827c478bd9Sstevel@tonic-gateR$* $| <?>	$@ OK
26837c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
26847c478bd9Sstevel@tonic-gateR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
26857c478bd9Sstevel@tonic-gatednl use the generic routine (for now)
26867c478bd9Sstevel@tonic-gateR$* $| <$+>	$@ $>"TLS_connection" $&{verify} $| <$2>')
26877c478bd9Sstevel@tonic-gate
26887c478bd9Sstevel@tonic-gate######################################################################
26897c478bd9Sstevel@tonic-gate###  tls_client: is connection with client "good" enough?
26907c478bd9Sstevel@tonic-gate###	(done in server)
26917c478bd9Sstevel@tonic-gate###
26927c478bd9Sstevel@tonic-gate###	Parameters:
26937c478bd9Sstevel@tonic-gate###		${verify} $| (MAIL|STARTTLS)
26947c478bd9Sstevel@tonic-gate######################################################################
26957c478bd9Sstevel@tonic-gatednl MAIL: called from check_mail
26967c478bd9Sstevel@tonic-gatednl STARTTLS: called from smtp() after STARTTLS has been accepted
26977c478bd9Sstevel@tonic-gateStls_client
26987c478bd9Sstevel@tonic-gateifdef(`_LOCAL_TLS_CLIENT_', `dnl
2699d4660949SjbeckR$*			$: $1 <?> $>"Local_tls_client" $1
2700d4660949SjbeckR$* <?> $#$*		$#$2
2701d4660949SjbeckR$* <?> $*		$: $1', `dnl')
27027c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
27037c478bd9Sstevel@tonic-gatednl store name of other side
2704*e9af4bc0SJohn BeckR$*		$: $(macro {TLS_Name} $@ $&{client_name} $) $1
27057c478bd9Sstevel@tonic-gatednl ignore second arg for now
27067c478bd9Sstevel@tonic-gatednl maybe use it to distinguish permanent/temporary error?
27077c478bd9Sstevel@tonic-gatednl if MAIL: permanent (STARTTLS has not been offered)
27087c478bd9Sstevel@tonic-gatednl if STARTTLS: temporary (offered but maybe failed)
27097c478bd9Sstevel@tonic-gateR$* $| $*	$: $1 $| $>D <$&{client_name}> <?> <! TLS_CLT_TAG> <>
27107c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
27117c478bd9Sstevel@tonic-gatednl do a default lookup: just TLS_CLT_TAG
27127c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
27137c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
27147c478bd9Sstevel@tonic-gateR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
27157c478bd9Sstevel@tonic-gateR$*		$@ $>"TLS_connection" $1', `dnl
27167c478bd9Sstevel@tonic-gateR$* $| $*	$@ $>"TLS_connection" $1')
27177c478bd9Sstevel@tonic-gate
27187c478bd9Sstevel@tonic-gate######################################################################
27197c478bd9Sstevel@tonic-gate###  tls_server: is connection with server "good" enough?
27207c478bd9Sstevel@tonic-gate###	(done in client)
27217c478bd9Sstevel@tonic-gate###
27227c478bd9Sstevel@tonic-gate###	Parameter:
27237c478bd9Sstevel@tonic-gate###		${verify}
27247c478bd9Sstevel@tonic-gate######################################################################
27257c478bd9Sstevel@tonic-gatednl i.e. has the server been authenticated and is encryption active?
27267c478bd9Sstevel@tonic-gatednl called from deliver() after STARTTLS command
27277c478bd9Sstevel@tonic-gateStls_server
27287c478bd9Sstevel@tonic-gateifdef(`_LOCAL_TLS_SERVER_', `dnl
27297c478bd9Sstevel@tonic-gateR$*			$: $1 $| $>"Local_tls_server" $1
27307c478bd9Sstevel@tonic-gateR$* $| $#$*		$#$2
27317c478bd9Sstevel@tonic-gateR$* $| $*		$: $1', `dnl')
27327c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
27337c478bd9Sstevel@tonic-gatednl store name of other side
27347c478bd9Sstevel@tonic-gateR$*		$: $(macro {TLS_Name} $@ $&{server_name} $) $1
27357c478bd9Sstevel@tonic-gateR$*		$: $1 $| $>D <$&{server_name}> <?> <! TLS_SRV_TAG> <>
27367c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
27377c478bd9Sstevel@tonic-gatednl do a default lookup: just TLS_SRV_TAG
27387c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
27397c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
27407c478bd9Sstevel@tonic-gateR$* $| <$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
27417c478bd9Sstevel@tonic-gateR$*		$@ $>"TLS_connection" $1', `dnl
27427c478bd9Sstevel@tonic-gateR$*		$@ $>"TLS_connection" $1')
27437c478bd9Sstevel@tonic-gate
27447c478bd9Sstevel@tonic-gate######################################################################
27457c478bd9Sstevel@tonic-gate###  TLS_connection: is TLS connection "good" enough?
27467c478bd9Sstevel@tonic-gate###
27477c478bd9Sstevel@tonic-gate###	Parameters:
27487c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
27497c478bd9Sstevel@tonic-gate###		${verify} $| <Requirement> [<>]', `dnl
27507c478bd9Sstevel@tonic-gate###		${verify}')
27517c478bd9Sstevel@tonic-gate###		Requirement: RHS from access map, may be ? for none.
27527c478bd9Sstevel@tonic-gatednl	syntax for Requirement:
27537c478bd9Sstevel@tonic-gatednl	[(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
27547c478bd9Sstevel@tonic-gatednl	extensions: could be a list of further requirements
27557c478bd9Sstevel@tonic-gatednl		for now: CN:string	{cn_subject} == string
27567c478bd9Sstevel@tonic-gate######################################################################
27577c478bd9Sstevel@tonic-gateSTLS_connection
27587c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
27597c478bd9Sstevel@tonic-gatednl deal with TLS handshake failures: abort
27607c478bd9Sstevel@tonic-gateRSOFTWARE	$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
27617c478bd9Sstevel@tonic-gatedivert(-1)')
27627c478bd9Sstevel@tonic-gatednl common ruleset for tls_{client|server}
27637c478bd9Sstevel@tonic-gatednl input: ${verify} $| <ResultOfLookup> [<>]
27647c478bd9Sstevel@tonic-gatednl remove optional <>
27657c478bd9Sstevel@tonic-gateR$* $| <$*>$*			$: $1 $| <$2>
27667c478bd9Sstevel@tonic-gatednl workspace: ${verify} $| <ResultOfLookup>
27677c478bd9Sstevel@tonic-gate# create the appropriate error codes
27687c478bd9Sstevel@tonic-gatednl permanent or temporary error?
27697c478bd9Sstevel@tonic-gateR$* $| <PERM + $={Tls} $*>	$: $1 $| <503:5.7.0> <$2 $3>
27707c478bd9Sstevel@tonic-gateR$* $| <TEMP + $={Tls} $*>	$: $1 $| <403:4.7.0> <$2 $3>
27717c478bd9Sstevel@tonic-gatednl default case depends on TLS_PERM_ERR
27727c478bd9Sstevel@tonic-gateR$* $| <$={Tls} $*>		$: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3>
27737c478bd9Sstevel@tonic-gatednl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
27747c478bd9Sstevel@tonic-gate# deal with TLS handshake failures: abort
27757c478bd9Sstevel@tonic-gateRSOFTWARE $| <$-:$+> $* 	$#error $@ $2 $: $1 " TLS handshake failed."
27767c478bd9Sstevel@tonic-gatednl no <reply:dns> i.e. not requirements in the access map
27777c478bd9Sstevel@tonic-gatednl use default error
27787c478bd9Sstevel@tonic-gateRSOFTWARE $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
277949218d4fSjbeck# deal with TLS protocol errors: abort
278049218d4fSjbeckRPROTOCOL $| <$-:$+> $* 	$#error $@ $2 $: $1 " STARTTLS failed."
278149218d4fSjbeckdnl no <reply:dns> i.e. not requirements in the access map
278249218d4fSjbeckdnl use default error
278349218d4fSjbeckRPROTOCOL $| $* 		$#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
27847c478bd9Sstevel@tonic-gateR$* $| <$*> <VERIFY>		$: <$2> <VERIFY> <> $1
27857c478bd9Sstevel@tonic-gatednl separate optional requirements
27867c478bd9Sstevel@tonic-gateR$* $| <$*> <VERIFY + $+>	$: <$2> <VERIFY> <$3> $1
27877c478bd9Sstevel@tonic-gateR$* $| <$*> <$={Tls}:$->$*	$: <$2> <$3:$4> <> $1
27887c478bd9Sstevel@tonic-gatednl separate optional requirements
27897c478bd9Sstevel@tonic-gateR$* $| <$*> <$={Tls}:$- + $+>$*	$: <$2> <$3:$4> <$5> $1
27907c478bd9Sstevel@tonic-gatednl some other value in access map: accept
27917c478bd9Sstevel@tonic-gatednl this also allows to override the default case (if used)
27927c478bd9Sstevel@tonic-gateR$* $| $*			$@ OK
27937c478bd9Sstevel@tonic-gate# authentication required: give appropriate error
27947c478bd9Sstevel@tonic-gate# other side did authenticate (via STARTTLS)
27957c478bd9Sstevel@tonic-gatednl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
27967c478bd9Sstevel@tonic-gatednl only verification required and it succeeded
27977c478bd9Sstevel@tonic-gateR<$*><VERIFY> <> OK		$@ OK
27987c478bd9Sstevel@tonic-gatednl verification required and it succeeded but extensions are given
27997c478bd9Sstevel@tonic-gatednl change it to <SMTP:ESC> <REQ:0>  <extensions>
28007c478bd9Sstevel@tonic-gateR<$*><VERIFY> <$+> OK		$: <$1> <REQ:0> <$2>
28017c478bd9Sstevel@tonic-gatednl verification required + some level of encryption
28027c478bd9Sstevel@tonic-gateR<$*><VERIFY:$-> <$*> OK	$: <$1> <REQ:$2> <$3>
28037c478bd9Sstevel@tonic-gatednl just some level of encryption required
28047c478bd9Sstevel@tonic-gateR<$*><ENCR:$-> <$*> $*		$: <$1> <REQ:$2> <$3>
28057c478bd9Sstevel@tonic-gatednl workspace:
28067c478bd9Sstevel@tonic-gatednl 1. <SMTP:ESC> <VERIFY [:bits]>  <[extensions]> {verify} (!= OK)
28077c478bd9Sstevel@tonic-gatednl 2. <SMTP:ESC> <REQ:bits>  <[extensions]>
28087c478bd9Sstevel@tonic-gatednl verification required but ${verify} is not set (case 1.)
28097c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*>	$#error $@ $2 $: $1 " authentication required"
28107c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*> FAIL	$#error $@ $2 $: $1 " authentication failed"
28117c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*> NO	$#error $@ $2 $: $1 " not authenticated"
28127c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*> NOT	$#error $@ $2 $: $1 " no authentication requested"
28137c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*> NONE	$#error $@ $2 $: $1 " other side does not support STARTTLS"
28147c478bd9Sstevel@tonic-gatednl some other value for ${verify}
28157c478bd9Sstevel@tonic-gateR<$-:$+><VERIFY $*> <$*> $+	$#error $@ $2 $: $1 " authentication failure " $4
28167c478bd9Sstevel@tonic-gatednl some level of encryption required: get the maximum level (case 2.)
28177c478bd9Sstevel@tonic-gateR<$*><REQ:$-> <$*>		$: <$1> <REQ:$2> <$3> $>max $&{cipher_bits} : $&{auth_ssf}
28187c478bd9Sstevel@tonic-gatednl compare required bits with actual bits
28197c478bd9Sstevel@tonic-gateR<$*><REQ:$-> <$*> $-		$: <$1> <$2:$4> <$3> $(arith l $@ $4 $@ $2 $)
28207c478bd9Sstevel@tonic-gateR<$-:$+><$-:$-> <$*> TRUE	$#error $@ $2 $: $1 " encryption too weak " $4 " less than " $3
28217c478bd9Sstevel@tonic-gatednl strength requirements fulfilled
28227c478bd9Sstevel@tonic-gatednl TLS Additional Requirements Separator
28237c478bd9Sstevel@tonic-gatednl this should be something which does not appear in the extensions itself
28247c478bd9Sstevel@tonic-gatednl @ could be part of a CN, DN, etc...
28257c478bd9Sstevel@tonic-gatednl use < > ? those are encoded in CN, DN, ...
28267c478bd9Sstevel@tonic-gatedefine(`_TLS_ARS_', `++')dnl
28277c478bd9Sstevel@tonic-gatednl workspace:
28287c478bd9Sstevel@tonic-gatednl <SMTP:ESC> <REQ:bits> <extensions> result-of-compare
28297c478bd9Sstevel@tonic-gateR<$-:$+><$-:$-> <$*> $*		$: <$1:$2 _TLS_ARS_ $5>
28307c478bd9Sstevel@tonic-gatednl workspace: <SMTP:ESC _TLS_ARS_ extensions>
28317c478bd9Sstevel@tonic-gatednl continue: check  extensions
28327c478bd9Sstevel@tonic-gateR<$-:$+ _TLS_ARS_ >			$@ OK
28337c478bd9Sstevel@tonic-gatednl split extensions into own list
28347c478bd9Sstevel@tonic-gateR<$-:$+ _TLS_ARS_ $+ >			$: <$1:$2> <$3>
28357c478bd9Sstevel@tonic-gateR<$-:$+> < $+ _TLS_ARS_ $+ >		<$1:$2> <$3> <$4>
28367c478bd9Sstevel@tonic-gateR<$-:$+> $+			$@ $>"TLS_req" $3 $| <$1:$2>
28377c478bd9Sstevel@tonic-gate
28387c478bd9Sstevel@tonic-gate######################################################################
28397c478bd9Sstevel@tonic-gate###  TLS_req: check additional TLS requirements
28407c478bd9Sstevel@tonic-gate###
28417c478bd9Sstevel@tonic-gate###	Parameters: [<list> <of> <req>] $| <$-:$+>
28427c478bd9Sstevel@tonic-gate###		$-: SMTP reply code
28437c478bd9Sstevel@tonic-gate###		$+: Enhanced Status Code
28447c478bd9Sstevel@tonic-gatednl  further requirements for this ruleset:
28457c478bd9Sstevel@tonic-gatednl	name of "other side" is stored is {TLS_name} (client/server_name)
28467c478bd9Sstevel@tonic-gatednl
28477c478bd9Sstevel@tonic-gatednl	currently only CN[:common_name] is implemented
28487c478bd9Sstevel@tonic-gatednl	right now this is only a logical AND
28497c478bd9Sstevel@tonic-gatednl	i.e. all requirements must be true
28507c478bd9Sstevel@tonic-gatednl	how about an OR? CN must be X or CN must be Y or ..
28517c478bd9Sstevel@tonic-gatednl	use a macro to compute this as a trivial sequential
28527c478bd9Sstevel@tonic-gatednl	operations (no precedences etc)?
28537c478bd9Sstevel@tonic-gate######################################################################
28547c478bd9Sstevel@tonic-gateSTLS_req
28557c478bd9Sstevel@tonic-gatednl no additional requirements: ok
28567c478bd9Sstevel@tonic-gateR $| $+		$@ OK
28577c478bd9Sstevel@tonic-gatednl require CN: but no CN specified: use name of other side
28587c478bd9Sstevel@tonic-gateR<CN> $* $| <$+>		$: <CN:$&{TLS_Name}> $1 $| <$2>
28597c478bd9Sstevel@tonic-gatednl match, check rest
28607c478bd9Sstevel@tonic-gateR<CN:$&{cn_subject}> $* $| <$+>		$@ $>"TLS_req" $1 $| <$2>
28617c478bd9Sstevel@tonic-gatednl CN does not match
28627c478bd9Sstevel@tonic-gatednl  1   2      3  4
28637c478bd9Sstevel@tonic-gateR<CN:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
28647c478bd9Sstevel@tonic-gatednl cert subject
28657c478bd9Sstevel@tonic-gateR<CS:$&{cert_subject}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
28667c478bd9Sstevel@tonic-gatednl CS does not match
28677c478bd9Sstevel@tonic-gatednl  1   2      3  4
28687c478bd9Sstevel@tonic-gateR<CS:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
28697c478bd9Sstevel@tonic-gatednl match, check rest
28707c478bd9Sstevel@tonic-gateR<CI:$&{cert_issuer}> $* $| <$+>	$@ $>"TLS_req" $1 $| <$2>
28717c478bd9Sstevel@tonic-gatednl CI does not match
28727c478bd9Sstevel@tonic-gatednl  1   2      3  4
28737c478bd9Sstevel@tonic-gateR<CI:$+> $* $| <$-:$+>	$#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
28747c478bd9Sstevel@tonic-gatednl return from recursive call
28757c478bd9Sstevel@tonic-gateROK			$@ OK
28767c478bd9Sstevel@tonic-gate
28777c478bd9Sstevel@tonic-gate######################################################################
28787c478bd9Sstevel@tonic-gate###  max: return the maximum of two values separated by :
28797c478bd9Sstevel@tonic-gate###
28807c478bd9Sstevel@tonic-gate###	Parameters: [$-]:[$-]
28817c478bd9Sstevel@tonic-gate######################################################################
28827c478bd9Sstevel@tonic-gateSmax
28837c478bd9Sstevel@tonic-gateR:		$: 0
28847c478bd9Sstevel@tonic-gateR:$-		$: $1
28857c478bd9Sstevel@tonic-gateR$-:		$: $1
28867c478bd9Sstevel@tonic-gateR$-:$-		$: $(arith l $@ $1 $@ $2 $) : $1 : $2
28877c478bd9Sstevel@tonic-gateRTRUE:$-:$-	$: $2
28887c478bd9Sstevel@tonic-gateR$-:$-:$-	$: $2
28897c478bd9Sstevel@tonic-gatednl endif _ACCESS_TABLE_
28907c478bd9Sstevel@tonic-gatedivert(0)
28917c478bd9Sstevel@tonic-gate
28927c478bd9Sstevel@tonic-gate######################################################################
28937c478bd9Sstevel@tonic-gate###  RelayTLS: allow relaying based on TLS authentication
28947c478bd9Sstevel@tonic-gate###
28957c478bd9Sstevel@tonic-gate###	Parameters:
28967c478bd9Sstevel@tonic-gate###		none
28977c478bd9Sstevel@tonic-gate######################################################################
28987c478bd9Sstevel@tonic-gateSRelayTLS
28997c478bd9Sstevel@tonic-gate# authenticated?
29007c478bd9Sstevel@tonic-gatednl we do not allow relaying for anyone who can present a cert
29017c478bd9Sstevel@tonic-gatednl signed by a "trusted" CA. For example, even if we put verisigns
29027c478bd9Sstevel@tonic-gatednl CA in CertPath so we can authenticate users, we do not allow
29037c478bd9Sstevel@tonic-gatednl them to abuse our server (they might be easier to get hold of,
29047c478bd9Sstevel@tonic-gatednl but anyway).
29057c478bd9Sstevel@tonic-gatednl so here is the trick: if the verification succeeded
29067c478bd9Sstevel@tonic-gatednl we look up the cert issuer in the access map
29077c478bd9Sstevel@tonic-gatednl (maybe after extracting a part with a regular expression)
29087c478bd9Sstevel@tonic-gatednl if this returns RELAY we relay without further questions
29097c478bd9Sstevel@tonic-gatednl if it returns SUBJECT we perform a similar check on the
29107c478bd9Sstevel@tonic-gatednl cert subject.
29117c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
29127c478bd9Sstevel@tonic-gateR$*			$: <?> $&{verify}
29137c478bd9Sstevel@tonic-gateR<?> OK			$: OK		authenticated: continue
29147c478bd9Sstevel@tonic-gateR<?> $*			$@ NO		not authenticated
29157c478bd9Sstevel@tonic-gateifdef(`_CERT_REGEX_ISSUER_', `dnl
29167c478bd9Sstevel@tonic-gateR$*			$: $(CERTIssuer $&{cert_issuer} $)',
29177c478bd9Sstevel@tonic-gate`R$*			$: $&{cert_issuer}')
29187c478bd9Sstevel@tonic-gateR$+			$: $(access CERTISSUER`'_TAG_DELIM_`'$1 $)
29197c478bd9Sstevel@tonic-gatednl use $# to stop further checks (delay_check)
29207c478bd9Sstevel@tonic-gateRRELAY			$# RELAY
29217c478bd9Sstevel@tonic-gateifdef(`_CERT_REGEX_SUBJECT_', `dnl
29227c478bd9Sstevel@tonic-gateRSUBJECT		$: <@> $(CERTSubject $&{cert_subject} $)',
29237c478bd9Sstevel@tonic-gate`RSUBJECT		$: <@> $&{cert_subject}')
29247c478bd9Sstevel@tonic-gateR<@> $+			$: <@> $(access CERTSUBJECT`'_TAG_DELIM_`'$1 $)
29257c478bd9Sstevel@tonic-gateR<@> RELAY		$# RELAY
29267c478bd9Sstevel@tonic-gateR$*			$: NO', `dnl')
29277c478bd9Sstevel@tonic-gate
29287c478bd9Sstevel@tonic-gate######################################################################
29297c478bd9Sstevel@tonic-gate###  authinfo: lookup authinfo in the access map
29307c478bd9Sstevel@tonic-gate###
29317c478bd9Sstevel@tonic-gate###	Parameters:
29327c478bd9Sstevel@tonic-gate###		$1: {server_name}
29337c478bd9Sstevel@tonic-gate###		$2: {server_addr}
29347c478bd9Sstevel@tonic-gatednl	both are currently ignored
29357c478bd9Sstevel@tonic-gatednl if it should be done via another map, we either need to restrict
29367c478bd9Sstevel@tonic-gatednl functionality (it calls D and A) or copy those rulesets (or add another
29377c478bd9Sstevel@tonic-gatednl parameter which I want to avoid, it's quite complex already)
29387c478bd9Sstevel@tonic-gate######################################################################
29397c478bd9Sstevel@tonic-gatednl omit this ruleset if neither is defined?
29407c478bd9Sstevel@tonic-gatednl it causes DefaultAuthInfo to be ignored
29417c478bd9Sstevel@tonic-gatednl (which may be considered a good thing).
29427c478bd9Sstevel@tonic-gateSauthinfo
29437c478bd9Sstevel@tonic-gateifdef(`_AUTHINFO_TABLE_', `dnl
29447c478bd9Sstevel@tonic-gateR$*		$: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
29457c478bd9Sstevel@tonic-gateR<?>		$: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
29467c478bd9Sstevel@tonic-gateR<?>		$: <$(authinfo AuthInfo: $: ? $)>
29477c478bd9Sstevel@tonic-gateR<?>		$@ no				no authinfo available
29487c478bd9Sstevel@tonic-gateR<$*>		$# $1
29497c478bd9Sstevel@tonic-gatednl', `dnl
29507c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
29517c478bd9Sstevel@tonic-gateR$*		$: $1 $| $>D <$&{server_name}> <?> <! AuthInfo> <>
29527c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| $>A <$&{server_addr}> <?> <! AuthInfo> <>
29537c478bd9Sstevel@tonic-gateR$* $| <?>$*	$: $1 $| <$(access AuthInfo`'_TAG_DELIM_ $: ? $)> <>
29547c478bd9Sstevel@tonic-gateR$* $| <?>$*	$@ no				no authinfo available
29557c478bd9Sstevel@tonic-gateR$* $| <$*> <>	$# $2
29567c478bd9Sstevel@tonic-gatednl', `dnl')')
29577c478bd9Sstevel@tonic-gate
29587c478bd9Sstevel@tonic-gateifdef(`_RATE_CONTROL_',`dnl
29597c478bd9Sstevel@tonic-gate######################################################################
29607c478bd9Sstevel@tonic-gate###  RateControl:
29617c478bd9Sstevel@tonic-gate###	Parameters:	ignored
29627c478bd9Sstevel@tonic-gate###	return: $#error or OK
29637c478bd9Sstevel@tonic-gate######################################################################
29647c478bd9Sstevel@tonic-gateSRateControl
29657c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
29667c478bd9Sstevel@tonic-gateR$*		$: <A:$&{client_addr}> <E:>
29677c478bd9Sstevel@tonic-gatednl also look up a default value via E:
29687c478bd9Sstevel@tonic-gateR$+		$: $>SearchList <! ClientRate> $| $1 <>
29697c478bd9Sstevel@tonic-gatednl found nothing: stop here
29707c478bd9Sstevel@tonic-gateR<?>		$@ OK
29717c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
29727c478bd9Sstevel@tonic-gateR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
29737c478bd9Sstevel@tonic-gatednl use the generic routine (for now)
29747c478bd9Sstevel@tonic-gateR<0>		$@ OK		no limit
29757800901eSjbeckR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
29767c478bd9Sstevel@tonic-gatednl log this? Connection rate $&{client_rate} exceeds limit $1.
29777800901eSjbeckR<$+> $| TRUE	$#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded.
29787c478bd9Sstevel@tonic-gate')')
29797c478bd9Sstevel@tonic-gate
29807c478bd9Sstevel@tonic-gateifdef(`_CONN_CONTROL_',`dnl
29817c478bd9Sstevel@tonic-gate######################################################################
29827c478bd9Sstevel@tonic-gate###  ConnControl:
29837c478bd9Sstevel@tonic-gate###	Parameters:	ignored
29847c478bd9Sstevel@tonic-gate###	return: $#error or OK
29857c478bd9Sstevel@tonic-gate######################################################################
29867c478bd9Sstevel@tonic-gateSConnControl
29877c478bd9Sstevel@tonic-gateifdef(`_ACCESS_TABLE_', `dnl
29887c478bd9Sstevel@tonic-gateR$*		$: <A:$&{client_addr}> <E:>
29897c478bd9Sstevel@tonic-gatednl also look up a default value via E:
29907c478bd9Sstevel@tonic-gateR$+		$: $>SearchList <! ClientConn> $| $1 <>
29917c478bd9Sstevel@tonic-gatednl found nothing: stop here
29927c478bd9Sstevel@tonic-gateR<?>		$@ OK
29937c478bd9Sstevel@tonic-gateifdef(`_ATMPF_', `dnl tempfail?
29947c478bd9Sstevel@tonic-gateR<$* _ATMPF_>	$#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
29957c478bd9Sstevel@tonic-gatednl use the generic routine (for now)
29967c478bd9Sstevel@tonic-gateR<0>		$@ OK		no limit
29977800901eSjbeckR<$+>		$: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
29987c478bd9Sstevel@tonic-gatednl log this: Open connections $&{client_connections} exceeds limit $1.
29997800901eSjbeckR<$+> $| TRUE	$#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections.
30007c478bd9Sstevel@tonic-gate')')
30017c478bd9Sstevel@tonic-gate
30027c478bd9Sstevel@tonic-gateundivert(9)dnl LOCAL_RULESETS
30037c478bd9Sstevel@tonic-gate#
30047c478bd9Sstevel@tonic-gate######################################################################
30057c478bd9Sstevel@tonic-gate######################################################################
30067c478bd9Sstevel@tonic-gate#####
30077c478bd9Sstevel@tonic-gate`#####			MAIL FILTER DEFINITIONS'
30087c478bd9Sstevel@tonic-gate#####
30097c478bd9Sstevel@tonic-gate######################################################################
30107c478bd9Sstevel@tonic-gate######################################################################
30117c478bd9Sstevel@tonic-gate_MAIL_FILTERS_
30127c478bd9Sstevel@tonic-gate#
30137c478bd9Sstevel@tonic-gate######################################################################
30147c478bd9Sstevel@tonic-gate######################################################################
30157c478bd9Sstevel@tonic-gate#####
30167c478bd9Sstevel@tonic-gate`#####			MAILER DEFINITIONS'
30177c478bd9Sstevel@tonic-gate#####
30187c478bd9Sstevel@tonic-gate######################################################################
30197c478bd9Sstevel@tonic-gate######################################################################
30207c478bd9Sstevel@tonic-gateundivert(7)dnl MAILER_DEFINITIONS
30217c478bd9Sstevel@tonic-gate
3022