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 New Issue
Block a user