summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src
diff options
context:
space:
mode:
authorcjs <cjs@NetBSD.org>1997-07-13 19:42:13 +0000
committercjs <cjs@NetBSD.org>1997-07-13 19:42:13 +0000
commitfce01e04e20bca396dc45dc38e3658469ea93b7a (patch)
treea6c5aeae79876b5d2801e4e1d72d89341a58077b /usr.sbin/sendmail/src
parent28db57eb43fee36a8c41b7116507ddf46495f6f6 (diff)
Resolve conflicts in 8.8.6 import.
Diffstat (limited to 'usr.sbin/sendmail/src')
-rw-r--r--usr.sbin/sendmail/src/clock.c47
-rw-r--r--usr.sbin/sendmail/src/collect.c39
-rw-r--r--usr.sbin/sendmail/src/conf.c843
-rw-r--r--usr.sbin/sendmail/src/conf.h141
-rw-r--r--usr.sbin/sendmail/src/convtime.c4
-rw-r--r--usr.sbin/sendmail/src/daemon.c251
-rw-r--r--usr.sbin/sendmail/src/deliver.c186
-rw-r--r--usr.sbin/sendmail/src/domain.c8
-rw-r--r--usr.sbin/sendmail/src/envelope.c39
-rw-r--r--usr.sbin/sendmail/src/err.c91
-rw-r--r--usr.sbin/sendmail/src/headers.c155
-rw-r--r--usr.sbin/sendmail/src/macro.c4
-rw-r--r--usr.sbin/sendmail/src/main.c193
-rw-r--r--usr.sbin/sendmail/src/makesendmail14
-rw-r--r--usr.sbin/sendmail/src/map.c361
-rw-r--r--usr.sbin/sendmail/src/mci.c54
-rw-r--r--usr.sbin/sendmail/src/mime.c36
-rw-r--r--usr.sbin/sendmail/src/newaliases.15
18 files changed, 1676 insertions, 795 deletions
diff --git a/usr.sbin/sendmail/src/clock.c b/usr.sbin/sendmail/src/clock.c
index 5639f440517..6940b297894 100644
--- a/usr.sbin/sendmail/src/clock.c
+++ b/usr.sbin/sendmail/src/clock.c
@@ -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;
diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c
index 660521cf8c7..219a47f7b8b 100644
--- a/usr.sbin/sendmail/src/collect.c
+++ b/usr.sbin/sendmail/src/collect.c
@@ -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 @@ readerr:
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 @@ readerr:
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 @@ readerr:
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 @@ readerr:
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 */
diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c
index 4c050dd5b7a..fa22ae2eefe 100644
--- a/usr.sbin/sendmail/src/conf.c
+++ b/usr.sbin/sendmail/src/conf.c
@@ -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[] = "@(#)conf.c 8.333 (Berkeley) 1/21/97";
+static char sccsid[] = "@(#)conf.c 8.362 (Berkeley) 6/14/97";
#endif /* not lint */
# include "sendmail.h"
@@ -140,6 +140,9 @@ struct prival PrivacyValues[] =
{ "novrfy", PRIV_NOVRFY },
{ "restrictmailq", PRIV_RESTRICTMAILQ },
{ "restrictqrun", PRIV_RESTRICTQRUN },
+#if _FFR_PRIVACY_NOETRN
+ { "noetrn", PRIV_NOETRN },
+#endif
{ "authwarnings", PRIV_AUTHWARNINGS },
{ "noreceipts", PRIV_NORECEIPTS },
{ "goaway", PRIV_GOAWAY },
@@ -187,6 +190,7 @@ setdefaults(e)
extern void setdefuser();
extern void setupmaps();
extern void setupmailers();
+ extern void setupheaders();
SpaceSub = ' '; /* option B */
QueueLA = 8; /* option x */
@@ -233,6 +237,7 @@ setdefaults(e)
setdefuser();
setupmaps();
setupmailers();
+ setupheaders();
}
@@ -252,48 +257,6 @@ setdefuser()
defpwent == NULL ? "nobody" : defpwent->pw_name);
}
/*
-** HOST_MAP_INIT -- initialize host class structures
-*/
-
-bool host_map_init __P((MAP *map, char *args));
-
-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;
-}
- /*
** SETUPMAILERS -- initialize default mailers
*/
@@ -368,8 +331,8 @@ setupmaps()
#endif
#ifdef LDAPMAP
MAPDEF("ldapx", NULL, 0,
- ldap_map_parseargs, ldap_map_open, ldap_map_close,
- ldap_map_lookup, null_map_store);
+ ldap_map_parseargs, ldap_map_open, ldap_map_close,
+ ldap_map_lookup, null_map_store);
#endif
#ifdef HESIOD
@@ -1062,7 +1025,11 @@ setsignal(sig, handler)
sigfunc_t handler;
{
#if defined(SYS5SIGNALS) || defined(BSD4_3)
+# ifdef BSD4_3
return signal(sig, handler);
+# else
+ return sigset(sig, handler);
+# endif
#else
struct sigaction n, o;
@@ -1525,8 +1492,8 @@ getla()
dg_sys_info((long *)&load_info,
DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
- if (tTd(3, 1))
- printf("getla: %d\n", (int) (load_info.one_minute + 0.5));
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (load_info.one_minute + 0.5));
return((int) (load_info.one_minute + 0.5));
}
@@ -1557,8 +1524,8 @@ getla()
(size_t) 1, 0) == -1)
return 0;
- if (tTd(3, 1))
- printf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
return (int) (pstd.psd_avg_1_min + 0.5);
}
@@ -1699,8 +1666,7 @@ int getla(void)
static int kmem = -1;
static enum { getla_none, getla_32, getla_64 } kernel_type =
getla_none;
- uint32_t avenrun32[3];
- uint64_t avenrun64[3];
+ uint32_t avenrun[3];
if (kernel_type == getla_none)
{
@@ -1783,57 +1749,47 @@ int getla(void)
switch (kernel_type)
{
+ case getla_none:
+ return -1;
+
case getla_32:
if (lseek(kmem, (off_t) Nl32[X_AVENRUN].n_value, SEEK_SET) == -1 ||
- read(kmem, (char *) avenrun32, sizeof(avenrun32)) < sizeof(avenrun32))
+ read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
{
if (tTd(3, 1))
printf("getla: lseek or read: %s\n",
errstring(errno));
return -1;
}
- if (tTd(3, 5))
- {
- printf("getla: avenrun{32} = %ld",
- (long int) avenrun32[0]);
- if (tTd(3, 15))
- printf(", %ld, %ld",
- (long int)avenrun32[1],
- (long int)avenrun32[2]);
- printf("\n");
- }
- if (tTd(3, 1))
- printf("getla: %d\n",
- (int) (avenrun32[0] + FSCALE/2) >> FSHIFT);
- return ((int) (avenrun32[0] + FSCALE/2) >> FSHIFT);
+ break;
case getla_64:
/* Using of lseek64 is perhaps overkill ... */
if (lseek64(kmem, (off64_t) Nl64[X_AVENRUN].n_value, SEEK_SET) == -1 ||
- read(kmem, (char *) avenrun64, sizeof(avenrun64)) <
- sizeof(avenrun64))
+ read(kmem, (char *) avenrun, sizeof(avenrun)) <
+ sizeof(avenrun))
{
if (tTd(3, 1))
printf("getla: lseek64 or read: %s\n",
errstring(errno));
return -1;
}
- if (tTd(3, 5))
- {
- printf("getla: avenrun{64} = %lld",
- (long long int) avenrun64[0]);
- if (tTd(3, 15))
- printf(", %lld, %lld",
- (long long int) avenrun64[1],
- (long long int) avenrun64[2]);
- printf("\n");
- }
- if (tTd(3, 1))
- printf("getla: %d\n",
- (int) (avenrun64[0] + FSCALE/2) >> FSHIFT);
- return ((int) (avenrun64[0] + FSCALE/2) >> FSHIFT);
+ break;
}
- return -1;
+ if (tTd(3, 5))
+ {
+ printf("getla: avenrun = %ld",
+ (long int) avenrun[0]);
+ if (tTd(3, 15))
+ printf(", %ld, %ld",
+ (long int)avenrun[1],
+ (long int)avenrun[2]);
+ printf("\n");
+ }
+ if (tTd(3, 1))
+ printf("getla: %d\n",
+ (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+ return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
}
#endif
@@ -1913,7 +1869,9 @@ getla()
afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
if (afd < 0)
{
- syslog(LOG_ERR, "can't open %s: %m", _PATH_AVENRUN);
+ sm_syslog(LOG_ERR, NOQID,
+ "can't open %s: %m",
+ _PATH_AVENRUN);
return -1;
}
}
@@ -1998,7 +1956,7 @@ getla()
/* Non Apollo stuff removed by Don Lewis 11/15/93 */
#ifndef lint
-static char rcsid[] = "@(#)$Id: conf.c,v 1.18 1997/01/24 04:01:55 cjs Exp $";
+static char rcsid[] = "@(#)Id: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp ";
#endif /* !lint */
#ifdef apollo
@@ -2036,16 +1994,19 @@ int getloadavg( call_data )
** none.
*/
+extern int get_num_procs_online __P((void));
+
bool
shouldqueue(pri, ctime)
long pri;
time_t ctime;
{
bool rval;
+ int queuela = QueueLA * get_num_procs_online();
if (tTd(3, 30))
printf("shouldqueue: CurrentLA=%d, pri=%ld: ", CurrentLA, pri);
- if (CurrentLA < QueueLA)
+ if (CurrentLA < queuela)
{
if (tTd(3, 30))
printf("FALSE (CurrentLA < QueueLA)\n");
@@ -2059,7 +2020,7 @@ shouldqueue(pri, ctime)
return (TRUE);
}
#endif
- rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
+ rval = pri > (QueueFactor / (CurrentLA - queuela + 1));
if (tTd(3, 30))
printf("%s (by calculation)\n", rval ? "TRUE" : "FALSE");
return rval;
@@ -2083,6 +2044,7 @@ bool
refuseconnections(port)
int port;
{
+ int refusela = RefuseLA * get_num_procs_online();
time_t now;
static time_t lastconn = (time_t) 0;
static int conncnt = 0;
@@ -2105,24 +2067,22 @@ refuseconnections(port)
/* sleep to flatten out connection load */
setproctitle("deferring connections on port %d: %d per second",
port, ConnRateThrottle);
-#ifdef LOG
if (LogLevel >= 14)
- syslog(LOG_INFO, "deferring connections on port %d: %d per second",
+ sm_syslog(LOG_INFO, NOQID,
+ "deferring connections on port %d: %d per second",
port, ConnRateThrottle);
-#endif
sleep(1);
}
CurrentLA = getla();
- if (CurrentLA >= RefuseLA)
+ if (CurrentLA >= refusela)
{
setproctitle("rejecting connections on port %d: load average: %d",
port, CurrentLA);
-#ifdef LOG
if (LogLevel >= 14)
- syslog(LOG_INFO, "rejecting connections on port %d: load average: %d",
+ sm_syslog(LOG_INFO, NOQID,
+ "rejecting connections on port %d: load average: %d",
port, CurrentLA);
-#endif
return TRUE;
}
@@ -2130,11 +2090,10 @@ refuseconnections(port)
{
setproctitle("rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
-#ifdef LOG
if (LogLevel >= 14)
- syslog(LOG_INFO, "rejecting connections on port %d: min free: %d",
+ sm_syslog(LOG_INFO, NOQID,
+ "rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
-#endif
return TRUE;
}
@@ -2147,11 +2106,10 @@ refuseconnections(port)
{
setproctitle("rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
-#ifdef LOG
if (LogLevel >= 14)
- syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d",
+ sm_syslog(LOG_INFO, NOQID,
+ "rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
-#endif
return TRUE;
}
}
@@ -2180,6 +2138,7 @@ refuseconnections(port)
#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */
#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */
#define SPT_SCO 6 /* write kernel u. area */
+#define SPT_CHANGEARGV 7 /* write our own strings into argv[] */
#ifndef SPT_TYPE
# define SPT_TYPE SPT_REUSEARGV
@@ -2204,7 +2163,7 @@ typedef unsigned int *pt_entry_t;
# endif
# endif
-# if SPT_TYPE == SPT_PSSTRINGS
+# if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
# define SETPROC_STATIC static
# else
# define SETPROC_STATIC
@@ -2253,7 +2212,7 @@ initsetproctitle(argc, argv, envp)
extern char **environ;
/*
- ** Move the environment so setproctitle can use the space at
+ ** Move the environment so setproctitle can use the space at
** the top of memory.
*/
@@ -2355,11 +2314,65 @@ setproctitle(fmt, va_alist)
*p++ = SPT_PADCHAR;
Argv[1] = NULL;
# endif
+# if SPT_TYPE == SPT_CHANGEARGV
+ Argv[0] = buf;
+ Argv[1] = 0;
+# endif
# endif /* SPT_TYPE != SPT_NONE */
}
#endif /* SPT_TYPE != SPT_BUILTIN */
/*
+** 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;
+#if defined(ISC_UNIX) || defined(_SCO_unix_)
+ int savesig;
+#endif
+
+ do
+ {
+ errno = 0;
+#if defined(ISC_UNIX) || defined(_SCO_unix_)
+ savesig = releasesignal(SIGCHLD);
+#endif
+ i = wait(&st);
+#if defined(ISC_UNIX) || defined(_SCO_unix_)
+ if (savesig > 0)
+ blocksignal(SIGCHLD);
+#endif
+ 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
+}
+ /*
** REAPCHILD -- pick up the body of my child, lest it become a zombie
**
** Parameters:
@@ -2387,12 +2400,10 @@ reapchild(sig)
{
if (count++ > 1000)
{
-#ifdef LOG
if (LogLevel > 0)
- syslog(LOG_ALERT,
+ sm_syslog(LOG_ALERT, NOQID,
"reapchild: waitpid loop: pid=%d, status=%x",
pid, status);
-#endif
break;
}
proc_list_drop(pid);
@@ -2406,7 +2417,14 @@ reapchild(sig)
# else /* WNOHANG */
auto int status;
- while ((pid = wait(&status)) > 0)
+ /*
+ ** Catch one zombie -- we will be re-invoked (we hope) if there
+ ** are more. Unreliable signals probably break this, but this
+ ** is the "old system" situation -- waitpid or wait3 are to be
+ ** strongly preferred.
+ */
+
+ if ((pid = wait(&status)) > 0)
proc_list_drop(pid);
# endif /* WNOHANG */
# endif
@@ -2880,12 +2898,10 @@ vsprintf(s, fmt, ap)
** %lx has been added.
*/
-#if !HASSNPRINTF
-
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
+ * A bombproof version of doprnt (sm_dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
@@ -2896,11 +2912,13 @@ vsprintf(s, fmt, ap)
* causing nast effects.
**************************************************************/
-/*static char _id[] = "$Id: conf.c,v 1.18 1997/01/24 04:01:55 cjs Exp $";*/
-static void dopr();
-static char *end;
+/*static char _id[] = "Id: snprintf.c,v 1.2 1995/10/09 11:19:47 roberto Exp ";*/
+static void sm_dopr();
+static char *DoprEnd;
static int SnprfOverflow;
+#if !HASSNPRINTF
+
/* VARARGS3 */
int
# ifdef __STDC__
@@ -2932,19 +2950,22 @@ vsnprintf(str, count, fmt, args)
va_list args;
{
str[0] = 0;
- end = str + count - 1;
+ DoprEnd = str + count - 1;
SnprfOverflow = 0;
- dopr( str, fmt, args );
+ sm_dopr( str, fmt, args );
if (count > 0)
- end[0] = 0;
+ DoprEnd[0] = 0;
if (SnprfOverflow && tTd(57, 2))
printf("\nvsnprintf overflow, len = %d, str = %s",
count, shortenstring(str, 203));
return strlen(str);
}
+# endif /* !luna2 */
+#endif /* !HASSNPRINTF */
+
/*
- * dopr(): poor man's version of doprintf
+ * sm_dopr(): poor man's version of doprintf
*/
static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
@@ -2952,9 +2973,10 @@ static void fmtnum __P((long value, int base, int dosign, int ljust, int len, in
static void dostr __P(( char * , int ));
static char *output;
static void dopr_outch __P(( int c ));
+static int SyslogErrno;
static void
-dopr( buffer, format, args )
+sm_dopr( buffer, format, args )
char *buffer;
const char *format;
va_list args;
@@ -2968,30 +2990,35 @@ dopr( buffer, format, args )
int ljust;
int len;
int zpad;
+# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+# endif
+
output = buffer;
while( (ch = *format++) ){
- switch( ch ){
- case '%':
- ljust = len = zpad = maxwidth = 0;
- longflag = pointflag = 0;
- nextch:
- ch = *format++;
- switch( ch ){
- case 0:
- dostr( "**end of format**" , 0);
- return;
- case '-': ljust = 1; goto nextch;
- case '0': /* set zero padding if len not set */
- if(len==0 && !pointflag) zpad = '0';
- case '1': case '2': case '3':
- case '4': case '5': case '6':
- case '7': case '8': case '9':
+ switch( ch ){
+ case '%':
+ ljust = len = zpad = maxwidth = 0;
+ longflag = pointflag = 0;
+ nextch:
+ ch = *format++;
+ switch( ch ){
+ case 0:
+ dostr( "**end of format**" , 0);
+ return;
+ case '-': ljust = 1; goto nextch;
+ case '0': /* set zero padding if len not set */
+ if(len==0 && !pointflag) zpad = '0';
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
if (pointflag)
maxwidth = maxwidth*10 + ch - '0';
else
len = len*10 + ch - '0';
- goto nextch;
+ goto nextch;
case '*':
if (pointflag)
maxwidth = va_arg( args, int );
@@ -2999,64 +3026,78 @@ dopr( buffer, format, args )
len = va_arg( args, int );
goto nextch;
case '.': pointflag = 1; goto nextch;
- case 'l': longflag = 1; goto nextch;
- case 'u': case 'U':
- /*fmtnum(value,base,dosign,ljust,len,zpad) */
- if( longflag ){
- value = va_arg( args, long );
- } else {
- value = va_arg( args, int );
- }
- fmtnum( value, 10,0, ljust, len, zpad ); break;
- case 'o': case 'O':
- /*fmtnum(value,base,dosign,ljust,len,zpad) */
- if( longflag ){
- value = va_arg( args, long );
- } else {
- value = va_arg( args, int );
- }
- fmtnum( value, 8,0, ljust, len, zpad ); break;
- case 'd': case 'D':
- if( longflag ){
- value = va_arg( args, long );
- } else {
- value = va_arg( args, int );
- }
- fmtnum( value, 10,1, ljust, len, zpad ); break;
- case 'x':
- if( longflag ){
- value = va_arg( args, long );
- } else {
- value = va_arg( args, int );
- }
- fmtnum( value, 16,0, ljust, len, zpad ); break;
- case 'X':
- if( longflag ){
- value = va_arg( args, long );
- } else {
- value = va_arg( args, int );
- }
- fmtnum( value,-16,0, ljust, len, zpad ); break;
- case 's':
- strvalue = va_arg( args, char *);
+ case 'l': longflag = 1; goto nextch;
+ case 'u': case 'U':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 10,0, ljust, len, zpad ); break;
+ case 'o': case 'O':
+ /*fmtnum(value,base,dosign,ljust,len,zpad) */
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 8,0, ljust, len, zpad ); break;
+ case 'd': case 'D':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 10,1, ljust, len, zpad ); break;
+ case 'x':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value, 16,0, ljust, len, zpad ); break;
+ case 'X':
+ if( longflag ){
+ value = va_arg( args, long );
+ } else {
+ value = va_arg( args, int );
+ }
+ fmtnum( value,-16,0, ljust, len, zpad ); break;
+ case 's':
+ strvalue = va_arg( args, char *);
if (maxwidth > 0 || !pointflag) {
if (pointflag && len > maxwidth)
len = maxwidth; /* Adjust padding */
fmtstr( strvalue,ljust,len,zpad, maxwidth);
}
break;
- case 'c':
- ch = va_arg( args, int );
- dopr_outch( ch ); break;
- case '%': dopr_outch( ch ); continue;
- default:
- dostr( "???????" , 0);
- }
- break;
- default:
- dopr_outch( ch );
- break;
- }
+ case 'c':
+ ch = va_arg( args, int );
+ dopr_outch( ch ); break;
+ case 'm':
+#if HASSTRERROR
+ dostr(strerror(SyslogErrno), 0);
+#else
+ if (SyslogErrno < 0 || SyslogErrno > sys_nerr)
+ {
+ dostr("Error ", 0);
+ fmtnum(SyslogErrno, 10, 0, 0, 0, 0);
+ }
+ else
+ dostr(sys_errlist[SyslogErrno], 0);
+#endif
+ break;
+
+ case '%': dopr_outch( ch ); continue;
+ default:
+ dostr( "???????" , 0);
+ }
+ break;
+ default:
+ dopr_outch( ch );
+ break;
+ }
}
*output = 0;
}
@@ -3069,7 +3110,7 @@ fmtstr( value, ljust, len, zpad, maxwidth )
int padlen, strlen; /* amount to pad */
if( value == 0 ){
- value = "<NULL>";
+ value = "<NULL>";
}
for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
if (strlen > maxwidth && maxwidth)
@@ -3078,13 +3119,13 @@ fmtstr( value, ljust, len, zpad, maxwidth )
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
while( padlen > 0 ) {
- dopr_outch( ' ' );
- --padlen;
+ dopr_outch( ' ' );
+ --padlen;
}
dostr( value, maxwidth );
while( padlen < 0 ) {
- dopr_outch( ' ' );
- ++padlen;
+ dopr_outch( ' ' );
+ ++padlen;
}
}
@@ -3101,50 +3142,50 @@ fmtnum( value, base, dosign, ljust, len, zpad )
int caps = 0;
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
- value, base, dosign, ljust, len, zpad )); */
+ value, base, dosign, ljust, len, zpad )); */
uvalue = value;
if( dosign ){
- if( value < 0 ) {
- signvalue = '-';
- uvalue = -value;
- }
+ if( value < 0 ) {
+ signvalue = '-';
+ uvalue = -value;
+ }
}
if( base < 0 ){
- caps = 1;
- base = -base;
+ caps = 1;
+ base = -base;
}
do{
- convert[place++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")
- [uvalue % (unsigned)base ];
- uvalue = (uvalue / (unsigned)base );
+ convert[place++] =
+ (caps? "0123456789ABCDEF":"0123456789abcdef")
+ [uvalue % (unsigned)base ];
+ uvalue = (uvalue / (unsigned)base );
}while(uvalue);
convert[place] = 0;
padlen = len - place;
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
- convert,place,signvalue,padlen)); */
+ convert,place,signvalue,padlen)); */
if( zpad && padlen > 0 ){
- if( signvalue ){
- dopr_outch( signvalue );
- --padlen;
- signvalue = 0;
- }
- while( padlen > 0 ){
- dopr_outch( zpad );
- --padlen;
- }
+ if( signvalue ){
+ dopr_outch( signvalue );
+ --padlen;
+ signvalue = 0;
+ }
+ while( padlen > 0 ){
+ dopr_outch( zpad );
+ --padlen;
+ }
}
while( padlen > 0 ) {
- dopr_outch( ' ' );
- --padlen;
+ dopr_outch( ' ' );
+ --padlen;
}
if( signvalue ) dopr_outch( signvalue );
while( place > 0 ) dopr_outch( convert[--place] );
while( padlen < 0 ){
- dopr_outch( ' ' );
- ++padlen;
+ dopr_outch( ' ' );
+ ++padlen;
}
}
@@ -3166,20 +3207,16 @@ dopr_outch( c )
{
#if 0
if( iscntrl(c) && c != '\n' && c != '\t' ){
- c = '@' + (c & 0x1F);
- if( end == 0 || output < end )
- *output++ = '^';
+ c = '@' + (c & 0x1F);
+ if( DoprEnd == 0 || output < DoprEnd )
+ *output++ = '^';
}
#endif
- if( end == 0 || output < end )
- *output++ = c;
+ if( DoprEnd == 0 || output < DoprEnd )
+ *output++ = c;
else
SnprfOverflow++;
}
-
-# endif /* !luna2 */
-
-#endif /* !HASSNPRINTF */
/*
** USERSHELLOK -- tell if a user's shell is ok for unrestricted use
**
@@ -3434,7 +3471,7 @@ freediskspace(dir, bsize)
{
if (bsize != NULL)
*bsize = FSBLOCKSIZE;
- if (fs.SFS_BAVAIL < 0)
+ if (fs.SFS_BAVAIL <= 0)
return 0;
else
return fs.SFS_BAVAIL;
@@ -3483,15 +3520,12 @@ enoughdiskspace(msize)
if (bfree < msize)
{
-#ifdef LOG
if (LogLevel > 0)
- syslog(LOG_ALERT,
- "%s: low on space (have %ld, %s needs %ld in %s)",
- CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id,
+ sm_syslog(LOG_ALERT, CurEnv->e_id,
+ "low on space (have %ld, %s needs %ld in %s)",
bfree,
CurHostName == NULL ? "SMTP-DAEMON" : CurHostName,
msize, QueueDir);
-#endif
return FALSE;
}
}
@@ -3597,7 +3631,7 @@ transienterror(err)
#if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
case ENOSR: /* Out of streams resources */
#endif
- case EOPENTIMEOUT: /* PSEUDO: open timed out */
+ case E_SM_OPENTIMEOUT: /* PSEUDO: open timed out */
return TRUE;
}
@@ -3627,6 +3661,7 @@ lockfile(fd, filename, ext, type)
char *ext;
int type;
{
+ int i;
# if !HASFLOCK
int action;
struct flock lfd;
@@ -3651,7 +3686,9 @@ lockfile(fd, filename, ext, type)
printf("lockfile(%s%s, action=%d, type=%d): ",
filename, ext, action, lfd.l_type);
- if (fcntl(fd, action, &lfd) >= 0)
+ while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
+ continue;
+ if (i >= 0)
{
if (tTd(55, 60))
printf("SUCCESS\n");
@@ -3697,7 +3734,9 @@ lockfile(fd, filename, ext, type)
if (tTd(55, 60))
printf("lockfile(%s%s, type=%o): ", filename, ext, type);
- if (flock(fd, type) >= 0)
+ while ((i = flock(fd, type)) < 0 && errno == EINTR)
+ continue;
+ if (i >= 0)
{
if (tTd(55, 60))
printf("SUCCESS\n");
@@ -3728,53 +3767,73 @@ lockfile(fd, filename, ext, type)
/*
** CHOWNSAFE -- tell if chown is "safe" (executable only by root)
**
+** Unfortunately, given that we can't predict other systems on which
+** a remote mounted (NFS) filesystem will be mounted, the answer is
+** almost always that this is unsafe.
+**
+** Note also that many operating systems have non-compliant
+** implementations of the _POSIX_CHOWN_RESTRICTED variable and the
+** fpathconf() routine. According to IEEE 1003.1-1990, if
+** _POSIX_CHOWN_RESTRICTED is defined and not equal to -1, then
+** no non-root process can give away the file. However, vendors
+** don't take NFS into account, so a comfortable value of
+** _POSIX_CHOWN_RESTRICTED tells us nothing.
+**
+** Also, some systems (e.g., IRIX 6.2) return 1 from fpathconf()
+** even on files where chown is not restricted. Many systems get
+** this wrong on NFS-based filesystems (that is, they say that chown
+** is restricted [safe] on NFS filesystems where it may not be, since
+** other systems can access the same filesystem and do file giveaway;
+** only the NFS server knows for sure!) Hence, it is important to
+** get the value of SAFENFSPATHCONF correct -- it should be defined
+** _only_ after testing (see test/t_pathconf.c) a system on an unsafe
+** NFS-based filesystem to ensure that you can get meaningful results.
+** If in doubt, assume unsafe!
+**
+** You may also need to tweak IS_SAFE_CHOWN -- it should be a
+** condition indicating whether the return from pathconf indicates
+** that chown is safe (typically either > 0 or >= 0 -- there isn't
+** even any agreement about whether a zero return means that a file
+** is or is not safe). It defaults to "> 0".
+**
+** If the parent directory is safe (writable only by owner back
+** to the root) then we can relax slightly and trust fpathconf
+** in more circumstances. This is really a crock -- if this is an
+** NFS mounted filesystem then we really know nothing about the
+** underlying implementation. However, most systems pessimize and
+** return an error (EINVAL or EOPNOTSUPP) on NFS filesystems, which
+** we interpret as unsafe, as we should. Thus, this heuristic gets
+** us into a possible problem only on systems that have a broken
+** pathconf implementation and which are also poorly configured
+** (have :include: files in group- or world-writable directories).
+**
** Parameters:
** fd -- the file descriptor to check.
+** safedir -- set if the parent directory is safe.
**
** Returns:
-** TRUE -- if only root can chown the file to an arbitrary
-** user.
+** TRUE -- if the chown(2) operation is "safe" -- that is,
+** only root can chown the file to an arbitrary user.
** FALSE -- if an arbitrary user can give away a file.
*/
+#ifndef IS_SAFE_CHOWN
+# define IS_SAFE_CHOWN > 0
+#endif
+
bool
-chownsafe(fd)
+chownsafe(fd, safedir)
int fd;
+ bool safedir;
{
-#ifdef __hpux
- char *s;
- int tfd;
- uid_t o_uid, o_euid;
- gid_t o_gid, o_egid;
- bool rval;
- struct stat stbuf;
-
- o_uid = getuid();
- o_euid = geteuid();
- o_gid = getgid();
- o_egid = getegid();
- fstat(fd, &stbuf);
- setresuid(stbuf.st_uid, stbuf.st_uid, -1);
- setresgid(stbuf.st_gid, stbuf.st_gid, -1);
- s = tmpnam(NULL);
- tfd = open(s, O_RDONLY|O_CREAT, 0600);
- rval = fchown(tfd, DefUid, DefGid) != 0;
- close(tfd);
- setresuid(o_uid, o_euid, -1);
- setresgid(o_gid, o_egid, -1);
- unlink(s);
- return rval;
-#else
-# ifdef _POSIX_CHOWN_RESTRICTED
-# if _POSIX_CHOWN_RESTRICTED == -1
- return FALSE;
-# else
- return TRUE;
-# endif
-# else
-# ifdef _PC_CHOWN_RESTRICTED
+#if !defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1
+# if defined(_PC_CHOWN_RESTRICTED)
int rval;
+ /* give the system administrator a chance to override */
+ if (ChownAlwaysSafe)
+ return TRUE;
+
/*
** Some systems (e.g., SunOS) seem to have the call and the
** #define _PC_CHOWN_RESTRICTED, but don't actually implement
@@ -3783,15 +3842,14 @@ chownsafe(fd)
errno = 0;
rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
- if (errno == 0)
- return rval > 0;
-# endif
-# ifdef BSD
- return TRUE;
+# if SAFENFSPATHCONF
+ return errno == 0 && rval IS_SAFE_CHOWN;
# else
- return FALSE;
+ return safedir && errno == 0 && rval IS_SAFE_CHOWN;
# endif
# endif
+#else
+ return ChownAlwaysSafe;
#endif
}
/*
@@ -4028,11 +4086,10 @@ validate_connection(sap, hostname, e)
#if TCPWRAPPERS
if (!hosts_ctl("sendmail", hostname, anynet_ntoa(sap), STRING_UNKNOWN))
{
-# ifdef LOG
if (LogLevel >= 4)
- syslog(LOG_NOTICE, "tcpwrappers (%s, %s) rejection",
+ sm_syslog(LOG_NOTICE, NOQID,
+ "tcpwrappers (%s, %s) rejection",
hostname, anynet_ntoa(sap));
-# endif
return FALSE;
}
#endif
@@ -4385,7 +4442,7 @@ secureware_setup_secure(uid)
** Loads $=w with the names of all the interfaces.
*/
-#ifdef SIOCGIFCONF
+#if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
struct rtentry;
struct mbuf;
# include <arpa/inet.h>
@@ -4398,19 +4455,38 @@ struct mbuf;
void
load_if_names()
{
-#ifdef SIOCGIFCONF
+#if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
int s;
int i;
- struct ifconf ifc;
- char interfacebuf[10240];
+ struct ifconf ifc;
+ int numifs;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
return;
/* get the list of known IP address from the kernel */
- ifc.ifc_buf = interfacebuf;
- ifc.ifc_len = sizeof interfacebuf;
+# ifdef SIOCGIFNUM
+ if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0)
+ {
+ /* can't get number of interfaces -- fall back */
+ if (tTd(0, 4))
+ printf("SIOCGIFNUM failed: %s\n", errstring(errno));
+ numifs = -1;
+ }
+ else if (tTd(0, 42))
+ printf("system has %d interfaces\n", numifs);
+ if (numifs < 0)
+# endif
+ numifs = 512;
+
+ if (numifs <= 0)
+ {
+ close(s);
+ return;
+ }
+ ifc.ifc_len = numifs * sizeof (struct ifreq);
+ ifc.ifc_buf = xalloc(ifc.ifc_len);
if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
{
if (tTd(0, 4))
@@ -4435,7 +4511,6 @@ load_if_names()
#endif
char ip_addr[256];
extern char *inet_ntoa();
- extern struct hostent *gethostbyaddr();
#ifdef BSD4_4_SOCKADDR
if (sa->sa_len > sizeof ifr->ifr_addr)
@@ -4456,12 +4531,12 @@ load_if_names()
ioctl(s, SIOCGIFFLAGS, (char *) &ifrf);
if (tTd(0, 41))
printf("\tflags: %x\n", ifrf.ifr_flags);
- if (!bitset(IFF_UP, ifrf.ifr_flags))
- continue;
+# define IFRFREF ifrf
#else
- if (!bitset(IFF_UP, ifr->ifr_flags))
- continue;
+# define IFRFREF (*ifr)
#endif
+ if (!bitset(IFF_UP, IFRFREF.ifr_flags))
+ continue;
/* extract IP address from the list*/
ia = (((struct sockaddr_in *) sa)->sin_addr);
@@ -4484,18 +4559,21 @@ load_if_names()
}
/* skip "loopback" interface "lo" */
- if (strcmp("lo0", ifr->ifr_name) == 0)
+ if (bitset(IFF_LOOPBACK, IFRFREF.ifr_flags))
continue;
/* lookup name with IP address */
hp = sm_gethostbyaddr((char *) &ia, sizeof(ia), AF_INET);
if (hp == NULL)
{
-#ifdef LOG
if (LogLevel > 3)
- syslog(LOG_WARNING,
- "gethostbyaddr() failed for %.100s\n",
- inet_ntoa(ia));
+ sm_syslog(LOG_WARNING, NOQID,
+ "gethostbyaddr(%.100s) failed: %d\n",
+ inet_ntoa(ia),
+#if NAMED_BIND
+ h_errno);
+#else
+ -1);
#endif
continue;
}
@@ -4520,7 +4598,166 @@ load_if_names()
hp->h_aliases++;
}
}
+ free(ifc.ifc_buf);
close(s);
+# undef IFRFREF
+#endif
+}
+ /*
+** GET_NUM_PROCS_ONLINE -- return the number of processors currently online
+**
+** Parameters:
+** none.
+**
+** Returns:
+** The number of processors online.
+*/
+
+int
+get_num_procs_online()
+{
+ int nproc = 0;
+
+#if _FFR_SCALE_LA_BY_NUM_PROCS
+#ifdef _SC_NPROCESSORS_ONLN
+ nproc = (int) sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+#endif
+ if (nproc <= 0)
+ nproc = 1;
+ return nproc;
+}
+ /*
+** SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE
+**
+** Parameters:
+** level -- syslog level
+** id -- envelope ID or NULL (NOQUEUE)
+** fmt -- format string
+** arg... -- arguments as implied by fmt.
+**
+** Returns:
+** none
+*/
+
+/* VARARGS3 */
+void
+# ifdef __STDC__
+sm_syslog(int level, const char *id, const char *fmt, ...)
+# else
+sm_syslog(level, id, fmt, va_alist)
+ int level;
+ const char *id;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ static char *buf = NULL;
+ static size_t bufsize = MAXLINE;
+ char *begin, *end;
+ int seq = 1;
+ int idlen;
+ extern int SnprfOverflow;
+ VA_LOCAL_DECL
+
+ SyslogErrno = errno;
+ if (id == NULL)
+ {
+ id = "NOQUEUE";
+ idlen = 9;
+ }
+ else if (strcmp(id, NOQID) == 0)
+ {
+ id = "";
+ idlen = 0;
+ }
+ else
+ idlen = strlen(id + 2);
+bufalloc:
+ if (buf == NULL)
+ buf = (char *) xalloc(sizeof(char) * bufsize);
+
+ /* do a virtual vsnprintf into buf */
+ VA_START(fmt);
+ buf[0] = 0;
+ DoprEnd = buf + bufsize - 1;
+ SnprfOverflow = 0;
+ sm_dopr(buf, fmt, ap);
+ *DoprEnd = '\0';
+ VA_END;
+ /* end of virtual vsnprintf */
+
+ if (SnprfOverflow)
+ {
+ /* String too small, redo with correct size */
+ bufsize += SnprfOverflow + 1;
+ free(buf);
+ buf = NULL;
+ goto bufalloc;
+ }
+ if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE)
+ {
+#if LOG
+ if (*id == '\0')
+ syslog(level, "%s", buf);
+ else
+ syslog(level, "%s: %s", id, buf);
+#else
+ /*XXX should do something more sensible */
+ if (*id == '\0')
+ fprintf(stderr, "%s\n", buf);
+ else
+ fprintf(stderr, "%s: %s\n", id, buf);
+#endif
+ return;
+ }
+
+ begin = buf;
+ while (*begin != '\0' &&
+ (strlen(begin) + idlen + 5) > SYSLOG_BUFSIZE)
+ {
+ char save;
+
+ if (seq == 999)
+ {
+ /* Too many messages */
+ break;
+ }
+ end = begin + SYSLOG_BUFSIZE - idlen - 12;
+ while (end > begin)
+ {
+ /* Break on comma or space */
+ if (*end == ',' || *end == ' ')
+ {
+ end++; /* Include separator */
+ break;
+ }
+ end--;
+ }
+ /* No separator, break midstring... */
+ if (end == begin)
+ end = begin + SYSLOG_BUFSIZE - idlen - 12;
+ save = *end;
+ *end = 0;
+#if LOG
+ syslog(level, "%s[%d]: %s ...", id, seq++, begin);
+#else
+ fprintf(stderr, "%s[%d]: %s ...\n", id, seq++, begin);
+#endif
+ *end = save;
+ begin = end;
+ }
+ if (seq == 999)
+#if LOG
+ syslog(level, "%s[%d]: log terminated, too many parts", id, seq);
+#else
+ fprintf(stderr, "%s[%d]: log terminated, too many parts\n", id, seq);
+#endif
+ else if (*begin != '\0')
+#if LOG
+ syslog(level, "%s[%d]: %s", id, seq, begin);
+#else
+ fprintf(stderr, "%s[%d]: %s\n", id, seq, begin);
#endif
}
/*
@@ -4553,7 +4790,7 @@ hard_syslog(pri, msg, va_alist)
# endif
{
int i;
- char buf[SYSLOG_BUFSIZE * 2];
+ char buf[SYSLOG_BUFSIZE];
VA_LOCAL_DECL;
VA_START(msg);
@@ -4613,7 +4850,7 @@ char *CompileOptions[] =
#if LDAPMAP
"LDAPMAP",
#endif
-#ifdef LOG
+#if LOG
"LOG",
#endif
#if MATCHGECOS
@@ -4695,6 +4932,9 @@ char *CompileOptions[] =
char *OsCompileOptions[] =
{
+#if BOGUS_O_EXCL
+ "BOGUS_O_EXCL",
+#endif
#if HASFCHMOD
"HASFCHMOD",
#endif
@@ -4731,6 +4971,9 @@ char *OsCompileOptions[] =
#if HASSNPRINTF
"HASSNPRINTF",
#endif
+#if HASSTRERROR
+ "HASSTRERROR",
+#endif
#if HASULIMIT
"HASULIMIT",
#endif
@@ -4758,12 +5001,18 @@ char *OsCompileOptions[] =
#if RLIMIT_NEEDS_SYS_TIME_H
"RLIMIT_NEEDS_SYS_TIME_H",
#endif
+#if SAFENFSPATHCONF
+ "SAFENFSPATHCONF",
+#endif
#if SECUREWARE
"SECUREWARE",
#endif
#if SHARE_V1
"SHARE_V1",
#endif
+#if SIOCGIFCONF_IS_BROKEN
+ "SIOCGIFCONF_IS_BROKEN",
+#endif
#if SYS5SETPGRP
"SYS5SETPGRP",
#endif
diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h
index 595ed433e0a..bf81bbfa342 100644
--- a/usr.sbin/sendmail/src/conf.h
+++ b/usr.sbin/sendmail/src/conf.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.
*
@@ -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
@@ -1957,6 +2031,13 @@ typedef struct msgb mblk_t;
/*
+** 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
** reasonable. They are printed in errstring.
@@ -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
diff --git a/usr.sbin/sendmail/src/convtime.c b/usr.sbin/sendmail/src/convtime.c
index 65994f88758..5ca1b39149e 100644
--- a/usr.sbin/sendmail/src/convtime.c
+++ b/usr.sbin/sendmail/src/convtime.c
@@ -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"
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
index 7529e36cf32..1a202bf0a4e 100644
--- a/usr.sbin/sendmail/src/daemon.c
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -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;
@@ -867,7 +896,7 @@ gothostent:
hp->h_length);
break;
}
- i = 1;
+ addrno = 1;
}
/*
@@ -880,10 +909,9 @@ gothostent:
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
@@ -985,22 +1013,23 @@ gothostent:
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)
@@ -1015,7 +1044,7 @@ gothostent:
/* 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",
@@ -1024,14 +1053,14 @@ gothostent:
{
#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;
@@ -1126,19 +1155,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);
}
@@ -1178,6 +1205,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];
@@ -1200,6 +1230,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;
@@ -1337,6 +1391,9 @@ noident:
postident:
#if IP_SRCROUTE
+# ifndef GET_IPOPT_DST
+# define GET_IPOPT_DST(dst) (dst)
+# endif
/*
** Extract IP source routing information.
**
@@ -1380,21 +1437,31 @@ postident:
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));
@@ -1409,7 +1476,7 @@ postident:
l -= i + 1;
q += sizeof(struct in_addr);
}
- o += *o;
+ o += o[1];
break;
default:
@@ -1430,6 +1497,11 @@ noipsr:
(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))
@@ -1440,7 +1512,7 @@ postipsr:
** 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.
@@ -1454,7 +1526,8 @@ postipsr:
** 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 *
@@ -1495,7 +1568,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;
}
/*
@@ -1529,16 +1611,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
@@ -1586,9 +1664,10 @@ host_map_lookup(map, name, av, statp)
return (NULL);
*cp = '\0';
(void) inet_aton(&name[1], &in_addr);
-
- /* nope -- ask the name server */
- hp = gethostbyaddr((char *)&in_addr, sizeof(in_addr), AF_INET);
+ *cp = ']';
+
+ /* nope -- ask the name server */
+ hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET);
s->s_namecanon.nc_errno = errno;
#if NAMED_BIND
s->s_namecanon.nc_herrno = h_errno;
@@ -1601,9 +1680,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;
}
@@ -1685,16 +1767,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:
@@ -1704,7 +1833,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>
diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c
index 97a1050552a..c98c4bcbca9 100644
--- a/usr.sbin/sendmail/src/deliver.c
+++ b/usr.sbin/sendmail/src/deliver.c
@@ -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 @@ tryhost:
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 @@ tryhost:
}
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 @@ tryhost:
#endif
if (i == EX_OK)
{
+ goodmxfound = TRUE;
mci->mci_state = MCIS_OPENING;
mci_cache(mci);
if (TrafficLogFile != NULL)
@@ -1355,6 +1391,8 @@ tryhost:
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 @@ tryhost:
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 @@ tryhost:
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 @@ tryhost:
/* 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*/
}
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c
index 70706555f0d..920b618f5b3 100644
--- a/usr.sbin/sendmail/src/domain.c
+++ b/usr.sbin/sendmail/src/domain.c
@@ -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)
{
@@ -881,6 +882,7 @@ gethostalias(host)
fclose(fp);
return NULL;
}
+ fclose(fp);
/* got a match; extract the equivalent name */
while (*p != '\0' && isascii(*p) && isspace(*p))
diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c
index c5e98f7e3f1..4dc07ae7fc3 100644
--- a/usr.sbin/sendmail/src/envelope.c
+++ b/usr.sbin/sendmail/src/envelope.c
@@ -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 @@ simpledrop:
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 @@ simpledrop:
}
/* 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);
diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c
index 2e0f0b91004..5bec0884d02 100644
--- a/usr.sbin/sendmail/src/err.c
+++ b/usr.sbin/sendmail/src/err.c
@@ -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
}
diff --git a/usr.sbin/sendmail/src/headers.c b/usr.sbin/sendmail/src/headers.c
index d40d95f470a..a4ece010dde 100644
--- a/usr.sbin/sendmail/src/headers.c
+++ b/usr.sbin/sendmail/src/headers.c
@@ -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
@@ -172,6 +223,13 @@ chompheader(line, def, hdrp, e)
}
/*
+ ** 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)
** insert the full name information in all circumstances.
@@ -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
diff --git a/usr.sbin/sendmail/src/macro.c b/usr.sbin/sendmail/src/macro.c
index e31d0deb21c..0f31d11f3b4 100644
--- a/usr.sbin/sendmail/src/macro.c
+++ b/usr.sbin/sendmail/src/macro.c
@@ -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"
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c
index 3c30fb3e617..880b181ca25 100644
--- a/usr.sbin/sendmail/src/main.c
+++ b/usr.sbin/sendmail/src/main.c
@@ -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);
diff --git a/usr.sbin/sendmail/src/makesendmail b/usr.sbin/sendmail/src/makesendmail
index 41b73202fae..a28e2f4cc4e 100644
--- a/usr.sbin/sendmail/src/makesendmail
+++ b/usr.sbin/sendmail/src/makesendmail
@@ -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.43 (Berkeley) 12/14/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
diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c
index 3d40d62e511..e0a0fd24088 100644
--- a/usr.sbin/sendmail/src/map.c
+++ b/usr.sbin/sendmail/src/map.c
@@ -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))
{
diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c
index a81e61de2c7..f8ba789ff8a 100644
--- a/usr.sbin/sendmail/src/mci.c
+++ b/usr.sbin/sendmail/src/mci.c
@@ -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;
diff --git a/usr.sbin/sendmail/src/mime.c b/usr.sbin/sendmail/src/mime.c
index 999c5ab5897..3e5a610bb39 100644
--- a/usr.sbin/sendmail/src/mime.c
+++ b/usr.sbin/sendmail/src/mime.c
@@ -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);
diff --git a/usr.sbin/sendmail/src/newaliases.1 b/usr.sbin/sendmail/src/newaliases.1
index c611b78b62b..7168c1303f4 100644
--- a/usr.sbin/sendmail/src/newaliases.1
+++ b/usr.sbin/sendmail/src/newaliases.1
@@ -1,3 +1,4 @@
+.\" Copyright (c) 1983, 1997 Eric P. Allman
.\" Copyright (c) 1985, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -29,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)newaliases.1 8.4 (Berkeley) 2/22/94
+.\" @(#)newaliases.1 8.5 (Berkeley) 2/1/97
.\"
-.Dd February 22, 1994
+.Dd February 1, 1997
.Dt NEWALIASES 1
.Os BSD 4
.Sh NAME