mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
Import sendmail-8.8.6
Obtained from: ftp.sendmail.org
This commit is contained in:
parent
52c4d6f5d6
commit
f3a1fc342b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/sendmail/dist-old/; revision=26986
|
@ -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
|
||||
|
|
|
@ -38,7 +38,7 @@ divert(-1)
|
|||
#
|
||||
|
||||
divert(0)dnl
|
||||
VERSIONID(`@(#)knecht.mc 8.4 (Berkeley) 11/24/96')
|
||||
VERSIONID(`@(#)knecht.mc 8.11 (Berkeley) 6/12/97')
|
||||
OSTYPE(bsd4.4)dnl
|
||||
DOMAIN(generic)dnl
|
||||
define(`confDEF_USER_ID', `mailnull')dnl
|
||||
|
@ -46,6 +46,49 @@ define(`confHOST_STATUS_DIRECTORY', `.hoststat')dnl
|
|||
define(`confTO_ICONNECT', `10s')dnl
|
||||
define(`confCOPY_ERRORS_TO', `Postmaster')dnl
|
||||
define(`confTO_QUEUEWARN', `8h')dnl
|
||||
define(`confPRIVACY_FLAGS', ``authwarnings,noexpn,novrfy'')dnl
|
||||
FEATURE(virtusertable)dnl
|
||||
MAILER(local)dnl
|
||||
MAILER(smtp)dnl
|
||||
|
||||
LOCAL_CONFIG
|
||||
# domains that are not us but which we will relay
|
||||
FR-o /etc/sendmail.cR
|
||||
|
||||
# domain override table to accept unresolvable/reject resolvable domains
|
||||
Kdomaincheck hash -o /etc/domaincheck
|
||||
|
||||
|
||||
LOCAL_RULESETS
|
||||
|
||||
# reject bogus return addresses
|
||||
Scheck_mail
|
||||
R<> $@ <OK>
|
||||
R$* $: <?> $>Parse0 $>3 $1 make domain canonical
|
||||
R<?> $* < @ $+ . > $* $: < $( domaincheck $2 $: OK $) > $1 < @ $2 . > $3
|
||||
tag resolved names
|
||||
R<?> $* < @ $+ > $* $: < $( domaincheck $2 $: ? $) > $1 < @ $2 > $3
|
||||
check for overrides
|
||||
R<OK> $* $@ <OK>
|
||||
R<?> $* < @ $+ > $* $#error $: 451 Sender domain must resolve
|
||||
R<?> $* $: < ? $&{client_name} > $1 no @domain on address...
|
||||
R<?> $* $@ <OK> ...local unqualed ok
|
||||
R<? $+> $* $#error $: 551 Domain name required
|
||||
...remote is not
|
||||
R<$+> $* $#error $: $1 error from domaincheck
|
||||
|
||||
# disallow relaying
|
||||
Scheck_rcpt
|
||||
# anything terminating locally is ok
|
||||
R$* $: $>Parse0 $>3 $1 strip local crud
|
||||
R$+ < @ $=w . > $@ OK
|
||||
R$+ < @ $* $=R . > $@ OK
|
||||
|
||||
# anything originating locally is ok
|
||||
R$* $: $(dequote "" $&{client_name} $)
|
||||
R$=w $@ OK
|
||||
R$=R $@ OK
|
||||
R$@ $@ OK
|
||||
|
||||
# anything else is bogus
|
||||
R$* $#error $: "550 Relaying Denied"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -38,7 +38,7 @@ static char copyright[] =
|
|||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mail.local.c 8.34 (Berkeley) 11/24/96";
|
||||
static char sccsid[] = "@(#)mail.local.c 8.39 (Berkeley) 5/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -86,6 +86,7 @@ static char sccsid[] = "@(#)mail.local.c 8.34 (Berkeley) 11/24/96";
|
|||
|
||||
#if defined(_AIX)
|
||||
# define USE_LOCKF 1
|
||||
# define USET_SETEUID 1
|
||||
# define USE_VSYSLOG 0
|
||||
#endif
|
||||
|
||||
|
@ -146,9 +147,17 @@ static char sccsid[] = "@(#)mail.local.c 8.34 (Berkeley) 11/24/96";
|
|||
# define _BSD_VA_LIST_ va_list
|
||||
#endif
|
||||
|
||||
#if defined(BSD4_4) || defined(linux)
|
||||
# define HASSNPRINTF 1
|
||||
#endif
|
||||
|
||||
#if SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206)
|
||||
# define HASSNPRINTF 1 /* has snprintf starting in 2.6 */
|
||||
#endif
|
||||
|
||||
#if !defined(BSD4_4) && !defined(linux)
|
||||
extern char *strerror __P((int));
|
||||
extern int snprintf __P((char *, int, const char *, ...));
|
||||
extern int snprintf __P((char *, size_t, const char *, ...));
|
||||
extern FILE *fdopen __P((int, const char *));
|
||||
#endif
|
||||
|
||||
|
@ -374,9 +383,13 @@ deliver(fd, name)
|
|||
*/
|
||||
tryagain:
|
||||
lockmbox(path);
|
||||
if (lstat(path, &sb)) {
|
||||
if (lstat(path, &sb) < 0) {
|
||||
mbfd = open(path,
|
||||
O_APPEND|O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
|
||||
if (lstat(path, &sb) < 0)
|
||||
goto filechanged;
|
||||
else
|
||||
sb.st_uid = pw->pw_uid;
|
||||
if (mbfd == -1) {
|
||||
if (errno == EEXIST)
|
||||
goto tryagain;
|
||||
|
@ -395,20 +408,20 @@ deliver(fd, name)
|
|||
goto err0;
|
||||
} else {
|
||||
mbfd = open(path, O_APPEND|O_WRONLY, 0);
|
||||
if (mbfd != -1 &&
|
||||
(fstat(mbfd, &fsb) || fsb.st_nlink != 1 ||
|
||||
!S_ISREG(fsb.st_mode) || sb.st_dev != fsb.st_dev ||
|
||||
sb.st_ino != fsb.st_ino || sb.st_uid != fsb.st_uid)) {
|
||||
eval = EX_CANTCREAT;
|
||||
warn("%s: file changed after open", path);
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mbfd == -1) {
|
||||
e_to_sys(errno);
|
||||
warn("%s: %s", path, strerror(errno));
|
||||
goto err0;
|
||||
} else if (fstat(mbfd, &fsb) < 0 ||
|
||||
fsb.st_nlink != 1 || sb.st_nlink != 1 ||
|
||||
!S_ISREG(fsb.st_mode) || sb.st_dev != fsb.st_dev ||
|
||||
sb.st_ino != fsb.st_ino || sb.st_uid != fsb.st_uid) {
|
||||
filechanged:
|
||||
eval = EX_CANTCREAT;
|
||||
warn("%s: file changed after open", path);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
/* Wait until we can get a lock on the file. */
|
||||
|
@ -474,9 +487,9 @@ err0: unlockmbox();
|
|||
if (close(mbfd)) {
|
||||
e_to_sys(errno);
|
||||
warn("%s: %s", path, strerror(errno));
|
||||
unlockmbox();
|
||||
return;
|
||||
}
|
||||
truncate(path, curoff);
|
||||
} else
|
||||
notifybiff(biffmsg);
|
||||
|
||||
if (setreuid(0, 0) < 0) {
|
||||
e_to_sys(errno);
|
||||
|
@ -486,7 +499,6 @@ err0: unlockmbox();
|
|||
printf("reset euid = %d\n", geteuid());
|
||||
#endif
|
||||
unlockmbox();
|
||||
notifybiff(biffmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -507,6 +519,8 @@ lockmbox(path)
|
|||
|
||||
if (locked)
|
||||
return;
|
||||
if (strlen(path) + 6 > sizeof lockname)
|
||||
return;
|
||||
sprintf(lockname, "%s.lock", path);
|
||||
for (;; sleep(5)) {
|
||||
int fd;
|
||||
|
@ -761,16 +775,16 @@ strerror(eno)
|
|||
return ebuf;
|
||||
}
|
||||
|
||||
# endif
|
||||
#endif /* !defined(BSD4_4) && !defined(__osf__) */
|
||||
|
||||
#if !defined(BSD4_4) && !defined(linux)
|
||||
#if !HASSNPRINTF
|
||||
|
||||
# if __STDC__
|
||||
snprintf(char *buf, int bufsiz, const char *fmt, ...)
|
||||
snprintf(char *buf, size_t bufsiz, const char *fmt, ...)
|
||||
# else
|
||||
snprintf(buf, bufsiz, fmt, va_alist)
|
||||
char *buf;
|
||||
int bufsiz;
|
||||
size_t bufsiz;
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
# endif
|
||||
|
@ -786,7 +800,7 @@ snprintf(buf, bufsiz, fmt, va_alist)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !HASSNPRINTF */
|
||||
|
||||
#ifdef ultrix
|
||||
|
||||
|
@ -879,7 +893,7 @@ _gettemp(path, doopen)
|
|||
break;
|
||||
if (*trv == '/') {
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
if (stat(path, &sbuf) < 0)
|
||||
return(0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
|
@ -898,7 +912,7 @@ _gettemp(path, doopen)
|
|||
if (errno != EEXIST)
|
||||
return(0);
|
||||
}
|
||||
else if (stat(path, &sbuf))
|
||||
else if (stat(path, &sbuf) < 0)
|
||||
return(errno == ENOENT ? 1 : 0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
|
@ -919,4 +933,4 @@ _gettemp(path, doopen)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* ultrix */
|
||||
|
|
|
@ -40,7 +40,7 @@ static char copyright[] =
|
|||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mailstats.c 8.8 (Berkeley) 9/25/96";
|
||||
static char sccsid[] = "@(#)mailstats.c 8.10 (Berkeley) 5/30/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#define NOT_SENDMAIL
|
||||
|
@ -66,7 +66,7 @@ main(argc, argv)
|
|||
bool mnames;
|
||||
long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0;
|
||||
char mtable[MAXMAILERS][MNAMELEN+1];
|
||||
char sfilebuf[100];
|
||||
char sfilebuf[MAXLINE];
|
||||
char buf[MAXLINE];
|
||||
extern char *ctime();
|
||||
|
||||
|
@ -145,6 +145,13 @@ main(argc, argv)
|
|||
}
|
||||
|
||||
/* this is the S or StatusFile option -- save it */
|
||||
if (strlen(b) >= sizeof sfilebuf)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"StatusFile filename too long: %.30s...\n",
|
||||
s);
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
strcpy(sfilebuf, b);
|
||||
b = strchr(sfilebuf, '#');
|
||||
if (b == NULL)
|
||||
|
|
13
usr.sbin/sendmail/makemap/Makefile
Normal file
13
usr.sbin/sendmail/makemap/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
# @(#)Makefile 8.4 (Berkeley) 6/10/97
|
||||
|
||||
PROG= makemap
|
||||
MAN8= makemap.0
|
||||
CFLAGS+=-I${.CURDIR}/../src -DNEWDB -DNOT_SENDMAIL
|
||||
|
||||
SRCS= makemap.c safefile.c
|
||||
|
||||
safefile.c: ${.CURDIR}/../src/safefile.c
|
||||
ln -s ${.CURDIR}/../src/safefile.c
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
|
@ -33,21 +33,15 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)makemap.c 8.19 (Berkeley) 11/18/96";
|
||||
static char sccsid[] = "@(#)makemap.c 8.35 (Berkeley) 6/10/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sysexits.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#ifndef ISC_UNIX
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#define NOT_SENDMAIL
|
||||
#include "useful.h"
|
||||
#include "conf.h"
|
||||
#include "sendmail.h"
|
||||
|
||||
#ifdef NDBM
|
||||
#include <ndbm.h>
|
||||
|
@ -74,6 +68,17 @@ union dbent
|
|||
} xx;
|
||||
};
|
||||
|
||||
uid_t RealUid;
|
||||
gid_t RealGid;
|
||||
char *RealUserName;
|
||||
uid_t RunAsUid;
|
||||
uid_t RunAsGid;
|
||||
char *RunAsUserName;
|
||||
int Verbose = 2;
|
||||
bool DontInitGroups = TRUE;
|
||||
bool UnsafeGroupWrites = FALSE;
|
||||
u_char tTdvect[100];
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
main(argc, argv)
|
||||
|
@ -87,12 +92,12 @@ main(argc, argv)
|
|||
bool allowdups = FALSE;
|
||||
bool verbose = FALSE;
|
||||
bool foldcase = TRUE;
|
||||
bool ignoresafeties = FALSE;
|
||||
int exitstat;
|
||||
int opt;
|
||||
char *typename;
|
||||
char *mapname;
|
||||
char *ext;
|
||||
char *lext;
|
||||
int lineno;
|
||||
int st;
|
||||
int mode;
|
||||
|
@ -117,15 +122,33 @@ main(argc, argv)
|
|||
#endif
|
||||
char ibuf[BUFSIZE];
|
||||
char fbuf[MAXNAME];
|
||||
char lbuf[MAXNAME];
|
||||
char dbuf[MAXNAME];
|
||||
char pbuf[MAXNAME];
|
||||
static char rnamebuf[MAXNAME]; /* holds RealUserName */
|
||||
struct passwd *pw;
|
||||
int sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOLINK|SFF_NOWLINK;
|
||||
struct stat std, stp;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern bool lockfile();
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
#ifdef FFR_CFLAG
|
||||
#define OPTIONS "Nc:dforv"
|
||||
RunAsUid = RealUid = getuid();
|
||||
RunAsGid = RealGid = getgid();
|
||||
pw = getpwuid(RealUid);
|
||||
if (pw != NULL)
|
||||
{
|
||||
if (strlen(pw->pw_name) > MAXNAME - 1)
|
||||
pw->pw_name[MAXNAME] = 0;
|
||||
sprintf(rnamebuf, "%s", pw->pw_name);
|
||||
}
|
||||
else
|
||||
sprintf(rnamebuf, "Unknown UID %d", RealUid);
|
||||
RunAsUserName = RealUserName = rnamebuf;
|
||||
|
||||
#if _FFR_NEW_MAKEMAP_FLAGS
|
||||
#define OPTIONS "Nc:dforsv"
|
||||
#else
|
||||
#define OPTIONS "Ndforv"
|
||||
#endif
|
||||
|
@ -137,7 +160,7 @@ main(argc, argv)
|
|||
inclnull = TRUE;
|
||||
break;
|
||||
|
||||
#ifdef FFR_CFLAG
|
||||
#if _FFR_NEW_MAKEMAP_FLAGS
|
||||
case 'c':
|
||||
dbcachesize = atol(optarg);
|
||||
break;
|
||||
|
@ -159,6 +182,12 @@ main(argc, argv)
|
|||
allowreplace = TRUE;
|
||||
break;
|
||||
|
||||
#if _FFR_NEW_MAKEMAP_FLAGS
|
||||
case 's':
|
||||
ignoresafeties = TRUE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'v':
|
||||
verbose = TRUE;
|
||||
break;
|
||||
|
@ -178,12 +207,10 @@ main(argc, argv)
|
|||
typename = argv[0];
|
||||
mapname = argv[1];
|
||||
ext = NULL;
|
||||
lext = NULL;
|
||||
|
||||
if (strcmp(typename, "dbm") == 0)
|
||||
{
|
||||
type = T_DBM;
|
||||
lext = ".dir";
|
||||
}
|
||||
else if (strcmp(typename, "btree") == 0)
|
||||
{
|
||||
|
@ -202,8 +229,10 @@ main(argc, argv)
|
|||
switch (type)
|
||||
{
|
||||
case T_ERR:
|
||||
#ifdef FFR_CFLAG
|
||||
fprintf(stderr, "Usage: %s [-N] [-c cachesize] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname);
|
||||
#if _FFR_NEW_MAKEMAP_FLAGS
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-N] [-c cachesize] [-d] [-f] [-o] [-r] [-s] [-v] type mapname\n",
|
||||
progname);
|
||||
#else
|
||||
fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname);
|
||||
#endif
|
||||
|
@ -270,6 +299,11 @@ main(argc, argv)
|
|||
|
||||
el = strlen(ext);
|
||||
fl = strlen(mapname);
|
||||
if (el + fl + 1 >= sizeof fbuf)
|
||||
{
|
||||
fprintf(stderr, "%s: file name too long", mapname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
if (fl < el || strcmp(&mapname[fl - el], ext) != 0)
|
||||
{
|
||||
strcpy(fbuf, mapname);
|
||||
|
@ -278,9 +312,68 @@ main(argc, argv)
|
|||
}
|
||||
}
|
||||
|
||||
strcpy(lbuf, mapname);
|
||||
if (lext != NULL)
|
||||
strcat(lbuf, lext);
|
||||
if (!notrunc)
|
||||
sff |= SFF_CREAT;
|
||||
switch (type)
|
||||
{
|
||||
#ifdef NEWDB
|
||||
case T_BTREE:
|
||||
case T_HASH:
|
||||
if (strlen(mapname) >= sizeof dbuf)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: map name too long\n", mapname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
strcpy(dbuf, mapname);
|
||||
if (!ignoresafeties &&
|
||||
(st = safefile(dbuf, RealUid, RealGid, RealUserName,
|
||||
sff, S_IWUSR, &std)) != 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: could not create: %s\n",
|
||||
dbuf, errstring(st));
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef NDBM
|
||||
case T_DBM:
|
||||
if (strlen(mapname) + 5 > sizeof dbuf)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: map name too long\n", mapname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
sprintf(dbuf, "%s.dir", mapname);
|
||||
if (!ignoresafeties &&
|
||||
(st = safefile(dbuf, RealUid, RealGid, RealUserName,
|
||||
sff, S_IWUSR, &std)) != 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: could not create: %s\n",
|
||||
dbuf, errstring(st));
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
sprintf(pbuf, "%s.pag", mapname);
|
||||
if (!ignoresafeties &&
|
||||
(st = safefile(pbuf, RealUid, RealGid, RealUserName,
|
||||
sff, S_IWUSR, &stp)) != 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: could not create: %s\n",
|
||||
pbuf, errstring(st));
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"%s: internal error: type %d\n",
|
||||
progname,
|
||||
type);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Create the database.
|
||||
|
@ -289,24 +382,36 @@ main(argc, argv)
|
|||
mode = O_RDWR;
|
||||
if (!notrunc)
|
||||
mode |= O_CREAT|O_TRUNC;
|
||||
#ifdef O_EXLOCK
|
||||
#if O_EXLOCK
|
||||
mode |= O_EXLOCK;
|
||||
#else
|
||||
/* pre-lock the database */
|
||||
fd = open(lbuf, mode & ~O_TRUNC, 0644);
|
||||
if (ignoresafeties)
|
||||
fd = dfopen(dbuf, mode & ~O_TRUNC, 0644, sff);
|
||||
else
|
||||
fd = safeopen(dbuf, mode & ~O_TRUNC, 0644, sff);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot create type %s map %s\n",
|
||||
progname, typename, mapname);
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
(void) lockfile(fd);
|
||||
#endif
|
||||
switch (type)
|
||||
{
|
||||
#ifdef NDBM
|
||||
case T_DBM:
|
||||
dbp.dbm = dbm_open(mapname, mode, 0644);
|
||||
if (!ignoresafeties && dbp.dbm != NULL &&
|
||||
(filechanged(dbuf, dbm_dirfno(dbp.dbm), &std, sff) ||
|
||||
filechanged(pbuf, dbm_pagfno(dbp.dbm), &stp, sff)))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbm map %s: file changed after open\n",
|
||||
mapname);
|
||||
dbm_close(dbp.dbm);
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -315,10 +420,19 @@ main(argc, argv)
|
|||
/* tweak some parameters for performance */
|
||||
hinfo.nelem = 4096;
|
||||
hinfo.cachesize = dbcachesize;
|
||||
|
||||
|
||||
dbp.db = dbopen(mapname, mode, 0644, DB_HASH, &hinfo);
|
||||
if (dbp.db != NULL)
|
||||
{
|
||||
if (!ignoresafeties &&
|
||||
filechanged(dbuf, dbp.db->fd(dbp.db), &std, sff))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"db map %s: file changed after open\n",
|
||||
mapname);
|
||||
dbp.db->close(dbp.db);
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
# if OLD_NEWDB
|
||||
(void) (*dbp.db->sync)(dbp.db);
|
||||
# else
|
||||
|
@ -334,6 +448,15 @@ main(argc, argv)
|
|||
dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti);
|
||||
if (dbp.db != NULL)
|
||||
{
|
||||
if (!ignoresafeties &&
|
||||
filechanged(dbuf, dbp.db->fd(dbp.db), &std, sff))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"db map %s: file changed after open\n",
|
||||
mapname);
|
||||
dbp.db->close(dbp.db);
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
# if OLD_NEWDB
|
||||
(void) (*dbp.db->sync)(dbp.db);
|
||||
# else
|
||||
|
@ -344,7 +467,8 @@ main(argc, argv)
|
|||
#endif
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: internal error: type %d\n", progname, type);
|
||||
fprintf(stderr, "%s: internal error: type %d\n",
|
||||
progname, type);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
|
@ -447,7 +571,8 @@ main(argc, argv)
|
|||
}
|
||||
else if (st > 0)
|
||||
{
|
||||
fprintf(stderr, "%s: %s: line %d: key %s: duplicate key\n",
|
||||
fprintf(stderr,
|
||||
"%s: %s: line %d: key %s: duplicate key\n",
|
||||
progname, mapname, lineno, key.xx.data);
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +602,7 @@ main(argc, argv)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef O_EXLOCK
|
||||
#if !O_EXLOCK
|
||||
/* release locks */
|
||||
close(fd);
|
||||
#endif
|
||||
|
@ -489,6 +614,11 @@ main(argc, argv)
|
|||
**
|
||||
** Parameters:
|
||||
** fd -- the file descriptor of the file.
|
||||
** filename -- the file name (for error messages).
|
||||
** ext -- the filename extension.
|
||||
** type -- type of the lock. Bits can be:
|
||||
** LOCK_EX -- exclusive lock.
|
||||
** LOCK_NB -- non-blocking.
|
||||
**
|
||||
** Returns:
|
||||
** TRUE if the lock was acquired.
|
||||
|
@ -496,8 +626,11 @@ main(argc, argv)
|
|||
*/
|
||||
|
||||
bool
|
||||
lockfile(fd)
|
||||
lockfile(fd, filename, ext, type)
|
||||
int fd;
|
||||
char *filename;
|
||||
char *ext;
|
||||
int type;
|
||||
{
|
||||
# if !HASFLOCK
|
||||
int action;
|
||||
|
@ -505,8 +638,16 @@ lockfile(fd)
|
|||
extern int errno;
|
||||
|
||||
bzero(&lfd, sizeof lfd);
|
||||
lfd.l_type = F_WRLCK;
|
||||
action = F_SETLKW;
|
||||
if (bitset(LOCK_UN, type))
|
||||
lfd.l_type = F_UNLCK;
|
||||
else if (bitset(LOCK_EX, type))
|
||||
lfd.l_type = F_WRLCK;
|
||||
else
|
||||
lfd.l_type = F_RDLCK;
|
||||
if (bitset(LOCK_NB, type))
|
||||
action = F_SETLK;
|
||||
else
|
||||
action = F_SETLKW;
|
||||
|
||||
if (fcntl(fd, action, &lfd) >= 0)
|
||||
return TRUE;
|
||||
|
@ -525,10 +666,110 @@ lockfile(fd)
|
|||
|
||||
# else /* HASFLOCK */
|
||||
|
||||
if (flock(fd, LOCK_EX) >= 0)
|
||||
if (flock(fd, type) >= 0)
|
||||
return TRUE;
|
||||
|
||||
# endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*VARARGS2*/
|
||||
void
|
||||
#ifdef __STDC__
|
||||
message(const char *msg, ...)
|
||||
#else
|
||||
message(msg, va_alist)
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
const char *m;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
m = msg;
|
||||
if (isdigit(m[0]) && isdigit(m[1]) && isdigit(m[2]) && m[3] == ' ')
|
||||
m += 4;
|
||||
VA_START(msg);
|
||||
vfprintf(stderr, m, ap);
|
||||
VA_END;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*VARARGS2*/
|
||||
void
|
||||
#ifdef __STDC__
|
||||
syserr(const char *msg, ...)
|
||||
#else
|
||||
syserr(msg, va_alist)
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
const char *m;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
m = msg;
|
||||
if (isdigit(m[0]) && isdigit(m[1]) && isdigit(m[2]) && m[3] == ' ')
|
||||
m += 4;
|
||||
VA_START(msg);
|
||||
vfprintf(stderr, m, ap);
|
||||
VA_END;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
const char *
|
||||
errstring(err)
|
||||
int err;
|
||||
{
|
||||
static char errstr[64];
|
||||
#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
#endif
|
||||
|
||||
/* handle pseudo-errors internal to sendmail */
|
||||
switch (err)
|
||||
{
|
||||
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 HASSTRERROR
|
||||
return strerror(err);
|
||||
#else
|
||||
if (err < 0 || err > sys_nerr)
|
||||
{
|
||||
sprintf(errstr, "Error %d", err);
|
||||
return errstr;
|
||||
}
|
||||
return sys_errlist[err];
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ static char copyright[] =
|
|||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)praliases.c 8.4 (Berkeley) 9/25/96";
|
||||
static char sccsid[] = "@(#)praliases.c 8.5 (Berkeley) 5/28/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <ndbm.h>
|
||||
|
@ -81,6 +81,11 @@ main(argc, argv)
|
|||
argv += optind;
|
||||
|
||||
#ifdef NEWDB
|
||||
if (strlen(filename) + 4 >= sizeof buf)
|
||||
{
|
||||
fprintf(stderr, "Alias filename too long: %.30s...\n", filename);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
(void) strcpy(buf, filename);
|
||||
(void) strcat(buf, ".db");
|
||||
if (db = dbopen(buf, O_RDONLY, 0444 , DB_HASH, NULL)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# @(#)Makefile 8.7 (Berkeley) 10/31/95
|
||||
# @(#)Makefile 8.8 (Berkeley) 3/28/97
|
||||
|
||||
#########################################################################
|
||||
# This Makefile is for 4.4BSD only!!! For all other systems, use #
|
||||
|
@ -21,9 +21,9 @@ CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO
|
|||
|
||||
SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
|
||||
deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
|
||||
mci.c mime.c parseaddr.c queue.c readcf.c recipient.c savemail.c \
|
||||
srvrsmtp.c stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
|
||||
util.c version.c
|
||||
mci.c mime.c parseaddr.c queue.c readcf.c recipient.c safefile.c \
|
||||
savemail.c srvrsmtp.c stab.c stats.c sysexits.c trace.c udb.c \
|
||||
usersmtp.c util.c version.c
|
||||
DPADD=
|
||||
LDADD=
|
||||
MAN1= mailq.0 newaliases.0
|
||||
|
|
|
@ -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)
|
||||
|
|
107
usr.sbin/sendmail/src/aliases.5
Normal file
107
usr.sbin/sendmail/src/aliases.5
Normal file
|
@ -0,0 +1,107 @@
|
|||
.\" Copyright (c) 1983, 1997 Eric P. Allman
|
||||
.\" Copyright (c) 1985, 1991, 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.
|
||||
.\"
|
||||
.\" @(#)aliases.5 8.3 (Berkeley) 2/1/97
|
||||
.\"
|
||||
.Dd February 1, 1997
|
||||
.Dt ALIASES 5
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm aliases
|
||||
.Nd aliases file for sendmail
|
||||
.Sh SYNOPSIS
|
||||
.Nm aliases
|
||||
.Sh DESCRIPTION
|
||||
This file describes user
|
||||
.Tn ID
|
||||
aliases used by
|
||||
.Pa /usr/sbin/sendmail .
|
||||
The file resides in
|
||||
.Pa /etc
|
||||
and
|
||||
is formatted as a series of lines of the form
|
||||
.Bd -filled -offset indent
|
||||
name: name_1, name2, name_3, . . .
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Em name
|
||||
is the name to alias, and the
|
||||
.Em name_n
|
||||
are the aliases for that name.
|
||||
Lines beginning with white space are continuation lines.
|
||||
Lines beginning with
|
||||
.Ql #
|
||||
are comments.
|
||||
.Pp
|
||||
Aliasing occurs only on local names.
|
||||
Loops can not occur, since no message will be sent to any person more than once.
|
||||
.Pp
|
||||
After aliasing has been done, local and valid recipients who have a
|
||||
.Dq Pa .forward
|
||||
file in their home directory have messages forwarded to the
|
||||
list of users defined in that file.
|
||||
.Pp
|
||||
This is only the raw data file; the actual aliasing information is
|
||||
placed into a binary format in the file
|
||||
.Pa /etc/aliases.db
|
||||
using the program
|
||||
.Xr newaliases 1 .
|
||||
A
|
||||
.Xr newaliases
|
||||
command should be executed each time the aliases file is changed for the
|
||||
change to take effect.
|
||||
.Sh SEE ALSO
|
||||
.Xr newaliases 1 ,
|
||||
.Xr dbopen 3 ,
|
||||
.Xr dbm 3 ,
|
||||
.Xr sendmail 8
|
||||
.Rs
|
||||
.%T "SENDMAIL Installation and Operation Guide"
|
||||
.Re
|
||||
.Rs
|
||||
.%T "SENDMAIL An Internetwork Mail Router"
|
||||
.Re
|
||||
.Sh BUGS
|
||||
If you have compiled
|
||||
.Xr sendmail
|
||||
with DBM support instead of NEWDB,
|
||||
you may have encountered problems in
|
||||
.Xr dbm 3
|
||||
restricting a single alias to about 1000 bytes of information.
|
||||
You can get longer aliases by ``chaining''; that is, make the last name in
|
||||
the alias be a dummy name which is a continuation alias.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
file format appeared in
|
||||
.Bx 4.0 .
|
|
@ -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[] = "@(#)collect.c 8.62 (Berkeley) 12/11/96";
|
||||
static char sccsid[] = "@(#)collect.c 8.69 (Berkeley) 5/29/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include <errno.h>
|
||||
|
@ -52,8 +52,6 @@ static char sccsid[] = "@(#)collect.c 8.62 (Berkeley) 12/11/96";
|
|||
** style message to say we are ready to collect
|
||||
** input, and never ignore a single dot to mean
|
||||
** end of message.
|
||||
** requeueflag -- this message will be requeued later, so
|
||||
** don't do final processing on it.
|
||||
** hdrp -- the location to stash the header.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
|
@ -83,10 +81,9 @@ static EVENT *CollectTimeout;
|
|||
#define MS_BODY 2 /* reading message body */
|
||||
|
||||
void
|
||||
collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
collect(fp, smtpmode, hdrp, e)
|
||||
FILE *fp;
|
||||
bool smtpmode;
|
||||
bool requeueflag;
|
||||
HDR **hdrp;
|
||||
register ENVELOPE *e;
|
||||
{
|
||||
|
@ -94,7 +91,7 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
volatile bool ignrdot = smtpmode ? FALSE : IgnrDot;
|
||||
volatile time_t dbto = smtpmode ? TimeOuts.to_datablock : 0;
|
||||
register char *volatile bp;
|
||||
volatile int c = '\0';
|
||||
volatile int c = EOF;
|
||||
volatile bool inputerr = FALSE;
|
||||
bool headeronly;
|
||||
char *volatile buf;
|
||||
|
@ -103,7 +100,7 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
volatile int mstate;
|
||||
u_char *volatile pbp;
|
||||
u_char peekbuf[8];
|
||||
char dfname[20];
|
||||
char dfname[MAXQFNAME];
|
||||
char bufbuf[MAXLINE];
|
||||
extern bool isheader();
|
||||
extern void eatheader();
|
||||
|
@ -117,10 +114,12 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
|
||||
if (!headeronly)
|
||||
{
|
||||
int tfd;
|
||||
struct stat stbuf;
|
||||
|
||||
strcpy(dfname, queuename(e, 'd'));
|
||||
if ((tf = dfopen(dfname, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL)
|
||||
tfd = dfopen(dfname, O_WRONLY|O_CREAT|O_TRUNC, FileMode, SFF_ANYFILE);
|
||||
if (tfd < 0 || (tf = fdopen(tfd, "w")) == NULL)
|
||||
{
|
||||
syserr("Cannot create %s", dfname);
|
||||
e->e_flags |= EF_NO_BODY_RETN;
|
||||
|
@ -169,12 +168,10 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
/* handle possible input timeout */
|
||||
if (setjmp(CtxCollectTimeout) != 0)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 2)
|
||||
syslog(LOG_NOTICE,
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"timeout waiting for input from %s during message collect",
|
||||
CurHostName ? CurHostName : "<local machine>");
|
||||
#endif
|
||||
errno = 0;
|
||||
usrerr("451 timeout waiting for input during message collect");
|
||||
goto readerr;
|
||||
|
@ -417,10 +414,9 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
|
||||
if (tTd(30, 1))
|
||||
printf("collect: premature EOM: %s\n", errmsg);
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 2)
|
||||
syslog(LOG_WARNING, "collect: premature EOM: %s", errmsg);
|
||||
#endif
|
||||
sm_syslog(LOG_WARNING, e->e_id,
|
||||
"collect: premature EOM: %s", errmsg);
|
||||
inputerr = TRUE;
|
||||
}
|
||||
|
||||
|
@ -455,14 +451,12 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
problem = "I/O error";
|
||||
else
|
||||
problem = "read timeout";
|
||||
# ifdef LOG
|
||||
if (LogLevel > 0 && feof(fp))
|
||||
syslog(LOG_NOTICE,
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"collect: %s on connection from %.100s, sender=%s: %s",
|
||||
problem, host,
|
||||
shortenstring(e->e_from.q_paddr, 203),
|
||||
errstring(errno));
|
||||
# endif
|
||||
if (feof(fp))
|
||||
usrerr("451 collect: %s on connection from %s, from=%s",
|
||||
problem, host,
|
||||
|
@ -501,7 +495,7 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
markstats(e, (ADDRESS *) NULL);
|
||||
}
|
||||
|
||||
#ifdef _FFR_DSN_RRT
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
/*
|
||||
** If we have a Return-Receipt-To:, turn it into a DSN.
|
||||
*/
|
||||
|
@ -576,11 +570,10 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
|||
e->e_status = "5.2.3";
|
||||
usrerr("552 Message exceeds maximum fixed size (%ld)",
|
||||
MaxMessageSize);
|
||||
# ifdef LOG
|
||||
if (LogLevel > 6)
|
||||
syslog(LOG_NOTICE, "%s: message size (%ld) exceeds maximum (%ld)",
|
||||
e->e_id, e->e_msgsize, MaxMessageSize);
|
||||
# endif
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"message size (%ld) exceeds maximum (%ld)",
|
||||
e->e_msgsize, MaxMessageSize);
|
||||
}
|
||||
|
||||
/* check for illegal 8-bit data */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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.
|
||||
*
|
||||
|
@ -31,7 +31,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)conf.h 8.288 (Berkeley) 1/17/97
|
||||
* @(#)conf.h 8.313 (Berkeley) 6/11/97
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -79,6 +79,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
|||
# define MAXMIMEARGS 20 /* max args in Content-Type: */
|
||||
# define MAXMIMENESTING 20 /* max MIME multipart nesting */
|
||||
# define QUEUESEGSIZE 1000 /* increment for queue size */
|
||||
# define MAXQFNAME 20 /* max qf file name length */
|
||||
|
||||
/**********************************************************************
|
||||
** Compilation options.
|
||||
|
@ -130,7 +131,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
|||
** be turned off unless absolutely necessary.
|
||||
**********************************************************************/
|
||||
|
||||
# define LOG /* enable logging -- don't turn off */
|
||||
# define LOG 1 /* enable logging -- don't turn off */
|
||||
|
||||
/**********************************************************************
|
||||
** End of site-specific configuration.
|
||||
|
@ -175,6 +176,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
|||
# define HASINITGROUPS 1 /* has initgroups(3) call */
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define USESETEUID 1 /* has useable seteuid(2) call */
|
||||
# define BOGUS_O_EXCL 1 /* exclusive open follows symlinks */
|
||||
# define seteuid(e) setresuid(-1, e, -1)
|
||||
# define IP_SRCROUTE 1 /* can check IP source routing */
|
||||
# define LA_TYPE LA_HPUX
|
||||
|
@ -185,6 +187,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
|||
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
|
||||
# endif
|
||||
# define syslog hard_syslog
|
||||
# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */
|
||||
|
||||
# ifdef V4FS
|
||||
/* HP-UX 10.x */
|
||||
|
@ -217,6 +220,7 @@ extern void hard_syslog(int, char *, ...);
|
|||
*/
|
||||
|
||||
#ifdef _AIX4
|
||||
# include <sys/select.h>
|
||||
# define _AIX3 1 /* pull in AIX3 stuff */
|
||||
# define USESETEUID 1 /* seteuid(2) works */
|
||||
# define TZ_TYPE TZ_NAME /* use tzname[] vector */
|
||||
|
@ -336,6 +340,7 @@ typedef int pid_t;
|
|||
# define SFS_BAVAIL f_bfree /* alternate field name */
|
||||
# ifdef IRIX6
|
||||
# define LA_TYPE LA_IRIX6 /* figure out at run time */
|
||||
# define SAFENFSPATHCONF 0 /* pathconf(2) lies on NFS filesystems */
|
||||
# else
|
||||
# define LA_TYPE LA_INT
|
||||
|
||||
|
@ -373,6 +378,7 @@ typedef int pid_t;
|
|||
# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define IP_SRCROUTE 1 /* can check IP source routing */
|
||||
# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */
|
||||
|
||||
# ifdef SOLARIS_2_3
|
||||
# define SOLARIS 20300 /* for back compat only -- use -DSOLARIS=20300 */
|
||||
|
@ -402,6 +408,9 @@ typedef int pid_t;
|
|||
# ifndef SYSLOG_BUFSIZE
|
||||
# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
|
||||
# endif
|
||||
# ifndef TZ_TYPE
|
||||
# define TZ_TYPE TZ_TZNAME
|
||||
# endif
|
||||
# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203)
|
||||
# define USESETEUID 1 /* seteuid works as of 2.3 */
|
||||
# endif
|
||||
|
@ -529,6 +538,7 @@ extern long dgux_inet_addr();
|
|||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* pre-4.4 TCP/IP implementation is broken */
|
||||
# endif
|
||||
# define SYSLOG_BUFSIZE 256
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -558,6 +568,8 @@ extern long dgux_inet_addr();
|
|||
# ifndef TZ_TYPE
|
||||
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
|
||||
# endif
|
||||
# define GIDSET_T gid_t
|
||||
# define MAXNAMLEN NAME_MAX
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -600,8 +612,10 @@ extern long dgux_inet_addr();
|
|||
# define UID_T int /* compiler gripes on uid_t */
|
||||
# define GID_T int /* ditto for gid_t */
|
||||
# define MODE_T int /* and mode_t */
|
||||
# define sleep sleepX
|
||||
# define setpgid setpgrp
|
||||
# ifndef NOT_SENDMAIL
|
||||
# define sleep sleepX
|
||||
# endif
|
||||
# ifndef LA_TYPE
|
||||
# define LA_TYPE LA_MACH
|
||||
# endif
|
||||
|
@ -624,12 +638,13 @@ typedef int pid_t;
|
|||
** See also BSD defines.
|
||||
*/
|
||||
|
||||
#if defined(BSD4_4) && !defined(__bsdi__)
|
||||
#if defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__)
|
||||
# include <paths.h>
|
||||
# define HASUNSETENV 1 /* has unsetenv(3) call */
|
||||
# define USESETEUID 1 /* has useable seteuid(2) call */
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# include <sys/cdefs.h>
|
||||
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
|
||||
# define BSD4_4_SOCKADDR /* has sa_len */
|
||||
|
@ -655,6 +670,7 @@ typedef int pid_t;
|
|||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
|
||||
# define HASUNAME 1 /* has uname(2) syscall */
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# include <sys/cdefs.h>
|
||||
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
|
||||
# define BSD4_4_SOCKADDR /* has sa_len */
|
||||
|
@ -696,10 +712,12 @@ typedef int pid_t;
|
|||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
|
||||
# define HASUNAME 1 /* has uname(2) syscall */
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# include <sys/cdefs.h>
|
||||
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
|
||||
# define BSD4_4_SOCKADDR /* has sa_len */
|
||||
# define NETLINK 1 /* supports AF_LINK */
|
||||
# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */
|
||||
# define GIDSET_T gid_t
|
||||
# ifndef LA_TYPE
|
||||
# define LA_TYPE LA_SUBR
|
||||
|
@ -737,7 +755,7 @@ typedef int pid_t;
|
|||
** For mt Xinu's Mach386 system.
|
||||
*/
|
||||
|
||||
#if defined(MACH) && defined(i386)
|
||||
#if defined(MACH) && defined(i386) && !defined(__GNU__)
|
||||
# define MACH386 1
|
||||
# define HASUNSETENV 1 /* has unsetenv(3) call */
|
||||
# define HASINITGROUPS 1 /* has initgroups(3) call */
|
||||
|
@ -761,6 +779,50 @@ typedef int pid_t;
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** GNU OS (hurd)
|
||||
** Largely BSD & posix compatible.
|
||||
** Port contributed by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
*/
|
||||
|
||||
#ifdef __GNU_HURD__
|
||||
# define SIOCGIFCONF_IS_BROKEN 1
|
||||
# define IP_SRCROUTE 0
|
||||
# define HASFCHMOD 1
|
||||
# define HASFLOCK 1
|
||||
# define HASUNAME 1
|
||||
# define HASUNSETENV 1
|
||||
# define HASSETSID 1
|
||||
# define HASINITGROUPS 1
|
||||
# define HASSETVBUF 1
|
||||
# define HASSETREUID 1
|
||||
# define USESETEUID 1
|
||||
# define HASLSTAT 1
|
||||
# define HASSETRLIMIT 1
|
||||
# define HASWAITPID 1
|
||||
# define HASGETDTABLESIZE 1
|
||||
# define HASSTRERROR 1
|
||||
/* # define NEEDGETOPT 1 */
|
||||
# define HASGETUSERSHELL 1
|
||||
# define ERRLIST_PREDEFINED 1
|
||||
# define BSD4_4_SOCKADDR 1
|
||||
# define GIDSET_T gid_t
|
||||
# define LA_TYPE LA_MACH
|
||||
|
||||
/* GNU uses mach[34], which renames some rpcs from mach2.x. */
|
||||
# define host_self mach_host_self
|
||||
# define SFS_TYPE SFS_STATFS
|
||||
# define SPT_TYPE SPT_CHANGEARGV
|
||||
|
||||
/* GNU has no MAXPATHLEN; ideally the code should be changed to not use it. */
|
||||
# define MAXPATHLEN 2048
|
||||
|
||||
/* Define device num frobbing macros. */
|
||||
# define major(x) ((x)>>8)
|
||||
# define minor(x) ((x)&0xFF)
|
||||
#endif /* GNU */
|
||||
|
||||
/*
|
||||
** 4.3 BSD -- this is for very old systems
|
||||
**
|
||||
|
@ -1066,6 +1128,7 @@ extern void *malloc();
|
|||
# define GIDSET_T gid_t /* from <linux/types.h> */
|
||||
# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */
|
||||
# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */
|
||||
# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */
|
||||
# ifndef HASFLOCK
|
||||
# include <linux/version.h>
|
||||
# if LINUX_VERSION_CODE < 66399
|
||||
|
@ -1117,10 +1180,12 @@ extern void *malloc();
|
|||
# define HASUNAME 1 /* use System V uname(2) system call */
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define HASINITGROUPS 1 /* has initgroups(3) call */
|
||||
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
|
||||
# define HASSETVBUF 1 /* has setvbuf(3) in libc */
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# define SIGFUNC_DEFINED /* sigfunc_t already defined */
|
||||
# define SIGFUNC_RETURN (0) /* XXX this is a guess */
|
||||
# define SIGFUNC_DECL int /* XXX this is a guess */
|
||||
# define SIGFUNC_RETURN /* POSIX-mode */
|
||||
# define SIGFUNC_DECL void /* POSIX-mode */
|
||||
# define ERRLIST_PREDEFINED 1
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# endif
|
||||
|
@ -1829,7 +1894,7 @@ typedef struct msgb mblk_t;
|
|||
** are closed. Some firewalls return this error if you try to connect
|
||||
** to the IDENT port (113), so you can't receive email from these hosts
|
||||
** on these systems. The firewall really should use a more specific
|
||||
** message such as ICMP_UNREACH_PROTOCOL or _PORT or _NET_PROHIB. If
|
||||
** message such as ICMP_UNREACH_PROTOCOL or _PORT or _FILTER_PROHIB. If
|
||||
** not explicitly set to zero above, default it on.
|
||||
*/
|
||||
|
||||
|
@ -1930,12 +1995,21 @@ typedef struct msgb mblk_t;
|
|||
#if !defined(S_ISLNK) && defined(S_IFLNK)
|
||||
# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR 0400
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR 0200
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0040
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
# define S_IWGRP 0020
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
# define S_IROTH 0004
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
# define S_IWOTH 0002
|
||||
#endif
|
||||
|
@ -1956,6 +2030,13 @@ typedef struct msgb mblk_t;
|
|||
# define EX_NOTSTICKY -5 /* don't save persistent status */
|
||||
|
||||
|
||||
/*
|
||||
** An "impossible" file mode to indicate that the file does not exist.
|
||||
*/
|
||||
|
||||
#define ST_MODE_NOFILE 0171147 /* unlikely to occur */
|
||||
|
||||
|
||||
/*
|
||||
** These are used in a few cases where we need some special
|
||||
** error codes, but where the system doesn't provide something
|
||||
|
@ -1966,7 +2047,16 @@ typedef struct msgb mblk_t;
|
|||
# define E_PSEUDOBASE 256
|
||||
#endif
|
||||
|
||||
#define EOPENTIMEOUT (E_PSEUDOBASE + 0) /* timeout on open */
|
||||
#define E_SM_OPENTIMEOUT (E_PSEUDOBASE + 0) /* Timeout on file open */
|
||||
#define E_SM_NOSLINK (E_PSEUDOBASE + 1) /* Symbolic links not allowed */
|
||||
#define E_SM_NOHLINK (E_PSEUDOBASE + 2) /* Hard links not allowed */
|
||||
#define E_SM_REGONLY (E_PSEUDOBASE + 3) /* Regular files only */
|
||||
#define E_SM_ISEXEC (E_PSEUDOBASE + 4) /* Executable files not allowed */
|
||||
#define E_SM_WWDIR (E_PSEUDOBASE + 5) /* World writable directory */
|
||||
#define E_SM_GWDIR (E_PSEUDOBASE + 6) /* Group writable directory */
|
||||
#define E_SM_FILECHANGE (E_PSEUDOBASE + 7) /* File changed after open */
|
||||
#define E_SM_WWFILE (E_PSEUDOBASE + 8) /* World writable file */
|
||||
#define E_SM_GWFILE (E_PSEUDOBASE + 9) /* Group writable file */
|
||||
#define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */
|
||||
|
||||
/* type of arbitrary pointer */
|
||||
|
@ -1978,16 +2068,8 @@ typedef struct msgb mblk_t;
|
|||
# include "cdefs.h"
|
||||
#endif
|
||||
|
||||
#if NAMED_BIND
|
||||
# include <arpa/nameser.h>
|
||||
# ifdef __svr4__
|
||||
# ifdef NOERROR
|
||||
# undef NOERROR /* avoid compiler conflict with stream.h */
|
||||
# endif
|
||||
# endif
|
||||
# ifndef __ksr__
|
||||
extern int h_errno;
|
||||
# endif
|
||||
#if NAMED_BIND && !defined(__ksr__)
|
||||
extern int h_errno;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -2133,7 +2215,7 @@ typedef void (*sigfunc_t) __P((int));
|
|||
# if (SYSLOG_BUFSIZE) > 768
|
||||
# define TOBUFSIZE (SYSLOG_BUFSIZE - 512)
|
||||
# else
|
||||
# define TOBUFSIZE 256
|
||||
# define TOBUFSIZE (SYSLOG_BUFSIZE / 2)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -2182,3 +2264,18 @@ typedef void (*sigfunc_t) __P((int));
|
|||
#if !defined(NGROUPS_MAX) && defined(NGROUPS)
|
||||
# define NGROUPS_MAX NGROUPS /* POSIX naming convention */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If we don't have a system syslog, simulate it.
|
||||
*/
|
||||
|
||||
#if !LOG
|
||||
# define LOG_EMERG 0 /* system is unusable */
|
||||
# define LOG_ALERT 1 /* action must be taken immediately */
|
||||
# define LOG_CRIT 2 /* critical conditions */
|
||||
# define LOG_ERR 3 /* error conditions */
|
||||
# define LOG_WARNING 4 /* warning conditions */
|
||||
# define LOG_NOTICE 5 /* normal but significant condition */
|
||||
# define LOG_INFO 6 /* informational */
|
||||
# define LOG_DEBUG 7 /* debug-level messages */
|
||||
#endif
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -37,13 +37,17 @@
|
|||
|
||||
#ifndef lint
|
||||
#ifdef DAEMON
|
||||
static char sccsid[] = "@(#)daemon.c 8.159 (Berkeley) 1/14/97 (with daemon mode)";
|
||||
static char sccsid[] = "@(#)daemon.c 8.175 (Berkeley) 6/1/97 (with daemon mode)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)daemon.c 8.159 (Berkeley) 1/14/97 (without daemon mode)";
|
||||
static char sccsid[] = "@(#)daemon.c 8.175 (Berkeley) 6/1/97 (without daemon mode)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#if DAEMON || defined(SOCK_STREAM)
|
||||
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
|
||||
# define USE_SOCK_STREAM 1
|
||||
#endif
|
||||
|
||||
#if DAEMON || defined(USE_SOCK_STREAM)
|
||||
# include <arpa/inet.h>
|
||||
# if NAMED_BIND
|
||||
# include <resolv.h>
|
||||
|
@ -55,6 +59,8 @@ static char sccsid[] = "@(#)daemon.c 8.159 (Berkeley) 1/14/97 (without daemon mo
|
|||
|
||||
#if DAEMON
|
||||
|
||||
# include <sys/time.h>
|
||||
|
||||
# if IP_SRCROUTE
|
||||
# include <netinet/in_systm.h>
|
||||
# include <netinet/ip.h>
|
||||
|
@ -166,8 +172,12 @@ getrequests(e)
|
|||
|
||||
/* write the pid to the log file for posterity */
|
||||
pidf = safefopen(PidFile, O_WRONLY|O_CREAT|O_TRUNC, 0644,
|
||||
SFF_NOSLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT);
|
||||
if (pidf != NULL)
|
||||
SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT);
|
||||
if (pidf == NULL)
|
||||
{
|
||||
sm_syslog(LOG_ERR, NOQID, "unable to write %s", PidFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
extern char *CommandLineArgs;
|
||||
|
||||
|
@ -200,7 +210,6 @@ getrequests(e)
|
|||
int savederrno;
|
||||
int pipefd[2];
|
||||
extern bool refuseconnections();
|
||||
extern int getla();
|
||||
|
||||
/* see if we are rejecting connections */
|
||||
(void) blocksignal(SIGALRM);
|
||||
|
@ -234,13 +243,15 @@ getrequests(e)
|
|||
if (!wordinclass(jbuf, 'w'))
|
||||
{
|
||||
dumpstate("daemon lost $j");
|
||||
syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog");
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"daemon process doesn't have $j in $=w; see syslog");
|
||||
abort();
|
||||
}
|
||||
else if (j_has_dot && strchr(jbuf, '.') == NULL)
|
||||
{
|
||||
dumpstate("daemon $j lost dot");
|
||||
syslog(LOG_ALERT, "daemon process $j lost dot; see syslog");
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"daemon process $j lost dot; see syslog");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
@ -260,13 +271,29 @@ getrequests(e)
|
|||
log an error here;
|
||||
#endif
|
||||
(void) releasesignal(SIGALRM);
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
fd_set readfds;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(DaemonSocket, &readfds);
|
||||
timeout.tv_sec = 60;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
t = select(DaemonSocket + 1, &readfds, NULL, NULL, &timeout);
|
||||
if (DoQueueRun)
|
||||
(void) runqueue(TRUE, FALSE);
|
||||
if (t <= 0 || !FD_ISSET(DaemonSocket, &readfds))
|
||||
continue;
|
||||
|
||||
errno = 0;
|
||||
lotherend = socksize;
|
||||
t = accept(DaemonSocket,
|
||||
(struct sockaddr *)&RealHostAddr, &lotherend);
|
||||
} while (t < 0 && errno == EINTR);
|
||||
if (t >= 0 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
savederrno = errno;
|
||||
(void) blocksignal(SIGALRM);
|
||||
if (t < 0)
|
||||
|
@ -381,6 +408,9 @@ getrequests(e)
|
|||
OutChannel = outchannel;
|
||||
DisConnected = FALSE;
|
||||
|
||||
/* open maps for check_relay ruleset */
|
||||
initmaps(FALSE, e);
|
||||
|
||||
/* validate the connection */
|
||||
HoldErrs = TRUE;
|
||||
nullconn = !validate_connection(&RealHostAddr, RealHostName, e);
|
||||
|
@ -463,10 +493,9 @@ opendaemonsocket(firsttime)
|
|||
saveerrno = errno;
|
||||
syserr("opendaemonsocket: can't create server SMTP socket");
|
||||
severe:
|
||||
# ifdef LOG
|
||||
if (LogLevel > 0)
|
||||
syslog(LOG_ALERT, "problem creating SMTP socket");
|
||||
# endif /* LOG */
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"problem creating SMTP socket");
|
||||
DaemonSocket = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -747,7 +776,7 @@ makeconnection(host, port, mci, e)
|
|||
register MCI *mci;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
register volatile int i = 0;
|
||||
register volatile int addrno = 0;
|
||||
register volatile int s;
|
||||
register struct hostent *volatile hp = (struct hostent *)NULL;
|
||||
SOCKADDR addr;
|
||||
|
@ -870,7 +899,7 @@ makeconnection(host, port, mci, e)
|
|||
hp->h_length);
|
||||
break;
|
||||
}
|
||||
i = 1;
|
||||
addrno = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -883,10 +912,9 @@ makeconnection(host, port, mci, e)
|
|||
|
||||
if (sp == NULL)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 2)
|
||||
syslog(LOG_ERR, "makeconnection: service \"smtp\" unknown");
|
||||
#endif
|
||||
sm_syslog(LOG_ERR, NOQID,
|
||||
"makeconnection: service \"smtp\" unknown");
|
||||
port = htons(25);
|
||||
}
|
||||
else
|
||||
|
@ -988,22 +1016,23 @@ makeconnection(host, port, mci, e)
|
|||
|
||||
if (setjmp(CtxConnectTimeout) == 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
|
||||
ev = setevent(TimeOuts.to_iconnect, connecttimeout, 0);
|
||||
else if (TimeOuts.to_connect != 0)
|
||||
ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
|
||||
else
|
||||
ev = NULL;
|
||||
if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
|
||||
{
|
||||
if (ev != NULL)
|
||||
clrevent(ev);
|
||||
i = connect(s, (struct sockaddr *) &addr, addrlen);
|
||||
sav_errno = errno;
|
||||
if (ev != NULL)
|
||||
clrevent(ev);
|
||||
if (i >= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sav_errno = errno;
|
||||
if (ev != NULL)
|
||||
clrevent(ev);
|
||||
else
|
||||
sav_errno = errno;
|
||||
|
||||
/* if running demand-dialed connection, try again */
|
||||
if (DialDelay > 0 && firstconnect)
|
||||
|
@ -1018,7 +1047,7 @@ makeconnection(host, port, mci, e)
|
|||
|
||||
/* couldn't connect.... figure out why */
|
||||
(void) close(s);
|
||||
if (hp != NULL && hp->h_addr_list[i])
|
||||
if (hp != NULL && hp->h_addr_list[addrno])
|
||||
{
|
||||
if (tTd(16, 1))
|
||||
printf("Connect failed (%s); trying new address....\n",
|
||||
|
@ -1027,14 +1056,14 @@ makeconnection(host, port, mci, e)
|
|||
{
|
||||
#if NETINET
|
||||
case AF_INET:
|
||||
bcopy(hp->h_addr_list[i++],
|
||||
bcopy(hp->h_addr_list[addrno++],
|
||||
&addr.sin.sin_addr,
|
||||
INADDRSZ);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
bcopy(hp->h_addr_list[i++],
|
||||
bcopy(hp->h_addr_list[addrno++],
|
||||
addr.sa.sa_data,
|
||||
hp->h_length);
|
||||
break;
|
||||
|
@ -1129,19 +1158,17 @@ myhostname(hostbuf, size)
|
|||
if (strchr(hostbuf, '.') == NULL &&
|
||||
!getcanonname(hostbuf, size, TRUE))
|
||||
{
|
||||
#ifdef LOG
|
||||
syslog(LOG_CRIT, "My unqualified host name (%s) unknown; sleeping for retry",
|
||||
sm_syslog(LOG_CRIT, NOQID,
|
||||
"My unqualified host name (%s) unknown; sleeping for retry",
|
||||
hostbuf);
|
||||
#endif
|
||||
message("My unqualified host name (%s) unknown; sleeping for retry",
|
||||
hostbuf);
|
||||
sleep(60);
|
||||
if (!getcanonname(hostbuf, size, TRUE))
|
||||
{
|
||||
#ifdef LOG
|
||||
syslog(LOG_ALERT, "unable to qualify my own domain name (%s) -- using short name",
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"unable to qualify my own domain name (%s) -- using short name",
|
||||
hostbuf);
|
||||
#endif
|
||||
message("WARNING: unable to qualify my own domain name (%s) -- using short name",
|
||||
hostbuf);
|
||||
}
|
||||
|
@ -1181,6 +1208,9 @@ getauthinfo(fd)
|
|||
int i;
|
||||
EVENT *ev;
|
||||
int nleft;
|
||||
struct hostent *hp;
|
||||
char **ha;
|
||||
bool may_be_forged;
|
||||
char ibuf[MAXNAME + 1];
|
||||
static char hbuf[MAXNAME * 2 + 2];
|
||||
|
||||
|
@ -1203,6 +1233,30 @@ getauthinfo(fd)
|
|||
RealHostName[MAXNAME - 1] = '\0';
|
||||
}
|
||||
|
||||
/* cross check RealHostName with forward DNS lookup */
|
||||
if (anynet_ntoa(&RealHostAddr)[0] == '[')
|
||||
{
|
||||
/* address is not a socket */
|
||||
may_be_forged = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try to match the reverse against the forward lookup */
|
||||
hp = gethostbyname(RealHostName);
|
||||
|
||||
if (hp == NULL)
|
||||
may_be_forged = TRUE;
|
||||
else
|
||||
{
|
||||
for (ha = hp->h_addr_list; *ha != NULL; ha++)
|
||||
if (bcmp(*ha,
|
||||
(char *) &RealHostAddr.sin.sin_addr,
|
||||
hp->h_length) == 0)
|
||||
break;
|
||||
may_be_forged = *ha == NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (TimeOuts.to_ident == 0)
|
||||
goto noident;
|
||||
|
||||
|
@ -1340,6 +1394,9 @@ getauthinfo(fd)
|
|||
|
||||
postident:
|
||||
#if IP_SRCROUTE
|
||||
# ifndef GET_IPOPT_DST
|
||||
# define GET_IPOPT_DST(dst) (dst)
|
||||
# endif
|
||||
/*
|
||||
** Extract IP source routing information.
|
||||
**
|
||||
|
@ -1383,21 +1440,31 @@ getauthinfo(fd)
|
|||
|
||||
case IPOPT_SSRR:
|
||||
case IPOPT_LSRR:
|
||||
/*
|
||||
** Source routing.
|
||||
** o[0] is the option type (loose/strict).
|
||||
** o[1] is the length of this option,
|
||||
** including option type and
|
||||
** length.
|
||||
** o[2] is the pointer into the route
|
||||
** data.
|
||||
** o[3] begins the route data.
|
||||
*/
|
||||
|
||||
p = &hbuf[strlen(hbuf)];
|
||||
l = sizeof hbuf - (hbuf - p) - 6;
|
||||
snprintf(p, SPACELEFT(hbuf, p), " [%s@%.*s",
|
||||
*o == IPOPT_SSRR ? "!" : "",
|
||||
l > 240 ? 120 : l / 2,
|
||||
inet_ntoa(ipopt.ipopt_dst));
|
||||
inet_ntoa(GET_IPOPT_DST(ipopt.ipopt_dst)));
|
||||
i = strlen(p);
|
||||
p += i;
|
||||
l -= strlen(p);
|
||||
|
||||
/* o[1] is option length */
|
||||
j = *++o / sizeof(struct in_addr) - 1;
|
||||
j = o[1] / sizeof(struct in_addr) - 1;
|
||||
|
||||
/* q skips length and router pointer to data */
|
||||
q = o + 2;
|
||||
q = &o[3];
|
||||
for ( ; j >= 0; j--)
|
||||
{
|
||||
memcpy(&addr, q, sizeof(addr));
|
||||
|
@ -1412,7 +1479,7 @@ getauthinfo(fd)
|
|||
l -= i + 1;
|
||||
q += sizeof(struct in_addr);
|
||||
}
|
||||
o += *o;
|
||||
o += o[1];
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1433,6 +1500,11 @@ getauthinfo(fd)
|
|||
(void) snprintf(p, SPACELEFT(hbuf, p), " [%.100s]",
|
||||
anynet_ntoa(&RealHostAddr));
|
||||
}
|
||||
if (may_be_forged)
|
||||
{
|
||||
p = &hbuf[strlen(hbuf)];
|
||||
(void) snprintf(p, SPACELEFT(hbuf, p), " (may be forged)");
|
||||
}
|
||||
|
||||
postipsr:
|
||||
if (tTd(9, 1))
|
||||
|
@ -1443,7 +1515,7 @@ getauthinfo(fd)
|
|||
** HOST_MAP_LOOKUP -- turn a hostname into canonical form
|
||||
**
|
||||
** Parameters:
|
||||
** map -- a pointer to this map (unused).
|
||||
** map -- a pointer to this map.
|
||||
** name -- the (presumably unqualified) hostname.
|
||||
** av -- unused -- for compatibility with other mapping
|
||||
** functions.
|
||||
|
@ -1457,7 +1529,8 @@ getauthinfo(fd)
|
|||
** Side Effects:
|
||||
** Looks up the host specified in hbuf. If it is not
|
||||
** the canonical name for that host, return the canonical
|
||||
** name.
|
||||
** name (unless MF_MATCHONLY is set, which will cause the
|
||||
** status only to be returned).
|
||||
*/
|
||||
|
||||
char *
|
||||
|
@ -1498,7 +1571,16 @@ host_map_lookup(map, name, av, statp)
|
|||
message("851 %s: Name server timeout",
|
||||
shortenstring(name, 33));
|
||||
}
|
||||
return s->s_namecanon.nc_cname;
|
||||
if (*statp != EX_OK)
|
||||
return NULL;
|
||||
if (bitset(MF_MATCHONLY, map->map_mflags))
|
||||
cp = map_rewrite(map, name, strlen(name), NULL);
|
||||
else
|
||||
cp = map_rewrite(map,
|
||||
s->s_namecanon.nc_cname,
|
||||
strlen(s->s_namecanon.nc_cname),
|
||||
av);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1532,16 +1614,12 @@ host_map_lookup(map, name, av, statp)
|
|||
{
|
||||
if (tTd(9, 1))
|
||||
printf("%s\n", hbuf);
|
||||
s->s_namecanon.nc_stat = EX_OK;
|
||||
s->s_namecanon.nc_cname = newstr(hbuf);
|
||||
if (bitset(MF_MATCHONLY, map->map_mflags))
|
||||
{
|
||||
cp = map_rewrite(map, name, strlen(name), av);
|
||||
s->s_namecanon.nc_cname = newstr(hbuf);
|
||||
}
|
||||
cp = map_rewrite(map, name, strlen(name), NULL);
|
||||
else
|
||||
{
|
||||
cp = map_rewrite(map, hbuf, strlen(hbuf), av);
|
||||
s->s_namecanon.nc_cname = newstr(cp);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
else
|
||||
|
@ -1589,6 +1667,7 @@ host_map_lookup(map, name, av, statp)
|
|||
return (NULL);
|
||||
*cp = '\0';
|
||||
in_addr.s_addr = inet_addr(&name[1]);
|
||||
*cp = ']';
|
||||
|
||||
/* nope -- ask the name server */
|
||||
hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET);
|
||||
|
@ -1604,9 +1683,12 @@ host_map_lookup(map, name, av, statp)
|
|||
}
|
||||
|
||||
/* found a match -- copy out */
|
||||
cp = map_rewrite(map, (char *) hp->h_name, strlen(hp->h_name), av);
|
||||
s->s_namecanon.nc_stat = *statp = EX_OK;
|
||||
s->s_namecanon.nc_cname = newstr(cp);
|
||||
s->s_namecanon.nc_cname = newstr(hp->h_name);
|
||||
if (bitset(MF_MATCHONLY, map->map_mflags))
|
||||
cp = map_rewrite(map, name, strlen(name), NULL);
|
||||
else
|
||||
cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
@ -1688,16 +1770,63 @@ host_map_lookup(map, name, avp, statp)
|
|||
char *statp;
|
||||
{
|
||||
register struct hostent *hp;
|
||||
char *cp;
|
||||
|
||||
hp = sm_gethostbyname(name);
|
||||
if (hp != NULL)
|
||||
return hp->h_name;
|
||||
*statp = EX_NOHOST;
|
||||
return NULL;
|
||||
if (hp == NULL)
|
||||
{
|
||||
*statp = EX_NOHOST;
|
||||
return NULL;
|
||||
}
|
||||
if (bitset(MF_MATCHONLY, map->map_mflags))
|
||||
cp = map_rewrite(map, name, strlen(name), NULL);
|
||||
else
|
||||
cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
|
||||
return cp;
|
||||
}
|
||||
|
||||
#endif /* DAEMON */
|
||||
/*
|
||||
** HOST_MAP_INIT -- initialize host class structures
|
||||
*/
|
||||
|
||||
bool
|
||||
host_map_init(map, args)
|
||||
MAP *map;
|
||||
char *args;
|
||||
{
|
||||
register char *p = args;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (isascii(*p) && isspace(*p))
|
||||
p++;
|
||||
if (*p != '-')
|
||||
break;
|
||||
switch (*++p)
|
||||
{
|
||||
case 'a':
|
||||
map->map_app = ++p;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
map->map_mflags |= MF_MATCHONLY;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
map->map_mflags |= MF_NODEFER;
|
||||
break;
|
||||
}
|
||||
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (map->map_app != NULL)
|
||||
map->map_app = newstr(map->map_app);
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
** ANYNET_NTOA -- convert a network address to printable form.
|
||||
**
|
||||
** Parameters:
|
||||
|
@ -1707,7 +1836,7 @@ host_map_lookup(map, name, avp, statp)
|
|||
** A printable version of that sockaddr.
|
||||
*/
|
||||
|
||||
#ifdef SOCK_STREAM
|
||||
#ifdef USE_SOCK_STREAM
|
||||
|
||||
#if NETLINK
|
||||
# include <net/if_dl.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[] = "@(#)deliver.c 8.266 (Berkeley) 1/17/97";
|
||||
static char sccsid[] = "@(#)deliver.c 8.282 (Berkeley) 6/11/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "sendmail.h"
|
||||
|
@ -76,7 +76,7 @@ sendall(e, mode)
|
|||
int otherowners;
|
||||
register ENVELOPE *ee;
|
||||
ENVELOPE *splitenv = NULL;
|
||||
bool oldverbose = Verbose;
|
||||
int oldverbose = Verbose;
|
||||
bool somedeliveries = FALSE;
|
||||
pid_t pid;
|
||||
extern void sendenvelope();
|
||||
|
@ -96,7 +96,6 @@ sendall(e, mode)
|
|||
}
|
||||
|
||||
/* determine actual delivery mode */
|
||||
CurrentLA = getla();
|
||||
if (mode == SM_DEFAULT)
|
||||
{
|
||||
mode = e->e_sendmode;
|
||||
|
@ -295,6 +294,7 @@ sendall(e, mode)
|
|||
{
|
||||
extern HDR *copyheader();
|
||||
extern ADDRESS *copyqueue();
|
||||
extern void dup_queue_file __P((ENVELOPE *, ENVELOPE *, int));
|
||||
|
||||
/*
|
||||
** Split this envelope into two.
|
||||
|
@ -360,42 +360,12 @@ sendall(e, mode)
|
|||
}
|
||||
|
||||
if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
|
||||
{
|
||||
char df1buf[20], df2buf[20];
|
||||
|
||||
ee->e_dfp = NULL;
|
||||
snprintf(df1buf, sizeof df1buf, "%s",
|
||||
queuename(e, 'd'));
|
||||
snprintf(df2buf, sizeof df2buf, "%s",
|
||||
queuename(ee, 'd'));
|
||||
if (link(df1buf, df2buf) < 0)
|
||||
{
|
||||
int saverrno = errno;
|
||||
|
||||
syserr("sendall: link(%s, %s)",
|
||||
df1buf, df2buf);
|
||||
if (saverrno == EEXIST)
|
||||
{
|
||||
if (unlink(df2buf) < 0)
|
||||
{
|
||||
syserr("!sendall: unlink(%s): permanent",
|
||||
df2buf);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (link(df1buf, df2buf) < 0)
|
||||
{
|
||||
syserr("!sendall: link(%s, %s): permanent",
|
||||
df1buf, df2buf);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef LOG
|
||||
dup_queue_file(e, ee, 'd');
|
||||
openxscript(ee);
|
||||
if (LogLevel > 4)
|
||||
syslog(LOG_INFO, "%s: clone %s, owner=%s",
|
||||
ee->e_id, e->e_id, owner);
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, ee->e_id,
|
||||
"clone %s, owner=%s",
|
||||
e->e_id, owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,6 +390,15 @@ sendall(e, mode)
|
|||
if (tTd(13, 29))
|
||||
printf("No deliveries: auto-queuing\n");
|
||||
mode = SM_QUEUE;
|
||||
|
||||
/* treat this as a delivery in terms of counting tries */
|
||||
e->e_dtime = curtime();
|
||||
e->e_ntries++;
|
||||
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
|
||||
{
|
||||
ee->e_dtime = curtime();
|
||||
ee->e_ntries++;
|
||||
}
|
||||
}
|
||||
|
||||
# if QUEUE
|
||||
|
@ -462,7 +441,7 @@ sendall(e, mode)
|
|||
switch (mode)
|
||||
{
|
||||
case SM_VERIFY:
|
||||
Verbose = TRUE;
|
||||
Verbose = 2;
|
||||
break;
|
||||
|
||||
case SM_QUEUE:
|
||||
|
@ -563,6 +542,9 @@ sendall(e, mode)
|
|||
finis();
|
||||
}
|
||||
|
||||
/* be sure to give error messages in child */
|
||||
QuickAbort = OnlyOneError = FALSE;
|
||||
|
||||
/*
|
||||
** Close any cached connections.
|
||||
**
|
||||
|
@ -619,12 +601,10 @@ sendenvelope(e, mode)
|
|||
printf("sendenvelope(%s) e_flags=0x%lx\n",
|
||||
e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
|
||||
e->e_flags);
|
||||
#ifdef LOG
|
||||
if (LogLevel > 80)
|
||||
syslog(LOG_DEBUG, "%s: sendenvelope, flags=0x%x",
|
||||
e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
|
||||
sm_syslog(LOG_DEBUG, e->e_id,
|
||||
"sendenvelope, flags=0x%x",
|
||||
e->e_flags);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If we have had global, fatal errors, don't bother sending
|
||||
|
@ -709,6 +689,51 @@ sendenvelope(e, mode)
|
|||
#endif
|
||||
}
|
||||
/*
|
||||
** DUP_QUEUE_FILE -- duplicate a queue file into a split queue
|
||||
**
|
||||
** Parameters:
|
||||
** e -- the existing envelope
|
||||
** ee -- the new envelope
|
||||
** type -- the queue file type (e.g., 'd')
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
*/
|
||||
|
||||
void
|
||||
dup_queue_file(e, ee, type)
|
||||
struct envelope *e, *ee;
|
||||
int type;
|
||||
{
|
||||
char f1buf[MAXQFNAME], f2buf[MAXQFNAME];
|
||||
|
||||
ee->e_dfp = NULL;
|
||||
ee->e_xfp = NULL;
|
||||
snprintf(f1buf, sizeof f1buf, "%s", queuename(e, type));
|
||||
snprintf(f2buf, sizeof f2buf, "%s", queuename(ee, type));
|
||||
if (link(f1buf, f2buf) < 0)
|
||||
{
|
||||
int saverrno = errno;
|
||||
|
||||
syserr("sendall: link(%s, %s)", f1buf, f2buf);
|
||||
if (saverrno == EEXIST)
|
||||
{
|
||||
if (unlink(f2buf) < 0)
|
||||
{
|
||||
syserr("!sendall: unlink(%s): permanent",
|
||||
f2buf);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (link(f1buf, f2buf) < 0)
|
||||
{
|
||||
syserr("!sendall: link(%s, %s): permanent",
|
||||
f1buf, f2buf);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
** DOFORK -- do a fork, retrying a couple of times on failure.
|
||||
**
|
||||
** This MUST be a macro, since after a vfork we are running
|
||||
|
@ -826,6 +851,7 @@ deliver(e, firstto)
|
|||
time_t xstart;
|
||||
bool suidwarn;
|
||||
bool anyok; /* at least one address was OK */
|
||||
bool goodmxfound = FALSE; /* at least one MX was OK */
|
||||
int mpvect[2];
|
||||
int rpvect[2];
|
||||
char *pv[MAXPV+1];
|
||||
|
@ -1018,6 +1044,7 @@ deliver(e, firstto)
|
|||
e->e_flags |= EF_NO_BODY_RETN;
|
||||
to->q_status = "5.2.3";
|
||||
usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
|
||||
markfailure(e, to, NULL, EX_UNAVAILABLE);
|
||||
giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e);
|
||||
continue;
|
||||
}
|
||||
|
@ -1294,8 +1321,11 @@ deliver(e, firstto)
|
|||
curhost++;
|
||||
continue;
|
||||
}
|
||||
strncpy(hostbuf, curhost, p - curhost);
|
||||
hostbuf[p - curhost] = '\0';
|
||||
i = p - curhost;
|
||||
if (i >= sizeof hostbuf)
|
||||
i = sizeof hostbuf - 1;
|
||||
strncpy(hostbuf, curhost, i);
|
||||
hostbuf[i] = '\0';
|
||||
if (*p != '\0')
|
||||
p++;
|
||||
curhost = p;
|
||||
|
@ -1318,11 +1348,16 @@ deliver(e, firstto)
|
|||
}
|
||||
mci->mci_mailer = m;
|
||||
if (mci->mci_exitstat != EX_OK)
|
||||
{
|
||||
if (mci->mci_exitstat == EX_TEMPFAIL)
|
||||
goodmxfound = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mci_lock_host(mci) != EX_OK)
|
||||
{
|
||||
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
|
||||
goodmxfound = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1343,6 +1378,7 @@ deliver(e, firstto)
|
|||
#endif
|
||||
if (i == EX_OK)
|
||||
{
|
||||
goodmxfound = TRUE;
|
||||
mci->mci_state = MCIS_OPENING;
|
||||
mci_cache(mci);
|
||||
if (TrafficLogFile != NULL)
|
||||
|
@ -1355,6 +1391,8 @@ deliver(e, firstto)
|
|||
if (tTd(11, 1))
|
||||
printf("openmailer: makeconnection => stat=%d, errno=%d\n",
|
||||
i, errno);
|
||||
if (i == EX_TEMPFAIL)
|
||||
goodmxfound = TRUE;
|
||||
mci_unlock_host(mci);
|
||||
}
|
||||
|
||||
|
@ -1863,7 +1901,12 @@ deliver(e, firstto)
|
|||
for (to = tochain; to != NULL; to = to->q_tchain)
|
||||
{
|
||||
e->e_to = to->q_paddr;
|
||||
if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
|
||||
if (strlen(to->q_paddr) + (t - tobuf) + 2 >= sizeof tobuf)
|
||||
{
|
||||
/* not enough room */
|
||||
continue;
|
||||
}
|
||||
else if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
|
||||
{
|
||||
markfailure(e, to, mci, i);
|
||||
giveresponse(i, m, mci, ctladdr, xstart, e);
|
||||
|
@ -1948,8 +1991,15 @@ deliver(e, firstto)
|
|||
rcode = smtpgetstat(m, mci, e);
|
||||
if (rcode == EX_OK)
|
||||
{
|
||||
strcat(tobuf, ",");
|
||||
strcat(tobuf, to->q_paddr);
|
||||
if (strlen(to->q_paddr) + strlen(tobuf) + 2 >= sizeof tobuf)
|
||||
{
|
||||
syserr("LMTP tobuf overflow");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(tobuf, ",");
|
||||
strcat(tobuf, to->q_paddr);
|
||||
}
|
||||
anyok = TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -1968,6 +2018,8 @@ deliver(e, firstto)
|
|||
/* mark bad addresses */
|
||||
if (rcode != EX_OK)
|
||||
{
|
||||
if (goodmxfound && rcode == EX_NOHOST)
|
||||
rcode = EX_TEMPFAIL;
|
||||
markfailure(e, to, mci, rcode);
|
||||
continue;
|
||||
}
|
||||
|
@ -2084,6 +2136,7 @@ markfailure(e, q, mci, rcode)
|
|||
case EX_IOERR:
|
||||
case EX_OSERR:
|
||||
q->q_flags |= QQUEUEUP;
|
||||
q->q_flags &= ~QDONTSEND;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2203,7 +2256,7 @@ endmailer(mci, e, pv)
|
|||
if (mci->mci_pid == 0)
|
||||
return (EX_OK);
|
||||
|
||||
#ifdef _FFR_TIMEOUT_WAIT
|
||||
#if _FFR_TIMEOUT_WAIT
|
||||
put a timeout around the wait
|
||||
#endif
|
||||
|
||||
|
@ -2428,7 +2481,6 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
time_t xstart;
|
||||
register ENVELOPE *e;
|
||||
{
|
||||
# ifdef LOG
|
||||
register char *bp;
|
||||
register char *p;
|
||||
int l;
|
||||
|
@ -2533,11 +2585,12 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
|
||||
if (q == NULL)
|
||||
break;
|
||||
syslog(LOG_INFO, "%s: to=%.*s [more]%s",
|
||||
e->e_id, ++q - p, p, buf);
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"to=%.*s [more]%s",
|
||||
++q - p, p, buf);
|
||||
p = q;
|
||||
}
|
||||
syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf);
|
||||
sm_syslog(LOG_INFO, e->e_id, "to=%s%s", p, buf);
|
||||
|
||||
# else /* we have a very short log buffer size */
|
||||
|
||||
|
@ -2549,11 +2602,12 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
|
||||
if (q == NULL)
|
||||
break;
|
||||
syslog(LOG_INFO, "%s: to=%.*s [more]",
|
||||
e->e_id, ++q - p, p);
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"to=%.*s [more]",
|
||||
++q - p, p);
|
||||
p = q;
|
||||
}
|
||||
syslog(LOG_INFO, "%s: to=%s", e->e_id, p);
|
||||
sm_syslog(LOG_INFO, e->e_id, "to=%s", p);
|
||||
|
||||
if (ctladdr != NULL)
|
||||
{
|
||||
|
@ -2567,7 +2621,7 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
ctladdr->q_uid, ctladdr->q_gid);
|
||||
bp += strlen(bp);
|
||||
}
|
||||
syslog(LOG_INFO, "%s: %s", e->e_id, buf);
|
||||
sm_syslog(LOG_INFO, e->e_id, "%s", buf);
|
||||
}
|
||||
bp = buf;
|
||||
snprintf(bp, SPACELEFT(buf, bp), "delay=%s",
|
||||
|
@ -2585,7 +2639,7 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
snprintf(bp, SPACELEFT(buf, bp), ", mailer=%s", m->m_name);
|
||||
bp += strlen(bp);
|
||||
}
|
||||
syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf);
|
||||
sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
|
||||
|
||||
buf[0] = '\0';
|
||||
bp = buf;
|
||||
|
@ -2612,11 +2666,10 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
|||
snprintf(buf, sizeof buf, "relay=%.100s", p);
|
||||
}
|
||||
if (buf[0] != '\0')
|
||||
syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf);
|
||||
sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
|
||||
|
||||
syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));
|
||||
sm_syslog(LOG_INFO, e->e_id, "stat=%s", shortenstring(stat, 63));
|
||||
# endif /* short log buffer */
|
||||
# endif /* LOG */
|
||||
}
|
||||
/*
|
||||
** PUTFROMLINE -- output a UNIX-style from line (or whatever)
|
||||
|
@ -2688,7 +2741,7 @@ putfromline(mci, e)
|
|||
}
|
||||
}
|
||||
expand(template, buf, sizeof buf, e);
|
||||
putxline(buf, mci, PXLF_NOTHINGSPECIAL);
|
||||
putxline(buf, strlen(buf), mci, PXLF_NOTHINGSPECIAL);
|
||||
}
|
||||
/*
|
||||
** PUTBODY -- put the body of a message.
|
||||
|
@ -2828,7 +2881,7 @@ putbody(mci, e, separator)
|
|||
switch (ostate)
|
||||
{
|
||||
case OS_HEAD:
|
||||
#ifdef _FFR_NONULLS
|
||||
#if _FFR_NONULLS
|
||||
if (c == '\0' &&
|
||||
bitnset(M_NONULLS, mci->mci_mailer->m_flags))
|
||||
break;
|
||||
|
@ -2933,7 +2986,7 @@ putbody(mci, e, separator)
|
|||
ostate = OS_CR;
|
||||
continue;
|
||||
}
|
||||
#ifdef _FFR_NONULLS
|
||||
#if _FFR_NONULLS
|
||||
if (c == '\0' &&
|
||||
bitnset(M_NONULLS, mci->mci_mailer->m_flags))
|
||||
break;
|
||||
|
@ -3214,7 +3267,7 @@ mailfile(filename, ctladdr, sfflags, e)
|
|||
if (setuid(RealUid) < 0 && suidwarn)
|
||||
syserr("mailfile: setuid(%ld) failed", (long) RealUid);
|
||||
|
||||
sfflags |= SFF_NOPATHCHECK;
|
||||
sfflags |= SFF_NOPATHCHECK|SFF_NOLINK;
|
||||
sfflags &= ~SFF_OPENASROOT;
|
||||
f = safefopen(filename, oflags, FileMode, sfflags);
|
||||
if (f == NULL)
|
||||
|
@ -3252,6 +3305,7 @@ mailfile(filename, ctladdr, sfflags, e)
|
|||
#endif
|
||||
(void) xfclose(f, "mailfile", filename);
|
||||
(void) fflush(stdout);
|
||||
setuid(RealUid);
|
||||
exit(ExitStat);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1986, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1986, 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 NAMED_BIND
|
||||
static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)";
|
||||
static char sccsid[] = "@(#)domain.c 8.67 (Berkeley) 4/9/97 (with name server)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)";
|
||||
static char sccsid[] = "@(#)domain.c 8.67 (Berkeley) 4/9/97 (without name server)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -197,6 +197,7 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
|
|||
goto punt;
|
||||
|
||||
case TRY_AGAIN:
|
||||
case -1:
|
||||
/* couldn't connect to the name server */
|
||||
if (fallbackMX != NULL)
|
||||
{
|
||||
|
@ -880,6 +881,7 @@ gethostalias(host)
|
|||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* got a match; extract the equivalent name */
|
||||
while (*p != '\0' && isascii(*p) && isspace(*p))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,13 +33,36 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)headers.c 8.103 (Berkeley) 12/11/96";
|
||||
static char sccsid[] = "@(#)headers.c 8.110 (Berkeley) 6/14/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include <errno.h>
|
||||
# include "sendmail.h"
|
||||
|
||||
/*
|
||||
** SETUPHEADERS -- initialize headers in symbol table
|
||||
**
|
||||
** Parameters:
|
||||
** none
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
*/
|
||||
|
||||
void
|
||||
setupheaders()
|
||||
{
|
||||
struct hdrinfo *hi;
|
||||
STAB *s;
|
||||
|
||||
for (hi = HdrInfo; hi->hi_field != NULL; hi++)
|
||||
{
|
||||
s = stab(hi->hi_field, ST_HEADER, ST_ENTER);
|
||||
s->s_header.hi_flags = hi->hi_flags;
|
||||
s->s_header.hi_ruleset = NULL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** CHOMPHEADER -- process and save a header line.
|
||||
**
|
||||
** Called by collect and by readcf to deal with header lines.
|
||||
|
@ -58,6 +81,8 @@ static char sccsid[] = "@(#)headers.c 8.103 (Berkeley) 12/11/96";
|
|||
** Contents of 'line' are destroyed.
|
||||
*/
|
||||
|
||||
struct hdrinfo NormalHeader = { NULL, 0, NULL };
|
||||
|
||||
int
|
||||
chompheader(line, def, hdrp, e)
|
||||
char *line;
|
||||
|
@ -70,9 +95,10 @@ chompheader(line, def, hdrp, e)
|
|||
HDR **hp;
|
||||
char *fname;
|
||||
char *fvalue;
|
||||
struct hdrinfo *hi;
|
||||
bool cond = FALSE;
|
||||
bool headeronly;
|
||||
STAB *s;
|
||||
struct hdrinfo *hi;
|
||||
BITMAP mopts;
|
||||
|
||||
if (tTd(31, 6))
|
||||
|
@ -116,7 +142,7 @@ chompheader(line, def, hdrp, e)
|
|||
if (*p++ != ':' || fname == fvalue)
|
||||
{
|
||||
syserr("553 header syntax error, line \"%s\"", line);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
*fvalue = '\0';
|
||||
fvalue = p;
|
||||
|
@ -129,19 +155,44 @@ chompheader(line, def, hdrp, e)
|
|||
if (strlen(fname) > 100)
|
||||
return H_EOH;
|
||||
|
||||
/* see if it is a known type */
|
||||
for (hi = HdrInfo; hi->hi_field != NULL; hi++)
|
||||
#if _FFR_HEADER_RSCHECK
|
||||
/* check to see if it represents a ruleset call */
|
||||
if (def)
|
||||
{
|
||||
if (strcasecmp(hi->hi_field, fname) == 0)
|
||||
break;
|
||||
char hbuf[50];
|
||||
|
||||
(void) expand(fvalue, hbuf, sizeof hbuf, e);
|
||||
for (p = hbuf; isascii(*p) && isspace(*p); )
|
||||
p++;
|
||||
if ((*p++ & 0377) == CALLSUBR)
|
||||
{
|
||||
auto char *endp;
|
||||
|
||||
if (strtorwset(p, &endp, ST_ENTER) > 0)
|
||||
{
|
||||
*endp = '\0';
|
||||
s = stab(fname, ST_HEADER, ST_ENTER);
|
||||
s->s_header.hi_ruleset = newstr(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* see if it is a known type */
|
||||
s = stab(fname, ST_HEADER, ST_FIND);
|
||||
if (s != NULL)
|
||||
hi = &s->s_header;
|
||||
else
|
||||
hi = &NormalHeader;
|
||||
|
||||
if (tTd(31, 9))
|
||||
{
|
||||
if (hi->hi_field == NULL)
|
||||
printf("no header match\n");
|
||||
if (s == NULL)
|
||||
printf("no header flags match\n");
|
||||
else
|
||||
printf("header match, hi_flags=%x\n", hi->hi_flags);
|
||||
printf("header match, flags=%x, ruleset=%s\n",
|
||||
hi->hi_flags, hi->hi_ruleset);
|
||||
}
|
||||
|
||||
/* see if this is a resent message */
|
||||
|
@ -155,7 +206,7 @@ chompheader(line, def, hdrp, e)
|
|||
|
||||
/* if this means "end of header" quit now */
|
||||
if (bitset(H_EOH, hi->hi_flags))
|
||||
return (hi->hi_flags);
|
||||
return hi->hi_flags;
|
||||
|
||||
/*
|
||||
** Horrible hack to work around problem with Lotus Notes SMTP
|
||||
|
@ -171,6 +222,13 @@ chompheader(line, def, hdrp, e)
|
|||
*p = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
** If there is a check ruleset, verify it against the header.
|
||||
*/
|
||||
|
||||
if (!def && hi->hi_ruleset != NULL)
|
||||
(void) rscheck(hi->hi_ruleset, fvalue, NULL, e);
|
||||
|
||||
/*
|
||||
** Drop explicit From: if same as what we would generate.
|
||||
** This is to make MH (which doesn't always give a full name)
|
||||
|
@ -191,7 +249,7 @@ chompheader(line, def, hdrp, e)
|
|||
if (e->e_from.q_paddr != NULL &&
|
||||
(strcmp(fvalue, e->e_from.q_paddr) == 0 ||
|
||||
strcmp(fvalue, e->e_from.q_user) == 0))
|
||||
return (hi->hi_flags);
|
||||
return hi->hi_flags;
|
||||
}
|
||||
|
||||
/* delete default value for this header */
|
||||
|
@ -232,7 +290,7 @@ chompheader(line, def, hdrp, e)
|
|||
e->e_flags &= ~EF_OLDSTYLE;
|
||||
}
|
||||
|
||||
return (h->h_flags);
|
||||
return h->h_flags;
|
||||
}
|
||||
/*
|
||||
** ADDHEADER -- add a header entry to the end of the queue.
|
||||
|
@ -258,15 +316,11 @@ addheader(field, value, hdrlist)
|
|||
HDR **hdrlist;
|
||||
{
|
||||
register HDR *h;
|
||||
register struct hdrinfo *hi;
|
||||
STAB *s;
|
||||
HDR **hp;
|
||||
|
||||
/* find info struct */
|
||||
for (hi = HdrInfo; hi->hi_field != NULL; hi++)
|
||||
{
|
||||
if (strcasecmp(field, hi->hi_field) == 0)
|
||||
break;
|
||||
}
|
||||
s = stab(field, ST_HEADER, ST_FIND);
|
||||
|
||||
/* find current place in list -- keep back pointer? */
|
||||
for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link)
|
||||
|
@ -280,7 +334,9 @@ addheader(field, value, hdrlist)
|
|||
h->h_field = field;
|
||||
h->h_value = newstr(value);
|
||||
h->h_link = *hp;
|
||||
h->h_flags = hi->hi_flags | H_DEFAULT;
|
||||
h->h_flags = H_DEFAULT;
|
||||
if (s != NULL)
|
||||
h->h_flags |= s->s_header.hi_flags;
|
||||
clrbitmap(h->h_mflags);
|
||||
*hp = h;
|
||||
}
|
||||
|
@ -577,10 +633,8 @@ eatheader(e, full)
|
|||
** Log collection information.
|
||||
*/
|
||||
|
||||
# ifdef LOG
|
||||
if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
|
||||
logsender(e, msgid);
|
||||
# endif /* LOG */
|
||||
e->e_flags &= ~EF_LOGSENDER;
|
||||
}
|
||||
/*
|
||||
|
@ -599,7 +653,6 @@ logsender(e, msgid)
|
|||
register ENVELOPE *e;
|
||||
char *msgid;
|
||||
{
|
||||
# ifdef LOG
|
||||
char *name;
|
||||
register char *sbp;
|
||||
register char *p;
|
||||
|
@ -663,37 +716,39 @@ logsender(e, msgid)
|
|||
p = macvalue('r', e);
|
||||
if (p != NULL)
|
||||
(void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", proto=%.20s", p);
|
||||
syslog(LOG_INFO, "%s: %.850s, relay=%.100s",
|
||||
e->e_id, sbuf, name);
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.850s, relay=%.100s",
|
||||
sbuf, name);
|
||||
|
||||
# else /* short syslog buffer */
|
||||
|
||||
syslog(LOG_INFO, "%s: from=%s",
|
||||
e->e_id, e->e_from.q_paddr == NULL ? "<NONE>" :
|
||||
shortenstring(e->e_from.q_paddr, 83));
|
||||
syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d",
|
||||
e->e_id, e->e_msgsize, e->e_class,
|
||||
e->e_msgpriority, e->e_nrcpts);
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"from=%s",
|
||||
e->e_from.q_paddr == NULL ? "<NONE>"
|
||||
: shortenstring(e->e_from.q_paddr, 83));
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"size=%ld, class=%ld, pri=%ld, nrcpts=%d",
|
||||
e->e_msgsize, e->e_class, e->e_msgpriority, e->e_nrcpts);
|
||||
if (msgid != NULL)
|
||||
syslog(LOG_INFO, "%s: msgid=%s",
|
||||
e->e_id, shortenstring(mbuf, 83));
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"msgid=%s",
|
||||
shortenstring(mbuf, 83));
|
||||
sbp = sbuf;
|
||||
snprintf(sbp, SPACELEFT(sbuf, sbp), "%s:", e->e_id);
|
||||
sbp += strlen(sbp);
|
||||
*sbp = '\0';
|
||||
if (e->e_bodytype != NULL)
|
||||
{
|
||||
snprintf(sbp, SPACELEFT(sbuf, sbp), " bodytype=%.20s,", e->e_bodytype);
|
||||
snprintf(sbp, SPACELEFT(sbuf, sbp), "bodytype=%.20s, ", e->e_bodytype);
|
||||
sbp += strlen(sbp);
|
||||
}
|
||||
p = macvalue('r', e);
|
||||
if (p != NULL)
|
||||
{
|
||||
snprintf(sbp, SPACELEFT(sbuf, sbp), " proto=%.20s,", p);
|
||||
snprintf(sbp, SPACELEFT(sbuf, sbp), "proto=%.20s, ", p);
|
||||
sbp += strlen(sbp);
|
||||
}
|
||||
syslog(LOG_INFO, "%.400s relay=%.100s", sbuf, name);
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.400srelay=%.100s", sbuf, name);
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
/*
|
||||
** PRIENCODE -- encode external priority names into internal values.
|
||||
|
@ -788,7 +843,7 @@ crackaddr(addr)
|
|||
*/
|
||||
|
||||
bp = bufhead = buf;
|
||||
buflim = &buf[sizeof buf - 6];
|
||||
buflim = &buf[sizeof buf - 7];
|
||||
p = addrhead = addr;
|
||||
copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0;
|
||||
bracklev = 0;
|
||||
|
@ -1165,7 +1220,7 @@ putheader(mci, hdr, e)
|
|||
|
||||
/* suppress return receipts if requested */
|
||||
if (bitset(H_RECEIPTTO, h->h_flags) &&
|
||||
#if _FFR_DSN_RRT
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
(RrtImpliesDsn || bitset(EF_NORECEIPT, e->e_flags)))
|
||||
#else
|
||||
bitset(EF_NORECEIPT, e->e_flags))
|
||||
|
@ -1181,7 +1236,7 @@ putheader(mci, hdr, e)
|
|||
{
|
||||
expand(p, buf, sizeof buf, e);
|
||||
p = buf;
|
||||
if (p == NULL || *p == '\0')
|
||||
if (*p == '\0')
|
||||
{
|
||||
if (tTd(34, 11))
|
||||
printf(" (skipped -- null value)\n");
|
||||
|
@ -1275,7 +1330,7 @@ put_vanilla_header(h, v, mci)
|
|||
char obuf[MAXLINE];
|
||||
|
||||
putflags = 0;
|
||||
#ifdef _FFR_7BITHDRS
|
||||
#if _FFR_7BITHDRS
|
||||
if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
|
||||
putflags |= PXLF_STRIP8BIT;
|
||||
#endif
|
||||
|
@ -1290,7 +1345,7 @@ put_vanilla_header(h, v, mci)
|
|||
l = sizeof obuf - (obp - obuf);
|
||||
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
|
||||
putxline(obuf, mci, putflags);
|
||||
putxline(obuf, strlen(obuf), mci, putflags);
|
||||
v += l + 1;
|
||||
obp = obuf;
|
||||
if (*v != ' ' && *v != '\t')
|
||||
|
@ -1298,7 +1353,7 @@ put_vanilla_header(h, v, mci)
|
|||
}
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
|
||||
sizeof obuf - (obp - obuf) - 1, v);
|
||||
putxline(obuf, mci, putflags);
|
||||
putxline(obuf, strlen(obuf), mci, putflags);
|
||||
}
|
||||
/*
|
||||
** COMMAIZE -- output a header field, making a comma-translated list.
|
||||
|
@ -1340,7 +1395,7 @@ commaize(h, p, oldstyle, mci, e)
|
|||
if (tTd(14, 2))
|
||||
printf("commaize(%s: %s)\n", h->h_field, p);
|
||||
|
||||
#ifdef _FFR_7BITHDRS
|
||||
#if _FFR_7BITHDRS
|
||||
if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
|
||||
putflags |= PXLF_STRIP8BIT;
|
||||
#endif
|
||||
|
@ -1348,6 +1403,8 @@ commaize(h, p, oldstyle, mci, e)
|
|||
obp = obuf;
|
||||
(void) snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ", h->h_field);
|
||||
opos = strlen(h->h_field) + 2;
|
||||
if (opos > 202)
|
||||
opos = 202;
|
||||
obp += opos;
|
||||
omax = mci->mci_mailer->m_linelimit - 2;
|
||||
if (omax < 0 || omax > 78)
|
||||
|
@ -1441,7 +1498,7 @@ commaize(h, p, oldstyle, mci, e)
|
|||
if (opos > omax && !firstone)
|
||||
{
|
||||
snprintf(obp, SPACELEFT(obuf, obp), ",\n");
|
||||
putxline(obuf, mci, putflags);
|
||||
putxline(obuf, strlen(obuf), mci, putflags);
|
||||
obp = obuf;
|
||||
(void) strcpy(obp, " ");
|
||||
opos = strlen(obp);
|
||||
|
@ -1460,7 +1517,7 @@ commaize(h, p, oldstyle, mci, e)
|
|||
*p = savechar;
|
||||
}
|
||||
*obp = '\0';
|
||||
putxline(obuf, mci, putflags);
|
||||
putxline(obuf, strlen(obuf), mci, putflags);
|
||||
}
|
||||
/*
|
||||
** COPYHEADER -- copy header list
|
||||
|
|
|
@ -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"
|
||||
|
|
89
usr.sbin/sendmail/src/mailq.1
Normal file
89
usr.sbin/sendmail/src/mailq.1
Normal file
|
@ -0,0 +1,89 @@
|
|||
.\" Copyright (c) 1983, 1997 Eric P. Allman
|
||||
.\" Copyright (c) 1985, 1990, 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.
|
||||
.\"
|
||||
.\" @(#)mailq.1 8.5 (Berkeley) 2/1/97
|
||||
.\"
|
||||
.Dd February 1, 1997
|
||||
.Dt MAILQ 1
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm mailq
|
||||
.Nd print the mail queue
|
||||
.Sh SYNOPSIS
|
||||
.Nm mailq
|
||||
.Op Fl v
|
||||
.Sh DESCRIPTION
|
||||
.Nm Mailq
|
||||
prints a summary of the mail messages queued for future delivery.
|
||||
.Pp
|
||||
The first line printed for each message
|
||||
shows the internal identifier used on this host
|
||||
for the message,
|
||||
the size of the message in bytes,
|
||||
the date and time the message was accepted into the queue,
|
||||
and the envelope sender of the message.
|
||||
The second line shows the error message that caused this message
|
||||
to be retained in the queue;
|
||||
it will not be present if the message is being processed
|
||||
for the first time.
|
||||
The following lines show message recipients,
|
||||
one per line.
|
||||
.Pp
|
||||
.Nm Mailq
|
||||
is identical to
|
||||
.Dq Li "sendmail -bp" .
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl v
|
||||
Print verbose information.
|
||||
This adds the priority of the message and
|
||||
a single character indicator (``+'' or blank)
|
||||
indicating whether a warning message has been sent
|
||||
on the first line of the message.
|
||||
Additionally, extra lines may be intermixed with the recipients
|
||||
indicating the ``controlling user'' information;
|
||||
this shows who will own any programs that are executed
|
||||
on behalf of this message
|
||||
and the name of the alias this command expanded from, if any.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm mailq
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr sendmail 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm mailq
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
|
@ -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.
|
||||
*
|
||||
|
@ -39,7 +39,7 @@ static char copyright[] =
|
|||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 8.230 (Berkeley) 1/17/97";
|
||||
static char sccsid[] = "@(#)main.c 8.246 (Berkeley) 6/11/97";
|
||||
#endif /* not lint */
|
||||
|
||||
#define _DEFINE
|
||||
|
@ -62,13 +62,8 @@ char edata, end;
|
|||
** turn calls a bunch of mail servers that do the real work of
|
||||
** delivering the mail.
|
||||
**
|
||||
** Sendmail is driven by tables read in from /usr/lib/sendmail.cf
|
||||
** (read by readcf.c). Some more static configuration info,
|
||||
** including some code that you may want to tailor for your
|
||||
** installation, is in conf.c. You may also want to touch
|
||||
** daemon.c (if you have some other IPC mechanism), acct.c
|
||||
** (to change your accounting), names.c (to adjust the name
|
||||
** server mechanism).
|
||||
** Sendmail is driven by settings read in from /etc/sendmail.cf
|
||||
** (read by readcf.c).
|
||||
**
|
||||
** Usage:
|
||||
** /usr/lib/sendmail [flags] addr ...
|
||||
|
@ -82,7 +77,7 @@ char edata, end;
|
|||
** International Computer Science Institute
|
||||
** (11/88 - 9/89).
|
||||
** UCB/Mammoth Project (10/89 - 7/95).
|
||||
** InReference, Inc. (8/95 - present).
|
||||
** InReference, Inc. (8/95 - 1/97).
|
||||
** The support of the my employers is gratefully acknowledged.
|
||||
** Few of them (Britton-Lee in particular) have had
|
||||
** anything to gain from my involvement in this project.
|
||||
|
@ -99,6 +94,10 @@ char *CommandLineArgs; /* command line args for pid file */
|
|||
bool Warn_Q_option = FALSE; /* warn about Q option use */
|
||||
char **SaveArgv; /* argument vector for re-execing */
|
||||
|
||||
#ifdef NGROUPS_MAX
|
||||
GIDSET_T InitialGidSet[NGROUPS_MAX];
|
||||
#endif
|
||||
|
||||
static void obsolete();
|
||||
extern void printmailer __P((MAILER *));
|
||||
extern void tTflag __P((char *));
|
||||
|
@ -219,7 +218,7 @@ main(argc, argv, envp)
|
|||
}
|
||||
errno = 0;
|
||||
|
||||
#ifdef LOG
|
||||
#if LOG
|
||||
# ifdef LOG_MAIL
|
||||
openlog("sendmail", LOG_PID, LOG_MAIL);
|
||||
# else
|
||||
|
@ -229,6 +228,15 @@ main(argc, argv, envp)
|
|||
|
||||
tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
|
||||
|
||||
#ifdef NGROUPS_MAX
|
||||
/* save initial group set for future checks */
|
||||
i = getgroups(NGROUPS_MAX, InitialGidSet);
|
||||
if (i == 0)
|
||||
InitialGidSet[0] = (GID_T) -1;
|
||||
while (i < NGROUPS_MAX)
|
||||
InitialGidSet[i++] = InitialGidSet[0];
|
||||
#endif
|
||||
|
||||
/* drop group id privileges (RunAsUser not yet set) */
|
||||
drop_privileges();
|
||||
|
||||
|
@ -489,9 +497,6 @@ main(argc, argv, envp)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* probe interfaces and locate any additional names */
|
||||
load_if_names();
|
||||
|
||||
/* current time */
|
||||
define('b', arpadate((char *) NULL), CurEnv);
|
||||
|
||||
|
@ -828,6 +833,10 @@ main(argc, argv, envp)
|
|||
expand("\201m", jbuf, sizeof jbuf, CurEnv);
|
||||
setclass('m', jbuf);
|
||||
|
||||
/* probe interfaces and locate any additional names */
|
||||
if (!DontProbeInterfaces)
|
||||
load_if_names();
|
||||
|
||||
if (tTd(0, 1))
|
||||
{
|
||||
printf("\n============ SYSTEM IDENTITY (after readcf) ============");
|
||||
|
@ -880,6 +889,10 @@ main(argc, argv, envp)
|
|||
setuserenv("TZ", NULL);
|
||||
tzset();
|
||||
|
||||
/* be sure we don't pick up bogus HOSTALIASES environment variable */
|
||||
if (queuemode && RealUid != 0)
|
||||
(void) unsetenv("HOSTALIASES");
|
||||
|
||||
/* check for sane configuration level */
|
||||
if (ConfigLevel > MAXCONFIGLEVEL)
|
||||
{
|
||||
|
@ -904,13 +917,12 @@ main(argc, argv, envp)
|
|||
/* check for permissions */
|
||||
if ((OpMode == MD_DAEMON || OpMode == MD_PURGESTAT) && RealUid != 0)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
syslog(LOG_ALERT, "user %d attempted to %s",
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"user %d attempted to %s",
|
||||
RealUid,
|
||||
OpMode == MD_DAEMON ? "run daemon"
|
||||
: "purge host status");
|
||||
#endif
|
||||
usrerr("Permission denied");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
@ -923,6 +935,8 @@ main(argc, argv, envp)
|
|||
case MD_TEST:
|
||||
/* don't have persistent host status in test mode */
|
||||
HostStatDir = NULL;
|
||||
Verbose = 2;
|
||||
CurEnv->e_errormode = EM_PRINT;
|
||||
break;
|
||||
|
||||
case MD_FGDAEMON:
|
||||
|
@ -938,10 +952,9 @@ main(argc, argv, envp)
|
|||
GrabTo = FALSE;
|
||||
|
||||
/* arrange to restart on hangup signal */
|
||||
#ifdef LOG
|
||||
if (SaveArgv[0] == NULL || SaveArgv[0][0] != '/')
|
||||
syslog(LOG_WARNING, "daemon invoked without full pathname; kill -1 won't work");
|
||||
#endif
|
||||
sm_syslog(LOG_WARNING, NOQID,
|
||||
"daemon invoked without full pathname; kill -1 won't work");
|
||||
setsignal(SIGHUP, sighup);
|
||||
|
||||
/* workaround: can't seem to release the signal in the parent */
|
||||
|
@ -949,7 +962,8 @@ main(argc, argv, envp)
|
|||
break;
|
||||
|
||||
case MD_INITALIAS:
|
||||
Verbose = TRUE;
|
||||
Verbose = 2;
|
||||
CurEnv->e_errormode = EM_PRINT;
|
||||
/* fall through... */
|
||||
|
||||
case MD_PRINT:
|
||||
|
@ -1088,17 +1102,23 @@ main(argc, argv, envp)
|
|||
#endif
|
||||
|
||||
/* operate in queue directory */
|
||||
if (OpMode == MD_TEST)
|
||||
/* nothing -- just avoid further if clauses */ ;
|
||||
else if (QueueDir == NULL)
|
||||
if (QueueDir == NULL)
|
||||
{
|
||||
syserr("QueueDirectory (Q) option must be set");
|
||||
ExitStat = EX_CONFIG;
|
||||
if (OpMode != MD_TEST)
|
||||
{
|
||||
syserr("QueueDirectory (Q) option must be set");
|
||||
ExitStat = EX_CONFIG;
|
||||
}
|
||||
}
|
||||
else if (chdir(QueueDir) < 0)
|
||||
else
|
||||
{
|
||||
syserr("cannot chdir(%s)", QueueDir);
|
||||
ExitStat = EX_CONFIG;
|
||||
/* test path to get warning messages */
|
||||
(void) safedirpath(QueueDir, (uid_t) 0, (gid_t) 0, NULL, SFF_ANYFILE);
|
||||
if (OpMode != MD_TEST && chdir(QueueDir) < 0)
|
||||
{
|
||||
syserr("cannot chdir(%s)", QueueDir);
|
||||
ExitStat = EX_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
/* check host status directory for validity */
|
||||
|
@ -1226,7 +1246,7 @@ main(argc, argv, envp)
|
|||
SIGFUNC_DECL intindebug __P((int));
|
||||
|
||||
if (isatty(fileno(stdin)))
|
||||
Verbose = TRUE;
|
||||
Verbose = 2;
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
|
@ -1261,7 +1281,6 @@ main(argc, argv, envp)
|
|||
|
||||
if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0)
|
||||
{
|
||||
(void) unsetenv("HOSTALIASES");
|
||||
(void) runqueue(FALSE, Verbose);
|
||||
finis();
|
||||
}
|
||||
|
@ -1305,9 +1324,8 @@ main(argc, argv, envp)
|
|||
if (tTd(0, 1))
|
||||
strcat(dtype, "+debugging");
|
||||
|
||||
#ifdef LOG
|
||||
syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1);
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, NOQID,
|
||||
"starting daemon (%s): %s", Version, dtype + 1);
|
||||
#ifdef XLA
|
||||
xla_create_file();
|
||||
#endif
|
||||
|
@ -1317,8 +1335,14 @@ main(argc, argv, envp)
|
|||
{
|
||||
(void) runqueue(TRUE, FALSE);
|
||||
if (OpMode != MD_DAEMON)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
pause();
|
||||
if (DoQueueRun)
|
||||
(void) runqueue(TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif /* QUEUE */
|
||||
dropenvelope(CurEnv, TRUE);
|
||||
|
@ -1402,7 +1426,7 @@ main(argc, argv, envp)
|
|||
|
||||
/* collect body for UUCP return */
|
||||
if (OpMode != MD_VERIFY)
|
||||
collect(InChannel, FALSE, FALSE, NULL, CurEnv);
|
||||
collect(InChannel, FALSE, NULL, CurEnv);
|
||||
finis();
|
||||
}
|
||||
|
||||
|
@ -1423,8 +1447,21 @@ main(argc, argv, envp)
|
|||
CurEnv->e_to = NULL;
|
||||
if (OpMode != MD_VERIFY || GrabTo)
|
||||
{
|
||||
long savedflags = CurEnv->e_flags & EF_FATALERRS;
|
||||
|
||||
CurEnv->e_flags |= EF_GLOBALERRS;
|
||||
collect(InChannel, FALSE, FALSE, NULL, CurEnv);
|
||||
CurEnv->e_flags &= ~EF_FATALERRS;
|
||||
collect(InChannel, FALSE, NULL, CurEnv);
|
||||
|
||||
/* bail out if there were fatal errors in collect */
|
||||
if (OpMode != MD_VERIFY && bitset(EF_FATALERRS, CurEnv->e_flags))
|
||||
{
|
||||
CurEnv->e_flags |= EF_CLRQUEUE;
|
||||
finis();
|
||||
/*NOTREACHED*/
|
||||
return -1;
|
||||
}
|
||||
CurEnv->e_flags |= savedflags;
|
||||
}
|
||||
errno = 0;
|
||||
|
||||
|
@ -1443,6 +1480,7 @@ main(argc, argv, envp)
|
|||
printaddr(&CurEnv->e_from, FALSE);
|
||||
}
|
||||
CurEnv->e_to = NULL;
|
||||
CurrentLA = getla();
|
||||
sendall(CurEnv, SM_DEFAULT);
|
||||
|
||||
/*
|
||||
|
@ -1493,6 +1531,13 @@ finis()
|
|||
if (tTd(2, 9))
|
||||
printopenfds(FALSE);
|
||||
|
||||
/* if we fail in finis(), just exit */
|
||||
if (setjmp(TopFrame) != 0)
|
||||
{
|
||||
/* failed -- just give it up */
|
||||
goto forceexit;
|
||||
}
|
||||
|
||||
/* clean up temp files */
|
||||
CurEnv->e_to = NULL;
|
||||
if (CurEnv->e_id != NULL)
|
||||
|
@ -1507,10 +1552,11 @@ finis()
|
|||
# endif
|
||||
|
||||
/* and exit */
|
||||
# ifdef LOG
|
||||
forceexit:
|
||||
if (LogLevel > 78)
|
||||
syslog(LOG_DEBUG, "finis, pid=%d", getpid());
|
||||
# endif /* LOG */
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"finis, pid=%d",
|
||||
getpid());
|
||||
if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET)
|
||||
ExitStat = EX_OK;
|
||||
|
||||
|
@ -1540,11 +1586,8 @@ SIGFUNC_DECL
|
|||
intsig(sig)
|
||||
int sig;
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 79)
|
||||
syslog(LOG_DEBUG, "%s: interrupt",
|
||||
CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id);
|
||||
#endif
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
|
||||
FileName = NULL;
|
||||
unlockqueue(CurEnv);
|
||||
#ifdef XLA
|
||||
|
@ -1665,11 +1708,10 @@ disconnect(droplev, e)
|
|||
printf("don't\n");
|
||||
return;
|
||||
}
|
||||
#ifdef LOG
|
||||
if (LogLevel > 93)
|
||||
syslog(LOG_DEBUG, "%s: disconnect level %d",
|
||||
e->e_id == NULL ? "[NOQUEUE]" : e->e_id, droplev);
|
||||
#endif
|
||||
sm_syslog(LOG_DEBUG, e->e_id,
|
||||
"disconnect level %d",
|
||||
droplev);
|
||||
|
||||
/* be sure we don't get nasty signals */
|
||||
(void) setsignal(SIGINT, SIG_IGN);
|
||||
|
@ -1678,7 +1720,7 @@ disconnect(droplev, e)
|
|||
/* we can't communicate with our caller, so.... */
|
||||
HoldErrs = TRUE;
|
||||
CurEnv->e_errormode = EM_MAIL;
|
||||
Verbose = FALSE;
|
||||
Verbose = 0;
|
||||
DisConnected = TRUE;
|
||||
|
||||
/* all input from /dev/null */
|
||||
|
@ -1719,10 +1761,10 @@ disconnect(droplev, e)
|
|||
checkfd012("disconnect");
|
||||
#endif
|
||||
|
||||
# ifdef LOG
|
||||
if (LogLevel > 71)
|
||||
syslog(LOG_DEBUG, "in background, pid=%d", getpid());
|
||||
# endif /* LOG */
|
||||
sm_syslog(LOG_DEBUG, e->e_id,
|
||||
"in background, pid=%d",
|
||||
getpid());
|
||||
|
||||
errno = 0;
|
||||
}
|
||||
|
@ -1822,11 +1864,10 @@ auth_warning(e, msg, va_alist)
|
|||
vsnprintf(p, SPACELEFT(buf, p), msg, ap);
|
||||
VA_END;
|
||||
addheader("X-Authentication-Warning", buf, &e->e_header);
|
||||
#ifdef LOG
|
||||
if (LogLevel > 3)
|
||||
syslog(LOG_INFO, "%s: Authentication-Warning: %.400s",
|
||||
e->e_id == NULL ? "[NOQUEUE]" : e->e_id, buf);
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"Authentication-Warning: %.400s",
|
||||
buf);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -1916,22 +1957,23 @@ void
|
|||
dumpstate(when)
|
||||
char *when;
|
||||
{
|
||||
#ifdef LOG
|
||||
register char *j = macvalue('j', CurEnv);
|
||||
int rs;
|
||||
|
||||
syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"--- dumping state on %s: $j = %s ---",
|
||||
when,
|
||||
j == NULL ? "<NULL>" : j);
|
||||
if (j != NULL)
|
||||
{
|
||||
if (!wordinclass(j, 'w'))
|
||||
syslog(LOG_DEBUG, "*** $j not in $=w ***");
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"*** $j not in $=w ***");
|
||||
}
|
||||
syslog(LOG_DEBUG, "CurChildren = %d", CurChildren);
|
||||
syslog(LOG_DEBUG, "--- open file descriptors: ---");
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "CurChildren = %d", CurChildren);
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- open file descriptors: ---");
|
||||
printopenfds(TRUE);
|
||||
syslog(LOG_DEBUG, "--- connection cache: ---");
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- connection cache: ---");
|
||||
mci_dump_all(TRUE);
|
||||
rs = strtorwset("debug_dumpstate", NULL, ST_FIND);
|
||||
if (rs > 0)
|
||||
|
@ -1942,14 +1984,13 @@ dumpstate(when)
|
|||
|
||||
pv[0] = NULL;
|
||||
stat = rewrite(pv, rs, 0, CurEnv);
|
||||
syslog(LOG_DEBUG,
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"--- ruleset debug_dumpstate returns stat %d, pv: ---",
|
||||
stat);
|
||||
for (pvp = pv; *pvp != NULL; pvp++)
|
||||
syslog(LOG_DEBUG, "%s", *pvp);
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "%s", *pvp);
|
||||
}
|
||||
syslog(LOG_DEBUG, "--- end of state dump ---");
|
||||
#endif
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- end of state dump ---");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1968,31 +2009,24 @@ sighup(sig)
|
|||
{
|
||||
if (SaveArgv[0][0] != '/')
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 3)
|
||||
syslog(LOG_INFO, "could not restart: need full path");
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, NOQID, "could not restart: need full path");
|
||||
exit(EX_OSFILE);
|
||||
}
|
||||
#ifdef LOG
|
||||
if (LogLevel > 3)
|
||||
syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]);
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, NOQID, "restarting %s on signal", SaveArgv[0]);
|
||||
alarm(0);
|
||||
releasesignal(SIGHUP);
|
||||
if (setgid(RealGid) < 0 || setuid(RealUid) < 0)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 0)
|
||||
syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m",
|
||||
sm_syslog(LOG_ALERT, NOQID, "could not set[ug]id(%d, %d): %m",
|
||||
RealUid, RealGid);
|
||||
#endif
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
execv(SaveArgv[0], (ARGV_T) SaveArgv);
|
||||
#ifdef LOG
|
||||
if (LogLevel > 0)
|
||||
syslog(LOG_ALERT, "could not exec %s: %m", SaveArgv[0]);
|
||||
#endif
|
||||
sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m", SaveArgv[0]);
|
||||
exit(EX_OSFILE);
|
||||
}
|
||||
/*
|
||||
|
@ -2285,6 +2319,11 @@ testmodeline(line, e)
|
|||
printf("Map named \"%s\" not found\n", p);
|
||||
return;
|
||||
}
|
||||
if (!bitset(MF_OPEN, map->s_map.map_mflags))
|
||||
{
|
||||
printf("Map named \"%s\" not open\n", p);
|
||||
return;
|
||||
}
|
||||
printf("map_lookup: %s (%s) ", p, q);
|
||||
p = (*map->s_map.map_class->map_lookup)
|
||||
(&map->s_map, q, NULL, &rcode);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 1993, 1996 Eric P. Allman
|
||||
# Copyright (c) 1993, 1996-1997 Eric P. Allman
|
||||
# Copyright (c) 1993 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -32,7 +32,7 @@
|
|||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)makesendmail 8.42 (Berkeley) 11/10/96
|
||||
# @(#)makesendmail 8.45 (Berkeley) 4/12/97
|
||||
#
|
||||
|
||||
#
|
||||
|
@ -115,6 +115,16 @@ then
|
|||
# old versions of SCO UNIX set uname -s the same as uname -n
|
||||
os=SCO_SV
|
||||
fi
|
||||
if [ "$os" = "$node" -a "$rel" = 4.0 -a "$arch" = "3360,3430-R" ]
|
||||
then
|
||||
# AT&T/NCR Machines also set uname -s == uname -n
|
||||
if [ -d /usr/sadm/sysadm/add-ons/WIN-TCP ]
|
||||
then
|
||||
os=NCR.MP-RAS.2.x
|
||||
else
|
||||
os=NCR.MP-RAS.3.x
|
||||
fi
|
||||
fi
|
||||
|
||||
case $os
|
||||
in
|
||||
|
@ -133,6 +143,7 @@ in
|
|||
os="UXPDS"
|
||||
rel=`uname -v | sed -e 's/\(V.*\)L.*/\1/'`
|
||||
fi;;
|
||||
SINIX-?) os=SINIX;;
|
||||
esac
|
||||
|
||||
# get "base part" of operating system release
|
||||
|
|
|
@ -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,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1994, 1996 Eric P. Allman
|
||||
* Copyright (c) 1994, 1996-1997 Eric P. Allman
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
|
@ -36,7 +36,7 @@
|
|||
# include <string.h>
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mime.c 8.54 (Berkeley) 1/14/97";
|
||||
static char sccsid[] = "@(#)mime.c 8.59 (Berkeley) 5/6/97";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -259,10 +259,10 @@ mime8to7(mci, header, e, boundaries, flags)
|
|||
if (strcasecmp(argv[i].field, "boundary") == 0)
|
||||
break;
|
||||
}
|
||||
if (i >= argc)
|
||||
if (i >= argc || argv[i].value == NULL)
|
||||
{
|
||||
syserr("mime8to7: Content-Type: \"%s\": missing boundary",
|
||||
p);
|
||||
syserr("mime8to7: Content-Type: \"%s\": %s boundary",
|
||||
i >= argc ? "missing" : "bogus", p);
|
||||
p = "---";
|
||||
|
||||
/* avoid bounce loops */
|
||||
|
@ -311,7 +311,7 @@ mime8to7(mci, header, e, boundaries, flags)
|
|||
bt = mimeboundary(buf, boundaries);
|
||||
if (bt != MBT_NOTSEP)
|
||||
break;
|
||||
putxline(buf, mci, PXLF_MAPFROM|PXLF_STRIP8BIT);
|
||||
putxline(buf, strlen(buf), mci, PXLF_MAPFROM|PXLF_STRIP8BIT);
|
||||
if (tTd(43, 99))
|
||||
printf(" ...%s", buf);
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ mime8to7(mci, header, e, boundaries, flags)
|
|||
putline(buf, mci);
|
||||
if (tTd(43, 35))
|
||||
printf(" ...%s\n", buf);
|
||||
collect(e->e_dfp, FALSE, FALSE, &hdr, e);
|
||||
collect(e->e_dfp, FALSE, &hdr, e);
|
||||
if (tTd(43, 101))
|
||||
putline("+++after collect", mci);
|
||||
putheader(mci, hdr, e);
|
||||
|
@ -346,7 +346,7 @@ mime8to7(mci, header, e, boundaries, flags)
|
|||
bt = mimeboundary(buf, boundaries);
|
||||
if (bt != MBT_NOTSEP)
|
||||
break;
|
||||
putxline(buf, mci, PXLF_MAPFROM|PXLF_STRIP8BIT);
|
||||
putxline(buf, strlen(buf), mci, PXLF_MAPFROM|PXLF_STRIP8BIT);
|
||||
if (tTd(43, 99))
|
||||
printf(" ...%s", buf);
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ mime8to7(mci, header, e, boundaries, flags)
|
|||
putline("", mci);
|
||||
|
||||
mci->mci_flags |= MCIF_INMIME;
|
||||
collect(e->e_dfp, FALSE, FALSE, &hdr, e);
|
||||
collect(e->e_dfp, FALSE, &hdr, e);
|
||||
if (tTd(43, 101))
|
||||
putline("+++after collect", mci);
|
||||
putheader(mci, hdr, e);
|
||||
|
@ -1048,8 +1048,8 @@ mime7to8(mci, header, e)
|
|||
if (*--fbufp != '\n' ||
|
||||
(fbufp > fbuf && *--fbufp != '\r'))
|
||||
fbufp++;
|
||||
*fbufp = '\0';
|
||||
putline((char *) fbuf, mci);
|
||||
putxline((char *) fbuf, fbufp - fbuf,
|
||||
mci, PXLF_MAPFROM);
|
||||
fbufp = fbuf;
|
||||
}
|
||||
if (c3 == '=')
|
||||
|
@ -1061,8 +1061,8 @@ mime7to8(mci, header, e)
|
|||
if (*--fbufp != '\n' ||
|
||||
(fbufp > fbuf && *--fbufp != '\r'))
|
||||
fbufp++;
|
||||
*fbufp = '\0';
|
||||
putline((char *) fbuf, mci);
|
||||
putxline((char *) fbuf, fbufp - fbuf,
|
||||
mci, PXLF_MAPFROM);
|
||||
fbufp = fbuf;
|
||||
}
|
||||
if (c4 == '=')
|
||||
|
@ -1074,8 +1074,8 @@ mime7to8(mci, header, e)
|
|||
if (*--fbufp != '\n' ||
|
||||
(fbufp > fbuf && *--fbufp != '\r'))
|
||||
fbufp++;
|
||||
*fbufp = '\0';
|
||||
putline((char *) fbuf, mci);
|
||||
putxline((char *) fbuf, fbufp - fbuf,
|
||||
mci, PXLF_MAPFROM);
|
||||
fbufp = fbuf;
|
||||
}
|
||||
}
|
||||
|
@ -1090,7 +1090,9 @@ mime7to8(mci, header, e)
|
|||
&fbuf[MAXLINE] - fbufp) == 0)
|
||||
continue;
|
||||
|
||||
putline((char *) fbuf, mci);
|
||||
if (fbufp - fbuf > 0)
|
||||
putxline((char *) fbuf, fbufp - fbuf - 1, mci,
|
||||
PXLF_MAPFROM);
|
||||
fbufp = fbuf;
|
||||
}
|
||||
}
|
||||
|
@ -1099,7 +1101,7 @@ mime7to8(mci, header, e)
|
|||
if (fbufp > fbuf)
|
||||
{
|
||||
*fbufp = '\0';
|
||||
putline((char *) fbuf, mci);
|
||||
putxline((char *) fbuf, fbufp - fbuf, mci, PXLF_MAPFROM);
|
||||
}
|
||||
if (tTd(43, 3))
|
||||
printf("\t\t\tmime7to8 => %s to 8bit done\n", cte);
|
||||
|
|
69
usr.sbin/sendmail/src/newaliases.1
Normal file
69
usr.sbin/sendmail/src/newaliases.1
Normal file
|
@ -0,0 +1,69 @@
|
|||
.\" Copyright (c) 1983, 1997 Eric P. Allman
|
||||
.\" Copyright (c) 1985, 1990, 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.
|
||||
.\"
|
||||
.\" @(#)newaliases.1 8.5 (Berkeley) 2/1/97
|
||||
.\"
|
||||
.Dd February 1, 1997
|
||||
.Dt NEWALIASES 1
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm newaliases
|
||||
.Nd rebuild the data base for the mail aliases file
|
||||
.Sh SYNOPSIS
|
||||
.Nm newaliases
|
||||
.Sh DESCRIPTION
|
||||
.Nm Newaliases
|
||||
rebuilds the random access data base for the mail aliases file
|
||||
.Pa /etc/aliases .
|
||||
It must be run each time this file is changed in order
|
||||
for the change to take effect.
|
||||
.Pp
|
||||
.Nm Newaliases
|
||||
is identical to
|
||||
.Dq Li "sendmail -bi" .
|
||||
.Pp
|
||||
The
|
||||
.Nm newaliases
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/aliases -compact
|
||||
.It Pa /etc/aliases
|
||||
The mail aliases file
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr aliases 5 ,
|
||||
.Xr sendmail 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm newaliases
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
|
@ -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[] = "@(#)parseaddr.c 8.115 (Berkeley) 11/24/96";
|
||||
static char sccsid[] = "@(#)parseaddr.c 8.128 (Berkeley) 6/14/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
|
@ -220,6 +220,11 @@ invalidaddr(addr, delimptr)
|
|||
if (savedelim != '\0')
|
||||
*delimptr = '\0';
|
||||
}
|
||||
if (strlen(addr) > TOBUFSIZE - 2)
|
||||
{
|
||||
usrerr("553 Address too long (%d bytes max)", TOBUFSIZE - 2);
|
||||
goto failure;
|
||||
}
|
||||
for (; *addr != '\0'; addr++)
|
||||
{
|
||||
if ((*addr & 0340) == 0200)
|
||||
|
@ -233,6 +238,7 @@ invalidaddr(addr, delimptr)
|
|||
}
|
||||
setstat(EX_USAGE);
|
||||
usrerr("553 Address contained invalid control characters");
|
||||
failure:
|
||||
if (delimptr != NULL && savedelim != '\0')
|
||||
*delimptr = savedelim;
|
||||
return TRUE;
|
||||
|
@ -756,6 +762,7 @@ rewrite(pvp, ruleset, reclevel, e)
|
|||
struct match mlist[MAXMATCH]; /* stores match on LHS */
|
||||
char *npvp[MAXATOM+1]; /* temporary space for rebuild */
|
||||
extern int callsubr __P((char**, int, ENVELOPE *));
|
||||
extern int sm_strcasecmp __P((char *, char *));
|
||||
|
||||
if (OpMode == MD_TEST || tTd(21, 1))
|
||||
{
|
||||
|
@ -930,7 +937,7 @@ rewrite(pvp, ruleset, reclevel, e)
|
|||
|
||||
default:
|
||||
/* must have exact match */
|
||||
if (strcasecmp(rp, ap))
|
||||
if (sm_strcasecmp(rp, ap))
|
||||
goto backup;
|
||||
avp++;
|
||||
break;
|
||||
|
@ -1436,7 +1443,7 @@ map_lookup(map, key, argvect, pstat, e)
|
|||
map->s_name, key, errno);
|
||||
if (e->e_message == NULL)
|
||||
{
|
||||
char mbuf[300];
|
||||
char mbuf[320];
|
||||
|
||||
snprintf(mbuf, sizeof mbuf,
|
||||
"%.80s map: lookup (%s): deferred",
|
||||
|
@ -2106,6 +2113,10 @@ remotename(name, m, flags, pstat, e)
|
|||
** none.
|
||||
*/
|
||||
|
||||
#define Q_COPYFLAGS (QPRIMARY|QBOGUSSHELL|QUNSAFEADDR|\
|
||||
Q_PINGFLAGS|QHASNOTIFY|\
|
||||
QRELAYED|QEXPANDED|QDELIVERED|QDELAYED)
|
||||
|
||||
void
|
||||
maplocaluser(a, sendq, aliaslevel, e)
|
||||
register ADDRESS *a;
|
||||
|
@ -2127,6 +2138,10 @@ maplocaluser(a, sendq, aliaslevel, e)
|
|||
if (pvp == NULL)
|
||||
return;
|
||||
|
||||
define('h', a->q_host, e);
|
||||
define('u', a->q_user, e);
|
||||
define('z', a->q_home, e);
|
||||
|
||||
if (rewrite(pvp, 5, 0, e) == EX_TEMPFAIL)
|
||||
{
|
||||
a->q_flags |= QQUEUEUP;
|
||||
|
@ -2139,7 +2154,16 @@ maplocaluser(a, sendq, aliaslevel, e)
|
|||
/* if non-null, mailer destination specified -- has it changed? */
|
||||
a1 = buildaddr(pvp, NULL, 0, e);
|
||||
if (a1 == NULL || sameaddr(a, a1))
|
||||
{
|
||||
if (a1 != NULL)
|
||||
free(a1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make new address take on flags and print attributes of old */
|
||||
a1->q_flags &= ~Q_COPYFLAGS;
|
||||
a1->q_flags |= a->q_flags & Q_COPYFLAGS;
|
||||
a1->q_paddr = a->q_paddr;
|
||||
|
||||
/* mark old address as dead; insert new address */
|
||||
a->q_flags |= QDONTSEND;
|
||||
|
@ -2324,6 +2348,8 @@ rscheck(rwset, p1, p2, e)
|
|||
int rsno;
|
||||
auto ADDRESS a1;
|
||||
bool saveQuickAbort = QuickAbort;
|
||||
bool saveSuprErrs = SuprErrs;
|
||||
bool saveOnlyOneError = OnlyOneError;
|
||||
char buf0[MAXLINE];
|
||||
char pvpbuf[PSBUFSIZE];
|
||||
extern char MsgBuf[];
|
||||
|
@ -2360,44 +2386,52 @@ rscheck(rwset, p1, p2, e)
|
|||
}
|
||||
(void) snprintf(buf, bufsize, "%s", p1);
|
||||
}
|
||||
SuprErrs = TRUE;
|
||||
OnlyOneError = QuickAbort = FALSE;
|
||||
pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
|
||||
SuprErrs = saveSuprErrs;
|
||||
if (pvp == NULL)
|
||||
{
|
||||
syserr("rscheck: cannot prescan input: \"%s\"",
|
||||
shortenstring(buf, 203));
|
||||
rstat = EX_DATAERR;
|
||||
goto finis;
|
||||
}
|
||||
(void) rewrite(pvp, rsno, 0, e);
|
||||
if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET ||
|
||||
pvp[1] == NULL || strcmp(pvp[1], "error") != 0)
|
||||
return EX_OK;
|
||||
{
|
||||
rstat = EX_OK;
|
||||
goto finis;
|
||||
}
|
||||
|
||||
/* got an error -- process it */
|
||||
saveexitstat = ExitStat;
|
||||
QuickAbort = FALSE;
|
||||
(void) buildaddr(pvp, &a1, 0, e);
|
||||
QuickAbort = saveQuickAbort;
|
||||
rstat = ExitStat;
|
||||
ExitStat = saveexitstat;
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 4)
|
||||
{
|
||||
if (p2 == NULL)
|
||||
syslog(LOG_NOTICE, "Ruleset %s (%s) rejection: %s",
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"Ruleset %s (%s) rejection: %s",
|
||||
rwset, p1, MsgBuf);
|
||||
else
|
||||
syslog(LOG_NOTICE, "Ruleset %s (%s, %s) rejection: %s",
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"Ruleset %s (%s, %s) rejection: %s",
|
||||
rwset, p1, p2, MsgBuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (QuickAbort)
|
||||
longjmp(TopFrame, 2);
|
||||
|
||||
/* clean up */
|
||||
finis:
|
||||
/* clean up */
|
||||
QuickAbort = saveQuickAbort;
|
||||
OnlyOneError = saveOnlyOneError;
|
||||
setstat(rstat);
|
||||
if (buf != buf0)
|
||||
free(buf);
|
||||
|
||||
if (rstat != EX_OK && (QuickAbort || (OnlyOneError && !HoldErrs)))
|
||||
longjmp(TopFrame, 2);
|
||||
return rstat;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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[] = "@(#)readcf.c 8.184 (Berkeley) 1/14/97";
|
||||
static char sccsid[] = "@(#)readcf.c 8.196 (Berkeley) 5/29/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
|
@ -121,7 +121,7 @@ readcf(cfname, safe, e)
|
|||
FileName = cfname;
|
||||
LineNumber = 0;
|
||||
|
||||
cf = fopen(cfname, "r");
|
||||
cf = safefopen(cfname, O_RDONLY, 0444, SFF_OPENASROOT|SFF_NOLOCK);
|
||||
if (cf == NULL)
|
||||
{
|
||||
syserr("cannot open");
|
||||
|
@ -145,11 +145,10 @@ readcf(cfname, safe, e)
|
|||
if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS)
|
||||
fprintf(stderr, "%s: WARNING: dangerous write permissions\n",
|
||||
FileName);
|
||||
#ifdef LOG
|
||||
if (LogLevel > 0)
|
||||
syslog(LOG_CRIT, "%s: WARNING: dangerous write permissions",
|
||||
sm_syslog(LOG_CRIT, NOQID,
|
||||
"%s: WARNING: dangerous write permissions",
|
||||
FileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XLA
|
||||
|
@ -745,7 +744,7 @@ fileclass(class, filename, fmt, safe, optional)
|
|||
else
|
||||
{
|
||||
pid = -1;
|
||||
sff = SFF_REGONLY;
|
||||
sff = SFF_REGONLY|SFF_NOWLINK;
|
||||
if (safe)
|
||||
sff |= SFF_OPENASROOT;
|
||||
f = safefopen(filename, O_RDONLY, 0, sff);
|
||||
|
@ -761,7 +760,7 @@ fileclass(class, filename, fmt, safe, optional)
|
|||
{
|
||||
register char *p;
|
||||
# if SCANF
|
||||
char wordbuf[MAXNAME+1];
|
||||
char wordbuf[MAXLINE + 1];
|
||||
# endif
|
||||
|
||||
if (buf[0] == '#')
|
||||
|
@ -1482,14 +1481,30 @@ struct optioninfo
|
|||
{ "SingleThreadDelivery", O_SINGTHREAD, FALSE },
|
||||
#define O_RUNASUSER 0x9d
|
||||
{ "RunAsUser", O_RUNASUSER, FALSE },
|
||||
#ifdef _FFR_DSN_RRT
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
#define O_DSN_RRT 0x9e
|
||||
{ "RrtImpliesDsn", O_DSN_RRT, FALSE },
|
||||
#endif
|
||||
#ifdef _FFR_PIDFILE_OPT
|
||||
#if _FFR_PIDFILE_OPTION
|
||||
#define O_PIDFILE 0x9f
|
||||
{ "PidFile", O_PIDFILE, FALSE },
|
||||
#endif
|
||||
#if _FFR_WRITABLE_DIRECTORIES_ARE_FATAL_OPTION
|
||||
#define O_WDAF 0xa0
|
||||
{ "WritableDirectoriesAreFatal", O_WDAF, FALSE },
|
||||
#endif
|
||||
#if _FFR_CHOWN_IS_ALWAYS_SAFE_OPTION
|
||||
#define O_CIAS 0xa1
|
||||
{ "ChownIsAlwaysSafe", O_CIAS, FALSE },
|
||||
#endif
|
||||
#if _FFR_DONT_PROBE_INTERFACES_OPTION
|
||||
#define O_DPI 0xa2
|
||||
{ "DontProbeInterfaces", O_DPI, FALSE },
|
||||
#endif
|
||||
#if _FFR_MAXRCPT_OPTION
|
||||
#define O_MAXRCPT 0xa3
|
||||
{ "MaxRecipientPerMessage", O_MAXRCPT, FALSE },
|
||||
#endif
|
||||
|
||||
{ NULL, '\0', FALSE }
|
||||
};
|
||||
|
@ -1575,9 +1590,9 @@ setoption(opt, val, safe, sticky, e)
|
|||
}
|
||||
if (strlen(val) != strlen(o->o_name))
|
||||
{
|
||||
bool oldVerbose = Verbose;
|
||||
int oldVerbose = Verbose;
|
||||
|
||||
Verbose = TRUE;
|
||||
Verbose = 1;
|
||||
message("Option %s used as abbreviation for %s",
|
||||
val, o->o_name);
|
||||
Verbose = oldVerbose;
|
||||
|
@ -2061,7 +2076,7 @@ setoption(opt, val, safe, sticky, e)
|
|||
break;
|
||||
|
||||
case 'v': /* run in verbose mode */
|
||||
Verbose = atobool(val);
|
||||
Verbose = atobool(val) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 'w': /* if we are best MX, try host directly */
|
||||
|
@ -2251,6 +2266,8 @@ setoption(opt, val, safe, sticky, e)
|
|||
syserr("readcf: option RunAsUser: unknown user %s", val);
|
||||
else
|
||||
{
|
||||
if (*p == '\0')
|
||||
RunAsUserName = newstr(val);
|
||||
RunAsUid = pw->pw_uid;
|
||||
RunAsGid = pw->pw_gid;
|
||||
}
|
||||
|
@ -2258,7 +2275,7 @@ setoption(opt, val, safe, sticky, e)
|
|||
if (*p == '\0')
|
||||
break;
|
||||
if (isascii(*p) && isdigit(*p))
|
||||
DefGid = atoi(p);
|
||||
RunAsGid = atoi(p);
|
||||
else
|
||||
{
|
||||
register struct group *gr;
|
||||
|
@ -2272,16 +2289,40 @@ setoption(opt, val, safe, sticky, e)
|
|||
}
|
||||
break;
|
||||
|
||||
#ifdef _FFR_DSN_RRT
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
case O_DSN_RRT:
|
||||
RrtImpliesDsn = atobool(p);
|
||||
RrtImpliesDsn = atobool(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef _FFR_PIDFILE_OPT
|
||||
#if _FFR_PIDFILE_OPTION
|
||||
case O_PIDFILE:
|
||||
free(PidFile);
|
||||
PidFile = newstr(p);
|
||||
PidFile = newstr(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if _FFR_WRITABLE_DIRECTORIES_ARE_FATAL_OPTION
|
||||
case O_WDAF:
|
||||
FatalWritableDirs = atobool(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if _FFR_CHOWN_IS_ALWAYS_SAFE_OPTION
|
||||
case O_CIAS:
|
||||
ChownIsAlwaysSafe = atobool(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if _FFR_DONT_PROBE_INTERFACES_OPTION
|
||||
case O_DPI:
|
||||
DontProbeInterfaces = atobool(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if _FFR_MAXRCPT_OPTION
|
||||
case O_MAXRCPT:
|
||||
MaxRcptPerMsg = atoi(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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[] = "@(#)recipient.c 8.118 (Berkeley) 12/1/96";
|
||||
static char sccsid[] = "@(#)recipient.c 8.130 (Berkeley) 5/29/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
|
@ -76,7 +76,6 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
|
|||
{
|
||||
register char *p;
|
||||
register ADDRESS *al; /* list of addresses to send to */
|
||||
bool firstone; /* set on first address sent */
|
||||
char delimiter; /* the address delimiter */
|
||||
int naddrs;
|
||||
int i;
|
||||
|
@ -105,7 +104,6 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
|
|||
if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL)
|
||||
delimiter = ',';
|
||||
|
||||
firstone = TRUE;
|
||||
al = NULL;
|
||||
naddrs = 0;
|
||||
|
||||
|
@ -185,7 +183,6 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
|
|||
}
|
||||
|
||||
al = a;
|
||||
firstone = FALSE;
|
||||
}
|
||||
|
||||
/* arrange to send to everyone on the local send list */
|
||||
|
@ -303,8 +300,12 @@ recipient(a, sendq, aliaslevel, e)
|
|||
{
|
||||
a->q_flags |= QBADADDR;
|
||||
a->q_status = "5.7.1";
|
||||
usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs",
|
||||
a->q_alias->q_ruser, MyHostName);
|
||||
if (a->q_alias->q_ruser == NULL)
|
||||
usrerr("550 UID %d is an unknown user: cannot mail to programs",
|
||||
a->q_alias->q_uid);
|
||||
else
|
||||
usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs",
|
||||
a->q_alias->q_ruser, MyHostName);
|
||||
}
|
||||
else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
|
||||
{
|
||||
|
@ -378,13 +379,11 @@ recipient(a, sendq, aliaslevel, e)
|
|||
ret = include(a->q_user, FALSE, a, sendq, aliaslevel, e);
|
||||
if (transienterror(ret))
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 2)
|
||||
syslog(LOG_ERR, "%s: include %s: transient error: %s",
|
||||
e->e_id == NULL ? "NOQUEUE" : e->e_id,
|
||||
sm_syslog(LOG_ERR, e->e_id,
|
||||
"include %s: transient error: %s",
|
||||
shortenstring(a->q_user, 203),
|
||||
errstring(ret));
|
||||
#endif
|
||||
a->q_flags |= QQUEUEUP;
|
||||
a->q_flags &= ~QDONTSEND;
|
||||
usrerr("451 Cannot open %s: %s",
|
||||
|
@ -416,8 +415,12 @@ recipient(a, sendq, aliaslevel, e)
|
|||
{
|
||||
a->q_flags |= QBADADDR;
|
||||
a->q_status = "5.7.1";
|
||||
usrerr("550 User %s@%s doesn't have a valid shell for mailing to files",
|
||||
a->q_alias->q_ruser, MyHostName);
|
||||
if (a->q_alias->q_ruser == NULL)
|
||||
usrerr("550 UID %d is an unknown user: cannot mail to files",
|
||||
a->q_alias->q_uid);
|
||||
else
|
||||
usrerr("550 User %s@%s doesn't have a valid shell for mailing to files",
|
||||
a->q_alias->q_ruser, MyHostName);
|
||||
}
|
||||
else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
|
||||
{
|
||||
|
@ -426,6 +429,10 @@ recipient(a, sendq, aliaslevel, e)
|
|||
usrerr("550 Address %s is unsafe for mailing to files",
|
||||
a->q_alias->q_paddr);
|
||||
}
|
||||
else if (strcmp(buf, "/dev/null") == 0)
|
||||
{
|
||||
/* /dev/null is always accepted */
|
||||
}
|
||||
else if (!writable(buf, a->q_alias, SFF_CREAT))
|
||||
{
|
||||
a->q_flags |= QBADADDR;
|
||||
|
@ -451,12 +458,10 @@ recipient(a, sendq, aliaslevel, e)
|
|||
a->q_flags |= QQUEUEUP;
|
||||
if (e->e_message == NULL)
|
||||
e->e_message = newstr("Deferred: user database error");
|
||||
# ifdef LOG
|
||||
if (LogLevel > 8)
|
||||
syslog(LOG_INFO, "%s: deferred: udbexpand: %s",
|
||||
e->e_id == NULL ? "NOQUEUE" : e->e_id,
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"deferred: udbexpand: %s",
|
||||
errstring(errno));
|
||||
# endif
|
||||
message("queued (user database error): %s",
|
||||
errstring(errno));
|
||||
e->e_nrcpts++;
|
||||
|
@ -808,7 +813,13 @@ writable(filename, ctladdr, flags)
|
|||
** File does exist -- check that it is writable.
|
||||
*/
|
||||
|
||||
if (ctladdr != NULL && geteuid() == 0)
|
||||
if (geteuid() != 0)
|
||||
{
|
||||
euid = geteuid();
|
||||
egid = getegid();
|
||||
uname = NULL;
|
||||
}
|
||||
else if (ctladdr != NULL)
|
||||
{
|
||||
euid = ctladdr->q_uid;
|
||||
egid = ctladdr->q_gid;
|
||||
|
@ -844,6 +855,7 @@ writable(filename, ctladdr, flags)
|
|||
if (geteuid() == 0 &&
|
||||
(ctladdr == NULL || !bitset(QGOODUID, ctladdr->q_flags)))
|
||||
flags |= SFF_SETUIDOK;
|
||||
flags |= SFF_NOLINK;
|
||||
|
||||
errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL);
|
||||
return errno == 0;
|
||||
|
@ -908,25 +920,11 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
char *volatile uname;
|
||||
int rval = 0;
|
||||
volatile int sfflags = SFF_REGONLY;
|
||||
register char *p;
|
||||
bool safechown = FALSE;
|
||||
bool safedir = FALSE;
|
||||
struct stat st;
|
||||
char buf[MAXLINE];
|
||||
#ifdef _POSIX_CHOWN_RESTRICTED
|
||||
# if _POSIX_CHOWN_RESTRICTED == -1
|
||||
# define safechown FALSE
|
||||
# else
|
||||
# define safechown TRUE
|
||||
# endif
|
||||
#else
|
||||
# ifdef _PC_CHOWN_RESTRICTED
|
||||
bool safechown;
|
||||
# else
|
||||
# ifdef BSD
|
||||
# define safechown TRUE
|
||||
# else
|
||||
# define safechown FALSE
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
extern bool chownsafe();
|
||||
|
||||
if (tTd(27, 2))
|
||||
|
@ -1000,7 +998,7 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
errno = 0;
|
||||
|
||||
/* return pseudo-error code */
|
||||
rval = EOPENTIMEOUT;
|
||||
rval = E_SM_OPENTIMEOUT;
|
||||
goto resetuid;
|
||||
}
|
||||
if (TimeOuts.to_fileopen > 0)
|
||||
|
@ -1008,8 +1006,25 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
else
|
||||
ev = NULL;
|
||||
|
||||
/* the input file must be marked safe */
|
||||
rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL);
|
||||
/* check for writable parent directory */
|
||||
p = strrchr(fname, '/');
|
||||
if (p != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
if (safedirpath(fname, uid, gid, uname, sfflags|SFF_SAFEDIRPATH) == 0)
|
||||
{
|
||||
/* in safe directory: relax chown & link rules */
|
||||
safedir = TRUE;
|
||||
sfflags |= SFF_NOPATHCHECK;
|
||||
}
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
/* allow links only in unwritable directories */
|
||||
if (!safedir)
|
||||
sfflags |= SFF_NOLINK;
|
||||
|
||||
rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, &st);
|
||||
if (rval != 0)
|
||||
{
|
||||
/* don't use this :include: file */
|
||||
|
@ -1017,15 +1032,17 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
printf("include: not safe (uid=%d): %s\n",
|
||||
(int) uid, errstring(rval));
|
||||
}
|
||||
else
|
||||
else if ((fp = fopen(fname, "r")) == NULL)
|
||||
{
|
||||
fp = fopen(fname, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
rval = errno;
|
||||
if (tTd(27, 4))
|
||||
printf("include: open: %s\n", errstring(rval));
|
||||
}
|
||||
rval = errno;
|
||||
if (tTd(27, 4))
|
||||
printf("include: open: %s\n", errstring(rval));
|
||||
}
|
||||
else if (filechanged(fname, fileno(fp), &st, sfflags))
|
||||
{
|
||||
rval = E_SM_FILECHANGE;
|
||||
if (tTd(27, 4))
|
||||
printf("include: file changed after open\n");
|
||||
}
|
||||
if (ev != NULL)
|
||||
clrevent(ev);
|
||||
|
@ -1058,7 +1075,7 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
printf("include: reset uid = %d/%d\n",
|
||||
(int) getuid(), (int) geteuid());
|
||||
|
||||
if (rval == EOPENTIMEOUT)
|
||||
if (rval == E_SM_OPENTIMEOUT)
|
||||
usrerr("451 open timeout on %s", fname);
|
||||
|
||||
if (fp == NULL)
|
||||
|
@ -1071,9 +1088,14 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
return rval;
|
||||
}
|
||||
|
||||
#ifndef safechown
|
||||
safechown = chownsafe(fileno(fp));
|
||||
#endif
|
||||
/* if path was writable, check to avoid file giveaway tricks */
|
||||
safechown = chownsafe(fileno(fp), safedir);
|
||||
if (tTd(27, 6))
|
||||
printf("include: parent of %s is %s, chown is %ssafe\n",
|
||||
fname,
|
||||
safedir ? "safe" : "dangerous",
|
||||
safechown ? "" : "un");
|
||||
|
||||
if (ca == NULL && safechown)
|
||||
{
|
||||
ctladdr->q_uid = st.st_uid;
|
||||
|
@ -1104,13 +1126,12 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
sh = "/SENDMAIL/ANY/SHELL/";
|
||||
if (!usershellok(pw->pw_name, sh))
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 12)
|
||||
syslog(LOG_INFO, "%s: user %s has bad shell %s, marked %s",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%s: user %s has bad shell %s, marked %s",
|
||||
shortenstring(fname, 203),
|
||||
pw->pw_name, sh,
|
||||
safechown ? "bogus" : "unsafe");
|
||||
#endif
|
||||
if (safechown)
|
||||
ctladdr->q_flags |= QBOGUSSHELL;
|
||||
else
|
||||
|
@ -1141,13 +1162,12 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
|
||||
if (bitset(S_IWOTH | (UnsafeGroupWrites ? S_IWGRP : 0), st.st_mode))
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 12)
|
||||
syslog(LOG_INFO, "%s: %s writable %s file, marked unsafe",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%s: %s writable %s file, marked unsafe",
|
||||
shortenstring(fname, 203),
|
||||
bitset(S_IWOTH, st.st_mode) ? "world" : "group",
|
||||
forwarding ? "forward" : ":include:");
|
||||
#endif
|
||||
ctladdr->q_flags |= QUNSAFEADDR;
|
||||
}
|
||||
|
||||
|
@ -1184,12 +1204,10 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
|||
e->e_to = NULL;
|
||||
message("%s to %s",
|
||||
forwarding ? "forwarding" : "sending", buf);
|
||||
#ifdef LOG
|
||||
if (forwarding && LogLevel > 9)
|
||||
syslog(LOG_INFO, "%s: forward %.200s => %s",
|
||||
e->e_id == NULL ? "NOQUEUE" : e->e_id,
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"forward %.200s => %s",
|
||||
oldto, shortenstring(buf, 203));
|
||||
#endif
|
||||
|
||||
nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e);
|
||||
}
|
||||
|
|
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,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[] = "@(#)savemail.c 8.103 (Berkeley) 1/18/97";
|
||||
static char sccsid[] = "@(#)savemail.c 8.110 (Berkeley) 4/7/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
|
@ -349,13 +349,13 @@ savemail(e, sendbody)
|
|||
/* we have a home directory; write dead.letter */
|
||||
define('z', p, e);
|
||||
expand("\201z/dead.letter", buf, sizeof buf, e);
|
||||
flags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
|
||||
flags = SFF_NOLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
|
||||
e->e_to = buf;
|
||||
if (mailfile(buf, NULL, flags, e) == EX_OK)
|
||||
{
|
||||
bool oldverb = Verbose;
|
||||
int oldverb = Verbose;
|
||||
|
||||
Verbose = TRUE;
|
||||
Verbose = 1;
|
||||
message("Saved message in %s", buf);
|
||||
Verbose = oldverb;
|
||||
state = ESM_DONE;
|
||||
|
@ -383,7 +383,7 @@ savemail(e, sendbody)
|
|||
|
||||
snprintf(buf, sizeof buf, "%sdead.letter", _PATH_VARTMP);
|
||||
|
||||
flags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT;
|
||||
flags = SFF_NOLINK|SFF_CREAT|SFF_REGONLY|SFF_OPENASROOT|SFF_MUSTOWN;
|
||||
if (!writable(buf, NULL, flags) ||
|
||||
(fp = safefopen(buf, O_WRONLY|O_CREAT|O_APPEND,
|
||||
FileMode, flags)) == NULL)
|
||||
|
@ -407,15 +407,15 @@ savemail(e, sendbody)
|
|||
state = ESM_PANIC;
|
||||
else
|
||||
{
|
||||
bool oldverb = Verbose;
|
||||
int oldverb = Verbose;
|
||||
|
||||
Verbose = TRUE;
|
||||
Verbose = 1;
|
||||
message("Saved message in %s", buf);
|
||||
Verbose = oldverb;
|
||||
#ifdef LOG
|
||||
if (LogLevel > 3)
|
||||
syslog(LOG_NOTICE, "Saved message in %s", buf);
|
||||
#endif
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"Saved message in %s",
|
||||
buf);
|
||||
state = ESM_DONE;
|
||||
}
|
||||
(void) xfclose(fp, "savemail", buf);
|
||||
|
@ -550,7 +550,6 @@ returntosender(msg, returnq, flags, e)
|
|||
addheader("To", q->q_paddr, &ee->e_header);
|
||||
}
|
||||
|
||||
# ifdef LOG
|
||||
if (LogLevel > 5)
|
||||
{
|
||||
if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags))
|
||||
|
@ -559,10 +558,10 @@ returntosender(msg, returnq, flags, e)
|
|||
p = "postmaster notify";
|
||||
else
|
||||
p = "DSN";
|
||||
syslog(LOG_INFO, "%s: %s: %s: %s",
|
||||
e->e_id, ee->e_id, p, shortenstring(msg, 203));
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%s: %s: %s",
|
||||
ee->e_id, p, shortenstring(msg, 203));
|
||||
}
|
||||
# endif
|
||||
|
||||
if (SendMIMEErrors)
|
||||
{
|
||||
|
@ -759,11 +758,15 @@ errbody(mci, e, separator)
|
|||
{
|
||||
if (*ErrMsgFile == '/')
|
||||
{
|
||||
xfile = fopen(ErrMsgFile, "r");
|
||||
xfile = safefopen(ErrMsgFile, O_RDONLY, 0444,
|
||||
SFF_ROOTOK|SFF_REGONLY);
|
||||
if (xfile != NULL)
|
||||
{
|
||||
while (fgets(buf, sizeof buf, xfile) != NULL)
|
||||
{
|
||||
#if _FFR_BUG_FIX
|
||||
translate_dollars(buf);
|
||||
#endif
|
||||
expand(buf, buf, sizeof buf, e);
|
||||
putline(buf, mci);
|
||||
}
|
||||
|
@ -1223,7 +1226,7 @@ smtptodsn(smtpstat)
|
|||
return "5.2.2";
|
||||
|
||||
case 553: /* Req action not taken: mailbox name not allowed */
|
||||
return "5.1.3";
|
||||
return "5.1.0";
|
||||
|
||||
case 554: /* Transaction failed */
|
||||
return "5.0.0";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.\" Copyright (c) 1983, 1997 Eric P. Allman
|
||||
.\" Copyright (c) 1988, 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.
|
||||
.\"
|
||||
.\" @(#)sendmail.8 8.11 (Berkeley) 1/16/97
|
||||
.\" @(#)sendmail.8 8.12 (Berkeley) 2/1/97
|
||||
.\"
|
||||
.Dd January 16, 1997
|
||||
.Dd February 1, 1997
|
||||
.Dt SENDMAIL 8
|
||||
.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.
|
||||
*
|
||||
|
@ -31,7 +31,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sendmail.h 8.219 (Berkeley) 1/14/97
|
||||
* @(#)sendmail.h 8.236 (Berkeley) 6/5/97
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -41,7 +41,7 @@
|
|||
# ifdef _DEFINE
|
||||
# define EXTERN
|
||||
# ifndef lint
|
||||
static char SmailSccsId[] = "@(#)sendmail.h 8.219 1/14/97";
|
||||
static char SmailSccsId[] = "@(#)sendmail.h 8.236 6/5/97";
|
||||
# endif
|
||||
# else /* _DEFINE */
|
||||
# define EXTERN extern
|
||||
|
@ -87,6 +87,13 @@ static char SmailSccsId[] = "@(#)sendmail.h 8.219 1/14/97";
|
|||
# include <netccitt/x25.h>
|
||||
# endif
|
||||
|
||||
#if NAMED_BIND
|
||||
# include <arpa/nameser.h>
|
||||
# ifdef NOERROR
|
||||
# undef NOERROR /* avoid <sys/streams.h> conflict */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* forward references for prototypes */
|
||||
|
@ -391,6 +398,7 @@ struct hdrinfo
|
|||
{
|
||||
char *hi_field; /* the name of the field */
|
||||
u_short hi_flags; /* status bits, see below */
|
||||
char *hi_ruleset; /* validity check ruleset */
|
||||
};
|
||||
|
||||
extern struct hdrinfo HdrInfo[];
|
||||
|
@ -726,7 +734,7 @@ MAPCLASS
|
|||
#define MCF_OPTFILE 0x0008 /* file name is optional */
|
||||
|
||||
/* functions */
|
||||
extern char *map_rewrite __P((MAP *, char *, int, char **));
|
||||
extern char *map_rewrite __P((MAP *, const char *, int, char **));
|
||||
extern MAP *makemapentry __P((char *));
|
||||
extern void initmaps __P((bool, ENVELOPE *));
|
||||
/*
|
||||
|
@ -752,6 +760,7 @@ struct symtab
|
|||
NAMECANON sv_namecanon; /* canonical name cache */
|
||||
int sv_macro; /* macro name => id mapping */
|
||||
int sv_ruleset; /* ruleset index */
|
||||
struct hdrinfo sv_header; /* header metainfo */
|
||||
char *sv_service[MAXMAPSTACK]; /* service switch */
|
||||
} s_value;
|
||||
};
|
||||
|
@ -771,6 +780,7 @@ typedef struct symtab STAB;
|
|||
# define ST_MACRO 9 /* macro name to id mapping */
|
||||
# define ST_RULESET 10 /* ruleset index */
|
||||
# define ST_SERVICE 11 /* service switch entry */
|
||||
# define ST_HEADER 12 /* special header flags */
|
||||
# define ST_MCI 16 /* mailer connection info (offset) */
|
||||
|
||||
# define s_class s_value.sv_class
|
||||
|
@ -785,6 +795,7 @@ typedef struct symtab STAB;
|
|||
# define s_macro s_value.sv_macro
|
||||
# define s_ruleset s_value.sv_ruleset
|
||||
# define s_service s_value.sv_service
|
||||
# define s_header s_value.sv_header
|
||||
|
||||
extern STAB *stab __P((char *, int, int));
|
||||
extern void stabapply __P((void (*)(STAB *, int), int));
|
||||
|
@ -916,6 +927,7 @@ EXTERN int NoRecipientAction;
|
|||
#define PRIV_NOVRFY 0x0010 /* disallow VRFY command entirely */
|
||||
#define PRIV_AUTHWARNINGS 0x0020 /* flag possible authorization probs */
|
||||
#define PRIV_NORECEIPTS 0x0040 /* disallow return receipts */
|
||||
#define PRIV_NOETRN 0x0080 /* disallow ETRN command entirely */
|
||||
#define PRIV_RESTRICTMAILQ 0x1000 /* restrict mailq command */
|
||||
#define PRIV_RESTRICTQRUN 0x2000 /* restrict queue run */
|
||||
#define PRIV_GOAWAY 0x0fff /* don't give no info, anyway, anyhow */
|
||||
|
@ -943,7 +955,7 @@ struct prival
|
|||
|
||||
|
||||
/*
|
||||
** Flags passed to safefile.
|
||||
** Flags passed to safefile/safedirpath.
|
||||
*/
|
||||
|
||||
#define SFF_ANYFILE 0 /* no special restrictions */
|
||||
|
@ -955,12 +967,25 @@ struct prival
|
|||
#define SFF_SETUIDOK 0x0020 /* setuid files are ok */
|
||||
#define SFF_CREAT 0x0040 /* ok to create file if necessary */
|
||||
#define SFF_REGONLY 0x0080 /* regular files only */
|
||||
#define SFF_SAFEDIRPATH 0x0100 /* no writable directories allowed */
|
||||
#define SFF_NOHLINK 0x0200 /* file cannot have hard links */
|
||||
#define SFF_NOWLINK 0x0400 /* links only in non-writable dirs */
|
||||
#define SFF_NOWFILES 0x0800 /* disallow world writable files */
|
||||
|
||||
/* flags that are actually specific to safefopen */
|
||||
/* flags that are actually specific to safeopen/safefopen/dfopen */
|
||||
#define SFF_OPENASROOT 0x1000 /* open as root instead of real user */
|
||||
#define SFF_NOLOCK 0x2000 /* don't lock the file */
|
||||
|
||||
/* pseudo-flags */
|
||||
#define SFF_NOLINK (SFF_NOHLINK|SFF_NOSLINK)
|
||||
|
||||
/* functions */
|
||||
extern int safefile __P((char *, UID_T, GID_T, char *, int, int, struct stat *));
|
||||
extern int safedirpath __P((char *, UID_T, GID_T, char *, int));
|
||||
extern int safeopen __P((char *, int, int, int));
|
||||
extern FILE *safefopen __P((char *, int, int, int));
|
||||
extern int dfopen __P((char *, int, int, int));
|
||||
extern bool filechanged __P((char *, int, struct stat *, int));
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1077,7 +1102,6 @@ EXTERN bool FromFlag; /* if set, "From" person is explicit */
|
|||
EXTERN bool MeToo; /* send to the sender also */
|
||||
EXTERN bool IgnrDot; /* don't let dot end messages */
|
||||
EXTERN bool SaveFrom; /* save leading "From" lines */
|
||||
EXTERN bool Verbose; /* set if blow-by-blow desired */
|
||||
EXTERN bool GrabTo; /* if set, get recipients from msg */
|
||||
EXTERN bool SuprErrs; /* set if we are suppressing errors */
|
||||
EXTERN bool HoldErrs; /* only output errors to transcript */
|
||||
|
@ -1102,6 +1126,7 @@ EXTERN uid_t DefUid; /* default uid to run as */
|
|||
EXTERN gid_t DefGid; /* default gid to run as */
|
||||
EXTERN char *DefUser; /* default user to run as (from DefUid) */
|
||||
EXTERN MODE_T OldUmask; /* umask when sendmail starts up */
|
||||
EXTERN int Verbose; /* set if blow-by-blow desired */
|
||||
EXTERN int Errors; /* set if errors (local to single pass) */
|
||||
EXTERN int ExitStat; /* exit status code */
|
||||
EXTERN int LineNumber; /* line number in current input */
|
||||
|
@ -1123,6 +1148,7 @@ EXTERN char *RealHostName; /* name of host we are talking to */
|
|||
EXTERN char *CurHostName; /* current host we are dealing with */
|
||||
EXTERN jmp_buf TopFrame; /* branch-to-top-of-loop-on-error frame */
|
||||
EXTERN bool QuickAbort; /* .... but only if we want a quick abort */
|
||||
EXTERN bool OnlyOneError; /* .... or only want to give one SMTP reply */
|
||||
EXTERN bool LogUsrErrs; /* syslog user errors (e.g., SMTP RCPT cmd) */
|
||||
EXTERN bool SendMIMEErrors; /* send error messages in MIME format */
|
||||
EXTERN bool MatchGecos; /* look for user names in gecos field */
|
||||
|
@ -1163,11 +1189,16 @@ EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
|
|||
EXTERN int DefaultNotify; /* default DSN notification flags */
|
||||
EXTERN bool AllowBogusHELO; /* allow syntax errors on HELO command */
|
||||
EXTERN bool UserSubmission; /* initial (user) mail submission */
|
||||
EXTERN char *RunAsUserName; /* user to become for bulk of run */
|
||||
EXTERN uid_t RunAsUid; /* UID to become for bulk of run */
|
||||
EXTERN gid_t RunAsGid; /* GID to become for bulk of run */
|
||||
#ifdef _FFR_DSN_RRT
|
||||
EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */
|
||||
EXTERN bool DoQueueRun; /* non-interrupt time queue run needed */
|
||||
#if _FFR_DSN_RRT_OPTION
|
||||
EXTERN bool RrtImpliesDsn; /* turn Return-Receipt-To: into DSN */
|
||||
#endif
|
||||
EXTERN bool DontProbeInterfaces; /* don't probe interfaces for names */
|
||||
EXTERN bool ChownAlwaysSafe; /* treat chown(2) as safe */
|
||||
EXTERN bool IgnoreHostStatus; /* ignore long term host status files */
|
||||
EXTERN bool SingleThreadDelivery; /* single thread hosts on delivery */
|
||||
EXTERN bool UnsafeGroupWrites; /* group-writable files are unsafe */
|
||||
|
@ -1194,6 +1225,7 @@ EXTERN char *QueueLimitSender; /* limit queue runs to this sender */
|
|||
EXTERN char *QueueLimitId; /* limit queue runs to this id */
|
||||
EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */
|
||||
EXTERN char *DoubleBounceAddr; /* where to send double bounces */
|
||||
EXTERN bool FatalWritableDirs; /* no writable dirs in map paths */
|
||||
EXTERN char **ExternalEnviron; /* input environment */
|
||||
EXTERN char *UserEnviron[MAXUSERENVIRON + 1];
|
||||
/* saved user environment */
|
||||
|
@ -1249,6 +1281,12 @@ EXTERN u_char tTdvect[100];
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
** The "no queue id" queue id for sm_syslog
|
||||
*/
|
||||
|
||||
#define NOQID "*~*"
|
||||
|
||||
|
||||
/*
|
||||
** Some in-line functions
|
||||
|
@ -1272,7 +1310,6 @@ EXTERN u_char tTdvect[100];
|
|||
*/
|
||||
|
||||
extern char *xalloc __P((int));
|
||||
extern FILE *dfopen __P((char *, int, int));
|
||||
extern char *sfgets __P((char *, int, FILE *, time_t, char *));
|
||||
extern char *queuename __P((ENVELOPE *, int));
|
||||
extern time_t curtime __P(());
|
||||
|
@ -1295,7 +1332,6 @@ extern void rebuildaliases __P((MAP *, bool));
|
|||
extern void readaliases __P((MAP *, FILE *, bool, bool));
|
||||
extern void finis __P(());
|
||||
extern void setsender __P((char *, ENVELOPE *, char **, int, bool));
|
||||
extern FILE *safefopen __P((char *, int, int, int));
|
||||
extern void xputs __P((const char *));
|
||||
extern void logsender __P((ENVELOPE *, char *));
|
||||
extern void smtprset __P((MAILER *, MCI *, ENVELOPE *));
|
||||
|
@ -1303,7 +1339,7 @@ extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *));
|
|||
extern void setuserenv __P((const char *, const char *));
|
||||
extern char *getextenv __P((const char *));
|
||||
extern void disconnect __P((int, ENVELOPE *));
|
||||
extern void putxline __P((char *, MCI *, int));
|
||||
extern void putxline __P((char *, size_t, MCI *, int));
|
||||
extern void dumpfd __P((int, bool, bool));
|
||||
extern void makemailer __P((char *));
|
||||
extern void putfromline __P((MCI *, ENVELOPE *));
|
||||
|
@ -1328,7 +1364,6 @@ extern void proc_list_clear __P((void));
|
|||
extern void buffer_errors __P((void));
|
||||
extern void flush_errors __P((bool));
|
||||
extern void putline __P((char *, MCI *));
|
||||
extern void putxline __P((char *, MCI *, int));
|
||||
extern bool xtextok __P((char *));
|
||||
extern char *xtextify __P((char *, char *));
|
||||
extern char *xuntextify __P((char *));
|
||||
|
@ -1341,7 +1376,7 @@ extern int endmailer __P((MCI *, ENVELOPE *, char **));
|
|||
extern void fixcrlf __P((char *, bool));
|
||||
extern int dofork __P((void));
|
||||
extern void initsys __P((ENVELOPE *));
|
||||
extern void collect __P((FILE *, bool, bool, HDR **, ENVELOPE *));
|
||||
extern void collect __P((FILE *, bool, HDR **, ENVELOPE *));
|
||||
extern void stripquotes __P((char *));
|
||||
extern int include __P((char *, bool, ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern void unlockqueue __P((ENVELOPE *));
|
||||
|
@ -1385,6 +1420,7 @@ extern void usrerr(const char *, ...);
|
|||
extern void message(const char *, ...);
|
||||
extern void nmessage(const char *, ...);
|
||||
extern void setproctitle(const char *fmt, ...);
|
||||
extern void sm_syslog(int, const char *, const char *, ...);
|
||||
#else
|
||||
extern void auth_warning();
|
||||
extern void syserr();
|
||||
|
@ -1392,6 +1428,7 @@ extern void usrerr();
|
|||
extern void message();
|
||||
extern void nmessage();
|
||||
extern void setproctitle();
|
||||
extern void sm_syslog();
|
||||
#endif
|
||||
|
||||
#if !HASSNPRINTF
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -36,9 +36,9 @@
|
|||
|
||||
#ifndef lint
|
||||
#if SMTP
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.136 (Berkeley) 1/17/97 (with SMTP)";
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.146 (Berkeley) 6/11/97 (with SMTP)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.136 (Berkeley) 1/17/97 (without SMTP)";
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.146 (Berkeley) 6/11/97 (without SMTP)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -153,6 +153,7 @@ smtp(nullserver, e)
|
|||
volatile int n_noop = 0; /* count of NOOP/VERB/ONEX etc cmds */
|
||||
volatile int n_helo = 0; /* count of HELO/EHLO commands */
|
||||
bool ok;
|
||||
int lognullconnection = TRUE;
|
||||
char inp[MAXLINE];
|
||||
char cmdbuf[MAXLINE];
|
||||
extern ENVELOPE BlankEnvelope;
|
||||
|
@ -160,7 +161,7 @@ smtp(nullserver, e)
|
|||
extern void settime __P((ENVELOPE *));
|
||||
extern bool enoughdiskspace __P((long));
|
||||
extern int runinchild __P((char *, ENVELOPE *));
|
||||
extern void checksmtpattack __P((volatile int *, int, char *));
|
||||
extern void checksmtpattack __P((volatile int *, int, char *, ENVELOPE *));
|
||||
|
||||
if (fileno(OutChannel) != fileno(stdout))
|
||||
{
|
||||
|
@ -177,11 +178,12 @@ smtp(nullserver, e)
|
|||
CurSmtpClient = CurHostName;
|
||||
|
||||
setproctitle("server %s startup", CurSmtpClient);
|
||||
#if defined(LOG) && DAEMON
|
||||
#if DAEMON
|
||||
if (LogLevel > 11)
|
||||
{
|
||||
/* log connection information */
|
||||
syslog(LOG_INFO, "SMTP connect from %.100s (%.100s)",
|
||||
sm_syslog(LOG_INFO, NOQID,
|
||||
"SMTP connect from %.100s (%.100s)",
|
||||
CurSmtpClient, anynet_ntoa(&RealHostAddr));
|
||||
}
|
||||
#endif
|
||||
|
@ -231,7 +233,9 @@ smtp(nullserver, e)
|
|||
}
|
||||
QuickAbort = FALSE;
|
||||
HoldErrs = FALSE;
|
||||
SuprErrs = FALSE;
|
||||
LogUsrErrs = FALSE;
|
||||
OnlyOneError = TRUE;
|
||||
e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
|
||||
|
||||
/* setup for the read */
|
||||
|
@ -252,11 +256,10 @@ smtp(nullserver, e)
|
|||
disconnect(1, e);
|
||||
message("421 %s Lost input channel from %s",
|
||||
MyHostName, CurSmtpClient);
|
||||
#ifdef LOG
|
||||
if (LogLevel > (gotmail ? 1 : 19))
|
||||
syslog(LOG_NOTICE, "lost input channel from %.100s",
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"lost input channel from %.100s",
|
||||
CurSmtpClient);
|
||||
#endif
|
||||
if (InChild)
|
||||
ExitStat = EX_QUIT;
|
||||
finis();
|
||||
|
@ -269,10 +272,10 @@ smtp(nullserver, e)
|
|||
if (e->e_xfp != NULL)
|
||||
fprintf(e->e_xfp, "<<< %s\n", inp);
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 15)
|
||||
syslog(LOG_INFO, "<-- %s", inp);
|
||||
#endif
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"<-- %s",
|
||||
inp);
|
||||
|
||||
if (e->e_id == NULL)
|
||||
setproctitle("%s: %.80s", CurSmtpClient, inp);
|
||||
|
@ -324,12 +327,21 @@ smtp(nullserver, e)
|
|||
default:
|
||||
if (++badcommands > MAXBADCOMMANDS)
|
||||
sleep(1);
|
||||
message("550 Access denied");
|
||||
usrerr("550 Access denied");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* non-null server */
|
||||
switch (c->cmdcode)
|
||||
{
|
||||
case CMDMAIL:
|
||||
case CMDEXPN:
|
||||
case CMDVRFY:
|
||||
case CMDETRN:
|
||||
lognullconnection = FALSE;
|
||||
}
|
||||
|
||||
switch (c->cmdcode)
|
||||
{
|
||||
case CMDHELO: /* hello -- introduce yourself */
|
||||
|
@ -346,12 +358,12 @@ smtp(nullserver, e)
|
|||
}
|
||||
|
||||
/* avoid denial-of-service */
|
||||
checksmtpattack(&n_helo, MAXHELOCOMMANDS, "HELO/EHLO");
|
||||
checksmtpattack(&n_helo, MAXHELOCOMMANDS, "HELO/EHLO", e);
|
||||
|
||||
/* check for duplicate HELO/EHLO per RFC 1651 4.2 */
|
||||
if (gothello)
|
||||
{
|
||||
message("503 %s Duplicate HELO/EHLO",
|
||||
usrerr("503 %s Duplicate HELO/EHLO",
|
||||
MyHostName);
|
||||
break;
|
||||
}
|
||||
|
@ -359,7 +371,7 @@ smtp(nullserver, e)
|
|||
/* check for valid domain name (re 1123 5.2.5) */
|
||||
if (*p == '\0' && !AllowBogusHELO)
|
||||
{
|
||||
message("501 %s requires domain address",
|
||||
usrerr("501 %s requires domain address",
|
||||
cmdbuf);
|
||||
break;
|
||||
}
|
||||
|
@ -384,7 +396,7 @@ smtp(nullserver, e)
|
|||
if (*q != '\0')
|
||||
{
|
||||
if (!AllowBogusHELO)
|
||||
message("501 Invalid domain name");
|
||||
usrerr("501 Invalid domain name");
|
||||
else
|
||||
{
|
||||
message("250 %s Invalid domain name, accepting anyway",
|
||||
|
@ -442,13 +454,13 @@ smtp(nullserver, e)
|
|||
|
||||
if (bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
|
||||
{
|
||||
message("503 Polite people say HELO first");
|
||||
usrerr("503 Polite people say HELO first");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gotmail)
|
||||
{
|
||||
message("503 Sender already specified");
|
||||
usrerr("503 Sender already specified");
|
||||
if (InChild)
|
||||
finis();
|
||||
break;
|
||||
|
@ -578,7 +590,7 @@ smtp(nullserver, e)
|
|||
|
||||
if (!enoughdiskspace(e->e_msgsize))
|
||||
{
|
||||
message("452 Insufficient disk space; try again later");
|
||||
usrerr("452 Insufficient disk space; try again later");
|
||||
break;
|
||||
}
|
||||
message("250 Sender ok");
|
||||
|
@ -600,6 +612,13 @@ smtp(nullserver, e)
|
|||
QuickAbort = TRUE;
|
||||
LogUsrErrs = TRUE;
|
||||
|
||||
/* limit flooding of our machine */
|
||||
if (MaxRcptPerMsg > 0 && nrcpts >= MaxRcptPerMsg)
|
||||
{
|
||||
usrerr("450 Too many recipients");
|
||||
break;
|
||||
}
|
||||
|
||||
if (e->e_sendmode != SM_DELIVER)
|
||||
e->e_flags |= EF_VRFYONLY;
|
||||
|
||||
|
@ -674,21 +693,20 @@ smtp(nullserver, e)
|
|||
else
|
||||
{
|
||||
/* punt -- should keep message in ADDRESS.... */
|
||||
message("550 Addressee unknown");
|
||||
usrerr("550 Addressee unknown");
|
||||
}
|
||||
e->e_to = NULL;
|
||||
break;
|
||||
|
||||
case CMDDATA: /* data -- text of mail */
|
||||
SmtpPhase = "server DATA";
|
||||
if (!gotmail)
|
||||
{
|
||||
message("503 Need MAIL command");
|
||||
usrerr("503 Need MAIL command");
|
||||
break;
|
||||
}
|
||||
else if (nrcpts <= 0)
|
||||
{
|
||||
message("503 Need RCPT (recipient)");
|
||||
usrerr("503 Need RCPT (recipient)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -713,7 +731,7 @@ smtp(nullserver, e)
|
|||
/* collect the text of the message */
|
||||
SmtpPhase = "collect";
|
||||
buffer_errors();
|
||||
collect(InChannel, TRUE, doublequeue, NULL, e);
|
||||
collect(InChannel, TRUE, NULL, e);
|
||||
flush_errors(TRUE);
|
||||
if (Errors != 0)
|
||||
goto abortmessage;
|
||||
|
@ -785,7 +803,10 @@ smtp(nullserver, e)
|
|||
break;
|
||||
|
||||
case CMDRSET: /* rset -- reset state */
|
||||
message("250 Reset state");
|
||||
if (tTd(94, 100))
|
||||
message("451 Test failure");
|
||||
else
|
||||
message("250 Reset state");
|
||||
|
||||
/* arrange to ignore any current send list */
|
||||
e->e_sendqueue = NULL;
|
||||
|
@ -795,6 +816,7 @@ smtp(nullserver, e)
|
|||
|
||||
/* clean up a bit */
|
||||
gotmail = FALSE;
|
||||
SuprErrs = TRUE;
|
||||
dropenvelope(e, TRUE);
|
||||
CurEnv = e = newenvelope(e, CurEnv);
|
||||
break;
|
||||
|
@ -802,7 +824,7 @@ smtp(nullserver, e)
|
|||
case CMDVRFY: /* vrfy -- verify address */
|
||||
case CMDEXPN: /* expn -- expand address */
|
||||
checksmtpattack(&nverifies, MAXVRFYCOMMANDS,
|
||||
c->cmdcode == CMDVRFY ? "VRFY" : "EXPN");
|
||||
c->cmdcode == CMDVRFY ? "VRFY" : "EXPN", e);
|
||||
vrfy = c->cmdcode == CMDVRFY;
|
||||
if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN,
|
||||
PrivacyFlags))
|
||||
|
@ -811,39 +833,35 @@ smtp(nullserver, e)
|
|||
message("252 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
|
||||
else
|
||||
message("502 Sorry, we do not allow this operation");
|
||||
#ifdef LOG
|
||||
if (LogLevel > 5)
|
||||
syslog(LOG_INFO, "%.100s: %s [rejected]",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.100s: %s [rejected]",
|
||||
CurSmtpClient,
|
||||
shortenstring(inp, 203));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
else if (!gothello &&
|
||||
bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
|
||||
PrivacyFlags))
|
||||
{
|
||||
message("503 I demand that you introduce yourself first");
|
||||
usrerr("503 I demand that you introduce yourself first");
|
||||
break;
|
||||
}
|
||||
if (runinchild(vrfy ? "SMTP-VRFY" : "SMTP-EXPN", e) > 0)
|
||||
break;
|
||||
#ifdef LOG
|
||||
if (LogLevel > 5)
|
||||
syslog(LOG_INFO, "%.100s: %s",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.100s: %s",
|
||||
CurSmtpClient,
|
||||
shortenstring(inp, 203));
|
||||
#endif
|
||||
vrfyqueue = NULL;
|
||||
QuickAbort = TRUE;
|
||||
if (vrfy)
|
||||
e->e_flags |= EF_VRFYONLY;
|
||||
while (*p != '\0' && isascii(*p) && isspace(*p))
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
{
|
||||
message("501 Argument required");
|
||||
Errors++;
|
||||
usrerr("501 Argument required");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -857,7 +875,7 @@ smtp(nullserver, e)
|
|||
}
|
||||
if (vrfyqueue == NULL)
|
||||
{
|
||||
message("554 Nothing to %s", vrfy ? "VRFY" : "EXPN");
|
||||
usrerr("554 Nothing to %s", vrfy ? "VRFY" : "EXPN");
|
||||
}
|
||||
while (vrfyqueue != NULL)
|
||||
{
|
||||
|
@ -878,24 +896,23 @@ smtp(nullserver, e)
|
|||
case CMDETRN: /* etrn -- force queue flush */
|
||||
if (strlen(p) <= 0)
|
||||
{
|
||||
message("500 Parameter required");
|
||||
usrerr("500 Parameter required");
|
||||
break;
|
||||
}
|
||||
|
||||
/* crude way to avoid denial-of-service attacks */
|
||||
checksmtpattack(&n_etrn, MAXETRNCOMMANDS, "ETRN");
|
||||
checksmtpattack(&n_etrn, MAXETRNCOMMANDS, "ETRN", e);
|
||||
|
||||
id = p;
|
||||
if (*id == '@')
|
||||
id++;
|
||||
else
|
||||
*--id = '@';
|
||||
#ifdef LOG
|
||||
if (LogLevel > 5)
|
||||
syslog(LOG_INFO, "%.100s: ETRN %s",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.100s: ETRN %s",
|
||||
CurSmtpClient,
|
||||
shortenstring(id, 203));
|
||||
#endif
|
||||
QueueLimitRecipient = id;
|
||||
ok = runqueue(TRUE, TRUE);
|
||||
QueueLimitRecipient = NULL;
|
||||
|
@ -908,7 +925,7 @@ smtp(nullserver, e)
|
|||
break;
|
||||
|
||||
case CMDNOOP: /* noop -- do nothing */
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "NOOP");
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "NOOP", e);
|
||||
message("250 OK");
|
||||
break;
|
||||
|
||||
|
@ -924,6 +941,10 @@ smtp(nullserver, e)
|
|||
|
||||
if (InChild)
|
||||
ExitStat = EX_QUIT;
|
||||
if (lognullconnection && LogLevel > 5)
|
||||
sm_syslog(LOG_INFO, NULL,
|
||||
"Null connection from %.100s",
|
||||
CurSmtpClient);
|
||||
finis();
|
||||
|
||||
case CMDVERB: /* set verbose mode */
|
||||
|
@ -933,20 +954,20 @@ smtp(nullserver, e)
|
|||
message("502 Verbose unavailable");
|
||||
break;
|
||||
}
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "VERB");
|
||||
Verbose = TRUE;
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "VERB", e);
|
||||
Verbose = 1;
|
||||
e->e_sendmode = SM_DELIVER;
|
||||
message("250 Verbose mode");
|
||||
break;
|
||||
|
||||
case CMDONEX: /* doing one transaction only */
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "ONEX");
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "ONEX", e);
|
||||
OneXact = TRUE;
|
||||
message("250 Only one transaction");
|
||||
break;
|
||||
|
||||
case CMDXUSR: /* initial (user) submission */
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "XUSR");
|
||||
checksmtpattack(&n_noop, MAXNOOPCOMMANDS, "XUSR", e);
|
||||
UserSubmission = TRUE;
|
||||
message("250 Initial submission");
|
||||
break;
|
||||
|
@ -968,13 +989,11 @@ smtp(nullserver, e)
|
|||
case CMDDBGDEBUG: /* set debug mode */
|
||||
# endif /* SMTPDEBUG */
|
||||
case CMDLOGBOGUS: /* bogus command */
|
||||
# ifdef LOG
|
||||
if (LogLevel > 0)
|
||||
syslog(LOG_CRIT,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"\"%s\" command from %.100s (%.100s)",
|
||||
c->cmdname, CurSmtpClient,
|
||||
anynet_ntoa(&RealHostAddr));
|
||||
# endif
|
||||
/* FALL THROUGH */
|
||||
|
||||
case CMDERROR: /* unknown command */
|
||||
|
@ -985,7 +1004,8 @@ smtp(nullserver, e)
|
|||
goto doquit;
|
||||
}
|
||||
|
||||
message("500 Command unrecognized");
|
||||
usrerr("500 Command unrecognized: \"%s\"",
|
||||
shortenstring(inp, 203));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1003,6 +1023,7 @@ smtp(nullserver, e)
|
|||
** maxcount -- maximum value for this counter before we
|
||||
** slow down.
|
||||
** cname -- command name for logging.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
|
@ -1012,20 +1033,20 @@ smtp(nullserver, e)
|
|||
*/
|
||||
|
||||
void
|
||||
checksmtpattack(pcounter, maxcount, cname)
|
||||
checksmtpattack(pcounter, maxcount, cname, e)
|
||||
volatile int *pcounter;
|
||||
int maxcount;
|
||||
char *cname;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
if (++(*pcounter) >= maxcount)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (*pcounter == maxcount && LogLevel > 5)
|
||||
{
|
||||
syslog(LOG_INFO, "%.100s: %.40s attack?",
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"%.100s: %.40s attack?",
|
||||
CurSmtpClient, cname);
|
||||
}
|
||||
#endif
|
||||
sleep(*pcounter / maxcount);
|
||||
}
|
||||
}
|
||||
|
@ -1065,9 +1086,8 @@ skipword(p, w)
|
|||
if (*p != ':')
|
||||
{
|
||||
syntax:
|
||||
message("501 Syntax error in parameters scanning \"%s\"",
|
||||
usrerr("501 Syntax error in parameters scanning \"%s\"",
|
||||
shortenstring(firstp, 203));
|
||||
Errors++;
|
||||
return (NULL);
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
@ -1411,7 +1431,8 @@ help(topic)
|
|||
extern char Version[];
|
||||
|
||||
|
||||
if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
|
||||
if (HelpFile == NULL ||
|
||||
(hf = safefopen(HelpFile, O_RDONLY, 0444, SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK)) == NULL)
|
||||
{
|
||||
/* no help */
|
||||
errno = 0;
|
||||
|
|
|
@ -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) 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 USERDB
|
||||
static char sccsid [] = "@(#)udb.c 8.47 (Berkeley) 12/6/96 (with USERDB)";
|
||||
static char sccsid [] = "@(#)udb.c 8.51 (Berkeley) 5/29/97 (with USERDB)";
|
||||
#else
|
||||
static char sccsid [] = "@(#)udb.c 8.47 (Berkeley) 12/6/96 (without USERDB)";
|
||||
static char sccsid [] = "@(#)udb.c 8.51 (Berkeley) 5/29/97 (without USERDB)";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -120,7 +120,7 @@ struct option
|
|||
char *val;
|
||||
};
|
||||
|
||||
extern int _udbx_init __P((void));
|
||||
extern int _udbx_init __P((ENVELOPE *));
|
||||
/*
|
||||
** UDBEXPAND -- look up user in database and expand
|
||||
**
|
||||
|
@ -173,7 +173,7 @@ udbexpand(a, sendq, aliaslevel, e)
|
|||
/* on first call, locate the database */
|
||||
if (!UdbInitialized)
|
||||
{
|
||||
if (_udbx_init() == EX_TEMPFAIL)
|
||||
if (_udbx_init(e) == EX_TEMPFAIL)
|
||||
return EX_TEMPFAIL;
|
||||
}
|
||||
|
||||
|
@ -259,14 +259,19 @@ udbexpand(a, sendq, aliaslevel, e)
|
|||
breakout = TRUE;
|
||||
if (info.size >= userleft - 1)
|
||||
{
|
||||
char *nuser = xalloc(usersize + MEMCHUNKSIZE);
|
||||
char *nuser;
|
||||
int size = MEMCHUNKSIZE;
|
||||
|
||||
if (info.size > MEMCHUNKSIZE)
|
||||
size = info.size;
|
||||
nuser = xalloc(usersize + size);
|
||||
|
||||
bcopy(user, nuser, usersize);
|
||||
if (user != userbuf)
|
||||
free(user);
|
||||
user = nuser;
|
||||
usersize += MEMCHUNKSIZE;
|
||||
userleft += MEMCHUNKSIZE;
|
||||
usersize += size;
|
||||
userleft += size;
|
||||
}
|
||||
p = &user[strlen(user)];
|
||||
if (p != user)
|
||||
|
@ -287,12 +292,11 @@ udbexpand(a, sendq, aliaslevel, e)
|
|||
break;
|
||||
|
||||
message("expanded to %s", user);
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 10)
|
||||
syslog(LOG_INFO, "%s: expand %.100s => %s",
|
||||
e->e_id, e->e_to,
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"expand %.100s => %s",
|
||||
e->e_to,
|
||||
shortenstring(user, 203));
|
||||
#endif
|
||||
naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
|
||||
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
|
||||
{
|
||||
|
@ -417,12 +421,11 @@ udbexpand(a, sendq, aliaslevel, e)
|
|||
user[info.size] = '\0';
|
||||
|
||||
message("hesioded to %s", user);
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 10)
|
||||
syslog(LOG_INFO, "%s: hesiod %.100s => %s",
|
||||
e->e_id, e->e_to,
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"hesiod %.100s => %s",
|
||||
e->e_to,
|
||||
shortenstring(user, 203));
|
||||
#endif
|
||||
naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
|
||||
|
||||
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
|
||||
|
@ -539,7 +542,7 @@ udbmatch(user, field)
|
|||
|
||||
if (!UdbInitialized)
|
||||
{
|
||||
if (_udbx_init() == EX_TEMPFAIL)
|
||||
if (_udbx_init(CurEnv) == EX_TEMPFAIL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -552,7 +555,10 @@ udbmatch(user, field)
|
|||
return NULL;
|
||||
|
||||
/* long names can never match and are a pain to deal with */
|
||||
if ((strlen(user) + strlen(field)) > sizeof keybuf - 4)
|
||||
i = strlen(field);
|
||||
if (i < sizeof "maildrop")
|
||||
i = sizeof "maildrop";
|
||||
if ((strlen(user) + i) > sizeof keybuf - 4)
|
||||
return NULL;
|
||||
|
||||
/* names beginning with colons indicate metadata */
|
||||
|
@ -785,7 +791,7 @@ udb_map_lookup(map, name, av, statp)
|
|||
** _UDBX_INIT -- parse the UDB specification, opening any valid entries.
|
||||
**
|
||||
** Parameters:
|
||||
** none.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** EX_TEMPFAIL -- if it appeared it couldn't get hold of a
|
||||
|
@ -800,7 +806,8 @@ udb_map_lookup(map, name, av, statp)
|
|||
#define MAXUDBOPTS 27
|
||||
|
||||
int
|
||||
_udbx_init()
|
||||
_udbx_init(e)
|
||||
ENVELOPE *e;
|
||||
{
|
||||
register char *p;
|
||||
register struct udbent *up;
|
||||
|
@ -957,19 +964,18 @@ _udbx_init()
|
|||
{
|
||||
int saveerrno = errno;
|
||||
|
||||
printf("dbopen(%s): %s",
|
||||
printf("dbopen(%s): %s\n",
|
||||
up->udb_dbname,
|
||||
errstring(errno));
|
||||
errno = saveerrno;
|
||||
}
|
||||
if (errno != ENOENT && errno != EACCES)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 2)
|
||||
syslog(LOG_ERR, "dbopen(%s): %s",
|
||||
sm_syslog(LOG_ERR, e->e_id,
|
||||
"dbopen(%s): %s",
|
||||
up->udb_dbname,
|
||||
errstring(errno));
|
||||
#endif
|
||||
up->udb_type = UDB_EOLIST;
|
||||
if (up->udb_dbname != spec)
|
||||
free(up->udb_dbname);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 SMTP
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.80 (Berkeley) 1/18/97 (with SMTP)";
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.87 (Berkeley) 6/3/97 (with SMTP)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.80 (Berkeley) 1/18/97 (without SMTP)";
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.87 (Berkeley) 6/3/97 (without SMTP)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -389,7 +389,7 @@ smtpmailfrom(m, mci, e)
|
|||
!bitset(EF_DONT_MIME, e->e_flags) &&
|
||||
!bitnset(M_8BITS, m->m_flags))
|
||||
bodytype = "8BITMIME";
|
||||
if (bodytype != NULL)
|
||||
if (bodytype != NULL && strlen(bodytype) + 7 < l)
|
||||
{
|
||||
strcat(optbuf, " BODY=");
|
||||
strcat(optbuf, bodytype);
|
||||
|
@ -524,6 +524,8 @@ smtpmailfrom(m, mci, e)
|
|||
{
|
||||
/* exceeded storage allocation */
|
||||
mci_setstat(mci, EX_NOTSTICKY, "5.2.2", SmtpReplyBuffer);
|
||||
if (bitset(MCIF_SIZE, mci->mci_flags))
|
||||
e->e_flags |= EF_NO_BODY_RETN;
|
||||
return EX_UNAVAILABLE;
|
||||
}
|
||||
else if (REPLYTYPE(r) == 5)
|
||||
|
@ -533,14 +535,13 @@ smtpmailfrom(m, mci, e)
|
|||
return EX_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
{
|
||||
syslog(LOG_CRIT, "%s: %.100s: SMTP MAIL protocol error: %s",
|
||||
e->e_id, mci->mci_host,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"%.100s: SMTP MAIL protocol error: %s",
|
||||
mci->mci_host,
|
||||
shortenstring(SmtpReplyBuffer, 403));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* protocol error -- close up */
|
||||
mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer);
|
||||
|
@ -651,14 +652,13 @@ smtprcpt(to, m, mci, e)
|
|||
return EX_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
{
|
||||
syslog(LOG_CRIT, "%s: %.100s: SMTP RCPT protocol error: %s",
|
||||
e->e_id, mci->mci_host,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"%.100s: SMTP RCPT protocol error: %s",
|
||||
mci->mci_host,
|
||||
shortenstring(SmtpReplyBuffer, 403));
|
||||
}
|
||||
#endif
|
||||
|
||||
mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer);
|
||||
return EX_PROTOCOL;
|
||||
|
@ -718,14 +718,13 @@ smtpdata(m, mci, e)
|
|||
}
|
||||
else if (r != 354)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
{
|
||||
syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-1 protocol error: %s",
|
||||
e->e_id, mci->mci_host,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"%.100s: SMTP DATA-1 protocol error: %s",
|
||||
mci->mci_host,
|
||||
shortenstring(SmtpReplyBuffer, 403));
|
||||
}
|
||||
#endif
|
||||
smtprset(m, mci, e);
|
||||
mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer);
|
||||
return (EX_PROTOCOL);
|
||||
|
@ -800,8 +799,6 @@ smtpdata(m, mci, e)
|
|||
xstat = EX_NOTSTICKY;
|
||||
if (r == 452)
|
||||
rstat = EX_TEMPFAIL;
|
||||
else if (r == 552)
|
||||
rstat = EX_UNAVAILABLE;
|
||||
else if (REPLYTYPE(r) == 4)
|
||||
rstat = xstat = EX_TEMPFAIL;
|
||||
else if (REPLYCLASS(r) != 5)
|
||||
|
@ -809,7 +806,7 @@ smtpdata(m, mci, e)
|
|||
else if (REPLYTYPE(r) == 2)
|
||||
rstat = xstat = EX_OK;
|
||||
else if (REPLYTYPE(r) == 5)
|
||||
rstat = xstat = EX_UNAVAILABLE;
|
||||
rstat = EX_UNAVAILABLE;
|
||||
else
|
||||
rstat = EX_PROTOCOL;
|
||||
mci_setstat(mci, xstat, smtptodsn(r), SmtpReplyBuffer);
|
||||
|
@ -818,14 +815,13 @@ smtpdata(m, mci, e)
|
|||
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
|
||||
if (rstat != EX_PROTOCOL)
|
||||
return rstat;
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
{
|
||||
syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-2 protocol error: %s",
|
||||
e->e_id, mci->mci_host,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"%.100s: SMTP DATA-2 protocol error: %s",
|
||||
mci->mci_host,
|
||||
shortenstring(SmtpReplyBuffer, 403));
|
||||
}
|
||||
#endif
|
||||
return rstat;
|
||||
}
|
||||
|
||||
|
@ -877,14 +873,13 @@ smtpgetstat(m, mci, e)
|
|||
else if (REPLYTYPE(r) == 5)
|
||||
stat = EX_UNAVAILABLE;
|
||||
mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer);
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1 && stat == EX_PROTOCOL)
|
||||
{
|
||||
syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-3 protocol error: %s",
|
||||
e->e_id, mci->mci_host,
|
||||
sm_syslog(LOG_CRIT, e->e_id,
|
||||
"%.100s: SMTP DATA-3 protocol error: %s",
|
||||
mci->mci_host,
|
||||
shortenstring(SmtpReplyBuffer, 403));
|
||||
}
|
||||
#endif
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
@ -929,10 +924,7 @@ smtpquit(m, mci, e)
|
|||
(void) reply(m, mci, e, TimeOuts.to_quit, NULL);
|
||||
SuprErrs = oldSuprErrs;
|
||||
if (mci->mci_state == MCIS_CLOSED)
|
||||
{
|
||||
SuprErrs = oldSuprErrs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* now actually close the connection and pick up the zombie */
|
||||
|
@ -1025,7 +1017,8 @@ reply(m, mci, e, timeout, pfunc)
|
|||
** Read the input line, being careful not to hang.
|
||||
*/
|
||||
|
||||
for (bufp = SmtpReplyBuffer;; bufp = junkbuf)
|
||||
bufp = SmtpReplyBuffer;
|
||||
for (;;)
|
||||
{
|
||||
register char *p;
|
||||
extern time_t curtime();
|
||||
|
@ -1120,26 +1113,32 @@ reply(m, mci, e, timeout, pfunc)
|
|||
if (Verbose)
|
||||
nmessage("050 %s", bufp);
|
||||
|
||||
/* ignore improperly formated input */
|
||||
if (!(isascii(bufp[0]) && isdigit(bufp[0])) ||
|
||||
!(isascii(bufp[1]) && isdigit(bufp[1])) ||
|
||||
!(isascii(bufp[2]) && isdigit(bufp[2])) ||
|
||||
!(bufp[3] == ' ' || bufp[3] == '-'))
|
||||
continue;
|
||||
|
||||
/* process the line */
|
||||
if (pfunc != NULL)
|
||||
(*pfunc)(bufp, firstline, m, mci, e);
|
||||
|
||||
firstline = FALSE;
|
||||
|
||||
/* if continuation is required, we can go on */
|
||||
if (bufp[3] == '-')
|
||||
continue;
|
||||
|
||||
/* ignore improperly formated input */
|
||||
if (!(isascii(bufp[0]) && isdigit(bufp[0])))
|
||||
continue;
|
||||
|
||||
/* decode the reply code */
|
||||
r = atoi(bufp);
|
||||
|
||||
/* extra semantics: 0xx codes are "informational" */
|
||||
if (r >= 100)
|
||||
if (r < 100)
|
||||
continue;
|
||||
|
||||
/* if no continuation lines, return this line */
|
||||
if (bufp[3] != '-')
|
||||
break;
|
||||
|
||||
/* first line of real reply -- ignore rest */
|
||||
bufp = junkbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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[] = "@(#)util.c 8.115 (Berkeley) 1/5/97";
|
||||
static char sccsid[] = "@(#)util.c 8.129 (Berkeley) 6/11/97";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
|
@ -449,352 +449,6 @@ buildfname(gecos, login, buf, buflen)
|
|||
*bp = '\0';
|
||||
}
|
||||
/*
|
||||
** 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
|
||||
|
||||
#define ST_MODE_NOFILE 0171147 /* unlikely to occur */
|
||||
|
||||
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;
|
||||
struct stat stbuf;
|
||||
struct stat fstbuf;
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (!bitset(SFF_NOPATHCHECK, flags) ||
|
||||
(uid == 0 && !bitset(SFF_ROOTOK, flags)))
|
||||
{
|
||||
/* check the path to the file for acceptability */
|
||||
for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/')
|
||||
{
|
||||
*p = '\0';
|
||||
if (stat(fn, &stbuf) < 0)
|
||||
break;
|
||||
if (uid == 0 && bitset(S_IWGRP|S_IWOTH, stbuf.st_mode))
|
||||
message("051 WARNING: writable directory %s",
|
||||
fn);
|
||||
if (uid == 0 && !bitset(SFF_ROOTOK, flags))
|
||||
{
|
||||
if (bitset(S_IXOTH, stbuf.st_mode))
|
||||
continue;
|
||||
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))
|
||||
break;
|
||||
}
|
||||
if (p != NULL)
|
||||
{
|
||||
int ret = errno;
|
||||
|
||||
if (ret == 0)
|
||||
ret = EACCES;
|
||||
if (tTd(44, 4))
|
||||
printf("\t[dir %s] %s\n", fn, errstring(ret));
|
||||
*p = '/';
|
||||
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;
|
||||
|
||||
if (tTd(44, 4))
|
||||
printf("\t%s\n", errstring(ret));
|
||||
|
||||
errno = 0;
|
||||
if (!bitset(SFF_CREAT, flags))
|
||||
return ret;
|
||||
|
||||
/* check to see if legal to create the file */
|
||||
p = strrchr(fn, '/');
|
||||
if (p == NULL)
|
||||
return ENOTDIR;
|
||||
*p = '\0';
|
||||
if (stat(fn, &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",
|
||||
fn, (int) stbuf.st_uid, (u_long) stbuf.st_mode,
|
||||
errstring(ret));
|
||||
*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]\tEPERM\n", st->st_mode);
|
||||
return EPERM;
|
||||
}
|
||||
#endif
|
||||
if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode))
|
||||
{
|
||||
if (tTd(44, 4))
|
||||
printf("\t[non-reg mode %o]\tEPERM\n", st->st_mode);
|
||||
return EPERM;
|
||||
}
|
||||
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]\tEPERM]\n", st->st_mode);
|
||||
return EPERM;
|
||||
}
|
||||
if (st->st_nlink > 1)
|
||||
{
|
||||
if (tTd(44, 4))
|
||||
printf("\t[link count %d]\tEPERM\n", st->st_nlink);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
|
||||
#ifndef O_ACCMODE
|
||||
# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
safefopen(fn, omode, cmode, sff)
|
||||
char *fn;
|
||||
int omode;
|
||||
int cmode;
|
||||
int sff;
|
||||
{
|
||||
int rval;
|
||||
FILE *fp;
|
||||
int smode;
|
||||
struct stat stb, sta;
|
||||
|
||||
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, 0, 0, NULL, sff, smode, &stb);
|
||||
else
|
||||
rval = safefile(fn, RealUid, RealGid, RealUserName,
|
||||
sff, smode, &stb);
|
||||
if (rval != 0)
|
||||
{
|
||||
errno = rval;
|
||||
return NULL;
|
||||
}
|
||||
if (stb.st_mode == ST_MODE_NOFILE)
|
||||
omode |= O_EXCL;
|
||||
|
||||
fp = dfopen(fn, omode, cmode);
|
||||
if (fp == NULL)
|
||||
return NULL;
|
||||
if (bitset(O_EXCL, omode))
|
||||
return fp;
|
||||
if (fstat(fileno(fp), &sta) < 0 ||
|
||||
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)
|
||||
{
|
||||
syserr("554 cannot open: file %s changed after open", fn);
|
||||
fclose(fp);
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
/*
|
||||
** FIXCRLF -- fix <CR><LF> in line.
|
||||
**
|
||||
** Looks for the <CR><LF> combination and turns it into the
|
||||
|
@ -830,80 +484,6 @@ fixcrlf(line, stripnl)
|
|||
*p = '\0';
|
||||
}
|
||||
/*
|
||||
** DFOPEN -- determined file open
|
||||
**
|
||||
** This routine has the semantics of fopen, 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.
|
||||
*/
|
||||
|
||||
struct omodes
|
||||
{
|
||||
int mask;
|
||||
int mode;
|
||||
char *farg;
|
||||
} OpenModes[] =
|
||||
{
|
||||
{ O_ACCMODE, O_RDONLY, "r" },
|
||||
{ O_ACCMODE|O_APPEND, O_WRONLY, "w" },
|
||||
{ O_ACCMODE|O_APPEND, O_WRONLY|O_APPEND, "a" },
|
||||
{ O_TRUNC, 0, "w+" },
|
||||
{ O_APPEND, O_APPEND, "a+" },
|
||||
{ 0, 0, "r+" },
|
||||
};
|
||||
|
||||
FILE *
|
||||
dfopen(filename, omode, cmode)
|
||||
char *filename;
|
||||
int omode;
|
||||
int cmode;
|
||||
{
|
||||
register int tries;
|
||||
int fd;
|
||||
register struct omodes *om;
|
||||
struct stat st;
|
||||
|
||||
for (om = OpenModes; om->mask != 0; om++)
|
||||
if ((omode & om->mask) == om->mode)
|
||||
break;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
else
|
||||
return fdopen(fd, om->farg);
|
||||
}
|
||||
/*
|
||||
** PUTLINE -- put a line like fputs obeying SMTP conventions
|
||||
**
|
||||
** This routine always guarantees outputing a newline (or CRLF,
|
||||
|
@ -925,7 +505,7 @@ putline(l, mci)
|
|||
register char *l;
|
||||
register MCI *mci;
|
||||
{
|
||||
putxline(l, mci, PXLF_MAPFROM);
|
||||
putxline(l, strlen(l), mci, PXLF_MAPFROM);
|
||||
}
|
||||
/*
|
||||
** PUTXLINE -- putline with flags bits.
|
||||
|
@ -935,6 +515,7 @@ putline(l, mci)
|
|||
**
|
||||
** Parameters:
|
||||
** l -- line to put.
|
||||
** len -- the length of the line.
|
||||
** mci -- the mailer connection information.
|
||||
** pxflags -- flag bits:
|
||||
** PXLF_MAPFROM -- map From_ to >From_.
|
||||
|
@ -948,12 +529,13 @@ putline(l, mci)
|
|||
*/
|
||||
|
||||
void
|
||||
putxline(l, mci, pxflags)
|
||||
putxline(l, len, mci, pxflags)
|
||||
register char *l;
|
||||
size_t len;
|
||||
register MCI *mci;
|
||||
int pxflags;
|
||||
{
|
||||
register char *p;
|
||||
register char *p, *end;
|
||||
register char svchar;
|
||||
int slop = 0;
|
||||
|
||||
|
@ -966,12 +548,13 @@ putxline(l, mci, pxflags)
|
|||
*p = svchar &~ 0200;
|
||||
}
|
||||
|
||||
end = l + len;
|
||||
do
|
||||
{
|
||||
/* find the end of the line */
|
||||
p = strchr(l, '\n');
|
||||
p = memchr(l, '\n', end - l);
|
||||
if (p == NULL)
|
||||
p = &l[strlen(l)];
|
||||
p = end;
|
||||
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%05d >>> ", (int) getpid());
|
||||
|
@ -1005,8 +588,12 @@ putxline(l, mci, pxflags)
|
|||
fputs(mci->mci_mailer->m_eol, mci->mci_out);
|
||||
(void) putc(' ', mci->mci_out);
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%s!\n%05d >>> ",
|
||||
l, (int) getpid());
|
||||
{
|
||||
for ( ; l < q; ++l)
|
||||
(void) putc(*l, TrafficLogFile);
|
||||
fprintf(TrafficLogFile, "!\n%05d >>> ",
|
||||
(int) getpid());
|
||||
}
|
||||
*q = svchar;
|
||||
l = q;
|
||||
slop = 1;
|
||||
|
@ -1029,10 +616,14 @@ putxline(l, mci, pxflags)
|
|||
if (TrafficLogFile != NULL)
|
||||
(void) putc('>', TrafficLogFile);
|
||||
}
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%.*s\n", p - l, l);
|
||||
for ( ; l < p; ++l)
|
||||
{
|
||||
if (TrafficLogFile != NULL)
|
||||
(void) putc(*l, TrafficLogFile);
|
||||
(void) putc(*l, mci->mci_out);
|
||||
}
|
||||
if (TrafficLogFile != NULL)
|
||||
(void) putc('\n', TrafficLogFile);
|
||||
fputs(mci->mci_mailer->m_eol, mci->mci_out);
|
||||
if (*l == '\n')
|
||||
{
|
||||
|
@ -1043,7 +634,7 @@ putxline(l, mci, pxflags)
|
|||
(void) putc(' ', TrafficLogFile);
|
||||
}
|
||||
}
|
||||
} while (l[0] != '\0');
|
||||
} while (l < end);
|
||||
}
|
||||
/*
|
||||
** XUNLINK -- unlink a file, doing logging as appropriate.
|
||||
|
@ -1064,16 +655,16 @@ xunlink(f)
|
|||
{
|
||||
register int i;
|
||||
|
||||
# ifdef LOG
|
||||
if (LogLevel > 98)
|
||||
syslog(LOG_DEBUG, "%s: unlink %s", CurEnv->e_id, f);
|
||||
# endif /* LOG */
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"unlink %s",
|
||||
f);
|
||||
|
||||
i = unlink(f);
|
||||
# ifdef LOG
|
||||
if (i < 0 && LogLevel > 97)
|
||||
syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno);
|
||||
# endif /* LOG */
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"%s: unlink-fail %d",
|
||||
f, errno);
|
||||
}
|
||||
/*
|
||||
** XFCLOSE -- close a file, doing logging as appropriate.
|
||||
|
@ -1147,20 +738,19 @@ sfgets(buf, siz, fp, timeout, during)
|
|||
{
|
||||
if (setjmp(CtxReadTimeout) != 0)
|
||||
{
|
||||
# ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
syslog(LOG_NOTICE,
|
||||
sm_syslog(LOG_NOTICE, CurEnv->e_id,
|
||||
"timeout waiting for input from %.100s during %s",
|
||||
CurHostName ? CurHostName : "local",
|
||||
during);
|
||||
# endif
|
||||
errno = 0;
|
||||
usrerr("451 timeout waiting for input during %s",
|
||||
during);
|
||||
buf[0] = '\0';
|
||||
#if XDEBUG
|
||||
checkfd012(during);
|
||||
#endif
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%05d <<< [TIMEOUT]\n",
|
||||
(int) getpid());
|
||||
return (NULL);
|
||||
}
|
||||
ev = setevent(timeout, readtimeout, 0);
|
||||
|
@ -1365,46 +955,6 @@ atooct(s)
|
|||
return (i);
|
||||
}
|
||||
/*
|
||||
** WAITFOR -- wait for a particular process id.
|
||||
**
|
||||
** Parameters:
|
||||
** pid -- process id to wait for.
|
||||
**
|
||||
** Returns:
|
||||
** status of pid.
|
||||
** -1 if pid never shows up.
|
||||
**
|
||||
** Side Effects:
|
||||
** none.
|
||||
*/
|
||||
|
||||
int
|
||||
waitfor(pid)
|
||||
pid_t pid;
|
||||
{
|
||||
#ifdef WAITUNION
|
||||
union wait st;
|
||||
#else
|
||||
auto int st;
|
||||
#endif
|
||||
pid_t i;
|
||||
|
||||
do
|
||||
{
|
||||
errno = 0;
|
||||
i = wait(&st);
|
||||
if (i > 0)
|
||||
proc_list_drop(i);
|
||||
} while ((i >= 0 || errno == EINTR) && i != pid);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
#ifdef WAITUNION
|
||||
return st.w_status;
|
||||
#else
|
||||
return st;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
** BITINTERSECT -- tell if two bitmaps intersect
|
||||
**
|
||||
** Parameters:
|
||||
|
@ -1606,7 +1156,9 @@ checkfds(where)
|
|||
continue;
|
||||
if (printhdr)
|
||||
{
|
||||
syslog(LOG_DEBUG, "%s: changed fds:", where);
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"%s: changed fds:",
|
||||
where);
|
||||
printhdr = FALSE;
|
||||
}
|
||||
dumpfd(fd, TRUE, TRUE);
|
||||
|
@ -1772,11 +1324,10 @@ dumpfd(fd, printclosed, logit)
|
|||
}
|
||||
|
||||
printit:
|
||||
#ifdef LOG
|
||||
if (logit)
|
||||
syslog(LOG_DEBUG, "%.800s", buf);
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"%.800s", buf);
|
||||
else
|
||||
#endif
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
/*
|
||||
|
@ -2084,10 +1635,8 @@ cleanstrcpy(t, f, l)
|
|||
register char *f;
|
||||
int l;
|
||||
{
|
||||
#ifdef LOG
|
||||
/* check for newlines and log if necessary */
|
||||
(void) denlstring(f, TRUE, TRUE);
|
||||
#endif
|
||||
|
||||
l--;
|
||||
while (l > 0 && *f != '\0')
|
||||
|
@ -2146,20 +1695,23 @@ denlstring(s, strict, logattacks)
|
|||
for (p = bp; (p = strchr(p, '\n')) != NULL; )
|
||||
*p++ = ' ';
|
||||
|
||||
#ifdef LOG
|
||||
if (logattacks)
|
||||
{
|
||||
syslog(LOG_NOTICE, "POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
|
||||
sm_syslog(LOG_NOTICE, CurEnv->e_id,
|
||||
"POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
|
||||
RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
|
||||
shortenstring(bp, 203));
|
||||
}
|
||||
#endif
|
||||
|
||||
return bp;
|
||||
}
|
||||
/*
|
||||
** PATH_IS_DIR -- check to see if file exists and is a directory.
|
||||
**
|
||||
** There are some additional checks for security violations in
|
||||
** here. This routine is intended to be used for the host status
|
||||
** support.
|
||||
**
|
||||
** Parameters:
|
||||
** pathname -- pathname to check for directory-ness.
|
||||
** createflag -- if set, create directory if needed.
|
||||
|
@ -2176,7 +1728,11 @@ path_is_dir(pathname, createflag)
|
|||
{
|
||||
struct stat statbuf;
|
||||
|
||||
#if HASLSTAT
|
||||
if (lstat(pathname, &statbuf) < 0)
|
||||
#else
|
||||
if (stat(pathname, &statbuf) < 0)
|
||||
#endif
|
||||
{
|
||||
if (errno != ENOENT || !createflag)
|
||||
return FALSE;
|
||||
|
@ -2189,6 +1745,14 @@ path_is_dir(pathname, createflag)
|
|||
errno = ENOTDIR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* security: don't allow writable directories */
|
||||
if (bitset(S_IWGRP|S_IWOTH, statbuf.st_mode))
|
||||
{
|
||||
errno = EACCES;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
|
@ -2320,11 +1884,10 @@ proc_list_probe()
|
|||
continue;
|
||||
if (kill(ProcListVec[i], 0) < 0)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 3)
|
||||
syslog(LOG_DEBUG, "proc_list_probe: lost pid %d",
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"proc_list_probe: lost pid %d",
|
||||
ProcListVec[i]);
|
||||
#endif
|
||||
ProcListVec[i] = NO_PID;
|
||||
CurChildren--;
|
||||
}
|
||||
|
@ -2332,3 +1895,119 @@ proc_list_probe()
|
|||
if (CurChildren < 0)
|
||||
CurChildren = 0;
|
||||
}
|
||||
/*
|
||||
** SM_STRCASECMP -- 8-bit clean version of strcasecmp
|
||||
**
|
||||
** Thank you, vendors, for making this all necessary.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* This array is designed for mapping upper and lower case letter
|
||||
* together for a case independent comparison. The mappings are
|
||||
* based upon ascii character sequences.
|
||||
*/
|
||||
static const u_char charmap[] = {
|
||||
0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
|
||||
0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
|
||||
0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
|
||||
0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
|
||||
0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
|
||||
0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
|
||||
0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
|
||||
0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
|
||||
0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
|
||||
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
||||
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
||||
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
||||
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
||||
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
||||
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
||||
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
||||
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
||||
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
||||
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
|
||||
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
|
||||
};
|
||||
|
||||
int
|
||||
sm_strcasecmp(s1, s2)
|
||||
const char *s1, *s2;
|
||||
{
|
||||
register const u_char *cm = charmap,
|
||||
*us1 = (const u_char *)s1,
|
||||
*us2 = (const u_char *)s2;
|
||||
|
||||
while (cm[*us1] == cm[*us2++])
|
||||
if (*us1++ == '\0')
|
||||
return (0);
|
||||
return (cm[*us1] - cm[*--us2]);
|
||||
}
|
||||
|
||||
int
|
||||
sm_strncasecmp(s1, s2, n)
|
||||
const char *s1, *s2;
|
||||
register size_t n;
|
||||
{
|
||||
if (n != 0) {
|
||||
register const u_char *cm = charmap,
|
||||
*us1 = (const u_char *)s1,
|
||||
*us2 = (const u_char *)s2;
|
||||
|
||||
do {
|
||||
if (cm[*us1] != cm[*us2++])
|
||||
return (cm[*us1] - cm[*--us2]);
|
||||
if (*us1++ == '\0')
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
return (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 a new issue