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:
commit
91453f6a62
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=26987
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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$@ $@ :; <@>
|
||||
|
@ -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 ###
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
41
usr.sbin/sendmail/cf/ostype/gnuhurd.m4
Normal file
41
usr.sbin/sendmail/cf/ostype/gnuhurd.m4
Normal 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
|
61
usr.sbin/sendmail/cf/ostype/irix6.m4
Normal file
61
usr.sbin/sendmail/cf/ostype/irix6.m4
Normal 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
|
@ -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
|
||||
|
28
usr.sbin/sendmail/contrib/passwd-to-alias.pl
Normal file
28
usr.sbin/sendmail/contrib/passwd-to-alias.pl
Normal 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;
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
686
usr.sbin/sendmail/src/safefile.c
Normal file
686
usr.sbin/sendmail/src/safefile.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
63
usr.sbin/sendmail/test/t_pathconf.c
Normal file
63
usr.sbin/sendmail/test/t_pathconf.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user