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