sendmail 8.6.9. may your cm5 explode

This commit is contained in:
glass 1994-04-20 06:26:31 +00:00
parent 02b2e464f5
commit 1ffc6c23e3
21 changed files with 858 additions and 211 deletions

View File

@ -30,7 +30,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)READ_ME 8.58 (Berkeley) 3/13/94
# @(#)READ_ME 8.61 (Berkeley) 4/17/94
#
This directory contains the source files for sendmail.
@ -136,7 +136,7 @@ these just include the support they indicate. [If you are using NEWDB,
get the latest version from FTP.CS.Berkeley.EDU in /ucb/4bsd. DO NOT
use the version from the Net2 distribution! However, if you are on
BSD/386 or 386BSD-based systems, use the one that already exists
on your system. You may need to define OLD_NEWDB to do this.]
on your system. You may need to #define OLD_NEWDB 1 to do this.]
[NOTE WELL: it is CRITICAL that you remove ndbm.o from libdb.a and
ndbm.h from the appropriate include directories if you want to get
@ -250,6 +250,10 @@ NEEDVPRINTF Define this if your standard C library does not define
vprintf(3). Note that the resulting fake implementation
is not very elegant and may not even work on some
architectures.
NEEDFSYNC Define this if your standard C library does not define
fsync(2). This will try to simulate the operation using
fcntl(2); if that is not available it does nothing, which
isn't great, but at least it compiles and runs.
HASGETUSERSHELL Define this to 1 if you have getusershell(3) in your
standard C library. If this is not defined, or is defined
to be 0, sendmail will scan the /etc/shells file (no
@ -296,11 +300,11 @@ SFS_TYPE Encodes how your kernel can locate the amount of free
SFS_USTAT (1) if you have the ustat(2) system call,
SFS_4ARGS (2) if you have a four-argument statfs(2)
system call (and the include file is <sys/statfs.h>),
and SFS_VFS (3), SFS_MOUNT (4), or SFS_STATFS (5) if
you have the two-argument statfs(2) system call, with
includes in <sys/vfs.h>, <sys/mount.h>, or <sys/statfs.h>
respectively. The default if nothing is defined is
SFS_NONE.
and SFS_VFS (3), SFS_MOUNT (4), SFS_STATFS (5) or
SFS_STATVFS (6) if you have the two-argument statfs(2)
system call, with includes in <sys/vfs.h>, <sys/mount.h>,
<sys/statfs.h>, or <sys/statvfs.h> respectively. The
default if nothing is defined is SFS_NONE.
ERRLIST_PREDEFINED
If set, assumes that some header file defines sys_errlist.
This may be needed if you get type conflicts on this
@ -341,6 +345,10 @@ NDBM Include support for "new" DBM library for aliases and maps.
Normally defined in the Makefile.
NEWDB Include support for Berkeley "db" package (hash & btree)
for aliases and maps. Normally defined in the Makefile.
OLD_NEWDB If non-zero, the version of NEWDB you have is the old
one that does not include the "fd" call. This call was
added in version 1.5 of the Berkeley DB code. If you
use -DOLD_NEWDB=0 it forces you to use the new interface.
NIS Define this to get NIS (YP) support for aliases and maps.
Normally defined in the Makefile.
USERDB Include support for the User Information Database. Implied
@ -575,7 +583,7 @@ BSDI (BSD/386) 1.0, NetBSD 0.9, FreeBSD 1.0
other system files, such as /etc/passwd, unless you use the
new db format throughout your system. You should normally just
use the version of db supplied in your release. You may need
to use -DOLD_NEWDB to make this work -- this turns off some
to use -DOLD_NEWDB=1 to make this work -- this turns off some
new interface calls (for file locking) that are not in older
versions of db. You'll get compile errors if you need this
flag and don't have it set.
@ -861,4 +869,4 @@ version.c The version number and information about this
Eric Allman
(Version 8.58, last update 3/13/94 09:38:06)
(Version 8.61, last update 4/17/94 07:05:32)

View File

@ -36,7 +36,7 @@
# include <pwd.h>
#ifndef lint
static char sccsid[] = "@(#)alias.c 8.24 (Berkeley) 2/28/94";
static char sccsid[] = "@(#)alias.c 8.25 (Berkeley) 4/14/94";
#endif /* not lint */
@ -144,11 +144,20 @@ alias(a, sendq, e)
if (!bitnset(M_USR_UPPER, a->q_mailer->m_flags))
makelower(obuf);
owner = aliaslookup(obuf, e);
if (owner != NULL)
if (owner == NULL)
return;
/* reflect owner into envelope sender */
if (strpbrk(owner, ",:/|\"") != NULL)
owner = obuf;
a->q_owner = newstr(owner);
/* announce delivery to this alias; NORECEIPT bit set later */
if (e->e_xfp != NULL)
{
if (strpbrk(owner, ",:/|\"") != NULL)
owner = obuf;
a->q_owner = newstr(owner);
fprintf(e->e_xfp, "Message delivered to mailing list %s\n",
a->q_paddr);
e->e_flags |= EF_SENDRECEIPT;
}
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)collect.c 8.9 (Berkeley) 1/31/94";
static char sccsid[] = "@(#)collect.c 8.14 (Berkeley) 4/18/94";
#endif /* not lint */
# include <errno.h>
@ -63,6 +63,9 @@ static char sccsid[] = "@(#)collect.c 8.9 (Berkeley) 1/31/94";
** The from person may be set.
*/
char *CollectErrorMessage;
bool CollectErrno;
collect(smtpmode, requeueflag, e)
bool smtpmode;
bool requeueflag;
@ -76,13 +79,16 @@ collect(smtpmode, requeueflag, e)
extern char *hvalue();
extern bool isheader(), flusheol();
CollectErrorMessage = NULL;
CollectErrno = 0;
/*
** Create the temp file name and create the file.
*/
e->e_df = queuename(e, 'd');
e->e_df = newstr(e->e_df);
if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT, FileMode)) == NULL)
if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL)
{
syserr("Cannot create %s", e->e_df);
NoReturn = TRUE;
@ -96,6 +102,9 @@ collect(smtpmode, requeueflag, e)
if (smtpmode)
message("354 Enter mail, end with \".\" on a line by itself");
/* set global timer to monitor progress */
sfgetset(TimeOuts.to_datablock);
/*
** Try to read a UNIX-style From line
*/
@ -287,17 +296,30 @@ readerr:
inputerr = TRUE;
}
/* reset global timer */
sfgetset((time_t) 0);
if (fflush(tf) != 0)
tferror(tf, e);
if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
{
syserr("cannot sync message data to disk (%s)", e->e_df);
tferror(tf, e);
finis();
}
/* An EOF when running SMTP is an error */
if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
if (CollectErrorMessage != NULL && Errors <= 0)
{
if (CollectErrno != 0)
{
errno = CollectErrno;
syserr(CollectErrorMessage, e->e_df);
finis();
}
usrerr(CollectErrorMessage);
}
else if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
{
/* An EOF when running SMTP is an error */
char *host;
char *problem;
@ -314,8 +336,8 @@ readerr:
# ifdef LOG
if (LogLevel > 0 && feof(InChannel))
syslog(LOG_NOTICE,
"collect: %s on connection from %s, sender=%s: %m\n",
problem, host, e->e_from.q_paddr);
"collect: %s on connection from %s, sender=%s: %s\n",
problem, host, e->e_from.q_paddr, errstring(errno));
# endif
if (feof(InChannel))
usrerr("451 collect: %s on connection from %s, from=%s",
@ -401,14 +423,12 @@ flusheol(buf, fp)
FILE *fp;
{
register char *p = buf;
bool printmsg = TRUE;
char junkbuf[MAXLINE];
while (strchr(p, '\n') == NULL)
{
if (printmsg)
usrerr("553 header line too long");
printmsg = FALSE;
CollectErrorMessage = "553 header line too long";
CollectErrno = 0;
if (sfgets(junkbuf, MAXLINE, fp, TimeOuts.to_datablock,
"long line flush") == NULL)
return (FALSE);
@ -435,14 +455,43 @@ tferror(tf, e)
FILE *tf;
register ENVELOPE *e;
{
CollectErrno = errno;
if (errno == ENOSPC)
{
struct stat st;
long avail;
long bsize;
NoReturn = TRUE;
if (fstat(fileno(tf), &st) < 0)
st.st_size = 0;
(void) freopen(e->e_df, "w", tf);
fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf);
usrerr("452 Out of disk space for temp file");
if (st.st_size <= 0)
fprintf(tf, "\n*** Mail could not be accepted");
else if (sizeof st.st_size > sizeof (long))
fprintf(tf, "\n*** Mail of at least %qd bytes could not be accepted\n",
st.st_size);
else
fprintf(tf, "\n*** Mail of at least %ld bytes could not be accepted\n",
st.st_size);
fprintf(tf, "*** at %s due to lack of disk space for temp file.\n",
MyHostName);
avail = freespace(QueueDir, &bsize);
if (avail > 0)
{
if (bsize > 1024)
avail *= bsize / 1024;
else if (bsize < 1024)
avail /= 1024 / bsize;
fprintf(tf, "*** Currently, %ld kilobytes are available for mail temp files.\n",
avail);
}
CollectErrorMessage = "452 Out of disk space for temp file";
}
else
syserr("collect: Cannot write %s", e->e_df);
{
CollectErrorMessage = "cannot write message body to disk (%s)";
}
(void) freopen("/dev/null", "w", tf);
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)conf.c 8.82 (Berkeley) 3/6/94";
static char sccsid[] = "@(#)conf.c 8.89 (Berkeley) 4/18/94";
#endif /* not lint */
# include "sendmail.h"
@ -147,6 +147,7 @@ struct prival PrivacyValues[] =
"restrictmailq", PRIV_RESTRICTMAILQ,
"restrictqrun", PRIV_RESTRICTQRUN,
"authwarnings", PRIV_AUTHWARNINGS,
"noreceipts", PRIV_NORECEIPTS,
"goaway", PRIV_GOAWAY,
NULL, 0,
};
@ -668,17 +669,17 @@ struct nlist Nl[] =
# define FSHIFT 5
# endif
# if defined(__alpha)
# if defined(__alpha) || defined(IRIX)
# define FSHIFT 10
# endif
# if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
# define FSHIFT 8
# endif
#endif
#if ((LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)) && !defined(FSCALE)
# define FSCALE (1 << FSHIFT)
#ifndef FSHIFT
# define FSHIFT 8
#endif
#ifndef FSCALE
# define FSCALE (1 << FSHIFT)
#endif
getla()
@ -721,6 +722,9 @@ getla()
_PATH_UNIX, LA_AVENRUN);
return (-1);
}
#ifdef IRIX
Nl[X_AVENRUN].n_value &= 0x7fffffff;
#endif
}
if (tTd(3, 20))
printf("getla: symbol address = %#x\n", Nl[X_AVENRUN].n_value);
@ -913,7 +917,7 @@ getla()
/* Non Apollo stuff removed by Don Lewis 11/15/93 */
#ifndef lint
static char rcsid[] = "@(#)$Id: conf.c,v 1.7 1994/03/16 02:13:13 glass Exp $";
static char rcsid[] = "@(#)$Id: conf.c,v 1.8 1994/04/20 06:26:38 glass Exp $";
#endif /* !lint */
#ifdef apollo
@ -1115,8 +1119,10 @@ reapchild()
{
if (count++ > 1000)
{
#ifdef LOG
syslog(LOG_ALERT, "reapchild: waitpid loop: pid=%d, status=%x",
pid, status);
#endif
break;
}
}
@ -1308,7 +1314,7 @@ setsid __P ((void))
#ifdef TIOCNOTTY
int fd;
fd = open("/dev/tty", 2);
fd = open("/dev/tty", O_RDWR, 0);
if (fd >= 0)
{
(void) ioctl(fd, (int) TIOCNOTTY, (char *) 0);
@ -1322,6 +1328,24 @@ setsid __P ((void))
# endif
}
#endif
/*
** FSYNC -- dummy fsync
*/
#ifdef NEEDFSYNC
fsync(fd)
int fd;
{
# ifdef O_SYNC
return fcntl(fd, F_SETFL, O_SYNC);
# else
/* nothing we can do */
return 0;
# endif
}
#endif
/*
** DGUX_INET_ADDR -- inet_addr for DG/UX
@ -1591,6 +1615,7 @@ usershellok(shell)
#define SFS_VFS 3 /* use <sys/vfs.h> implementation */
#define SFS_MOUNT 4 /* use <sys/mount.h> implementation */
#define SFS_STATFS 5 /* use <sys/statfs.h> implementation */
#define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */
#ifndef SFS_TYPE
# define SFS_TYPE SFS_NONE
@ -1608,6 +1633,9 @@ usershellok(shell)
#if SFS_TYPE == SFS_MOUNT
# include <sys/mount.h>
#endif
#if SFS_TYPE == SFS_STATVFS
# include <sys/statvfs.h>
#endif
long
freespace(dir, bsize)
@ -1626,10 +1654,15 @@ freespace(dir, bsize)
# define f_bavail fd_bfreen
# define FSBLOCKSIZE fs.fd_bsize
# else
# if SFS_TYPE == SFS_STATVFS
struct statvfs fs;
# define FSBLOCKSIZE fs.f_bsize
# else
struct statfs fs;
# define FSBLOCKSIZE fs.f_bsize
# if defined(_SCO_unix_) || defined(IRIX) || defined(apollo)
# define f_bavail f_bfree
# define FSBLOCKSIZE fs.f_bsize
# if defined(_SCO_unix_) || defined(IRIX) || defined(apollo)
# define f_bavail f_bfree
# endif
# endif
# endif
# endif

View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)conf.h 8.96 (Berkeley) 3/11/94
* @(#)conf.h 8.104 (Berkeley) 4/17/94
*/
/*
@ -182,7 +182,7 @@ extern int syslog(int, char *, ...);
*/
# ifdef IRIX
# include <sys/sysmacros.h>
# define SYSTEM5 1 /* this is a System-V derived system */
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
@ -191,6 +191,7 @@ extern int syslog(int, char *, ...);
# define setpgid BSDsetpgrp
# define GIDSET_T gid_t
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
# define LA_TYPE LA_INT
# endif
@ -255,6 +256,11 @@ extern int syslog(int, char *, ...);
typedef int pid_t;
extern char *getenv();
# else
/* 4.1.x specifics */
# define HASSETSID 1 /* has Posix setsid(2) call */
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
# endif
# endif
#endif
@ -394,17 +400,22 @@ typedef int pid_t;
#ifdef __bsdi__
# define HASUNSETENV 1 /* has the unsetenv(3) call */
# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
# define HASSETPROCTITLE 1 /* setproctitle is in libc */
# else
# define SETPROCTITLE 1
# endif
# include <sys/cdefs.h>
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
# endif
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
/* version 1.1 or later */
# define HASSETPROCTITLE 1 /* setproctitle is in libc */
# undef SETPROCTITLE /* so don't redefine it in conf.c */
# else
/* version 1.0 or earlier */
# ifndef OLD_NEWDB
# define OLD_NEWDB 1 /* old version of newdb library */
# endif
# endif
#endif
@ -427,6 +438,7 @@ typedef int pid_t;
# undef SETPROCTITLE
# define HASSETPROCTITLE
# define setreuid(r,e) __setreuid(r,e)
# define GIDSET_T gid_t
#endif
# include <sys/cdefs.h>
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
@ -510,6 +522,7 @@ extern int errno;
#ifdef _SCO_unix_4_2
# define _SCO_unix_
# define HASSETREUID 1 /* has setreuid(2) call */
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
# define _PATH_UNIX "/unix"
# ifndef _PATH_SENDMAILCF
# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
@ -826,6 +839,67 @@ typedef int pid_t;
#endif
/*
** UnixWare
**
** From Evan Champion <evanc@spatial.synapse.org>.
*/
#ifdef UNIXWARE
# define SYSTEM5 1
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
# endif
# define GIDSET_T int
# define SLEEP_T int
# define SFS_TYPE SFS_STATVFS
# define LA_TYPE LA_ZERO
# undef WIFEXITED
# undef WEXITSTATUS
# define _PATH_UNIX "/unix"
# ifndef _PATH_SENDMAILCF
# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf"
# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
# endif
# define SYSLOG_BUFSIZE 128
#endif
/*
** Intergraph CLIX 3.1
**
** From Paul Southworth <pauls@locust.cic.net>
*/
#ifdef CLIX
# define SYSTEM5 1 /* looks like System V */
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
# endif
# define DEV_BSIZE 512 /* device block size not defined */
# define GIDSET_T gid_t
# undef LOG /* syslog not available */
# define NEEDFSYNC 1 /* no fsync in system library */
# define GETSHORT _getshort
#endif
/*
** NCR 3000 Series (SysVr4)
**
** From From: Kevin Darcy <kevin@tech.mis.cfc.com>.
*/
#ifdef NCR3000
# define __svr4__
# undef BSD
# define LA_AVENRUN "avenrun"
#endif
/**********************************************************************
@ -935,6 +1009,10 @@ typedef int pid_t;
# define HASFLOCK 0 /* assume no flock(2) support */
#endif
#ifndef OLD_NEWDB
# define OLD_NEWDB 0 /* assume newer version of newdb */
#endif
/**********************************************************************
** Remaining definitions should never have to be changed. They are

View File

@ -37,9 +37,9 @@
#ifndef lint
#ifdef DAEMON
static char sccsid[] = "@(#)daemon.c 8.39 (Berkeley) 3/13/94 (with daemon mode)";
static char sccsid[] = "@(#)daemon.c 8.48 (Berkeley) 4/18/94 (with daemon mode)";
#else
static char sccsid[] = "@(#)daemon.c 8.39 (Berkeley) 3/13/94 (without daemon mode)";
static char sccsid[] = "@(#)daemon.c 8.48 (Berkeley) 4/18/94 (without daemon mode)";
#endif
#endif /* not lint */
@ -109,10 +109,12 @@ int TcpSndBufferSize = 0; /* size of TCP send buffer */
getrequests()
{
int t;
int on = 1;
bool refusingconnections = TRUE;
FILE *pidf;
int socksize;
#ifdef XDEBUG
bool j_has_dot;
#endif
extern void reapchild();
/*
@ -145,61 +147,7 @@ getrequests()
printf("getrequests: port 0x%x\n", DaemonAddr.sin.sin_port);
/* get a socket for the SMTP connection */
DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0);
if (DaemonSocket < 0)
{
/* probably another daemon already */
syserr("getrequests: can't create socket");
severe:
# ifdef LOG
if (LogLevel > 0)
syslog(LOG_ALERT, "problem creating SMTP socket");
# endif /* LOG */
finis();
}
/* turn on network debugging? */
if (tTd(15, 101))
(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof on);
(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on);
(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof on);
#ifdef SO_RCVBUF
if (TcpRcvBufferSize > 0)
{
if (setsockopt(DaemonSocket, SOL_SOCKET, SO_RCVBUF,
(char *) &TcpRcvBufferSize,
sizeof(TcpRcvBufferSize)) < 0)
syserr("getrequests: setsockopt(SO_RCVBUF)");
}
#endif
switch (DaemonAddr.sa.sa_family)
{
# ifdef NETINET
case AF_INET:
socksize = sizeof DaemonAddr.sin;
break;
# endif
# ifdef NETISO
case AF_ISO:
socksize = sizeof DaemonAddr.siso;
break;
# endif
default:
socksize = sizeof DaemonAddr;
break;
}
if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0)
{
syserr("getrequests: cannot bind");
(void) close(DaemonSocket);
goto severe;
}
socksize = opendaemonsocket(TRUE);
(void) setsignal(SIGCHLD, reapchild);
@ -219,6 +167,14 @@ getrequests()
fclose(pidf);
}
#ifdef XDEBUG
{
char jbuf[MAXHOSTNAMELEN];
expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
j_has_dot = strchr(jbuf, '.') != NULL;
}
#endif
if (tTd(15, 1))
printf("getrequests: %d\n", DaemonSocket);
@ -233,31 +189,50 @@ getrequests()
CurrentLA = getla();
if (refuseconnections())
{
if (!refusingconnections)
if (DaemonSocket >= 0)
{
/* don't queue so peer will fail quickly */
(void) listen(DaemonSocket, 0);
refusingconnections = TRUE;
/* close socket so peer will fail quickly */
(void) close(DaemonSocket);
DaemonSocket = -1;
}
refusingconnections = TRUE;
setproctitle("rejecting connections: load average: %d",
CurrentLA);
sleep(5);
sleep(15);
continue;
}
if (refusingconnections)
{
/* start listening again */
if (listen(DaemonSocket, ListenQueueSize) < 0)
{
syserr("getrequests: cannot listen");
(void) close(DaemonSocket);
goto severe;
}
(void) opendaemonsocket(FALSE);
setproctitle("accepting connections");
refusingconnections = FALSE;
}
#ifdef XDEBUG
/* check for disaster */
{
register STAB *s;
char jbuf[MAXHOSTNAMELEN];
expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
if ((s = stab(jbuf, ST_CLASS, ST_FIND)) == NULL ||
!bitnset('w', s->s_class))
{
dumpstate("daemon lost $j");
syslog(LOG_ALERT, "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");
abort();
}
}
#endif
/* wait for a connection */
do
{
@ -349,6 +324,118 @@ getrequests()
/*NOTREACHED*/
}
/*
** OPENDAEMONSOCKET -- open the SMTP socket
**
** Deals with setting all appropriate options. DaemonAddr must
** be set up in advance.
**
** Parameters:
** firsttime -- set if this is the initial open.
**
** Returns:
** Size in bytes of the daemon socket addr.
**
** Side Effects:
** Leaves DaemonSocket set to the open socket.
** Exits if the socket cannot be created.
*/
#define MAXOPENTRIES 10 /* maximum number of tries to open connection */
int
opendaemonsocket(firsttime)
bool firsttime;
{
int on = 1;
int socksize;
int ntries = 0;
int saveerrno;
if (tTd(15, 2))
printf("opendaemonsocket()\n");
do
{
if (ntries > 0)
sleep(5);
if (firsttime || DaemonSocket < 0)
{
DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0);
if (DaemonSocket < 0)
{
/* probably another daemon already */
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 */
DaemonSocket = -1;
continue;
}
/* turn on network debugging? */
if (tTd(15, 101))
(void) setsockopt(DaemonSocket, SOL_SOCKET,
SO_DEBUG, (char *)&on,
sizeof on);
(void) setsockopt(DaemonSocket, SOL_SOCKET,
SO_REUSEADDR, (char *)&on, sizeof on);
(void) setsockopt(DaemonSocket, SOL_SOCKET,
SO_KEEPALIVE, (char *)&on, sizeof on);
#ifdef SO_RCVBUF
if (TcpRcvBufferSize > 0)
{
if (setsockopt(DaemonSocket, SOL_SOCKET,
SO_RCVBUF,
(char *) &TcpRcvBufferSize,
sizeof(TcpRcvBufferSize)) < 0)
syserr("getrequests: setsockopt(SO_RCVBUF)");
}
#endif
switch (DaemonAddr.sa.sa_family)
{
# ifdef NETINET
case AF_INET:
socksize = sizeof DaemonAddr.sin;
break;
# endif
# ifdef NETISO
case AF_ISO:
socksize = sizeof DaemonAddr.siso;
break;
# endif
default:
socksize = sizeof DaemonAddr;
break;
}
if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0)
{
saveerrno = errno;
syserr("getrequests: cannot bind");
(void) close(DaemonSocket);
goto severe;
}
}
if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0)
{
saveerrno = errno;
syserr("getrequests: cannot listen");
(void) close(DaemonSocket);
goto severe;
}
return socksize;
} while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
finis();
}
/*
** CLRDAEMON -- reset the daemon connection
**
** Parameters:
@ -740,7 +827,7 @@ gothostent:
if (tTd(16, 101))
{
int on = 1;
(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG,
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof on);
}
if (CurEnv->e_xfp != NULL)
@ -828,29 +915,48 @@ myhostname(hostbuf, size)
(void) strcpy(hostbuf, "localhost");
}
hp = gethostbyname(hostbuf);
if (hp != NULL)
if (hp == NULL)
{
(void) strncpy(hostbuf, hp->h_name, size - 1);
hostbuf[size - 1] = '\0';
if (hp->h_addrtype == AF_INET && hp->h_length == 4)
{
register int i;
for (i = 0; hp->h_addr_list[i] != NULL; i++)
{
char ipbuf[100];
sprintf(ipbuf, "[%s]",
inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
setclass('w', ipbuf);
}
}
return (hp->h_aliases);
syserr("!My host name (%s) does not seem to exist!", hostbuf);
}
else
return (NULL);
(void) strncpy(hostbuf, hp->h_name, size - 1);
hostbuf[size - 1] = '\0';
#if NAMED_BIND
/* if still no dot, try DNS directly (i.e., avoid NIS problems) */
if (strchr(hostbuf, '.') == NULL)
{
extern bool getcanonname();
extern int h_errno;
/* try twice in case name server not yet started up */
if (!getcanonname(hostbuf, size, TRUE) &&
UseNameServer &&
(h_errno != TRY_AGAIN ||
(sleep(30), !getcanonname(hostbuf, size, TRUE))))
{
errno = h_errno + E_DNSBASE;
syserr("!My host name (%s) not known to DNS",
hostbuf);
}
}
#endif
if (hp->h_addrtype == AF_INET && hp->h_length == 4)
{
register int i;
for (i = 0; hp->h_addr_list[i] != NULL; i++)
{
char ipbuf[100];
sprintf(ipbuf, "[%s]",
inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
setclass('w', ipbuf);
}
}
return (hp->h_aliases);
}
/*
** GETAUTHINFO -- get the real host name asociated with a file descriptor
@ -880,7 +986,6 @@ char *
getauthinfo(fd)
int fd;
{
SOCKADDR fa;
int falen;
register char *p;
#if IDENTPROTO
@ -895,9 +1000,9 @@ getauthinfo(fd)
extern char *hostnamebyanyaddr();
extern char RealUserName[]; /* main.c */
falen = sizeof fa;
if (getpeername(fd, &fa.sa, &falen) < 0 || falen <= 0 ||
fa.sa.sa_family == 0)
falen = sizeof RealHostAddr;
if (getpeername(fd, &RealHostAddr.sa, &falen) < 0 || falen <= 0 ||
RealHostAddr.sa.sa_family == 0)
{
(void) sprintf(hbuf, "%s@localhost", RealUserName);
if (tTd(9, 1))
@ -905,12 +1010,18 @@ getauthinfo(fd)
return hbuf;
}
if (RealHostName == NULL)
{
/* translate that to a host name */
RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
}
#if IDENTPROTO
if (TimeOuts.to_ident == 0)
goto noident;
lalen = sizeof la;
if (fa.sa.sa_family != AF_INET ||
if (RealHostAddr.sa.sa_family != AF_INET ||
getsockname(fd, &la.sa, &lalen) < 0 || lalen <= 0 ||
la.sa.sa_family != AF_INET)
{
@ -920,7 +1031,7 @@ getauthinfo(fd)
/* create ident query */
(void) sprintf(hbuf, "%d,%d\r\n",
ntohs(fa.sin.sin_port), ntohs(la.sin.sin_port));
ntohs(RealHostAddr.sin.sin_port), ntohs(la.sin.sin_port));
/* create local address */
la.sin.sin_port = 0;
@ -928,9 +1039,9 @@ getauthinfo(fd)
/* create foreign address */
sp = getservbyname("auth", "tcp");
if (sp != NULL)
fa.sin.sin_port = sp->s_port;
RealHostAddr.sin.sin_port = sp->s_port;
else
fa.sin.sin_port = htons(113);
RealHostAddr.sin.sin_port = htons(113);
s = -1;
if (setjmp(CtxAuthTimeout) != 0)
@ -951,7 +1062,7 @@ getauthinfo(fd)
goto noident;
}
if (bind(s, &la.sa, sizeof la.sin) < 0 ||
connect(s, &fa.sa, sizeof fa.sin) < 0)
connect(s, &RealHostAddr.sa, sizeof RealHostAddr.sin) < 0)
{
goto closeident;
}

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)deliver.c 8.78 (Berkeley) 3/11/94";
static char sccsid[] = "@(#)deliver.c 8.82 (Berkeley) 4/18/94";
#endif /* not lint */
#include "sendmail.h"
@ -232,7 +232,8 @@ sendall(e, mode)
ee->e_header = copyheader(e->e_header);
ee->e_sendqueue = copyqueue(e->e_sendqueue);
ee->e_errorqueue = copyqueue(e->e_errorqueue);
ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS);
ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT);
ee->e_flags |= EF_NORECEIPT;
setsender(owner, ee, NULL, TRUE);
if (tTd(13, 5))
{
@ -289,6 +290,7 @@ sendall(e, mode)
}
e->e_from.q_flags |= QDONTSEND;
e->e_errormode = EM_MAIL;
e->e_flags |= EF_NORECEIPT;
}
# ifdef QUEUE
@ -1296,6 +1298,9 @@ tryhost:
}
env[i++] = NULL;
/* run disconnected from terminal */
(void) setsid();
/* try to execute the mailer */
execve(m->m_mailer, pv, env);
saveerrno = errno;
@ -1855,7 +1860,7 @@ logdelivery(m, mci, stat, ctladdr, e)
(void) strcat(bp, "]");
# endif
}
else
else if (strcmp(stat, "queued") != 0)
{
char *p = macvalue('h', e);
@ -1961,7 +1966,7 @@ logdelivery(m, mci, stat, ctladdr, e)
(void) strcat(buf, "]");
# endif
}
else
else if (strcmp(stat, "queued") != 0)
{
char *p = macvalue('h', e);

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)envelope.c 8.33 (Berkeley) 2/10/94";
static char sccsid[] = "@(#)envelope.c 8.34 (Berkeley) 4/14/94";
#endif /* not lint */
#include "sendmail.h"
@ -210,7 +210,8 @@ dropenvelope(e)
** Send back return receipts as requested.
*/
if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags))
if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)
&& !bitset(PRIV_NORECEIPTS, PrivacyFlags))
{
auto ADDRESS *rlist = NULL;

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)err.c 8.26 (Berkeley) 3/11/94";
static char sccsid[] = "@(#)err.c 8.27 (Berkeley) 4/18/94";
#endif /* not lint */
# include "sendmail.h"
@ -331,10 +331,10 @@ putoutmsg(msg, holdmsg)
#ifdef LOG
if (LogLevel > 0)
syslog(LOG_CRIT,
"%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %m",
"%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
CurHostName == NULL ? "NO-HOST" : CurHostName,
msg);
msg, errstring(errno));
#endif
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)headers.c 8.30 (Berkeley) 2/25/94";
static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94";
#endif /* not lint */
# include <errno.h>
@ -530,6 +530,7 @@ logsender(e, msgid)
register ENVELOPE *e;
char *msgid;
{
# ifdef LOG
char *name;
register char *sbp;
register char *p;
@ -604,6 +605,7 @@ logsender(e, msgid)
}
syslog(LOG_INFO, "%s relay=%s", sbuf, name);
# endif
# endif
}
/*
** PRIENCODE -- encode external priority names into internal values.
@ -954,6 +956,15 @@ putheader(mci, e)
continue;
}
/* suppress return receipts if requested */
if (bitset(H_RECEIPTTO, h->h_flags) &&
bitset(EF_NORECEIPT, e->e_flags))
{
if (tTd(34, 11))
printf(" (skipped (receipt))\n");
continue;
}
/* macro expand value if generated internally */
p = h->h_value;
if (bitset(H_DEFAULT, h->h_flags))

View File

@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 8.52 (Berkeley) 3/11/94";
static char sccsid[] = "@(#)main.c 8.55 (Berkeley) 4/15/94";
#endif /* not lint */
#define _DEFINE
@ -154,7 +154,7 @@ main(argc, argv, envp)
extern char *getcfname();
extern char *optarg;
extern char **environ;
extern void dumpstate();
extern void sigusr1();
/*
** Check to see if we reentered.
@ -174,7 +174,7 @@ main(argc, argv, envp)
/* arrange to dump state on signal */
#ifdef SIGUSR1
setsignal(SIGUSR1, dumpstate);
setsignal(SIGUSR1, sigusr1);
#endif
/* in 4.4BSD, the table can be huge; impose a reasonable limit */
@ -187,7 +187,7 @@ main(argc, argv, envp)
** But also be sure that 0, 1, & 2 are open.
*/
i = open("/dev/null", O_RDWR);
i = open("/dev/null", O_RDWR, 0);
if (fstat(STDIN_FILENO, &stb) < 0 && errno != EOPNOTSUPP)
(void) dup2(i, STDIN_FILENO);
if (fstat(STDOUT_FILENO, &stb) < 0 && errno != EOPNOTSUPP)
@ -205,10 +205,12 @@ main(argc, argv, envp)
}
errno = 0;
#ifdef LOG_MAIL
#ifdef LOG
# ifdef LOG_MAIL
openlog("sendmail", LOG_PID, LOG_MAIL);
#else
# else
openlog("sendmail", LOG_PID);
# endif
#endif
/* set up the blank envelope */
@ -985,7 +987,9 @@ main(argc, argv, envp)
if (tTd(0, 1))
strcat(dtype, "+debugging");
#ifdef LOG
syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1);
#endif
#ifdef XLA
xla_create_file();
#endif
@ -1424,22 +1428,28 @@ auth_warning(e, msg, va_alist)
}
}
/*
** DUMPSTATE -- dump state on user signal
** DUMPSTATE -- dump state
**
** For debugging.
*/
void
dumpstate()
dumpstate(when)
char *when;
{
#ifdef LOG
register char *j = macvalue('j', CurEnv);
register STAB *s;
syslog(LOG_DEBUG, "--- dumping state on user signal: $j = %s ---", j);
s = stab(j, ST_CLASS, ST_FIND);
if (s == NULL || !bitnset('w', s->s_class))
syslog(LOG_DEBUG, "*** $j not in $=w ***");
syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
when,
j == NULL ? "<NULL>" : j);
if (j != NULL)
{
s = stab(j, ST_CLASS, ST_FIND);
if (s == NULL || !bitnset('w', s->s_class))
syslog(LOG_DEBUG, "*** $j not in $=w ***");
}
syslog(LOG_DEBUG, "--- open file descriptors: ---");
printopenfds(TRUE);
syslog(LOG_DEBUG, "--- connection cache: ---");
@ -1460,3 +1470,10 @@ dumpstate()
syslog(LOG_DEBUG, "--- end of state dump ---");
#endif
}
void
sigusr1()
{
dumpstate("user signal");
}

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)map.c 8.22 (Berkeley) 2/18/94";
static char sccsid[] = "@(#)map.c 8.25 (Berkeley) 4/17/94";
#endif /* not lint */
#include "sendmail.h"
@ -575,6 +575,9 @@ void
ndbm_map_close(map)
register MAP *map;
{
if (tTd(38, 9))
printf("ndbm_map_close(%s, %x)\n", map->map_file, map->map_mflags);
if (bitset(MF_WRITABLE, map->map_mflags))
{
#ifdef NIS
@ -640,7 +643,7 @@ bt_map_open(map, mode)
omode |= O_CREAT|O_TRUNC;
#if defined(O_EXLOCK) && HASFLOCK
omode |= O_EXLOCK;
# if !defined(OLD_NEWDB)
# if !OLD_NEWDB
}
else
{
@ -664,7 +667,7 @@ bt_map_open(map, mode)
syserr("Cannot open BTREE database %s", map->map_file);
return FALSE;
}
#if !defined(OLD_NEWDB) && HASFLOCK
#if !OLD_NEWDB && HASFLOCK
fd = db->fd(db);
# if !defined(O_EXLOCK)
if (mode == O_RDWR && fd >= 0)
@ -682,7 +685,7 @@ bt_map_open(map, mode)
/* try to make sure that at least the database header is on disk */
if (mode == O_RDWR)
#ifdef OLD_NEWDB
#if OLD_NEWDB
(void) db->sync(db);
#else
(void) db->sync(db, 0);
@ -724,7 +727,7 @@ hash_map_open(map, mode)
omode |= O_CREAT|O_TRUNC;
#if defined(O_EXLOCK) && HASFLOCK
omode |= O_EXLOCK;
# if !defined(OLD_NEWDB)
# if !OLD_NEWDB
}
else
{
@ -748,7 +751,7 @@ hash_map_open(map, mode)
syserr("Cannot open HASH database %s", map->map_file);
return FALSE;
}
#if !defined(OLD_NEWDB) && HASFLOCK
#if !OLD_NEWDB && HASFLOCK
fd = db->fd(db);
# if !defined(O_EXLOCK)
if (mode == O_RDWR && fd >= 0)
@ -766,7 +769,7 @@ hash_map_open(map, mode)
/* try to make sure that at least the database header is on disk */
if (mode == O_RDWR)
#ifdef OLD_NEWDB
#if OLD_NEWDB
(void) db->sync(db);
#else
(void) db->sync(db, 0);
@ -811,7 +814,7 @@ db_map_lookup(map, name, av, statp)
bcopy(name, keybuf, key.size + 1);
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
makelower(keybuf);
#ifndef OLD_NEWDB
#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);
@ -831,7 +834,7 @@ db_map_lookup(map, name, av, statp)
map->map_mflags &= ~MF_TRY0NULL;
}
saveerrno = errno;
#ifndef OLD_NEWDB
#if !OLD_NEWDB
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
(void) lockfile(fd, map->map_file, ".db", LOCK_UN);
#endif
@ -973,8 +976,9 @@ nis_map_open(map, mode)
yperr = yp_get_default_domain(&map->map_domain);
if (yperr != 0)
{
syserr("NIS map %s specified, but NIS not running\n",
map->map_file);
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("NIS map %s specified, but NIS not running\n",
map->map_file);
return FALSE;
}
}

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mci.c 8.12 (Berkeley) 2/9/94";
static char sccsid[] = "@(#)mci.c 8.13 (Berkeley) 4/12/94";
#endif /* not lint */
#include "sendmail.h"
@ -367,9 +367,11 @@ mci_dump(mci, logit)
mci->mci_host == NULL ? "NULL" : mci->mci_host,
ctime(&mci->mci_lastuse));
printit:
#ifdef LOG
if (logit)
syslog(LOG_DEBUG, "%s", buf);
else
#endif
printf("%s\n", buf);
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)parseaddr.c 8.30 (Berkeley) 2/9/94";
static char sccsid[] = "@(#)parseaddr.c 8.31 (Berkeley) 4/15/94";
#endif /* not lint */
# include "sendmail.h"
@ -132,7 +132,7 @@ parseaddr(addr, a, flags, delim, delimptr, e)
if (savec != '\0')
**delimptr = '\0';
addr = newstr(addr);
e->e_to = addr = newstr(addr);
if (savec != '\0')
**delimptr = savec;
}

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef QUEUE
static char sccsid[] = "@(#)queue.c 8.40 (Berkeley) 3/6/94 (with queueing)";
static char sccsid[] = "@(#)queue.c 8.41 (Berkeley) 4/18/94 (with queueing)";
#else
static char sccsid[] = "@(#)queue.c 8.40 (Berkeley) 3/6/94 (without queueing)";
static char sccsid[] = "@(#)queue.c 8.41 (Berkeley) 4/18/94 (without queueing)";
#endif
#endif /* not lint */
@ -179,7 +179,7 @@ queueup(e, queueall, announce)
e->e_df = queuename(e, 'd');
e->e_df = newstr(e->e_df);
fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode);
fd = open(e->e_df, O_WRONLY|O_CREAT|O_TRUNC, FileMode);
if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL)
syserr("!queueup: cannot create data temp file %s, uid=%d",
e->e_df, geteuid());

View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)sendmail.h 8.41 (Berkeley) 2/6/94
* @(#)sendmail.h 8.43 (Berkeley) 4/14/94
*/
/*
@ -41,7 +41,7 @@
# ifdef _DEFINE
# define EXTERN
# ifndef lint
static char SmailSccsId[] = "@(#)sendmail.h 8.41 2/6/94";
static char SmailSccsId[] = "@(#)sendmail.h 8.43 4/14/94";
# endif
# else /* _DEFINE */
# define EXTERN extern
@ -377,6 +377,7 @@ ENVELOPE
#define EF_PM_NOTIFY 0x0002000 /* send return mail to postmaster */
#define EF_METOO 0x0004000 /* send to me too */
#define EF_LOGSENDER 0x0008000 /* need to log the sender */
#define EF_NORECEIPT 0x0010000 /* suppress all return-receipts */
EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
/*
@ -704,6 +705,7 @@ EXTERN char OpMode; /* operation mode, see below */
#define PRIV_NOEXPN 00010 /* disallow EXPN command entirely */
#define PRIV_NOVRFY 00020 /* disallow VRFY command entirely */
#define PRIV_AUTHWARNINGS 00040 /* flag possible authorization probs */
#define PRIV_NORECEIPTS 00100 /* disallow return receipts */
#define PRIV_RESTRICTMAILQ 01000 /* restrict mailq command */
#define PRIV_RESTRICTQRUN 02000 /* restrict queue run */
#define PRIV_GOAWAY 00777 /* don't give no info, anyway, anyhow */

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
static char sccsid[] = "@(#)srvrsmtp.c 8.32 (Berkeley) 3/8/94 (with SMTP)";
static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (with SMTP)";
#else
static char sccsid[] = "@(#)srvrsmtp.c 8.32 (Berkeley) 3/8/94 (without SMTP)";
static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (without SMTP)";
#endif
#endif /* not lint */
@ -135,7 +135,7 @@ smtp(e)
bool vrfy; /* set if this is a vrfy command */
char *protocol; /* sending protocol */
char *sendinghost; /* sending hostname */
long msize; /* approximate maximum message size */
unsigned long msize; /* approximate maximum message size */
char *peerhostname; /* name of SMTP peer or "localhost" */
auto char *delimptr;
char *id;
@ -165,11 +165,23 @@ smtp(e)
expand("\201e", inp, &inp[sizeof inp], e);
if (BrokenSmtpPeers)
{
p = strchr(inp, '\n');
if (p != NULL)
*p = '\0';
message("220 %s", inp);
}
else
{
message("220-%s", inp);
char *q = inp;
while (q != NULL)
{
p = strchr(q, '\n');
if (p != NULL)
*p++ = '\0';
message("220-%s", q);
q = p;
}
message("220 ESMTP spoken here");
}
protocol = NULL;
@ -285,7 +297,7 @@ smtp(e)
/* print extended message and brag */
message("250-%s Hello %s, pleased to meet you",
MyHostName, p);
MyHostName, CurSmtpClient);
if (!bitset(PRIV_NOEXPN, PrivacyFlags))
message("250-EXPN");
if (MaxMessageSize > 0)
@ -389,7 +401,7 @@ smtp(e)
/* now parse ESMTP arguments */
msize = 0;
for (; p != NULL && *p != '\0'; p++)
while (p != NULL && *p != '\0')
{
char *kp;
char *vp = NULL;
@ -420,7 +432,7 @@ smtp(e)
*p++ = '\0';
if (tTd(19, 1))
printf("MAIL: got arg %s=%s\n", kp,
printf("MAIL: got arg %s=\"%s\"\n", kp,
vp == NULL ? "<null>" : vp);
if (strcasecmp(kp, "size") == 0)
@ -430,7 +442,11 @@ smtp(e)
usrerr("501 SIZE requires a value");
/* NOTREACHED */
}
msize = atol(vp);
# ifdef __STDC__
msize = strtoul(vp, (char **) NULL, 10);
# else
msize = strtol(vp, (char **) NULL, 10);
# endif
}
else if (strcasecmp(kp, "body") == 0)
{

View File

@ -36,9 +36,9 @@
#ifndef lint
#ifdef USERDB
static char sccsid [] = "@(#)udb.c 8.6 (Berkeley) 3/11/94 (with USERDB)";
static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (with USERDB)";
#else
static char sccsid [] = "@(#)udb.c 8.6 (Berkeley) 3/11/94 (without USERDB)";
static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (without USERDB)";
#endif
#endif
@ -48,6 +48,10 @@ static char sccsid [] = "@(#)udb.c 8.6 (Berkeley) 3/11/94 (without USERDB)";
#include <netdb.h>
#include <db.h>
#ifdef HESIOD
#include <hesiod.h>
#endif /* HESIOD */
/*
** UDB.C -- interface between sendmail and Berkeley User Data Base.
**
@ -94,6 +98,7 @@ struct udbent
#define UDB_REMOTE 2 /* look up in remote database */
#define UDB_DBFETCH 3 /* look up in local database */
#define UDB_FORWARD 4 /* forward to remote host */
#define UDB_HESIOD 5 /* look up via hesiod */
#define MAXUDBENT 10 /* maximum number of UDB entries */
@ -164,6 +169,10 @@ udbexpand(a, sendq, e)
if (UdbSpec == NULL || UdbSpec[0] == '\0')
return EX_OK;
/* short circuit name begins with '\\' since it can't possibly match */
if (a->q_user[0] == '\\')
return EX_OK;
/* if name is too long, assume it won't match */
if (strlen(a->q_user) > sizeof keybuf - 12)
return EX_OK;
@ -196,7 +205,7 @@ udbexpand(a, sendq, e)
key.data = keybuf;
key.size = keylen;
if (tTd(28, 80))
printf("udbexpand: trying %s (%d)\n",
printf("udbexpand: trying %s (%d) via db\n",
keybuf, keylen);
i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_CURSOR);
if (i > 0 || info.size <= 0)
@ -283,8 +292,104 @@ udbexpand(a, sendq, e)
a->q_owner = xalloc(info.size + 1);
bcopy(info.data, a->q_owner, info.size);
a->q_owner[info.size] = '\0';
/* announce delivery; NORECEIPT bit set later */
if (e->e_xfp != NULL)
{
fprintf(e->e_xfp,
"Message delivered to mailing list %s\n",
a->q_paddr);
e->e_flags |= EF_SENDRECEIPT;
}
break;
#ifdef HESIOD
case UDB_HESIOD:
key.data = keybuf;
key.size = keylen;
if (tTd(28, 80))
printf("udbexpand: trying %s (%d) via hesiod\n",
keybuf, keylen);
/* look up the key via hesiod */
i = hes_udb_get(&key, &info);
if (i > 0 || info.size <= 0)
{
if (tTd(28, 2))
printf("udbexpand: no match on %s (%d)\n",
keybuf, keylen);
continue;
}
if (tTd(28, 80))
printf("udbexpand: match %.*s: %.*s\n",
key.size, key.data, info.size, info.data);
a->q_flags &= ~QSELFREF;
if (bitset(EF_VRFYONLY, e->e_flags))
{
a->q_flags |= QVERIFIED;
e->e_nrcpts++;
free(info.data);
return EX_OK;
}
breakout = TRUE;
if (info.size < sizeof buf)
user = buf;
else
user = xalloc(info.size + 1);
bcopy(info.data, user, info.size);
user[info.size] = '\0';
free(info.data);
message("hesioded to %s", user);
#ifdef LOG
if (LogLevel >= 10)
syslog(LOG_INFO, "%s: hesiod %s => %s",
e->e_id, e->e_to, user);
#endif
AliasLevel++;
naddrs = sendtolist(user, a, sendq, e);
AliasLevel--;
if (user != buf)
free(user);
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
{
if (tTd(28, 5))
{
printf("udbexpand: QDONTSEND ");
printaddr(a, FALSE);
}
a->q_flags |= QDONTSEND;
}
if (i < 0)
{
syserr("udbexpand: hesiod-get %.*s stat %d",
key.size, key.data, i);
return EX_TEMPFAIL;
}
/*
** If this address has a -request address, reflect
** it into the envelope.
*/
(void) strcpy(keybuf, a->q_user);
(void) strcat(keybuf, ":mailsender");
keylen = strlen(keybuf);
key.data = keybuf;
key.size = keylen;
i = hes_udb_get(&key, &info);
if (i != 0 || info.size <= 0)
break;
a->q_owner = xalloc(info.size + 1);
bcopy(info.data, a->q_owner, info.size);
a->q_owner[info.size] = '\0';
free(info.data);
break;
#endif /* HESIOD */
case UDB_REMOTE:
/* not yet implemented */
continue;
@ -378,6 +483,10 @@ udbmatch(user, field)
if (UdbSpec == NULL || UdbSpec[0] == '\0')
return NULL;
/* short circuit name begins with '\\' since it can't possibly match */
if (user[0] == '\\')
return NULL;
/* long names can never match and are a pain to deal with */
if ((strlen(user) + strlen(field)) > sizeof keybuf - 4)
return NULL;
@ -407,7 +516,7 @@ udbmatch(user, field)
if (i != 0 || info.size <= 0)
{
if (tTd(28, 2))
printf("udbmatch: no match on %s (%d)\n",
printf("udbmatch: no match on %s (%d) via db\n",
keybuf, keylen);
continue;
}
@ -418,6 +527,30 @@ udbmatch(user, field)
if (tTd(28, 1))
printf("udbmatch ==> %s\n", p);
return p;
break;
#ifdef HESIOD
case UDB_HESIOD:
key.data = keybuf;
key.size = keylen;
i = hes_udb_get(&key, &info);
if (i != 0 || info.size <= 0)
{
if (tTd(28, 2))
printf("udbmatch: no match on %s (%d) via hesiod\n",
keybuf, keylen);
continue;
}
p = xalloc(info.size + 1);
bcopy(info.data, p, info.size);
p[info.size] = '\0';
free(info.data);
if (tTd(28, 1))
printf("udbmatch ==> %s\n", p);
return p;
break;
#endif /* HESIOD */
}
}
@ -479,6 +612,54 @@ udbmatch(user, field)
if (tTd(28, 1))
printf("udbmatch ==> %s\n", p);
return p;
break;
#ifdef HESIOD
case UDB_HESIOD:
/* get the default case for this database */
if (up->udb_default == NULL)
{
key.data = ":default:mailname";
key.size = strlen(key.data);
i = hes_udb_get(&key, &info);
if (i != 0 || info.size <= 0)
{
/* no default case */
up->udb_default = "";
continue;
}
/* save the default case */
up->udb_default = xalloc(info.size + 1);
bcopy(info.data, up->udb_default, info.size);
up->udb_default[info.size] = '\0';
free(info.data);
}
else if (up->udb_default[0] == '\0')
continue;
/* we have a default case -- verify user:maildrop */
key.data = keybuf;
key.size = keylen;
i = hes_udb_get(&key, &info);
if (i != 0 || info.size <= 0)
{
/* nope -- no aliasing for this user */
continue;
}
free(info.data);
/* they exist -- build the actual address */
p = xalloc(strlen(user) + strlen(up->udb_default) + 2);
(void) strcpy(p, user);
(void) strcat(p, "@");
(void) strcat(p, up->udb_default);
if (tTd(28, 1))
printf("udbmatch ==> %s\n", p);
return p;
break;
#endif /* HESIOD */
}
}
@ -622,6 +803,16 @@ _udbx_init()
up++;
break;
case 'h': /* use hesiod */
case 'H':
#ifdef HESIOD
if (strcasecmp(spec, "hesiod") != 0)
break;
up->udb_type = UDB_HESIOD;
up++;
#endif /* HESIOD */
break;
case '/': /* look up remote name */
up->udb_dbname = spec;
errno = 0;
@ -669,6 +860,10 @@ _udbx_init()
up->udb_fwdhost);
break;
case UDB_HESIOD:
printf("HESIOD\n");
break;
default:
printf("UNKNOWN\n");
break;
@ -725,6 +920,57 @@ _udb_parsespec(udbspec, opt, maxopts)
return optnum;
}
#ifdef HESIOD
int
hes_udb_get(key, info)
DBT *key;
DBT *info;
{
char *name, *type;
char *p, **hp;
name = key->data;
type = strchr(name, ':');
if (type == NULL)
return 1;
*type++ = '\0';
if (tTd(28, 1))
printf("hes_udb_get(%s, %s)\n", name, type);
/* make the hesiod query */
hp = hes_resolve(name, type);
if (hp == NULL)
{
/* network problem or timeout */
if (hes_error() == HES_ER_NET)
return -1;
return 1;
}
else
{
/*
** If there are multiple matches, just return the
** first one and free the others.
**
** XXX These should really be returned; for example,
** XXX it is legal for :maildrop to be multi-valued.
*/
for (p = hp[1]; p; p++)
free(p);
info->data = hp[0];
info->size = (size_t) strlen(info->data);
}
return 0;
}
#endif /* HESIOD */
#else /* not USERDB */
int

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)util.c 8.34 (Berkeley) 3/11/94";
static char sccsid[] = "@(#)util.c 8.39 (Berkeley) 4/14/94";
#endif /* not lint */
# include "sendmail.h"
@ -100,6 +100,10 @@ xalloc(sz)
{
register char *p;
/* some systems can't handle size zero mallocs */
if (sz <= 0)
sz = 1;
p = malloc((unsigned) sz);
if (p == NULL)
{
@ -836,6 +840,9 @@ xfclose(fp, a, b)
static jmp_buf CtxReadTimeout;
static int readtimeout();
static EVENT *GlobalTimeout = NULL;
static bool EnableTimeout = FALSE;
static int ReadProgress;
char *
sfgets(buf, siz, fp, timeout, during)
@ -873,7 +880,10 @@ sfgets(buf, siz, fp, timeout, during)
#endif
return (NULL);
}
ev = setevent(timeout, readtimeout, 0);
if (GlobalTimeout == NULL)
ev = setevent(timeout, readtimeout, 0);
else
EnableTimeout = TRUE;
}
/* try to read */
@ -888,7 +898,10 @@ sfgets(buf, siz, fp, timeout, during)
}
/* clear the event if it has not sprung */
clrevent(ev);
if (GlobalTimeout == NULL)
clrevent(ev);
else
EnableTimeout = FALSE;
/* clean up the books and exit */
LineNumber++;
@ -907,10 +920,44 @@ sfgets(buf, siz, fp, timeout, during)
return (buf);
}
static
readtimeout()
void
sfgetset(timeout)
time_t timeout;
{
longjmp(CtxReadTimeout, 1);
/* cancel pending timer */
if (GlobalTimeout != NULL)
{
clrevent(GlobalTimeout);
GlobalTimeout = NULL;
}
/* schedule fresh one if so requested */
if (timeout != 0)
{
ReadProgress = LineNumber;
GlobalTimeout = setevent(timeout, readtimeout, timeout);
}
}
static
readtimeout(timeout)
time_t timeout;
{
/* terminate if ordinary timeout */
if (GlobalTimeout == NULL)
longjmp(CtxReadTimeout, 1);
/* terminate if no progress was made -- reset state */
if (EnableTimeout && (LineNumber <= ReadProgress))
{
EnableTimeout = FALSE;
GlobalTimeout = NULL;
longjmp(CtxReadTimeout, 2);
}
/* schedule a new timeout */
GlobalTimeout = NULL;
sfgetset(timeout);
}
/*
** FGETFOLDED -- like fgets, but know about folded lines.
@ -1259,6 +1306,7 @@ dumpfd(fd, printclosed, logit)
{
register struct hostent *hp;
register char *p;
char *fmtstr;
struct sockaddr_in sin;
auto int slen;
struct stat st;
@ -1350,16 +1398,22 @@ dumpfd(fd, printclosed, logit)
default:
defprint:
sprintf(p, "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%qd",
if (sizeof st.st_size > sizeof (long))
fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%qd";
else
fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld";
sprintf(p, fmtstr,
major(st.st_dev), minor(st.st_dev), st.st_ino,
st.st_nlink, st.st_uid, st.st_gid, st.st_size);
break;
}
printit:
#ifdef LOG
if (logit)
syslog(LOG_DEBUG, "%s", buf);
else
#endif
printf("%s\n", buf);
}
/*

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)version.c 8.6.8.1 (Berkeley) 3/18/94";
static char sccsid[] = "@(#)version.c 8.6.9.1 (Berkeley) 4/18/94";
#endif /* not lint */
char Version[] = "8.6.8";
char Version[] = "8.6.9";

View File

@ -39,6 +39,7 @@ NeXT 2.1 OK 93.07.28 eric
Linux 0.99p10 OK 93.08.08 Karl London
Linux 0.99p13 OK 93.09.27 Christian Kuhtz
Linux 0.99p14 OK 93.11.30 Christian Kuhtz <chk@data-hh.Hanse.DE>
Linux 1.0 OK 94.03.19 Shayne Smith <snsmith@rastus.brisnet.org.au>
BSD/386 1.0 OK 93.11.13 Tony Sanders