summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src')
-rw-r--r--usr.sbin/sendmail/src/READ_ME29
-rw-r--r--usr.sbin/sendmail/src/TRACEFLAGS3
-rw-r--r--usr.sbin/sendmail/src/envelope.c4
-rw-r--r--usr.sbin/sendmail/src/err.c32
-rw-r--r--usr.sbin/sendmail/src/map.c330
-rw-r--r--usr.sbin/sendmail/src/mci.c10
-rw-r--r--usr.sbin/sendmail/src/queue.c24
-rw-r--r--usr.sbin/sendmail/src/safefile.c32
-rw-r--r--usr.sbin/sendmail/src/version.c4
9 files changed, 368 insertions, 100 deletions
diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME
index 8046d41ac299..154916a0a6e6 100644
--- a/usr.sbin/sendmail/src/READ_ME
+++ b/usr.sbin/sendmail/src/READ_ME
@@ -30,7 +30,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# @(#)READ_ME 8.142 (Berkeley) 6/3/97
+# @(#)READ_ME 8.148 (Berkeley) 8/1/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://ftp.sleepycat.com/db/packages/db.1.85.tar.gz.
+ from http://www.sleepycat.com/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.
@@ -295,6 +295,8 @@ 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.
+HAS_ST_GEN Define this to 1 if your system has the st_gen field in
+ the stat structure (see stat(2)).
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.
@@ -339,6 +341,12 @@ SLEEP_T The type returned by the system sleep() function.
ARBPTR_T The type of an arbitrary pointer -- defaults to "void *".
If you are an very old compiler you may need to define
this to be "char *".
+SOCKADDR_LEN_T The type used for the third parameter to accept(2),
+ getsockname(2), and getpeername(2), representing the
+ length of a struct sockaddr. Defaults to int.
+SOCKOPT_LEN_T The type used for the fifth parameter to getsockopt(2)
+ and setsockopt(2), representing the length of the option
+ buffer. Defaults to int.
LA_TYPE The type of load average your kernel supports. These
can be one of:
LA_ZERO (1) -- it always returns the load average as
@@ -457,6 +465,14 @@ SAFENFSPATHCONF Set this to 1 if and only if you have verified that a
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.
+SIOCGIFCONF_IS_BROKEN
+ Set this if your system has an SIOCGIFCONF ioctl defined,
+ but it doesn't behave the same way as "most" systems (BSD,
+ Solaris, SunOS, HP-UX, etc.)
+SIOCGIFNUM_IS_BROKEN
+ Set this if your system has an SIOCGIFNUM ioctl defined,
+ but it doesn't behave the same way as "most" systems
+ (Solaris, HP-UX).
@@ -633,6 +649,12 @@ GCC 2.7.x problems
problems. I recommend against using -O on that architecture. This
has been seen on FreeBSD 2.0.5 RELEASE.
+GDBM GDBM does not work with sendmail 8.8 because the additional
+ security checks and file locking cause problems. Unfortunately,
+ gdbm does not provide a compile flag in its version of ndbm.h so
+ the code can adapt. We expect this to be fixed in 8.9, but
+ probably at the cost of a new command line compile flag.
+
Configuration file location
Up to 8.6, sendmail tried to find the sendmail.cf file in the same
place as the vendors had put it, even when this was obviously
@@ -960,6 +982,7 @@ A/UX
then re-compile sendmail with "-lgdbm", "-DNDBM", and using the
ndbm.h header file that comes with the gnu-package. This makes
things behave properly.
+ [NOTE: see comment above about GDBM]
I suppose porting the New Berkeley db package is another route,
however, I made a quick attempt at it, and found it difficult
@@ -1416,4 +1439,4 @@ version.c The version number and information about this
Eric Allman
-(Version 8.142, last update 6/3/97 11:34:09)
+(Version 8.148, last update 8/1/97 16:41:54)
diff --git a/usr.sbin/sendmail/src/TRACEFLAGS b/usr.sbin/sendmail/src/TRACEFLAGS
index e9d4818356fd..db461db60fc4 100644
--- a/usr.sbin/sendmail/src/TRACEFLAGS
+++ b/usr.sbin/sendmail/src/TRACEFLAGS
@@ -55,6 +55,9 @@
44 safefile.c safefile, safedirpath, filechanged
45 envelope.c setsender
46 envelope.c openxscript
+47 main.c drop_privileges
+48 parseaddr.c rscheck
+48 conf.c validate_connection
49 conf.c checkcompat
50 envelope.c dropenvelope
51 queue.c unlockqueue
diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c
index 4dc07ae7fc33..3e0fc204020d 100644
--- a/usr.sbin/sendmail/src/envelope.c
+++ b/usr.sbin/sendmail/src/envelope.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)envelope.c 8.104 (Berkeley) 6/3/97";
+static char sccsid[] = "@(#)envelope.c 8.105 (Berkeley) 6/24/97";
#endif /* not lint */
#include "sendmail.h"
@@ -178,7 +178,7 @@ dropenvelope(e, fulldrop)
{
failure_return = TRUE;
if (q->q_owner == NULL && !emptyaddr(&e->e_from))
- (void) sendtolist(e->e_from.q_paddr, NULL,
+ (void) sendtolist(e->e_from.q_paddr, NULLADDR,
&e->e_errorqueue, 0, e);
}
else if (bitset(QPINGONSUCCESS, q->q_flags) &&
diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c
index 5bec0884d02a..f4f95e6cd0f2 100644
--- a/usr.sbin/sendmail/src/err.c
+++ b/usr.sbin/sendmail/src/err.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)err.c 8.62 (Berkeley) 6/5/97";
+static char sccsid[] = "@(#)err.c 8.64 (Berkeley) 7/25/97";
#endif /* not lint */
# include "sendmail.h"
@@ -112,7 +112,7 @@ syserr(fmt, va_alist)
puterrmsg(MsgBuf);
/* save this message for mailq printing */
- if (!panic)
+ if (!panic && CurEnv != NULL)
{
if (CurEnv->e_message != NULL)
free(CurEnv->e_message);
@@ -140,9 +140,10 @@ syserr(fmt, va_alist)
}
if (LogLevel > 0)
- sm_syslog(panic ? LOG_ALERT : LOG_CRIT, CurEnv->e_id,
- "SYSERR(%s): %.900s",
- uname, &MsgBuf[4]);
+ sm_syslog(panic ? LOG_ALERT : LOG_CRIT,
+ CurEnv == NULL ? NOQID : CurEnv->e_id,
+ "SYSERR(%s): %.900s",
+ uname, &MsgBuf[4]);
switch (olderrno)
{
case EBADF:
@@ -178,7 +179,7 @@ syserr(fmt, va_alist)
exit(EX_OSERR);
}
errno = 0;
- if (QuickAbort || (OnlyOneError && !HoldErrs))
+ if (QuickAbort)
longjmp(TopFrame, 2);
}
/*
@@ -254,7 +255,7 @@ usrerr(fmt, va_alist)
"%.900s",
&MsgBuf[4]);
- if (QuickAbort || (OnlyOneError && !HoldErrs))
+ if (QuickAbort)
longjmp(TopFrame, 1);
}
/*
@@ -397,7 +398,8 @@ putoutmsg(msg, holdmsg, heldmsg)
msg[0] = '4';
/* output to transcript if serious */
- if (!heldmsg && CurEnv->e_xfp != NULL && strchr("45", msg[0]) != NULL)
+ if (!heldmsg && CurEnv != NULL && CurEnv->e_xfp != NULL &&
+ strchr("45", msg[0]) != NULL)
fprintf(CurEnv->e_xfp, "%s\n", msg);
if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
@@ -421,6 +423,9 @@ putoutmsg(msg, holdmsg, heldmsg)
(void) fflush(stdout);
+ if (OutChannel == NULL)
+ return;
+
/* if DisConnected, OutChannel now points to the transcript */
if (!DisConnected &&
(OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP))
@@ -441,7 +446,8 @@ putoutmsg(msg, holdmsg, heldmsg)
** rude servers don't read result.
*/
- if (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0)
+ if (InChannel == NULL || feof(InChannel) || ferror(InChannel) ||
+ strncmp(msg, "221", 3) == 0)
return;
/* can't call syserr, 'cause we are using MsgBuf */
@@ -474,8 +480,16 @@ puterrmsg(msg)
/* output the message as usual */
putoutmsg(msg, HoldErrs, FALSE);
+ /* be careful about multiple error messages */
+ if (OnlyOneError)
+ HoldErrs = TRUE;
+
/* signal the error */
Errors++;
+
+ if (CurEnv == NULL)
+ return;
+
if (msgcode == '6')
{
/* notify the postmaster */
diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c
index e0a0fd240884..88e82b19f98a 100644
--- a/usr.sbin/sendmail/src/map.c
+++ b/usr.sbin/sendmail/src/map.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)map.c 8.168 (Berkeley) 6/14/97";
+static char sccsid[] = "@(#)map.c 8.181 (Berkeley) 7/9/97";
#endif /* not lint */
#include "sendmail.h"
@@ -113,14 +113,6 @@ extern bool extract_canonname __P((char *, char *, char[], int));
# 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
@@ -733,7 +725,7 @@ extract_canonname(name, line, cbuf, cbuflen)
#ifdef NDBM
/*
-** DBM_MAP_OPEN -- DBM-style map open
+** NDBM_MAP_OPEN -- DBM-style map open
*/
bool
@@ -743,7 +735,8 @@ ndbm_map_open(map, mode)
{
register DBM *dbm;
struct stat st;
- int fd;
+ int dfd;
+ int pfd;
int sff;
int ret;
int smode = S_IREAD;
@@ -760,10 +753,10 @@ ndbm_map_open(map, mode)
/* 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;
+ sff = SFF_ROOTOK|SFF_REGONLY;
if (mode == O_RDWR)
{
- sff |= SFF_NOLINK;
+ sff |= SFF_NOLINK|SFF_CREAT;
smode = S_IWRITE;
}
else
@@ -786,13 +779,21 @@ ndbm_map_open(map, mode)
return FALSE;
}
if (std.st_mode == ST_MODE_NOFILE)
- mode |= O_EXCL;
+ mode |= O_CREAT|O_EXCL;
+
+ /* heuristic: if files are linked, this is actually gdbm */
+ if (std.st_dev == stp.st_dev && std.st_ino == stp.st_ino)
+ {
+ syserr("dbm map \"%s\": cannot support GDBM",
+ map->map_mname);
+ return FALSE;
+ }
#if LOCK_ON_OPEN
if (mode == O_RDONLY)
mode |= O_SHLOCK;
else
- mode |= O_CREAT|O_TRUNC|O_EXLOCK;
+ mode |= O_TRUNC|O_EXLOCK;
#else
if ((mode & O_ACCMODE) == O_RDWR)
{
@@ -804,7 +805,7 @@ ndbm_map_open(map, mode)
** but there isn't anything we can do about it.
*/
- mode |= O_CREAT|O_TRUNC;
+ mode |= O_TRUNC;
# else
/*
** This ugly code opens the map without truncating it,
@@ -815,29 +816,57 @@ ndbm_map_open(map, mode)
int dirfd;
int pagfd;
- dirfd = safeopen(dirfile, mode|O_CREAT, DBMMODE,
+ dirfd = safeopen(dirfile, mode, DBMMODE,
SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
- pagfd = safeopen(pagfile, mode|O_CREAT, DBMMODE,
+ pagfd = safeopen(pagfile, mode, DBMMODE,
SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT);
if (dirfd < 0 || pagfd < 0)
{
+ int save_errno = errno;
+
+ if (dirfd >= 0)
+ (void) close(dirfd);
+ if (pagfd >= 0)
+ (void) close(pagfd);
+ errno = save_errno;
syserr("ndbm_map_open: cannot create database %s",
map->map_file);
- close(dirfd);
- close(pagfd);
return FALSE;
}
- if (ftruncate(dirfd, (off_t) 0) < 0)
- syserr("ndbm_map_open: cannot truncate %s.dir",
+ if (ftruncate(dirfd, (off_t) 0) < 0 ||
+ ftruncate(pagfd, (off_t) 0) < 0)
+ {
+ int save_errno = errno;
+
+ (void) close(dirfd);
+ (void) close(pagfd);
+ errno = save_errno;
+ syserr("ndbm_map_open: cannot truncate %s.{dir,pag}",
map->map_file);
- if (ftruncate(pagfd, (off_t) 0) < 0)
- syserr("ndbm_map_open: cannot truncate %s.pag",
+ return FALSE;
+ }
+
+ /* if new file, get "before" bits for later filechanged check */
+ if (std.st_mode == ST_MODE_NOFILE &&
+ (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0))
+ {
+ int save_errno = errno;
+
+ (void) close(dirfd);
+ (void) close(pagfd);
+ errno = save_errno;
+ syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file",
map->map_file);
+ return FALSE;
+ }
/* have to save the lock for the duration (bletch) */
map->map_lockfd = dirfd;
close(pagfd);
+
+ /* twiddle bits for dbm_open */
+ mode &= ~(O_CREAT|O_EXCL);
# endif
}
#endif
@@ -846,37 +875,46 @@ ndbm_map_open(map, mode)
dbm = dbm_open(map->map_file, mode, DBMMODE);
if (dbm == NULL)
{
+ int save_errno = errno;
+
if (bitset(MF_ALIAS, map->map_mflags) &&
aliaswait(map, ".pag", FALSE))
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
+ errno = save_errno;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot open DBM database %s", map->map_file);
return FALSE;
}
- if (filechanged(dirfile, dbm_dirfno(dbm), &std, sff) ||
- filechanged(pagfile, dbm_pagfno(dbm), &stp, sff))
+ dfd = dbm_dirfno(dbm);
+ pfd = dbm_pagfno(dbm);
+ if (filechanged(dirfile, dfd, &std, sff) ||
+ filechanged(pagfile, pfd, &stp, sff))
{
- syserr("ndbm_map_open(%s): file changed after open",
- map->map_file);
+ int save_errno = errno;
+
dbm_close(dbm);
#if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
close(map->map_lockfd);
#endif
+ errno = save_errno;
+ syserr("ndbm_map_open(%s): file changed after open",
+ map->map_file);
return FALSE;
}
- map->map_db1 = (void *) dbm;
- fd = dbm_dirfno((DBM *) map->map_db1);
+ map->map_db1 = (ARBPTR_T) dbm;
if (mode == O_RDONLY)
{
#if LOCK_ON_OPEN
- if (fd >= 0)
- (void) lockfile(fd, map->map_file, ".pag", LOCK_UN);
+ if (dfd >= 0)
+ (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
+ if (pfd >= 0)
+ (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN);
#endif
if (bitset(MF_ALIAS, map->map_mflags) &&
!aliaswait(map, ".pag", TRUE))
@@ -886,14 +924,14 @@ ndbm_map_open(map, mode)
{
map->map_mflags |= MF_LOCKED;
}
- if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0)
+ if (fstat(dfd, &st) >= 0)
map->map_mtime = st.st_mtime;
return TRUE;
}
/*
-** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map
+** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map
*/
char *
@@ -951,7 +989,7 @@ ndbm_map_lookup(map, name, av, statp)
/*
-** DBM_MAP_STORE -- store a datum in the database
+** NDBM_MAP_STORE -- store a datum in the database
*/
void
@@ -994,7 +1032,7 @@ ndbm_map_store(map, lhs, rhs)
if (stat > 0)
{
if (!bitset(MF_APPEND, map->map_mflags))
- usrerr("050 Warning: duplicate alias name %s", lhs);
+ message("050 Warning: duplicate alias name %s", lhs);
else
{
static char *buf = NULL;
@@ -1157,7 +1195,6 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
int fd;
int sff;
int saveerrno;
- bool leavelocked = bitset(O_LEAVELOCKED, mode);
struct stat st;
char buf[MAXNAME + 1];
@@ -1170,10 +1207,10 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
mode &= O_ACCMODE;
omode = mode;
- sff = SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
+ sff = SFF_ROOTOK|SFF_REGONLY;
if (mode == O_RDWR)
{
- sff |= SFF_NOLINK;
+ sff |= SFF_NOLINK|SFF_CREAT;
smode = S_IWRITE;
}
else
@@ -1187,28 +1224,26 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
{
/* cannot open this map */
if (tTd(38, 2))
- printf("\tunsafe map file: %d\n", i);
+ printf("\tunsafe map file: %s\n", errstring(i));
+ errno = 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;
+ omode |= O_CREAT|O_EXCL;
map->map_lockfd = -1;
#if LOCK_ON_OPEN
if (mode == O_RDWR)
- omode |= O_CREAT|O_TRUNC|O_EXLOCK;
+ omode |= O_TRUNC|O_EXLOCK;
# if !OLD_NEWDB
else
omode |= O_SHLOCK;
# endif
#else
- if (mode == O_RDWR)
- omode |= O_CREAT;
-
/*
** Pre-lock the file to avoid race conditions. In particular,
** since dbopen returns NULL if the file is zero length, we
@@ -1216,26 +1251,51 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
*/
fd = open(buf, omode, DBMMODE);
-
if (fd < 0)
{
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("db_map_open: cannot pre-open database %s", buf);
- close(fd);
return FALSE;
}
- if (!lockfile(fd, map->map_file, ".db",
- mode == O_RDONLY ? LOCK_SH : LOCK_EX))
+
+ /* make sure no baddies slipped in just before the open... */
+ if (filechanged(buf, fd, &st, sff))
+ {
+ int save_errno = errno;
+
+ (void) close(fd);
+ errno = save_errno;
+ syserr("db_map_open(%s): file changed after pre-open", buf);
+ return FALSE;
+ }
+
+ /* if new file, get the "before" bits for later filechanged check */
+ if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0)
+ {
+ int save_errno = errno;
+
+ (void) close(fd);
+ errno = save_errno;
+ syserr("db_map_open(%s): cannot fstat pre-opened file",
+ buf);
+ return FALSE;
+ }
+
+ /* actually lock the pre-opened file */
+ if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
syserr("db_map_open: cannot lock %s", buf);
+
+ /* set up mode bits for dbopen */
if (mode == O_RDWR)
omode |= O_TRUNC;
+ omode &= ~(O_EXCL|O_CREAT);
#endif
db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
saveerrno = errno;
#if !LOCK_ON_OPEN
- if (leavelocked || mode == O_RDWR)
+ if (mode == O_RDWR)
map->map_lockfd = fd;
else
(void) close(fd);
@@ -1246,25 +1306,28 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
aliaswait(map, ".db", FALSE))
return TRUE;
- errno = saveerrno;
- if (!bitset(MF_OPTIONAL, map->map_mflags))
- 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
+ errno = saveerrno;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot open %s database %s",
+ mapclassname, map->map_file);
return FALSE;
}
if (filechanged(buf, db->fd(db), &st, sff))
{
- syserr("db_map_open(%s): file changed after open", buf);
+ int save_errno = errno;
+
db->close(db);
#if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
close(map->map_lockfd);
#endif
+ errno = save_errno;
+ syserr("db_map_open(%s): file changed after open", buf);
return FALSE;
}
@@ -1273,9 +1336,9 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
#if !OLD_NEWDB
fd = db->fd(db);
# if LOCK_ON_OPEN
- if (fd >= 0 && mode == O_RDONLY && !leavelocked)
+ if (fd >= 0 && mode == O_RDONLY)
{
- (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+ (void) lockfile(fd, buf, NULL, LOCK_UN);
}
# endif
#endif
@@ -1291,7 +1354,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
map->map_mtime = st.st_mtime;
#endif
- map->map_db2 = (void *) db;
+ map->map_db2 = (ARBPTR_T) db;
if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
!aliaswait(map, ".db", TRUE))
return FALSE;
@@ -1312,16 +1375,26 @@ db_map_lookup(map, name, av, statp)
{
DBT key, val;
register DB *db = (DB *) map->map_db2;
+ int i;
int st;
int saveerrno;
int fd;
struct stat stbuf;
char keybuf[MAXNAME + 1];
+ char buf[MAXNAME + 1];
if (tTd(38, 20))
printf("db_map_lookup(%s, %s)\n",
map->map_mname, name);
+ i = strlen(map->map_file);
+ if (i > MAXNAME)
+ i = MAXNAME;
+ strncpy(buf, map->map_file, i);
+ buf[i] = '\0';
+ if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
+ buf[i - 3] = '\0';
+
key.size = strlen(name);
if (key.size > sizeof keybuf - 1)
key.size = sizeof keybuf - 1;
@@ -1331,9 +1404,10 @@ db_map_lookup(map, name, av, statp)
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
makelower(keybuf);
#if !OLD_NEWDB
+ lockdb:
fd = db->fd(db);
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".db", LOCK_SH);
+ (void) lockfile(fd, buf, ".db", LOCK_SH);
if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
{
/* Reopen the database to sync the cache */
@@ -1342,14 +1416,13 @@ db_map_lookup(map, name, av, statp)
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);
+ goto lockdb;
}
else
{
@@ -1385,7 +1458,7 @@ db_map_lookup(map, name, av, statp)
saveerrno = errno;
#if !OLD_NEWDB
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+ (void) lockfile(fd, buf, ".db", LOCK_UN);
#endif
if (st != 0)
{
@@ -1446,7 +1519,7 @@ db_map_store(map, lhs, rhs)
if (stat > 0)
{
if (!bitset(MF_APPEND, map->map_mflags))
- usrerr("050 Warning: duplicate alias name %s", lhs);
+ message("050 Warning: duplicate alias name %s", lhs);
else
{
static char *buf = NULL;
@@ -1500,13 +1573,19 @@ db_map_close(map)
db_map_store(map, "@", "@");
}
- if (db->close(db) != 0)
- syserr("readaliases: db close failure");
+#if OLD_NEWDB
+ (void) db->sync(db);
+#else
+ (void) db->sync(db, 0);
+#endif
#if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
#endif
+
+ if (db->close(db) != 0)
+ syserr("readaliases: db close failure");
}
#endif
@@ -2735,6 +2814,123 @@ ldap_map_parseargs(map,args)
#endif /* LDAP Modules */
/*
+** syslog map
+*/
+
+#if _FFR_SYSLOG_MAP
+
+#define map_prio map_lockfd /* overload field */
+
+/*
+** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages.
+*/
+
+bool
+syslog_map_parseargs(map, args)
+ MAP *map;
+ char *args;
+{
+ char *p = args;
+ char *priority = NULL;
+
+ for (;;)
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '-')
+ break;
+ if (*++p == 'L')
+ priority = ++p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+
+ if (priority == NULL)
+ map->map_prio = LOG_INFO;
+ else
+ {
+ if (strncasecmp("LOG_", priority, 4) == 0)
+ priority += 4;
+
+#ifdef LOG_EMERG
+ if (strcasecmp("EMERG", priority) == 0)
+ map->map_prio = LOG_EMERG;
+ else
+#endif
+#ifdef LOG_ALERT
+ if (strcasecmp("ALERT", priority) == 0)
+ map->map_prio = LOG_ALERT;
+ else
+#endif
+#ifdef LOG_CRIT
+ if (strcasecmp("CRIT", priority) == 0)
+ map->map_prio = LOG_CRIT;
+ else
+#endif
+#ifdef LOG_ERR
+ if (strcasecmp("ERR", priority) == 0)
+ map->map_prio = LOG_ERR;
+ else
+#endif
+#ifdef LOG_WARNING
+ if (strcasecmp("WARNING", priority) == 0)
+ map->map_prio = LOG_WARNING;
+ else
+#endif
+#ifdef LOG_NOTICE
+ if (strcasecmp("NOTICE", priority) == 0)
+ map->map_prio = LOG_NOTICE;
+ else
+#endif
+#ifdef LOG_INFO
+ if (strcasecmp("INFO", priority) == 0)
+ map->map_prio = LOG_INFO;
+ else
+#endif
+#ifdef LOG_DEBUG
+ if (strcasecmp("DEBUG", priority) == 0)
+ map->map_prio = LOG_DEBUG;
+ else
+#endif
+ {
+ syserr("syslog_map_parseargs: Unknown priority %s\n",
+ priority);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+** SYSLOG_MAP_LOOKUP -- rewrite and syslog message. Always return empty string
+*/
+
+char *
+syslog_map_lookup(map, string, args, statp)
+ MAP *map;
+ char *string;
+ char **args;
+ int *statp;
+{
+ char *ptr = map_rewrite(map, string, strlen(string), args);
+
+ if (ptr != NULL)
+ {
+ if (tTd(38, 20))
+ printf("syslog_map_lookup(%s (priority %d): %s\n",
+ map->map_mname, map->map_prio, ptr);
+
+ sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr);
+ }
+
+ *statp = EX_OK;
+ return "";
+}
+
+#endif /* _FFR_SYSLOG_MAP */
+ /*
** HESIOD Modules
*/
diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c
index f8ba789ff8a0..929d82d463a3 100644
--- a/usr.sbin/sendmail/src/mci.c
+++ b/usr.sbin/sendmail/src/mci.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)mci.c 8.62 (Berkeley) 5/29/97";
+static char sccsid[] = "@(#)mci.c 8.66 (Berkeley) 8/2/97";
#endif /* not lint */
#include "sendmail.h"
@@ -330,10 +330,10 @@ mci_get(host, m)
{
/* get peer host address for logging reasons only */
/* (this should really be in the mci struct) */
- int socksize = sizeof CurHostAddr;
+ SOCKADDR_LEN_T socklen = sizeof CurHostAddr;
(void) getpeername(fileno(mci->mci_in),
- (struct sockaddr *) &CurHostAddr, &socksize);
+ (struct sockaddr *) &CurHostAddr, &socklen);
}
# endif
}
@@ -571,7 +571,7 @@ mci_lock_host_statfile(mci)
goto cleanup;
}
- mci->mci_statfile = safefopen(fname, O_RDWR|O_CREAT, FileMode,
+ mci->mci_statfile = safefopen(fname, O_RDWR, FileMode,
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_CREAT);
if (mci->mci_statfile == NULL)
@@ -694,7 +694,7 @@ mci_load_persistent(mci)
}
fp = safefopen(fname, O_RDONLY, FileMode,
- SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY);
+ SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY);
if (fp == NULL)
{
/* I can't think of any reason this should ever happen */
diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c
index 13965de01be2..1d812b8f50d6 100644
--- a/usr.sbin/sendmail/src/queue.c
+++ b/usr.sbin/sendmail/src/queue.c
@@ -36,9 +36,9 @@
#ifndef lint
#if QUEUE
-static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (with queueing)";
+static char sccsid[] = "@(#)queue.c 8.174 (Berkeley) 7/23/97 (with queueing)";
#else
-static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (without queueing)";
+static char sccsid[] = "@(#)queue.c 8.174 (Berkeley) 7/23/97 (without queueing)";
#endif
#endif /* not lint */
@@ -431,7 +431,9 @@ queueup(e, announce)
fprintf(tfp, ".\n");
- if (fflush(tfp) < 0 || fsync(fileno(tfp)) < 0 || ferror(tfp))
+ if (fflush(tfp) < 0 ||
+ (SuperSafe && fsync(fileno(tfp)) < 0) ||
+ ferror(tfp))
{
if (newid)
syserr("!552 Error writing control file %s", tf);
@@ -553,7 +555,6 @@ runqueue(forkflag, verbose)
extern ENVELOPE BlankEnvelope;
extern void clrdaemon __P((void));
extern void runqueueevent __P((void));
- extern void drop_privileges __P((void));
DoQueueRun = FALSE;
@@ -670,7 +671,7 @@ runqueue(forkflag, verbose)
/* drop privileges */
if (geteuid() == (uid_t) 0)
- drop_privileges();
+ (void) drop_privileges(FALSE);
/*
** Create ourselves an envelope
@@ -684,7 +685,7 @@ runqueue(forkflag, verbose)
if (forkflag)
{
disconnect(1, e);
- OnlyOneError = QuickAbort = FALSE;
+ QuickAbort = FALSE;
}
/*
@@ -1463,6 +1464,7 @@ dowork(id, forkflag, requeueflag, e)
{
if (tTd(40, 4))
printf("readqf(%s) failed\n", e->e_id);
+ e->e_id = NULL;
if (forkflag)
exit(EX_OK);
else
@@ -2325,13 +2327,17 @@ loseqfile(e, why)
char *why;
{
char *p;
- char buf[MAXQFNAME];
+ char buf[MAXQFNAME + 1];
if (e == NULL || e->e_id == NULL)
return;
- if (strlen(e->e_id) > (SIZE_T) sizeof buf - 4)
+ p = queuename(e, 'q');
+ if (strlen(p) > MAXQFNAME)
+ {
+ syserr("loseqfile: queuename (%s) too long", p);
return;
- strcpy(buf, queuename(e, 'q'));
+ }
+ strcpy(buf, p);
p = queuename(e, 'Q');
if (rename(buf, p) < 0)
syserr("cannot rename(%s, %s), uid=%d", buf, p, geteuid());
diff --git a/usr.sbin/sendmail/src/safefile.c b/usr.sbin/sendmail/src/safefile.c
index 08660347cafe..842a09f8ca86 100644
--- a/usr.sbin/sendmail/src/safefile.c
+++ b/usr.sbin/sendmail/src/safefile.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)safefile.c 8.12 (Berkeley) 6/14/97";
+static char sccsid[] = "@(#)safefile.c 8.18 (Berkeley) 8/1/97";
#endif /* not lint */
# include "sendmail.h"
@@ -108,6 +108,10 @@ safefile(fn, uid, gid, uname, flags, mode, st)
strcpy(fbuf, fn);
fn = fbuf;
+ /* ignore SFF_SAFEDIRPATH if we are debugging */
+ if (RealUid != 0 && RunAsUid == RealUid)
+ flags &= ~SFF_SAFEDIRPATH;
+
/* first check to see if the file exists at all */
#ifdef HASLSTAT
if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st)
@@ -464,6 +468,7 @@ safeopen(fn, omode, cmode, sff)
if (bitset(O_CREAT, omode))
sff |= SFF_CREAT;
+ omode &= ~O_CREAT;
smode = 0;
switch (omode & O_ACCMODE)
{
@@ -494,8 +499,8 @@ safeopen(fn, omode, cmode, sff)
errno = rval;
return -1;
}
- if (stb.st_mode == ST_MODE_NOFILE)
- omode |= O_EXCL;
+ if (stb.st_mode == ST_MODE_NOFILE && bitset(SFF_CREAT, sff))
+ omode |= O_EXCL|O_CREAT;
fd = dfopen(fn, omode, cmode, sff);
if (fd < 0)
@@ -561,10 +566,24 @@ safefopen(fn, omode, cmode, sff)
}
fd = safeopen(fn, omode, cmode, sff);
if (fd < 0)
+ {
+ if (tTd(44, 10))
+ printf("safefopen: safeopen failed: %s\n",
+ errstring(errno));
return NULL;
+ }
fp = fdopen(fd, fmode);
if (fp != NULL)
return fp;
+
+ if (tTd(44, 10))
+ {
+ printf("safefopen: fdopen(%s, %s) failed: omode=%x, sff=%x, err=%s\n",
+ fn, fmode, omode, sff, errstring(errno));
+#ifndef NOT_SENDMAIL
+ dumpfd(fd, TRUE, FALSE);
+#endif
+ }
(void) close(fd);
return NULL;
}
@@ -607,6 +626,9 @@ filechanged(fn, fd, stb, sff)
if (sta.st_nlink != stb->st_nlink ||
sta.st_dev != stb->st_dev ||
sta.st_ino != stb->st_ino ||
+#if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
+ sta.st_gen != stb->st_gen ||
+#endif
sta.st_uid != stb->st_uid ||
sta.st_gid != stb->st_gid)
{
@@ -619,6 +641,10 @@ filechanged(fn, fd, stb, sff)
(long) stb->st_dev, (long) sta.st_dev);
printf(" ino = %ld/%ld\n",
(long) stb->st_ino, (long) sta.st_ino);
+#if HAS_ST_GEN
+ printf(" gen = %ld/%ld\n",
+ (long) stb->st_gen, (long) sta.st_gen);
+#endif
printf(" uid = %ld/%ld\n",
(long) stb->st_uid, (long) sta.st_uid);
printf(" gid = %ld/%ld\n",
diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c
index 6f6ffad0c8ea..c531c5bdf075 100644
--- a/usr.sbin/sendmail/src/version.c
+++ b/usr.sbin/sendmail/src/version.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)version.c 8.8.6.1 (Berkeley) 6/14/97";
+static char sccsid[] = "@(#)version.c 8.8.7.3 (Berkeley) 8/3/97";
#endif /* not lint */
-char Version[] = "8.8.6";
+char Version[] = "8.8.7";