xref: /original-bsd/usr.sbin/sendmail/cf/m4/proto.m4 (revision ae4b497d)
1divert(-1)
2#
3# Copyright (c) 1983 Eric P. Allman
4# Copyright (c) 1988 The Regents of the University of California.
5# All rights reserved.
6#
7# %sccs.include.redist.sh%
8#
9divert(0)
10
11VERSIONID(`@(#)proto.m4	6.12 (Berkeley) 02/25/93')
12
13MAILER(local)dnl
14
15ifdef(`_OLD_SENDMAIL_', `dnl',
16`# level 4 config file format
17V4')
18
19##################
20#   local info   #
21##################
22
23Cwlocalhost
24ifdef(`USE_CW_FILE',
25`# file containing names of hosts for which we receive email
26Fw/etc/sendmail.cw', `dnl')
27
28ifdef(`UUCP_RELAY',
29`# UUCP relay host
30CONCAT(DY, UUCP_RELAY)
31
32')dnl
33ifdef(`BITNET_RELAY',
34`#  BITNET relay host
35CONCAT(DB, BITNET_RELAY)
36
37')dnl
38ifdef(`CSNET_RELAY',
39`# CSNET relay host
40CONCAT(DC, CSNET_RELAY)
41
42')dnl
43ifdef(`SMART_HOST',
44`# "Smart" UUCP relay host
45CONCAT(DS, SMART_HOST)
46
47')dnl
48# who I send unqualified names to (null means deliver locally)
49CONCAT(DR, ifdef(`LOCAL_RELAY', LOCAL_RELAY))
50
51# who gets all local email traffic ($R has precedence for unqualified names)
52CONCAT(DH, ifdef(`MAIL_HUB', MAIL_HUB))
53
54# my official hostname ($w or $w.$D)
55CONCAT(Dj$w, ifdef(`NEED_DOMAIN', .$D))
56
57# who I masquerade as (can be $j)
58CONCAT(DM, ifdef(`MASQUERADE_NAME', MASQUERADE_NAME, $j))
59
60# class L: names that should be delivered locally, even if we have a relay
61# class E: names that should be exposed as from this host, even if we masquerade
62CLroot
63CEroot
64undivert(5)dnl
65
66# operators that cannot be in local usernames (i.e., network indicators)
67CO @ % !
68
69# a class with just dot (for identifying canonical names)
70C..
71
72
73######################
74#   Special macros   #
75######################
76
77# SMTP initial login message
78CONCAT(De, confSMTP_LOGIN_MSG)
79
80# UNIX initial From header format
81CONCAT(Dl, confFROM_LINE)
82
83# my name for error messages
84CONCAT(Dn, confMAILER_NAME)
85
86# delimiter (operator) characters
87CONCAT(Do, confOPERATORS)
88
89# format of a total name
90CONCAT(Dq, ifdef(`confFROM_HEADER', confFROM_HEADER,
91	ifdef(`_OLD_SENDMAIL_', `$g$?x ($x)$.', `$?x$x <$g>$|$g$.')))
92include(`../m4/version.m4')
93
94###############
95#   Options   #
96###############
97
98# preserve 8 bits on message body on input?
99CONCAT(O8, confEIGHT_BIT_INPUT)
100
101# wait (in minutes) for alias file rebuild
102CONCAT(Oa, confALIAS_WAIT)
103
104# location of alias file
105CONCAT(OA, ifdef(`ALIAS_FILE', ALIAS_FILE, /etc/aliases))
106
107# minimum number of free blocks on filesystem
108CONCAT(Ob, confMIN_FREE_BLOCKS)
109
110# substitution for space (blank) characters
111CONCAT(OB, confBLANK_SUB)
112
113# connect to "expensive" mailers on initial submission?
114CONCAT(Oc, confCON_EXPENSIVE)
115
116# checkpoint queue runs after every N successful deliveries
117CONCAT(OC, confCHECKPOINT_INTERVAL)
118
119# default delivery mode
120CONCAT(Od, confDELIVERY_MODE)
121
122# automatically rebuild the alias database?
123CONCAT(OD, confAUTO_REBUILD)
124
125# error message header/file */
126ifdef(`confERROR_MESSAGE',
127	concat(OE, confERROR_MESSAGE),
128	#OE/etc/sendmail.oE)
129
130# error mode
131ifdef(`confERROR_MODE',
132	concat(Oe, confERROR_MODE),
133	#Oep)
134
135# save Unix-style "From_" lines at top of header?
136CONCAT(Of, confSAVE_FROM_LINES)
137
138# temporary file mode
139CONCAT(OF, confTEMP_FILE_MODE)
140
141# match recipients against GECOS field?
142CONCAT(OG, confMATCH_GECOS)
143
144# default GID
145CONCAT(Og, confDEF_GROUP_ID)
146
147# maximum hop count
148CONCAT(Oh, confMAX_HOP)
149
150# location of help file
151CONCAT(OH, ifdef(`HELP_FILE', HELP_FILE, /usr/lib/sendmail.hf))
152
153# ignore dots as terminators in incoming messages?
154CONCAT(Oi, confIGNORE_DOTS)
155
156# Insist that the BIND name server be running to resolve names
157ifdef(`confBIND_OPTS',
158	CONCAT(OI, confBIND_OPTS),
159	#OI)
160
161# Forward file search path
162ifdef(`confFORWARD_PATH',
163	CONCAT(OJ, confFORWARD_PATH),
164	#OJ/var/forward/$u:$z/.forward.$w:$z/.forward)
165
166# open connection cache size
167CONCAT(Ok, confMCI_CACHE_SIZE)
168
169# open connection cache timeout
170CONCAT(OK, confMCI_CACHE_TIMEOUT)
171
172# log level
173CONCAT(OL, confLOG_LEVEL)
174
175# send to me too, even in an alias expansion?
176CONCAT(Om, confME_TOO)
177
178# verify RHS in newaliases?
179CONCAT(On, confCHECK_ALIASES)
180
181# default messages to old style headers if no special punctuation?
182CONCAT(Oo, confOLD_STYLE_HEADERS)
183
184# privacy flags
185CONCAT(Op, confPRIVACY_FLAGS)
186
187# who (if anyone) should get extra copies of error messages
188ifdef(`confCOPY_ERRORS_TO',
189	CONCAT(OP, confCOPY_ERRORS_TO),
190	#OPPostmaster)
191
192# slope of queue-only function
193ifdef(`confQUEUE_FACTOR',
194	CONCAT(Oq, confQUEUE_FACTOR),
195	#Oq600000)
196
197# queue directory
198CONCAT(OQ, ifdef(`QUEUE_DIR', QUEUE_DIR, /var/spool/mqueue))
199
200# read timeout -- now OK per RFC 1123 section 5.3.2
201ifdef(`confREAD_TIMEOUT',
202	CONCAT(Or, confREAD_TIMEOUT),
203	#Ordatablock=10m)
204
205# queue up everything before forking?
206CONCAT(Os, confSAFE_QUEUE)
207
208# status file
209CONCAT(OS, ifdef(`STATUS_FILE', STATUS_FILE, /etc/sendmail.st))
210
211# default message timeout interval
212CONCAT(OT, confMESSAGE_TIMEOUT)
213
214# time zone handling:
215#  if undefined, use system default
216#  if defined but null, use TZ envariable passed in
217#  if defined and non-null, use that info
218ifelse(confTIME_ZONE, `USE_SYSTEM', `#Ot',
219	confTIME_ZONE, `USE_TZ', `',
220	`CONCAT(Ot, confTIME_ZONE)')
221
222# default UID
223CONCAT(Ou, confDEF_USER_ID)
224
225# list of locations of user database file (null means no lookup)
226CONCAT(OU, ifdef(`USERDB_SPEC', `USERDB_SPEC'))
227
228# load average at which we just queue messages
229CONCAT(Ox, confQUEUE_LA)
230
231# load average at which we refuse connections
232CONCAT(OX, confREFUSE_LA)
233
234# work recipient factor
235ifdef(`confWORK_RECIPIENT_FACTOR',
236	CONCAT(Oy, confWORK_RECIPIENT_FACTOR),
237	#Oy30000)
238
239# deliver each queued job in a separate process?
240CONCAT(OY, confSEPARATE_PROC)
241
242# work class factor
243ifdef(`confWORK_CLASS_FACTOR',
244	CONCAT(Oz, confWORK_CLASS_FACTOR),
245	#Oz1800)
246
247# work time factor
248ifdef(`confWORK_TIME_FACTOR',
249	CONCAT(OZ, confWORK_TIME_FACTOR),
250	#OZ90000)
251
252###########################
253#   Message precedences   #
254###########################
255
256Pfirst-class=0
257Pspecial-delivery=100
258Plist=-30
259Pbulk=-60
260Pjunk=-100
261
262#####################
263#   Trusted users   #
264#####################
265
266Troot
267Tdaemon
268Tuucp
269
270#########################
271#   Format of headers   #
272#########################
273
274H?P?Return-Path: <$?<$<$|$g$.>
275HReceived: $?sfrom $s $.by $j ($v/$Z) id $i; $b
276H?D?Resent-Date: $a
277H?D?Date: $a
278H?F?Resent-From: $q
279H?F?From: $q
280H?x?Full-Name: $x
281HSubject:
282# HPosted-Date: $a
283# H?l?Received-Date: $b
284H?M?Resent-Message-Id: <$t.$i@$j>
285H?M?Message-Id: <$t.$i@$j>
286undivert(6)dnl
287#
288######################################################################
289######################################################################
290#####
291#####			REWRITING RULES
292#####
293######################################################################
294######################################################################
295
296
297###########################################
298###  Rulset 3 -- Name Canonicalization  ###
299###########################################
300S3
301
302# handle null input (translate to <> special case)
303R$@			$@ <@>
304
305# basic textual canonicalization -- note RFC733 heuristic here
306R$*<$*>$*<$*>$*		<$2>$3$4$5			strip multiple <> <>
307R$*<$*<$+>$*>$*		<$3>$5				2-level <> nesting
308R$*<>$*			$@ <@>				MAIL FROM:<> case
309R$*<$+>$*		$2				basic RFC821/822 parsing
310
311# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
312R@ $+ , $+		@ $1 : $2			change all "," to ":"
313
314# localize and dispose of route-based addresses
315R@ $+ : $+		$@ $>6 < @$1 > : $2		handle <route-addr>
316
317# find focus for list syntax
318R $+ : $* ; @ $+	$@ $>6 $1 : $2 ; < @ $3 >	list syntax
319R $+ : $* ;		$@ $1 : $2;			list syntax
320
321# find focus for @ syntax addresses
322R$+ @ $+		$: $1 < @ $2 >			focus on domain
323R$+ < $+ @ $+ >		$1 $2 < @ $3 >			move gaze right
324R$+ < @ $+ >		$@ $>6 $1 < @ $2 >		already canonical
325
326# convert old-style addresses to a domain-based address
327R$- ! $+		$@ $>6 $2 < @ $1 .UUCP >	resolve uucp names
328R$+ . $- ! $+		$@ $>6 $3 < @ $1 . $2 >		domain uucps
329R$+ ! $+		$@ $>6 $2 < @ $1 .UUCP >	uucp subdomains
330
331# if we have % signs, take the rightmost one
332R$* % $*		$1 @ $2				First make them all @s.
333R$* @ $* @ $*		$1 % $2 @ $3			Undo all but the last.
334R$* @ $*		$@ $>6 $1 < @ $2 >		Insert < > and finish
335
336# else we must be a local name
337
338
339###############################################
340###  Ruleset 6 -- bottom half of ruleset 3  ###
341###############################################
342
343#  At this point, everything should be in a "local_part<@domain>extra" format.
344S6
345
346# handle special cases for local names
347R$* < @ $=w > $*		$: $1 < @ $j . > $3		no domain at all
348R$* < @ $=w . UUCP > $*		$: $1 < @ $j . > $3		.UUCP domain
349undivert(2)dnl
350
351ifdef(`UUCP_RELAY',
352`# pass UUCP addresses straight through
353R$* < @ $+ . UUCP > $*		$@ $1 < @ $2 . UUCP > $3',
354`# if really UUCP, handle it immediately
355ifdef(`_CLASS_U_',
356`R$* < @ $=U . UUCP > $*	$@ $1 < @ $2 . UUCP > $3', `dnl')
357ifdef(`_CLASS_V_',
358`R$* < @ $=V . UUCP > $*	$@ $1 < @ $2 . UUCP > $3', `dnl')
359ifdef(`_CLASS_W_',
360`R$* < @ $=W . UUCP > $*	$@ $1 < @ $2 . UUCP > $3', `dnl')
361ifdef(`_CLASS_X_',
362`R$* < @ $=X . UUCP > $*	$@ $1 < @ $2 . UUCP > $3', `dnl')
363ifdef(`_CLASS_Y_',
364`R$* < @ $=Y . UUCP > $*	$@ $1 < @ $2 . UUCP > $3', `dnl')
365
366# try UUCP traffic as a local address
367R$* < @ $+ . UUCP > $*		$: $1 < @ $[ $2 $] . UUCP > $3
368ifdef(`_OLD_SENDMAIL_',
369`R$* < @ $+ . $+ . UUCP > $*		$@ $1 < @ $2 . $3 . > $4',
370`R$* < @ $+ . . UUCP > $*		$@ $1 < @ $2 . > $3')')
371
372# pass to name server to make hostname canonical
373R$* < @ $* $~. > $*		$: $1 < @ $[ $2 $3 $] > $4
374
375# handle possible alternate names
376R$* < @ $=w . $m . > $*		$: $1 < @ $j . > $3
377R$* < @ $=w . $m > $*		$: $1 < @ $j . > $3
378undivert(8)dnl
379
380# if this is the local hostname, make sure we treat is as canonical
381R$* < @ $j > $*			$: $1 < @ $j . > $2
382
383
384##################################################
385###  Ruleset 4 -- Final Output Post-rewriting  ###
386##################################################
387S4
388
389R<@>			$@				handle <> error addr
390
391# resolve numeric addresses to name if possible
392R$* < @ [ $+ ] > $*	$: $1 < @ $[ [$2] $] > $3	lookup numeric internet addr
393
394# strip trailing dot off possibly canonical name
395R$* < @ $+ . > $*	$1 < @ $2 > $3
396
397# externalize local domain info
398R$* < $+ > $*		$1 $2 $3			defocus
399R@ $+ : @ $+ : $+	@ $1 , @ $2 : $3		<route-addr> canonical
400R@ $*			$@ @ $1				... and exit
401
402# UUCP must always be presented in old form
403R$+ @ $- . UUCP		$2!$1				u@h.UUCP => h!u
404
405# delete duplicate local names
406R$+ % $=w @ $=w		$1 @ $j				u%host@host => u@host
407
408
409
410#############################################################
411###   Ruleset 7 -- recanonicalize and call ruleset zero   ###
412###		   (used for recursive calls)		  ###
413#############################################################
414
415S7
416R$*			$: $>3 $1
417R$*			$@ $>0 $1
418
419
420######################################
421###   Ruleset 0 -- Parse Address   ###
422######################################
423
424S0
425
426ifdef(`_MAILER_smtp_',
427`# handle numeric address spec
428R$* < @ [ $+ ] > $*	$: $1 < @ $[ [$2] $] > $3	numeric internet addr
429R$* < @ [ $+ ] > $*	$#smtp $@ [$2] $: $1 @ [$2] $3	numeric internet spec',
430`dnl')
431
432# now delete the local info -- note $=O to find characters that cause forwarding
433R< @ $j . > : $*	$@ $>7 $1			@here:... -> ...
434R$* $=O $* < @ $j . >	$@ $>7 $1 $2 $3			...@here -> ...
435
436# short circuit local delivery so forwarded email works
437R$+ < @ $j . >		$: $1 < @ $j @ $H >		first try hub
438ifdef(`_OLD_SENDMAIL_',
439`R$+ < $+ @ $-:$+ >	$# $3 $@ $4 $: $1 < $2 >	yep ....
440R$+ < $+ @ $+ >		$#smtp $@ $3 $: $1 < $2 >	yep ....
441R$+ < $+ @ >		$#local $: $1			nope, local address',
442`R$+ < $+ @ $+ >		$#local $: $1			yep ....
443R$+ < $+ @ >		$#local $: @ $1			nope, local address')
444undivert(3)dnl
445undivert(4)dnl
446
447# resolve remotely connected UUCP links (if any)
448ifdef(`_CLASS_V_',
449`R$* < @ $=V . UUCP > $*		$#smtp $@ $V $: <@ $V> : $1 @ $2.UUCP $3',
450	`dnl')
451ifdef(`_CLASS_W_',
452`R$* < @ $=W . UUCP > $*		$#smtp $@ $W $: <@ $W> : $1 @ $2.UUCP $3',
453	`dnl')
454ifdef(`_CLASS_X_',
455`R$* < @ $=X . UUCP > $*		$#smtp $@ $X $: <@ $X> : $1 @ $2.UUCP $3',
456	`dnl')
457
458# resolve fake top level domains by forwarding to other hosts
459ifdef(`BITNET_RELAY',
460`R$*<@$+.BITNET>$*	$#smtp $@ $B $: $1 <@$2.BITNET> $3	user@host.BITNET',
461	`dnl')
462ifdef(`CSNET_RELAY',
463`R$*<@$+.CSNET>$*	$#smtp $@ $C $: $1 <@$2.CSNET> $3	user@host.CSNET',
464	`dnl')
465
466ifdef(`UUCP_RELAY',
467`# forward non-local UUCP traffic to our UUCP relay
468R$*<@$*.UUCP>$*		$#smtp $@ $Y $: <@ $Y> : $1 @ $2.UUCP $3	uucp mail',
469`ifdef(`_MAILER_uucp_',
470`# forward other UUCP traffic straight to UUCP
471R< @ $+ .UUCP > : $+	$#uucp $@ $1 $: $1:$2			@host.UUCP:...
472R$+ < @ $+ .UUCP >	$#uucp $@ $2 $: $1			user@host.UUCP',
473	`dnl')')
474
475ifdef(`_LOCAL_RULES_',
476`# figure out what should stay in our local mail system
477undivert(1)',
478`ifdef(`_MAILER_smtp_',
479`# deal with other remote names
480R$* < @ $* > $*		$#smtp $@ $2 $: $1 < @ $2 > $3		user@host.domain')')
481ifdef(`SMART_HOST', `
482# pass names that still have a host to a smarthost
483R$* < @ $* > $*		$: < $S > $1 < @ $2 > $3	glue on smarthost name
484R<$-:$+> $* < @$* > $*	$# $1 $@ $2 $: $3 < @ $4 > $5	if non-null, use it
485R<$+> $* < @$* > $*	$#suucp $@ $1 $: $2 < @ $3 > $4	if non-null, use it
486R<> $* < @ $* > $*	$1 < @ $2 > $3			else strip off gunk',
487`ifdef(`_LOCAL_RULES_', `
488# reject messages that have host names we do not understand
489R$* < @ $* > $*		$#error $@ NOHOST $: Unrecognized host name $2',
490`dnl')')
491ifdef(`_MAILER_USENET_', `
492# addresses sent to net.group.USENET will get forwarded to a newsgroup
493R$+ . USENET		$# usenet $: $1')
494
495ifdef(`_OLD_SENDMAIL_',
496`# forward remaining names to local relay, if any
497R$=L			$#local $: $1			special local names
498R$+			$: $1 < @ $R >			append relay
499R$+ < @ >		$: $1 < @ $H >			no relay, try hub
500R$+ < @ >		$#local $: $1			no relay or hub: local
501R$+ < @ $j  >		$#local $: $1			we are relay/hub: local
502R$+ < @ $-:$+ >		$# $2 $@ $3 $: $1		deliver to relay/hub
503R$+ < @ $+ >		$#smtp $@ $2 $: $1		deliver to relay/hub',
504`# handle locally delivered names
505R$=L			$#local $: @ $1			special local names
506R$+			$#local $: $1			regular local names
507
508###########################################################################
509###   Ruleset 5 -- special rewriting after aliases have been expanded   ###
510###		   (new sendmail only)					###
511###########################################################################
512
513S5
514
515ifdef(`_MAILER_smtp_',
516`R$+			$: $1 < @ $R >
517R$+ < @ >		$: $1 < @ $H >			no relay, try hub
518R$+ < @ $j >		$@ $1				we are relay/hub: local
519R$+ < @ $-:$+ >		$# $2 $@ $3 $: $1		send to relay or hub
520R$+ < @ $+ >		$#smtp $@ $2 $: $1		send to relay or hub')')
521#
522######################################################################
523######################################################################
524#####
525`#####			MAILER DEFINITIONS'
526#####
527######################################################################
528######################################################################
529undivert(7)dnl
530