1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-30 08:19:09 +00:00

This commit was generated by cvs2svn to compensate for changes in r26986,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Peter Wemm 1997-06-27 14:53:01 +00:00
commit 91453f6a62
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=26987
51 changed files with 2163 additions and 532 deletions

View File

@ -6,4 +6,6 @@ If you do not have access to anonymous FTP, you can retrieve it by
sending email to mail-server@rtfm.mit.edu with the command "send
usenet/news.answers/mail/sendmail-faq" in the message.
--Eric Allman 8/17/96
An HTML version is also available at http://www.sendmail.org/faq.
--Eric Allman 14 June 1997

View File

@ -1,13 +1,13 @@
K N O W N B U G S I N S E N D M A I L
(for 8.8)
(for 8.8.6)
The following are bugs or deficiencies in sendmail that I am aware of
but which have not been fixed in the current release. You probably
want to get the most up to date version of this from FTP.CS.Berkeley.EDU
in /ucb/sendmail/KNOWNBUGS. For descriptions of bugs that have been
want to get the most up to date version of this from ftp.sendmail.org
in /pub/sendmail/KNOWNBUGS. For descriptions of bugs that have been
fixed, see the file RELEASE_NOTES (in the root directory of the sendmail
distribution).
@ -40,20 +40,6 @@ This list is not guaranteed to be complete.
this address. It's not clear what the right behaviour is in this
circumstance.
* MX records that point at non-existent hosts work strangly.
Consider the DNS records:
hostH MX 1 hostA
MX 2 hostB
hostA A 128.32.8.9
(note that there is no A record for hostB). If hostA is down,
an attempt to send to hostH gives "host unknown" -- that is, it
reflects out the status on the last host it tries, which in this
case is hostB, which is unknown. It probably ought to eliminate
hostB early in processing.
* \231 considered harmful.
Header addresses that have the \231 character (and possibly others
@ -77,6 +63,18 @@ This list is not guaranteed to be complete.
Apparently, this problem is due to linking -lc before -lsocket;
if you are having this problem, check your Makefile.
* accept() problem on Linux.
Apparently, the accept() in sendmail daemon loop can return ETIMEDOUT
and cause sendmail to sleep for 5 seconds during which time no new
connections will be accepted. An error is reported to syslog:
Jun 9 17:14:12 hostname sendmail[207]: NOQUEUE: SYSERR(root):
getrequests: accept: Connection timed out
"Connection timed out" is not documented as a valid return from
accept(2) and this is believed to be a bug in the Linux kernel.
* Excessive mailing list nesting can run out of file descriptors.
If you have a mailing list that includes lots of other mailing
@ -106,4 +104,4 @@ This list is not guaranteed to be complete.
allow for 8->7 bit MIME conversions either.
(Version 8.23, last updated 10/15/96)
(Version 8.25, last updated 6/13/97)

View File

@ -1,5 +1,5 @@
/*-
* @(#)READ_ME 8.29 (Berkeley) 9/24/96
* @(#)READ_ME 8.30 (Berkeley) 5/8/97
*/
SENDMAIL RELEASE 8
@ -165,9 +165,9 @@ IF YOU WANT TO RUN THE NEW BERKELEY DB SOFTWARE: **** DO NOT ****
use the version that was on the Net2 tape -- it has a number of
nefarious bugs that were bad enough when I got them; you shouldn't have
to go through the same thing. Instead, get a new version via public
FTP from ftp.CS.Berkeley.EDU, file ucb/4bsd/db.tar.Z. This software
is highly recommended; it gets rid of several stupid limits, it's much
faster, and the interface is nicer to animals and plants. You will
FTP from ftp.sleepycat.com, file db/packages/db.1.85.tar.gz. This
software is highly recommended; it gets rid of several stupid limits, it's
much faster, and the interface is nicer to animals and plants. You will
also probably find that you have to add -I/where/you/put/db/include
to the sendmail makefile to get db.h to work properly.

View File

@ -1,11 +1,315 @@
SENDMAIL RELEASE NOTES
@(#)RELEASE_NOTES 8.8.5.3 (Berkeley) 1/21/97
@(#)RELEASE_NOTES 8.8.6.11 (Berkeley) 6/14/97
This listing shows the version of the sendmail binary, the version
of the sendmail configuration files, the date of release, and a
summary of the changes in that release.
8.8.6/8.8.6 97/06/14
*************************************************************
* The extensive assistance of Gregory Neil Shapiro of WPI *
* in preparing this release is gratefully appreciated. *
* Sun Microsystems has also provided resources toward *
* continued sendmail development. *
*************************************************************
SECURITY: A few systems allow an open with the O_EXCL|O_CREAT open
mode bits set to create a file that is a symbolic link that
points nowhere. This makes it possible to create a root
owned file in an arbitrary directory by inserting the symlink
into a writable directory after the initial lstat(2) check
determined that the file did not exist. The only verified
example of a system having these odd semantics for O_EXCL
and symbolic links was HP-UX prior to version 9.07. Most
systems do not have the problem, since a exclusive create
of a file disallows symbolic links. Systems that have been
verified to NOT have the problem include AIX 3.x, *BSD,
DEC OSF/1, HP-UX 9.07 and higher, Linux, SunOS, Solaris,
and Ultrix. This is a potential exposure on systems that
have this bug and which do not have a MAILER-DAEMON alias
pointing at a legitimate account, since this will cause old
mail to be dropped in /var/tmp/dead.letter.
SECURITY: Problems can occur on poorly managed systems, specifically,
if maps or alias files are in world writable directories.
If your system has alias maps in writable directories, it
is potentially possible for an attacker to replace the .db
(or .dir and .pag) files by symbolic links pointing at
another database; this can be used either to expose
information (e.g., by pointing an alias file at /etc/spwd.db
and probing for accounts), or as a denial-of-service attack
(by trashing the password database). The fix disallows
symbolic links entirely when rebuilding alias files or on
maps that are in writable directories, and always warns on
writable directories; 8.9 will probably consider writable
directories to be fatal errors. This does not represent an
exposure on systems that have alias files in unwritable
system directories.
SECURITY: disallow .forward or :include: files that are links (hard
or soft) if the parent directory (or any directory in the
path) is writable by anyone other than the owner. This is
similar to the previous case for user files. This change
should not affect most systems, but is necessary to prevent
an attacker who can write the directory from pointing such
files at other files that are readable only by the owner.
SECURITY: Tighten safechown rules: many systems will say that they
have a safe (restricted to root) chown even on files that
are mounted from another system that allows owners to give
away files. The new rules are very strict, trusting file
ownership only in those few cases where the system has
been verified to be at least as paranoid as necessary.
However, it is possible to relax the rules to partially
trust the ownership if the directory path is not world or
group writable. This might allow someone who has a legitimate
:include: file (referenced directly from /etc/aliases) to
become another non-root user if the :include: file is in a
non-writable directory on an NFS-mounted filesystem where
the local system says that giveaway is denied but it is
actually permitted. I believe this to be a very small set
of cases. If in doubt, do not point :include: aliases at
NFS-mounted filesystems.
SECURITY: When setting a numeric group id using the RunAsUser option
(e.g., "O RunAsUser=10:20", the group id would not be set.
Implicit group ids (e.g., "O RunAsUser=mailnull") or alpha
group ids (e.g., "O RunAsUser=mailuser:mailgrp") worked fine.
The user id was still set properly. Problem noted by Uli
Pralle of the Technical University of Berlin.
Save the initial gid set for use when checking for if the
PrivacyOptions=restrictmailq option is set. Problem reported
by Wolfgang Ley of DFN-CERT.
Make 55x reply codes to the SMTP DATA-"." be non-sticky (i.e., a
failure on one message won't affect future messages to the
same host).
IP source route printing had an "off by one" error that would
affect any options that came after the route option. Patch
from Theo de Raadt.
The "Message is too large" error didn't successfully bounce the error
back to the sender. Problem reported by Stephen More of
PSI; patch from Gregory Neil Shapiro of WPI.
Change SMTP status code 553 to map into Extended code 5.1.0 (instead
of 5.1.3); it apparently gets used in multiple ways.
Suggested by John Myers of Portola Communications.
Fix possible extra null byte generated during collection if errors
occur at the beginning of the stream. Patch contributed by
Andrey A. Chernov and Gregory Neil Shapiro.
Code changes to avoid possible reentrant call of malloc/free within
a signal handler. Problem noted by John Beck of Sun
Microsystems.
Move map initialization to be earlier so that check_relay ruleset
will have the latest version of the map data. Problem noted
by Paul Forgey of Metainfo; patch from Gregory Neil Shapiro.
If there are fatal errors during the collection phase (e.g., message
too large) don't send the bogus message.
Avoid "cannot open xfAAA00000" messages when sending to aliases that
have errors and have owner- aliases. Problem noted by Michael
Barber of MTU; fix from Gregory Neil Shapiro of WPI.
Avoid null pointer dereference on illegal Boundary= parameters in
multipart/mixed Content-Type: header. Problem noted by
Richard Muirden of RMIT University.
Always print error messages during newaliases (-bi) even if the
ErrorMode is not set to "print". Fix from Gregory Neil
Shapiro.
Test mode could core dump if you did a /map lookup in an optional map
that could not be opened. Based on a fix from John Beck of
Sun Microsystems.
If DNS is misconfigured so that the last MX record tried points to
a host that does not have an A record, but other MX records
pointed to something reasonable, don't bounce the message
with a "host unknown" error. Note that this should really
be fixed in the zone file for the domain. Problem noted by
Joe Rhett of Navigist, Inc.
If a map fails (e.g., DNS times out) on all recipient addresses, mark
the message as having been tried; otherwise the next queue
run will not realize that this is a second attempt and will
retry immediately. Problem noted by Bryan Costales of
Mercury Mail.
If the clock is set backwards, and a MinQueueAge is set, no jobs
will be run until the later setting of the clock is reached.
"Problem" (I use the term loosely) noted by Eric Hagberg of
Morgan Stanley.
If the load average rises above the cutoff threshold (above which
sendmail will not process the queue at all) during a queue
run, abort the queue run immediately. Problem noted by
Bryan Costales of Mercury Mail.
The variable queue processing algorithm (based on the message size,
number of recipients, message precedence, and job age) was
non-functional -- either the entire queue was processed or
none of the queue was processed. The updated algorithm
does no queue run if a single recipient zero size job will
not be run.
If there is a fatal ("panic") message that will cause sendmail to
die immediately, never hold the error message for future
printing.
Force ErrorMode=print in -bt mode so that all errors are printed
regardless of the setting of the ErrorMode option in the
configuration file. Patch from Gregory Neil Shapiro.
New compile flag HASSTRERROR says that this OS has the strerror(3)
routine available in one of the libraries. Use it in conf.h.
The -m (match only) flag now works on host class maps.
If class hash or btree maps are rebuilt, sendmail will now detect
this and reopen the map. Previously, they could give
erroneous results during a single message processing
(but would recover when the next message was received).
Don't delete zero length queue files when doing queue runs until the
files are at least ten minutes old. This avoids a potential
race condition: the creator creates the qf file, getting back
a file descriptor. The queue runner locks it and deletes it
because it is zero length. The creator then writes the
descriptor that is now for a disconnected file, and the
job goes away. Based on a suggestion by Bryan Costales.
When determining the "validated" host name ($_ macro), do a forward
(A) DNS lookup on the result of the PTR lookup and compare
results. If they differ or if the PTR lookup fails, tag the
address as "may be forged".
Log null connections (i.e., hosts that connect but do not do any
substantive activity on the connection before disconnecting;
"substantive" is defined to be MAIL, EXPN, VRFY, or ETRN.
Always permit "writes" to /dev/null regardless of the link count.
This is safe because /dev/null is special cased, and no open
or write is ever actually attempted. Patch from Villy Kruse
of TwinCom.
If a message cannot be sent because of a 552 (exceeded storage
allocation) response to the MAIL FROM:<>, and a SIZE= parameter
was given, don't return the body in the bounce, since there
is a very good chance that the message will double-bounce.
Fix possible line truncation if a quoted-printable had an =00 escape
in the body. Problem noted by Charles Karney of the Princeton
Plasma Physics Laboratory.
Notify flags (e.g., -NSUCCESS) were lost on user+detail addresses.
Problem noted by Kari Hurtta of the Finnish Meteorological
Institute.
The MaxDaemonChildren option wasn't applying to queue runs as
documented. Note that this increases the potential denial
of service problems with this option: an attacker can
connect many times, and thereby lock out queue runs as well
as incoming connections. If you use this option, you should
run the "sendmail -bd" and "sendmail -q30m" jobs separately
to avoid this attack. Failure to limit noted by Matthew
Dillon of BEST Internet Communications.
Always give a message in newaliases if alias files cannot be
opened instead of failing silently. Suggested by Gregory
Neil Shapiro. This change makes the code match the O'Reilly
book (2nd edition).
Some older versions of the resolver could return with h_errno == -1
if no name server could be reached, causing mail to bounce
instead of queueing. Treat this like TRY_AGAIN. Fix from
John Beck of SunSoft.
If a :include: file is owned by a user that does not have an entry
in the passwd file, sendmail could dereference a null pointer.
Problem noted by Satish Mynam of Sun Microsystems.
Take precautions to make sure that the SMTP protocol cannot get out
of sync if (for example) an alias file cannot be opened.
Fix a possible race condition that can cause a SIGALRM to come in
immediately after a SIGHUP, causing the new sendmail to die.
Avoid possible hang on SVr3 systems when doing child reaping. Patch
from Villy Kruse of TwinCom.
Ignore improperly formatted SMTP reply codes. Previously these were
partially processed, which could cause confusing error
returns.
Fix possible bogus pointer dereference when doing ldapx map lookups
on some architectures.
Portability:
A/UX: from Jim Jagielski of NASA/GSFC.
glibc: SOCK_STREAM was changed from a #define to an enum,
thus breaking #ifdef SOCK_STREAM. Only option seems
to be to assume SOCK_STREAM if __GNU_LIBRARY__ is
defined. Problem reported by A Sun of the University
of Washington.
Solaris: use SIOCGIFNUM to get the number of interfaces on
the system rather than guessing at compile time.
Patch contributed by John Beck of Sun Microsystems.
Intel Paragon: from Wendy Lin of Purdue University.
GNU Hurd: from Miles Bader of the GNU project.
RISC/os 4.50 from Harlan Stenn of PFCS Corporation.
ISC Unix: wait never returns if SIGCLD signals are blocked.
Unfortunately releasing them opens a race condition,
but there appears to be no fix for this. Patch from
Gregory Neil Shapiro.
BIND 8.1 for IPv6 compatibility from John Kennedy.
Solaris: a bug in strcasecmp caused characters with the
high order bit set to apparently randomly match
letters -- for example, $| (0233) matches "i" and "I".
Problem noted by John Gregson of the University of
Cambridge.
IRIX 6.x: make Makefile.IRIX.6.2 apply to all 6.x. From
Kari Hurtta.
IRIX 6.x: Create Makefiles for systems that claim to be
IRIX64 but are 6.2 or higher (so use the regular
IRIX Makefile).
IRIX 6.x: Fix load average computation on 64 bit kernels.
Problem noted by Eric Hagberg of Morgan Stanley.
CONFIG: Some canonification was still done for UUCP-like addresses
even if FEATURE(nocanonify) was set. Problem pointed out by
Brian Candler.
CONFIG: In some cases UUCP mailers wouldn't properly recognize all
local names as local. Problem noted by Jeff Polk of BSDI;
fix provided by Gregory Neil Shapiro.
CONFIG: The "local:user" syntax entries in mailertables and other
"mailer:user" syntax locations returned an incorrect value
for the $h macro. Problem noted by Gregory Neil Shapiro.
CONFIG: Retain "+detail" information when forwarding mail to a
MAIL_HUB, LUSER_RELAY, or LOCAL_RELAY. Patch from Philip
Guenther of Gustavus Adolphus College.
CONFIG: Make sure user+detail works for FEATURE(virtusertable);
rules are the same as for aliasing. Based on a patch from
Gregory Neil Shapiro.
CONFIG: Break up parsing rules into several pieces; this should
have no functional change in this release, but makes it
possible to have better anti-spam rulesets in the future.
CONFIG: Disallow double dots in host names to avoid having the
HostStatusDirectory store status under the wrong name.
In some cases this can be used as a denial-of-service attack.
Problem noted by Ron Jarrell of Virginia Tech, patch from
Gregory Neil Shapiro.
CONFIG: Don't use F=m (multiple recipients per invocation) for
MAILER(procmail), but do pass F=Pn9 (include Return-Path:,
don't include From_, and convert to 8-bit). Suggestions
from Kimmo Suominen and Roderick Schertler.
CONFIG: Domains under $=M (specified with MASQUERADE_DOMAIN) where
being masqueraded as though FEATURE(masquerade_entire_domain)
was specified, even when it wasn't.
MAIL.LOCAL: Solaris 2.6 has snprintf. From John Beck of SunSoft.
MAIL.LOCAL: SECURITY: check to make sure that an attacker doesn't
"slip in" a symbolic link between the lstat(2) call and the
exclusive open. This is only a problem on System V derived
systems that allow an exclusive create on files that are
symbolic links pointing nowhere.
MAIL.LOCAL: If the final mailbox close() failed, the user id was
not reset back to root, which on some systems would cause
later mailboxes to fail. Also, any partial message would
not be truncated, which could result in repeated deliveries.
Problem noted by Bruce Evans via Peter Wemm (FreeBSD
developers).
MAKEMAP: Handle cases where O_EXLOCK is #defined to be 0. A similar
change to the sendmail map code was made in 8.8.3. Problem
noted by Gregory Neil Shapiro.
MAKEMAP: Give warnings on file problems such as map files that are
symbolic links; although makemap is not setuid root, it is
often run as root and hence has the potential for the same
sorts of problems as alias rebuilds.
MAKEMAP: Change compilation so that it will link properly on
NEXTSTEP.
CONTRIB: etrn.pl: search for Cw as well as Fw lines in sendmail.cf.
Accept an optional list of arguments following the server
name for the ETRN arguments to use (instead of $=w). Other
miscellaneous bug fixes. From Christian von Roques via
John Beck of Sun Microsystems.
CONTRIB: Add passwd-to-alias.pl, contributed by Kari Hurtta. This
Perl script converts GECOS information in the /etc/passwd
file into aliases, allowing for faster access to full name
lookups; it is also clever about adding aliases (to root)
for system accounts.
NEW FILES:
src/safefile.c
cf/ostype/gnuhurd.m4
cf/ostype/irix6.m4
contrib/passwd-to-alias.pl
test/t_exclopen.c
src/Makefiles/Makefile.IRIX64.6.1
src/Makefiles/Makefile.IRIX64.6.x
RENAMED FILES:
src/Makefiles/Makefile.IRIX.6.2 => Makefile.IRIX.6.x
src/Makefiles/Makefile.IRIX64 => Makefile.IRIX64.6.0
8.8.5/8.8.5 97/01/21
SECURITY: Clear out group list during startup. Without this, sendmail
will continue to run with the group permissions of the caller,
@ -101,8 +405,7 @@ summary of the changes in that release.
Give better diagnostics on long alias lines. Based on code contributed
by Patrick Gosling of the University of Cambridge.
Increase the number of virtual interfaces that will be probed for
alternate names. Problem noted by Gregory Neil Shapiro of
WPI.
alternate names. Problem noted by Amy Rich of Shore.Net.
PORTABILITY:
UXP/DS V20L10 for Fujitsu DS/90: Makefile patches from
Toshiaki Nomura of Fujitsu Limited.
@ -138,8 +441,7 @@ summary of the changes in that release.
to the named user on the local machine. ``local:user@host''
is equivalent to ``local:user'' (the host is ignored). In
all cases, the original user@host is passed in $@ (i.e., the
detail information). Inspired by a report from Michael Fuhr
of Dimensional Communications, L.L.C.
detail information). Inspired by a report from Michael Fuhr.
CONFIG: Strip quotes from the first word of an "error:" host
indication. This lets you set (for example) the LUSER_RELAY
to be ``error:\"5.1.1\" Your Message Here''. Note the use
@ -837,8 +1139,7 @@ summary of the changes in that release.
Add new RunAsUser option; this causes sendmail to do a setuid to that
user early in processing to avoid potential security problems.
However, this means that all .forward and :include: files must
be readable by that user, and on systems that don't support the
saved uid bit properly, all files to be written must be
be readable by that user, and all files to be written must be
writable by that user and all programs will be executed by that
user. It is also incompatible with the SafeFileEnvironment
option. In other words, it may not actually add much to
@ -1407,7 +1708,7 @@ summary of the changes in that release.
``/mx host'' returns the MX records for ``host''.
``/parse address'' will parse address, returning the value of
crackaddr (essentially, the comment information)
and the parsed address (the same as -bv).
and the parsed address.
``/try mailer address'' will rewrite address into the form
it will have when presented to the indicated mailer.
``/tryflags flags'' will set flags used by parsing. The

View File

@ -4,7 +4,7 @@
Eric Allman <eric@CS.Berkeley.EDU>
@(#)README 8.111 (Berkeley) 1/16/97
@(#)README 8.120 (Berkeley) 6/14/97
This document describes the sendmail configuration files being used
@ -34,7 +34,8 @@ SunOS's /usr/5bin/m4 or BSD-Net/2's m4 both work. GNU m4 version 1.1
or later also works. Unfortunately, I'm told that the M4 on BSDI 1.0
doesn't work -- you'll have to use a Net/2 or GNU version. GNU m4 is
available from ftp://prep.ai.mit.edu/pub/gnu/m4-1.4.tar.gz (check for
the latest version).
the latest version). EXCEPTIONS: DEC's m4 on Digital UNIX 4.x is broken
(3.x is fine). Use GNU m4 on this platform.
IF YOU DON'T HAVE A BERKELEY MAKE, don't despair! Just run
"m4 ../m4/cf.m4 foo.mc > foo.cf" -- that should be all you need.
@ -120,7 +121,7 @@ Let's examine a typical .mc file:
#
# This is a Berkeley-specific configuration file for HP-UX 9.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -306,11 +307,11 @@ POP_MAILER_FLAGS [Penu] Flags added to POP mailer. Flags "lsDFM"
POP_MAILER_ARGS [pop $u] The arguments passed to the POP mailer.
PROCMAIL_MAILER_PATH [/usr/local/bin/procmail] The path to the procmail
program. This is also used by FEATURE(local_procmail).
PROCMAIL_MAILER_FLAGS [Shu] Flags added to Procmail mailer. Flags
``DFMmn'' are always set. This is NOT used by
PROCMAIL_MAILER_FLAGS [SPhnu9] Flags added to Procmail mailer. Flags
``DFM'' are always set. This is NOT used by
FEATURE(local_procmail); tweak LOCAL_MAILER_FLAGS
instead.
PROCMAIL_MAILER_ARGS [procmail -m $h $f $u] The arguments passed to
PROCMAIL_MAILER_ARGS [procmail -Y -m $h $f $u] The arguments passed to
the Procmail mailer. This is NOT used by
FEATURE(local_procmail); tweak LOCAL_MAILER_ARGS
instead.
@ -656,7 +657,10 @@ genericstable This feature will cause certain addresses originating in the
The key for this table is either the full address or the
unqualified username (the former is tried first); the
value is the new user address. If the new user address does
not include a domain, $j is used.
not include a domain, $j is used. Note that the address must
being looked up must be fully qualified. For local mail, it
is necessary to use FEATURE(always_add_domain) for the
addresses to be qualified.
virtusertable A domain-specific form of aliasing, allowing multiple
virtual domains to be hosted on one machine. For example,
@ -669,18 +673,28 @@ virtusertable A domain-specific form of aliasing, allowing multiple
then mail addressed to info@foo.com will be sent to the
address foo-info, mail addressed to info@bar.com will be
delivered to bar-info, and mail addressed to anyone at
baz.org will be sent to jane@elsewhere.net. All the host
names on the left hand side (foo.com, bar.com, and baz.org)
must be in $=w. The default map definition is:
baz.org will be sent to jane@elsewhere.net. The username
from the original address is passed as %1 allowing:
@foo.org %1@elsewhere.com
meaning someone@foo.org will be sent to someone@elsewhere.com.
All the host names on the left hand side (foo.com, bar.com,
and baz.org) must be in $=w. The default map definition is:
hash -o /etc/virtusertable
A new definition can be specified as the second argument of
the FEATURE macro.
the FEATURE macro, such as
FEATURE(virtusertable, dbm -o /etc/mail/virtusers)
nodns We aren't running DNS at our site (for example,
we are UUCP-only connected). It's hard to consider
this a "feature", but hey, it had to go somewhere.
Actually, as of 8.7 this is a no-op -- remove "dns" from
the hosts service switch entry instead.
nullclient This is a special case -- it creates a stripped down
configuration file containing nothing but support for
@ -1062,6 +1076,23 @@ specified with a terminal dot:
note the trailing dot ---^
+--------------------------------+
| ADDING NEW MAILERS OR RULESETS |
+--------------------------------+
Sometimes you may need to add entirely new mailers or rulesets. They
should be introduced with the constructs MAILER_DEFINITIONS and
LOCAL_RULESETS respectively. For example:
MAILER_DEFINITIONS
Mmymailer, ...
...
LOCAL_RULESETS
Scheck_relay
...
+-------------------------------+
| NON-SMTP BASED CONFIGURATIONS |
+-------------------------------+
@ -1102,10 +1133,6 @@ use:
That is, send directly only to things you found in your DNS lookup;
anything else goes through SMART_HOST.
If you are not running DNS at all, it is important to use
FEATURE(nodns) to avoid having sendmail queue everything waiting
for the name server to come up.
+-----------+
| WHO AM I? |
@ -1522,11 +1549,19 @@ confHOST_STATUS_DIRECTORY HostStatusDirectory
named directory tree. This need not be
a full pathname, in which case it is
interpreted relative to the queue
directory. This option also
single-threads connections to each
host, i.e., prevents multiple
connections to a single server from
this client.
directory.
confSINGLE_THREAD_DELIVERY SingleThreadDelivery
[False] If this option and the
HostStatusDirectory option are both
set, single thread deliveries to other
hosts. That is, don't allow any two
sendmails on this host to connect
simultaneously to any other single
host. This can slow down delivery in
some cases, in particular since a
cached but otherwise idle connection
to a host will prevent other sendmails
from connecting to the other host.
confUSE_ERRORS_TO* UserErrorsTo [False] Use the Errors-To: header to
deliver error messages. This should
not be necessary because of general
@ -1669,7 +1704,7 @@ confSEPARATE_PROC ForkEachJob [False] Run all deliveries in a separate
confWORK_CLASS_FACTOR ClassFactor [1800] Priority multiplier for class.
confWORK_TIME_FACTOR RetryFactor [90000] Cost of each delivery attempt.
confQUEUE_SORT_ORDER QueueSortOrder [Priority] Queue sort algorithm:
Priority or Host.
Priority, Host, or Time.
confMIN_QUEUE_AGE MinQueueAge [0] The minimum amount of time a job
must sit in the queue between queue
runs. This allows you to set the
@ -1782,18 +1817,6 @@ confRUN_AS_USER RunAsUser [undefined] If set, become this user
files will be written as this user.
Intended for use only on firewalls
where users do not have accounts.
confSINGLE_THREAD_DELIVERY SingleThreadDelivery
[False] If this option and the
HostStatusDirectory option are both
set, single thread deliveries to other
hosts. That is, don't allow any two
sendmails on this host to connect
simultaneously to any other single
host. This can slow down delivery in
some cases, in particular since a
cached but otherwise idle connection
to a host will prevent other sendmails
from connecting to the other host.
See also the description of OSTYPE for some parameters that can be
tweaked (generally pathnames to mailers).
@ -1935,7 +1958,7 @@ CLASSES
O operators that indicate network operations (cannot be in local names)
P top level pseudo-domains: BITNET, DECNET, FAX, UUCP, etc.
Q
R
R domains we are willing to relay (pass anti-spam filters)
S
T
U locally connected UUCP hosts

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for HP-UX 9.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-hpux10.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-hpux10.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(hpux10)dnl
DOMAIN(CS.Berkeley.EDU)dnl
define(`MAIL_HUB', mailspool.CS.Berkeley.EDU)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for HP-UX 9.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-hpux9.mc 8.5 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-hpux9.mc 8.6 (Berkeley) 6/3/97')
OSTYPE(hpux9)dnl
DOMAIN(CS.Berkeley.EDU)dnl
define(`MAIL_HUB', mailspool.CS.Berkeley.EDU)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for OSF/1.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-osf1.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-osf1.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(osf1)dnl
DOMAIN(CS.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for Solaris 2.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-solaris2.mc 8.3 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-solaris2.mc 8.4 (Berkeley) 6/3/97')
OSTYPE(solaris2)dnl
DOMAIN(CS.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for SunOS 4.1.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-sunos4.1.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-sunos4.1.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(sunos4.1)dnl
DOMAIN(CS.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for Ultrix 4.x.
# It applies only the the Computer Science Division at Berkeley,
# It applies only to the Computer Science Division at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)cs-ultrix4.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)cs-ultrix4.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(ultrix4)dnl
DOMAIN(CS.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for OSF/1.
# It applies only the the Sequoia 2000 Project at Berkeley,
# It applies only to the Sequoia 2000 Project at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)s2k-osf1.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)s2k-osf1.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(osf1)dnl
DOMAIN(S2K.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -35,7 +35,7 @@ divert(-1)
#
# This is a Berkeley-specific configuration file for Ultrix 4.x.
# It applies only the the Sequoia 2000 Project at Berkeley,
# It applies only to the Sequoia 2000 Project at Berkeley,
# and should not be used elsewhere. It is provided on the sendmail
# distribution as a sample only. To create your own configuration
# file, create an appropriate domain file in ../domain, change the
@ -44,7 +44,7 @@ divert(-1)
#
divert(0)dnl
VERSIONID(`@(#)s2k-ultrix4.mc 8.4 (Berkeley) 3/23/96')
VERSIONID(`@(#)s2k-ultrix4.mc 8.5 (Berkeley) 6/3/97')
OSTYPE(ultrix4)dnl
DOMAIN(S2K.Berkeley.EDU)dnl
MAILER(local)dnl

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)bestmx_is_local.m4 8.4 (Berkeley) 10/23/96')
VERSIONID(`@(#)bestmx_is_local.m4 8.5 (Berkeley) 3/28/97')
divert(-1)
LOCAL_CONFIG
@ -60,7 +60,7 @@ LOCAL_NET_CONFIG
ifelse(_ARG_, `', `', `#')dnl unlimited bestmx
R$* < @ $* > $* $: $1 < @ $2 @@ $(bestmx $2 $) > $3
ifelse(_ARG_, `', `#', `')dnl limit bestmx to $=B
R$* < @ $* $=B > $* $: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4
R$* < @ $* $=B . > $* $: $1 < @ $2 $3 . @@ $(bestmx $2 $3 . $) > $4
R$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3
R$* < @ $* @@ $=w . > $* $#local $: $1
R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)nullrelay.m4 8.12 (Berkeley) 10/12/96')
VERSIONID(`@(#)nullrelay.m4 8.13 (Berkeley) 4/30/97')
#
# This configuration applies only to relay-only hosts. They send
@ -68,7 +68,8 @@ 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 strip trailing semi
R$* < $* ; > $1 < $2 > bogus bracketed semi
# null input now results from list:; syntax
R$@ $@ :; <@>

View File

@ -34,7 +34,7 @@ divert(-1)
#
divert(0)
VERSIONID(`@(#)proto.m4 8.139 (Berkeley) 12/31/96')
VERSIONID(`@(#)proto.m4 8.149 (Berkeley) 4/30/97')
MAILER(local)dnl
@ -505,7 +505,8 @@ R$* [ $* : $* ] <@> $: $1 [ $2 : $3 ] unmark IPv6 addrs
R$* : $* [ $* ] $: $1 : $2 [ $3 ] <@> remark if leading colon
R$* : $* <@> $: $2 strip colon if marked
R$* <@> $: $1 unmark
R$* ; $: $1 strip trailing semi
R$* ; $1 strip trailing semi
R$* < $* ; > $1 < $2 > bogus bracketed semi
# null input now results from list:; syntax
R$@ $@ :; <@>
@ -593,9 +594,11 @@ ifdef(`_CLASS_X_',
ifdef(`_CLASS_Y_',
`R$* < @ $=Y . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
define(`X', ifdef(`_NO_CANONIFY_', `#', `'))dnl
# try UUCP traffic as a local address
R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3
R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3')
X`'R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3
X`'R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3')
undefine(`X')dnl
')
# pass to name server to make hostname canonical
ifdef(`_NO_CANONIFY_', `#')dnl
@ -604,7 +607,9 @@ R$* < @ $* $~P > $* $: $1 < @ $[ $2 $3 $] > $4
# local host aliases and pseudo-domains are always canonical
R$* < @ $=w > $* $: $1 < @ $2 . > $3
R$* < @ $j > $* $: $1 < @ $j . > $2
R$* < @ $* $=M > $* $: $1 < @ $2 $3 . > $4
ifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
`R$* < @ $* $=M > $* $: $1 < @ $2 $3 . > $4',
`R$* < @ $=M > $* $: $1 < @ $2 . > $3')
R$* < @ $* $=P > $* $: $1 < @ $2 $3 . > $4
R$* < @ $* . . > $* $1 < @ $2 . > $3
@ -656,6 +661,11 @@ R$* $@ $>0 $1
S0
R$* $: $>Parse0 $1 initial parsing
R$* $: $>98 $1 handle local hacks
R$* $: $>Parse1 $1 final parsing
SParse0
R<@> $#_LOCAL_ $: <@> special case error msgs
R$* : $* ; <@> $#error $@ 5.1.3 $: "list:; syntax illegal for recipient addresses"
R<@ $+> $#error $@ 5.1.1 $: "user address required"
@ -664,6 +674,7 @@ R<> $* < @ [ $+ ] > $* $1 < @ [ $2 ] > $3
R<> $* <$* : $* > $* $#error $@ 5.1.1 $: "colon illegal in host name part"
R<> $* $1
R$* < @ . $* > $* $#error $@ 5.1.2 $: "invalid host name"
R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "invalid host name"
ifdef(`_MAILER_smtp_',
`# handle numeric address spec
@ -672,20 +683,22 @@ R$* < @ [ $+ ] > $* $#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3 still numeric: send',
`dnl')
# now delete the local info -- note $=O to find characters that cause forwarding
R$* < @ > $* $@ $>97 $1 user@ => user
R< @ $=w . > : $* $@ $>97 $2 @here:... -> ...
R$* < @ > $* $@ $>Parse0 $>3 $1 user@ => user
R< @ $=w . > : $* $@ $>Parse0 $>3 $2 @here:... -> ...
R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
R< @ $+ > $#error $@ 5.1.1 $: "user address required"
R$* $=O $* < @ $=w . > $@ $>97 $1 $2 $3 ...@here -> ...
# handle local hacks
R$* $: $>98 $1
R$* $=O $* < @ $=w . > $@ $>Parse0 $>3 $1 $2 $3 ...@here -> ...
SParse1
# handle virtual users
define(`X', ifdef(`VIRTUSER_TABLE', `', `#'))dnl
X`'R$+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
X`'R< @ > $+ < @ $+ . > $: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
X`'R< @ > $+ $: $1
X`'R<@> $+ + $* < @ $* . >
$: < $(virtuser $1 + * @ $3 $@ $1 $: @ $) > $1 + $2 < @ $3 . >
X`'R<@> $+ + $* < @ $* . >
$: < $(virtuser $1 @ $3 $@ $1 $: @ $) > $1 + $2 < @ $3 . >
X`'R<@> $+ < @ $+ . > $: < $(virtuser @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
X`'R<@> $+ $: $1
X`'R< error : $- $+ > $* $#error $@ $( dequote $1 $) $: $2
X`'R< $+ > $+ < @ $+ > $: $>97 $1
undefine(`X')dnl
@ -779,26 +792,26 @@ S5
# deal with plussed users so aliases work nicely
R$+ + * $#_LOCAL_ $@ $&h $: $1
R$+ + $* $#_LOCAL_ $@ $2 $: $1 + *
R$+ + $* $#_LOCAL_ $@ + $2 $: $1 + *
# prepend an empty "forward host" on the front
R$+ $: <> $1
define(`X', ifdef(`LUSER_RELAY', `', `#'))dnl
# send unrecognized local users to a relay host
X`'R< > $+ + $* $: < $L . > $( user $1 $) + $2
X`'R< > $+ $: < $L . > $( user $1 $) look up user
X`'R< $* > $+ <> $* $: < > $2 $3 found; strip $L
X`'R< $* . > $+ $: < $1 > $2 strip extra dot
undefine(`X')dnl
# handle plussed local names
R< > $+ + $* $#_LOCAL_ $@ $2 $: $1
# see if we have a relay or a hub
R< > $+ $: < $H > $1 try hub
R< > $+ $: < $R > $1 try relay
R< > $+ $@ $1 nope, give up
R< > $+ $: < > < $1 $(dequote "" $&h $) > nope, restore +detail
R< > < $+ + $* > $* < > < $1 > + $2 $3 find the user part
R< > < $+ > + $* $#_LOCAL_ $@ $2 $: @ $1 strip the extra +
R< > < $+ > $@ $1 no +detail
R$+ $: $1 $(dequote "" $&h $) add +detail back in
R< local : $* > $* $: $>95 < local : $1 > $2 no host extension
R< error : $* > $* $: $>95 < error : $1 > $2 no host extension
R< $- : $+ > $+ $: $>95 < $1 : $2 > $3 < @ $2 >
@ -840,15 +853,15 @@ SCanonLocal
R< $* > $* < @ $* . > $: < $1 > $2 < @ $3 >
# handle local: syntax -- use old user, either with or without host
R< > $* < @ $* > $* $#local $@ $1@$2 $: $1
R< > $+ $#local $@ $1 $: $1
R< > $* < @ $* > $* $#_LOCAL_ $@ $1@$2 $: $1
R< > $+ $#_LOCAL_ $@ $1 $: $1
# handle local:user@host syntax -- ignore host part
R< $+ @ $+ > $* $: < $1 > $3
R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 >
# handle local:user syntax
R< $+ > $* <@ $* > $* $#local $@ $2@$3 $: $1
R< $+ > $* $#local $@ $2 $: $1
R< $+ > $* <@ $* > $* $#_LOCAL_ $@ $2@$3 $: $1
R< $+ > $* $#_LOCAL_ $@ $2 $: $1
###################################################################
### Ruleset 93 -- convert header names to masqueraded form ###

View File

@ -32,8 +32,8 @@ divert(-1)
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
VERSIONID(`@(#)version.m4 8.8.5.3 (Berkeley) 1/21/97')
VERSIONID(`@(#)version.m4 8.8.6.1 (Berkeley) 6/14/97')
#
divert(0)
# Configuration version number
DZ8.8.5`'ifdef(`confCF_VERSION', `/confCF_VERSION')
DZ8.8.6`'ifdef(`confCF_VERSION', `/confCF_VERSION')

View File

@ -15,12 +15,13 @@ ifdef(`MAIL11_MAILER_PATH',, `define(`MAIL11_MAILER_PATH', /usr/etc/mail11)')
ifdef(`MAIL11_MAILER_FLAGS',, `define(`MAIL11_MAILER_FLAGS', nsFx)')
ifdef(`MAIL11_MAILER_ARGS',, `define(`MAIL11_MAILER_ARGS', mail11 $g $x $h $u)')
define(`_USE_DECNET_SYNTAX_')
define(`_LOCAL_', ifdef(`confLOCAL_MAILER', confLOCAL_MAILER, `local'))
POPDIVERT
PUSHDIVERT(3)
# DECNET delivery
R$* < @ $=w .DECNET. > $#local $: $1 local DECnet
R$* < @ $=w .DECNET. > $#_LOCAL_ $: $1 local DECnet
R$+ < @ $+ .DECNET. > $#mail11 $@ $2 $: $1 DECnet user
POPDIVERT
@ -32,7 +33,7 @@ POPDIVERT
### UTK-MAIL11 Mailer specification ###
###########################################
VERSIONID(`@(#)mail11.m4 8.1 (Berkeley) 5/23/95')
VERSIONID(`@(#)mail11.m4 8.4 (Berkeley) 3/18/97')
Mmail11, P=MAIL11_MAILER_PATH, F=MAIL11_MAILER_FLAGS, S=15, R=25,
A=MAIL11_MAILER_ARGS

View File

@ -38,9 +38,9 @@ ifdef(`PROCMAIL_MAILER_PATH',,
`define(`PROCMAIL_MAILER_PATH', PROCMAIL_PATH)',
`define(`PROCMAIL_MAILER_PATH', /usr/local/bin/procmail)')')
ifdef(`PROCMAIL_MAILER_FLAGS',,
`define(`PROCMAIL_MAILER_FLAGS', `Shu')')
`define(`PROCMAIL_MAILER_FLAGS', `SPhnu9')')
ifdef(`PROCMAIL_MAILER_ARGS',,
`define(`PROCMAIL_MAILER_ARGS', `procmail -m $h $f $u')')
`define(`PROCMAIL_MAILER_ARGS', `procmail -Y -m $h $f $u')')
POPDIVERT
@ -48,7 +48,7 @@ POPDIVERT
### PROCMAIL Mailer specification ###
##################*****##################
VERSIONID(`@(#)procmail.m4 8.5 (Berkeley) 12/28/95')
VERSIONID(`@(#)procmail.m4 8.6 (Berkeley) 4/30/97')
Mprocmail, P=PROCMAIL_MAILER_PATH, F=CONCAT(`DFMm', PROCMAIL_MAILER_FLAGS), S=11/31, R=21/31, T=DNS/RFC822/X-Unix,
Mprocmail, P=PROCMAIL_MAILER_PATH, F=CONCAT(`DFM', PROCMAIL_MAILER_FLAGS), S=11/31, R=21/31, T=DNS/RFC822/X-Unix,
ifdef(`PROCMAIL_MAILER_MAX', `M=PROCMAIL_MAILER_MAX, ')A=PROCMAIL_MAILER_ARGS

View File

@ -44,7 +44,7 @@ POPDIVERT
### UUCP Mailer specification ###
#####################################
VERSIONID(`@(#)uucp.m4 8.24 (Berkeley) 9/5/95')
VERSIONID(`@(#)uucp.m4 8.25 (Berkeley) 3/16/97')
#
# There are innumerable variations on the UUCP mailer. It really
@ -110,7 +110,7 @@ S22
R:; <@> $@
R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots
R$* < @ $j > $1 strip local name
R$* < @ $=w > $1 strip local name
R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
R<@ $+ > : $+ $1 ! $2 convert to UUCP format
R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format
@ -125,7 +125,7 @@ S42
R:; <@> $@
R$* < @ $* . > $* $1 < @ $2 > $3 strip trailing dots
R$* < @ $j > $1 strip local name
R$* < @ $=w > $1 strip local name
R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
R<@ $+ > : $+ $1 ! $2 convert to UUCP format
R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format

View File

@ -0,0 +1,41 @@
divert(-1)
#
# Copyright (c) 1983 Eric P. Allman
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# 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.
#
#
divert(0)
VERSIONID(`@(#)gnuhurd.m4 8.1 (Berkeley) 3/8/97')
ifdef(`HELP_FILE',, `define(`HELP_FILE', /share/misc/sendmail.hf)')dnl
ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /var/log/sendmail.st)')dnl
ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /libexec/mail.local)')dnl

View File

@ -0,0 +1,61 @@
divert(-1)
#
# Copyright (c) 1995 Eric P. Allman
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# Contributed by Kari E. Hurtta <Kari.Hurtta@dionysos.fmi.fi>
#
# 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.
#
#
# Notes:
# - SGI's /etc/sendmail.cf defines also 'u' for local mailer flags -- you
# perhaps don't want it.
# - Perhaps is should also add define(`LOCAL_MAILER_CHARSET', iso-8859-1)
# put some Asian sites may prefer otherwise -- or perhaps not.
# - SGI's /etc/sendmail.cf seems use: A=mail -s -d $u
# It seems work without that -s however.
# - SGI's /etc/sendmail.cf set's default uid and gid to 998 (guest)
# - In SGI seems that TZ variable is needed that correct time is marked to
# syslog
# - helpfile is in /etc/sendmail.hf in SGI's /etc/sendmail.cf
#
divert(0)
VERSIONID(`@(#)irix6.m4 8.1 (Berkeley) 4/11/97')
ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', Ehmu9)')dnl
ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -s -d $u')')dnl
ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /var/spool/mqueue)')dnl
define(`ALIAS_FILE', /etc/aliases)dnl
ifdef(`STATUS_FILE',, `define(`STATUS_FILE', /var/sendmail.st)')dnl
ifdef(`HELP_FILE',, `define(`HELP_FILE', /etc/sendmail.hf)')dnl
define(`confDEF_USER_ID', `998:998')dnl
define(`confTIME_ZONE', USE_TZ)dnl

View File

@ -7,7 +7,8 @@
#
# hardcoded constants, should work fine for BSD-based systems
require 'sys/socket.ph';
use Socket;
use Getopt::Std;
$sockaddr = 'S n a4 x8';
# system requirements:
@ -61,53 +62,56 @@ chop($name = `hostname || uname -n`);
$0 = "$av0 - lookup host FQDN and IP addr";
($hostname,$aliases,$type,$len,$thisaddr) = gethostbyname($name);
push(@hosts,$hostname);
$0 = "$av0 - parsing sendmail.cf";
open(CF, "</etc/sendmail.cf") || die "open /etc/sendmail.cf: $!";
while (<CF>){
if (/^Fw.*$/){ # look for a line starting with "Fw"
$cwfile = $_;
chop($cwfile);
$optional = /^Fw-o/;
$cwfile =~ s,^Fw[^/]*,,; # extract the file name
}
}
close(CF);
$0 = "$av0 - reading $cwfile";
if (open(CW, "<$cwfile")){
while (<CW>){
$thishost = $_;
chop($thishost);
push(@hosts, $thishost) unless $thishost =~ $hostname;
}
close(CW);
} else {
die "open $cwfile: $!" unless optional;
}
$0 = "$av0 - parsing args";
$usage = "Usage: $av0 [-wd] host";
for $a (@ARGV) {
die $usage if $a eq "-";
while ($a =~ s/^(-.*)([wd])/$1/) {
eval '$'."flag_$2 += 1";
}
next if $a eq "-";
die $usage if $a =~ /^-/;
$server = $a;
}
$watch = $flag_w;
$debug = $flag_d;
$usage = "Usage: $av0 [-wd] host [args]";
getopts('dw');
$watch = $opt_w;
$debug = $opt_d;
$server = shift(@ARGV);
@hosts = @ARGV;
die $usage unless $server;
if (!@hosts) {
push(@hosts,$hostname);
$0 = "$av0 - parsing sendmail.cf";
open(CF, "</etc/sendmail.cf") || die "open /etc/sendmail.cf: $!";
while (<CF>){
if (/^Fw.*$/){ # look for a line starting with "Fw"
$cwfile = $_;
chop($cwfile);
$optional = /^Fw-o/;
$cwfile =~ s,^Fw[^/]*,,; # extract the file name
}
if (/^Cw(.*)$/){ # look for a line starting with "Cw"
@cws = split (' ', $1);
while (@cws) {
$thishost = shift(@cws);
push(@hosts, $thishost) unless $thishost =~ "$hostname|localhost";
}
}
}
close(CF);
if ($cwfile){
$0 = "$av0 - reading $cwfile";
if (open(CW, "<$cwfile")){
while (<CW>){
$thishost = $_;
chop($thishost);
push(@hosts, $thishost) unless $thishost =~ $hostname;
}
close(CW);
} else {
die "open $cwfile: $!" unless $optional;
}
}
}
$0 = "$av0 - building local socket";
($name,$aliases,$proto) = getprotobyname('tcp');
($name,$aliases,$port) = getservbyname($port,'tcp')
unless $port =~ /^\d+/;
$this = pack($sockaddr, &AF_INET, 0, $thisaddr);
# look it up
$0 = "$av0 - gethostbyname($server)";
@ -119,9 +123,6 @@ $0 = "$av0 - socket to $server";
$that = pack($sockaddr, &AF_INET, $port, $thataddr);
socket(S, &AF_INET, &SOCK_STREAM, $proto)
|| die "socket: $!";
$0 = "$av0 - bind to $server";
bind(S, $this)
|| die "bind $hostname,0: $!";
$0 = "$av0 - connect to $server";
print "debug = $debug server = $server\n" if $debug > 8;
if (! connect(S, $that)) {
@ -170,7 +171,7 @@ while(<S>) {
alarm(0);
if ($etrn_support){
print "ETRN supported\n" if ($debug)
print "ETRN supported\n" if ($debug);
&alarm("sending etrn to $server",'');
while (@hosts) {
$server = shift(@hosts);
@ -244,7 +245,7 @@ $flag_d;
.nr % 0
.\\"'; __END__
.\" ############## END PERL/TROFF TRANSITION
.TH ETRN 1 "November 16, 1996"
.TH ETRN 1 "January 25, 1997"
.AT 3
.SH NAME
etrn \- start mail queue run
@ -253,11 +254,22 @@ etrn \- start mail queue run
.RI [ -w ]
.RI [ -d ]
.IR hostname
.RI [ args ]
.SH DESCRIPTION
.B etrn
will use the SMTP
.B etrn
command to start mail delivery from the host given on the command line.
.B etrn
usually sends an
.B etrn
for each host the local sendmail accepts e-mail for, but if
.IR args
are specified,
.B etrn
uses these as arguments for the SMTP
.B etrn
commands passed to the host given on the command line.
.SH OPTIONS
.LP
The normal mode of operation for
@ -291,6 +303,9 @@ Not all mail daemons will implement
It is assumed that you are running domain names.
.SH CREDITS
Leveraged from David Muir Sharnoff's expn.pl script.
Christian von Roques added support for
.IR args
and fixed a couple of bugs.
.SH AVAILABILITY
The latest version of
.B etrn

View File

@ -0,0 +1,28 @@
#!/bin/perl
#
# Convert GECOS information in password files to alias syntax.
#
# Contributed by Kari E. Hurtta <Kari.Hurtta@ozone.fmi.fi>
#
print "# Generated from passwd by $0\n";
while (@a = getpwent) {
($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = @a;
($fullname = $gcos) =~ s/,.*$//;
if (!-d $dir || !-x $shell) {
print "$name: root\n";
}
$fullname =~ s/\.*[ _]+\.*/./g;
if ($fullname =~ /^[a-zA-Z]+(\.[a-zA-Z]+)+$/) {
print "$fullname: $name\n";
} else {
print "# $fullname: $name\n";
}
};
endpwent;

View File

@ -30,7 +30,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)op.me 8.103 (Berkeley) 12/13/96
.\" @(#)op.me 8.104 (Berkeley) 3/10/97
.\"
.\" eqn op.me | pic | troff -me
.eh 'SMM:08-%''Sendmail Installation and Operation Guide'
@ -67,7 +67,7 @@
Eric Allman
eric@Sendmail.ORG
.sp
Version 8.103
Version 8.104
.sp
For Sendmail Version 8.8
.)l
@ -7020,17 +7020,15 @@ These are then added to the routine
.pp
The initialization function is called as
.(b
\fIxxx\fP_map_init(MAP *map, char *mapname, char *args)
\fIxxx\fP_map_init(MAP *map, char *args)
.)b
The
.i map
is an internal data structure.
The
.i mapname
is the name of the map (used for error messages).
The
.i args
is a pointer to the rest of the configuration file line;
is a pointer to the portion of the configuration file line
following the map class name;
flags and filenames can be extracted from this line.
The initialization function must return
.sm TRUE
@ -7040,16 +7038,14 @@ otherwise.
.pp
The lookup function is called as
.(b
\fIxxx\fP_map_lookup(MAP *map, char buf[], int bufsize, char **av, int *statp)
\fIxxx\fP_map_lookup(MAP *map, char buf[], char **av, int *statp)
.)b
The
.i map
defines the map internally.
The parameters
The
.i buf
and
.i bufsize
have the input key.
has the input key.
This may be (and often is) used destructively.
The
.i av
@ -8163,7 +8159,7 @@ replace it with a blank sheet for double-sided output.
.\".sz 10
.\"Eric Allman
.\".sp
.\"Version 8.103
.\"Version 8.104
.\".ce 0
.bp 3
.ce

View File

@ -1,4 +1,4 @@
# Copyright (c) 1983, 1995, 1996 Eric P. Allman
# Copyright (c) 1983, 1995-1997 Eric P. Allman
# Copyright (c) 1988 The Regents of the University of California.
# All rights reserved.
#
@ -30,7 +30,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)READ_ME 8.135 (Berkeley) 1/21/97
# @(#)READ_ME 8.142 (Berkeley) 6/3/97
#
This directory contains the source files for sendmail.
@ -149,7 +149,7 @@ The options are:
NEWDB The new Berkeley DB package. Some systems (e.g., BSD/OS and
Digital UNIX 4.0) have this package pre-installed. If your
system does not have NEWDB installed, get the latest version
from FTP.CS.Berkeley.EDU in /ucb/4bsd/db.tar.gz (or db.tar.Z).
from FTP://ftp.sleepycat.com/db/packages/db.1.85.tar.gz.
DO NOT use the version from the Net2 distribution. If you are
still running BSD/386 1.x, you will also need to define
OLD_NEWDB.
@ -273,14 +273,14 @@ HASSETREUID Define this if you have setreuid(2) ***AND*** root can
security, since sendmail doesn't have to read .forward
and :include: files as root. There are certain attacks
that may be unpreventable without this call.
USESETEUID Define this to 1 if you have seteuid(2) if you have a seteuid
system call that will allow root to set only the effective
user id to an arbitrary value ***AND*** you have saved user
ids. This is preferable to HASSETREUID if these conditions
are fulfilled. These are the semantics of the to-be-released
revision of Posix.1. The test program ../test/t_seteuid.c
will try this out on your system. If you define both
HASSETREUID and USESETEUID, the former is ignored.
USESETEUID Define this to 1 if you have a seteuid(2) system call that
will allow root to set only the effective user id to an
arbitrary value ***AND*** you have saved user ids. This is
preferable to HASSETREUID if these conditions are fulfilled.
These are the semantics of the to-be-released revision of
Posix.1. The test program ../test/t_seteuid.c will try
this out on your system. If you define both HASSETREUID
and USESETEUID, the former is ignored.
HASLSTAT Define this if you have symbolic links (and thus the
lstat(2) system call). This improves security. Unlike
most other options, this one is on by default, so you
@ -295,6 +295,9 @@ HASULIMIT Define this if you have the ulimit(2) syscall (System V
HASWAITPID Define this if you have the waitpid(2) syscall.
HASGETDTABLESIZE
Define this if you have the getdtablesize(2) syscall.
USESTRERROR Define this if you have the libc strerror function (which
should be declared in <errno.h>), and it should be used
instead of sys_errlist.
NEEDGETOPT Define this if you need a reimplementation of getopt(3).
On some systems, getopt does very odd things if called
to scan the arguments twice. This flag will ask sendmail
@ -396,7 +399,7 @@ SFS_TYPE Encodes how your kernel can locate the amount of free
<sys/vfs.h>, <sys/mount.h>, or <sys/statfs.h> respectively,
or SFS_STATVFS (6) if you have the two-argument statvfs(2)
call. The default if nothing is defined is SFS_NONE.
SFS_BAVAIL with SFS_4ARGS hou can also set SFS_BAVAIL to the field name
SFS_BAVAIL with SFS_4ARGS you can also set SFS_BAVAIL to the field name
in the statfs structure that holds the useful information;
this defaults to f_bavail.
SPT_TYPE Encodes how your system can display what a process is doing
@ -409,6 +412,10 @@ SPT_TYPE Encodes how your system can display what a process is doing
SPT_PSTAT (3) -- Use the PSTAT_SETCMD option to pstat(2)
to set the process title; this is used by HP-UX.
SPT_PSSTRINGS (4) -- Use the magic PS_STRINGS pointer (4.4BSD).
SPT_SYSMIPS (5) -- Use sysmips() supported by NEWS-OS 6.
SPT_SCO (6) -- Write kernel u. area.
SPT_CHANGEARGV (7) -- Write pointers to our own strings into
the existing argv vector.
SPT_PADCHAR Character used to pad the process title; if undefined,
the space character (0x20) is used. This is ignored if
SPT_TYPE != SPT_REUSEARGV
@ -441,6 +448,15 @@ NAMELISTMASK If defined, values returned by nlist(3) are masked
0x7fffffff to strip off the top bit.
BSD4_4_SOCKADDR If defined, socket addresses have an sa_len field that
defines the length of this address.
SAFENFSPATHCONF Set this to 1 if and only if you have verified that a
pathconf(2) call with _PC_CHOWN_RESTRICTED argument on an
NFS filesystem where the underlying system allows users to
give away files to other users returns <= 0. Be sure you
try both on NFS V2 and V3. Some systems assume that their
local policy apply to NFS servers -- this is a bad
assumption! The test/t_pathconf.c program will try this
for you -- you have to run it in a directory that is
mounted from a server that allows file giveaway.
@ -521,8 +537,7 @@ MATCHGECOS Permit fuzzy matching of user names against the full
MIME8TO7 If non-zero, include 8 to 7 bit MIME conversions. This
also controls advertisement of 8BITMIME in the ESMTP
startup dialogue.
MIME7TO8 If non-zero, include 7 to 8 bit MIME conversions. Not yet
implemented.
MIME7TO8 If non-zero, include 7 to 8 bit MIME conversions.
HES_GETMAILHOST Define this to 1 if you are using Hesiod with the
hes_getmailhost() routine. This is included with the MIT
Hesiod distribution, but not with the DEC Hesiod distribution.
@ -791,13 +806,6 @@ Solaris 2.6 (SunOS 5.6)
incompatible snprintf(3s) calls. This problem is fixed in sendmail
8.8.5.
Ultrix
By default, the IDENT protocol is turned off on Ultrix. If you
are running Ultrix 4.4 or later, or if you have included patch
CXO-8919 for Ultrix 4.2 or 4.3 to fix the TCP problem, you can turn
IDENT on in the configuration file by setting the "ident" timeout
to 30 seconds.
Solaris 2.5.1 (SunOS 5.5.1)
Apparently patch 103663-01 installs a new /usr/include/resolv.h
file that defines the __P macro without checking to see if it is
@ -815,6 +823,13 @@ Solaris 2.5.1 (SunOS 5.5.1)
... And then file a bug report with Sun.
Ultrix
By default, the IDENT protocol is turned off on Ultrix. If you
are running Ultrix 4.4 or later, or if you have included patch
CXO-8919 for Ultrix 4.2 or 4.3 to fix the TCP problem, you can turn
IDENT on in the configuration file by setting the "ident" timeout
to 30 seconds.
OSF/1
If you are compiling on OSF/1 (DEC Alpha), you must use
-L/usr/shlib (otherwise it core dumps on startup). You may also
@ -1279,15 +1294,6 @@ LDAP
It requires the ldap and lber libraries from the Umich Ldap3.2
release.
- KNOWN BUGS: It does not work under Digital Unix 3.2c, with gcc and
ldap3.2 or ldap3.3. It dumps core after attempting to take strlen
of a garbage string pointer in the lber libraries routine
ber_printf.
The string pointer in question is set to 0x50000000, when the
program crashes. If anyone recognizes where this magic number comes
from that would be really helpful.
I've tested the software on Solaris.2.4 with gcc and on NeXTStep3.2
and it runs without problems. If you have any questions, please
send them along.
@ -1384,11 +1390,14 @@ main.c The main routine to sendmail. This file also
contains some miscellaneous routines.
map.c Support for database maps.
mci.c Routines that handle mail connection information caching.
mime.c MIME conversion routines.
parseaddr.c The routines which do address parsing.
queue.c Routines to implement message queueing.
readcf.c The routine that reads the configuration file and
translates it to internal form.
recipient.c Routines that manipulate the recipient list.
safefile.c Routines to do careful checking of file modes and permissions
when opening or creating files.
savemail.c Routines which save the letter on processing errors.
sendmail.h Main header file for sendmail.
srvrsmtp.c Routines to implement server SMTP.
@ -1407,4 +1416,4 @@ version.c The version number and information about this
Eric Allman
(Version 8.135, last update 1/21/97 07:47:02)
(Version 8.142, last update 6/3/97 11:34:09)

View File

@ -52,7 +52,7 @@
42 mci.c mci_get
43 mime.c mime8to7
44 recipient.c writeable
44 util.c safefile
44 safefile.c safefile, safedirpath, filechanged
45 envelope.c setsender
46 envelope.c openxscript
49 conf.c checkcompat
@ -70,4 +70,5 @@
80 content length
81 sun remote mode
91 mci.c syslogging of MCI cache information
94 srvrsmtp.c cause commands to fail (for protocol testing)
99 main.c avoid backgrounding (no printed output)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -35,7 +35,7 @@
# include "sendmail.h"
#ifndef lint
static char sccsid[] = "@(#)alias.c 8.67 (Berkeley) 1/18/97";
static char sccsid[] = "@(#)alias.c 8.73 (Berkeley) 5/8/97";
#endif /* not lint */
@ -74,7 +74,6 @@ alias(a, sendq, aliaslevel, e)
register ENVELOPE *e;
{
register char *p;
int naliases;
char *owner;
auto int stat = EX_OK;
char obuf[MAXNAME + 7];
@ -125,12 +124,10 @@ alias(a, sendq, aliaslevel, e)
return;
}
message("aliased to %s", shortenstring(p, 203));
#ifdef LOG
if (LogLevel > 9)
syslog(LOG_INFO, "%s: alias %.100s => %s",
e->e_id == NULL ? "NOQUEUE" : e->e_id,
sm_syslog(LOG_INFO, e->e_id,
"alias %.100s => %s",
a->q_paddr, shortenstring(p, 203));
#endif
a->q_flags &= ~QSELFREF;
if (tTd(27, 5))
{
@ -138,7 +135,7 @@ alias(a, sendq, aliaslevel, e)
printaddr(a, FALSE);
}
a->q_flags |= QDONTSEND;
naliases = sendtolist(p, a, sendq, aliaslevel + 1, e);
(void) sendtolist(p, a, sendq, aliaslevel + 1, e);
if (bitset(QSELFREF, a->q_flags))
a->q_flags &= ~QDONTSEND;
@ -279,7 +276,7 @@ setalias(spec)
else
{
class = "implicit";
map->map_mflags = MF_OPTIONAL|MF_INCLNULL;
map->map_mflags = MF_INCLNULL;
}
/* find end of spec */
@ -423,11 +420,10 @@ aliaswait(map, ext, isopen)
}
else
{
#ifdef LOG
if (LogLevel > 3)
syslog(LOG_INFO, "alias database %s out of date",
sm_syslog(LOG_INFO, NOQID,
"alias database %s out of date",
buf);
#endif /* LOG */
message("Warning: alias database %s out of date", buf);
}
}
@ -456,6 +452,7 @@ rebuildaliases(map, automatic)
{
FILE *af;
bool nolock = FALSE;
int sff = SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK|SFF_NOWLINK|SFF_NOWFILES;
sigfunc_t oldsigint, oldsigquit;
#ifdef SIGTSTP
sigfunc_t oldsigtstp;
@ -465,12 +462,12 @@ rebuildaliases(map, automatic)
return;
/* try to lock the source file */
if ((af = fopen(map->map_file, "r+")) == NULL)
if ((af = safefopen(map->map_file, O_RDWR, 0, sff)) == NULL)
{
struct stat stb;
if ((errno != EACCES && errno != EROFS) || automatic ||
(af = fopen(map->map_file, "r")) == NULL)
(af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL)
{
int saveerr = errno;
@ -517,14 +514,13 @@ rebuildaliases(map, automatic)
if (map->map_class->map_open(map, O_RDWR))
{
#ifdef LOG
if (LogLevel > 7)
{
syslog(LOG_NOTICE, "alias database %s %srebuilt by %s",
sm_syslog(LOG_NOTICE, NOQID,
"alias database %s %srebuilt by %s",
map->map_file, automatic ? "auto" : "",
username());
}
#endif /* LOG */
map->map_mflags |= MF_OPEN|MF_WRITABLE;
readaliases(map, af, !automatic, TRUE);
}
@ -605,6 +601,15 @@ readaliases(map, af, announcestats, logstats)
LineNumber++;
p = strchr(line, '\n');
#if _FFR_BACKSLASH_IN_ALIASES
while (p != NULL && p > line && p[-1] == '\\')
{
p--;
if (fgets(p, SPACELEFT(line, p), af) == NULL)
break;
p = strchr(p, '\n');
}
#endif
if (p != NULL)
*p = '\0';
else if (!feof(af))
@ -762,11 +767,10 @@ readaliases(map, af, announcestats, logstats)
if (Verbose || announcestats)
message("%s: %d aliases, longest %d bytes, %d bytes total",
map->map_file, naliases, longest, bytes);
# ifdef LOG
if (LogLevel > 7 && logstats)
syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
sm_syslog(LOG_INFO, NOQID,
"%s: %d aliases, longest %d bytes, %d bytes total",
map->map_file, naliases, longest, bytes);
# endif /* LOG */
}
/*
** FORWARD -- Try to forward mail
@ -846,12 +850,10 @@ forward(user, sendq, aliaslevel, e)
got_transient = TRUE;
if (tTd(27, 2))
printf("forward: transient error on %s\n", buf);
#ifdef LOG
if (LogLevel > 2)
syslog(LOG_ERR, "%s: forward %s: transient error: %s",
e->e_id == NULL ? "NOQUEUE" : e->e_id,
sm_syslog(LOG_ERR, e->e_id,
"forward %s: transient error: %s",
buf, errstring(err));
#endif
}
}
if (pp == NULL && got_transient)

View File

@ -1,3 +1,4 @@
.\" Copyright (c) 1983, 1997 Eric P. Allman
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -29,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)aliases.5 8.2 (Berkeley) 12/11/93
.\" @(#)aliases.5 8.3 (Berkeley) 2/1/97
.\"
.Dd December 11, 1993
.Dd February 1, 1997
.Dt ALIASES 5
.Os BSD 4
.Sh NAME

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)arpadate.c 8.6 (Berkeley) 9/16/96";
static char sccsid[] = "@(#)arpadate.c 8.7 (Berkeley) 2/1/97";
#endif /* not lint */
# include "sendmail.h"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)clock.c 8.18 (Berkeley) 12/31/96";
static char sccsid[] = "@(#)clock.c 8.24 (Berkeley) 4/19/97";
#endif /* not lint */
# include "sendmail.h"
@ -60,7 +60,9 @@ static char sccsid[] = "@(#)clock.c 8.18 (Berkeley) 12/31/96";
** none.
*/
static SIGFUNC_DECL tick __P((int));
EVENT *FreeEventList; /* list of free events */
static SIGFUNC_DECL tick __P((int));
EVENT *
setevent(intvl, func, arg)
@ -71,6 +73,7 @@ setevent(intvl, func, arg)
register EVENT **evp;
register EVENT *ev;
auto time_t now;
int wasblocked;
if (intvl <= 0)
{
@ -78,7 +81,7 @@ setevent(intvl, func, arg)
return (NULL);
}
(void) setsignal(SIGALRM, SIG_IGN);
wasblocked = blocksignal(SIGALRM);
(void) time(&now);
/* search event queue for correct position */
@ -89,7 +92,11 @@ setevent(intvl, func, arg)
}
/* insert new event */
ev = (EVENT *) xalloc(sizeof *ev);
ev = FreeEventList;
if (ev == NULL)
ev = (EVENT *) xalloc(sizeof *ev);
else
FreeEventList = ev->ev_link;
ev->ev_time = now + intvl;
ev->ev_func = func;
ev->ev_arg = arg;
@ -101,7 +108,11 @@ setevent(intvl, func, arg)
printf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
intvl, now + intvl, (u_long) func, arg, (u_long) ev);
tick(0);
setsignal(SIGALRM, tick);
intvl = EventQueue->ev_time - now;
(void) alarm((unsigned) intvl < 1 ? 1 : intvl);
if (wasblocked == 0)
(void) releasesignal(SIGALRM);
return (ev);
}
/*
@ -122,6 +133,7 @@ clrevent(ev)
register EVENT *ev;
{
register EVENT **evp;
int wasblocked;
if (tTd(5, 5))
printf("clrevent: ev=%lx\n", (u_long) ev);
@ -129,7 +141,7 @@ clrevent(ev)
return;
/* find the parent event */
(void) setsignal(SIGALRM, SIG_IGN);
wasblocked = blocksignal(SIGALRM);
for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
{
if (*evp == ev)
@ -140,16 +152,22 @@ clrevent(ev)
if (*evp != NULL)
{
*evp = ev->ev_link;
free((char *) ev);
ev->ev_link = FreeEventList;
FreeEventList = ev;
}
/* restore clocks and pick up anything spare */
tick(0);
if (wasblocked == 0)
releasesignal(SIGALRM);
if (EventQueue != NULL)
kill(getpid(), SIGALRM);
}
/*
** TICK -- take a clock tick
**
** Called by the alarm clock. This routine runs events as needed.
** Always called as a signal handler, so we assume that SIGALRM
** has been blocked.
**
** Parameters:
** One that is ignored; for compatibility with signal handlers.
@ -170,13 +188,14 @@ tick(arg)
int mypid = getpid();
int olderrno = errno;
(void) setsignal(SIGALRM, SIG_IGN);
(void) alarm(0);
now = curtime();
if (tTd(5, 4))
printf("tick: now=%ld\n", now);
/* reset signal in case System V semantics */
(void) setsignal(SIGALRM, tick);
while ((ev = EventQueue) != NULL &&
(ev->ev_time <= now || ev->ev_pid != mypid))
{
@ -196,7 +215,8 @@ tick(arg)
f = ev->ev_func;
arg = ev->ev_arg;
pid = ev->ev_pid;
free((char *) ev);
ev->ev_link = FreeEventList;
FreeEventList = ev;
if (pid != getpid())
continue;
if (EventQueue != NULL)
@ -207,17 +227,12 @@ tick(arg)
(void) alarm(3);
}
/* restore signals so that we can take ticks while in ev_func */
(void) setsignal(SIGALRM, tick);
(void) releasesignal(SIGALRM);
/* call ev_func */
errno = olderrno;
(*f)(arg);
(void) alarm(0);
now = curtime();
}
(void) setsignal(SIGALRM, tick);
if (EventQueue != NULL)
(void) alarm((unsigned) (EventQueue->ev_time - now));
errno = olderrno;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)convtime.c 8.8 (Berkeley) 11/24/96";
static char sccsid[] = "@(#)convtime.c 8.9 (Berkeley) 2/1/97";
#endif /* not lint */
# include "sendmail.h"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)envelope.c 8.101 (Berkeley) 12/16/96";
static char sccsid[] = "@(#)envelope.c 8.104 (Berkeley) 6/3/97";
#endif /* not lint */
#include "sendmail.h"
@ -121,12 +121,10 @@ dropenvelope(e, fulldrop)
}
}
#ifdef LOG
if (LogLevel > 84)
syslog(LOG_DEBUG, "%s: dropenvelope, e_flags=0x%x, OpMode=%c, pid=%d",
id == NULL ? "[NOQUEUE]" : id,
sm_syslog(LOG_DEBUG, id,
"dropenvelope, e_flags=0x%x, OpMode=%c, pid=%d",
e->e_flags, OpMode, getpid());
#endif
/* we must have an id to remove disk files */
if (id == NULL)
@ -168,8 +166,9 @@ dropenvelope(e, fulldrop)
queueit = TRUE;
#if XDEBUG
else if (bitset(QQUEUEUP, q->q_flags))
syslog(LOG_DEBUG, "dropenvelope: %s: q_flags = %x, paddr = %s",
e->e_id, q->q_flags, q->q_paddr);
sm_syslog(LOG_DEBUG, e->e_id,
"dropenvelope: q_flags = %x, paddr = %s",
q->q_flags, q->q_paddr);
#endif
/* see if a notification is needed */
@ -296,6 +295,8 @@ dropenvelope(e, fulldrop)
{
auto ADDRESS *rlist = NULL;
if (tTd(50, 8))
printf("dropenvelope(%s): sending return receipt\n", id);
e->e_flags |= EF_SENDRECEIPT;
(void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e);
(void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e);
@ -310,6 +311,8 @@ dropenvelope(e, fulldrop)
{
extern void savemail __P((ENVELOPE *, bool));
if (tTd(50, 8))
printf("dropenvelope(%s): saving mail\n", id);
savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags));
}
@ -323,6 +326,8 @@ dropenvelope(e, fulldrop)
{
auto ADDRESS *rlist = NULL;
if (tTd(50, 8))
printf("dropenvelope(%s): sending postmaster copy\n", id);
(void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e);
(void) returntosender(e->e_message, rlist, RTSF_PM_BOUNCE, e);
}
@ -332,6 +337,9 @@ dropenvelope(e, fulldrop)
*/
simpledrop:
if (tTd(50, 8))
printf("dropenvelope(%s): at simpledrop, queueit=%d\n",
id, queueit);
if (!queueit || bitset(EF_CLRQUEUE, e->e_flags))
{
if (tTd(50, 1))
@ -345,10 +353,8 @@ dropenvelope(e, fulldrop)
xunlink(queuename(e, 'd'));
xunlink(queuename(e, 'q'));
#ifdef LOG
if (LogLevel > 10)
syslog(LOG_INFO, "%s: done", id);
#endif
sm_syslog(LOG_INFO, id, "done");
}
else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
{
@ -360,6 +366,8 @@ dropenvelope(e, fulldrop)
}
/* now unlock the job */
if (tTd(50, 8))
printf("dropenvelope(%s): unlocking job\n", id);
closexscript(e);
unlockqueue(e);
@ -698,7 +706,6 @@ setsender(from, e, delimptr, delimchar, internal)
e->e_from.q_mailer == InclMailer)
{
/* log garbage addresses for traceback */
# ifdef LOG
if (from != NULL && LogLevel > 2)
{
char *p;
@ -716,11 +723,10 @@ setsender(from, e, delimptr, delimchar, internal)
MAXNAME, host);
p = ebuf;
}
syslog(LOG_NOTICE,
sm_syslog(LOG_NOTICE, e->e_id,
"setsender: %s: invalid or unparseable, received from %s",
shortenstring(from, 83), p);
}
# endif /* LOG */
if (from != NULL)
{
if (!bitset(QBADADDR, e->e_from.q_flags))
@ -838,11 +844,10 @@ setsender(from, e, delimptr, delimchar, internal)
if (pvp == NULL)
{
/* don't need to give error -- prescan did that already */
# ifdef LOG
if (LogLevel > 2)
syslog(LOG_NOTICE, "cannot prescan from (%s)",
sm_syslog(LOG_NOTICE, e->e_id,
"cannot prescan from (%s)",
shortenstring(from, 203));
# endif
finis();
}
(void) rewrite(pvp, 3, 0, e);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)err.c 8.52 (Berkeley) 12/1/96";
static char sccsid[] = "@(#)err.c 8.62 (Berkeley) 6/5/97";
#endif /* not lint */
# include "sendmail.h"
@ -42,8 +42,7 @@ static char sccsid[] = "@(#)err.c 8.52 (Berkeley) 12/1/96";
/*
** SYSERR -- Print error message.
**
** Prints an error message via printf to the diagnostic
** output. If LOG is defined, it logs it also.
** Prints an error message via printf to the diagnostic output.
**
** If the first character of the syserr message is `!' it will
** log this as an ALERT message and exit immediately. This can
@ -90,16 +89,17 @@ syserr(fmt, va_alist)
register char *p;
int olderrno = errno;
bool panic;
#ifdef LOG
char *uname;
struct passwd *pw;
char ubuf[80];
#endif
VA_LOCAL_DECL
panic = *fmt == '!';
if (panic)
{
fmt++;
HoldErrs = FALSE;
}
/* format and output the error message */
if (olderrno == 0)
@ -130,7 +130,6 @@ syserr(fmt, va_alist)
printf("syserr: ExitStat = %d\n", ExitStat);
}
# ifdef LOG
pw = sm_getpwuid(getuid());
if (pw != NULL)
uname = pw->pw_name;
@ -141,10 +140,9 @@ syserr(fmt, va_alist)
}
if (LogLevel > 0)
syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR(%s): %.900s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
sm_syslog(panic ? LOG_ALERT : LOG_CRIT, CurEnv->e_id,
"SYSERR(%s): %.900s",
uname, &MsgBuf[4]);
# endif /* LOG */
switch (olderrno)
{
case EBADF:
@ -180,7 +178,7 @@ syserr(fmt, va_alist)
exit(EX_OSERR);
}
errno = 0;
if (QuickAbort)
if (QuickAbort || (OnlyOneError && !HoldErrs))
longjmp(TopFrame, 2);
}
/*
@ -251,14 +249,12 @@ usrerr(fmt, va_alist)
puterrmsg(MsgBuf);
# ifdef LOG
if (LogLevel > 3 && LogUsrErrs)
syslog(LOG_NOTICE, "%s: %.900s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
sm_syslog(LOG_NOTICE, CurEnv->e_id,
"%.900s",
&MsgBuf[4]);
# endif /* LOG */
if (QuickAbort)
if (QuickAbort || (OnlyOneError && !HoldErrs))
longjmp(TopFrame, 1);
}
/*
@ -404,10 +400,10 @@ putoutmsg(msg, holdmsg, heldmsg)
if (!heldmsg && CurEnv->e_xfp != NULL && strchr("45", msg[0]) != NULL)
fprintf(CurEnv->e_xfp, "%s\n", msg);
#ifdef LOG
if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
syslog(LOG_INFO, "--> %s%s", msg, holdmsg ? " (held)" : "");
#endif
sm_syslog(LOG_INFO, CurEnv->e_id,
"--> %s%s",
msg, holdmsg ? " (held)" : "");
if (msgcode == '8')
msg[0] = '0';
@ -450,14 +446,11 @@ putoutmsg(msg, holdmsg, heldmsg)
/* can't call syserr, 'cause we are using MsgBuf */
HoldErrs = TRUE;
#ifdef LOG
if (LogLevel > 0)
syslog(LOG_CRIT,
"%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
sm_syslog(LOG_CRIT, CurEnv->e_id,
"SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
CurHostName == NULL ? "NO-HOST" : CurHostName,
shortenstring(msg, 203), errstring(errno));
#endif
}
/*
** PUTERRMSG -- like putoutmsg, but does special processing for error messages
@ -522,7 +515,6 @@ fmtmsg(eb, to, num, eno, fmt, ap)
va_list ap;
{
char del;
char *meb;
int l;
int spaceleft = sizeof MsgBuf;
@ -559,8 +551,6 @@ fmtmsg(eb, to, num, eno, fmt, ap)
*eb++ &= 0177;
}
meb = eb;
/* output the message */
(void) vsnprintf(eb, spaceleft, fmt, ap);
spaceleft -= strlen(eb);
@ -627,7 +617,7 @@ errstring(errnum)
char *dnsmsg;
char *bp;
static char buf[MAXLINE];
# ifndef ERRLIST_PREDEFINED
# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
extern char *sys_errlist[];
extern int sys_nerr;
# endif
@ -648,7 +638,11 @@ errstring(errnum)
case ETIMEDOUT:
case ECONNRESET:
bp = buf;
#if HASSTRERROR
snprintf(bp, SPACELEFT(buf, bp), "%s", strerror(errnum));
#else
snprintf(bp, SPACELEFT(buf, bp), "%s", sys_errlist[errnum]);
#endif
bp += strlen(bp);
if (CurHostName != NULL)
{
@ -690,9 +684,6 @@ errstring(errnum)
return (buf);
# endif
case EOPENTIMEOUT:
return "Timeout on file open";
# if NAMED_BIND
case HOST_NOT_FOUND + E_DNSBASE:
dnsmsg = "host not found";
@ -714,6 +705,40 @@ errstring(errnum)
case EPERM:
/* SunOS gives "Not owner" -- this is the POSIX message */
return "Operation not permitted";
/*
** Error messages used internally in sendmail.
*/
case E_SM_OPENTIMEOUT:
return "Timeout on file open";
case E_SM_NOSLINK:
return "Symbolic links not allowed";
case E_SM_NOHLINK:
return "Hard links not allowed";
case E_SM_REGONLY:
return "Regular files only";
case E_SM_ISEXEC:
return "Executable files not allowed";
case E_SM_WWDIR:
return "World writable directory";
case E_SM_GWDIR:
return "Group writable directory";
case E_SM_FILECHANGE:
return "File changed after open";
case E_SM_WWFILE:
return "World writable file";
case E_SM_GWFILE:
return "Group writable file";
}
if (dnsmsg != NULL)
@ -731,9 +756,13 @@ errstring(errnum)
return buf;
}
#if HASSTRERROR
return strerror(errnum);
#else
if (errnum > 0 && errnum < sys_nerr)
return (sys_errlist[errnum]);
(void) snprintf(buf, sizeof buf, "Error %d", errnum);
return (buf);
#endif
}

View File

@ -5,12 +5,14 @@
** Please go to him for support -- since I (Eric) don't run LDAP, I
** can't help you at all.
**
** @(#)ldap_map.h 8.2 (Berkeley) 5/22/96
** @(#)ldap_map.h 8.4 (Berkeley) 6/3/97
*/
#ifndef _LDAP_MAP_H
#define _LDAP_MAP_H
#include <sys/time.h>
struct ldap_map_struct
{
/* needed for ldap_open */
@ -33,7 +35,7 @@ struct ldap_map_struct
char *base;
int scope;
char *filter;
char *attr;
char *attr[2];
int attrsonly;
struct timeval timeout;
LDAPMessage *res;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)macro.c 8.17 (Berkeley) 5/13/96";
static char sccsid[] = "@(#)macro.c 8.18 (Berkeley) 2/1/97";
#endif /* not lint */
# include "sendmail.h"

View File

@ -1,3 +1,4 @@
.\" Copyright (c) 1983, 1997 Eric P. Allman
.\" Copyright (c) 1985, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -29,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)mailq.1 8.4 (Berkeley) 2/22/94
.\" @(#)mailq.1 8.5 (Berkeley) 2/1/97
.\"
.Dd February 22, 1994
.Dd February 1, 1997
.Dt MAILQ 1
.Os BSD 4
.Sh NAME

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1995, 1996 Eric P. Allman.
* Copyright (c) 1992, 1995-1997 Eric P. Allman.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)map.c 8.147 (Berkeley) 1/17/97";
static char sccsid[] = "@(#)map.c 8.168 (Berkeley) 6/14/97";
#endif /* not lint */
#include "sendmail.h"
@ -107,11 +107,23 @@ static char sccsid[] = "@(#)map.c 8.147 (Berkeley) 1/17/97";
extern bool aliaswait __P((MAP *, char *, int));
extern bool extract_canonname __P((char *, char *, char[], int));
#if O_EXLOCK && HASFLOCK
#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
#else
# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
#endif
#ifndef O_LEAVELOCKED
# if O_SHLOCK
# define O_LEAVELOCKED O_SHLOCK
# else
# define O_LEAVELOCKED 0x1000
# endif
#endif
#ifndef O_ACCMODE
# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#endif
/*
** MAP_PARSEARGS -- parse config line arguments for database lookup
**
@ -284,7 +296,7 @@ map_parseargs(map, ap)
char *
map_rewrite(map, s, slen, av)
register MAP *map;
register char *s;
register const char *s;
int slen;
char **av;
{
@ -314,14 +326,15 @@ map_rewrite(map, s, slen, av)
i = len = slen;
if (av != NULL)
{
bp = s;
for (i = slen; --i >= 0 && (c = *bp++) != 0; )
const char *sp = s;
for (i = slen; --i >= 0 && (c = *sp++) != 0; )
{
if (c != '%')
continue;
if (--i < 0)
break;
c = *bp++;
c = *sp++;
if (!(isascii(c) && isdigit(c)))
continue;
for (avp = av; --c >= '0' && *avp != NULL; avp++)
@ -675,11 +688,9 @@ extract_canonname(name, line, cbuf, cbuflen)
int i;
char *p;
bool found = FALSE;
int l;
extern char *get_column __P((char *, int, char, char *, int));
cbuf[0] = '\0';
l = cbuflen;
if (line[0] == '#')
return FALSE;
@ -733,11 +744,49 @@ ndbm_map_open(map, mode)
register DBM *dbm;
struct stat st;
int fd;
int sff;
int ret;
int smode = S_IREAD;
char dirfile[MAXNAME + 1];
char pagfile[MAXNAME + 1];
struct stat std, stp;
if (tTd(38, 2))
printf("ndbm_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
map->map_lockfd = -1;
mode &= O_ACCMODE;
/* do initial file and directory checks */
snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file);
snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file);
sff = SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
if (mode == O_RDWR)
{
sff |= SFF_NOLINK;
smode = S_IWRITE;
}
else
{
sff |= SFF_NOWLINK;
}
if (FatalWritableDirs)
sff |= SFF_SAFEDIRPATH;
if ((ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName,
sff, smode, &std)) != 0 ||
(ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName,
sff, smode, &stp)) != 0)
{
/* cannot open this map */
if (tTd(38, 2))
printf("\tunsafe map file: %d\n", ret);
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("dbm map \"%s\": unsafe map file %s",
map->map_mname, map->map_file);
return FALSE;
}
if (std.st_mode == ST_MODE_NOFILE)
mode |= O_EXCL;
#if LOCK_ON_OPEN
if (mode == O_RDONLY)
@ -745,12 +794,14 @@ ndbm_map_open(map, mode)
else
mode |= O_CREAT|O_TRUNC|O_EXLOCK;
#else
if (mode == O_RDWR)
if ((mode & O_ACCMODE) == O_RDWR)
{
# if NOFTRUNCATE
/*
** Warning: race condition. Try to lock the file as
** quickly as possible after opening it.
** This may also have security problems on some systems,
** but there isn't anything we can do about it.
*/
mode |= O_CREAT|O_TRUNC;
@ -763,13 +814,11 @@ ndbm_map_open(map, mode)
int dirfd;
int pagfd;
char dirfile[MAXNAME + 1];
char pagfile[MAXNAME + 1];
snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file);
snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file);
dirfd = open(dirfile, mode|O_CREAT, DBMMODE);
pagfd = open(pagfile, mode|O_CREAT, DBMMODE);
dirfd = safeopen(dirfile, mode|O_CREAT, DBMMODE,
SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
pagfd = safeopen(pagfile, mode|O_CREAT, DBMMODE,
SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
if (dirfd < 0 || pagfd < 0)
{
@ -779,9 +828,6 @@ ndbm_map_open(map, mode)
close(pagfd);
return FALSE;
}
if (!lockfile(dirfd, map->map_file, ".dir", LOCK_EX))
syserr("ndbm_map_open: cannot lock %s.dir",
map->map_file);
if (ftruncate(dirfd, (off_t) 0) < 0)
syserr("ndbm_map_open: cannot truncate %s.dir",
map->map_file);
@ -805,8 +851,25 @@ ndbm_map_open(map, mode)
return TRUE;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open DBM database %s", map->map_file);
#if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
close(map->map_lockfd);
#endif
return FALSE;
}
if (filechanged(dirfile, dbm_dirfno(dbm), &std, sff) ||
filechanged(pagfile, dbm_pagfno(dbm), &stp, sff))
{
syserr("ndbm_map_open(%s): file changed after open",
map->map_file);
dbm_close(dbm);
#if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
close(map->map_lockfd);
#endif
return FALSE;
}
map->map_db1 = (void *) dbm;
fd = dbm_dirfno((DBM *) map->map_db1);
if (mode == O_RDONLY)
@ -1036,7 +1099,7 @@ ndbm_map_close(map)
** be pokey about it. That's hard to do.
*/
extern bool db_map_open __P((MAP *, int, DBTYPE, const void *));
extern bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
/* these should be K line arguments */
#ifndef DB_CACHE_SIZE
@ -1059,7 +1122,7 @@ bt_map_open(map, mode)
bzero(&btinfo, sizeof btinfo);
btinfo.cachesize = DB_CACHE_SIZE;
return db_map_open(map, mode, DB_BTREE, &btinfo);
return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
}
bool
@ -1076,32 +1139,65 @@ hash_map_open(map, mode)
bzero(&hinfo, sizeof hinfo);
hinfo.nelem = DB_HASH_NELEM;
hinfo.cachesize = DB_CACHE_SIZE;
return db_map_open(map, mode, DB_HASH, &hinfo);
return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
}
bool
db_map_open(map, mode, dbtype, openinfo)
db_map_open(map, mode, mapclassname, dbtype, openinfo)
MAP *map;
int mode;
char *mapclassname;
DBTYPE dbtype;
const void *openinfo;
{
DB *db;
int i;
int omode;
int smode = S_IREAD;
int fd;
int sff;
int saveerrno;
bool leavelocked = bitset(O_LEAVELOCKED, mode);
struct stat st;
char buf[MAXNAME + 1];
/* do initial file and directory checks */
snprintf(buf, sizeof buf - 3, "%s", map->map_file);
i = strlen(buf);
if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
(void) strcat(buf, ".db");
map->map_lockfd = -1;
mode &= O_ACCMODE;
omode = mode;
sff = SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
if (mode == O_RDWR)
{
sff |= SFF_NOLINK;
smode = S_IWRITE;
}
else
{
sff |= SFF_NOWLINK;
}
if (FatalWritableDirs)
sff |= SFF_SAFEDIRPATH;
if ((i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName,
sff, smode, &st)) != 0)
{
/* cannot open this map */
if (tTd(38, 2))
printf("\tunsafe map file: %d\n", i);
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("%s map \"%s\": unsafe map file %s",
mapclassname, map->map_mname, map->map_file);
return FALSE;
}
if (st.st_mode == ST_MODE_NOFILE)
omode |= O_EXCL;
map->map_lockfd = -1;
#if LOCK_ON_OPEN
if (mode == O_RDWR)
omode |= O_CREAT|O_TRUNC|O_EXLOCK;
@ -1139,7 +1235,7 @@ db_map_open(map, mode, dbtype, openinfo)
saveerrno = errno;
#if !LOCK_ON_OPEN
if (mode == O_RDWR)
if (leavelocked || mode == O_RDWR)
map->map_lockfd = fd;
else
(void) close(fd);
@ -1152,7 +1248,23 @@ db_map_open(map, mode, dbtype, openinfo)
return TRUE;
errno = saveerrno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open DB database %s", map->map_file);
syserr("Cannot open %s database %s",
mapclassname, map->map_file);
#if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
#endif
return FALSE;
}
if (filechanged(buf, db->fd(db), &st, sff))
{
syserr("db_map_open(%s): file changed after open", buf);
db->close(db);
#if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
close(map->map_lockfd);
#endif
return FALSE;
}
@ -1161,7 +1273,7 @@ db_map_open(map, mode, dbtype, openinfo)
#if !OLD_NEWDB
fd = db->fd(db);
# if LOCK_ON_OPEN
if (fd >= 0 && mode == O_RDONLY)
if (fd >= 0 && mode == O_RDONLY && !leavelocked)
{
(void) lockfile(fd, map->map_file, ".db", LOCK_UN);
}
@ -1203,6 +1315,7 @@ db_map_lookup(map, name, av, statp)
int st;
int saveerrno;
int fd;
struct stat stbuf;
char keybuf[MAXNAME + 1];
if (tTd(38, 20))
@ -1220,8 +1333,41 @@ db_map_lookup(map, name, av, statp)
#if !OLD_NEWDB
fd = db->fd(db);
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
(void) lockfile(db->fd(db), map->map_file, ".db", LOCK_SH);
(void) lockfile(fd, map->map_file, ".db", LOCK_SH);
if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
{
/* Reopen the database to sync the cache */
int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
: O_RDONLY;
map->map_class->map_close(map);
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
omode |= O_LEAVELOCKED;
if (map->map_class->map_open(map, omode))
{
map->map_mflags |= MF_OPEN;
if ((omode && O_ACCMODE) == O_RDWR)
map->map_mflags |= MF_WRITABLE;
db = (DB *) map->map_db2;
fd = db->fd(db);
}
else
{
if (!bitset(MF_OPTIONAL, map->map_mflags))
{
extern MAPCLASS BogusMapClass;
*statp = EX_TEMPFAIL;
map->map_class = &BogusMapClass;
map->map_mflags |= MF_OPEN;
syserr("Cannot reopen DB database %s",
map->map_file);
}
return NULL;
}
}
#endif
st = 1;
if (bitset(MF_TRY0NULL, map->map_mflags))
{
@ -1392,6 +1538,7 @@ nis_map_open(map, mode)
printf("nis_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
/* issue a pseudo-error message */
@ -1581,6 +1728,8 @@ nis_getcanonname(name, hbsize, statp)
*statp = EX_UNAVAILABLE;
return FALSE;
}
if (vsize >= sizeof host_record)
vsize = sizeof host_record - 1;
strncpy(host_record, vp, vsize);
host_record[vsize] = '\0';
if (tTd(38, 44))
@ -1637,6 +1786,7 @@ nisplus_map_open(map, mode)
printf("nisplus_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
errno = ENODEV;
@ -1657,15 +1807,17 @@ nisplus_map_open(map, mode)
map->map_file, map->map_domain);
}
if (!PARTIAL_NAME(map->map_file))
{
map->map_domain = newstr("");
/* check to see if this map actually exists */
if (PARTIAL_NAME(map->map_file))
snprintf(qbuf, sizeof qbuf, "%s", map->map_file);
}
else
{
/* check to see if this map actually exists */
snprintf(qbuf, sizeof qbuf, "%s.%s",
map->map_file, map->map_domain);
else
strcpy(qbuf, map->map_file);
}
retry_cnt = 0;
while (res == NULL || res->status != NIS_SUCCESS)
{
@ -1769,10 +1921,11 @@ nisplus_map_lookup(map, name, av, statp)
char **av;
int *statp;
{
char *vp;
char *p;
auto int vsize;
int buflen;
char search_key[MAXNAME + 1];
char *skp;
int skleft;
char search_key[MAXNAME + 4];
char qbuf[MAXLINE + NIS_MAXNAMELEN];
nis_result *result;
@ -1791,11 +1944,40 @@ nisplus_map_lookup(map, name, av, statp)
}
}
buflen = strlen(name);
if (buflen > sizeof search_key - 1)
buflen = sizeof search_key - 1;
bcopy(name, search_key, buflen);
search_key[buflen] = '\0';
/*
** Copy the name to the key buffer, escaping double quote characters
** by doubling them and quoting "]" and "," to avoid having the
** NIS+ parser choke on them.
*/
skleft = sizeof search_key - 4;
skp = search_key;
for (p = name; *p != '\0' && skleft > 0; p++)
{
switch (*p)
{
case ']':
case ',':
/* quote the character */
*skp++ = '"';
*skp++ = *p;
*skp++ = '"';
skleft -= 3;
break;
case '"':
/* double the quote */
*skp++ = '"';
skleft--;
/* fall through... */
default:
*skp++ = *p;
skleft--;
break;
}
}
*skp = '\0';
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
makelower(search_key);
@ -1819,7 +2001,7 @@ nisplus_map_lookup(map, name, av, statp)
if ((count = NIS_RES_NUMOBJ(result)) != 1)
{
if (LogLevel > 10)
syslog(LOG_WARNING,
sm_syslog(LOG_WARNING, CurEnv->e_id,
"%s: lookup error, expected 1 entry, got %d",
map->map_file, count);
@ -1829,18 +2011,18 @@ nisplus_map_lookup(map, name, av, statp)
name, count);
}
vp = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
/* set the length of the result */
if (vp == NULL)
vp = "";
vsize = strlen(vp);
if (p == NULL)
p = "";
vsize = strlen(p);
if (tTd(38, 20))
printf("nisplus_map_lookup(%s), found %s\n",
name, vp);
name, p);
if (bitset(MF_MATCHONLY, map->map_mflags))
str = map_rewrite(map, name, strlen(name), NULL);
else
str = map_rewrite(map, vp, vsize, av);
str = map_rewrite(map, p, vsize, av);
nis_freeresult(result);
*statp = EX_OK;
return str;
@ -1923,12 +2105,10 @@ nisplus_getcanonname(name, hbsize, statp)
if ((count = NIS_RES_NUMOBJ(result)) != 1)
{
#ifdef LOG
if (LogLevel > 10)
syslog(LOG_WARNING,
sm_syslog(LOG_WARNING, CurEnv->e_id,
"nisplus_getcanonname: lookup error, expected 1 entry, got %d",
count);
#endif
/* ignore second entry */
if (tTd(38, 20))
@ -2031,6 +2211,7 @@ ldap_map_open(map, mode)
if (tTd(38, 2))
printf("ldap_map_open(%s, %d)\n", map->map_mname, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
/* issue a pseudo-error message */
@ -2207,7 +2388,7 @@ ldap_map_lookup(map, name, av, statp)
snprintf(filter, sizeof filter, lmap->filter, keybuf);
if (ldap_search_st(lmap->ld, lmap->base,lmap->scope,filter,
&(lmap->attr), lmap->attrsonly, &(lmap->timeout),
lmap->attr, lmap->attrsonly, &(lmap->timeout),
&(lmap->res)) != LDAP_SUCCESS)
{
/* try close/opening map */
@ -2219,7 +2400,7 @@ ldap_map_lookup(map, name, av, statp)
goto quick_exit;
}
if (ldap_search_st(lmap->ld, lmap->base, lmap->scope, filter,
&(lmap->attr), lmap->attrsonly,
lmap->attr, lmap->attrsonly,
&(lmap->timeout), &(lmap->res))
!= LDAP_SUCCESS)
{
@ -2243,7 +2424,7 @@ ldap_map_lookup(map, name, av, statp)
}
/* Need to build the args for map_rewrite here */
attr_values = ldap_get_values(lmap->ld,entry,lmap->attr);
attr_values = ldap_get_values(lmap->ld,entry,lmap->attr[0]);
if (attr_values == NULL)
{
/* bad things happened */
@ -2258,12 +2439,10 @@ ldap_map_lookup(map, name, av, statp)
vp = attr_values[0];
vsize = strlen(vp);
# ifdef LOG
if (LogLevel > 9)
syslog(LOG_INFO, "%s: ldap %.100s => %s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
sm_syslog(LOG_INFO, CurEnv->e_id,
"ldap %.100s => %s",
name, vp);
# endif
if (bitset(MF_MATCHONLY, map->map_mflags))
result = map_rewrite(map, name, strlen(name), NULL);
else
@ -2398,7 +2577,8 @@ ldap_map_parseargs(map,args)
case 'v': /* attr to return */
while (isascii(*++p) && isspace(*p))
continue;
lmap->attr = p;
lmap->attr[0] = p;
lmap->attr[1] = NULL;
break;
/* args stolen from ldapsearch.c */
@ -2538,8 +2718,8 @@ ldap_map_parseargs(map,args)
return FALSE;
}
}
if (lmap->attr != NULL)
lmap->attr = newstr(ldap_map_dequote(lmap->attr));
if (lmap->attr[0] != NULL)
lmap->attr[0] = newstr(ldap_map_dequote(lmap->attr[0]));
else
{
if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
@ -2690,6 +2870,7 @@ ni_map_open(map, mode)
if (tTd(38, 2))
printf("ni_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
if (*map->map_file == '\0')
map->map_file = NETINFO_DEFAULT_DIR;
@ -2970,6 +3151,8 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
** This code donated by Sun Microsystems.
*/
#define map_sff map_lockfd /* overload field */
/*
** TEXT_MAP_OPEN -- open text table
@ -2980,12 +3163,14 @@ text_map_open(map, mode)
MAP *map;
int mode;
{
struct stat sbuf;
int sff;
int i;
if (tTd(38, 2))
printf("text_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
errno = ENODEV;
@ -3005,33 +3190,22 @@ text_map_open(map, mode)
map->map_mname);
return FALSE;
}
/* check to see if this map actually accessable */
if (access(map->map_file, R_OK) <0)
sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOWLINK;
if (FatalWritableDirs)
sff |= SFF_SAFEDIRPATH;
if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName,
sff, S_IRUSR, NULL)) != 0)
{
/* cannot open this map */
if (tTd(38, 2))
printf("text_map_open(%s, %s): cannot access: %s\n",
map->map_mname, map->map_file, errstring(errno));
printf("\tunsafe map file: %d\n", i);
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("text map \"%s\": cannot access file %s",
syserr("text map \"%s\": unsafe map file %s",
map->map_mname, map->map_file);
return FALSE;
}
/* check to see if this map actually exist */
if (stat(map->map_file, &sbuf) <0)
{
syserr("text_map_open(%s, %s): cannot stat",
map->map_mname, map->map_file);
return FALSE;
}
if (!S_ISREG(sbuf.st_mode))
{
syserr("text map \"%s\": %s is not a regular file",
map->map_mname, map->map_file);
return FALSE;
}
if (map->map_keycolnm == NULL)
map->map_keycolno = 0;
else
@ -3070,6 +3244,7 @@ text_map_open(map, mode)
printf("%c\n", map->map_coldelim);
}
map->map_sff = sff;
return TRUE;
}
@ -3088,13 +3263,14 @@ text_map_lookup(map, name, av, statp)
char *vp;
auto int vsize;
int buflen;
char search_key[MAXNAME + 1];
char linebuf[MAXLINE];
FILE *f;
char buf[MAXNAME + 1];
char delim;
int key_idx;
bool found_it;
int sff = map->map_sff;
char search_key[MAXNAME + 1];
char linebuf[MAXLINE];
char buf[MAXNAME + 1];
extern char *get_column __P((char *, int, char, char *, int));
found_it = FALSE;
@ -3109,7 +3285,7 @@ text_map_lookup(map, name, av, statp)
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
makelower(search_key);
f = fopen(map->map_file, "r");
f = safefopen(map->map_file, O_RDONLY, FileMode, sff);
if (f == NULL)
{
map->map_mflags &= ~(MF_VALID|MF_OPEN);
@ -3166,7 +3342,6 @@ text_getcanonname(name, hbsize, statp)
char linebuf[MAXLINE];
char cbuf[MAXNAME + 1];
char nbuf[MAXNAME + 1];
extern char *get_column __P((char *, int, char, char *, int));
if (tTd(38, 20))
printf("text_getcanonname(%s)\n", name);
@ -3272,19 +3447,24 @@ stab_map_open(map, mode)
int mode;
{
FILE *af;
int sff;
struct stat st;
if (tTd(38, 2))
printf("stab_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
errno = ENODEV;
return FALSE;
}
af = fopen(map->map_file, "r");
sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOWLINK;
if (FatalWritableDirs)
sff |= SFF_SAFEDIRPATH;
af = safefopen(map->map_file, O_RDONLY, 0444, sff);
if (af == NULL)
return FALSE;
readaliases(map, af, FALSE, FALSE);
@ -3365,6 +3545,7 @@ impl_map_open(map, mode)
printf("impl_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
#ifdef NEWDB
map->map_mflags |= MF_IMPL_HASH;
if (hash_map_open(map, mode))
@ -3447,6 +3628,7 @@ user_map_open(map, mode)
printf("user_map_open(%s, %d)\n",
map->map_mname, mode);
mode &= O_ACCMODE;
if (mode != O_RDONLY)
{
/* issue a pseudo-error message */
@ -3768,6 +3950,7 @@ switch_map_open(map, mode)
printf("switch_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
nmaps = switch_map_find(map->map_file, maptype, map->map_return);
if (tTd(38, 19))
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 1996 Eric P. Allman
* Copyright (c) 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mci.c 8.54 (Berkeley) 12/1/96";
static char sccsid[] = "@(#)mci.c 8.62 (Berkeley) 5/29/97";
#endif /* not lint */
#include "sendmail.h"
@ -116,12 +116,10 @@ mci_cache(mci)
if (tTd(42, 5))
printf("mci_cache: caching %lx (%s) in slot %d\n",
(u_long) mci, mci->mci_host, mcislot - MciCache);
#ifdef LOG
if (tTd(91, 100))
syslog(LOG_DEBUG, "%s: mci_cache: caching %x (%.100s) in slot %d",
CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
sm_syslog(LOG_DEBUG, CurEnv->e_id,
"mci_cache: caching %x (%.100s) in slot %d",
mci, mci->mci_host, mcislot - MciCache);
#endif
*mcislot = mci;
mci->mci_flags |= MCIF_CACHED;
@ -216,12 +214,10 @@ mci_uncache(mcislot, doquit)
if (tTd(42, 5))
printf("mci_uncache: uncaching %lx (%s) from slot %d (%d)\n",
(u_long) mci, mci->mci_host, mcislot - MciCache, doquit);
#ifdef LOG
if (tTd(91, 100))
syslog(LOG_DEBUG, "%s: mci_uncache: uncaching %x (%.100s) from slot %d (%d)",
CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
sm_syslog(LOG_DEBUG, CurEnv->e_id,
"mci_uncache: uncaching %x (%.100s) from slot %d (%d)",
mci, mci->mci_host, mcislot - MciCache, doquit);
#endif
#if SMTP
if (doquit)
@ -485,11 +481,9 @@ mci_dump(mci, logit)
mci->mci_host == NULL ? "NULL" : mci->mci_host,
ctime(&mci->mci_lastuse));
printit:
#ifdef LOG
if (logit)
syslog(LOG_DEBUG, "%.1000s", buf);
sm_syslog(LOG_DEBUG, CurEnv->e_id, "%.1000s", buf);
else
#endif
printf("%s\n", buf);
}
/*
@ -577,8 +571,8 @@ mci_lock_host_statfile(mci)
goto cleanup;
}
if ((mci->mci_statfile = fopen(fname, "r+")) == NULL)
mci->mci_statfile = fopen(fname, "w");
mci->mci_statfile = safefopen(fname, O_RDWR|O_CREAT, FileMode,
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_CREAT);
if (mci->mci_statfile == NULL)
{
@ -699,7 +693,8 @@ mci_load_persistent(mci)
goto cleanup;
}
fp = fopen(fname, "r");
fp = safefopen(fname, O_RDONLY, FileMode,
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY);
if (fp == NULL)
{
/* I can't think of any reason this should ever happen */
@ -744,6 +739,7 @@ mci_read_persistent(fp, mci)
{
int ver;
register char *p;
int saveLineNumber = LineNumber;
char buf[MAXLINE];
if (fp == NULL)
@ -763,8 +759,10 @@ mci_read_persistent(fp, mci)
rewind(fp);
ver = -1;
LineNumber = 0;
while (fgets(buf, sizeof buf, fp) != NULL)
{
LineNumber++;
p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';
@ -806,9 +804,11 @@ mci_read_persistent(fp, mci)
default:
syserr("Unknown host status line \"%s\"", buf);
LineNumber = saveLineNumber;
return -1;
}
}
LineNumber = saveLineNumber;
if (ver < 0)
return -1;
return 0;
@ -1053,7 +1053,8 @@ mci_print_persistent(pathname, hostname)
printf(" -------------- Hostname --------------- How long ago ---------Results---------\n");
}
fp = fopen(pathname, "r+");
fp = safefopen(pathname, O_RDWR, FileMode,
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY);
if (fp == NULL)
{
@ -1063,16 +1064,19 @@ mci_print_persistent(pathname, hostname)
return 0;
}
FileName = pathname;
bzero(&mcib, sizeof mcib);
if (mci_read_persistent(fp, &mcib) < 0)
{
syserr("%s: could not read status file", pathname);
fclose(fp);
FileName = NULL;
return 0;
}
locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB);
fclose(fp);
FileName = NULL;
printf("%c%-39s %12s ",
locked ? '*' : ' ', hostname,
@ -1193,13 +1197,22 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
*/
if (host == NULL)
{
syserr("mci_generate_persistent_path: null host");
return -1;
}
if (path == NULL)
{
syserr("mci_generate_persistent_path: null path");
return -1;
}
if (tTd(56, 80))
printf("mci_generate_persistent_path(%s): ", host);
if (*host == '\0')
return -1;
/* make certain this is not a bracketed host number */
if (strlen(host) > sizeof t_host - 1)
return -1;
@ -1214,16 +1227,19 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
*/
elem = t_host + strlen(t_host);
while (elem > t_host && (elem[-1] == '.' || elem[-1] == ']'))
while (elem > t_host &&
(elem[-1] == '.' || (host[0] == '[' && elem[-1] == ']')))
*--elem = '\0';
/* check for what will be the final length of the path */
len = strlen(HostStatDir) + 2;
for (p = (char *) host; *p != '\0'; p++)
{
if (*p == '|' || *p != '.')
if (*p == '|' || *p == '.')
len++;
len++;
if (p[0] == '.' && p[1] == '.')
return -1;
}
if (len > pathlen)
return -1;

View File

@ -1,3 +1,4 @@
.\" Copyright (c) 1983, 1997 Eric P. Allman
.\" Copyright (c) 1985, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -29,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)newaliases.1 8.4 (Berkeley) 2/22/94
.\" @(#)newaliases.1 8.5 (Berkeley) 2/1/97
.\"
.Dd February 22, 1994
.Dd February 1, 1997
.Dt NEWALIASES 1
.Os BSD 4
.Sh NAME

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -36,9 +36,9 @@
#ifndef lint
#if QUEUE
static char sccsid[] = "@(#)queue.c 8.153 (Berkeley) 1/14/97 (with queueing)";
static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (with queueing)";
#else
static char sccsid[] = "@(#)queue.c 8.153 (Berkeley) 1/14/97 (without queueing)";
static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (without queueing)";
#endif
#endif /* not lint */
@ -99,7 +99,8 @@ queueup(e, announce)
register char *p;
MAILER nullmailer;
MCI mcibuf;
char buf[MAXLINE], tf[MAXLINE];
char tf[MAXQFNAME];
char buf[MAXLINE];
extern void printctladdr __P((ADDRESS *, FILE *));
/*
@ -125,21 +126,19 @@ queueup(e, announce)
{
if (errno != EEXIST)
break;
#ifdef LOG
if (LogLevel > 0 && (i % 32) == 0)
syslog(LOG_ALERT, "queueup: cannot create %s, uid=%d: %s",
sm_syslog(LOG_ALERT, e->e_id,
"queueup: cannot create %s, uid=%d: %s",
tf, geteuid(), errstring(errno));
#endif
}
else
{
if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB))
break;
#ifdef LOG
else if (LogLevel > 0 && (i % 32) == 0)
syslog(LOG_ALERT, "queueup: cannot lock %s: %s",
sm_syslog(LOG_ALERT, e->e_id,
"queueup: cannot lock %s: %s",
tf, errstring(errno));
#endif
close(fd);
}
@ -192,7 +191,7 @@ queueup(e, announce)
if (!bitset(EF_HAS_DF, e->e_flags))
{
register FILE *dfp = NULL;
char dfname[20];
char dfname[MAXQFNAME];
struct stat stbuf;
strcpy(dfname, queuename(e, 'd'));
@ -247,6 +246,11 @@ queueup(e, announce)
if (e->e_bodytype != NULL)
fprintf(tfp, "B%s\n", denlstring(e->e_bodytype, TRUE, FALSE));
#if _FFR_SAVE_CHARSET
if (e->e_charset != NULL)
fprintf(tfp, "X%s\n", denlstring(e->e_charset, TRUE, FALSE));
#endif
/* message from envelope, if it exists */
if (e->e_message != NULL)
fprintf(tfp, "M%s\n", denlstring(e->e_message, TRUE, FALSE));
@ -296,9 +300,9 @@ queueup(e, announce)
{
#if XDEBUG
if (bitset(QQUEUEUP, q->q_flags))
syslog(LOG_DEBUG,
"dropenvelope: %s: q_flags = %x, paddr = %s",
e->e_id, q->q_flags, q->q_paddr);
sm_syslog(LOG_DEBUG, e->e_id,
"dropenvelope: q_flags = %x, paddr = %s",
q->q_flags, q->q_paddr);
#endif
continue;
}
@ -453,11 +457,9 @@ queueup(e, announce)
errno = 0;
e->e_flags |= EF_INQUEUE;
# ifdef LOG
/* save log info */
if (LogLevel > 79)
syslog(LOG_DEBUG, "%s: queueup, qf=%s", e->e_id, qf);
# endif /* LOG */
sm_syslog(LOG_DEBUG, e->e_id, "queueup, qf=%s", qf);
if (tTd(40, 1))
printf("<<<<< done queueing %s <<<<<\n\n", e->e_id);
@ -537,6 +539,7 @@ printctladdr(a, tfp)
*/
ENVELOPE QueueEnvelope; /* the queue run envelope */
extern int get_num_procs_online __P((void));
bool
runqueue(forkflag, verbose)
@ -546,30 +549,45 @@ runqueue(forkflag, verbose)
register ENVELOPE *e;
int njobs;
int sequenceno = 0;
time_t current_la_time;
extern ENVELOPE BlankEnvelope;
extern void clrdaemon __P((void));
extern void runqueueevent __P((bool));
extern void runqueueevent __P((void));
extern void drop_privileges __P((void));
DoQueueRun = FALSE;
/*
** If no work will ever be selected, don't even bother reading
** the queue.
*/
CurrentLA = getla(); /* get load average */
current_la_time = curtime();
if (CurrentLA >= QueueLA)
if (shouldqueue(WkRecipFact, current_la_time))
{
char *msg = "Skipping queue run -- load average too high";
if (verbose)
message("458 %s\n", msg);
#ifdef LOG
if (LogLevel > 8)
syslog(LOG_INFO, "runqueue: %s", msg);
#endif
sm_syslog(LOG_INFO, NOQID,
"runqueue: %s",
msg);
if (forkflag && QueueIntvl != 0)
(void) setevent(QueueIntvl, runqueueevent, TRUE);
(void) setevent(QueueIntvl, runqueueevent, 0);
return FALSE;
}
/*
** See if we already have too many children.
*/
if (forkflag && QueueIntvl != 0 &&
MaxChildren > 0 && CurChildren >= MaxChildren)
{
(void) setevent(QueueIntvl, runqueueevent, 0);
return FALSE;
}
@ -596,12 +614,12 @@ runqueue(forkflag, verbose)
if (verbose)
message("458 %s: %s\n", msg, err);
#ifdef LOG
if (LogLevel > 8)
syslog(LOG_INFO, "runqueue: %s: %s", msg, err);
#endif
sm_syslog(LOG_INFO, NOQID,
"runqueue: %s: %s",
msg, err);
if (QueueIntvl != 0)
(void) setevent(QueueIntvl, runqueueevent, TRUE);
(void) setevent(QueueIntvl, runqueueevent, 0);
(void) releasesignal(SIGCHLD);
return FALSE;
}
@ -617,7 +635,7 @@ runqueue(forkflag, verbose)
releasesignal(SIGCHLD);
#endif /* SIGCHLD */
if (QueueIntvl != 0)
(void) setevent(QueueIntvl, runqueueevent, TRUE);
(void) setevent(QueueIntvl, runqueueevent, 0);
return TRUE;
}
/* child -- double fork and clean up signals */
@ -634,11 +652,10 @@ runqueue(forkflag, verbose)
setproctitle("running queue: %s", QueueDir);
# ifdef LOG
if (LogLevel > 69)
syslog(LOG_DEBUG, "runqueue %s, pid=%d, forkflag=%d",
sm_syslog(LOG_DEBUG, NOQID,
"runqueue %s, pid=%d, forkflag=%d",
QueueDir, getpid(), forkflag);
# endif /* LOG */
/*
** Release any resources used by the daemon code.
@ -665,7 +682,10 @@ runqueue(forkflag, verbose)
/* make sure we have disconnected from parent */
if (forkflag)
{
disconnect(1, e);
OnlyOneError = QuickAbort = FALSE;
}
/*
** Make sure the alias database is open.
@ -705,17 +725,52 @@ runqueue(forkflag, verbose)
/*
** Ignore jobs that are too expensive for the moment.
**
** Get new load average every 30 seconds.
*/
if (current_la_time < curtime() - 30)
{
CurrentLA = getla();
current_la_time = curtime();
}
if (shouldqueue(WkRecipFact, current_la_time))
{
char *msg = "Aborting queue run: load average too high";
if (Verbose)
message("%s", msg);
if (LogLevel > 8)
sm_syslog(LOG_INFO, NOQID,
"runqueue: %s",
msg);
break;
}
sequenceno++;
if (shouldqueue(w->w_pri, w->w_ctime))
{
if (Verbose)
{
message("");
if (QueueSortOrder == QS_BYPRIORITY)
{
if (Verbose)
message("Skipping %s (sequence %d of %d) and flushing rest of queue",
w->w_name + 2,
sequenceno,
njobs);
if (LogLevel > 8)
sm_syslog(LOG_INFO, NOQID,
"runqueue: Flushing queue from %s (pri %ld, LA %d, %d of %d)",
w->w_name + 2,
w->w_pri,
CurrentLA,
sequenceno,
njobs);
break;
}
else if (Verbose)
message("Skipping %s (sequence %d of %d)",
w->w_name + 2, sequenceno, njobs);
}
}
else
{
@ -752,10 +807,9 @@ runqueue(forkflag, verbose)
*/
void
runqueueevent(forkflag)
bool forkflag;
runqueueevent()
{
(void) runqueue(forkflag, FALSE);
DoQueueRun = TRUE;
}
/*
** ORDERQ -- order the work queue.
@ -843,6 +897,9 @@ orderq(doall)
if (d->d_name[0] != 'q' || d->d_name[1] != 'f')
continue;
if (strlen(d->d_name) > MAXQFNAME)
continue;
if (QueueLimitId != NULL &&
!strcontainedin(QueueLimitId, d->d_name))
continue;
@ -866,11 +923,10 @@ orderq(doall)
{
if (Verbose)
printf("orderq: bogus qf name %s\n", d->d_name);
# ifdef LOG
if (LogLevel > 0)
syslog(LOG_ALERT, "orderq: bogus qf name %s",
sm_syslog(LOG_ALERT, NOQID,
"orderq: bogus qf name %s",
d->d_name);
# endif
if (strlen(d->d_name) > (SIZE_T) MAXNAME)
d->d_name[MAXNAME] = '\0';
strcpy(lbuf, d->d_name);
@ -883,11 +939,10 @@ orderq(doall)
/* open control file (if not too many files) */
if (++wn >= MaxQueueRun && MaxQueueRun > 0)
{
# ifdef LOG
if (wn == MaxQueueRun && LogLevel > 0)
syslog(LOG_ALERT, "WorkList for %s maxed out at %d",
QueueDir, MaxQueueRun);
# endif
sm_syslog(LOG_ALERT, NOQID,
"WorkList for %s maxed out at %d",
QueueDir, MaxQueueRun);
continue;
}
if (wn >= WorkListSize)
@ -930,8 +985,20 @@ orderq(doall)
while (i != 0 && fgets(lbuf, sizeof lbuf, cf) != NULL)
{
int qfver = 0;
char *p;
int c;
extern bool strcontainedin();
p = strchr(lbuf, '\n');
if (p != NULL)
*p = '\0';
else
{
/* flush rest of overly long line */
while ((c = getc(cf)) != EOF && c != '\n')
continue;
}
switch (lbuf[0])
{
case 'V':
@ -1140,18 +1207,18 @@ grow_wlist()
{
WorkListSize = newsize;
WorkList = newlist;
# ifdef LOG
if (LogLevel > 1)
{
syslog(LOG_NOTICE, "grew WorkList for %s to %d",
QueueDir, WorkListSize);
sm_syslog(LOG_NOTICE, NOQID,
"grew WorkList for %s to %d",
QueueDir, WorkListSize);
}
}
else if (LogLevel > 0)
{
syslog(LOG_ALERT, "FAILED to grow WorkList for %s to %d",
QueueDir, newsize);
# endif
sm_syslog(LOG_ALERT, NOQID,
"FAILED to grow WorkList for %s to %d",
QueueDir, newsize);
}
}
if (tTd(41, 1))
@ -1347,6 +1414,11 @@ dowork(id, forkflag, requeueflag, e)
/* parent -- clean out connection cache */
mci_flush(FALSE, NULL);
}
else
{
/* child -- error messages to the transcript */
QuickAbort = OnlyOneError = FALSE;
}
}
else
{
@ -1378,11 +1450,10 @@ dowork(id, forkflag, requeueflag, e)
OpMode = MD_DELIVER;
}
setproctitle("%s: from queue", id);
# ifdef LOG
if (LogLevel > 76)
syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id,
getpid());
# endif /* LOG */
sm_syslog(LOG_DEBUG, e->e_id,
"dowork, pid=%d",
getpid());
/* don't use the headers from sendmail.cf... */
e->e_header = NULL;
@ -1443,7 +1514,7 @@ readqf(e)
register char *p;
char *orcpt = NULL;
bool nomore = FALSE;
char qf[20];
char qf[MAXQFNAME];
char buf[MAXLINE];
extern ADDRESS *setctluser __P((char *, int));
@ -1468,10 +1539,8 @@ readqf(e)
/* being processed by another queuer */
if (Verbose || tTd(40, 8))
printf("%s: locked\n", e->e_id);
# ifdef LOG
if (LogLevel > 19)
syslog(LOG_DEBUG, "%s: locked", e->e_id);
# endif /* LOG */
sm_syslog(LOG_DEBUG, e->e_id, "locked");
(void) fclose(qfp);
return FALSE;
}
@ -1493,13 +1562,12 @@ readqf(e)
if ((st.st_uid != geteuid() && geteuid() != RealUid) ||
bitset(S_IWOTH|S_IWGRP, st.st_mode))
{
# ifdef LOG
if (LogLevel > 0)
{
syslog(LOG_ALERT, "%s: bogus queue file, uid=%d, mode=%o",
e->e_id, st.st_uid, st.st_mode);
sm_syslog(LOG_ALERT, e->e_id,
"bogus queue file, uid=%d, mode=%o",
st.st_uid, st.st_mode);
}
# endif /* LOG */
if (tTd(40, 8))
printf("readqf(%s): bogus file\n", qf);
loseqfile(e, "bogus file uid in mqueue");
@ -1509,11 +1577,14 @@ readqf(e)
if (st.st_size == 0)
{
/* must be a bogus file -- just remove it */
qf[0] = 'd';
(void) unlink(qf);
qf[0] = 'q';
(void) unlink(qf);
/* must be a bogus file -- if also old, just remove it */
if (st.st_ctime + 10 * 60 < curtime())
{
qf[0] = 'd';
(void) unlink(qf);
qf[0] = 'q';
(void) unlink(qf);
}
fclose(qfp);
return FALSE;
}
@ -1636,6 +1707,7 @@ readqf(e)
hdrsize += strlen(&bp[1]);
break;
case 'L': /* Solaris Content-Length: */
case 'M': /* message */
/* ignore this; we want a new message next time */
break;
@ -1648,6 +1720,12 @@ readqf(e)
e->e_bodytype = newstr(&bp[1]);
break;
#if _FFR_SAVE_CHARSET
case 'X': /* character set */
e->e_charset = newstr(&bp[1]);
break;
#endif
case 'D': /* data file name */
/* obsolete -- ignore */
break;
@ -1669,7 +1747,7 @@ readqf(e)
/* if this has been tried recently, let it be */
if (e->e_ntries > 0 &&
(curtime() - e->e_dtime) < MinQueueAge)
curtime() < e->e_dtime + MinQueueAge)
{
char *howlong = pintvl(curtime() - e->e_dtime, TRUE);
extern void unlockqueue();
@ -1677,11 +1755,10 @@ readqf(e)
if (Verbose || tTd(40, 8))
printf("%s: too young (%s)\n",
e->e_id, howlong);
#ifdef LOG
if (LogLevel > 19)
syslog(LOG_DEBUG, "%s: too young (%s)",
e->e_id, howlong);
#endif
sm_syslog(LOG_DEBUG, e->e_id,
"too young (%s)",
howlong);
e->e_id = NULL;
unlockqueue(e);
return FALSE;
@ -1822,7 +1899,7 @@ printqueue()
struct stat st;
# ifdef NGROUPS_MAX
int n;
GIDSET_T gidset[NGROUPS_MAX];
extern GIDSET_T InitialGidSet[NGROUPS_MAX];
# endif
if (stat(QueueDir, &st) < 0)
@ -1831,10 +1908,10 @@ printqueue()
return;
}
# ifdef NGROUPS_MAX
n = getgroups(NGROUPS_MAX, gidset);
n = NGROUPS_MAX;
while (--n >= 0)
{
if (gidset[n] == st.st_gid)
if (InitialGidSet[n] == st.st_gid)
break;
}
if (n < 0 && RealGid != st.st_gid)
@ -2037,7 +2114,7 @@ queuename(e, type)
if (e->e_id == NULL)
{
char qf[20];
char qf[MAXQFNAME];
/* find a unique id */
if (pid != getpid())
@ -2100,10 +2177,8 @@ queuename(e, type)
printf(" lockfd=");
dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
}
# ifdef LOG
if (LogLevel > 93)
syslog(LOG_DEBUG, "%s: assigned id", e->e_id);
# endif /* LOG */
sm_syslog(LOG_DEBUG, e->e_id, "assigned id");
}
if (type == '\0')
@ -2144,10 +2219,8 @@ unlockqueue(e)
return;
/* remove the transcript */
# ifdef LOG
if (LogLevel > 87)
syslog(LOG_DEBUG, "%s: unlock", e->e_id);
# endif /* LOG */
sm_syslog(LOG_DEBUG, e->e_id, "unlock");
if (!tTd(51, 104))
xunlink(queuename(e, 'x'));
@ -2252,7 +2325,7 @@ loseqfile(e, why)
char *why;
{
char *p;
char buf[40];
char buf[MAXQFNAME];
if (e == NULL || e->e_id == NULL)
return;
@ -2262,8 +2335,7 @@ loseqfile(e, why)
p = queuename(e, 'Q');
if (rename(buf, p) < 0)
syserr("cannot rename(%s, %s), uid=%d", buf, p, geteuid());
#ifdef LOG
else if (LogLevel > 0)
syslog(LOG_ALERT, "Losing %s: %s", buf, why);
#endif
sm_syslog(LOG_ALERT, e->e_id,
"Losing %s: %s", buf, why);
}

View File

@ -0,0 +1,686 @@
/*
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* 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.
*/
#ifndef lint
static char sccsid[] = "@(#)safefile.c 8.12 (Berkeley) 6/14/97";
#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>
#ifndef S_IXOTH
# define S_IXOTH (S_IEXEC >> 6)
#endif
#ifndef S_IXGRP
# define S_IXGRP (S_IEXEC >> 3)
#endif
#ifndef S_IXUSR
# define S_IXUSR (S_IEXEC)
#endif
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;
/* 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)
#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
{
/* 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)
md >>= 6;
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 %o]\tE_SM_NOSLINK\n",
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 %o]\tE_SM_REGONLY\n",
st->st_mode);
return E_SM_REGONLY;
}
if (bitset(SFF_NOWFILES, flags) &&
bitset(S_IWOTH | (UnsafeGroupWrites ? S_IWGRP : 0), st->st_mode))
{
if (tTd(44, 4))
printf("\t[write bits %o]\tE_SM_%cWFILE\n",
st->st_mode,
bitset(S_IWOTH, st->st_mode) ? 'W' : 'G');
return bitset(S_IWOTH, st->st_mode) ? E_SM_WWFILE : E_SM_GWFILE;
}
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 %o]\tE_SM_ISEXEC]\n",
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",
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)
{
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 ||
!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;
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);
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(S_IWGRP|S_IWOTH, stbuf.st_mode))
{
if (tTd(44, 4))
printf("\t[dir %s] mode %o\n",
fn, 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: writable directory %s", fn);
}
if (uid == 0 && !bitset(SFF_ROOTOK|SFF_OPENASROOT, flags))
{
if (bitset(S_IXOTH, stbuf.st_mode))
continue;
ret = EACCES;
break;
}
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;
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)
omode |= O_EXCL;
fd = dfopen(fn, omode, cmode, sff);
if (fd < 0)
return fd;
if (filechanged(fn, fd, &stb, sff))
{
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)
return NULL;
fp = fdopen(fd, fmode);
if (fp != NULL)
return fp;
(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.
** sff -- safe file flags.
**
** Returns:
** TRUE -- if a problem was detected.
** FALSE -- if this file is still the same.
*/
bool
filechanged(fn, fd, stb, sff)
char *fn;
int fd;
struct stat *stb;
int sff;
{
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 ||
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);
printf(" ino = %ld/%ld\n",
(long) stb->st_ino, (long) sta.st_ino);
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;
}

View File

@ -1,9 +1,9 @@
cpyr
cpyr Copyright (c) 1983, 1995, 1996 Eric P. Allman
cpyr Copyright (c) 1983, 1995-1997 Eric P. Allman
cpyr Copyright (c) 1988, 1993
cpyr The Regents of the University of California. All rights reserved.
cpyr
cpyr @(#)sendmail.hf 8.11 (Berkeley) 9/11/96
cpyr @(#)sendmail.hf 8.12 (Berkeley) 2/1/97
cpyr
smtp Topics:
smtp HELO EHLO MAIL RCPT DATA

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)stab.c 8.10 (Berkeley) 11/23/96";
static char sccsid[] = "@(#)stab.c 8.13 (Berkeley) 4/19/97";
#endif /* not lint */
# include "sendmail.h"
@ -131,11 +131,7 @@ stab(name, type, op)
printf("entered\n");
/* determine size of new entry */
#ifdef _FFR_MEMORY_MISER
if (type >= ST_MCI)
len = sizeof s->s_mci;
else
len = -1;
#if _FFR_MEMORY_MISER
switch (type)
{
case ST_CLASS:
@ -180,11 +176,20 @@ stab(name, type, op)
case ST_SERVICE:
len = sizeof s->s_service;
break;
}
if (len < 0)
{
syserr("stab: unknown symbol type %d", type);
len = sizeof s->s_value;
case ST_HEADER:
len = sizeof s->s_header;
break;
default:
if (type >= ST_MCI)
len = sizeof s->s_mci;
else
{
syserr("stab: unknown symbol type %d", type);
len = sizeof s->s_value;
}
break;
}
len += sizeof *s - sizeof s->s_value;
#else

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)stats.c 8.6 (Berkeley) 2/21/96";
static char sccsid[] = "@(#)stats.c 8.11 (Berkeley) 4/9/97";
#endif /* not lint */
# include "sendmail.h"
@ -97,13 +97,12 @@ poststats(sfile)
(void) time(&Stat.stat_itime);
Stat.stat_size = sizeof Stat;
fd = open(sfile, O_RDWR);
fd = safeopen(sfile, O_RDWR, 0644, SFF_REGONLY|SFF_NOLINK|SFF_OPENASROOT);
if (fd < 0)
{
errno = 0;
return;
}
(void) lockfile(fd, sfile, NULL, LOCK_EX);
if (read(fd, (char *) &stat, sizeof stat) == sizeof stat &&
stat.stat_size == sizeof stat)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)sysexits.c 8.6 (Berkeley) 2/21/96";
static char sccsid[] = "@(#)sysexits.c 8.7 (Berkeley) 2/1/97";
#endif /* not lint */
#include <sendmail.h>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1983, 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)trace.c 8.5 (Berkeley) 2/21/96";
static char sccsid[] = "@(#)trace.c 8.6 (Berkeley) 2/1/97";
#endif /* not lint */
# include "sendmail.h"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 1996 Eric P. Allman
* Copyright (c) 1995-1997 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@ -31,15 +31,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)useful.h 8.5 (Berkeley) 2/21/96
* @(#)useful.h 8.7 (Berkeley) 5/29/97
*/
# 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

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)version.c 8.8.5.3 (Berkeley) 1/21/97";
static char sccsid[] = "@(#)version.c 8.8.6.1 (Berkeley) 6/14/97";
#endif /* not lint */
char Version[] = "8.8.5";
char Version[] = "8.8.6";

View File

@ -47,6 +47,7 @@ IRIX 4.0.4 OK 93.09.25 Robert Elz
IRIX 5.2 OK 94.12.06 Mark Andrews <mandrews@alias.com>
IRIX 5.3 OK 94.12.06 Mark Andrews <mandrews@alias.com>
IRIX 6.2 OK 96.09.16 Kari E. Hurtta <Kari.Hurtta@ozone.FMI.FI>
IRIX 6.3 OK 97.02.10 Mark Andrews <mandrews@aw.sgi.com>
SCO 3.2v4.0 OK 93.10.02 Peter Wemm (with -lsocket from 3.2v4 devsys)
@ -86,6 +87,7 @@ AIX 4.1 OK 96.10.21 Hakan Lindholm <hakan@af.lu.se>
IRIX 5.2 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com>
IRIX 5.3 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com>
IRIX 6.2 OK 96.09.16 Kari E. Hurtta <Kari.Hurtta@ozone.FMI.FI>
IRIX 6.3 OK 97.02.10 Mark Andrews <mandrews@aw.sgi.com>
FreeBSD 2.1-sta OK 96.04.14 Jaye Mathisen <mrcpu@cdsnet.net>
@ -95,3 +97,60 @@ OSF/1 3.2D OK 96.09.18 Gregory Neil Shapiro <gshapiro@wpi.edu>
OSF/1 4.0 OK 96.09.18 Gregory Neil Shapiro <gshapiro@wpi.edu>
CxOS 11.5 FAIL 96.07.08 Eric Schnoebelen <eric@cirr.com>
The following are the results of running t_pathconf.c. Safe means that
the underlying filesystem (in NFS, the filesystem on the server) does not
permit regular (non-root) users to chown their files to another user.
Unsafe means that they can. Typically, BSD-based systems do not permit
giveaway and System V-based systems do. However, some systems (e.g.,
Solaris) can set this on a per-system or per-filesystem basis. Entries
are the return value of pathconf, the errno value, and a * if chown
disagreed with the result of the pathconf call, and a ? if the test has
not been run. A mark of [R] means that the local filesystem has
chown set to be restricted, [U] means that it is set to be unrestricted.
Safe Filesystem Unsafe Filesystem
SYSTEM LOCAL NFS-V2 NFS-V3 NFS-V2 NFS-V3
SunOS 4.1.3_U1 1/0 -1/EINVAL* n/a -1/EINVAL? n/a
SunOS 4.1.4 1/0 -1/EINVAL* n/a -1/EINVAL n/a
AIX 3.2 0/0 0/0
Solaris 2.4 1/0 -1/EINVAL*
Solaris 2.5 1/0 -1/EINVAL* 1/0 0/0?
Solaris 2.5.1 1/0 -1/EINVAL* 0/0
DEC OSF1 3.0 0/0 0/0
DEC OSF1 3.2D-2 0/0 0/0 0/0
DEC OSF1 4.0A 0/0 0/0 0/0
DEC OSF 4.0B 0/0 0/0 0/0
Ultrix 4.3 0/0 0/0 n/a n/a
Ultrix 4.5 1/0 1/0
HP-UX 9.05 -1/0 -1/EOPNOTSUPP* -1/EOPNOTSUPP
HP-UX 9.05[R] 1/0 -1/EOPNOTSUPP* -1/EOPNOTSUPP*
HP-UX 10.10 -1/0 -1/EOPNOTSUPP* -1/EOPNOTSUPP
HP-UX 10.20 -1/EOPNOTSUPP? -1/EOPNOTSUPP?
HP-UX 10.30 -1/0 -1/EOPNOTSUPP -1/EOPNOTSUPP
BSD/OS 2.1 1/0
FreeBSD 2.1.7 1/0 -1/EINVAL* -1/EINVAL
Irix 5.3 -1/0* -1/0
Irix 6.2 1/0 -1/0 0/0*
Irix 6.2 -1/0 -1/0
Irix 6.3 R10000 -1/0 -1/0 0/0*
A/UX 3.1.1 1/0
DomainOS [R] -1/0*
DomainOS [U] -1/0
NCR MP-RAS 2 -1/0
NCR MP-RAS 3 -1/0
Linux 2.0.27 1/0 1/0

View File

@ -0,0 +1,63 @@
/*
** The following test program tries the pathconf(2) routine. It should
** be run in a non-NFS-mounted directory (e.g., /tmp) and on remote (NFS)
** mounted directories running both NFS-v2 and NFS-v3 from systems that
** both do and do not permit file giveaway.
*/
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sysexits.h>
main()
{
int fd;
int i;
char tbuf[100];
extern int errno;
if (geteuid() == 0)
{
printf("*** Run me as a non-root user! ***\n");
exit(EX_USAGE);
}
strcpy(tbuf, "TXXXXXX");
fd = mkstemp(tbuf);
if (fd < 0)
{
printf("*** Could not create test file %s\n", tbuf);
exit(EX_CANTCREAT);
}
errno = 0;
i = pathconf(".", _PC_CHOWN_RESTRICTED);
printf("pathconf(.) returns %2d, errno = %d\n", i, errno);
errno = 0;
i = pathconf(tbuf, _PC_CHOWN_RESTRICTED);
printf("pathconf(%s) returns %2d, errno = %d\n", tbuf, i, errno);
errno = 0;
i = fpathconf(fd, _PC_CHOWN_RESTRICTED);
printf("fpathconf(%s) returns %2d, errno = %d\n", tbuf, i, errno);
if (errno == 0 && i >= 0)
{
/* so it claims that it doesn't work -- try anyhow */
printf(" fpathconf claims that chown is safe ");
if (fchown(fd, 1, 1) >= 0)
printf("*** but fchown works anyhow! ***\n");
else
printf("and fchown agrees\n");
}
else
{
/* well, let's see what really happens */
printf(" fpathconf claims that chown is not safe ");
if (fchown(fd, 1, 1) >= 0)
printf("as indeed it is not\n");
else
printf("*** but in fact it is safe ***\n");
}
unlink(tbuf);
exit(EX_OK);
}