Subject: v16i080: IDA Sendmail kit, Part08/08 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Lennart Lovstrand Posting-number: Volume 16, Issue 80 Archive-name: ida2/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh ida/cf/Sendmail.mc <<'END_OF_ida/cf/Sendmail.mc' X########################################################################## X### The IDA Sendmail Master Configuration File ################## X########################################################################## X### Lennart_Lovstrand.EuroPARC@Xerox.COM ### X### Rank Xerox EuroPARC, 61 Regent St, Cambridge, England ### X### Copyright (c) 1984-88 -- Use it, abuse it, but don't sell it ### X########################################################################## X# Current version XDVIDA-1.2.5 Xchangequote({,}) X X####### INTRODUCTION ##################################################### X# X# This is The IDA Sendmail Master Configuration File--a completely X# independent development having nothing to do with the version X# distributed by Berkeley. In order to work properly, it requires X# a set of new functions implemented by the IDA Sendmail Enhancement X# Kit, available from your nearest comp.sources.unix archive. X# X# Get it today, tomorrow they might have a disk crash! X X# IDA is an abbreviation of "Institutionen for Datavetenskap", X# which is Swedish for "The Department of Computer and Information X# Science". Under no circumstance should it be confused with the X# IDA that stands for the Institute for Defense Analysis, with X# which the author has no relationship to nor wish to become X# associated with. X X X####### REWRITING STRATEGIES ############################################# X# X# Ruleset 3 completely canonicalizes addresses to an internal X# format which looks like "user@.domain", including the dot X# after the atsign. The "user" part may end up containing a X# route in either standard RFC822 format or using the %-kludge. X# The "domain" will be mapped to its full, official domain name X# using the TCP/IP name server and a dbm domaintable. !- and X# ::-style paths are rewritten into RFC822 routes internally. X# Resonable mixtures of !-, %-, and RFC822 routes are resolved, X# either using straight domain preference, or using heuristics. X# Some effort is made to repair malformed addresses. X# X# This format is used in all internal rulesets until finally X# rewritten by the mailer dependant rules, where they are fully X# transformed into the mailer's preferred address syntax. Three X# kinds of mailers currently exist: X# X# [1] Domain based mailers, for which the official domain names X# are used and routes are given in the %-format for header X# addresses and envelope recipient addresses, while X# envelope return paths are kept in RFC822 route syntax. X# Typical examples of this type are the TCP/IP and LOCAL X# mailers. X# X# [2] Domain based mailers with flat node name mappings. These X# use full domain names in header addresses but translate X# envelope domains to names relative the actual network's X# name space. Two mailers fit into this category: The DECnet X# mailer, which map domain names to DECnet names, and the X# UUCP-A/B mailers, which map domains to UUCP node names. X# Both the DECnet and the UUCP worlds use flat namespaces. X# The DECnet and the UUCP-B mailers essentially uses type I X# routes while the UUCP-A mailer uses type III routes (ie, X# !-paths). X# X# [3] UUCP !-path based mailers. This mailer type rewrites all X# addresses into !-paths, both header and envelope addresses. X# Header addresses are made relative the remote node by X# removing "remote!" from them or prefixing "localhost!" to X# them. UUCP nodes with domain names are translated to their X# UUCP equivlanents. X X X####### SENDMAIL CONFIGURATION EXTENSIONS ################################ X# X# This is a short table describing extensions to the configuration X# language. See the reference guide for a detailed definition. X# X# Option "/" will turn on general envelope/header specific X# rewriting. Mailer specific e/h rulesets are given as in X# "R=14/15", where ruleset 14 is used for envelope recipient X# addresses and ruleset 15 for header recipients. X# X# The M_FROMPATH (p) flag will work for mailers that use "From_" X# line envelopes as well as SMTP mailers. X# X# The M_RELATIVIZE (V) flag has been added, which make all header X# lines relative the recipient host by removing "remote!" or X# adding "localhost!". X# X# TCP/IP nameserver lookups are extended with a default argument, X# as in "$[ hostname $: default $]". The "default" string will be X# returned if the host isn't known to gethostname(3). X# X# General dbm database functions have been added. The option "K" X# will declare a dbm database and associate it with a letter, X# which later on is used in constructs like: X# "$(x key $@ arg $: default $)" X# The "x" is the one-letter name of the database, the "key" is the X# lookup string; the optional "arg" is then sprintf(3)'ed through X# the result, if found. The whole expression evaluates to X# "default", or "key" if "$: default" is not present, if the "key" X# can't be found in the database. The "@" database is X# automatically connected to the aliases(5) file. X X X####### M4 IDENTIFIERS ################################################### X# X# NOTE: Be aware that this is an m4 source where curly braces are X# used as quote characters. You will lose heavily if you care- X# lessly mention reserved m4 words or use curly braces where you X# shouldn't. X# X# The following is a list of all m4 identifiers used in this file. X# All of them are optional. X# X# ALIASES X# Name of the aliases file, defaults to sendmail's default. X# BANGIMPLIESUUCP X# If defined, will assume that all !-paths with leading, X# unqualified nodes resides in the UUCP pseudo-domain. X# Will otherwise try to qualify node using the name server X# and domaintable, retreating to .UUCP if unknown by them. X# DECNETNODES X# A file containing DECnet host names. Used in combination X# with DECNETXTABLE to determine delivery through the DECnet X# mailer and when to expand flatspaced DECnet host names into X# domains. X# DECNETXTABLE X# The DECnet translation table. Returns a node's DECnet X# host name if given its domain name. (Dbm file, see X# ruleset 24 for more info). X# DEFAULT_HOST X# Explicit host name, replaces automatic definition of $w. X# DEFAULT_DOMAIN X# The string that (+ ".") will be attached to $w to X# form $j, this node's official domain name. Only define X# this if $w doesn't already include your full domain X# (ie, as returned by gethostbyname()). X# DOMAINTABLE X# Dbm database used for hostname canonicalization, ie. X# to find the official domain name for local or otherwise X# unqualified hosts. X# GENERICFROM X# A database mapping actual user names to generic user X# names. Used instead of HIDDENNET in a heterogenous X# environment. X# HIDDENNET X# Points to a file containing a list of host names, one X# per line. Mail from users on any of these hosts will X# have the host name substituted for our host, $w. X# LIBDIR X# The directory that will hold most data files, including X# sendmail.{hf,st}; defaults to /usr/lib/mail. X# LIUIDA X# Site specific parts for the CIS Dept, U of Linkoping. X# PATHTABLE X# The heart & soul of this sendmail configuration--the X# pathalias routing table in dbm format, as produced by X# the pathalias program. Either you define this or rel(a)y X# on RELAY_HOST/RELAY_MAILER. X# MAILERTABLE X# A dbm table mapping node names to "mailer:host" pairs. X# It is used for special cases when the resolving heuristics X# of ruleset 26 aren't enough. X# NEWALIASES X# If defined, will make ruleset 26 return all addresses X# as local. This should be used by the newaliases program X# only when parsing the aliases file if you want to be X# able to handle non-local aliases (ie aliases of type X# "user@host: whatever"). Note that you can't let X# sendmail rebuild the database automatically if this is X# the case or else those aliases will be thrown away. X# PSEUDODOMAINS X# A list of well-known top level pseudo domains such as X# BITNET, CSNET, UUCP, etc. Addresses ending with a top X# level domain in this class won't be canonicalized using X# the resolver to reduce load on the root name servers. X# Note that this variable is independent of the T class X# below. Any "well-known" top level domain that is not X# part of NIC's registered domains may be put here. X# PSEUDONYMS X# Additional names that we are known under (in addition X# to those returned by gethostbyname()). X# RELAY_HOST & RELAY_MAILER X# Name of the host and mailer to ship unknown recipient X# addresses to. X# RSH_SERVER X# If defined, do local deliveries by rsh'ing /bin/mail X# on the RSH_SERVER host. Make sure that root is allowed X# to remotely login to the server. X# SPOOLDIR X# Directory for sendmail queue files; defaults to X# /usr/spool/mqueue. X# STRICTLY822 X# This flag will guide the interpretation of mixed (hybrid) X# !/@ addresses. If left undefined, we will look at the X# protocol used to receive the message and interpret X# accordingly (! takes precedence for UUCP; @ for others). X# If you define STRICTLY822, all mixed addresses will be X# interpreted as path@host. X# TCPMAILER X# The default TCP mailer to use for SMTP/TCP deliveries. X# Defaults to TCP (as opposed to TCP-D or TCP-U, qv). X# UUCPMAILER X# The default UUCP mailer to use for UUCP deliveries. X# Defaults to UUCP (as opposed to UUCP-A or UUCP-B, qv). X# UUCPNAME X# This node's UUCP host name, if different from $k. X# UUCPNODES X# A file containing names of directly connectable UUCP nodes. X# UUCPPRECEDENCE X# This option has been obsoleted by checking the receiving X# protocol when resolving mixed !/@ addresses. Define X# STRICTLY822 to disable this. X# UUCPRELAYS X# Name of file containing names of known (UUCP) relays. X# Header addresses containing paths through any of these X# will be shortened by having the path to the relay removed. X# (It is assumed that paths to each of these are known to X# everybody) X# UUCPXTABLE X# A table mapping domain node names to UUCP node names. X# Used in envelope addresses sent using UUCP/rmail. X# X# The following are still experimental: X# XEROXGV & XEROXNS X# Default gateways for unspecified Xerox Grapevine and XNS X# addresses. X# XNSDOMAIN X# The name of the XNS Gateway domain {from the XNS side}. X# XNSMAIL X# The name of your XNS Mail Gateway program. X X X####### CLASSES, DEFINITIONS, and DATABASES ############################## X# X# The following classes, macro definitions and keyed databases are X# being used: X# X# CA An atsign (@), used in class membership negations X# CD Known DECnet host names (see DECNETNODES above) X# CH Node names that should be hidden by $w (see HIDDENNET above) X# CP Known top level pseudo domains (see PSEUDODOMAINS above) X# CR Removeable relays from header addresses (see UUCPRELAYS above) X# CT Known top level domains (global + local) X# CU Directly connectable UUCP nodes X# CX A set of chars that delimit the LHS of a domain (@ %) X# CY A set of chars that delimit the RHS of a domain (, : % @) X# CZ RFC822 Source Route punctuation chars (, :) X# X# DV Configuration version number X# X# OK@ The aliases database (automatically defined; see ALIASES above) X# OKD DECnet domain translation table (see DECNETXTABLE above) X# OKG Generic usernames (see GENERICFROM above) X# OKM Special domain => mailer:host table (see MAILERTABLE above) X# OKN Official name lookup table (see DOMAINTABLE above) X# OKP Pathalias routing database (see PATHTABLE above) X# OKU UUCP domain translation table (see UUCPXTABLE above) X X X########################################################################## X## Default Definitions ################################################### X########################################################################## Xifdef({LIBDIR},,{define(LIBDIR, /usr/lib/mail)}) Xifdef({SPOOLDIR},,{define(SPOOLDIR, /usr/spool/mqueue)}) Xifdef({TCPMAILER},,{define(TCPMAILER, TCP)}) Xifdef({UUCPMAILER},,{define(UUCPMAILER, UUCP)}) Xifdef({UUCPPRECEDENCE}, X {errprint({Note: UUCPPRECEDENCE is obsolete, please see Sendmail.mc})}) X X# X########################################################################## X## Domain Definitions #################################################### X########################################################################## X X########################################################################## X# Universally known top-level domains X X# Organizational domains XCTcom edu gov org mil net X# National domains XCTau ar at be ca cdn ch cl de dk es fi fr ie il irl is it jp kr XCTmy nl no nz pg se uk us X# Network based domains XCTarpa bitnet csnet junet mailnet uucp X X########################################################################## X# Well-known pseudo domains X# (that the resolver shouldn't be bothered with) X Xifdef({PSEUDODOMAINS},{ X{CP}PSEUDODOMAINS X}) X X########################################################################## X## Misc Definitions ###################################################### X########################################################################## X Xifdef({DEFAULT_HOST}, X# This node's local host name X{Dw}DEFAULT_HOST) X X# This node's official domain name Xifdef({DEFAULT_DOMAIN}, X{Dj$w.}DEFAULT_DOMAIN, XDj$w) X Xifdef({PSEUDONYMS}, X# Other names for this node X{Cw}PSEUDONYMS) XCw$k X X# my name XDnMAILER-DAEMON X X# UNIX header format XDlFrom $g $d X X# delimiter (operator) characters XDo".:;%@!=/[]?#^,<>" X X# Characters that mark the left (X) & right (Y) hand side of a domain XCX@ % XCY, : % @ X X# Pure RFC822 route punctuation characters XCZ, : X X# The atsign-in-a-class XCA@ X X# Format of a total name: Personal Name XDq$?x$!x <$g>$|$g$. X X# SMTP login message XDeWelcome to IDA Sendmail $v/$V running on $j X X X########################################################################## X# Options X X# set default alias file Xifdef({ALIASES},{OA}ALIASES) X# time to look for "@:@" in alias file XOa15 X# substitution for blank character XOB. X# don't connect to "expensive" mailers XOc X# delivery mode XOdb X# rebuild alias database as needed X# OD X# set error processing mode X# Oe X# temporary file mode XOF0600 X# save Unix-style From lines on front X# Of X# default gid XOg1 X# help file X{OH}LIBDIR/sendmail.hf X# ignore dot lines in message X# Oi X# database files Xifdef({DECNETXTABLE},{OKD}DECNETXTABLE) Xifdef({GENERICFROM},{OKG}GENERICFROM) Xifdef({MAILERTABLE},{OKM}MAILERTABLE) Xifdef({DOMAINTABLE},{OKN}DOMAINTABLE) Xifdef({PATHTABLE},{OKP}PATHTABLE) Xifdef({UUCPXTABLE},{OKU}UUCPXTABLE) X# log level XOL9 X# define macro X# OM X# send to me too XOm X# local network name Xifdef({DEFAULT_DOMAIN},{ON}DEFAULT_DOMAIN) X# assume old style headers XOo X# postmaster copy of returned messages XOPPostmaster X# queue directory X{OQ}SPOOLDIR X# read timeout -- violates protocols XOr30m X# status file X{OS}LIBDIR/sendmail.st X# be super safe, even if expensive XOs X# queue timeout XOT4d X# time zone name X# OtMET,MET DST X# set default uid XOu1 X# run in verbose mode X# Ov X# wizard's password XOW* X# load avg at which to auto-queue msgs XOx3 X# load avg to auto-reject connections XOX8 X# fork when running the queue X# OY X# use separate envelope/header rewriting rulesets XO/ X X########################################################################## X# Message precedences X XPfirst-class=0 XPspecial-delivery=100 XPjunk=-100 X X########################################################################## X# Trusted users X XTroot XTdaemon XTuucp X X########################################################################## X# Header Formats X X#HReceived: $?sfrom $s $.by $j; $b XHReceived: $?sfrom $s $.by $j$?r with $r$. X ($v/$V) id $i; $b XH?P?Return-Path: <$g> XH?D?Date: $a XH?F?From: $q XH?x?Full-Name: $x XH?M?Message-ID: <$t.$i@$j> X X X# X########################################################################## X## Mailer Specifications ################################################# X########################################################################## X X########################################################################## X# X# Local & Prog mailer definitions X X# List of nodes that should be hidden by our name (header senders) Xifdef({HIDDENNET},{FH}HIDDENNET) X Xifdef({RSH_SERVER}, { XMlocal, P=/usr/ucb/rsh, F=DFMlmns, A=RSH_SERVER /bin/mail -d $u X}, { XMlocal, P=/bin/mail, F=DFMSlmnrs, A=mail -d $u X}) XMprog, P=/bin/csh, F=DFMhlsu, A=csh -fc $u X X X########################################################################## X# X# TCP/IP mailer specification X# X# The TCP mailer is the normal choice for SMTP/TCP delivery, but a X# couple of variations exist for compatibility with mailers that X# need special address formatting for indirect UUCP and DECnet X# addresses. Both has to be explicitly mentioned in the mailertable X# to be chosen as all normal mail will use the standard TCP mailer. X# X# TCP-D -- will flatten envelope recipient DECnet domains for X# messages destinated to our DECnet gateway. Unfortunately, our X# (Linkoping) DECnet gateway is too dumb to do this itself. X# X# TCP-U -- is available for hosts which require hybrid addresses X# for deliveries to UUCP destinations. Eg. "bar!foo@desthost" will X# be translated to "foo%bar@desthost", then to "bar!foo@desthost" X# [as opposed to just "foo@bar" which is what the standard TCP X# mailer would have produced]. X# X# Both of the above only touch envelope addresses; header X# addresses are still kept in our preferred format. Change the X# R/S settings below if you don't like that. X XMTCP, P=[IPC], F=CDFMXhnmpu, E=\r\n, A=IPC $h XMTCP-D, P=[IPC], F=CDFMXhnmpu, E=\r\n, R=24/0, A=IPC $h XMTCP-U, P=[IPC], F=CDFMXhnmpu, E=\r\n, R=13/0, S=13/0, A=IPC $h X X# Produce hybrid (brr) addresses for unqualified or .UUCP hosts XS13 XR$+@.$- $:$>19 $1@.$2 bangify unqualified XR$+@.$-.UUCP $:$>19 $1@.$2.UUCP bangify .UUCP XR$+@.$+ $@ $1@.$2 let normal domains pass XR$+ $@ $1@.$[$&h$] add rcpt host for paths X X X########################################################################## X# X# (Pseudo)DECnet mailer specification X# X# Send all envelope recipients thru DECnet domain name flattener. X X# List of DECnet nodes Xifdef({DECNETNODES},{FD}DECNETNODES) X Xifdef({LIUIDA},{ X# Since we don't have any Unix boxes with DECnet yet, we cheat... XMDECnet, P=[IPC], F=CDFMXhnmpu, R=24/0, E=\r\n, A=IPC lisbet.liu.se X}) X X X########################################################################## X# X# UUCP mailer definitions X X# Our UUCP name, if other than $w Xifdef({UUCPNAME},{Dk}UUCPNAME) X X# List of known UUCP nodes Xifdef({UUCPNODES},{FU}UUCPNODES) XCU$k X X# List of UUCP relays that are to be removed from sender paths Xifdef({UUCPRELAYS},{FR}UUCPRELAYS) X XMUUCP, P=/usr/bin/uux, F=DFMUVShpu, S=19, R=19, A=uux - -z -r $h!rmail ($u) XMUUCP-A, P=/usr/bin/uux, F=DFMShmpu, S=19/0, R=15/0, A=uux - -z -r $h!rmail ($u) XMUUCP-B, P=/usr/bin/uux, F=BDFMSXhmpu, S=0, R=15/0, A=uux - -z -r $h!bsmtp X X# Canonicalize envelope recipient addresses before UUCP-ifying them. XS14 XR$+ $@ $>19$>3 $1 X X# UUCP-ify address, then move domain back if not UUCP destination XS15 XR$+ $: $>19 $1 UUCP-ify XR$+!$+ $: $1?$2 mark first bang XR$+.$=T?$+ $@ $3@.$1.$2 restore if real domain XR$+?$+ $@ $1!$2 just put bang back otherwise X X########################################################################## X# X# XNS Mailer -- this is still experimental. X# X XMXNS, {P=}XNSMAIL, F=CDFMXhnmprsu, R=16/0, S=16/0, A=xnsmail -q -O $u X X# Convert address to XNS Object Name. XS16 XR$+ $: $>4 $1 first externalize XR{$+@}XEROXNS $@ $1 this is already an XNS addrs XR$+ $@ {$1:}XNSDOMAIN add XNS domain for others X X X# X########################################################################## X## Standard Rewriting Rules ############################################## X########################################################################## X X######################################################################### X# # X# Rule Set #0: Mailer Resolving Ruleset # X# # X# This is rather straightforward. The code should say it all. # X# # X######################################################################### XS0 X X# Digest routes through ourselves XR$+@.$+ $:$>29 $1@.$2 remove routed self X X# Try immediate delivery XR$+@.$+ $:$>26 $1@.$2 try to find mailer XR$#$+ $# $1 found one, return it X X# Unknown domain, try to find a pathalias route XR$+@.$+ $:$>22 $1@.$2 go get route XR$+@.$+ $:$>29 $1@.$2 remove routed self XR$+@.$+ $:$>26 $1@.$2 now look for mailer XR$#$+ $# $1 success, return it X Xifdef({RELAY_HOST}, { X# If we have a RELAY_HOST/RELAY_MAILER, use it XR$+@.$+ ${#}RELAY_MAILER $@RELAY_HOST $:$1@.$2 X}) X X# Try TCP/IP otherwise, there might be an MX record for it X# (there should be a way of checking for this) XR$+@.$+ {$#}TCPMAILER $@$2 $:$1@.$2 X X# Undeliverable recipients--complain loudly & return to sender XR$+@.$- $#ERROR $:Host $2 not known--please specify domain XR$+@.$-.$*$=T $#ERROR $:Host $2 not known within the $3$4 domain XR$+@.$+.$- $#ERROR $:Domain $3 not known--please try to route manually XR@$+ $#ERROR $:"Incomplete Source Route--use <...> format" XR$* $#ERROR $:Could not parse $1 X X X######################################################################### X# # X# Rule Set #1: [Envelope] Sender Specific Rewriting # X# # X# [Currently nothing.] # X# # X######################################################################### XS1 X X X######################################################################### X# # X# Rule Set #2: [Envelope] Receiver Specific Rewriting # X# # X# Turn RFC822 Source Routes into a %-paths since most MTAs # X# don't know about how to handle the former format. # X# # X######################################################################### XS2 X XR$+@.$+ $:$>25 $1@.$2 Src Routes => %-routes X X X######################################################################### X# # X# Rule Set #3: Address Canonicalization # X# # X# Turns the address into the (internally) canonical format # X# mailbox@.domain. The `domain' is what you think it is, but # X# the `mailbox' may be either a "real" mailbox in which case # X# no further meaning is associated to it, or a route in either # X# the Source Route format as specified by RFC822 or the (un- # X# documented) Good Ole ARPAnet %-Kludge Format. # X# # X# Input formats include the standard "mailbox@domain" format, # X# RFC822 Source Routes, RFC822 Group Names, ARPAnet %-Kludges, # X# UUCP !-Paths, the Berknet "host:user" format, the VAX/VMS # X# "host::user" format and resonable mixtures of the above. # X# # X# The code even tries to clean up after various mistakes that # X# other nodes has done when reformatting the addresses, such # X# as mangled Xerox distribution lists or malformatted RFC822 # X# Group Specifications. # X# # X######################################################################### XS3 X X### X### First attempt to repair malformed addresses X### X XR$*<$+>$* $2 turn to essentials XR$*<>$* Postmaster default user X X# These are not for us XR:{include}:$*@$* $@:{include}:$1@.$2 indirect address XR:{include}:$* $@:{include}:$1@.$w indirect address XR$*/$*@$* $@$1/$2@.$3 file name XR$*/$* $@$1/$2@.$w file name X X# Fix group names and return them XR$+:;@$+ $:$1:; remove host info XR$+: $:$1:; missing semicolon XR$+!; $:$1:; UUCP-style mangled group XR$+!$+:; $2:; remove UUCP host info XR$+:; $@$1:; Finally return group X X# Miscellaneous cleanup (sigh) XR$+!.$+ $1^.$2 fix mangled Xerox dList XR$+::$+ $1!$2 VAX/VMS relative address XR$+!:$+@$+ $1!$3!$2 scrambled source route XR$+!:$+ $1!$2 mangled VAX/VMS address Xifdef({XEROXNS},,{ XR$-:$- $1!$2 Berknet style address X}) XR$+:@$+ $1,@$2 slightly malformed src route XR$*$~Z@$+@$+ $1$2%$3@$4 fix user@host@relay Xifdef({LIUIDA},{ XRenea!$+!!$+,!$+ enea!$1!!$2,@$3 brutally beaten src route XRenea!$+!!$+:$+!$+ $: enea!$1!$2!$4!$3 seriously smashed src route XRenea!$+!!$+ $: enea!@$2@$1 maddenly messy src route X}) XR$+@$+.$=T.UUCP $1@$2.$3 strip UUCP off foo@bar.EDU.UUCP X X# Fix %-kludgified RFC822 source routes (double sigh) XR$+!%$+:$+%$+ $1!%$2:$3@$4 change all %'s into @'s XR$+!%$+,%$+ $1!%$2,@$3 XR$+!%$+ $1!@$2 X X### X### The address should be in a reasonable format now. X### Time to resolve mixed !/@ hybrid addresses and !-paths. X### X XR$+!$+ $:$>18 $1!$2 resolve UUCP address X X### X### Address should be close to canonical now, give or take X### the @domain part. Make it really internal by adding a X### dot before the [direct] domain (if any). Also qualify X### known domain names. X### X X# Add dot and put direct host on back for RFC822 Source Routes XR$+ $: $1@ make sure address has atsign XR$+@$+@ $: $1@$2 remove again if already there XR$*@$+ $: $1@.$2 add dot after [direct] domain XR@.$+$=Z$+ $: $3@.$1 tack direct domain on end XR$+@..$+ $: $1@.$2 one dot is enough! (intern fix) X X# Routed address (good ol' ARPA version) XR$+%$+@ $:$1@.$2 replace '%' with '@.' XR$+@.$+%$+ $1%$2@.$3 move gaze right X X# Sometimes users try to send to RFC822 Source Routes without angle X# brackets. This will cause the mailer to split the comma-separated X# domain path into separate phony addresses, which all look like X# "@domain". There's not much to do about it here though. XR@.$+@ $@ @$1 incomplete Source Route X X# Automatically route Grapevine and XNS addresses via resp gateways. X# Note that this assumes that there won't be any local users with dots X# or colons in their names; nor any such names in aliases. Xifdef({XEROXGV},{ XR$-.$*@ $: {$1.$2@.}XEROXGV GW for Grapvine User.registry X}) Xifdef({XEROXNS},{ XR$+:$*@ $: {$1:$2@.}XEROXNS XNS User:Domain:Organization X}) X X# No domain, attach default X# (tip: passing it through the domaintable allows us to hide local hosts) Xifdef({DOMAINTABLE},{ XR$+@ $: $1@.$(N $w $) no host/domain, attach default X},{ XR$+@ $: $1@.$w no host/domain, attach default X}) X X# Try to find official name for domain XR$+@.$*$~P $: $1@.$[ $2$3 $] officialize using resolver Xifdef({DOMAINTABLE},{ XR$+@.$+ $: $1@.$(N $2 $) officialize using domaintable X}) X X X######################################################################### X# # X# Rule Set #4: Address PrettyPrinter # X# # X# Does the final prettyprinting before the address is included # X# in the message. (This is essentially a trivial reformatting # X# from internal to external format) # X# # X######################################################################### XS4 X X# Remove dot and return RFC822 Source Routes XR@$+@.$+ $@ @$2,@$1 XR$+@$+@.$+ $@ @$3:$1@$2 X X# Remove dot for normal domain addresses XR$+@.$+ $@ $1@$2 X X X######################################################################### X# # X# Rule Set #5: [Header] Sender Specific Rewriting # X# # X# Rewrite RFC822 source routes into %-routes, since most mailer # X# UAs can't handle them. Compact obvious routes, mostly for # X# aesthetical reasons. Possibly hide local nodes behind ourself. # X# Substitute generic names for physical senders. # X# # X######################################################################### XS5 X XR$+@.$+ $:$>23 $1@.$2 unsourcify & prettify X X# Hide these nodes using our own name XR$+@.$=H $: $1@.$j X Xifdef({GENERICFROM}, { X# Use (canonicalized) generic names for local users X# (Assumes that it never will find a $+@.$+ address in the db, ie. with dot) XR$+@.$+ $: $1@.$2 ? $1@.$2 duplicate XR$+?$+@.$+.$- $1 ? $(G $2@$3.$4 $: $2@.$3 $) search db foreach dom XR$+?$+@.$- $: $1 ? $(G $2@$3 $: $2@. $) search for last dom XR$+@.$=w?$+@. $: $1@.$2 ? $(G $3 $: $3@. $) search for locals XR$+@.$+?$+@.$* $@ $1@.$2 not found XR$+?$+ $@ $>3 $2 found, canonicalize X}) X X X######################################################################### X# # X# Rule Set #6: [Header] Receiver Specific Rewriting # X# # X# Rewrite RFC822 source routes into %-routes, since most mailer # X# UAs can't handle them. Compact obvious routes, mostly for # X# aesthetical reasons. # X# # X######################################################################### XS6 X XR$+@.$+ $:$>23 $1@.$2 unsourcify & prettify X X X# X########################################################################## X## General Rewriting Rule Subroutines #################################### X########################################################################## X X######################################################################### X# # X# Rule Set #18: Resolve mixed (hybrid) !/@ addresses # X# # X# Given an address like a!b@c, resolve it into either a->c->b # X# (UUCP style !-precedence) or c->a->b (others, @-precedence). # X# Pure UUCP !-paths (ie without domain part) are also handled. # X# Used by ruleset 3 *before* the address has been put into # X# into internal canonical format (ie. no dot after atsign). # X# # X######################################################################### XS18 X X# Case 0: !-prefixed RFC822 source route--extend to complete source route XR$+!$+!@$+ $1,@$2!@$3 !-path to ,@-route XR$+!@$+ $: @$1,@$2 including first & last !-host X Xifdef({STRICTLY822},,{ X# Case 1: Let ! take precedence if protocol is UUCP XR$~A$*!$+@$+ $: $1$2!$3@$4?$&r attach protocol XR$~A$*!$+@$+?UUCP $@$>21 $1$2!$3%$4@ UUCP: ! takes precedence XR$~A$*!$+@$+?$* $: $1$2!$3@$4 remove protocol X}) X X# Case 2: Let @ take precedence for others X# (2a -- !-path on top of %-route on top of @-domain (ugh!)) XR$~A$*!$+%$+@$+ $: $1$2?$3%$4@$5 mark first bang XR$+?$+!$+%$+ $1!$2?$3%$4 find rightmost XR$+?$+%$+%$+@$+ $3!$1?$2%$4@$5 move %hosts around XR$+?$+%$+@$+ $@$>21 $4!$3!$1!$2@ now send it thru unbanger X# (2b -- Domain address without %-route) XR$~A$*!$+@$+ $@$>21 $4!$1$2!$3@ @ takes precedence X X# Case 3: Pure UUCP-path XR$~A$*!$+ $@$>21 $1$2!$3@ pure UUCP style X X X######################################################################### X# # X# Rule Set #19: Translate domain addresses to UUCP !-paths # X# # X# Takes an domain style address as input and transforms this # X# into a !-path. There will be no atsign left in the address # X# after this, but there may(?) still be a percent sign. # X# Routes are specially processed, trying to qualify all non- # X# qualified nodes in the path. This is to make sure local nodes # X# will have their proper domains properly attached before the # X# messages leavs us. I'm not sure if this is a good thing or # X# not, since they may not be local at all. UUCP nodes with # X# domain style names are qualified, anyway. # X# # X######################################################################### XS19 X X# Don't touch groups! XR$+:; $@ $1:; return groups X X# Translate RFC822 Source Routes FULLY into !-path format XR$+@$+@.$+ $:$>4 $1@$2@.$3 first externalize XR@$+ $: ?@$1 mark first node XR$*?@$+$=Z$+ $1$2!?$4 change prefix path to ! XR$+?$~A$*@$+ $: $1$4!$2$3 turn last pair into ! format 2 XR$*?$* $: $1$2 remove possible trailing mark X X# Translate normal domain addresses Xifdef({UUCPXTABLE},{ XR$+%$-@.$+ $: $1%$2@.$3 ? $(U $3 $: $) UUCP node as domain? XR$+%$-@.$+?$+ $:$>20 $1%$2@.$3 yes, !-ify XR$+%$-@.$+? $: $1%$2@.$3 no, remove mark X}) XR$+%$-@.$+.UUCP $:$>20 $1%$2@.$3.UUCP !-ify "obvious" UUCP routes XR$+%$-@.$+.$- $: $3.$4!$1%$2 don't know about other domains XR$+@.$+ $:$>20 $1@.$2 all the rest to the !-ifyer X X### X### Address should be in !-path format now. X### X Xifdef({DOMAINTABLE},{ X# Qualify all nodes that we know of X# THIS IS DANGEROUS AND WRONG! But still needed since some nodes out there X# do heavy path optimizations and our DECnet nodes may lose due to that. XR$* $: ?$1 mark start XR$*?$+!$+ $1$(N $2 $)!?$3 qualify node XR$*?$* $: $1$2 remove mark X}) X X# Unqualify all UUCP nodes Xifdef({UUCPXTABLE},{ XR$* $: ?$1 mark start XR$*?$+!$+ $1$(U $2 $)!?$3 unqualify node XR$*?$* $: $1$2 remove mark X}) XR$-.UUCP!$+ $: $1!$2 remove first .UUCP XR$+!$-.UUCP!$+ $1!$2!$3 remove other .UUCP's X X X######################################################################### X# # X# Rule Set #20: %-Route to !-Path Translator # X# # X# Translates Good Ol' ARPA %-Routes to UUCP style !-paths. # X# This is done up to, but not beyond, the first non-UUCP # X# domain found in the path. # X# This ruleset is used strictly for heuristical reasons. # X# Nodes with Real Domain Names are assumed in general not to # X# understand !-paths, but rather prefer %-routes. This wouldn't # X# have been necessary to do here if all gateways had fully # X# converted all addresses. # X# Eg. mbox%a%b%c@.domain => domain!c!b!a!mbox # X# mbox%a.b%c%d@.domain => domain!d!c!mbox%a.b # X# # X######################################################################### XS20 X Xifdef({UUCPXTABLE},{ XR$+@.$+ $: $(U $2 $)?$1 move translated domain to front X},{ XR$+@.$+ $: $2?$1 move domain to front X}) XR$+?$+%$- $1!$3?$2 prefix host route Xifdef({UUCPXTABLE},{ XR$+?$+%$+ $: $1?$2%$(U $3 $) translate UUCP domains to hosts XR$+?$+%$- $@$>20 $1?$2%$3 recurse if host found X}) XR$+?$+%$-.UUCP $@$>20 $1?$2%$3 recurse if ending in host.UUCP XR$+?$+ $: $1!$2 get rid of temp !-subst X X X######################################################################### X# # X# Rule Set #21: Prehost to Posthost Converter # X# # X# Changes !-paths into RFC822 Source Routes. # X# Eg. a!b!c!d => a,@b,@c,@d => @a,@b:d@c # X# a!b!c%d => a,@b,@c%d => @a:c%d@b # X# a!b!c@d => a,@b,@c@d => @a,@b:c@d) # X# # X######################################################################### XS21 X X# Initial canonicalization (get rid of possible '@' as in path!u@h) XR$+@ $: $1 remove optional trailing '@' XR$+!$+ $: $1?$2 find the rightmost '!' XR$+?$+!$+ $1!$2?$3 ..and change it into a '?' XR$+?$+@$+ $: $1!$3!$2 change last u@h to h!u if any XR$+?$+ $: $1!$2 just remove '?' otherwise X X# The address is now formatted as a!b!..!h!u -- transform it into a,@b,@..?h?u XR$+!$+ $: ?$1?$2 find last h!u-pair XR$*?$+?$+!$+ $1,@$2?$3?$4 change all '!'s before to ',@' XR?$+?$+ $: $2@$1 h!u => u@h XR,$+?$+?$+ $: $1:$3@$2 ,path..h!u => path:u@h X X X X# Infer .UUCP domain on first host if it is unqualified and either: X# (BANGIMPLIESUUCP is defined) OR (DOMAINTABLE is undefined and the host X# isn't known by the name server) OR (the host isn't known by the domaintable) X Xifdef({BANGIMPLIESUUCP},{ X# (BANGIMPLIESUUCP is defined) XR@$-$=Z$+ $@ @$1.UUCP$2$3 route: add .UUCP XR$+@$- $@ $1@$2.UUCP host: add .UUCP X},{ifdef({DOMAINTABLE},{ X# (DOMAINTABLE is defined) XR@$-$=Z$+ $: @$[ $1 $: $1 $]$2$3 route: try name server XR@$-$=Z$+ $@ @$(N $1 $: $1.UUCP $)$2$3 route: try domain table XR@$+ $@ @$1 already has domain XR$+@$- $: $1@$[ $2 $: $2 $] host: try name server XR$+@$- $@ $1@$(N $2 $: $2.UUCP $) host: try domain table X},{ X# (neither BANGIMPLIESUUCP nor DOMAINTABLE is defined) XR@$-$=Z$+ $@ @$[ $1 $: $1.UUCP $]$2$3 route: try name server XR$+@$- $@ $1@$[ $2 $: $2.UUCP $] host: try name server X})}) X X######################################################################### X# # X# Rule Set #22: General Pathalias Router # X# # X# Tries to find a route for an address using the pathalias # X# database. It will return the complete (canonicalized) # X# route if found, or the same address otherwise. # X# # X######################################################################### XS22 X Xifdef({PATHTABLE},{ X# Change RFC822 Source Routes into %-path to get rid of multiple atsigns XR$+@$+@.$+ $:$>25 $1@$2@.$3 Src Route to %-path X X# Search pathalias database XR$+@.$-.UUCP $: $(P $2 $@$1 $:$1@.$2.UUCP $) 0th: UUCP host w/o .UUCP XR$+@.$+ $: $(P $2 $@$1 $:$1@?$2 $) 1st: try full domain XR$+@$*?$-.$+ $(P .$3.$4 $@$1%$2.$3.$4 $:$1@$2.$3?$4 $) 2nd: subdomains XR$+@.$+?$- $: $(P .$3 $@$1%$2.$3 $:$1@?$2.$3 $) 3rd: try top domain X X# Found a route? XR$+@?$+ $@ $1@.$2 failure: return XR$+%.$+ $1%$2 success: remove '.' X X# Yes, canonicalize result XR$+@$+ $@$>3 $1@$2 canonicalize domains XR$+!$+ $@$>3 $1!$2 canonicalize !-paths XR$+%$+ $@$>3 $1%$2 canonicalize %-paths XR$+ $@ $1@.$w canonicalize users X}) X X######################################################################### X# # X# Rule Set #23: Route prettyprinter & compressor. # X# # X# This code rewrities RFC822 Source Routes into %-routes, which # X# most users and mail FEs understand better. It also comresses # X# "obvious" routes whenever considered necessary -- mostly just # X# for aesthetical reasons, though. If you don't like this, feel # X# free to disable it. Sendmail shouldn't break, anyway. (But # X# there will probably be others...) X# # X######################################################################### XS23 X X# Turn RFC822 Source Route into %-path XR$+@$+@.$+ $:$>25 $1@$2@.$3 X X# Remove route to well-known domain XR$+%$+.$=T$=Y$+ $:$>3 $1%$2.$3 known top domain X X# Strip routes through well-known UUCP relays XR$+%$-@.$=R $:$>3 $2!$1 known UUCP relay X Xifdef({LIUIDA},{ifdef({DOMAINTABLE},{ X# LOCAL FIX: Strip header %-routes that paranoid instances of MM produce XR$+%aida%$+@.majestix.liu.se $@ $1@.$(N aida $) AIDA's MM does this XR$+%carmen%$+@.majestix.liu.se $@ $1@.$(N carmen $) CARMEN's too X})}) X X X######################################################################### X# # X# Rule Set #24: Unqualify domains for DECnet nodes # X# # X# This is needed since DECnet has a flat namespace. All DECnet # X# nodes that are [externally] known to have a certain domain # X# name are unqualified to their corresponding DECnet host name. # X# # X######################################################################### XS24 X Xifdef({DECNETXTABLE}, { XR$+ $: ?$1 mark beginning of addrs XR$*?$*$=X$+$=Y$* $1$2$3$(D $4 $)?$5$6 scan & lookup domains XR$*?$*@.$+ $1$2@.$(D $3 $) lookup direct domain X}) Xifdef({LIUIDA},{ X# LOCAL FIX: The SUNET.SE domain only consists of DECnet nodes. XR$*$=X$-.SUNET.SE$=Y$* $1$2$3$4$5 *.SUNET.SE are on DECnet XR$+@.$-.SUNET.SE $1@.$2 dito X}) X X X######################################################################### X# # X# Rule Set #25: Translate RFC822 Source Routes into %-Paths # X# # X# This ruleset takes a (perhaps internalized) RFC822 Source # X# Route and translates it into it's %-kludgified equivalent. # X# Non-RFC822 Source Routes should pass through unharmed. # X# # X# Eg: [u@h@.a =>] @a:u@h => u%h@a # X# [@b:u@h@.a =>] @a,@b:u@h => u%h%b@a # X# [@c,@b:u@h@.a =>] @a,@b,@c:u@h => u%h%b%a%c@d # X# # X######################################################################### XS25 X X# Take care of internal mbox@.domain format XR@$+:$+@$+@.$+ $: @$4,@$1:$2@$3 move @.domain to front XR$+@$+@.$+ $: @$3:$1@$2 dito X X# Address is now real RFC822 Source Route--make sure user isn't !-path X# (an address like <@a,@b:x!y!z@c> would otherwise be rewritten as X# , which is highly ambiguous--rewrite to instead) XR@$+:$+!$+@$+ $: @$1:$>4$>3 $2!$3@$4.DUMMY rewrite last user@host XR$+.DUMMY$+ $: $1$2 remove host canon inhibitor XR@$+:$+:$+@$+ $: @$1,$2:$3@$4 merge possible double Src Route X X# Finally, the actual translation XR@$+:$+@$+ $: @$1:$2%$3? path:u@.h => path:u%h + mark XR@$+:$+@ $: @$1:$2? path:u@ => path:u + mark XR@$+$=Z$+?$* $3?%$1$4 rotate & concat XR$+%$+?$* $1@.$2$3 instantiate '%' & remove mark XR$+@.$+%$+ $1%$2@.$3 move gaze right X X X######################################################################### X# # X# Rule Set #26: Determine Mailer for Address # X# # X# Takes an address in canonical format as input and returns # X# a complete mailer specification if a mailer is known for # X# the supplied domain. Just returns the address otherwise. # X# # X######################################################################### XS26 X Xifdef({NEWALIASES}, { X# Updating aliases database -- return all addresses as local XR$+@.$w $#LOCAL $@$w $:$1 default host XR$+@.$+ $#LOCAL $@$2 $:$1@.$2 specified host X}) X X# Search for possible global alias XR$+@.$+ $: $1@.$2 ? $>4$>10$>2 $1@.$2 externalize XR$+?$+ $: $1 ? $(@ $2 $:$) search aliases XR$+@.$+?$+ $#LOCAL $@$2 $:$1@.$2 found it! XR$+? $: $1 not found, remove mark X X# Deliver to locals right away XR$+@.$=w $#LOCAL $@$2 $:$1 X Xifdef({MAILERTABLE},{ X### X### Determine delivery over specific media X### XR$+@.$+ $: $1@.$2 ? $(M $2 $: $) search mailer table XR$+@.$+?$+:$+ $#$3 $@$4 $:$>28 $1@.$2 relativize & return XR$+@.$+?$* $: $1@.$2 no match, remove mark X}) X X### X### Determine delivery over TCP/IP X### XR$+@.$*$~P $: $1@.$2$3 ? $[ $2$3 $: $] ask nameserver XR$+@.$+?$+ {$#}TCPMAILER $@$3 $:$>28 $1@.$2 relativize & return XR$+@.$+?$* $: $1@.$2 no match, remove mark X X### X### Determine delivery over XNS X### Xifdef({XNSDOMAIN}, X{R$+@.}XEROXNS {$#XNS $@xnsmail $:$1@.}XEROXNS X) X X### X### Determine delivery over DECnet X### (Kludge: Should relativize too if we had a real DECnet connection) X### Xifdef({DECNETXTABLE},{ XR$+@.$+ $: $1@.$2 ? $(D $2 $: $) check DECnet table XR$+@.$+?$=D $#DECnet $@$3 $:$1@.$2 only return real ones XR$+@.$+?$* $: $1@.$2 not found, remove mark X}) X X### X### Determine delivery over UUCP X### (Can't use ruleset 28 since we need to relativize immediate users) X### Xifdef({UUCPXTABLE},{ XR$+@.$+ $: $1@.$2 ? $(U $2 $: $) check UUCP table XR$+@.$+?$=U $: $1@.$3 replace if found real XR$+@.$+?$* $: $1@.$2 not found, remove mark X}) XR$+@.$=U.UUCP $: $1@.$2 remove pseudo domain XR$+%$+@.$=U {$#}UUCPMAILER $@$3 $:$>3 $1%$2 (canonicalize routes) XR$+@$+@.$=U {$#}UUCPMAILER $@$3 $:$>3 $1@$2 (canonicalize routes) XR$+@.$=U {$#}UUCPMAILER $@$2 $:$1 (immediate delivery) X X X######################################################################### X# # X# Rule Set #27: Simple %-Path to !-Paths Translator # X# # X# Subroutine of other address translators. Will change a # X# "a!b!c%d%e" path into "e!d!a!b!c". Typically used when # X# a message have travelled from UUCP-land into Domain land # X# (and back again). # X# # X######################################################################### XS27 X XR$+%$+ $: $1?$2 mark first % XR$+?$+%$+ $1%$2?$3 find last % XR$+?$+!$+ $@ $1%$2!$3 this is weird--don't change it XR$+?$+ $: $2!$>27 $1 put on front and recurse X X X######################################################################### X# # X# Rule Set #28: One-level route stripper # X# # X# Remove immediate host for routed addresses. Typically used # X# in ruleset 26 to produce a recipient relative to the immediate # X# host. Only to be used for routed full domains. # X# # X######################################################################### XS28 X XR$+@$+@.$+ $@$>3 $1@$2 relativize & return src route XR$+%$+@.$+ $@$>3 $1@$2 relativize & return %-path X X X######################################################################### X# # X# Rule Set #29: Multi-level self route stripper # X# # X# Remove immediate host for routed addresses if it is self. # X# Typically used in ruleset 0 to remove superfluous routing # X# info and produce a path relative to this host. # X# # X######################################################################### XS29 X XR$+@$+@.$=w $@$>29$>3 $1@$2 RFC822 Src Route XR$+%$+@.$=w $@$>29$>3 $1%$2 %-Path END_OF_ida/cf/Sendmail.mc if test 43347 -ne `wc -c