mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-23 02:04:46 +00:00
Add a FREEBSD-upgrade file describing what was done for the import
Remove obsolete files after the 8.11.0 import
This commit is contained in:
parent
3299c2f123
commit
cd904b75f9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64566
49
contrib/sendmail/FREEBSD-upgrade
Normal file
49
contrib/sendmail/FREEBSD-upgrade
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
$FreeBSD$
|
||||||
|
|
||||||
|
sendmail 8.11.0
|
||||||
|
originals can be found at: ftp://ftp.sendmail.org/pub/sendmail/
|
||||||
|
|
||||||
|
For the import of sendmail, the following files were removed:
|
||||||
|
|
||||||
|
cf/cf/generic-bsd4.4.cf
|
||||||
|
cf/cf/generic-hpux10.cf
|
||||||
|
cf/cf/generic-hpux9.cf
|
||||||
|
cf/cf/generic-linux.cf
|
||||||
|
cf/cf/generic-osf1.cf
|
||||||
|
cf/cf/generic-solaris2.cf
|
||||||
|
cf/cf/generic-sunos4.1.cf
|
||||||
|
cf/cf/generic-ultrix4.cf
|
||||||
|
devtools/*
|
||||||
|
doc/op/op.ps
|
||||||
|
mail.local/mail.local.0
|
||||||
|
mailstats/mailstats.0
|
||||||
|
makemap/makemap.0
|
||||||
|
praliases/praliases.0
|
||||||
|
rmail/rmail.0
|
||||||
|
sendmail/aliases.0
|
||||||
|
sendmail/mailq.0
|
||||||
|
sendmail/newaliases.0
|
||||||
|
sendmail/sendmail.0
|
||||||
|
sendmail/sysexits.h
|
||||||
|
smrsh/smrsh.0
|
||||||
|
vacation/vacation.0
|
||||||
|
|
||||||
|
The following directories were renamed:
|
||||||
|
|
||||||
|
sendmail -> src
|
||||||
|
|
||||||
|
Imported using:
|
||||||
|
|
||||||
|
cvs import -m 'Import sendmail 8.11.0' \
|
||||||
|
src/contrib/sendmail SENDMAIL v8_11_0
|
||||||
|
|
||||||
|
|
||||||
|
To make local changes to sendmail, simply patch and commit to the main
|
||||||
|
branch (aka HEAD). Never make local changes on the vendor (SENDMAIL)
|
||||||
|
branch.
|
||||||
|
|
||||||
|
All local changes should be submitted to the Sendmail Consortium
|
||||||
|
<sendmail@sendmail.org> for inclusion in the next vendor release.
|
||||||
|
|
||||||
|
gshapiro@FreeBSD.org
|
||||||
|
12-August-2000
|
|
@ -1,113 +0,0 @@
|
||||||
divert(-1)
|
|
||||||
#
|
|
||||||
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
# Copyright (c) 1983, 1995 Eric P. Allman. All rights reserved.
|
|
||||||
# Copyright (c) 1988, 1993
|
|
||||||
# The Regents of the University of California. All rights reserved.
|
|
||||||
#
|
|
||||||
# By using this file, you agree to the terms and conditions set
|
|
||||||
# forth in the LICENSE file which can be found at the top level of
|
|
||||||
# the sendmail distribution.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
divert(0)
|
|
||||||
|
|
||||||
VERSIONID(`@(#)nullrelay.m4 8.19 (Berkeley) 5/19/1998')
|
|
||||||
|
|
||||||
#
|
|
||||||
# This configuration applies only to relay-only hosts. They send
|
|
||||||
# all mail to a hub without consideration of the address syntax
|
|
||||||
# or semantics, except for adding the hub qualification to the
|
|
||||||
# addresses.
|
|
||||||
#
|
|
||||||
# This is based on a prototype done by Bryan Costales of ICSI.
|
|
||||||
#
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
######################################################################
|
|
||||||
#####
|
|
||||||
##### REWRITING RULES
|
|
||||||
#####
|
|
||||||
######################################################################
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
###########################################
|
|
||||||
### Rulset 3 -- Name Canonicalization ###
|
|
||||||
###########################################
|
|
||||||
S3
|
|
||||||
|
|
||||||
# handle null input
|
|
||||||
R$@ $@ <@>
|
|
||||||
|
|
||||||
# strip group: syntax (not inside angle brackets!) and trailing semicolon
|
|
||||||
R$* $: $1 <@> mark addresses
|
|
||||||
R$* < $* > $* <@> $: $1 < $2 > $3 unmark <addr>
|
|
||||||
R$* :: $* <@> $: $1 :: $2 unmark node::addr
|
|
||||||
R:`include': $* <@> $: :`include': $1 unmark :`include':...
|
|
||||||
R$* : $* <@> $: $2 strip colon if marked
|
|
||||||
R$* <@> $: $1 unmark
|
|
||||||
R$* ; $1 strip trailing semi
|
|
||||||
R$* < $* ; > $1 < $2 > bogus bracketed semi
|
|
||||||
|
|
||||||
# null input now results from list:; syntax
|
|
||||||
R$@ $@ :; <@>
|
|
||||||
|
|
||||||
# basic textual canonicalization -- note RFC733 heuristic here
|
|
||||||
R$* $: < $1 > housekeeping <>
|
|
||||||
R$+ < $* > < $2 > strip excess on left
|
|
||||||
R< $* > $+ < $1 > strip excess on right
|
|
||||||
R<> $@ < @ > MAIL FROM:<> case
|
|
||||||
R< $+ > $: $1 remove housekeeping <>
|
|
||||||
|
|
||||||
ifdef(`_NO_CANONIFY_', `dnl',
|
|
||||||
`# eliminate local host if present
|
|
||||||
R@ $=w $=: $+ $@ @ $M $2 $3 @thishost ...
|
|
||||||
R@ $+ $@ @ $1 @somewhere ...
|
|
||||||
|
|
||||||
R$=E @ $=w $@ $1 @ $2 leave exposed
|
|
||||||
R$+ @ $=w $@ $1 @ $M ...@thishost
|
|
||||||
R$+ @ $+ $@ $1 @ $2 ...@somewhere
|
|
||||||
|
|
||||||
R$=w ! $=E $@ $2 @ $1 leave exposed
|
|
||||||
R$=w ! $+ $@ $2 @ $M thishost!...
|
|
||||||
R$+ ! $+ $@ $1 ! $2 @ $M somewhere ! ...
|
|
||||||
|
|
||||||
R$=E % $=w $@ $1 @ $2 leave exposed
|
|
||||||
R$+ % $=w $@ $1 @ $M ...%thishost
|
|
||||||
R$+ % $+ $@ $1 @ $2 ...%somewhere
|
|
||||||
|
|
||||||
R$=E $@ $1 @ $j leave exposed
|
|
||||||
R$+ $@ $1 @ $M unadorned user')
|
|
||||||
|
|
||||||
|
|
||||||
######################################
|
|
||||||
### Ruleset 0 -- Parse Address ###
|
|
||||||
######################################
|
|
||||||
|
|
||||||
S0
|
|
||||||
|
|
||||||
R$*:;<@> $#error $@ USAGE $: "List:; syntax illegal for recipient addresses"
|
|
||||||
|
|
||||||
# pass everything else to a relay host
|
|
||||||
R$* $#_RELAY_ $@ $H $: $1
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
### Ruleset 4 -- Final Output Post-rewriting ###
|
|
||||||
##################################################
|
|
||||||
S4
|
|
||||||
|
|
||||||
R$* <@> $@ handle <> and list:;
|
|
||||||
|
|
||||||
# strip trailing dot off before passing to nullclient relay
|
|
||||||
R$* @ $+ . $1 @ $2
|
|
||||||
|
|
||||||
#
|
|
||||||
######################################################################
|
|
||||||
######################################################################
|
|
||||||
#####
|
|
||||||
`##### MAILER DEFINITIONS'
|
|
||||||
#####
|
|
||||||
######################################################################
|
|
||||||
######################################################################
|
|
||||||
undivert(7)dnl
|
|
|
@ -1,20 +0,0 @@
|
||||||
divert(-1)
|
|
||||||
#
|
|
||||||
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
# Copyright (c) 1997 Eric P. Allman. All rights reserved.
|
|
||||||
# Copyright (c) 1988, 1993
|
|
||||||
# The Regents of the University of California. All rights reserved.
|
|
||||||
#
|
|
||||||
# By using this file, you agree to the terms and conditions set
|
|
||||||
# forth in the LICENSE file which can be found at the top level of
|
|
||||||
# the sendmail distribution.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
divert(0)
|
|
||||||
VERSIONID(`@(#)gnuhurd.m4 8.8 (Berkeley) 10/6/1998')
|
|
||||||
ifdef(`HELP_FILE',, `define(`HELP_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/helpfile', `/share/misc/sendmail.hf'))')dnl
|
|
||||||
ifdef(`STATUS_FILE',, `define(`STATUS_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/statistics', `/var/log/sendmail.st'))')dnl
|
|
||||||
ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /libexec/mail.local)')dnl
|
|
||||||
define(`confEBINDIR', `/libexec')dnl
|
|
|
@ -1,446 +0,0 @@
|
||||||
|
|
||||||
Converting Standard Sun Config
|
|
||||||
Files to Sendmail Version 8
|
|
||||||
|
|
||||||
Rick McCarty
|
|
||||||
Texas Instruments Inc.
|
|
||||||
Latest Update: 08/25/93 - RJMc
|
|
||||||
|
|
||||||
This document details the changes necessary to continue using your
|
|
||||||
current SunOS sendmail.cf with sendmail version 8. In the longer term,
|
|
||||||
it is recommended that one move to using an m4 based configuration such
|
|
||||||
as those shipped with sendmail, but if you're like me and have made
|
|
||||||
enough modifications to your .cf file that you'd rather put that task
|
|
||||||
off until later, here's the sum total of my experience to get you to
|
|
||||||
version 8 with minimal pain. I'll cover .cf as well as build issues.
|
|
||||||
|
|
||||||
Some background - as many are surely aware, Sun has some "special"
|
|
||||||
features in the sendmail they ship ($%x, %y LHS lookup, NIS alias DB
|
|
||||||
search, etc.). (Some of those features can be had in alternative forms
|
|
||||||
in IDA sendmail, but v8 has picked up some IDA capabilities as well as
|
|
||||||
new ones, making it IMHO a most desirable version to go to.) What I
|
|
||||||
will explain below includes v8 functional "equivalences" to these Sun
|
|
||||||
sendmail features.
|
|
||||||
|
|
||||||
So with that out of the way, let's begin.
|
|
||||||
|
|
||||||
First, some assumptions:
|
|
||||||
|
|
||||||
1) I'm going to assume you've got sendmail version 8.6 or
|
|
||||||
later in hand - if not, grab it from ftp.cs.berkeley.edu
|
|
||||||
in the ucb/sendmail directory. There are bugs in earlier
|
|
||||||
versions which affect some of the needed functionality.
|
|
||||||
|
|
||||||
2) Second, I'm going to detail this based upon the
|
|
||||||
"sendmail.main.cf" configuration. (BTW, if you attempt
|
|
||||||
to move to using an m4 generated config in the future,
|
|
||||||
MAIL_HUB is the feature which should provide similar
|
|
||||||
functionality).
|
|
||||||
|
|
||||||
In general, the changes will be similar for a subsidiary
|
|
||||||
file, but since we (my TI group) funnel all non-local mail
|
|
||||||
through our mailhost, we're not as interested in getting v8
|
|
||||||
to run on such systems and I haven't tried it.
|
|
||||||
|
|
||||||
3) You're using DNS and sendmail.mx. If you're not, you ought
|
|
||||||
to be, even if you're also running it along with NIS (which
|
|
||||||
we do - except for gethostbyxxx() lookups, which I'll be
|
|
||||||
talking about later). I would imagine you could get things
|
|
||||||
running OK without DNS support, but I haven't tried it myself.
|
|
||||||
|
|
||||||
4) You're not mounting /var/spool/mail from other systems.
|
|
||||||
I haven't found a v8 feature to guarantee this will work
|
|
||||||
correctly. Anyway, in the past, we've tried doing that
|
|
||||||
here and found it to be a rather "ugly" feature, though
|
|
||||||
Sun ostensibly supports it ("R" option). Perhaps v8
|
|
||||||
will one day have a similar feature, but for now, bottom
|
|
||||||
line, I would recommend against it.
|
|
||||||
|
|
||||||
5) You're not on Solaris or using NIS+. I'm on 4.1.3. I've
|
|
||||||
looked at Solaris briefly and have noted that things are
|
|
||||||
pretty much similar there except that they've moved some
|
|
||||||
things into the /etc/mail directory. I'd guess the
|
|
||||||
executables aren't functionally all that different from
|
|
||||||
what they had before - the configs are roughly the same.
|
|
||||||
So I'd bet most of what I say in here will apply to
|
|
||||||
Solaris.
|
|
||||||
|
|
||||||
OK, let's configure our sendmail.cf! I'll just go from the top down...
|
|
||||||
|
|
||||||
VARIOUS DECLARATIONS
|
|
||||||
|
|
||||||
1) For v8, you need to define your .cf as AT LEAST a version level 4
|
|
||||||
configuration. Add the following line:
|
|
||||||
|
|
||||||
V4
|
|
||||||
|
|
||||||
There are some issues regarding certain predefined macros - $w, $j, and
|
|
||||||
$m. With a V4 configuration:
|
|
||||||
|
|
||||||
$w is defined to be the hostname, which will usually be fully
|
|
||||||
qualified (i.e. "firefly.add.itg.ti.com").
|
|
||||||
|
|
||||||
$j should have the same value as $w.
|
|
||||||
|
|
||||||
$m will be predefined as the domain portion of $w
|
|
||||||
(ex. "add.itg.ti.com").
|
|
||||||
|
|
||||||
One note about this - if your configuration relies on the "w" macro to
|
|
||||||
be the "simple" hostname (as mine does)...
|
|
||||||
|
|
||||||
If the configuration version is 5 or larger:
|
|
||||||
|
|
||||||
$w is supposed to be the "simple" name (ex. "firefly")
|
|
||||||
|
|
||||||
$j should be the fully qualified name (i.e. "firefly.add.itg.ti.com")
|
|
||||||
|
|
||||||
$m will be predefined as the domain portion of $j
|
|
||||||
(ex. "add.itg.ti.com").
|
|
||||||
|
|
||||||
I have not experimented with the various combinations, so I cannot
|
|
||||||
guarantee you that the above definitions will always come out as
|
|
||||||
expected. Bottom line: if your sendmail.cf depends on $w being the
|
|
||||||
simple hostname, test it carefully or define the name explicitly,
|
|
||||||
for example:
|
|
||||||
|
|
||||||
Dwfirefly
|
|
||||||
|
|
||||||
2) To replace the Sun's "%y" feature, we must use a hostname mapping
|
|
||||||
feature in v8. If you want to do similar lookups with v8, you need
|
|
||||||
to define the following map (we'll go over the rules that use this
|
|
||||||
map later):
|
|
||||||
|
|
||||||
Khostlookup host -f -m -a.
|
|
||||||
|
|
||||||
This will define a "lookup only" map that is otherwise the same as
|
|
||||||
sendmail version 8's built-in "host" map (see the "Sendmail
|
|
||||||
Installation and Operation Guide" for details on this map.).
|
|
||||||
|
|
||||||
An important note: Whether or not these lookups will be done via
|
|
||||||
NIS is a function of what gethostbyxxx() functions you link into
|
|
||||||
your sendmail. DO NOT redefine your host mapping to use NIS
|
|
||||||
explicitly within sendmail - there can be unexpected behaviour if
|
|
||||||
you do so (if you do any canonicalization in your .cf, you can get
|
|
||||||
incorrect results, for one thing).
|
|
||||||
|
|
||||||
For example, DO NOT TRY:
|
|
||||||
|
|
||||||
Khost nis -f -a. hosts.byname
|
|
||||||
|
|
||||||
3) If you're doing reverse alias mapping as done in ruleset 22, instead of:
|
|
||||||
|
|
||||||
DZmail.byaddr
|
|
||||||
|
|
||||||
you'll need to declare the following:
|
|
||||||
|
|
||||||
Kaliasrev nis -f -N mail.byaddr
|
|
||||||
|
|
||||||
4) If you are doing any other NIS map lookups, you'll need to define the
|
|
||||||
map as done in the below example. I have a "mailhosts" map, which I
|
|
||||||
use to distinguish between local and non-local hosts. Look at the
|
|
||||||
sendmail doc for details on this stuff.
|
|
||||||
|
|
||||||
Kmailhosts nis -f -m -a. mailhosts
|
|
||||||
|
|
||||||
5) You might wish to add the following line to support Errors-To: headers.
|
|
||||||
I don't.
|
|
||||||
|
|
||||||
Ol
|
|
||||||
|
|
||||||
6) Comment out/remove the following line:
|
|
||||||
|
|
||||||
OR
|
|
||||||
|
|
||||||
The R option means something different under v8 - check the documentation
|
|
||||||
if you're interested in using it.
|
|
||||||
|
|
||||||
7) If you're running NIS and have a separate alias map, BELOW the
|
|
||||||
following line where the alias file is declared:
|
|
||||||
|
|
||||||
OA/etc/aliases
|
|
||||||
|
|
||||||
ADD the following:
|
|
||||||
|
|
||||||
OAnis:mail.aliases
|
|
||||||
|
|
||||||
This will set things up so v8 will look at the local alias DB first,
|
|
||||||
then the NIS map, just as Sun sendmail does.
|
|
||||||
|
|
||||||
8) Though you don't have to, I'd suggest changing:
|
|
||||||
|
|
||||||
OT3d
|
|
||||||
|
|
||||||
to use v8's warning feature, which allows a warning message to be
|
|
||||||
sent if a message cannot be delivered within a specified period.
|
|
||||||
I use:
|
|
||||||
|
|
||||||
OT5d/4h
|
|
||||||
|
|
||||||
which says - bounce after 5 days, warn after 4 hours.
|
|
||||||
|
|
||||||
9) I set the following option to be explicit about how I want DNS
|
|
||||||
handled:
|
|
||||||
|
|
||||||
OI +DNSRCH +DEFNAMES
|
|
||||||
|
|
||||||
10) The following line:
|
|
||||||
|
|
||||||
T root daemon uucp
|
|
||||||
|
|
||||||
may be deleted, though it will be ignored if you leave it around.
|
|
||||||
|
|
||||||
11) It would probably be good to change the version macro value (which
|
|
||||||
shows up in "Received:" headers) so no one debugging mail problems
|
|
||||||
gets the wrong idea about what config you're running under. Look
|
|
||||||
for something like:
|
|
||||||
|
|
||||||
DVSMI-4.1
|
|
||||||
|
|
||||||
Mine, for example is:
|
|
||||||
|
|
||||||
DVADD-HUB-2.1
|
|
||||||
|
|
||||||
RULESETS
|
|
||||||
|
|
||||||
1) In ruleset 3, BELOW this rule:
|
|
||||||
|
|
||||||
# basic textual canonicalization
|
|
||||||
R$*<$+>$* $2 basic RFC822 parsing
|
|
||||||
|
|
||||||
|
|
||||||
I add the following rule to remove a trailing dot in the domain spec so
|
|
||||||
it won't interfere with v8 mapping features, etc. (Having a trailing dot is
|
|
||||||
not RFC-compliant anyway.):
|
|
||||||
|
|
||||||
R$+. $1
|
|
||||||
|
|
||||||
2) Because ruleset 5 is special in v8, I rename it to S95 and also change
|
|
||||||
all RHS expressions containing ">5" to use ">95" instead. In v8,
|
|
||||||
5 is executed against addresses which resolve to the local mailer and
|
|
||||||
are not an alias. If you don't change S5 to something else, you might
|
|
||||||
get a surprise!
|
|
||||||
|
|
||||||
3) If you're doing any lookups via the generalized NIS "$%x/$!x"
|
|
||||||
mechanisms (such as with the mailhost map I referred to earlier) it's
|
|
||||||
done differently under v8. For example:
|
|
||||||
|
|
||||||
DMmailhosts
|
|
||||||
...
|
|
||||||
R$*<@$%M.uucp>$* $#ether $@$2 $:$1<@$2>$3
|
|
||||||
|
|
||||||
takes a different map definition and two rules under version 8:
|
|
||||||
|
|
||||||
Kmailhosts nis -f -m -a. mailhosts
|
|
||||||
...
|
|
||||||
R$*<@$+.uucp>$* $: $1<@$(mailhosts $2 $).uucp>$3
|
|
||||||
R$*<@$+..uucp>$* $#ether $@$2 $:$1<@$2>$3
|
|
||||||
|
|
||||||
4) Sun has a special case of the "$%x" feature for host lookups - "%y" is
|
|
||||||
automagically defined to do an NIS "hosts.byname" search with no other
|
|
||||||
definition, as done in the below example:
|
|
||||||
|
|
||||||
R$*<@$%y.LOCAL>$* $#ether $@$2 $:$1<@$2>$3
|
|
||||||
|
|
||||||
(Sun does this in more than one place. But the above syntax is almost
|
|
||||||
identical in each - mostly a case of changing names to protect the
|
|
||||||
innocent.)
|
|
||||||
|
|
||||||
In version 8, the predefined "host" map can be used to do essentially
|
|
||||||
the same thing. (However, whether or not it does an NIS lookup is
|
|
||||||
a function of what gethostbyxxx() functions are linked in.)
|
|
||||||
|
|
||||||
Recall the map definition I mentioned earlier in the DECLARATIONS
|
|
||||||
section:
|
|
||||||
|
|
||||||
Khostlookup host -f -m -a.
|
|
||||||
|
|
||||||
Here's where we will use it. It will take two rules:
|
|
||||||
|
|
||||||
R$*<@$+.LOCAL>$* $: $1<@$(hostlookup $2 $).LOCAL>$3
|
|
||||||
R$*<@$+..LOCAL>$* $#ether $@$2 $:$1<@$2>$3
|
|
||||||
|
|
||||||
Note that this is almost verbatim the same change as was used in the
|
|
||||||
previous "mailhosts" example.
|
|
||||||
|
|
||||||
5) Although Sun's default configs don't do this, because I mentioned
|
|
||||||
canonicalization earlier, it deserves an example, as it's illustrative
|
|
||||||
of the functional difference in the map definitions I discussed before.
|
|
||||||
This stuff is also convered in the "Sendmail Installation and Operation
|
|
||||||
Guide".
|
|
||||||
|
|
||||||
Remember the built-in "host" map definition? As you'll recall, unlike
|
|
||||||
the "hostlookup" map we defined, "host" will actually CHANGE the
|
|
||||||
hostname in addition to appending a dot. "hostlookup" only appends a
|
|
||||||
dot if the name is found and doesn't change it otherwise. Anyway,
|
|
||||||
here's the example:
|
|
||||||
|
|
||||||
R$*<@$+>$* $: $1<@$(host $2 $)>$3 canonicalize
|
|
||||||
R$*<@$+.>$* $1<@$2>$3 remove trailing dot
|
|
||||||
|
|
||||||
Using the above, say you had input of:
|
|
||||||
|
|
||||||
joe<@tilde>
|
|
||||||
|
|
||||||
OR
|
|
||||||
|
|
||||||
joe<@[128.247.160.56]>
|
|
||||||
|
|
||||||
Assuming "tilde" or the IP address is found, it might be
|
|
||||||
canonicalized as:
|
|
||||||
|
|
||||||
joe<@tilde.csc.ti.com>
|
|
||||||
|
|
||||||
6) As another instance of the NIS lookup feature, with a slightly
|
|
||||||
different twist, Sun implements reverse alias mapping in ruleset 22
|
|
||||||
with the below:
|
|
||||||
|
|
||||||
DZmail.byaddr
|
|
||||||
...
|
|
||||||
R$-<@$-> $:$>3${Z$1@$2$} invert aliases
|
|
||||||
|
|
||||||
To use this feature under v8, change the above rule a (remember to
|
|
||||||
define the alias map as I showed earlier):
|
|
||||||
|
|
||||||
R$-<@$-> $:$>3$(aliasrev $1@$2 $) invert aliases
|
|
||||||
|
|
||||||
|
|
||||||
MAILER DEFINITIONS
|
|
||||||
|
|
||||||
1) Where "TCP" is defined in the "P=" and "A=" parameters of mailers, I
|
|
||||||
changed it to "IPC". Version 8 will accept "TCP", but "IPC" is
|
|
||||||
preferred.
|
|
||||||
|
|
||||||
2) On all IPC mailers, I also defined "E=\r\n" and added an "L=1000" as
|
|
||||||
in the below example:
|
|
||||||
|
|
||||||
Mether, P=[IPC], F=mDFMuCX, S=11, R=21, L=1000, E=\r\n, A=IPC $h
|
|
||||||
|
|
||||||
The "E=\r\n" will save you headaches interoperating with such things as
|
|
||||||
VMS TCP products.
|
|
||||||
|
|
||||||
The "L=1000" is for RFC821 compatibility. Not strictly necessary.
|
|
||||||
|
|
||||||
I also removed the "s" (strip quotes) mailer flag Sun puts in for
|
|
||||||
these mailers. Stripping quotes violates protocols, which say
|
|
||||||
clearly that you can't touch the local-part (left hand side of
|
|
||||||
the @) until you are on the delivering host.
|
|
||||||
|
|
||||||
NOW. If I haven't left anything out, you should be able to run through
|
|
||||||
your Sun sendmail.cf file and convert it to run under v8.
|
|
||||||
|
|
||||||
BUILD ISSUES
|
|
||||||
|
|
||||||
Some important notes on building v8 on SunOS:
|
|
||||||
|
|
||||||
Makefile
|
|
||||||
|
|
||||||
The default makefile in the version 8 source (src) directory assumes the
|
|
||||||
new Berkeley make. Unless you want to go to the trouble of building it,
|
|
||||||
you can use your regular make, but you need to use a different makefile.
|
|
||||||
You can use "Makefile.dist" or "Makefile.SunOS" in the src directory. I
|
|
||||||
made changes to get it to build so it is as compatible as possible with
|
|
||||||
the file/directory locations Sun uses. Here are some relevant sections
|
|
||||||
out of my makefile:
|
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
|
|
||||||
# use O=-O (usual) or O=-g (debugging)
|
|
||||||
O= -O
|
|
||||||
|
|
||||||
# define the database mechanisms available for map & alias lookups:
|
|
||||||
# -DNDBM -- use new DBM
|
|
||||||
# -DNEWDB -- use new Berkeley DB
|
|
||||||
# -DNDBM -DNEWDB -DYPCOMPAT -- use both plus YP compatility
|
|
||||||
# -DNIS -- include client NIS support
|
|
||||||
# The really old (V7) DBM library is no longer supported.
|
|
||||||
# See README for a description of how these flags interact.
|
|
||||||
#DBMDEF= -DNDBM -DNEWDB
|
|
||||||
DBMDEF= -DNDBM -DNIS
|
|
||||||
|
|
||||||
# environment definitions (e.g., -D_AIX3)
|
|
||||||
ENVDEF=
|
|
||||||
|
|
||||||
# see also conf.h for additional compilation flags
|
|
||||||
|
|
||||||
# library directories
|
|
||||||
LIBDIRS=-L/usr/local/lib
|
|
||||||
|
|
||||||
# libraries required on your system
|
|
||||||
#LIBS= -ldb -ldbm
|
|
||||||
LIBS= -ldbm -lresolv
|
|
||||||
|
|
||||||
# location of sendmail binary (usually /usr/sbin or /usr/lib)
|
|
||||||
BINDIR= ${DESTDIR}/usr/lib
|
|
||||||
|
|
||||||
# location of sendmail.st file (usually /var/log or /usr/lib)
|
|
||||||
STDIR= ${DESTDIR}/etc
|
|
||||||
|
|
||||||
# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
|
|
||||||
HFDIR= ${DESTDIR}/usr/lib
|
|
||||||
|
|
||||||
For the resolver library, you can use the one shipped with Sun if you
|
|
||||||
want. But I'd recommend using another version of the resolver library
|
|
||||||
(such as the one with Bind 4.8.3 or 4.9). Sun's resolver stuff (at
|
|
||||||
least with 4.1.x) is quite old - I believe it is of 4.3.1 vintage. (Do
|
|
||||||
you get the impression I don't TRUST what Sun ships with their systems?)
|
|
||||||
|
|
||||||
If you want NIS host lookup while maintaining DNS capability, you might
|
|
||||||
take a look at resolv+, which has NIS capable gethostbyxxx() functions
|
|
||||||
in it. My recommendation, however, is to avoid doing NIS host lookups
|
|
||||||
in sendmail altogether, and to use a "pure" version of the resolver
|
|
||||||
library.
|
|
||||||
|
|
||||||
There are probably no situations (at least I think so) where it makes
|
|
||||||
any sense to link in Sun's NIS gethostbyxxx() functions from libc.
|
|
||||||
You could, I guess do it (I haven't tried it) and wind up with a
|
|
||||||
sendmail equivalent to the non-mx version Sun ships. You'd need to
|
|
||||||
insure that NAMED_BIND is not defined in the build. (If you do
|
|
||||||
this and have the "-b" DNS passthru option set in NIS, remember that
|
|
||||||
while you have some DNS functionality you'll not have any MX support.
|
|
||||||
(This, IMO, is what makes this a non-optimal choice.)
|
|
||||||
|
|
||||||
INSTALLATION/TESTING ISSUES
|
|
||||||
|
|
||||||
The sendmail.hf file in the src directory should replace the one currently
|
|
||||||
in /usr/lib. You also might choose to edit it a bit to "localize" what it
|
|
||||||
says.
|
|
||||||
|
|
||||||
The sendmail executable goes, of course, in /usr/lib in place of the current
|
|
||||||
one. What I did was create a subdirectory in /usr/lib and put all of the
|
|
||||||
Sun sendmail stuff in there. I named the v8 sendmail executable to be
|
|
||||||
sendmail.v8.mx and then symbolically linked it to sendmail.
|
|
||||||
|
|
||||||
One other thing. If you use address test mode, keep in mind that
|
|
||||||
Version 8 is like IDA in that it does not automatically execute ruleset
|
|
||||||
3 first. So say you're playing around with things testing addresses and
|
|
||||||
you're used to things like:
|
|
||||||
|
|
||||||
0 jimbob@good.old.boy.com
|
|
||||||
|
|
||||||
under v8 you need to say instead:
|
|
||||||
|
|
||||||
3,0 jimbob@good.old.boy.com
|
|
||||||
|
|
||||||
INTEROPERABILITY ISSUES YOU MIGHT ENCOUNTER
|
|
||||||
|
|
||||||
Be aware that sendmail v8 issues a multi-line SMTP welcome (220)
|
|
||||||
response upon a client connection. Most systems in your network should
|
|
||||||
handle it OK, but there are some that choke on it, because whoever wrote
|
|
||||||
the clients assumed only a single line. THIS IS NOT SENDMAIL's FAULT.
|
|
||||||
A multi-line 220 response is perfectly valid. A likely place you'll
|
|
||||||
encounter this problem is with non-Un*x SMTP clients. If you do run
|
|
||||||
into it, you should report it to the vendor.
|
|
||||||
|
|
||||||
A final note about version 8 - if you follow the above configuration
|
|
||||||
scenario, you'll notice it doesn't like to get envelope sender
|
|
||||||
addresses it doesn't know how to get back to. Sun sendmail would take
|
|
||||||
anything, even though it might not be able to bounce the message back
|
|
||||||
should something happen downstream. So if another sendmail on a host
|
|
||||||
that's not locally known is trying to pump mail through your v8 host,
|
|
||||||
the ENVELOPE sender it gives had better be fully qualified. This is
|
|
||||||
a GREAT thing, because it helps clear up problems we've had with not
|
|
||||||
being able to get things back to the sender, resulting in an
|
|
||||||
overburdened postmaster.
|
|
||||||
|
|
||||||
I hope this helps those running Sun sendmail feel more at ease with moving
|
|
||||||
on to v8. It's really worth going to.
|
|
|
@ -1,13 +0,0 @@
|
||||||
# @(#)Makefile 8.1 (Berkeley) 4/13/1994
|
|
||||||
|
|
||||||
DIR= smm/09.sendmail
|
|
||||||
SRCS= changes.me
|
|
||||||
MACROS= -me
|
|
||||||
|
|
||||||
all: changes.ps
|
|
||||||
|
|
||||||
changes.ps: ${SRCS}
|
|
||||||
rm -f ${.TARGET}
|
|
||||||
${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
|
|
||||||
|
|
||||||
.include <bsd.doc.mk>
|
|
|
@ -1,975 +0,0 @@
|
||||||
.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
.\" Copyright (c) 1994 Eric P. Allman. All rights reserved.
|
|
||||||
.\" Copyright (c) 1988, 1994
|
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" By using this file, you agree to the terms and conditions set
|
|
||||||
.\" forth in the LICENSE file which can be found at the top level of
|
|
||||||
.\" the sendmail distribution.
|
|
||||||
.\"
|
|
||||||
.\"
|
|
||||||
.\" @(#)changes.me 8.7 (Berkeley) 5/19/1998
|
|
||||||
.\"
|
|
||||||
.\" ditroff -me -Pxx changes.me
|
|
||||||
.eh '%''Changes in Sendmail Version 8'
|
|
||||||
.oh 'Changes in Sendmail Version 8''%'
|
|
||||||
.nr si 3n
|
|
||||||
.if n .ls 2
|
|
||||||
.+c
|
|
||||||
.(l C
|
|
||||||
.sz 14
|
|
||||||
Changes in Sendmail Version 8*
|
|
||||||
.sz
|
|
||||||
.sp
|
|
||||||
Eric Allman
|
|
||||||
.sp 0.5
|
|
||||||
.i
|
|
||||||
University of California, Berkeley
|
|
||||||
Mammoth Project
|
|
||||||
.)l
|
|
||||||
.(f
|
|
||||||
*An earlier version of this paper was printed in the
|
|
||||||
Proceedings of the 1994 AUUG Queensland Summer Technical Conference,
|
|
||||||
Gateway Hotel, Brisbane, March 1994.
|
|
||||||
.)f
|
|
||||||
.sp
|
|
||||||
.(l F
|
|
||||||
.ce
|
|
||||||
ABSTRACT
|
|
||||||
.sp \n(psu
|
|
||||||
Version 8 of
|
|
||||||
.i sendmail
|
|
||||||
includes a number of major changes from previous versions.
|
|
||||||
This paper gives a very short history of
|
|
||||||
.i sendmail ,
|
|
||||||
a summary of the major differences between version 5
|
|
||||||
(the last publically available version)
|
|
||||||
and version 8,
|
|
||||||
and some discussion of future directions.
|
|
||||||
.)l
|
|
||||||
.sp 2
|
|
||||||
.pp
|
|
||||||
In 1987, the author stopped major work on
|
|
||||||
.i sendmail
|
|
||||||
due to other time committments,
|
|
||||||
only to return to active work in 1991.
|
|
||||||
This paper explores why work resumed
|
|
||||||
and what changes have been made.
|
|
||||||
.pp
|
|
||||||
Section 1 gives a short history of
|
|
||||||
.i sendmail
|
|
||||||
through version 5 and the motivation behind working on version 8.
|
|
||||||
Section 2 has
|
|
||||||
a rather detailed description of what has changed
|
|
||||||
between version 5 and version 8.
|
|
||||||
The paper finishes off with some thoughts
|
|
||||||
about what still needs to be done.
|
|
||||||
.sh 1 "HISTORY"
|
|
||||||
.pp
|
|
||||||
As discussed elsewhere,
|
|
||||||
[Allman83a, Allman83b, Allman&Amos85]
|
|
||||||
sendmail has existed in various forms since 1980.
|
|
||||||
It was released under the name
|
|
||||||
.i delivermail
|
|
||||||
in 4BSD and 4.1BSD, and as
|
|
||||||
.i sendmail
|
|
||||||
in 4.2BSD.
|
|
||||||
.\"4.0BSD delivermail 1.10
|
|
||||||
.\"4.1BSD delivermail 1.10
|
|
||||||
.\"4.2BSD sendmail 4.12
|
|
||||||
.\"4.3BSD sendmail 5.52
|
|
||||||
It quickly became the dominant mail system for networked UNIX systems.
|
|
||||||
.pp
|
|
||||||
Prior the release of 4.3BSD in November 1986,
|
|
||||||
the author had left the University for private industry,
|
|
||||||
but continued to do some work on
|
|
||||||
.i sendmail
|
|
||||||
with activity slowly trailing off
|
|
||||||
until effectively stopping after February 1987.
|
|
||||||
There was minimal support done by many people for several years,
|
|
||||||
until July of 1991 when the original author,
|
|
||||||
who had returned the University,
|
|
||||||
started active work on it again.
|
|
||||||
.pp
|
|
||||||
There were several reasons for renewed work on
|
|
||||||
.i sendmail .
|
|
||||||
There was a desire at Berkeley to convert to a subdomained structure
|
|
||||||
so that individuals were identified by their subdomain
|
|
||||||
rather than by their individual workstation;
|
|
||||||
although possible in the old code, there were some problems,
|
|
||||||
and the author was the obvious person to address them.
|
|
||||||
The Computer Systems Research Group (CSRG),
|
|
||||||
the group that produced the Berkeley Software Distributions,
|
|
||||||
was working on 4.4BSD,
|
|
||||||
and wanted an update to the mail system.
|
|
||||||
Bryan Costales was working on a book on
|
|
||||||
.i sendmail
|
|
||||||
that was being reviewed by the author,
|
|
||||||
which encouraged him to make some revisions.
|
|
||||||
And the author wanted to try to unify some of the disparate versions of
|
|
||||||
.i sendmail
|
|
||||||
that had been permitted to proliferate.
|
|
||||||
.pp
|
|
||||||
During the 1987\-91 fallow period,
|
|
||||||
many vendors and outside volunteers
|
|
||||||
had produced variants of
|
|
||||||
.i sendmail .
|
|
||||||
Perhaps the best known is the IDA version
|
|
||||||
[IDA87].
|
|
||||||
Originally intended to be a new set of configuration files,
|
|
||||||
IDA expanded into a fairly large set of patches for the code.
|
|
||||||
Originally produced in Sweden,
|
|
||||||
IDA development passed to the University of Illinois,
|
|
||||||
and was widely used by the fairly large set of people
|
|
||||||
who prefer to get and compile their own source code
|
|
||||||
rather than use vendor-supplied binaries.
|
|
||||||
.pp
|
|
||||||
In about the same time frame,
|
|
||||||
attempts were made to clean up and extend the Simple Mail Transport Protocol
|
|
||||||
(SMTP)
|
|
||||||
[RFC821].
|
|
||||||
This involved clarifications of some ambiguities in the protocol,
|
|
||||||
and correction of some problem areas
|
|
||||||
[RFC1123],
|
|
||||||
as well as extensions for additional functionality
|
|
||||||
(dubbed Extended Simple Mail Transport Protocol, or ESMTP)
|
|
||||||
[RFC1425, RFC1426, RFC1427]
|
|
||||||
and a richer set of semantics in the body of messages
|
|
||||||
(the Multipurpose Internet Mail Extensions, a.k.a. MIME)
|
|
||||||
[RFC1521, RFC1344].
|
|
||||||
Neither the IDA group nor most vendors
|
|
||||||
were modifying
|
|
||||||
.i sendmail
|
|
||||||
to conform to these new standards.
|
|
||||||
It seemed clear that these were ``good things''
|
|
||||||
that should be encouraged.
|
|
||||||
However, since no one was working on a publically available version of
|
|
||||||
.i sendmail
|
|
||||||
with these updates,
|
|
||||||
they were unlikely to be widely deployed any time in the near future.
|
|
||||||
.pp
|
|
||||||
There are, of course, other mail transport agents available,
|
|
||||||
such as
|
|
||||||
.i MMDF
|
|
||||||
.\"[ref],
|
|
||||||
.i zmailer
|
|
||||||
.\"[ref],
|
|
||||||
.i smail
|
|
||||||
.\"[ref],
|
|
||||||
and
|
|
||||||
.i PP
|
|
||||||
.\"[ref].
|
|
||||||
However, none of these seemed to be gaining the prominence of
|
|
||||||
.i sendmail ;
|
|
||||||
it appeared that most companies would not convert to another
|
|
||||||
mail transport agent any time in the forseeable future.
|
|
||||||
However, they might be persuaded to convert to a newer version of
|
|
||||||
.i sendmail .
|
|
||||||
.pp
|
|
||||||
All of these convinced the author
|
|
||||||
to work on a updated version of
|
|
||||||
.i sendmail
|
|
||||||
for public distribution.
|
|
||||||
.pp
|
|
||||||
The new version of
|
|
||||||
.i sendmail
|
|
||||||
is referred to as version eight (V8).
|
|
||||||
Versions six and seven were skipped
|
|
||||||
because of an agreement
|
|
||||||
that all files in 4.4BSD would be numbered as
|
|
||||||
.q 8.1 .
|
|
||||||
Rather than have an external version number
|
|
||||||
that differed from the file version numbers,
|
|
||||||
.i sendmail
|
|
||||||
just jumped directly to V8.
|
|
||||||
.sh 1 "CHANGES IN VERSION EIGHT"
|
|
||||||
.pp
|
|
||||||
The following is a summary of the changes between the last commonly
|
|
||||||
available version of sendmail from Berkeley (5.67) and the latest
|
|
||||||
version (8.6.6).
|
|
||||||
.pp
|
|
||||||
Many of these are ideas that had been tried in IDA,
|
|
||||||
but many of them were generalized in V8.
|
|
||||||
.sh 2 "Performance Enhancements"
|
|
||||||
.pp
|
|
||||||
Instead of closing SMTP connections immediately, open connections are
|
|
||||||
cached for possible future use. There is a limit to the number of
|
|
||||||
simultaneous open connections and the idle time of any individual
|
|
||||||
connection.
|
|
||||||
.pp
|
|
||||||
This is of best help during queue processing (since there is the
|
|
||||||
potential of many different messages going to one site), although
|
|
||||||
it can also help when processing MX records which aren't handled
|
|
||||||
by MX Piggybacking.
|
|
||||||
.pp
|
|
||||||
If two hosts with different names in a single message happen to
|
|
||||||
have the same set of MX hosts, they can be sent in the same
|
|
||||||
transaction. Version 8 notices this and tries to batch the messages.
|
|
||||||
.pp
|
|
||||||
For example, if two sites ``foo.com'' and ``bar.com'' are both
|
|
||||||
served by UUNET, they will have the same set of MX hosts and will
|
|
||||||
be sent in one transaction. UUNET will then split the message
|
|
||||||
and send it to the two individual hosts.
|
|
||||||
.sh 2 "RFC 1123 Changes"
|
|
||||||
.pp
|
|
||||||
A number of changes have been made to make sendmail ``conditionally
|
|
||||||
compliant'' (that is, it satisfies all of the MUST clauses and most
|
|
||||||
but not all of the SHOULD clauses in RFC 1123).
|
|
||||||
.pp
|
|
||||||
The major areas of change are (numbers are RFC 1123 section numbers):
|
|
||||||
.nr ii 0.75i
|
|
||||||
.ip \(sc5.2.7
|
|
||||||
Response to RCPT command is fast. Previously, sendmail
|
|
||||||
expanded all aliases as far as it could \*- this could
|
|
||||||
take a very long time, particularly if there were
|
|
||||||
name server delays. Version 8 only checks for the
|
|
||||||
existence of an alias and does the expansion later.
|
|
||||||
It does still do a DNS lookup if there is an explicit host name
|
|
||||||
in the RCPT command,
|
|
||||||
but this time is bounded.
|
|
||||||
.ip \(sc5.2.8
|
|
||||||
Numeric IP addresses are logged in Received: lines.
|
|
||||||
This helps tracing spoofed messages.
|
|
||||||
.ip \(sc5.2.17
|
|
||||||
Self domain literal is properly handled. Previously,
|
|
||||||
if someone sent to user@[1.2.3.4], where 1.2.3.4 is
|
|
||||||
your IP address, the mail would probably be rejected
|
|
||||||
with a ``configuration error''.
|
|
||||||
Version 8 can handle these addresses.
|
|
||||||
.ip \(sc5.3.2
|
|
||||||
Better control over individual timeouts. RFC 821 specified
|
|
||||||
no timeouts. Older versions of sendmail had a single
|
|
||||||
timeout, typically set to two hours. Version 8 allows
|
|
||||||
the configuration file to set timeouts for various
|
|
||||||
SMTP commands individually.
|
|
||||||
.ip \(sc5.3.3
|
|
||||||
Error messages are sent as From:<>. This was urged by
|
|
||||||
RFC 821 and reiterated by RFC 1123, but older versions
|
|
||||||
of sendmail never really did it properly. Version 8
|
|
||||||
does. However, some systems cannot handle this
|
|
||||||
perfectly legal address; if necessary, you can create
|
|
||||||
a special mailer that uses the `g' flag to disable this.
|
|
||||||
.ip \(sc5.3.3
|
|
||||||
Error messages are never sent to <>. Previously,
|
|
||||||
sendmail was happy to send responses-to-responses which
|
|
||||||
sometimes resulted in responses-to-responses-to-responses
|
|
||||||
which resulted in .... you get the idea.
|
|
||||||
.ip \(sc5.3.3
|
|
||||||
Route-addrs (the ugly ``<@hosta,@hostb:user@hostc>''
|
|
||||||
syntax) are pruned. RFC 821 urged the use of this
|
|
||||||
bletcherous syntax. RFC 1123 has seen the light and
|
|
||||||
officially deprecates them, further urging that you
|
|
||||||
eliminate all but ``user@hostc'' should you receive
|
|
||||||
one of these things. Version 8 is slightly more generous
|
|
||||||
than the standards suggest; instead of stripping off all
|
|
||||||
the route addressees, it only strips hosts off up to
|
|
||||||
the one before the last one known to DNS, thus allowing
|
|
||||||
you to have pseudo-hosts such as foo.BITNET. The `R'
|
|
||||||
option will turn this off.
|
|
||||||
.lp
|
|
||||||
The areas in which sendmail is not ``unconditionally compliant'' are:
|
|
||||||
.ip \(sc5.2.6
|
|
||||||
Sendmail does do header munging.
|
|
||||||
.ip \(sc5.2.10
|
|
||||||
Sendmail doesn't always use the exact SMTP message
|
|
||||||
text from RFC 821. This is a rather silly requirement.
|
|
||||||
.ip \(sc5.3.1.1
|
|
||||||
Sendmail doesn't guarantee only one connect for each
|
|
||||||
host on queue runs. Connection caching gives you most
|
|
||||||
of this, but it does not provide a guarantee.
|
|
||||||
.ip \(sc5.3.1.1
|
|
||||||
Sendmail doesn't always provide an adequate limit
|
|
||||||
on concurrency. That is, there can be several
|
|
||||||
independent sendmails running at once. My feeling
|
|
||||||
is that doing an absolute limit would be a mistake
|
|
||||||
(it might result in lost mail). However, if you use
|
|
||||||
the XLA contributed software, most of this will be
|
|
||||||
guaranteed (but I don't guarantee the guarantee).
|
|
||||||
.sh 2 "Extended SMTP Support
|
|
||||||
.pp
|
|
||||||
Version 8 includes both sending and receiving support for Extended
|
|
||||||
SMTP support as defined by RFC 1425 (basic) and RFC 1427 (SIZE);
|
|
||||||
and limited support for RFC 1426 (BODY).
|
|
||||||
The body support is minimal because the
|
|
||||||
.q 8BITMIME
|
|
||||||
body type is not currently advertised.
|
|
||||||
Although such a body type will be accepted,
|
|
||||||
it will not be correctly converted to 7 bits
|
|
||||||
if speaking to a non-8-bit-MIME aware SMTP server.
|
|
||||||
.pp
|
|
||||||
.i Sendmail
|
|
||||||
tries to speak ESMTP if you have the `a' flag set
|
|
||||||
in the flags for the mailer descriptor,
|
|
||||||
or if the other end advertises the fact that it speaks ESMTP.
|
|
||||||
This is a non-standard advertisement:
|
|
||||||
.i sendmail
|
|
||||||
announces
|
|
||||||
.q "ESMTP spoken here"
|
|
||||||
during the initial connection message,
|
|
||||||
and client sendmails search for this message.
|
|
||||||
This creates some problems for some PC-based mailers,
|
|
||||||
which do not understand two-line greeting messages
|
|
||||||
as required by RFC 821.
|
|
||||||
.sh 2 "Eight-Bit Clean
|
|
||||||
.pp
|
|
||||||
Previous versions of sendmail used the 0200 bit for quoting. This
|
|
||||||
version avoids that use.
|
|
||||||
However, you can set option `7' to get seven bit stripping
|
|
||||||
for compatibility with RFC 821,
|
|
||||||
which is a 7-bit protocol.
|
|
||||||
This option says ``strip to 7 bits on input''.
|
|
||||||
.pp
|
|
||||||
Individual mailers can still produce seven bit out put using the
|
|
||||||
`7' mailer flag.
|
|
||||||
This flag says ``strip to 7 bits on output''.
|
|
||||||
.sh 2 "User Database"
|
|
||||||
.pp
|
|
||||||
The User Database (UDB) is an as-yet experimental attempt to provide
|
|
||||||
unified large-site name support.
|
|
||||||
We are installing it at Berkeley;
|
|
||||||
future versions may show significant modifications.
|
|
||||||
Briefly, UDB contains a database that is intended to contain
|
|
||||||
all the per-user information for your workgroup,
|
|
||||||
such as people's full names, their .plan information,
|
|
||||||
their outgoing mail name, and their mail drop.
|
|
||||||
.pp
|
|
||||||
The user database allows you to map both incoming and outgoing
|
|
||||||
addresses, much like IDA. However, the interface is still
|
|
||||||
better with IDA;
|
|
||||||
in particular, the alias file with incoming/outgoing marks
|
|
||||||
provides better locality of information.
|
|
||||||
.sh 2 "Improved BIND Support"
|
|
||||||
.pp
|
|
||||||
The BIND support, particularly for MX records, had a number of
|
|
||||||
annoying ``features'' which have been removed in this release. In
|
|
||||||
particular, these more tightly bind (pun intended) the name server
|
|
||||||
to sendmail, so that the name server resolution rules are incorporated
|
|
||||||
directly into sendmail.
|
|
||||||
.pp
|
|
||||||
The major change has been that the $[ ... $] operator didn't fully
|
|
||||||
qualify names that were in DNS as A or MX records. Version 8 does
|
|
||||||
this qualification.
|
|
||||||
.pp
|
|
||||||
This has proven to be an annoyance in Sun shops,
|
|
||||||
who often still run without BIND support.
|
|
||||||
However, it is really critical that this be supported,
|
|
||||||
since MX records are mandatory.
|
|
||||||
In SunOS you can choose either MX support or NIS support,
|
|
||||||
but not both.
|
|
||||||
This is fixed in Solaris,
|
|
||||||
and some
|
|
||||||
.i sendmail
|
|
||||||
support to allow this in SunOS should be forthcoming in a future release.
|
|
||||||
.sh 2 "Keyed Files"
|
|
||||||
.pp
|
|
||||||
Generalized keyed files is an idea taken directly from IDA sendmail
|
|
||||||
(albeit with a completely different implementation).
|
|
||||||
They can be useful on large sites.
|
|
||||||
.pp
|
|
||||||
Version 8 includes the following built-in map classes:
|
|
||||||
.ip dbm
|
|
||||||
Support for the ndbm(3) library.
|
|
||||||
.ip hash
|
|
||||||
Support for the ``Hash'' type from the new Berkeley db(3) library.
|
|
||||||
this library provides substantially better database support
|
|
||||||
than ndbm(3),
|
|
||||||
including in-memory caching,
|
|
||||||
arbitrarily long keys and values,
|
|
||||||
and better disk utilization.
|
|
||||||
.ip btree
|
|
||||||
Support for the ``B-Tree'' type from the new Berkeley db(3) library.
|
|
||||||
B-Trees provide better clustering than Hashed files
|
|
||||||
if you are fetching lots of records that have similar keys,
|
|
||||||
such as searching a dictionary for words beginning with ``detr''.
|
|
||||||
.ip nis
|
|
||||||
Support for NIS (a.k.a. YP) maps.
|
|
||||||
NIS+ is not supported in this version.
|
|
||||||
.ip host
|
|
||||||
Support for DNS lookups.
|
|
||||||
.ip dequote
|
|
||||||
A ``pseudo-map'' (that is, once that does not have any external data)
|
|
||||||
that allows a configuration file to break apart a quoted string
|
|
||||||
in the address.
|
|
||||||
This is necessary primarily for DECnet addresses,
|
|
||||||
which often have quoted addresses that need to be unwrapped on gateways.
|
|
||||||
.sh 2 "Multi-Word Classes & Macros in Classes"
|
|
||||||
.pp
|
|
||||||
Classes can now be multiple words. For example,
|
|
||||||
.(b
|
|
||||||
CShofmann.CS.Berkeley.EDU
|
|
||||||
.)b
|
|
||||||
allows you to match the entire string ``hofmann.CS.Berkeley.EDU''
|
|
||||||
using the single construct ``$=S''.
|
|
||||||
.pp
|
|
||||||
Class definitions are now allowed to include macros \*- for example:
|
|
||||||
.(b
|
|
||||||
Cw$k
|
|
||||||
.)b
|
|
||||||
is legal.
|
|
||||||
.sh 2 "IDENT Protocol Support"
|
|
||||||
.pp
|
|
||||||
The IDENT protocol as defined in RFC 1413 [RFC1413] is supported.
|
|
||||||
However, many systems have a TCP/IP bug that renders this useless,
|
|
||||||
and the feature must be turned off.
|
|
||||||
Roughly, if one of these system receives a
|
|
||||||
.q "No route to host"
|
|
||||||
message (ICMP message ICMP_UNREACH_HOST) on
|
|
||||||
.i any
|
|
||||||
connection, all connections to that host are closed.
|
|
||||||
Some firewalls return this error if you try to connect
|
|
||||||
to the IDENT port,
|
|
||||||
so you can't receive email from these hosts on these systems.
|
|
||||||
It's possible that if the firewall used a more specific message
|
|
||||||
(such as ICMP_UNREACH_PROTOCOL, ICMP_UNREACH_PORT or ICMP_UNREACH_NET_PROHIB)
|
|
||||||
it would work, but this hasn't been verified.
|
|
||||||
.pp
|
|
||||||
IDENT protocol support cannot be used on
|
|
||||||
4.3BSD,
|
|
||||||
Apollo DomainOS,
|
|
||||||
Apple A/UX,
|
|
||||||
ConvexOS,
|
|
||||||
Data General DG/UX,
|
|
||||||
HP-UX,
|
|
||||||
Sequent Dynix,
|
|
||||||
or
|
|
||||||
Ultrix 4.x, x \(<= 3.
|
|
||||||
It seems to work on
|
|
||||||
4.4BSD,
|
|
||||||
IBM AIX 3.x,
|
|
||||||
OSF/1,
|
|
||||||
SGI IRIX,
|
|
||||||
Solaris,
|
|
||||||
SunOS,
|
|
||||||
and Ultrix 4.4.
|
|
||||||
.sh 2 "Separate Envelope/Header Processing
|
|
||||||
.pp
|
|
||||||
Since the From: line is passed in separately from the envelope
|
|
||||||
sender, these have both been made visible; the $g macro is set to
|
|
||||||
the envelope sender during processing of mailer argument vectors
|
|
||||||
and the header sender during processing of headers.
|
|
||||||
.pp
|
|
||||||
It is also possible to specify separate per-mailer envelope and
|
|
||||||
header processing. The SenderRWSet and RecipientRWset arguments
|
|
||||||
for mailers can be specified as ``envelope/header'' to give different
|
|
||||||
rewritings for envelope versus header addresses.
|
|
||||||
.sh 2 "Owner-List Propagates to Envelope
|
|
||||||
.pp
|
|
||||||
When an alias has an associated owner-list name, that alias is used
|
|
||||||
to change the envelope sender address. This will cause downstream
|
|
||||||
errors to be returned to that owner.
|
|
||||||
.pp
|
|
||||||
Some people find this confusing
|
|
||||||
because the envelope sender is what appears in the first
|
|
||||||
``From_'' line in UNIX messages
|
|
||||||
(that is, the line beginning ``From<space>''
|
|
||||||
instead of ``From:'';
|
|
||||||
the latter is the header from, which
|
|
||||||
.i does
|
|
||||||
indicate the sender of the message).
|
|
||||||
In previous versions,
|
|
||||||
.i sendmail
|
|
||||||
has tried to avoid changing the envelope sender
|
|
||||||
for back compatibility with UNIX convention;
|
|
||||||
at this point that back compatibility is creating too many problems,
|
|
||||||
and it is necessary to move forward into the 1980s.
|
|
||||||
.sh 2 "Command Line Flags"
|
|
||||||
.pp
|
|
||||||
The
|
|
||||||
.b \-B
|
|
||||||
flag has been added to pass in body type information.
|
|
||||||
.pp
|
|
||||||
The
|
|
||||||
.b \-p
|
|
||||||
flag has been added to pass in protocol information
|
|
||||||
that was previously passed in by defining the
|
|
||||||
.b $r
|
|
||||||
and
|
|
||||||
.b $s
|
|
||||||
macros.
|
|
||||||
.pp
|
|
||||||
The
|
|
||||||
.b \-X
|
|
||||||
flag has been added to allow logging of all protocol in and
|
|
||||||
out of sendmail for debugging.
|
|
||||||
You can set
|
|
||||||
.q "\-X filename"
|
|
||||||
and a complete transcript will be logged in that file.
|
|
||||||
This gets big fast: the option is only for debugging.
|
|
||||||
.pp
|
|
||||||
The
|
|
||||||
.b \-q
|
|
||||||
flag can limit limit a queue run to specific recipients,
|
|
||||||
senders, or queue ids using \-qRsubstring, \-qSsubstring, or
|
|
||||||
\-qIsubstring respectively.
|
|
||||||
.sh 2 "New Configuration Line Types
|
|
||||||
.pp
|
|
||||||
The `T' (Trusted users) configuration line has been deleted. It
|
|
||||||
will still be accepted but will be ignored.
|
|
||||||
.pp
|
|
||||||
The `K' line has been added to declare database maps.
|
|
||||||
.pp
|
|
||||||
The `V' line has been added to declare the configuration version
|
|
||||||
level.
|
|
||||||
.pp
|
|
||||||
The `M' (mailer) line takes a D= field to specify execution
|
|
||||||
directory.
|
|
||||||
.sh 2 "New and Extended Options"
|
|
||||||
.pp
|
|
||||||
Several new options have been added, many to support new features,
|
|
||||||
others to allow tuning that was previously available only by
|
|
||||||
recompiling. Briefly:
|
|
||||||
.nr ii 0.5i
|
|
||||||
.ip A
|
|
||||||
The alias file specification can now be a list of alias files.
|
|
||||||
Also, the configuration can specify a class of file.
|
|
||||||
For example, to search the NIS aliases, use
|
|
||||||
.q OAnis:mail.aliases .
|
|
||||||
.ip b
|
|
||||||
Insist on a minimum number of disk blocks.
|
|
||||||
.ip C
|
|
||||||
Delivery checkpoint interval. Checkpoint the queue (to avoid
|
|
||||||
duplicate deliveries) every C addresses.
|
|
||||||
.ip E
|
|
||||||
Default error message. This message (or the contents of the
|
|
||||||
indicated file) are prepended to error messages.
|
|
||||||
.ip G
|
|
||||||
Enable GECOS matching. If you can't find a local user name
|
|
||||||
and this option is enabled, do a sequential scan of the passwd
|
|
||||||
file to match against full names. Previously a compile option.
|
|
||||||
.ip h
|
|
||||||
Maximum hop count. Previously this was compiled in.
|
|
||||||
.ip I
|
|
||||||
This option has been extended to allow setting of resolver parameters.
|
|
||||||
.ip j
|
|
||||||
Send errors in MIME-encapsulated format.
|
|
||||||
.ip J
|
|
||||||
Forward file path. Where to search for .forward files \*- defaults
|
|
||||||
to $HOME/.forward.
|
|
||||||
.ip k
|
|
||||||
Connection cache size. The total number of connections that will
|
|
||||||
be kept open at any time.
|
|
||||||
.ip K
|
|
||||||
Connection cache lifetime. The amount of time any connection
|
|
||||||
will be permitted to sit idle.
|
|
||||||
.ip l
|
|
||||||
Enable Errors-To: header. These headers violate RFC 1123;
|
|
||||||
this option is included to provide back compatibility with
|
|
||||||
old versions of sendmail.
|
|
||||||
.ip O
|
|
||||||
Incoming daemon options (e.g., use alternate SMTP port).
|
|
||||||
.ip p
|
|
||||||
Privacy options. These can be used to make your SMTP server
|
|
||||||
less friendly.
|
|
||||||
.ip r
|
|
||||||
This option has been extended to allow finer grained control
|
|
||||||
over timeouts.
|
|
||||||
For example, you can set the timeout for SMTP commands individually.
|
|
||||||
.ip R
|
|
||||||
Don't prune route-addrs. Normally, if version 8 sees an address
|
|
||||||
like "<@hostA,@hostB:user@hostC>, sendmail will try to strip off
|
|
||||||
as much as it can (up to user@hostC) as suggested by RFC 1123.
|
|
||||||
This option disables that behaviour.
|
|
||||||
.ip T
|
|
||||||
The
|
|
||||||
.q "Return To Sender"
|
|
||||||
timeout has been extended
|
|
||||||
to allow specification of a warning message interval,
|
|
||||||
typically something on the order of four hours.
|
|
||||||
If a message cannot be delivered in that interval,
|
|
||||||
a warning message is sent back to the sender
|
|
||||||
but the message continues to be tried.
|
|
||||||
.ip U
|
|
||||||
User database spec. This is still experimental.
|
|
||||||
.ip V
|
|
||||||
Fallback ``MX'' host. This can be thought of as an MX host
|
|
||||||
that applies to all addresses that has a very high preference
|
|
||||||
value (that is, use it only if everything else fails).
|
|
||||||
.ip w
|
|
||||||
If set, assume that if you are the best MX host for a host,
|
|
||||||
you should send directly to that host. This is intended
|
|
||||||
for compatibility with UIUC sendmail, and may have some
|
|
||||||
use on firewalls.
|
|
||||||
.ip 7
|
|
||||||
Do not run eight bit clean. Technically, you have to assert
|
|
||||||
this option to be RFC 821 compatible.
|
|
||||||
.sh 2 "New Mailer Definitions"
|
|
||||||
.ip L=
|
|
||||||
Set the allowable line length. In V5, the L mailer flag implied
|
|
||||||
a line length limit of 990 characters; this is now settable to
|
|
||||||
an arbitrary value.
|
|
||||||
.ip F=a
|
|
||||||
Try to use ESMTP. It will fall back to SMTP if the initial
|
|
||||||
EHLO packet is rejected.
|
|
||||||
.ip F=b
|
|
||||||
Ensure a blank line at the end of messages. Useful on the
|
|
||||||
*file* mailer.
|
|
||||||
.ip F=c
|
|
||||||
Strip all comments from addresses; this should only be used as
|
|
||||||
a last resort when dealing with cranky mailers.
|
|
||||||
.ip F=g
|
|
||||||
Never use the null sender as the envelope sender, even when
|
|
||||||
running SMTP. This violates RFC 1123.
|
|
||||||
.ip F=7
|
|
||||||
Strip all output to this mailer to 7 bits.
|
|
||||||
.ip F=L
|
|
||||||
Used to set the line limit to 990 bytes for SMTP compatibility.
|
|
||||||
It now does that only if the L= keyletter is not specified.
|
|
||||||
This flag is obsolete and should not be used.
|
|
||||||
.sh 2 "New or Changed Pre-Defined Macros"
|
|
||||||
.ip $k
|
|
||||||
UUCP node name from uname(2).
|
|
||||||
.ip $m
|
|
||||||
Domain part of our full hostname.
|
|
||||||
.ip $_
|
|
||||||
RFC 1413-provided sender address.
|
|
||||||
.ip $w
|
|
||||||
Previously was sometimes the full domain name, sometimes
|
|
||||||
just the first word. Now guaranteed to be the first word
|
|
||||||
of the domain name (i.e., the host name).
|
|
||||||
.ip $j
|
|
||||||
Previously had to be defined \*- it is now predefined to be
|
|
||||||
the full domain name, if that can be determined. That is,
|
|
||||||
it is equivalent to $w.$m.
|
|
||||||
.sh 2 "New and Changed Classes"
|
|
||||||
.ip $=k
|
|
||||||
Initialized to contain $k.
|
|
||||||
.ip $=w
|
|
||||||
Now includes
|
|
||||||
.q [1.2.3.4]
|
|
||||||
(where 1.2.3.4 is your IP address)
|
|
||||||
to allow the configuration file to recognize your own IP address.
|
|
||||||
.sh 2 "New Rewriting Tokens"
|
|
||||||
.pp
|
|
||||||
The
|
|
||||||
.b $&
|
|
||||||
construct has been adopted from IDA to defer macro evaluation.
|
|
||||||
Normally, macros in rulesets are bound when the rule is first parsed
|
|
||||||
during startup.
|
|
||||||
Some macros change during processing and are uninteresting during startup.
|
|
||||||
However, that macro can be referenced using
|
|
||||||
.q $&x
|
|
||||||
to defer the evaulation of
|
|
||||||
$x
|
|
||||||
until the rule is processed.
|
|
||||||
.pp
|
|
||||||
The tokens
|
|
||||||
.b $(
|
|
||||||
and
|
|
||||||
.b $)
|
|
||||||
have been added to allow specification of map rewriting.
|
|
||||||
.pp
|
|
||||||
Version 8 allows
|
|
||||||
.b $@
|
|
||||||
on the Left Hand Side of an `R' line to match
|
|
||||||
zero tokens.
|
|
||||||
This is intended to be used to match the null input.
|
|
||||||
.sh 2 "Bigger Defaults
|
|
||||||
.pp
|
|
||||||
Version 8 allows up to 100 rulesets instead of 30. It is recommended
|
|
||||||
that rulesets 0\-9 be reserved for sendmail's dedicated use in future
|
|
||||||
releases.
|
|
||||||
.pp
|
|
||||||
The total number of MX records that can be used has been raised to
|
|
||||||
20.
|
|
||||||
.pp
|
|
||||||
The number of queued messages that can be handled at one time has
|
|
||||||
been raised from 600 to 1000.
|
|
||||||
.sh 2 "Different Default Tuning Parameters
|
|
||||||
.pp
|
|
||||||
Version 8 has changed the default parameters for tuning queue costs
|
|
||||||
to make the number of recipients more important than the size of
|
|
||||||
the message (for small messages). This is reasonable if you are
|
|
||||||
connected with reasonably fast links.
|
|
||||||
.sh 2 "Auto-Quoting in Addresses
|
|
||||||
.pp
|
|
||||||
Previously, the ``Full Name <email address>'' syntax would generate
|
|
||||||
incorrect protocol output if ``Full Name'' had special characters
|
|
||||||
such as dot. This version puts quotes around such names.
|
|
||||||
.sh 2 "Symbolic Names On Error Mailer
|
|
||||||
.pp
|
|
||||||
Several names have been built in to the $@ portion of the $#error
|
|
||||||
mailer. For example:
|
|
||||||
.(b
|
|
||||||
$#error $@NOHOST $: Host unknown
|
|
||||||
.)b
|
|
||||||
Prints the indicated message
|
|
||||||
and sets the exit status of
|
|
||||||
.i sendmail
|
|
||||||
to
|
|
||||||
.sm EX_NOHOST .
|
|
||||||
.sh 2 "New Built-In Mailers"
|
|
||||||
.pp
|
|
||||||
Two new mailers, *file* and *include*, are included to define options
|
|
||||||
when mailing to a file or a :include: file respectively. Previously
|
|
||||||
these were overloaded on the local mailer.
|
|
||||||
.sh 2 "SMTP VRFY Doesn't Expand
|
|
||||||
.pp
|
|
||||||
Previous versions of sendmail treated VRFY and EXPN the same. In
|
|
||||||
this version, VRFY doesn't expand aliases or follow .forward files.
|
|
||||||
.pp
|
|
||||||
As an optimization, if you run with your default delivery mode
|
|
||||||
being queue-only, the RCPT command will also not chase aliases and
|
|
||||||
\&.forward files.
|
|
||||||
It will chase them when it processes the queue.
|
|
||||||
This speeds up RCPT processing.
|
|
||||||
.sh 2 "[IPC] Mailers Allow Multiple Hosts
|
|
||||||
.pp
|
|
||||||
When an address resolves to a mailer that has ``[IPC]'' as its
|
|
||||||
``Path'', the $@ part (host name) can be a colon-separated list of
|
|
||||||
hosts instead of a single hostname. This asks sendmail to search
|
|
||||||
the list for the first entry that is available exactly as though
|
|
||||||
it were an MX record. The intent is to route internal traffic
|
|
||||||
through internal networks without publishing an MX record to the
|
|
||||||
net. MX expansion is still done on the individual items.
|
|
||||||
.sh 2 "Aliases Extended"
|
|
||||||
.pp
|
|
||||||
The implementation has been merged with maps. Among other things,
|
|
||||||
this supports multiple alias files and NIS-based aliases. For
|
|
||||||
example:
|
|
||||||
.(b
|
|
||||||
OA/etc/aliases,nis:mail.aliases
|
|
||||||
.)b
|
|
||||||
will search first the local database
|
|
||||||
.q /etc/aliases
|
|
||||||
followed by the NIS map
|
|
||||||
|
|
||||||
.sh 2 "Portability and Security Enhancements
|
|
||||||
.pp
|
|
||||||
A number of internal changes have been made to enhance portability.
|
|
||||||
.pp
|
|
||||||
Several fixes have been made to increase the paranoia factor.
|
|
||||||
.pp
|
|
||||||
In particular, the permissions required for .forward and :include:
|
|
||||||
files have been tightened up considerably. V5 would pretty much
|
|
||||||
read any file it could get to as root, which exposed some security
|
|
||||||
holes. V8 insists that all directories leading up to the .forward
|
|
||||||
or :include: file be searchable ("x" permission) by the controlling
|
|
||||||
user" (defined below), that the file itself be readable by the
|
|
||||||
controlling user, and that .forward files be owned by the user
|
|
||||||
who is being forwarded to or root.
|
|
||||||
.pp
|
|
||||||
The "controlling user" is the user on whose behalf the mail is
|
|
||||||
being delivered. For example, if you mail to "user1" then the
|
|
||||||
controlling user for ~user1/.forward and any mailers invoked
|
|
||||||
by that .forward file, including :include: files.
|
|
||||||
.pp
|
|
||||||
Previously, anyone who had a home directory could create a .forward
|
|
||||||
could forward to a program. Now, sendmail checks to make sure
|
|
||||||
that they have an "approved shell", that is, a shell listed in
|
|
||||||
the /etc/shells file.
|
|
||||||
.sh 2 "Miscellaneous Fixes and Enhancements"
|
|
||||||
.pp
|
|
||||||
A number of small bugs having to do with things like backslash-escaped
|
|
||||||
quotes inside of comments have been fixed.
|
|
||||||
.pp
|
|
||||||
The fixed size limit on header lines
|
|
||||||
(such as
|
|
||||||
.q To:
|
|
||||||
and
|
|
||||||
.q Cc: )
|
|
||||||
has been eliminated;
|
|
||||||
those buffers are dynamically allocated now.
|
|
||||||
.pp
|
|
||||||
Sendmail writes a /etc/sendmail.pid file with the current process id
|
|
||||||
and the current invocation flags.
|
|
||||||
.pp
|
|
||||||
Two people using the same program (e.g., submit) are considered
|
|
||||||
"different" so that duplicate elimination doesn't delete one of
|
|
||||||
them. For example, two people forwarding their email to
|
|
||||||
|submit will be treated as two recipients.
|
|
||||||
.pp
|
|
||||||
The mailstats program prints mailer names and gets the location of
|
|
||||||
the sendmail.st file from /etc/sendmail.cf.
|
|
||||||
.pp
|
|
||||||
Many minor bugs have been fixed, such as handling of backslashes
|
|
||||||
inside of quotes.
|
|
||||||
.pp
|
|
||||||
A hook has been added to allow rewriting of local addresses after
|
|
||||||
aliasing.
|
|
||||||
.sh 1 "FUTURE WORK"
|
|
||||||
.pp
|
|
||||||
The previous section describes
|
|
||||||
.i sendmail
|
|
||||||
as of version 8.6.6.
|
|
||||||
There is still much to be done.
|
|
||||||
Some high points are described below.
|
|
||||||
This list is by no means exhaustive.
|
|
||||||
.sh 2 "Full MIME Support"
|
|
||||||
.pp
|
|
||||||
Currently
|
|
||||||
.i sendmail
|
|
||||||
only supports seven bit MIME messages.
|
|
||||||
Although it can pass eight bit MIME messages,
|
|
||||||
it cannot advertise that fact because the standards say
|
|
||||||
that the mail agent must be able to do 8- to 7-bit conversion
|
|
||||||
to have full 8-bit support.
|
|
||||||
This requires far more extensive modification of the message body
|
|
||||||
than is currently supported.
|
|
||||||
.pp
|
|
||||||
The best way to do this would be to support the general concept
|
|
||||||
of an external
|
|
||||||
``message filter''
|
|
||||||
that could do arbitrary modifications of the message.
|
|
||||||
This would allow MIME conversion as well as such things as
|
|
||||||
automatic encryption of messages sent over external links.
|
|
||||||
This is probably an extremely non-trivial change.
|
|
||||||
.sh 2 "Service Switch Abstraction"
|
|
||||||
.pp
|
|
||||||
Most modern systems include some concept of a
|
|
||||||
.q "service switch"
|
|
||||||
\*- for example, to look up host names you can try
|
|
||||||
DNS, NIS, NIS+, text tables, NetInfo,
|
|
||||||
or other services in some arbitrary order.
|
|
||||||
This is currently very clumsy in
|
|
||||||
.i sendmail ,
|
|
||||||
with only limited control of the services provided.
|
|
||||||
.sh 2 "More Control of Local Addresses"
|
|
||||||
.pp
|
|
||||||
Currently some addresses are declared as
|
|
||||||
.q local
|
|
||||||
and are handled specially \*-
|
|
||||||
for example, they may have .forward files,
|
|
||||||
may be translated into program calls or file deliveries,
|
|
||||||
and so forth.
|
|
||||||
These should be broken out into separate flags
|
|
||||||
to allow the local system administrator
|
|
||||||
to have more fine-grained control over operations.
|
|
||||||
.sh 2 "More Run-Time Configuration Options"
|
|
||||||
.pp
|
|
||||||
There are many options that are configured at compile time,
|
|
||||||
such as the method of file locking
|
|
||||||
and the use of the IDENT protocol
|
|
||||||
[RFC1413].
|
|
||||||
These should be transfered to run time
|
|
||||||
by adding new options.
|
|
||||||
.pp
|
|
||||||
Similarly, some options are currently overloaded,
|
|
||||||
that is, a single option controls more than one thing.
|
|
||||||
These should probably be broken out into separate options.
|
|
||||||
.pp
|
|
||||||
This implies that options will change from single characters
|
|
||||||
to words.
|
|
||||||
.sh 2 "More Configuration Control Over Errors"
|
|
||||||
.pp
|
|
||||||
Currently,
|
|
||||||
the configuration file can generate an error message during parsing.
|
|
||||||
However,
|
|
||||||
it cannot tweak other operations,
|
|
||||||
such as issuing a warning message to the system postmaster.
|
|
||||||
Similarly,
|
|
||||||
some errors should not be triggered if they are in aliases
|
|
||||||
during an alias file rebuild,
|
|
||||||
but should be triggered if that alias is actually used.
|
|
||||||
.sh 2 "Long Term Host State"
|
|
||||||
.pp
|
|
||||||
Currently,
|
|
||||||
.i sendmail
|
|
||||||
only remembers host status during a single queue run.
|
|
||||||
This should be converted to long term status
|
|
||||||
stored on disk
|
|
||||||
so it can be shared between instantiations of
|
|
||||||
.i sendmail .
|
|
||||||
Entries will have to be timestamped
|
|
||||||
so they can time out.
|
|
||||||
This will allow
|
|
||||||
.i sendmail
|
|
||||||
to implement exponential backoff on queue runs
|
|
||||||
on a per-host basis.
|
|
||||||
.sh 2 "Connection Control"
|
|
||||||
.pp
|
|
||||||
Modern networks have different types of connectivity
|
|
||||||
than the past.
|
|
||||||
In particular, the rising prominence of dialup IP
|
|
||||||
has created certain challenges for automated servers.
|
|
||||||
It is not uncommon to try to make a connection to a host
|
|
||||||
and have it fail, even though if you tried again it would succeed.
|
|
||||||
The connection management could be a bit cleverer
|
|
||||||
to try to adapt to such situations.
|
|
||||||
.sh 2 "Other Caching"
|
|
||||||
.pp
|
|
||||||
When you do an MX record lookup,
|
|
||||||
the name server automatically returns the IP addresses
|
|
||||||
of the associated MX servers.
|
|
||||||
This information is currently ignored,
|
|
||||||
and another query is done to get this information.
|
|
||||||
It should be cached to avoid excess name server traffic.
|
|
||||||
.sh 1 "REFERENCES"
|
|
||||||
.ip [Allman83a]
|
|
||||||
.q "Sendmail \*- An Internetwork Mail Router."
|
|
||||||
E. Allman.
|
|
||||||
In
|
|
||||||
.ul
|
|
||||||
Unix Programmers's Manual,
|
|
||||||
4.2 Berkeley Software Distribution,
|
|
||||||
volume 2C.
|
|
||||||
August 1983.
|
|
||||||
.ip [Allman83b]
|
|
||||||
.q "Mail Systems and Addressing in 4.2BSD."
|
|
||||||
E. Allman
|
|
||||||
In
|
|
||||||
.ul
|
|
||||||
UNICOM Conference Proceedings.
|
|
||||||
San Diego, California.
|
|
||||||
January 1983.
|
|
||||||
.ip [Allman&Amos85]
|
|
||||||
``Sendmail Revisited.''
|
|
||||||
E. Allman and M. Amos.
|
|
||||||
In
|
|
||||||
.ul
|
|
||||||
Usenix Summer 1985 Conference Proceedings.
|
|
||||||
Portland, Oregon.
|
|
||||||
June 1985.
|
|
||||||
.ip [IDA87]
|
|
||||||
.ul 3
|
|
||||||
Electronic Mail Addressing in Theory and Practice
|
|
||||||
with the IDA Sendmail Enhancement Kit
|
|
||||||
(or The Postmaster's Last Will and Testament).
|
|
||||||
Lennart Lo\*:vstrand.
|
|
||||||
Department of Computer and Information Science,
|
|
||||||
University of Linko\*:ping,
|
|
||||||
Sweden,
|
|
||||||
Report no. LiTH-IDA-Ex-8715.
|
|
||||||
May 1987.
|
|
||||||
.ip [RFC821]
|
|
||||||
.ul
|
|
||||||
Simple Mail Transport Protocol.
|
|
||||||
J. Postel.
|
|
||||||
August 1982.
|
|
||||||
.ip [RFC1123]
|
|
||||||
.ul
|
|
||||||
Requirements for Internet Hosts \*- Application and Support.
|
|
||||||
Internet Engineering Task Force,
|
|
||||||
R. Braden, Editor.
|
|
||||||
October 1989.
|
|
||||||
.ip [RFC1344]
|
|
||||||
.ul
|
|
||||||
Implications of MIME for Internet Mail Gateways.
|
|
||||||
N. Borenstein.
|
|
||||||
June 1992.
|
|
||||||
.ip [RFC1413]
|
|
||||||
.ul
|
|
||||||
Identification Protocol.
|
|
||||||
M. St. Johns.
|
|
||||||
February 1993.
|
|
||||||
.ip [RFC1425]
|
|
||||||
.ul
|
|
||||||
SMTP Service Extensions.
|
|
||||||
J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker.
|
|
||||||
February 1993.
|
|
||||||
.ip [RFC1426]
|
|
||||||
.ul
|
|
||||||
SMTP Service Extension for 8bit-MIMEtransport.
|
|
||||||
J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker.
|
|
||||||
February 1993.
|
|
||||||
.ip [RFC1427]
|
|
||||||
.ul
|
|
||||||
SMTP Service Extension for Message Size Declaration.
|
|
||||||
J. Klensin, N. Freed, and K. Moore.
|
|
||||||
February 1993.
|
|
||||||
.ip [RFC1521]
|
|
||||||
.ul 3
|
|
||||||
MIME (Multipurpose Internet Mail Extensions) Part One:
|
|
||||||
Mechanisms for Specifying and Describing
|
|
||||||
the Format of Internet Message Bodies.
|
|
||||||
N. Borenstein and N. Freed.
|
|
||||||
September 1993.
|
|
|
@ -1,13 +0,0 @@
|
||||||
# @(#)Makefile 8.2 (Berkeley) 2/28/1994
|
|
||||||
|
|
||||||
DIR= smm/09.sendmail
|
|
||||||
SRCS= intro.me
|
|
||||||
MACROS= -me
|
|
||||||
|
|
||||||
all: intro.ps
|
|
||||||
|
|
||||||
intro.ps: ${SRCS}
|
|
||||||
rm -f ${.TARGET}
|
|
||||||
${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
|
|
||||||
|
|
||||||
.include <bsd.doc.mk>
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,12 +0,0 @@
|
||||||
# @(#)Makefile 8.2 (Berkeley) 2/28/1994
|
|
||||||
|
|
||||||
SRCS= usenix.me
|
|
||||||
MACROS= -me
|
|
||||||
|
|
||||||
all: usenix.ps
|
|
||||||
|
|
||||||
usenix.ps: ${SRCS}
|
|
||||||
rm -f ${.TARGET}
|
|
||||||
${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
|
|
||||||
|
|
||||||
.include <bsd.doc.mk>
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,16 +0,0 @@
|
||||||
/*-
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1990, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @(#)pathnames.h 8.5 (Berkeley) 5/19/1998
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
#include <paths.h>
|
|
||||||
|
|
||||||
#define _PATH_LOCTMP "/var/tmp/local.XXXXXX"
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1991, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to Berkeley by
|
|
||||||
* Berkeley Software Design, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
|
||||||
* must display the following acknowledgement:
|
|
||||||
* This product includes software developed by the University of
|
|
||||||
* California, Berkeley and its contributors.
|
|
||||||
* 4. Neither the name of the University nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CDEFS_H_
|
|
||||||
#define _CDEFS_H_
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
#define __BEGIN_DECLS extern "C" {
|
|
||||||
#define __END_DECLS };
|
|
||||||
#else
|
|
||||||
#define __BEGIN_DECLS
|
|
||||||
#define __END_DECLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
|
|
||||||
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
|
|
||||||
* The __CONCAT macro is a bit tricky -- make sure you don't put spaces
|
|
||||||
* in between its arguments. __CONCAT can also concatenate double-quoted
|
|
||||||
* strings produced by the __STRING macro, but this only works with ANSI C.
|
|
||||||
*/
|
|
||||||
#if defined(__STDC__) || defined(__cplusplus)
|
|
||||||
#define __P(protos) protos /* full-blown ANSI C */
|
|
||||||
#define __CONCAT(x,y) x ## y
|
|
||||||
#define __STRING(x) #x
|
|
||||||
|
|
||||||
#define __const const /* define reserved names to standard */
|
|
||||||
#define __signed signed
|
|
||||||
#define __volatile volatile
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
#define __inline inline /* convert to C++ keyword */
|
|
||||||
#else
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#define __inline /* delete GCC keyword */
|
|
||||||
#endif /* !__GNUC__ */
|
|
||||||
#endif /* !__cplusplus */
|
|
||||||
|
|
||||||
#else /* !(__STDC__ || __cplusplus) */
|
|
||||||
#define __P(protos) () /* traditional C preprocessor */
|
|
||||||
#define __CONCAT(x,y) x/**/y
|
|
||||||
#define __STRING(x) "x"
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#define __const /* delete pseudo-ANSI C keywords */
|
|
||||||
#define __inline
|
|
||||||
#define __signed
|
|
||||||
#define __volatile
|
|
||||||
/*
|
|
||||||
* In non-ANSI C environments, new programs will want ANSI-only C keywords
|
|
||||||
* deleted from the program and old programs will want them left alone.
|
|
||||||
* When using a compiler other than gcc, programs using the ANSI C keywords
|
|
||||||
* const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
|
|
||||||
* When using "gcc -traditional", we assume that this is the intent; if
|
|
||||||
* __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
|
|
||||||
*/
|
|
||||||
#ifndef NO_ANSI_KEYWORDS
|
|
||||||
#define const /* delete ANSI C keywords */
|
|
||||||
#define inline
|
|
||||||
#define signed
|
|
||||||
#define volatile
|
|
||||||
#endif
|
|
||||||
#endif /* !__GNUC__ */
|
|
||||||
#endif /* !(__STDC__ || __cplusplus) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GCC1 and some versions of GCC2 declare dead (non-returning) and
|
|
||||||
* pure (no side effects) functions using "volatile" and "const";
|
|
||||||
* unfortunately, these then cause warnings under "-ansi -pedantic".
|
|
||||||
* GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
|
|
||||||
* these work for GNU C++ (modulo a slight glitch in the C++ grammar
|
|
||||||
* in the distribution version of 2.5.5).
|
|
||||||
*/
|
|
||||||
#if !defined(__GNUC__) || __GNUC__ < 2 || \
|
|
||||||
(__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
|
||||||
#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
|
|
||||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
|
||||||
#define __dead __volatile
|
|
||||||
#define __pure __const
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Delete pseudo-keywords wherever they are not available or needed. */
|
|
||||||
#ifndef __dead
|
|
||||||
#define __dead
|
|
||||||
#define __pure
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !_CDEFS_H_ */
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Support for LDAP.
|
|
||||||
**
|
|
||||||
** Contributed by Booker C. Bense <bbense+ldap@stanford.edu>.
|
|
||||||
** Please go to him for support -- since I (Eric) don't run LDAP, I
|
|
||||||
** can't help you at all.
|
|
||||||
**
|
|
||||||
** @(#)ldap_map.h 8.12 (Berkeley) 2/2/1999
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LDAP_MAP_H
|
|
||||||
#define _LDAP_MAP_H
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
struct ldap_map_struct
|
|
||||||
{
|
|
||||||
/* needed for ldap_open */
|
|
||||||
char *ldaphost;
|
|
||||||
int ldapport;
|
|
||||||
|
|
||||||
/* Options set in ld struct before ldap_bind_s */
|
|
||||||
int deref;
|
|
||||||
int timelimit;
|
|
||||||
int sizelimit;
|
|
||||||
int ldap_options;
|
|
||||||
|
|
||||||
/* args for ldap_bind_s */
|
|
||||||
LDAP *ld;
|
|
||||||
char *binddn;
|
|
||||||
char *passwd;
|
|
||||||
int method;
|
|
||||||
|
|
||||||
/* args for ldap_search_st */
|
|
||||||
char *base;
|
|
||||||
int scope;
|
|
||||||
char *filter;
|
|
||||||
char *attr[2];
|
|
||||||
int attrsonly;
|
|
||||||
struct timeval timeout;
|
|
||||||
LDAPMessage *res;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct ldap_map_struct LDAP_MAP_STRUCT;
|
|
||||||
|
|
||||||
#define DEFAULT_LDAP_MAP_PORT LDAP_PORT
|
|
||||||
#define DEFAULT_LDAP_MAP_SCOPE LDAP_SCOPE_SUBTREE
|
|
||||||
#define DEFAULT_LDAP_MAP_BINDDN NULL
|
|
||||||
#define DEFAULT_LDAP_MAP_PASSWD NULL
|
|
||||||
#define DEFAULT_LDAP_MAP_METHOD LDAP_AUTH_SIMPLE
|
|
||||||
#define DEFAULT_LDAP_MAP_TIMELIMIT 5
|
|
||||||
#define DEFAULT_LDAP_MAP_DEREF LDAP_DEREF_NEVER
|
|
||||||
#define DEFAULT_LDAP_MAP_SIZELIMIT 0
|
|
||||||
#define DEFAULT_LDAP_MAP_ATTRSONLY 0
|
|
||||||
#define LDAP_MAP_MAX_FILTER 1024
|
|
||||||
#ifdef LDAP_REFERRALS
|
|
||||||
# define DEFAULT_LDAP_MAP_LDAP_OPTIONS LDAP_OPT_REFERRALS
|
|
||||||
#else /* LDAP_REFERRALS */
|
|
||||||
# define DEFAULT_LDAP_MAP_LDAP_OPTIONS 0
|
|
||||||
#endif /* LDAP_REFERRALS */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ldap_init(3) is broken in Umich 3.x and OpenLDAP 1.0/1.1.
|
|
||||||
** Use the lack of LDAP_OPT_SIZELIMIT to detect old API implementations
|
|
||||||
** and assume (falsely) that all old API implementations are broken.
|
|
||||||
** (OpenLDAP 1.2 and later have a working ldap_init(), add -DUSE_LDAP_INIT)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_INIT)
|
|
||||||
# define USE_LDAP_INIT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
** LDAP_OPT_SIZELIMIT is not defined under Umich 3.x nor OpenLDAP 1.x,
|
|
||||||
** hence ldap_set_option() must not exist.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_SET_OPTION)
|
|
||||||
# define USE_LDAP_SET_OPTION 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _LDAP_MAP_H */
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
|
|
||||||
* Copyright (c) 1988, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @(#)mailstats.h 8.8 (Berkeley) 5/19/1998
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define STAT_VERSION 2
|
|
||||||
#define STAT_MAGIC 0x1B1DE
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Statistics structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct statistics
|
|
||||||
{
|
|
||||||
int stat_magic; /* magic number */
|
|
||||||
int stat_version; /* stat file version */
|
|
||||||
time_t stat_itime; /* file initialization time */
|
|
||||||
short stat_size; /* size of this structure */
|
|
||||||
long stat_nf[MAXMAILERS]; /* # msgs from each mailer */
|
|
||||||
long stat_bf[MAXMAILERS]; /* kbytes from each mailer */
|
|
||||||
long stat_nt[MAXMAILERS]; /* # msgs to each mailer */
|
|
||||||
long stat_bt[MAXMAILERS]; /* kbytes to each mailer */
|
|
||||||
long stat_nr[MAXMAILERS]; /* # rejects by each mailer */
|
|
||||||
long stat_nd[MAXMAILERS]; /* # discards by each mailer */
|
|
||||||
};
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*-
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1990, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @(#)pathnames.h 8.8 (Berkeley) 5/19/1998
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PATH_SENDMAILCF
|
|
||||||
# if defined(USE_VENDOR_CF_PATH) && defined(_PATH_VENDOR_CF)
|
|
||||||
# define _PATH_SENDMAILCF _PATH_VENDOR_CF
|
|
||||||
# else
|
|
||||||
# define _PATH_SENDMAILCF "/etc/sendmail.cf"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_SENDMAILPID
|
|
||||||
# ifdef BSD4_4
|
|
||||||
# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
|
|
||||||
# else
|
|
||||||
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _PATH_HOSTS
|
|
||||||
# define _PATH_HOSTS "/etc/hosts"
|
|
||||||
#endif
|
|
|
@ -1,751 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
|
|
||||||
* Copyright (c) 1988, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
static char sccsid[] = "@(#)safefile.c 8.43 (Berkeley) 10/13/1998";
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
# include "sendmail.h"
|
|
||||||
/*
|
|
||||||
** SAFEFILE -- return true if a file exists and is safe for a user.
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** fn -- filename to check.
|
|
||||||
** uid -- user id to compare against.
|
|
||||||
** gid -- group id to compare against.
|
|
||||||
** uname -- user name to compare against (used for group
|
|
||||||
** sets).
|
|
||||||
** flags -- modifiers:
|
|
||||||
** SFF_MUSTOWN -- "uid" must own this file.
|
|
||||||
** SFF_NOSLINK -- file cannot be a symbolic link.
|
|
||||||
** mode -- mode bits that must match.
|
|
||||||
** st -- if set, points to a stat structure that will
|
|
||||||
** get the stat info for the file.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** 0 if fn exists, is owned by uid, and matches mode.
|
|
||||||
** An errno otherwise. The actual errno is cleared.
|
|
||||||
**
|
|
||||||
** Side Effects:
|
|
||||||
** none.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <grp.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
safefile(fn, uid, gid, uname, flags, mode, st)
|
|
||||||
char *fn;
|
|
||||||
UID_T uid;
|
|
||||||
GID_T gid;
|
|
||||||
char *uname;
|
|
||||||
int flags;
|
|
||||||
int mode;
|
|
||||||
struct stat *st;
|
|
||||||
{
|
|
||||||
register char *p;
|
|
||||||
register struct group *gr = NULL;
|
|
||||||
int file_errno = 0;
|
|
||||||
bool checkpath;
|
|
||||||
struct stat stbuf;
|
|
||||||
struct stat fstbuf;
|
|
||||||
char fbuf[MAXPATHLEN + 1];
|
|
||||||
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("safefile(%s, uid=%d, gid=%d, flags=%x, mode=%o):\n",
|
|
||||||
fn, (int) uid, (int) gid, flags, mode);
|
|
||||||
errno = 0;
|
|
||||||
if (st == NULL)
|
|
||||||
st = &fstbuf;
|
|
||||||
if (strlen(fn) > sizeof fbuf - 1)
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\tpathname too long\n");
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
}
|
|
||||||
strcpy(fbuf, fn);
|
|
||||||
fn = fbuf;
|
|
||||||
|
|
||||||
/* ignore SFF_SAFEDIRPATH if we are debugging */
|
|
||||||
if (RealUid != 0 && RunAsUid == RealUid)
|
|
||||||
flags &= ~SFF_SAFEDIRPATH;
|
|
||||||
|
|
||||||
/* first check to see if the file exists at all */
|
|
||||||
#ifdef HASLSTAT
|
|
||||||
if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st)
|
|
||||||
: stat(fn, st)) < 0)
|
|
||||||
#else
|
|
||||||
if (stat(fn, st) < 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
file_errno = errno;
|
|
||||||
}
|
|
||||||
else if (bitset(SFF_SETUIDOK, flags) &&
|
|
||||||
!bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode) &&
|
|
||||||
S_ISREG(st->st_mode))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
** If final file is setuid, run as the owner of that
|
|
||||||
** file. Gotta be careful not to reveal anything too
|
|
||||||
** soon here!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef SUID_ROOT_FILES_OK
|
|
||||||
if (bitset(S_ISUID, st->st_mode))
|
|
||||||
#else
|
|
||||||
if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0 &&
|
|
||||||
st->st_uid != TrustedUid)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
uid = st->st_uid;
|
|
||||||
uname = NULL;
|
|
||||||
}
|
|
||||||
#ifdef SUID_ROOT_FILES_OK
|
|
||||||
if (bitset(S_ISGID, st->st_mode))
|
|
||||||
#else
|
|
||||||
if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0)
|
|
||||||
#endif
|
|
||||||
gid = st->st_gid;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkpath = !bitset(SFF_NOPATHCHECK, flags) ||
|
|
||||||
(uid == 0 && !bitset(SFF_ROOTOK|SFF_OPENASROOT, flags));
|
|
||||||
if (bitset(SFF_NOWLINK, flags) && !bitset(SFF_SAFEDIRPATH, flags))
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* check the directory */
|
|
||||||
p = strrchr(fn, '/');
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
ret = safedirpath(".", uid, gid, uname, flags|SFF_SAFEDIRPATH);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
ret = safedirpath(fn, uid, gid, uname, flags|SFF_SAFEDIRPATH);
|
|
||||||
*p = '/';
|
|
||||||
}
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
/* directory is safe */
|
|
||||||
checkpath = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef HASLSTAT
|
|
||||||
/* Need lstat() information if called stat() before */
|
|
||||||
if (!bitset(SFF_NOSLINK, flags) && lstat(fn, st) < 0)
|
|
||||||
{
|
|
||||||
ret = errno;
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t%s\n", errstring(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* directory is writable: disallow links */
|
|
||||||
flags |= SFF_NOLINK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkpath)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
p = strrchr(fn, '/');
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
ret = safedirpath(".", uid, gid, uname, flags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
ret = safedirpath(fn, uid, gid, uname, flags);
|
|
||||||
*p = '/';
|
|
||||||
}
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** If the target file doesn't exist, check the directory to
|
|
||||||
** ensure that it is writable by this user.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (file_errno != 0)
|
|
||||||
{
|
|
||||||
int ret = file_errno;
|
|
||||||
char *dir = fn;
|
|
||||||
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t%s\n", errstring(ret));
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
if (!bitset(SFF_CREAT, flags) || file_errno != ENOENT)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* check to see if legal to create the file */
|
|
||||||
p = strrchr(dir, '/');
|
|
||||||
if (p == NULL)
|
|
||||||
dir = ".";
|
|
||||||
else if (p == dir)
|
|
||||||
dir = "/";
|
|
||||||
else
|
|
||||||
*p = '\0';
|
|
||||||
if (stat(dir, &stbuf) >= 0)
|
|
||||||
{
|
|
||||||
int md = S_IWRITE|S_IEXEC;
|
|
||||||
|
|
||||||
if (stbuf.st_uid == uid)
|
|
||||||
;
|
|
||||||
else if (uid == 0 && stbuf.st_uid == TrustedUid)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
md >>= 3;
|
|
||||||
if (stbuf.st_gid == gid)
|
|
||||||
;
|
|
||||||
#ifndef NO_GROUP_SET
|
|
||||||
else if (uname != NULL && !DontInitGroups &&
|
|
||||||
((gr != NULL &&
|
|
||||||
gr->gr_gid == stbuf.st_gid) ||
|
|
||||||
(gr = getgrgid(stbuf.st_gid)) != NULL))
|
|
||||||
{
|
|
||||||
register char **gp;
|
|
||||||
|
|
||||||
for (gp = gr->gr_mem; *gp != NULL; gp++)
|
|
||||||
if (strcmp(*gp, uname) == 0)
|
|
||||||
break;
|
|
||||||
if (*gp == NULL)
|
|
||||||
md >>= 3;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
md >>= 3;
|
|
||||||
}
|
|
||||||
if ((stbuf.st_mode & md) != md)
|
|
||||||
errno = EACCES;
|
|
||||||
}
|
|
||||||
ret = errno;
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[final dir %s uid %d mode %lo] %s\n",
|
|
||||||
dir, (int) stbuf.st_uid, (u_long) stbuf.st_mode,
|
|
||||||
errstring(ret));
|
|
||||||
if (p != NULL)
|
|
||||||
*p = '/';
|
|
||||||
st->st_mode = ST_MODE_NOFILE;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef S_ISLNK
|
|
||||||
if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[slink mode %lo]\tE_SM_NOSLINK\n",
|
|
||||||
(u_long) st->st_mode);
|
|
||||||
return E_SM_NOSLINK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[non-reg mode %lo]\tE_SM_REGONLY\n",
|
|
||||||
(u_long) st->st_mode);
|
|
||||||
return E_SM_REGONLY;
|
|
||||||
}
|
|
||||||
if (bitset(SFF_NOGWFILES, flags) &&
|
|
||||||
bitset(S_IWGRP, st->st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[write bits %lo]\tE_SM_GWFILE\n",
|
|
||||||
(u_long) st->st_mode);
|
|
||||||
return E_SM_GWFILE;
|
|
||||||
}
|
|
||||||
if (bitset(SFF_NOWWFILES, flags) &&
|
|
||||||
bitset(S_IWOTH, st->st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[write bits %lo]\tE_SM_WWFILE\n",
|
|
||||||
(u_long) st->st_mode);
|
|
||||||
return E_SM_WWFILE;
|
|
||||||
}
|
|
||||||
if (bitset(S_IWUSR|S_IWGRP|S_IWOTH, mode) &&
|
|
||||||
bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[exec bits %lo]\tE_SM_ISEXEC]\n",
|
|
||||||
(u_long) st->st_mode);
|
|
||||||
return E_SM_ISEXEC;
|
|
||||||
}
|
|
||||||
if (bitset(SFF_NOHLINK, flags) && st->st_nlink != 1)
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[link count %d]\tE_SM_NOHLINK\n",
|
|
||||||
(int) st->st_nlink);
|
|
||||||
return E_SM_NOHLINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uid == 0 && bitset(SFF_OPENASROOT, flags))
|
|
||||||
;
|
|
||||||
else if (uid == 0 && !bitset(SFF_ROOTOK, flags))
|
|
||||||
mode >>= 6;
|
|
||||||
else if (st->st_uid == uid)
|
|
||||||
;
|
|
||||||
else if (uid == 0 && st->st_uid == TrustedUid)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mode >>= 3;
|
|
||||||
if (st->st_gid == gid)
|
|
||||||
;
|
|
||||||
#ifndef NO_GROUP_SET
|
|
||||||
else if (uname != NULL && !DontInitGroups &&
|
|
||||||
((gr != NULL && gr->gr_gid == st->st_gid) ||
|
|
||||||
(gr = getgrgid(st->st_gid)) != NULL))
|
|
||||||
{
|
|
||||||
register char **gp;
|
|
||||||
|
|
||||||
for (gp = gr->gr_mem; *gp != NULL; gp++)
|
|
||||||
if (strcmp(*gp, uname) == 0)
|
|
||||||
break;
|
|
||||||
if (*gp == NULL)
|
|
||||||
mode >>= 3;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
mode >>= 3;
|
|
||||||
}
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[uid %d, nlink %d, stat %lo, mode %lo] ",
|
|
||||||
(int) st->st_uid, (int) st->st_nlink,
|
|
||||||
(u_long) st->st_mode, (u_long) mode);
|
|
||||||
if ((st->st_uid == uid || st->st_uid == 0 ||
|
|
||||||
st->st_uid == TrustedUid ||
|
|
||||||
!bitset(SFF_MUSTOWN, flags)) &&
|
|
||||||
(st->st_mode & mode) == mode)
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\tOK\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\tEACCES\n");
|
|
||||||
return EACCES;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** SAFEDIRPATH -- check to make sure a path to a directory is safe
|
|
||||||
**
|
|
||||||
** Safe means not writable and owned by the right folks.
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** fn -- filename to check.
|
|
||||||
** uid -- user id to compare against.
|
|
||||||
** gid -- group id to compare against.
|
|
||||||
** uname -- user name to compare against (used for group
|
|
||||||
** sets).
|
|
||||||
** flags -- modifiers:
|
|
||||||
** SFF_ROOTOK -- ok to use root permissions to open.
|
|
||||||
** SFF_SAFEDIRPATH -- writable directories are considered
|
|
||||||
** to be fatal errors.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** 0 -- if the directory path is "safe".
|
|
||||||
** else -- an error number associated with the path.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
safedirpath(fn, uid, gid, uname, flags)
|
|
||||||
char *fn;
|
|
||||||
UID_T uid;
|
|
||||||
GID_T gid;
|
|
||||||
char *uname;
|
|
||||||
int flags;
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
register struct group *gr = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
int mode = S_IWOTH;
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
/* special case root directory */
|
|
||||||
if (*fn == '\0')
|
|
||||||
fn = "/";
|
|
||||||
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("safedirpath(%s, uid=%ld, gid=%ld, flags=%x):\n",
|
|
||||||
fn, (long) uid, (long) gid, flags);
|
|
||||||
|
|
||||||
if (!bitset(DBS_GROUPWRITABLEDIRPATHSAFE, DontBlameSendmail))
|
|
||||||
mode |= S_IWGRP;
|
|
||||||
|
|
||||||
p = fn;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (*p == '\0')
|
|
||||||
*p = '/';
|
|
||||||
p = strchr(++p, '/');
|
|
||||||
if (p != NULL)
|
|
||||||
*p = '\0';
|
|
||||||
if (stat(fn, &stbuf) < 0)
|
|
||||||
{
|
|
||||||
ret = errno;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((uid == 0 || bitset(SFF_SAFEDIRPATH, flags)) &&
|
|
||||||
bitset(mode, stbuf.st_mode))
|
|
||||||
{
|
|
||||||
if (tTd(44, 4))
|
|
||||||
printf("\t[dir %s] mode %lo\n",
|
|
||||||
fn, (u_long) stbuf.st_mode);
|
|
||||||
if (bitset(SFF_SAFEDIRPATH, flags))
|
|
||||||
{
|
|
||||||
if (bitset(S_IWOTH, stbuf.st_mode))
|
|
||||||
ret = E_SM_WWDIR;
|
|
||||||
else
|
|
||||||
ret = E_SM_GWDIR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Verbose > 1)
|
|
||||||
message("051 WARNING: %s writable directory %s",
|
|
||||||
bitset(S_IWOTH, stbuf.st_mode)
|
|
||||||
? "World"
|
|
||||||
: "Group",
|
|
||||||
fn);
|
|
||||||
}
|
|
||||||
if (uid == 0 && !bitset(SFF_ROOTOK|SFF_OPENASROOT, flags))
|
|
||||||
{
|
|
||||||
if (bitset(S_IXOTH, stbuf.st_mode))
|
|
||||||
continue;
|
|
||||||
ret = EACCES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Let OS determine access to file if we are not
|
|
||||||
** running as a privileged user. This allows ACLs
|
|
||||||
** to work.
|
|
||||||
*/
|
|
||||||
if (geteuid() != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (stbuf.st_uid == uid &&
|
|
||||||
bitset(S_IXUSR, stbuf.st_mode))
|
|
||||||
continue;
|
|
||||||
if (stbuf.st_gid == gid &&
|
|
||||||
bitset(S_IXGRP, stbuf.st_mode))
|
|
||||||
continue;
|
|
||||||
#ifndef NO_GROUP_SET
|
|
||||||
if (uname != NULL && !DontInitGroups &&
|
|
||||||
((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
|
|
||||||
(gr = getgrgid(stbuf.st_gid)) != NULL))
|
|
||||||
{
|
|
||||||
register char **gp;
|
|
||||||
|
|
||||||
for (gp = gr->gr_mem; gp != NULL && *gp != NULL; gp++)
|
|
||||||
if (strcmp(*gp, uname) == 0)
|
|
||||||
break;
|
|
||||||
if (gp != NULL && *gp != NULL &&
|
|
||||||
bitset(S_IXGRP, stbuf.st_mode))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!bitset(S_IXOTH, stbuf.st_mode))
|
|
||||||
{
|
|
||||||
ret = EACCES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (p != NULL);
|
|
||||||
if (ret != 0 && tTd(44, 4))
|
|
||||||
printf("\t[dir %s] %s\n", fn, errstring(ret));
|
|
||||||
if (p != NULL)
|
|
||||||
*p = '/';
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** SAFEOPEN -- do a file open with extra checking
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** fn -- the file name to open.
|
|
||||||
** omode -- the open-style mode flags.
|
|
||||||
** cmode -- the create-style mode flags.
|
|
||||||
** sff -- safefile flags.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** Same as open.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef O_ACCMODE
|
|
||||||
# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
safeopen(fn, omode, cmode, sff)
|
|
||||||
char *fn;
|
|
||||||
int omode;
|
|
||||||
int cmode;
|
|
||||||
int sff;
|
|
||||||
{
|
|
||||||
int rval;
|
|
||||||
int fd;
|
|
||||||
int smode;
|
|
||||||
struct stat stb;
|
|
||||||
|
|
||||||
if (bitset(O_CREAT, omode))
|
|
||||||
sff |= SFF_CREAT;
|
|
||||||
omode &= ~O_CREAT;
|
|
||||||
smode = 0;
|
|
||||||
switch (omode & O_ACCMODE)
|
|
||||||
{
|
|
||||||
case O_RDONLY:
|
|
||||||
smode = S_IREAD;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case O_WRONLY:
|
|
||||||
smode = S_IWRITE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case O_RDWR:
|
|
||||||
smode = S_IREAD|S_IWRITE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
smode = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (bitset(SFF_OPENASROOT, sff))
|
|
||||||
rval = safefile(fn, RunAsUid, RunAsGid, RunAsUserName,
|
|
||||||
sff, smode, &stb);
|
|
||||||
else
|
|
||||||
rval = safefile(fn, RealUid, RealGid, RealUserName,
|
|
||||||
sff, smode, &stb);
|
|
||||||
if (rval != 0)
|
|
||||||
{
|
|
||||||
errno = rval;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (stb.st_mode == ST_MODE_NOFILE && bitset(SFF_CREAT, sff))
|
|
||||||
omode |= O_EXCL|O_CREAT;
|
|
||||||
|
|
||||||
fd = dfopen(fn, omode, cmode, sff);
|
|
||||||
if (fd < 0)
|
|
||||||
return fd;
|
|
||||||
if (filechanged(fn, fd, &stb))
|
|
||||||
{
|
|
||||||
syserr("554 cannot open: file %s changed after open", fn);
|
|
||||||
close(fd);
|
|
||||||
errno = E_SM_FILECHANGE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** SAFEFOPEN -- do a file open with extra checking
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** fn -- the file name to open.
|
|
||||||
** omode -- the open-style mode flags.
|
|
||||||
** cmode -- the create-style mode flags.
|
|
||||||
** sff -- safefile flags.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** Same as fopen.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FILE *
|
|
||||||
safefopen(fn, omode, cmode, sff)
|
|
||||||
char *fn;
|
|
||||||
int omode;
|
|
||||||
int cmode;
|
|
||||||
int sff;
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
FILE *fp;
|
|
||||||
char *fmode;
|
|
||||||
|
|
||||||
switch (omode & O_ACCMODE)
|
|
||||||
{
|
|
||||||
case O_RDONLY:
|
|
||||||
fmode = "r";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case O_WRONLY:
|
|
||||||
if (bitset(O_APPEND, omode))
|
|
||||||
fmode = "a";
|
|
||||||
else
|
|
||||||
fmode = "w";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case O_RDWR:
|
|
||||||
if (bitset(O_TRUNC, omode))
|
|
||||||
fmode = "w+";
|
|
||||||
else if (bitset(O_APPEND, omode))
|
|
||||||
fmode = "a+";
|
|
||||||
else
|
|
||||||
fmode = "r+";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
syserr("safefopen: unknown omode %o", omode);
|
|
||||||
fmode = "x";
|
|
||||||
}
|
|
||||||
fd = safeopen(fn, omode, cmode, sff);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
if (tTd(44, 10))
|
|
||||||
printf("safefopen: safeopen failed: %s\n",
|
|
||||||
errstring(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
fp = fdopen(fd, fmode);
|
|
||||||
if (fp != NULL)
|
|
||||||
return fp;
|
|
||||||
|
|
||||||
if (tTd(44, 10))
|
|
||||||
{
|
|
||||||
printf("safefopen: fdopen(%s, %s) failed: omode=%x, sff=%x, err=%s\n",
|
|
||||||
fn, fmode, omode, sff, errstring(errno));
|
|
||||||
#ifndef NOT_SENDMAIL
|
|
||||||
dumpfd(fd, TRUE, FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
(void) close(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** FILECHANGED -- check to see if file changed after being opened
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** fn -- pathname of file to check.
|
|
||||||
** fd -- file descriptor to check.
|
|
||||||
** stb -- stat structure from before open.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** TRUE -- if a problem was detected.
|
|
||||||
** FALSE -- if this file is still the same.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
filechanged(fn, fd, stb)
|
|
||||||
char *fn;
|
|
||||||
int fd;
|
|
||||||
struct stat *stb;
|
|
||||||
{
|
|
||||||
struct stat sta;
|
|
||||||
|
|
||||||
if (stb->st_mode == ST_MODE_NOFILE)
|
|
||||||
{
|
|
||||||
#if HASLSTAT && BOGUS_O_EXCL
|
|
||||||
/* only necessary if exclusive open follows symbolic links */
|
|
||||||
if (lstat(fn, stb) < 0 || stb->st_nlink != 1)
|
|
||||||
return TRUE;
|
|
||||||
#else
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (fstat(fd, &sta) < 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (sta.st_nlink != stb->st_nlink ||
|
|
||||||
sta.st_dev != stb->st_dev ||
|
|
||||||
sta.st_ino != stb->st_ino ||
|
|
||||||
#if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
|
|
||||||
sta.st_gen != stb->st_gen ||
|
|
||||||
#endif
|
|
||||||
sta.st_uid != stb->st_uid ||
|
|
||||||
sta.st_gid != stb->st_gid)
|
|
||||||
{
|
|
||||||
if (tTd(44, 8))
|
|
||||||
{
|
|
||||||
printf("File changed after opening:\n");
|
|
||||||
printf(" nlink = %ld/%ld\n",
|
|
||||||
(long) stb->st_nlink, (long) sta.st_nlink);
|
|
||||||
printf(" dev = %ld/%ld\n",
|
|
||||||
(long) stb->st_dev, (long) sta.st_dev);
|
|
||||||
if (sizeof sta.st_ino > sizeof (long))
|
|
||||||
{
|
|
||||||
printf(" ino = %s/",
|
|
||||||
quad_to_string(stb->st_ino));
|
|
||||||
printf("%s\n",
|
|
||||||
quad_to_string(sta.st_ino));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf(" ino = %lu/%lu\n",
|
|
||||||
(unsigned long) stb->st_ino,
|
|
||||||
(unsigned long) sta.st_ino);
|
|
||||||
#if HAS_ST_GEN
|
|
||||||
printf(" gen = %ld/%ld\n",
|
|
||||||
(long) stb->st_gen, (long) sta.st_gen);
|
|
||||||
#endif
|
|
||||||
printf(" uid = %ld/%ld\n",
|
|
||||||
(long) stb->st_uid, (long) sta.st_uid);
|
|
||||||
printf(" gid = %ld/%ld\n",
|
|
||||||
(long) stb->st_gid, (long) sta.st_gid);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** DFOPEN -- determined file open
|
|
||||||
**
|
|
||||||
** This routine has the semantics of open, except that it will
|
|
||||||
** keep trying a few times to make this happen. The idea is that
|
|
||||||
** on very loaded systems, we may run out of resources (inodes,
|
|
||||||
** whatever), so this tries to get around it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
dfopen(filename, omode, cmode, sff)
|
|
||||||
char *filename;
|
|
||||||
int omode;
|
|
||||||
int cmode;
|
|
||||||
int sff;
|
|
||||||
{
|
|
||||||
register int tries;
|
|
||||||
int fd;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
for (tries = 0; tries < 10; tries++)
|
|
||||||
{
|
|
||||||
sleep((unsigned) (10 * tries));
|
|
||||||
errno = 0;
|
|
||||||
fd = open(filename, omode, cmode);
|
|
||||||
if (fd >= 0)
|
|
||||||
break;
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case ENFILE: /* system file table full */
|
|
||||||
case EINTR: /* interrupted syscall */
|
|
||||||
#ifdef ETXTBSY
|
|
||||||
case ETXTBSY: /* Apollo: net file locked */
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!bitset(SFF_NOLOCK, sff) &&
|
|
||||||
fd >= 0 &&
|
|
||||||
fstat(fd, &st) >= 0 &&
|
|
||||||
S_ISREG(st.st_mode))
|
|
||||||
{
|
|
||||||
int locktype;
|
|
||||||
|
|
||||||
/* lock the file to avoid accidental conflicts */
|
|
||||||
if ((omode & O_ACCMODE) != O_RDONLY)
|
|
||||||
locktype = LOCK_EX;
|
|
||||||
else
|
|
||||||
locktype = LOCK_SH;
|
|
||||||
(void) lockfile(fd, filename, NULL, locktype);
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
cpyr
|
|
||||||
cpyr Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
cpyr Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
|
|
||||||
cpyr Copyright (c) 1988, 1993
|
|
||||||
cpyr The Regents of the University of California. All rights reserved.
|
|
||||||
cpyr
|
|
||||||
cpyr
|
|
||||||
cpyr By using this file, you agree to the terms and conditions set
|
|
||||||
cpyr forth in the LICENSE file which can be found at the top level of
|
|
||||||
cpyr the sendmail distribution.
|
|
||||||
cpyr
|
|
||||||
cpyr @(#)sendmail.hf 8.18 (Berkeley) 11/19/1998
|
|
||||||
cpyr
|
|
||||||
smtp Topics:
|
|
||||||
smtp HELO EHLO MAIL RCPT DATA
|
|
||||||
smtp RSET NOOP QUIT HELP VRFY
|
|
||||||
smtp EXPN VERB ETRN DSN
|
|
||||||
smtp For more info use "HELP <topic>".
|
|
||||||
smtp To report bugs in the implementation send email to
|
|
||||||
smtp sendmail-bugs@sendmail.org.
|
|
||||||
smtp For local information send email to Postmaster at your site.
|
|
||||||
help HELP [ <topic> ]
|
|
||||||
help The HELP command gives help info.
|
|
||||||
helo HELO <hostname>
|
|
||||||
helo Introduce yourself.
|
|
||||||
ehlo EHLO <hostname>
|
|
||||||
ehlo Introduce yourself, and request extended SMTP mode.
|
|
||||||
ehlo Possible replies include:
|
|
||||||
ehlo SEND Send as mail [RFC821]
|
|
||||||
ehlo SOML Send as mail or terminal [RFC821]
|
|
||||||
ehlo SAML Send as mail and terminal [RFC821]
|
|
||||||
ehlo EXPN Expand the mailing list [RFC821]
|
|
||||||
ehlo HELP Supply helpful information [RFC821]
|
|
||||||
ehlo TURN Turn the operation around [RFC821]
|
|
||||||
ehlo 8BITMIME Use 8-bit data [RFC1652]
|
|
||||||
ehlo SIZE Message size declaration [RFC1870]
|
|
||||||
ehlo VERB Verbose [Allman]
|
|
||||||
ehlo ONEX One message transaction only [Allman]
|
|
||||||
ehlo CHUNKING Chunking [RFC1830]
|
|
||||||
ehlo BINARYMIME Binary MIME [RFC1830]
|
|
||||||
ehlo PIPELINING Command Pipelining [RFC1854]
|
|
||||||
ehlo DSN Delivery Status Notification [RFC1891]
|
|
||||||
ehlo ETRN Remote Message Queue Starting [RFC1985]
|
|
||||||
ehlo XUSR Initial (user) submission [Allman]
|
|
||||||
mail MAIL FROM: <sender> [ <parameters> ]
|
|
||||||
mail Specifies the sender. Parameters are ESMTP extensions.
|
|
||||||
mail See "HELP DSN" for details.
|
|
||||||
rcpt RCPT TO: <recipient> [ <parameters> ]
|
|
||||||
rcpt Specifies the recipient. Can be used any number of times.
|
|
||||||
rcpt Parameters are ESMTP extensions. See "HELP DSN" for details.
|
|
||||||
data DATA
|
|
||||||
data Following text is collected as the message.
|
|
||||||
data End with a single dot.
|
|
||||||
rset RSET
|
|
||||||
rset Resets the system.
|
|
||||||
quit QUIT
|
|
||||||
quit Exit sendmail (SMTP).
|
|
||||||
verb VERB
|
|
||||||
verb Go into verbose mode. This sends 0xy responses that are
|
|
||||||
verb not RFC821 standard (but should be) They are recognized
|
|
||||||
verb by humans and other sendmail implementations.
|
|
||||||
vrfy VRFY <recipient>
|
|
||||||
vrfy Verify an address. If you want to see what it aliases
|
|
||||||
vrfy to, use EXPN instead.
|
|
||||||
expn EXPN <recipient>
|
|
||||||
expn Expand an address. If the address indicates a mailing
|
|
||||||
expn list, return the contents of that list.
|
|
||||||
noop NOOP
|
|
||||||
noop Do nothing.
|
|
||||||
send SEND FROM: <sender>
|
|
||||||
send replaces the MAIL command, and can be used to send
|
|
||||||
send directly to a users terminal. Not supported in this
|
|
||||||
send implementation.
|
|
||||||
soml SOML FROM: <sender>
|
|
||||||
soml Send or mail. If the user is logged in, send directly,
|
|
||||||
soml otherwise mail. Not supported in this implementation.
|
|
||||||
saml SAML FROM: <sender>
|
|
||||||
saml Send and mail. Send directly to the user's terminal,
|
|
||||||
saml and also mail a letter. Not supported in this
|
|
||||||
saml implementation.
|
|
||||||
turn TURN
|
|
||||||
turn Reverses the direction of the connection. Not currently
|
|
||||||
turn implemented.
|
|
||||||
etrn ETRN [ <hostname> | @<domain> | #<queuename> ]
|
|
||||||
etrn Run the queue for the specified <hostname>, or
|
|
||||||
etrn all hosts within a given <domain>, or a specially-named
|
|
||||||
etrn <queuename> (implementation-specific).
|
|
||||||
dsn MAIL FROM: <sender> [ RET={ FULL | HDRS} ] [ ENVID=<envid> ]
|
|
||||||
dsn RCPT TO: <recipient> [ NOTIFY={NEVER,SUCCESS,FAILURE,DELAY} ]
|
|
||||||
dsn [ ORCPT=<recipient> ]
|
|
||||||
dsn SMTP Delivery Status Notifications.
|
|
||||||
dsn Descriptions:
|
|
||||||
dsn RET Return either the full message or only headers.
|
|
||||||
dsn ENVID Sender's "envelope identifier" for tracking.
|
|
||||||
dsn NOTIFY When to send a DSN. Multiple options are OK, comma-
|
|
||||||
dsn delimited. NEVER must appear by itself.
|
|
||||||
dsn ORCPT Original recipient.
|
|
||||||
-bt Help for test mode:
|
|
||||||
-bt ? :this help message.
|
|
||||||
-bt .Dmvalue :define macro `m' to `value'.
|
|
||||||
-bt .Ccvalue :add `value' to class `c'.
|
|
||||||
-bt =Sruleset :dump the contents of the indicated ruleset.
|
|
||||||
-bt =M :display the known mailers.
|
|
||||||
-bt -ddebug-spec :equivalent to the command-line -d debug flag.
|
|
||||||
-bt $m :print the value of macro $m.
|
|
||||||
-bt $=c :print the contents of class $=c.
|
|
||||||
-bt /mx host :returns the MX records for `host'.
|
|
||||||
-bt /parse address :parse address, returning the value of crackaddr, and
|
|
||||||
-bt the parsed address (same as -bv).
|
|
||||||
-bt /try mailer addr :rewrite address into the form it will have when
|
|
||||||
-bt presented to the indicated mailer.
|
|
||||||
-bt /tryflags flags :set flags used by parsing. The flags can be `H' for
|
|
||||||
-bt Header or `E' for Envelope, and `S' for Sender or `R'
|
|
||||||
-bt for Recipient. These can be combined, `HR' sets
|
|
||||||
-bt flags for header recipients.
|
|
||||||
-bt /canon hostname :try to canonify hostname.
|
|
||||||
-bt /map mapname key :look up `key' in the indicated `mapname'.
|
|
||||||
-bt rules addr :run the indicated address through the named rules.
|
|
||||||
-bt Rules can be a comma separated list of rules.
|
|
||||||
control Help for smcontrol:
|
|
||||||
control help This message.
|
|
||||||
control restart Restart sendmail.
|
|
||||||
control shutdown Shutdown sendmail.
|
|
||||||
control status Show sendmail status.
|
|
|
@ -1,428 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1997 Eric P. Allman. All rights reserved.
|
|
||||||
* Copyright (c) 1988, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
static char sccsid[] = "@(#)snprintf.c 8.12 (Berkeley) 10/13/1998";
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include "sendmail.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNPRINTF, VSNPRINT -- counted versions of printf
|
|
||||||
**
|
|
||||||
** These versions have been grabbed off the net. They have been
|
|
||||||
** cleaned up to compile properly and support for .precision and
|
|
||||||
** %lx has been added.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
* Original:
|
|
||||||
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
|
|
||||||
* A bombproof version of doprnt (sm_dopr) included.
|
|
||||||
* Sigh. This sort of thing is always nasty do deal with. Note that
|
|
||||||
* the version here does not include floating point...
|
|
||||||
*
|
|
||||||
* snprintf() is used instead of sprintf() as it does limit checks
|
|
||||||
* for string length. This covers a nasty loophole.
|
|
||||||
*
|
|
||||||
* The other functions are there to prevent NULL pointers from
|
|
||||||
* causing nast effects.
|
|
||||||
**************************************************************/
|
|
||||||
|
|
||||||
/*static char _id[] = "$Id: snprintf.c,v 1.2 1995/10/09 11:19:47 roberto Exp $";*/
|
|
||||||
void sm_dopr();
|
|
||||||
char *DoprEnd;
|
|
||||||
int SnprfOverflow;
|
|
||||||
|
|
||||||
#if !HASSNPRINTF
|
|
||||||
|
|
||||||
/* VARARGS3 */
|
|
||||||
int
|
|
||||||
# ifdef __STDC__
|
|
||||||
snprintf(char *str, size_t count, const char *fmt, ...)
|
|
||||||
# else
|
|
||||||
snprintf(str, count, fmt, va_alist)
|
|
||||||
char *str;
|
|
||||||
size_t count;
|
|
||||||
const char *fmt;
|
|
||||||
va_dcl
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
VA_LOCAL_DECL
|
|
||||||
|
|
||||||
VA_START(fmt);
|
|
||||||
len = vsnprintf(str, count, fmt, ap);
|
|
||||||
VA_END;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ifndef luna2
|
|
||||||
int
|
|
||||||
vsnprintf(str, count, fmt, args)
|
|
||||||
char *str;
|
|
||||||
size_t count;
|
|
||||||
const char *fmt;
|
|
||||||
va_list args;
|
|
||||||
{
|
|
||||||
str[0] = 0;
|
|
||||||
DoprEnd = str + count - 1;
|
|
||||||
SnprfOverflow = 0;
|
|
||||||
sm_dopr( str, fmt, args );
|
|
||||||
if (count > 0)
|
|
||||||
DoprEnd[0] = 0;
|
|
||||||
if (SnprfOverflow && tTd(57, 2))
|
|
||||||
printf("\nvsnprintf overflow, len = %ld, str = %s",
|
|
||||||
(long) count, shortenstring(str, MAXSHORTSTR));
|
|
||||||
return strlen(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* !luna2 */
|
|
||||||
#endif /* !HASSNPRINTF */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sm_dopr(): poor man's version of doprintf
|
|
||||||
*/
|
|
||||||
|
|
||||||
void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
|
|
||||||
void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad));
|
|
||||||
void dostr __P(( char * , int ));
|
|
||||||
char *output;
|
|
||||||
void dopr_outch __P(( int c ));
|
|
||||||
int SyslogErrno;
|
|
||||||
|
|
||||||
void
|
|
||||||
sm_dopr( buffer, format, args )
|
|
||||||
char *buffer;
|
|
||||||
const char *format;
|
|
||||||
va_list args;
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
long value;
|
|
||||||
int longflag = 0;
|
|
||||||
int pointflag = 0;
|
|
||||||
int maxwidth = 0;
|
|
||||||
char *strvalue;
|
|
||||||
int ljust;
|
|
||||||
int len;
|
|
||||||
int zpad;
|
|
||||||
# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
|
|
||||||
extern char *sys_errlist[];
|
|
||||||
extern int sys_nerr;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
output = buffer;
|
|
||||||
while( (ch = *format++) != '\0' ){
|
|
||||||
switch( ch ){
|
|
||||||
case '%':
|
|
||||||
ljust = len = zpad = maxwidth = 0;
|
|
||||||
longflag = pointflag = 0;
|
|
||||||
nextch:
|
|
||||||
ch = *format++;
|
|
||||||
switch( ch ){
|
|
||||||
case 0:
|
|
||||||
dostr( "**end of format**" , 0);
|
|
||||||
return;
|
|
||||||
case '-': ljust = 1; goto nextch;
|
|
||||||
case '0': /* set zero padding if len not set */
|
|
||||||
if(len==0 && !pointflag) zpad = '0';
|
|
||||||
case '1': case '2': case '3':
|
|
||||||
case '4': case '5': case '6':
|
|
||||||
case '7': case '8': case '9':
|
|
||||||
if (pointflag)
|
|
||||||
maxwidth = maxwidth*10 + ch - '0';
|
|
||||||
else
|
|
||||||
len = len*10 + ch - '0';
|
|
||||||
goto nextch;
|
|
||||||
case '*':
|
|
||||||
if (pointflag)
|
|
||||||
maxwidth = va_arg( args, int );
|
|
||||||
else
|
|
||||||
len = va_arg( args, int );
|
|
||||||
goto nextch;
|
|
||||||
case '.': pointflag = 1; goto nextch;
|
|
||||||
case 'l': longflag = 1; goto nextch;
|
|
||||||
case 'u': case 'U':
|
|
||||||
/*fmtnum(value,base,dosign,ljust,len,zpad) */
|
|
||||||
if( longflag ){
|
|
||||||
value = va_arg( args, long );
|
|
||||||
} else {
|
|
||||||
value = va_arg( args, int );
|
|
||||||
}
|
|
||||||
fmtnum( value, 10,0, ljust, len, zpad ); break;
|
|
||||||
case 'o': case 'O':
|
|
||||||
/*fmtnum(value,base,dosign,ljust,len,zpad) */
|
|
||||||
if( longflag ){
|
|
||||||
value = va_arg( args, long );
|
|
||||||
} else {
|
|
||||||
value = va_arg( args, int );
|
|
||||||
}
|
|
||||||
fmtnum( value, 8,0, ljust, len, zpad ); break;
|
|
||||||
case 'd': case 'D':
|
|
||||||
if( longflag ){
|
|
||||||
value = va_arg( args, long );
|
|
||||||
} else {
|
|
||||||
value = va_arg( args, int );
|
|
||||||
}
|
|
||||||
fmtnum( value, 10,1, ljust, len, zpad ); break;
|
|
||||||
case 'x':
|
|
||||||
if( longflag ){
|
|
||||||
value = va_arg( args, long );
|
|
||||||
} else {
|
|
||||||
value = va_arg( args, int );
|
|
||||||
}
|
|
||||||
fmtnum( value, 16,0, ljust, len, zpad ); break;
|
|
||||||
case 'X':
|
|
||||||
if( longflag ){
|
|
||||||
value = va_arg( args, long );
|
|
||||||
} else {
|
|
||||||
value = va_arg( args, int );
|
|
||||||
}
|
|
||||||
fmtnum( value,-16,0, ljust, len, zpad ); break;
|
|
||||||
case 's':
|
|
||||||
strvalue = va_arg( args, char *);
|
|
||||||
if (maxwidth > 0 || !pointflag) {
|
|
||||||
if (pointflag && len > maxwidth)
|
|
||||||
len = maxwidth; /* Adjust padding */
|
|
||||||
fmtstr( strvalue,ljust,len,zpad, maxwidth);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
ch = va_arg( args, int );
|
|
||||||
dopr_outch( ch ); break;
|
|
||||||
case 'm':
|
|
||||||
#if HASSTRERROR
|
|
||||||
dostr(strerror(SyslogErrno), 0);
|
|
||||||
#else
|
|
||||||
if (SyslogErrno < 0 || SyslogErrno >= sys_nerr)
|
|
||||||
{
|
|
||||||
dostr("Error ", 0);
|
|
||||||
fmtnum(SyslogErrno, 10, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dostr((char *)sys_errlist[SyslogErrno], 0);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '%': dopr_outch( ch ); continue;
|
|
||||||
default:
|
|
||||||
dostr( "???????" , 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dopr_outch( ch );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*output = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fmtstr( value, ljust, len, zpad, maxwidth )
|
|
||||||
char *value;
|
|
||||||
int ljust, len, zpad, maxwidth;
|
|
||||||
{
|
|
||||||
int padlen, strlen; /* amount to pad */
|
|
||||||
|
|
||||||
if( value == 0 ){
|
|
||||||
value = "<NULL>";
|
|
||||||
}
|
|
||||||
for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
|
|
||||||
if (strlen > maxwidth && maxwidth)
|
|
||||||
strlen = maxwidth;
|
|
||||||
padlen = len - strlen;
|
|
||||||
if( padlen < 0 ) padlen = 0;
|
|
||||||
if( ljust ) padlen = -padlen;
|
|
||||||
while( padlen > 0 ) {
|
|
||||||
dopr_outch( ' ' );
|
|
||||||
--padlen;
|
|
||||||
}
|
|
||||||
dostr( value, maxwidth );
|
|
||||||
while( padlen < 0 ) {
|
|
||||||
dopr_outch( ' ' );
|
|
||||||
++padlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fmtnum( value, base, dosign, ljust, len, zpad )
|
|
||||||
long value;
|
|
||||||
int base, dosign, ljust, len, zpad;
|
|
||||||
{
|
|
||||||
int signvalue = 0;
|
|
||||||
unsigned long uvalue;
|
|
||||||
char convert[20];
|
|
||||||
int place = 0;
|
|
||||||
int padlen = 0; /* amount to pad */
|
|
||||||
int caps = 0;
|
|
||||||
|
|
||||||
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
|
|
||||||
value, base, dosign, ljust, len, zpad )); */
|
|
||||||
uvalue = value;
|
|
||||||
if( dosign ){
|
|
||||||
if( value < 0 ) {
|
|
||||||
signvalue = '-';
|
|
||||||
uvalue = -value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( base < 0 ){
|
|
||||||
caps = 1;
|
|
||||||
base = -base;
|
|
||||||
}
|
|
||||||
do{
|
|
||||||
convert[place++] =
|
|
||||||
(caps? "0123456789ABCDEF":"0123456789abcdef")
|
|
||||||
[uvalue % (unsigned)base ];
|
|
||||||
uvalue = (uvalue / (unsigned)base );
|
|
||||||
}while(uvalue);
|
|
||||||
convert[place] = 0;
|
|
||||||
padlen = len - place;
|
|
||||||
if( padlen < 0 ) padlen = 0;
|
|
||||||
if( ljust ) padlen = -padlen;
|
|
||||||
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
|
|
||||||
convert,place,signvalue,padlen)); */
|
|
||||||
if( zpad && padlen > 0 ){
|
|
||||||
if( signvalue ){
|
|
||||||
dopr_outch( signvalue );
|
|
||||||
--padlen;
|
|
||||||
signvalue = 0;
|
|
||||||
}
|
|
||||||
while( padlen > 0 ){
|
|
||||||
dopr_outch( zpad );
|
|
||||||
--padlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while( padlen > 0 ) {
|
|
||||||
dopr_outch( ' ' );
|
|
||||||
--padlen;
|
|
||||||
}
|
|
||||||
if( signvalue ) dopr_outch( signvalue );
|
|
||||||
while( place > 0 ) dopr_outch( convert[--place] );
|
|
||||||
while( padlen < 0 ){
|
|
||||||
dopr_outch( ' ' );
|
|
||||||
++padlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dostr( str , cut)
|
|
||||||
char *str;
|
|
||||||
int cut;
|
|
||||||
{
|
|
||||||
if (cut) {
|
|
||||||
while(*str && cut-- > 0) dopr_outch(*str++);
|
|
||||||
} else {
|
|
||||||
while(*str) dopr_outch(*str++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dopr_outch( c )
|
|
||||||
int c;
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if( iscntrl(c) && c != '\n' && c != '\t' ){
|
|
||||||
c = '@' + (c & 0x1F);
|
|
||||||
if( DoprEnd == 0 || output < DoprEnd )
|
|
||||||
*output++ = '^';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( DoprEnd == 0 || output < DoprEnd )
|
|
||||||
*output++ = c;
|
|
||||||
else
|
|
||||||
SnprfOverflow++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** QUAD_TO_STRING -- Convert a quad type to a string.
|
|
||||||
**
|
|
||||||
** Convert a quad type to a string. This must be done
|
|
||||||
** separately as %lld/%qd are not supported by snprint()
|
|
||||||
** and adding support would slow down systems which only
|
|
||||||
** emulate the data type.
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** value -- number to convert to a string.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** pointer to a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
quad_to_string(value)
|
|
||||||
QUAD_T value;
|
|
||||||
{
|
|
||||||
char *fmtstr;
|
|
||||||
static char buf[64];
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Use sprintf() instead of snprintf() since snprintf()
|
|
||||||
** does not support %qu or %llu. The buffer is large enough
|
|
||||||
** to hold the string so there is no danger of buffer
|
|
||||||
** overflow.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if NEED_PERCENTQ
|
|
||||||
fmtstr = "%qu";
|
|
||||||
#else
|
|
||||||
fmtstr = "%llu";
|
|
||||||
#endif
|
|
||||||
sprintf(buf, fmtstr, value);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** SHORTENSTRING -- return short version of a string
|
|
||||||
**
|
|
||||||
** If the string is already short, just return it. If it is too
|
|
||||||
** long, return the head and tail of the string.
|
|
||||||
**
|
|
||||||
** Parameters:
|
|
||||||
** s -- the string to shorten.
|
|
||||||
** m -- the max length of the string.
|
|
||||||
**
|
|
||||||
** Returns:
|
|
||||||
** Either s or a short version of s.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
shortenstring(s, m)
|
|
||||||
register const char *s;
|
|
||||||
int m;
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
static char buf[MAXSHORTSTR + 1];
|
|
||||||
|
|
||||||
l = strlen(s);
|
|
||||||
if (l < m)
|
|
||||||
return (char *) s;
|
|
||||||
if (m > MAXSHORTSTR)
|
|
||||||
m = MAXSHORTSTR;
|
|
||||||
else if (m < 10)
|
|
||||||
{
|
|
||||||
if (m < 5)
|
|
||||||
{
|
|
||||||
strncpy(buf, s, m);
|
|
||||||
buf[m] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
strncpy(buf, s, m - 3);
|
|
||||||
strcpy(buf + m - 3, "...");
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
m = (m - 3) / 2;
|
|
||||||
strncpy(buf, s, m);
|
|
||||||
strcpy(buf + m, "...");
|
|
||||||
strcpy(buf + m + 3, s + l - m);
|
|
||||||
return buf;
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 1995-1997 Eric P. Allman. All rights reserved.
|
|
||||||
* Copyright (c) 1988, 1993
|
|
||||||
* The Regents of the University of California. All rights reserved.
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the sendmail distribution.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @(#)useful.h 8.12 (Berkeley) 5/19/1998
|
|
||||||
*/
|
|
||||||
|
|
||||||
# include <sys/types.h>
|
|
||||||
|
|
||||||
/* support for bool type */
|
|
||||||
typedef int bool;
|
|
||||||
#ifndef TRUE
|
|
||||||
# define TRUE 1
|
|
||||||
# define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# ifndef NULL
|
|
||||||
# define NULL 0
|
|
||||||
# endif /* NULL */
|
|
||||||
|
|
||||||
/* bit hacking */
|
|
||||||
# define bitset(bit, word) (((word) & (bit)) != 0)
|
|
||||||
|
|
||||||
/* some simple functions */
|
|
||||||
# ifndef max
|
|
||||||
# define max(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
# define min(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* assertions */
|
|
||||||
# ifndef NASSERT
|
|
||||||
# define ASSERT(expr, msg, parm)\
|
|
||||||
if (!(expr))\
|
|
||||||
{\
|
|
||||||
fprintf(stderr, "assertion botch: %s:%d: ", __FILE__, __LINE__);\
|
|
||||||
fprintf(stderr, msg, parm);\
|
|
||||||
}
|
|
||||||
# else /* NASSERT */
|
|
||||||
# define ASSERT(expr, msg, parm)
|
|
||||||
# endif /* NASSERT */
|
|
||||||
|
|
||||||
/* sccs id's */
|
|
||||||
# ifndef lint
|
|
||||||
# ifdef __STDC__
|
|
||||||
# define SCCSID(arg) static char SccsId[] = #arg;
|
|
||||||
# else
|
|
||||||
# define SCCSID(arg) static char SccsId[] = "arg";
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define SCCSID(arg)
|
|
||||||
# endif
|
|
Loading…
Reference in a new issue