Fold sendmail-8.8.2 changes into files that have been touched.
(^!&@$#&^! delete !!@^@^ trailing !@^&#$!& whitespace!!!)
This commit is contained in:
parent
3b50ea913d
commit
82c2534fd0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19149
@ -1,4 +1,4 @@
|
||||
# @(#)Makefile 8.12 (Berkeley) 5/29/95
|
||||
# @(#)Makefile 8.15 (Berkeley) 9/21/96
|
||||
|
||||
VER= XX
|
||||
SUBDIR= src mailstats makemap praliases smrsh cf/cf
|
||||
@ -12,6 +12,11 @@ tar: sccs-check compile-world run-pax
|
||||
sccs-check:
|
||||
sccs check
|
||||
(cd src; sccs check)
|
||||
(cd mail.local; sccs check)
|
||||
(cd mailstats; sccs check)
|
||||
(cd makemap; sccs check)
|
||||
(cd praliases; sccs check)
|
||||
(cd smrsh; sccs check)
|
||||
(cd doc/op; sccs check)
|
||||
(cd doc/intro; sccs check)
|
||||
(cd doc/usenix; sccs check)
|
||||
@ -24,7 +29,12 @@ sccs-check:
|
||||
(cd cf/domain; sccs check)
|
||||
|
||||
compile-world:
|
||||
(cd src; ${MAKE})
|
||||
(cd src; sh makesendmail)
|
||||
(cd mail.local; ${MAKE})
|
||||
(cd mailstats; ${MAKE})
|
||||
(cd makemap; ${MAKE})
|
||||
(cd praliases; ${MAKE})
|
||||
(cd smrsh; ${MAKE})
|
||||
(cd doc; PRINTER=ps ${MAKE})
|
||||
(cd doc; chmod 444 op/op.ps intro/intro.ps usenix/usenix.ps)
|
||||
(cd cf/cf; ${MAKE})
|
||||
|
@ -1,4 +1,4 @@
|
||||
# @(#)Makefile 8.12 (Berkeley) 5/29/95
|
||||
# @(#)Makefile 8.15 (Berkeley) 9/21/96
|
||||
|
||||
VER= XX
|
||||
SUBDIR= src mailstats makemap praliases smrsh cf/cf
|
||||
@ -12,6 +12,11 @@ tar: sccs-check compile-world run-pax
|
||||
sccs-check:
|
||||
sccs check
|
||||
(cd src; sccs check)
|
||||
(cd mail.local; sccs check)
|
||||
(cd mailstats; sccs check)
|
||||
(cd makemap; sccs check)
|
||||
(cd praliases; sccs check)
|
||||
(cd smrsh; sccs check)
|
||||
(cd doc/op; sccs check)
|
||||
(cd doc/intro; sccs check)
|
||||
(cd doc/usenix; sccs check)
|
||||
@ -24,7 +29,12 @@ sccs-check:
|
||||
(cd cf/domain; sccs check)
|
||||
|
||||
compile-world:
|
||||
(cd src; ${MAKE})
|
||||
(cd src; sh makesendmail)
|
||||
(cd mail.local; ${MAKE})
|
||||
(cd mailstats; ${MAKE})
|
||||
(cd makemap; ${MAKE})
|
||||
(cd praliases; ${MAKE})
|
||||
(cd smrsh; ${MAKE})
|
||||
(cd doc; PRINTER=ps ${MAKE})
|
||||
(cd doc; chmod 444 op/op.ps intro/intro.ps usenix/usenix.ps)
|
||||
(cd cf/cf; ${MAKE})
|
||||
|
@ -44,7 +44,7 @@ POPDIVERT
|
||||
### SMTP Mailer specification ###
|
||||
#####################################
|
||||
|
||||
VERSIONID(`@(#)smtp.m4 8.32 (Berkeley) 11/20/95')
|
||||
VERSIONID(`@(#)smtp.m4 8.33 (Berkeley) 7/9/96')
|
||||
|
||||
Msmtp, P=[IPC], F=CONCAT(mDFMuX8, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `21/31', `21'), E=\r\n, L=990,
|
||||
_OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,
|
||||
@ -114,7 +114,9 @@ R$+ < @ $* > $* $@ $1 < @ $2 > $3 not UUCP form
|
||||
R< $&h ! > $- ! $+ $@ $2 < @ $1 .UUCP. >
|
||||
R< $&h ! > $-.$+ ! $+ $@ $3 < @ $1.$2 >
|
||||
R< $&h ! > $+ $@ $1 < @ $&h .UUCP. >
|
||||
R< $+ ! > $+ $: $1 ! $2 < @ *LOCAL* >')
|
||||
R< $+ ! > $+ $: $1 ! $2 < @ $Y > use UUCP_RELAY
|
||||
R$+ < @ $+ : $+ > $@ $1 < @ $3 > strip mailer: part
|
||||
R$+ < @ > $: $1 < @ *LOCAL* > if no UUCP_RELAY')
|
||||
|
||||
|
||||
#
|
||||
|
@ -1,8 +1,8 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/7/93
|
||||
# @(#)Makefile 8.2 (Berkeley) 9/21/96
|
||||
|
||||
PROG= mailstats
|
||||
CFLAGS+=-I${.CURDIR}/../src
|
||||
MAN8= mailstats.8
|
||||
CFLAGS+=-I${.CURDIR}/../src
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -40,9 +40,10 @@ static char copyright[] =
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mailstats.c 8.4 (Berkeley) 8/14/94";
|
||||
static char sccsid[] = "@(#)mailstats.c 8.8 (Berkeley) 9/25/96";
|
||||
#endif /* not lint */
|
||||
|
||||
#define NOT_SENDMAIL
|
||||
#include <sendmail.h>
|
||||
#include <mailstats.h>
|
||||
#include <pathnames.h>
|
||||
@ -91,7 +92,8 @@ main(argc, argv)
|
||||
case '?':
|
||||
default:
|
||||
usage:
|
||||
fputs("usage: mailstats [-o] [-C cffile] [-f stfile]\n", stderr);
|
||||
fputs("usage: mailstats [-o] [-C cffile] [-f stfile]\n",
|
||||
stderr);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
}
|
||||
@ -189,13 +191,24 @@ main(argc, argv)
|
||||
exit (EX_OSFILE);
|
||||
}
|
||||
|
||||
if ((fd = open(sfile, O_RDONLY)) < 0) {
|
||||
if ((fd = open(sfile, O_RDONLY)) < 0 ||
|
||||
(i = read(fd, &stat, sizeof stat)) < 0)
|
||||
{
|
||||
fputs("mailstats: ", stderr);
|
||||
perror(sfile);
|
||||
exit(EX_NOINPUT);
|
||||
}
|
||||
if (read(fd, &stat, sizeof(stat)) != sizeof(stat) ||
|
||||
stat.stat_size != sizeof(stat))
|
||||
if (i == 0)
|
||||
{
|
||||
sleep(1);
|
||||
i = read(fd, &stat, sizeof stat);
|
||||
if (i == 0)
|
||||
{
|
||||
bzero((ARBPTR_T) &stat, sizeof stat);
|
||||
(void) time(&stat.stat_itime);
|
||||
}
|
||||
}
|
||||
else if (i != sizeof stat || stat.stat_size != sizeof(stat))
|
||||
{
|
||||
fputs("mailstats: file size changed.\n", stderr);
|
||||
exit(EX_OSERR);
|
||||
|
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)makemap.c 8.14 (Berkeley) 11/5/95";
|
||||
static char sccsid[] = "@(#)makemap.c 8.17 (Berkeley) 9/25/96";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
@ -45,6 +45,7 @@ static char sccsid[] = "@(#)makemap.c 8.14 (Berkeley) 11/5/95";
|
||||
#ifndef ISC_UNIX
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#define NOT_SENDMAIL
|
||||
#include "useful.h"
|
||||
#include "conf.h"
|
||||
|
||||
@ -95,6 +96,7 @@ main(argc, argv)
|
||||
int lineno;
|
||||
int st;
|
||||
int mode;
|
||||
int putflags;
|
||||
enum type type;
|
||||
int fd;
|
||||
union
|
||||
@ -211,20 +213,33 @@ main(argc, argv)
|
||||
bzero(&bti, sizeof bti);
|
||||
if (allowdups)
|
||||
bti.flags |= R_DUP;
|
||||
if (allowdups || allowreplace)
|
||||
putflags = 0;
|
||||
else
|
||||
putflags = R_NOOVERWRITE;
|
||||
break;
|
||||
|
||||
case T_HASH:
|
||||
if (allowreplace)
|
||||
putflags = 0;
|
||||
else
|
||||
putflags = R_NOOVERWRITE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NDBM
|
||||
case T_DBM:
|
||||
#endif
|
||||
if (allowdups)
|
||||
{
|
||||
fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n",
|
||||
progname, typename);
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
if (allowreplace)
|
||||
putflags = DBM_REPLACE;
|
||||
else
|
||||
putflags = DBM_INSERT;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -386,16 +401,14 @@ main(argc, argv)
|
||||
{
|
||||
#ifdef NDBM
|
||||
case T_DBM:
|
||||
st = dbm_store(dbp.dbm, key.dbm, val.dbm,
|
||||
allowreplace ? DBM_REPLACE : DBM_INSERT);
|
||||
st = dbm_store(dbp.dbm, key.dbm, val.dbm, putflags);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef NEWDB
|
||||
case T_BTREE:
|
||||
case T_HASH:
|
||||
st = (*dbp.db->put)(dbp.db, &key.db, &val.db,
|
||||
allowreplace ? 0 : R_NOOVERWRITE);
|
||||
st = (*dbp.db->put)(dbp.db, &key.db, &val.db, putflags);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)smrsh.8 8.1 (Berkeley) 11/13/94
|
||||
.\" @(#)smrsh.8 8.2 (Berkeley) 1/9/96
|
||||
.\"
|
||||
.TH SMRSH 8 11/02/93
|
||||
.SH NAME
|
||||
@ -62,8 +62,8 @@ limits programs to be in the directory
|
||||
/usr/libexec/sm.bin,
|
||||
allowing the system administrator to choose the set of acceptable commands.
|
||||
It also rejects any commands with the characters
|
||||
`\`', `<', `>', `|', `;', `&', `$', `(', `)', `\r' (carriage return),
|
||||
or `\n' (newline)
|
||||
`\`', `<', `>', `|', `;', `&', `$', `(', `)', `\er' (carriage return),
|
||||
or `\en' (newline)
|
||||
on the command line to prevent ``end run'' attacks.
|
||||
.PP
|
||||
Initial pathnames on programs are stripped,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 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.49 (Berkeley) 10/29/95";
|
||||
static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include <errno.h>
|
||||
@ -101,8 +101,8 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
int buflen;
|
||||
int istate;
|
||||
int mstate;
|
||||
char *pbp;
|
||||
char peekbuf[8];
|
||||
u_char *pbp;
|
||||
u_char peekbuf[8];
|
||||
char dfname[20];
|
||||
char bufbuf[MAXLINE];
|
||||
extern bool isheader();
|
||||
@ -170,6 +170,7 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
if (setjmp(CtxCollectTimeout) != 0)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 2)
|
||||
syslog(LOG_NOTICE,
|
||||
"timeout waiting for input from %s during message collect",
|
||||
CurHostName ? CurHostName : "<local machine>");
|
||||
@ -216,8 +217,6 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
c &= 0x7f;
|
||||
else
|
||||
HasEightBits |= bitset(0x80, c);
|
||||
if (!headeronly)
|
||||
e->e_msgsize++;
|
||||
}
|
||||
if (tTd(30, 94))
|
||||
printf("istate=%d, c=%c (0x%x)\n",
|
||||
@ -253,7 +252,7 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
break;
|
||||
|
||||
case IS_DOTCR:
|
||||
if (c == '\n')
|
||||
if (c == '\n' && !ignrdot)
|
||||
goto readerr;
|
||||
else
|
||||
{
|
||||
@ -287,6 +286,8 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
istate = IS_NORM;
|
||||
|
||||
bufferchar:
|
||||
if (!headeronly)
|
||||
e->e_msgsize++;
|
||||
if (mstate == MS_BODY)
|
||||
{
|
||||
/* just put the character out */
|
||||
@ -316,7 +317,13 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
if (obuf != bufbuf)
|
||||
free(obuf);
|
||||
}
|
||||
if (c != '\0')
|
||||
if (c >= 0200 && c <= 0237)
|
||||
{
|
||||
#if 0 /* causes complaints -- figure out something for 8.9 */
|
||||
usrerr("Illegal character 0x%x in header", c);
|
||||
#endif
|
||||
}
|
||||
else if (c != '\0')
|
||||
*bp++ = c;
|
||||
if (istate == IS_BOL)
|
||||
break;
|
||||
@ -564,7 +571,8 @@ collect(fp, smtpmode, requeueflag, hdrp, e)
|
||||
if (HasEightBits)
|
||||
{
|
||||
e->e_flags |= EF_HAS8BIT;
|
||||
if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode))
|
||||
if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode) &&
|
||||
!bitset(EF_IS_MIME, e->e_flags))
|
||||
{
|
||||
e->e_status = "5.6.1";
|
||||
usrerr("554 Eight bit data not allowed");
|
||||
@ -625,6 +633,7 @@ tferror(tf, e)
|
||||
struct stat st;
|
||||
long avail;
|
||||
long bsize;
|
||||
extern long freediskspace __P((char *, long *));
|
||||
|
||||
e->e_flags |= EF_NO_BODY_RETN;
|
||||
if (fstat(fileno(tf), &st) < 0)
|
||||
@ -729,7 +738,6 @@ eatfrom(fm, e)
|
||||
if (*p != '\0')
|
||||
{
|
||||
char *q;
|
||||
extern char *arpadate();
|
||||
|
||||
/* we have found a date */
|
||||
q = xalloc(25);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 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.220 (Berkeley) 11/29/95
|
||||
* @(#)conf.h 8.267 (Berkeley) 10/17/96
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -66,7 +66,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
||||
# define MAXMAILERS 25 /* maximum mailers known to system */
|
||||
# define MAXRWSETS 200 /* max # of sets of rewriting rules */
|
||||
# define MAXPRIORITIES 25 /* max values for Precedence: field */
|
||||
# define MAXMXHOSTS 20 /* max # of MX records */
|
||||
# define MAXMXHOSTS 100 /* max # of MX records for one host */
|
||||
# define SMTPLINELIM 990 /* maximum SMTP line length */
|
||||
# define MAXKEY 128 /* maximum size of a database key */
|
||||
# define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
|
||||
@ -183,9 +183,6 @@ 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
|
||||
# ifdef __STDC__
|
||||
extern void hard_syslog(int, char *, ...);
|
||||
# endif
|
||||
|
||||
# ifdef V4FS
|
||||
/* HP-UX 10.x */
|
||||
@ -205,11 +202,24 @@ extern void hard_syslog(int, char *, ...);
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# endif
|
||||
# ifdef __STDC__
|
||||
extern void hard_syslog(int, char *, ...);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** IBM AIX 4.x
|
||||
*/
|
||||
|
||||
#ifdef _AIX4
|
||||
# define _AIX3 1 /* pull in AIX3 stuff */
|
||||
# define HASSETREUID 1 /* setreuid(2) works */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** IBM AIX 3.x -- actually tested for 3.2.3
|
||||
*/
|
||||
@ -222,15 +232,58 @@ extern void hard_syslog(int, char *, ...);
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
|
||||
# define FORK fork /* no vfork primitive available */
|
||||
# define GIDSET_T gid_t
|
||||
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
|
||||
# define SPT_PADCHAR '\0' /* pad process title with nulls */
|
||||
# define LA_TYPE LA_INT
|
||||
# define FSHIFT 16
|
||||
# define LA_AVENRUN "avenrun"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** IBM AIX 2.2.1 -- actually tested for osupdate level 2706+1773
|
||||
**
|
||||
** From Mark Whetzel <markw@wg.waii.com>.
|
||||
*/
|
||||
|
||||
#ifdef AIX /* AIX/RT compiler pre-defines this */
|
||||
# include <paths.h>
|
||||
# include <sys/time.h> /* AIX/RT resource.h does NOT include this */
|
||||
# define HASINITGROUPS 1 /* has initgroups(3) call */
|
||||
# define HASUNAME 1 /* use System V uname(2) system call */
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define HASFCHMOD 0 /* does not have fchmod(2) syscall */
|
||||
# define HASSETREUID 1 /* use setreuid(2) -lbsd system call */
|
||||
# define HASSETVBUF 1 /* use setvbuf(2) system call */
|
||||
# define HASSETRLIMIT 0 /* does not have setrlimit call */
|
||||
# define HASFLOCK 0 /* does not have flock call - use fcntl */
|
||||
# define HASULIMIT 1 /* use ulimit instead of setrlimit call */
|
||||
# define NEEDGETOPT 1 /* Do we need theirs or ours */
|
||||
# define SYS5SETPGRP 1 /* don't have setpgid on AIX/RT */
|
||||
# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
|
||||
# define BSD4_3 1 /* NOT bsd 4.4 or posix signals */
|
||||
# define GIDSET_T int
|
||||
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
|
||||
# define SPT_PADCHAR '\0' /* pad process title with nulls */
|
||||
# define LA_TYPE LA_SUBR /* use our ported loadavgd daemon */
|
||||
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
|
||||
# define ARBPTR_T int *
|
||||
# define void int
|
||||
typedef int pid_t;
|
||||
/* RTisms for BSD compatibility, specified in the Makefile
|
||||
define BSD 1
|
||||
define BSD_INCLUDES 1
|
||||
define BSD_REMAP_SIGNAL_TO_SIGVEC
|
||||
RTisms needed above */
|
||||
/* make this sendmail in a completely different place */
|
||||
# define _PATH_VENDORCF "/usr/local/newmail/sendmail.cf"
|
||||
# ifndef _PATH_SENDMAILPID
|
||||
# define _PATH_SENDMAILPID "/usr/local/newmail/sendmail.pid"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Silicon Graphics IRIX
|
||||
**
|
||||
@ -239,12 +292,29 @@ extern void hard_syslog(int, char *, ...);
|
||||
** Use IRIX64 instead of IRIX for 64-bit IRIX (6.0).
|
||||
** Use IRIX5 instead of IRIX for IRIX 5.x.
|
||||
**
|
||||
** This version tries to be adaptive using _MIPS_SIM:
|
||||
** _MIPS_SIM == _ABIO32 (= 1) Abi: -32 on IRIX 6.2
|
||||
** _MIPS_SIM == _ABIN32 (= 2) Abi: -n32 on IRIX 6.2
|
||||
** _MIPS_SIM == _ABI64 (= 3) Abi: -64 on IRIX 6.2
|
||||
**
|
||||
** _MIPS_SIM is 1 also on IRIX 5.3
|
||||
**
|
||||
** IRIX64 changes from Mark R. Levinson <ml@cvdev.rochester.edu>.
|
||||
** IRIX5 changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>.
|
||||
** Adaptive changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>.
|
||||
*/
|
||||
|
||||
#if defined(IRIX64) || defined(IRIX5)
|
||||
#if defined(__sgi)
|
||||
# ifndef IRIX
|
||||
# define IRIX
|
||||
# endif
|
||||
# if _MIPS_SIM > 0 && !defined(IRIX5)
|
||||
# define IRIX5 /* IRIX5 or IRIX6 */
|
||||
# endif
|
||||
# if _MIPS_SIM > 1 && !defined(IRIX6) && !defined(IRIX64)
|
||||
# define IRIX6 /* IRIX6 */
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IRIX
|
||||
@ -254,18 +324,24 @@ extern void hard_syslog(int, char *, ...);
|
||||
# define HASFCHMOD 1 /* has fchmod(2) syscall */
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define IP_SRCROUTE 1 /* can check IP source routing */
|
||||
# define FORK fork /* no vfork primitive available */
|
||||
# define setpgid BSDsetpgrp
|
||||
# define GIDSET_T gid_t
|
||||
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
|
||||
# define SFS_BAVAIL f_bfree /* alternate field name */
|
||||
# ifdef IRIX6
|
||||
# define LA_TYPE LA_IRIX6 /* figure out at run time */
|
||||
# else
|
||||
# define LA_TYPE LA_INT
|
||||
|
||||
# ifdef IRIX64
|
||||
# define NAMELISTMASK 0x7fffffffffffffff /* mask for nlist() values */
|
||||
# else
|
||||
# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */
|
||||
# endif
|
||||
# endif
|
||||
# if defined(IRIX64) || defined(IRIX5)
|
||||
# include <sys/cdefs.h>
|
||||
# include <paths.h>
|
||||
# define ARGV_T char *const *
|
||||
# define HASSETRLIMIT 1 /* has setrlimit(2) syscall */
|
||||
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) syscall */
|
||||
@ -290,10 +366,16 @@ extern void hard_syslog(int, char *, ...);
|
||||
# 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 */
|
||||
# ifndef LA_TYPE
|
||||
# define LA_TYPE LA_INT
|
||||
# endif
|
||||
|
||||
# ifdef SOLARIS_2_3
|
||||
# define SOLARIS 203 /* for back compat only -- use -DSOLARIS=203 */
|
||||
# define SOLARIS 20300 /* for back compat only -- use -DSOLARIS=20300 */
|
||||
# endif
|
||||
|
||||
# if defined(NOT_SENDMAIL) && !defined(SOLARIS) && defined(sun) && (defined(__svr4__) || defined(__SVR4))
|
||||
# define SOLARIS 1 /* unknown Solaris version */
|
||||
# endif
|
||||
|
||||
# ifdef SOLARIS
|
||||
@ -303,6 +385,7 @@ extern void hard_syslog(int, char *, ...);
|
||||
# endif
|
||||
# include <sys/time.h>
|
||||
# define GIDSET_T gid_t
|
||||
# define USE_SA_SIGACTION 1 /* use sa_sigaction field */
|
||||
# ifndef _PATH_UNIX
|
||||
# define _PATH_UNIX "/dev/ksyms"
|
||||
# endif
|
||||
@ -316,6 +399,20 @@ extern void hard_syslog(int, char *, ...);
|
||||
# ifndef SYSLOG_BUFSIZE
|
||||
# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
|
||||
# endif
|
||||
# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203)
|
||||
# define USESETEUID 1 /* seteuid works as of 2.3 */
|
||||
# endif
|
||||
# if SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205)
|
||||
# define HASSNPRINTF 1 /* has snprintf starting in 2.5 */
|
||||
# define HASSETREUID 1 /* setreuid works as of 2.5 */
|
||||
# if SOLARIS == 20500 || SOLARIS == 205
|
||||
# define snprintf __snprintf /* but names it oddly in 2.5 */
|
||||
# define vsnprintf __vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# ifndef HASGETUSERSHELL
|
||||
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
|
||||
# endif
|
||||
|
||||
# else
|
||||
/* SunOS 4.0.3 or 4.1.x */
|
||||
@ -432,8 +529,6 @@ extern long dgux_inet_addr();
|
||||
|
||||
#ifdef __ksr__
|
||||
# define __osf__ 1 /* get OSF/1 defines below */
|
||||
# define FORK fork /* no vfork primitive available */
|
||||
# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
|
||||
# ifndef TZ_TYPE
|
||||
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
|
||||
# endif
|
||||
@ -449,12 +544,16 @@ extern long dgux_inet_addr();
|
||||
|
||||
#ifdef __PARAGON__
|
||||
# define __osf__ 1 /* get OSF/1 defines below */
|
||||
# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
|
||||
# ifndef TZ_TYPE
|
||||
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** OSF/1 (tested on Alpha)
|
||||
** OSF/1 (tested on Alpha) -- now known as Digital UNIX.
|
||||
**
|
||||
** Tested for 3.2 and 4.0.
|
||||
*/
|
||||
|
||||
#ifdef __osf__
|
||||
@ -468,6 +567,7 @@ extern long dgux_inet_addr();
|
||||
# endif
|
||||
# define LA_TYPE LA_INT
|
||||
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
|
||||
# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
|
||||
# ifndef _PATH_SENDMAILPID
|
||||
# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
|
||||
# endif
|
||||
@ -487,6 +587,7 @@ extern long dgux_inet_addr();
|
||||
# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
|
||||
# define WAITUNION 1 /* use "union wait" as wait argument type */
|
||||
# define UID_T int /* compiler gripes on uid_t */
|
||||
# define GID_T int /* ditto for gid_t */
|
||||
# define sleep sleepX
|
||||
# define setpgid setpgrp
|
||||
# ifndef LA_TYPE
|
||||
@ -512,6 +613,7 @@ typedef int pid_t;
|
||||
*/
|
||||
|
||||
#if defined(BSD4_4) && !defined(__bsdi__)
|
||||
# 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 */
|
||||
@ -529,11 +631,12 @@ typedef int pid_t;
|
||||
|
||||
|
||||
/*
|
||||
** BSD/386 (all versions)
|
||||
** BSD/OS (was BSD/386) (all versions)
|
||||
** From Tony Sanders, BSDI
|
||||
*/
|
||||
|
||||
#ifdef __bsdi__
|
||||
# include <paths.h>
|
||||
# define HASUNSETENV 1 /* has the unsetenv(3) call */
|
||||
# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
|
||||
# define USESETEUID 1 /* has useable seteuid(2) call */
|
||||
@ -592,15 +695,14 @@ typedef int pid_t;
|
||||
# if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1)
|
||||
# undef SPT_TYPE
|
||||
# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */
|
||||
# define setreuid __setreuid
|
||||
# endif
|
||||
# if defined(__FreeBSD__)
|
||||
# undef SPT_TYPE
|
||||
# if __FreeBSD__ == 2
|
||||
# include <osreldate.h> /* and this works */
|
||||
# if __FreeBSD_version >= 199512 /* 2.2-current right now */
|
||||
# define SPT_TYPE SPT_BUILTIN
|
||||
# include <libutil.h>
|
||||
# define SPT_TYPE SPT_BUILTIN
|
||||
# endif
|
||||
# endif
|
||||
# ifndef SPT_TYPE
|
||||
@ -611,6 +713,7 @@ typedef int pid_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Mach386
|
||||
**
|
||||
@ -672,38 +775,65 @@ extern int errno;
|
||||
/*
|
||||
** SCO Unix
|
||||
**
|
||||
** This includes two parts -- the first is for SCO Open Server 3.2v4
|
||||
** (contributed by Philippe Brand <phb@colombo.telesys-innov.fr>).
|
||||
** The second is, I believe, for an older version.
|
||||
** This includes three parts:
|
||||
**
|
||||
** The first is for SCO OpenServer 5.
|
||||
** (Contributed by Keith Reynolds <keithr@sco.COM>).
|
||||
**
|
||||
** SCO OpenServer 5 has a compiler version number macro,
|
||||
** which we can use to figure out what version we're on.
|
||||
** This may have to change in future releases.
|
||||
**
|
||||
** The second is for SCO UNIX 3.2v4.2/Open Desktop 3.0.
|
||||
** (Contributed by Philippe Brand <phb@colombo.telesys-innov.fr>).
|
||||
**
|
||||
** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier.
|
||||
*/
|
||||
|
||||
#if _SCO_DS >= 1
|
||||
# include <paths.h>
|
||||
# define _SCO_unix_4_2
|
||||
# define HASSNPRINTF 1 /* has snprintf() call */
|
||||
# define HASFCHMOD 1 /* has fchmod() call */
|
||||
# define HASSETRLIMIT 1 /* has setrlimit() call */
|
||||
# define RLIMIT_NEEDS_SYS_TIME_H 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _SCO_unix_4_2
|
||||
# define _SCO_unix_
|
||||
# define HASSETREUID 1 /* has setreuid(2) call */
|
||||
# define _PATH_UNIX "/unix"
|
||||
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
|
||||
# ifndef _PATH_SENDMAILPID
|
||||
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _SCO_unix_
|
||||
# include <sys/stream.h> /* needed for IP_SRCROUTE */
|
||||
# define SYSTEM5 1 /* include all the System V defines */
|
||||
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */
|
||||
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
|
||||
# define FORK fork
|
||||
# define MAXPATHLEN PATHSIZE
|
||||
# define LA_TYPE LA_SHORT
|
||||
# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */
|
||||
# define SFS_BAVAIL f_bfree /* alternate field name */
|
||||
# define SPT_TYPE SPT_SCO /* write kernel u. area */
|
||||
# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */
|
||||
# define _PATH_UNIX "/unix"
|
||||
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
|
||||
# ifndef _PATH_SENDMAILPID
|
||||
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
|
||||
# endif
|
||||
|
||||
/* stuff fixed in later releases */
|
||||
# ifndef _SCO_unix_4_2
|
||||
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
|
||||
# endif
|
||||
|
||||
# ifndef _SCO_DS
|
||||
# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */
|
||||
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
|
||||
# define NETUNIX 0 /* no unix domain socket support */
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** ISC (SunSoft) Unix.
|
||||
@ -721,7 +851,6 @@ extern int errno;
|
||||
# define HASSETREUID 1 /* has setreuid(2) call */
|
||||
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
|
||||
# define NETUNIX 0 /* no unix domain socket support */
|
||||
# define FORK fork
|
||||
# define MAXPATHLEN 1024
|
||||
# define LA_TYPE LA_SHORT
|
||||
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
|
||||
@ -736,22 +865,24 @@ extern int errno;
|
||||
|
||||
|
||||
/*
|
||||
** Altos System V.
|
||||
** Contributed by Tim Rice <timr@crl.com>.
|
||||
** Altos System V (5.3.1)
|
||||
** Contributed by Tim Rice <tim@trr.metro.net>.
|
||||
*/
|
||||
|
||||
#ifdef ALTOS_SYS_V
|
||||
#ifdef ALTOS_SYSTEM_V
|
||||
# include <sys/stream.h>
|
||||
# include <limits.h>
|
||||
# define SYSTEM5 1 /* include all the System V defines */
|
||||
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define WAITUNION 1 /* use "union wait" as wait argument type */
|
||||
# define NEEDFSYNC 1 /* no fsync(2) in system library */
|
||||
# define FORK fork
|
||||
# define MAXPATHLEN PATHSIZE
|
||||
# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# define LA_TYPE LA_SHORT
|
||||
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
|
||||
# define SFS_BAVAIL f_bfree /* alternate field name */
|
||||
# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */
|
||||
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
|
||||
# define NETUNIX 0 /* no unix domain socket support */
|
||||
# undef WIFEXITED
|
||||
# undef WEXITSTATUS
|
||||
@ -760,6 +891,17 @@ extern int errno;
|
||||
typedef unsigned short uid_t;
|
||||
typedef unsigned short gid_t;
|
||||
typedef short pid_t;
|
||||
|
||||
/* some stuff that should have been in the include files */
|
||||
# include <grp.h>
|
||||
extern char *malloc();
|
||||
extern struct passwd *getpwent();
|
||||
extern struct passwd *getpwnam();
|
||||
extern struct passwd *getpwuid();
|
||||
extern char *getenv();
|
||||
extern struct group *getgrgid();
|
||||
extern struct group *getgrnam();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -768,13 +910,26 @@ typedef short pid_t;
|
||||
**
|
||||
** "Todd C. Miller" <millert@mroe.cs.colorado.edu> claims this
|
||||
** works on 9.1 as well.
|
||||
**
|
||||
** ConvexOS 11.5 and later, should work on 11.0 as defined.
|
||||
** For pre-ConvexOOS 11.0, define NEEDGETOPT, undef IDENTPROTO
|
||||
**
|
||||
** Eric Schnoebelen (eric@cirr.com) For CONVEX Computer Corp.
|
||||
** (now the CONVEX Technologies Center of Hewlett Packard)
|
||||
*/
|
||||
|
||||
#ifdef _CONVEX_SOURCE
|
||||
# define BSD 1 /* include all the BSD defines */
|
||||
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) */
|
||||
# define HASINITGROUPS 1 /* has initgroups(3) */
|
||||
# define HASUNAME 1 /* use System V uname(2) system call */
|
||||
# define HASSETSID 1 /* has POSIX setsid(2) call */
|
||||
# define NEEDGETOPT 1 /* need replacement for getopt(3) */
|
||||
# define HASUNSETENV 1 /* has unsetenv(3) */
|
||||
# define HASFLOCK 1 /* has flock(2) */
|
||||
# define HASSETRLIMIT 1 /* has setrlimit(2) */
|
||||
# define HASSETREUID 1 /* has setreuid(2) */
|
||||
# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_error=0 */
|
||||
# define NEEDPUTENV 1 /* needs putenv (written in terms of setenv) */
|
||||
# define NEEDGETOPT 0 /* need replacement for getopt(3) */
|
||||
# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
|
||||
# define LA_TYPE LA_FLOAT
|
||||
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
|
||||
@ -787,8 +942,23 @@ typedef short pid_t;
|
||||
# define S_IFCHR _S_IFCHR
|
||||
# define S_IFBLK _S_IFBLK
|
||||
# endif
|
||||
# ifndef TZ_TYPE
|
||||
# define TZ_TYPE TZ_TIMEZONE
|
||||
# endif
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# define IDENTPROTO 1
|
||||
# endif
|
||||
# ifndef SHARE_V1
|
||||
# define SHARE_V1 1 /* version 1 of the fair share scheduler */
|
||||
# endif
|
||||
# if !defined(__GNUC__ )
|
||||
# define UID_T int /* GNUC gets it right, ConvexC botches */
|
||||
# define GID_T int /* GNUC gets it right, ConvexC botches */
|
||||
# endif
|
||||
# if SECUREWARE
|
||||
# define FORK fork /* SecureWare wants the real fork! */
|
||||
# else
|
||||
# define FORK vfork /* the rest of the OS versions don't care */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -839,9 +1009,14 @@ extern void *malloc();
|
||||
** Florian La Roche <rzsfl@rz.uni-sb.de>
|
||||
** Karl London <karl@borg.demon.co.uk>
|
||||
**
|
||||
** Last compiled against: [09/06/95 @ 10:20:58 AM (Wednesday)]
|
||||
** sendmail 8.7-b14 named 4.9.3-beta17 db-1.85
|
||||
** gcc 2.7.0 libc-5.2.7 linux 1.2.13
|
||||
** Last compiled against: [06/10/96 @ 09:21:40 PM (Monday)]
|
||||
** sendmail 8.8-a4 named bind-4.9.4-T4B db-1.85
|
||||
** gcc 2.7.2 libc-5.3.12 linux 2.0.0
|
||||
**
|
||||
** NOTE: Override HASFLOCK as you will but, as of 1.99.6, mixed-style
|
||||
** file locking is no longer allowed. In particular, make sure
|
||||
** your DBM library and sendmail are both using either flock(2)
|
||||
** *or* fcntl(2) file locking, but not both.
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
@ -857,7 +1032,12 @@ extern void *malloc();
|
||||
# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */
|
||||
# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */
|
||||
# ifndef HASFLOCK
|
||||
# include <linux/version.h>
|
||||
# if LINUX_VERSION_CODE < 66399
|
||||
# define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */
|
||||
# else
|
||||
# define HASFLOCK 1 /* flock(2) fixed after 1.3.95 */
|
||||
# endif
|
||||
# endif
|
||||
# ifndef LA_TYPE
|
||||
# define LA_TYPE LA_PROCSTR
|
||||
@ -907,7 +1087,6 @@ extern void *malloc();
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# endif
|
||||
# define FORK fork
|
||||
# ifndef LA_TYPE
|
||||
# define LA_TYPE LA_INT
|
||||
# define FSHIFT 16
|
||||
@ -937,7 +1116,6 @@ extern void *malloc();
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
|
||||
# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */
|
||||
# define FORK fork /* no vfork(2) primitive available */
|
||||
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
extern struct passwd *getpwent(), *getpwnam(), *getpwuid();
|
||||
@ -1010,9 +1188,12 @@ typedef int pid_t;
|
||||
** For DYNIX/ptx v1.x, undefine HASSETREUID.
|
||||
**
|
||||
** From Tim Wright <timw@sequent.com>.
|
||||
** Update from Jack Woolley <jwoolley@sctcorp.com>, 26 Dec 1995,
|
||||
** for DYNIX/ptx 4.0.2.
|
||||
*/
|
||||
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/stream.h>
|
||||
# define SYSTEM5 1 /* include all the System V defines */
|
||||
# define HASSETSID 1 /* has POSIX setsid(2) call */
|
||||
# define HASINITGROUPS 1 /* has initgroups(3) call */
|
||||
@ -1076,6 +1257,7 @@ typedef int pid_t;
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# endif
|
||||
# define RLIMIT_NEEDS_SYS_TIME_H 1
|
||||
#endif
|
||||
|
||||
|
||||
@ -1138,18 +1320,30 @@ typedef int pid_t;
|
||||
|
||||
|
||||
/*
|
||||
** NCR 3000 Series (SysVr4)
|
||||
** NCR MP-RAS 2.x (SysVr4) with Wollongong TCP/IP
|
||||
**
|
||||
** From Kevin Darcy <kevin@tech.mis.cfc.com>.
|
||||
*/
|
||||
|
||||
#ifdef NCR3000
|
||||
#ifdef NCR_MP_RAS2
|
||||
# include <sys/sockio.h>
|
||||
# define __svr4__
|
||||
# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
|
||||
# undef BSD
|
||||
# define LA_AVENRUN "avenrun"
|
||||
# define SYSLOG_BUFSIZE 1024
|
||||
# define SPT_TYPE SPT_NONE
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** NCR MP-RAS 3.x (SysVr4) with STREAMware TCP/IP
|
||||
**
|
||||
** From Tom Moore <Tom.Moore@DaytonOH.NCR.COM>
|
||||
*/
|
||||
|
||||
#ifdef NCR_MP_RAS3
|
||||
# define __svr4__
|
||||
# define SYSLOG_BUFSIZE 1024
|
||||
# define SPT_TYPE SPT_NONE
|
||||
#endif
|
||||
|
||||
|
||||
@ -1372,20 +1566,75 @@ extern int errno;
|
||||
** Fujitsu/ICL UXP/DS (For the DS/90 Series)
|
||||
**
|
||||
** From Diego R. Lopez <drlopez@cica.es>.
|
||||
** Additional changes from Fumio Moriya and Toshiaki Nomura of the
|
||||
** Fujitsu Fresoftware gruop <dsfrsoft@oai6.yk.fujitsu.co.jp>.
|
||||
*/
|
||||
|
||||
#ifdef UXPDS
|
||||
#ifdef __uxp__
|
||||
# include <arpa/nameser.h>
|
||||
# include <sys/sysmacros.h>
|
||||
# include <sys/mkdev.h>
|
||||
# define __svr4__
|
||||
# define HASGETUSERSHELL 1
|
||||
# define HASGETUSERSHELL 0
|
||||
# define HASFLOCK 0
|
||||
# if UXPDS == 10
|
||||
# define HASSNPRINTF 0 /* no snprintf(3) or vsnprintf(3) */
|
||||
# else
|
||||
# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
|
||||
# endif
|
||||
# define _PATH_UNIX "/stand/unix"
|
||||
# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
|
||||
# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
|
||||
# ifndef _PATH_SENDMAILPID
|
||||
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
|
||||
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Pyramid DC/OSx
|
||||
**
|
||||
** From Earle Ake <akee@wpdis01.wpafb.af.mil>.
|
||||
*/
|
||||
|
||||
#ifdef DCOSx
|
||||
# define GIDSET_T gid_t
|
||||
# ifndef IDENTPROTO
|
||||
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Concurrent Computer Corporation Maxion
|
||||
**
|
||||
** From Donald R. Laster Jr. <laster@access.digex.net>.
|
||||
*/
|
||||
|
||||
#ifdef __MAXION__
|
||||
|
||||
# include <sys/stream.h>
|
||||
# define __svr4__ 1 /* SVR4.2MP */
|
||||
# define HASSETREUID 1 /* have setreuid(2) */
|
||||
# define HASLSTAT 1 /* have lstat(2) */
|
||||
# define HASSETRLIMIT 1 /* have setrlimit(2) */
|
||||
# define HASGETDTABLESIZE 1 /* have getdtablesize(2) */
|
||||
# define HASSNPRINTF 1 /* have snprintf(3) */
|
||||
# define HASGETUSERSHELL 1 /* have getusershell(3) */
|
||||
# define NOFTRUNCATE 1 /* do not have ftruncate(2) */
|
||||
# define SLEEP_T unsigned
|
||||
# define SFS_TYPE SFS_STATVFS
|
||||
# define SFS_BAVAIL f_bavail
|
||||
# ifndef SYSLOG_BUFSIZE
|
||||
# define SYSLOG_BUFSIZE 256 /* Use 256 bytes */
|
||||
# endif
|
||||
|
||||
# undef WUNTRACED
|
||||
# undef WIFEXITED
|
||||
# undef WIFSIGNALED
|
||||
# undef WIFSTOPPED
|
||||
# undef WEXITSTATUS
|
||||
# undef WTERMSIG
|
||||
# undef WSTOPSIG
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
** End of Per-Operating System defines
|
||||
@ -1425,6 +1674,9 @@ extern int errno;
|
||||
# ifndef HASGETUSERSHELL
|
||||
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
|
||||
# endif
|
||||
# ifndef HASFCHMOD
|
||||
# define HASFCHMOD 1 /* most (all?) SVr4s seem to have fchmod(2) */
|
||||
# endif
|
||||
|
||||
# ifndef _PATH_UNIX
|
||||
# define _PATH_UNIX "/unix"
|
||||
@ -1442,6 +1694,7 @@ extern int errno;
|
||||
# define SFS_TYPE SFS_STATVFS
|
||||
# endif
|
||||
|
||||
/* SVr4 uses different routines for setjmp/longjmp with signal support */
|
||||
# define jmp_buf sigjmp_buf
|
||||
# define setjmp(env) sigsetjmp(env, 1)
|
||||
# define longjmp(env, val) siglongjmp(env, val)
|
||||
@ -1499,7 +1752,7 @@ extern int errno;
|
||||
# undef bcopy /* despite SystemV claim, uses BSD bcopy */
|
||||
#endif
|
||||
|
||||
#ifdef ALTOS_SYS_V
|
||||
#ifdef ALTOS_SYSTEM_V
|
||||
# undef bcopy /* despite SystemV claim, uses BSD bcopy */
|
||||
# undef bzero /* despite SystemV claim, uses BSD bzero */
|
||||
# undef bcmp /* despite SystemV claim, uses BSD bcmp */
|
||||
@ -1561,6 +1814,10 @@ extern int errno;
|
||||
# define OLD_NEWDB 0 /* assume newer version of newdb */
|
||||
#endif
|
||||
|
||||
#ifndef SECUREWARE
|
||||
# define SECUREWARE 0 /* assume no SecureWare C2 auditing hooks */
|
||||
#endif
|
||||
|
||||
/* heuristic setting of HASSETSIGMASK; can override above */
|
||||
#ifndef HASSIGSETMASK
|
||||
# ifdef SIGVTALRM
|
||||
@ -1584,6 +1841,10 @@ extern int errno;
|
||||
# define UID_T uid_t
|
||||
#endif
|
||||
|
||||
#ifndef GID_T
|
||||
# define GID_T gid_t
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_T
|
||||
# define SIZE_T size_t
|
||||
#endif
|
||||
@ -1601,6 +1862,9 @@ extern int errno;
|
||||
#ifndef S_ISREG
|
||||
# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(foo) ((foo & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISLNK) && defined(S_IFLNK)
|
||||
# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
@ -1729,7 +1993,7 @@ struct utsname
|
||||
};
|
||||
#endif /* HASUNAME */
|
||||
|
||||
#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYS_V)
|
||||
#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V)
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
@ -1809,9 +2073,10 @@ typedef void (*sigfunc_t) __P((int));
|
||||
*/
|
||||
|
||||
# define PSBUFSIZE (MAXNAME + MAXATOM) /* size of prescan buffer */
|
||||
|
||||
/* fork routine -- set above using #ifdef _osname_ or in Makefile */
|
||||
# ifndef FORK
|
||||
# define FORK vfork /* function to call to fork mailer */
|
||||
# define FORK fork /* function to call to fork mailer */
|
||||
# endif
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -37,9 +37,9 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifdef DAEMON
|
||||
static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (with daemon mode)";
|
||||
static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemon mode)";
|
||||
static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -70,7 +70,7 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
|
||||
** thing yourself, I recommend chucking the entire file
|
||||
** and starting from scratch. Basic semantics are:
|
||||
**
|
||||
** getrequests()
|
||||
** getrequests(e)
|
||||
** Opens a port and initiates a connection.
|
||||
** Returns in a child. Must set InChannel and
|
||||
** OutChannel appropriately.
|
||||
@ -80,7 +80,7 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
|
||||
** etc., to avoid having extra file descriptors during
|
||||
** the queue run and to avoid confusing the network
|
||||
** code (if it cares).
|
||||
** makeconnection(host, port, outfile, infile, usesecureport)
|
||||
** makeconnection(host, port, outfile, infile, e)
|
||||
** Make a connection to the named host on the given
|
||||
** port. Set *outfile and *infile to the files
|
||||
** appropriate for communication. Returns zero on
|
||||
@ -93,10 +93,12 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
|
||||
** GETREQUESTS -- open mail IPC port and get requests.
|
||||
**
|
||||
** Parameters:
|
||||
** none.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
** TRUE -- if a "null server" should be used -- that is, one
|
||||
** that rejects all commands.
|
||||
** FALSE -- to use a normal server.
|
||||
**
|
||||
** Side Effects:
|
||||
** Waits until some interesting activity occurs. When
|
||||
@ -113,8 +115,9 @@ int ListenQueueSize = 10; /* size of listen queue */
|
||||
int TcpRcvBufferSize = 0; /* size of TCP receive buffer */
|
||||
int TcpSndBufferSize = 0; /* size of TCP send buffer */
|
||||
|
||||
void
|
||||
getrequests()
|
||||
bool
|
||||
getrequests(e)
|
||||
ENVELOPE *e;
|
||||
{
|
||||
int t;
|
||||
bool refusingconnections = TRUE;
|
||||
@ -124,6 +127,7 @@ getrequests()
|
||||
bool j_has_dot;
|
||||
#endif
|
||||
extern void reapchild();
|
||||
extern int opendaemonsocket __P((bool));
|
||||
|
||||
/*
|
||||
** Set up the address for the mailer.
|
||||
@ -166,7 +170,7 @@ getrequests()
|
||||
extern char *CommandLineArgs;
|
||||
|
||||
/* write the process id on line 1 */
|
||||
fprintf(pidf, "%d\n", getpid());
|
||||
fprintf(pidf, "%ld\n", (long) getpid());
|
||||
|
||||
/* line 2 contains all command line flags */
|
||||
fprintf(pidf, "%s\n", CommandLineArgs);
|
||||
@ -179,7 +183,7 @@ getrequests()
|
||||
{
|
||||
char jbuf[MAXHOSTNAMELEN];
|
||||
|
||||
expand("\201j", jbuf, sizeof jbuf, CurEnv);
|
||||
expand("\201j", jbuf, sizeof jbuf, e);
|
||||
j_has_dot = strchr(jbuf, '.') != NULL;
|
||||
}
|
||||
#endif
|
||||
@ -195,8 +199,7 @@ getrequests()
|
||||
extern int getla();
|
||||
|
||||
/* see if we are rejecting connections */
|
||||
CurrentLA = getla();
|
||||
if (refuseconnections())
|
||||
if (refuseconnections(ntohs(DaemonAddr.sin.sin_port)))
|
||||
{
|
||||
if (DaemonSocket >= 0)
|
||||
{
|
||||
@ -220,8 +223,9 @@ getrequests()
|
||||
/* check for disaster */
|
||||
{
|
||||
char jbuf[MAXHOSTNAMELEN];
|
||||
extern void dumpstate __P((char *));
|
||||
|
||||
expand("\201j", jbuf, sizeof jbuf, CurEnv);
|
||||
expand("\201j", jbuf, sizeof jbuf, e);
|
||||
if (!wordinclass(jbuf, 'w'))
|
||||
{
|
||||
dumpstate("daemon lost $j");
|
||||
@ -238,7 +242,8 @@ getrequests()
|
||||
#endif
|
||||
|
||||
/* wait for a connection */
|
||||
setproctitle("accepting connections");
|
||||
setproctitle("accepting connections on port %d",
|
||||
ntohs(DaemonAddr.sin.sin_port));
|
||||
do
|
||||
{
|
||||
errno = 0;
|
||||
@ -277,9 +282,9 @@ getrequests()
|
||||
if (pid == 0)
|
||||
{
|
||||
char *p;
|
||||
extern char *hostnamebyanyaddr();
|
||||
extern void intsig();
|
||||
FILE *inchannel, *outchannel;
|
||||
bool nullconn;
|
||||
|
||||
/*
|
||||
** CHILD -- return to caller.
|
||||
@ -296,7 +301,7 @@ getrequests()
|
||||
|
||||
/* determine host name */
|
||||
p = hostnamebyanyaddr(&RealHostAddr);
|
||||
if (strlen(p) > MAXNAME)
|
||||
if (strlen(p) > (SIZE_T) MAXNAME)
|
||||
p[MAXNAME] = '\0';
|
||||
RealHostName = newstr(p);
|
||||
setproctitle("startup with %s", p);
|
||||
@ -313,7 +318,13 @@ getrequests()
|
||||
OutChannel = outchannel;
|
||||
DisConnected = FALSE;
|
||||
|
||||
/* should we check for illegal connection here? XXX */
|
||||
/* validate the connection */
|
||||
HoldErrs = TRUE;
|
||||
nullconn = !validate_connection(&RealHostAddr, RealHostName, e);
|
||||
HoldErrs = FALSE;
|
||||
if (nullconn)
|
||||
break;
|
||||
|
||||
#ifdef XLA
|
||||
if (!xla_host_ok(RealHostName))
|
||||
{
|
||||
@ -323,16 +334,19 @@ getrequests()
|
||||
#endif
|
||||
|
||||
if (tTd(15, 2))
|
||||
printf("getreq: returning\n");
|
||||
return;
|
||||
printf("getreq: returning (normal server)\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurChildren++;
|
||||
/* parent -- keep track of children */
|
||||
proc_list_add(pid);
|
||||
|
||||
/* close the port so that others will hang (for a while) */
|
||||
(void) close(t);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
if (tTd(15, 2))
|
||||
printf("getreq: returning (null server)\n");
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
** OPENDAEMONSOCKET -- open the SMTP socket
|
||||
@ -446,6 +460,7 @@ opendaemonsocket(firsttime)
|
||||
} while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
|
||||
syserr("!opendaemonsocket: server SMTP socket wedged: exiting");
|
||||
finis();
|
||||
return -1; /* avoid compiler warning on IRIX */
|
||||
}
|
||||
/*
|
||||
** CLRDAEMON -- reset the daemon connection
|
||||
@ -536,16 +551,16 @@ setdaemonoptions(p)
|
||||
#if NETINET
|
||||
case AF_INET:
|
||||
if (isascii(*v) && isdigit(*v))
|
||||
DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v));
|
||||
DaemonAddr.sin.sin_addr.s_addr = inet_addr(v);
|
||||
else
|
||||
{
|
||||
register struct netent *np;
|
||||
register struct hostent *hp;
|
||||
|
||||
np = getnetbyname(v);
|
||||
if (np == NULL)
|
||||
syserr("554 network \"%s\" unknown", v);
|
||||
hp = sm_gethostbyname(v);
|
||||
if (hp == NULL)
|
||||
syserr("554 host \"%s\" unknown", v);
|
||||
else
|
||||
DaemonAddr.sin.sin_addr.s_addr = np->n_net;
|
||||
bcopy(hp->h_addr, &DaemonAddr.sin.sin_addr, INADDRSZ);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -630,8 +645,7 @@ setdaemonoptions(p)
|
||||
** port -- the port number to connect to.
|
||||
** mci -- a pointer to the mail connection information
|
||||
** structure to be filled in.
|
||||
** usesecureport -- if set, use a low numbered (reserved)
|
||||
** port to provide some rudimentary authentication.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** An exit code telling whether the connection could be
|
||||
@ -653,11 +667,11 @@ connecttimeout()
|
||||
SOCKADDR CurHostAddr; /* address of current host */
|
||||
|
||||
int
|
||||
makeconnection(host, port, mci, usesecureport)
|
||||
makeconnection(host, port, mci, e)
|
||||
char *host;
|
||||
u_short port;
|
||||
register MCI *mci;
|
||||
bool usesecureport;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
register int i = 0;
|
||||
register int s;
|
||||
@ -691,7 +705,7 @@ makeconnection(host, port, mci, usesecureport)
|
||||
*p = '\0';
|
||||
#if NETINET
|
||||
hid = inet_addr(&host[1]);
|
||||
if (hid == -1)
|
||||
if (hid == INADDR_NONE)
|
||||
#endif
|
||||
{
|
||||
/* try it as a host name (avoid MX lookup) */
|
||||
@ -717,8 +731,11 @@ makeconnection(host, port, mci, usesecureport)
|
||||
}
|
||||
if (p == NULL)
|
||||
{
|
||||
extern char MsgBuf[];
|
||||
|
||||
usrerr("553 Invalid numeric domain spec \"%s\"", host);
|
||||
mci->mci_status = "5.1.2";
|
||||
mci->mci_rstatus = newstr(MsgBuf);
|
||||
return (EX_NOHOST);
|
||||
}
|
||||
#if NETINET
|
||||
@ -727,6 +744,8 @@ makeconnection(host, port, mci, usesecureport)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* contortion to get around SGI cc complaints */
|
||||
{
|
||||
register char *p = &host[strlen(host) - 1];
|
||||
|
||||
@ -745,6 +764,7 @@ makeconnection(host, port, mci, usesecureport)
|
||||
_res.options = oldopts;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
gothostent:
|
||||
if (hp == NULL)
|
||||
{
|
||||
@ -754,6 +774,7 @@ makeconnection(host, port, mci, usesecureport)
|
||||
(errno == ECONNREFUSED && UseNameServer))
|
||||
{
|
||||
mci->mci_status = "4.4.3";
|
||||
mci->mci_rstatus = NULL;
|
||||
return (EX_TEMPFAIL);
|
||||
}
|
||||
#endif
|
||||
@ -841,7 +862,7 @@ makeconnection(host, port, mci, usesecureport)
|
||||
/* save for logging */
|
||||
CurHostAddr = addr;
|
||||
|
||||
if (usesecureport)
|
||||
if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags))
|
||||
{
|
||||
int rport = IPPORT_RESERVED - 1;
|
||||
|
||||
@ -878,8 +899,8 @@ makeconnection(host, port, mci, usesecureport)
|
||||
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
|
||||
(char *)&on, sizeof on);
|
||||
}
|
||||
if (CurEnv->e_xfp != NULL)
|
||||
(void) fflush(CurEnv->e_xfp); /* for debugging */
|
||||
if (e->e_xfp != NULL)
|
||||
(void) fflush(e->e_xfp); /* for debugging */
|
||||
errno = 0; /* for debugging */
|
||||
|
||||
/*
|
||||
@ -889,10 +910,12 @@ makeconnection(host, port, mci, usesecureport)
|
||||
|
||||
if (setjmp(CtxConnectTimeout) == 0)
|
||||
{
|
||||
if (TimeOuts.to_connect == 0)
|
||||
ev = NULL;
|
||||
else
|
||||
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)
|
||||
@ -986,7 +1009,6 @@ myhostname(hostbuf, size)
|
||||
int size;
|
||||
{
|
||||
register struct hostent *hp;
|
||||
extern bool getcanonname();
|
||||
|
||||
if (gethostname(hostbuf, size) < 0)
|
||||
{
|
||||
@ -1087,7 +1109,6 @@ getauthinfo(fd)
|
||||
int nleft;
|
||||
char ibuf[MAXNAME + 1];
|
||||
static char hbuf[MAXNAME * 2 + 2];
|
||||
extern char *hostnamebyanyaddr();
|
||||
|
||||
falen = sizeof RealHostAddr;
|
||||
if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 ||
|
||||
@ -1104,6 +1125,8 @@ getauthinfo(fd)
|
||||
{
|
||||
/* translate that to a host name */
|
||||
RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
|
||||
if (strlen(RealHostName) > MAXNAME)
|
||||
RealHostName[MAXNAME - 1] = '\0';
|
||||
}
|
||||
|
||||
if (TimeOuts.to_ident == 0)
|
||||
@ -1170,6 +1193,9 @@ getauthinfo(fd)
|
||||
{
|
||||
p += i;
|
||||
nleft -= i;
|
||||
*p = '\0';
|
||||
if (strchr(ibuf, '\n') != NULL)
|
||||
break;
|
||||
}
|
||||
(void) close(s);
|
||||
clrevent(ev);
|
||||
@ -1207,14 +1233,6 @@ getauthinfo(fd)
|
||||
}
|
||||
|
||||
/* p now points to the OSTYPE field */
|
||||
while (isascii(*p) && isspace(*p))
|
||||
p++;
|
||||
if (strncasecmp(p, "other", 5) == 0 &&
|
||||
(p[5] == ':' || p[5] == ' ' || p[5] == ',' || p[5] == '\0'))
|
||||
{
|
||||
/* not useful information */
|
||||
goto noident;
|
||||
}
|
||||
p = strchr(p, ':');
|
||||
if (p == NULL)
|
||||
{
|
||||
@ -1432,25 +1450,28 @@ host_map_lookup(map, name, av, statp)
|
||||
|
||||
if (*name != '[')
|
||||
{
|
||||
extern bool getcanonname();
|
||||
|
||||
if (tTd(9, 1))
|
||||
printf("host_map_lookup(%s) => ", name);
|
||||
s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
|
||||
if (strlen(name) < sizeof hbuf)
|
||||
snprintf(hbuf, sizeof hbuf, "%s", name);
|
||||
if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX))
|
||||
{
|
||||
if (tTd(9, 1))
|
||||
printf("%s\n", hbuf);
|
||||
if (bitset(MF_MATCHONLY, map->map_mflags))
|
||||
{
|
||||
cp = map_rewrite(map, name, strlen(name), av);
|
||||
s->s_namecanon.nc_cname = newstr(hbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
cp = map_rewrite(map, hbuf, strlen(hbuf), av);
|
||||
s->s_namecanon.nc_cname = newstr(cp);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
register struct hostent *hp;
|
||||
|
||||
s->s_namecanon.nc_errno = errno;
|
||||
#if NAMED_BIND
|
||||
s->s_namecanon.nc_herrno = h_errno;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 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.185.1.2 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "sendmail.h"
|
||||
@ -69,7 +69,7 @@ extern char SmtpError[];
|
||||
void
|
||||
sendall(e, mode)
|
||||
ENVELOPE *e;
|
||||
char mode;
|
||||
int mode;
|
||||
{
|
||||
register ADDRESS *q;
|
||||
char *owner;
|
||||
@ -125,6 +125,8 @@ sendall(e, mode)
|
||||
*/
|
||||
|
||||
CurEnv = e;
|
||||
if (tTd(62, 1))
|
||||
checkfds(NULL);
|
||||
|
||||
if (e->e_hopcount > MaxHopCount)
|
||||
{
|
||||
@ -184,12 +186,21 @@ sendall(e, mode)
|
||||
q->q_owner = NULL;
|
||||
}
|
||||
|
||||
if (tTd(13, 25))
|
||||
{
|
||||
printf("\nAfter first owner pass, sendq =\n");
|
||||
printaddr(e->e_sendqueue, TRUE);
|
||||
}
|
||||
|
||||
owner = "";
|
||||
otherowners = 1;
|
||||
while (owner != NULL && otherowners > 0)
|
||||
{
|
||||
if (tTd(13, 28))
|
||||
printf("owner = \"%s\", otherowners = %d\n",
|
||||
owner, otherowners);
|
||||
owner = NULL;
|
||||
otherowners = 0;
|
||||
otherowners = bitset(EF_SENDRECEIPT, e->e_flags) ? 1 : 0;
|
||||
|
||||
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
|
||||
{
|
||||
@ -204,27 +215,49 @@ sendall(e, mode)
|
||||
printf(" ... QDONTSEND\n");
|
||||
continue;
|
||||
}
|
||||
if (tTd(13, 29) && !tTd(13, 30))
|
||||
{
|
||||
printf("Checking ");
|
||||
printaddr(q, FALSE);
|
||||
}
|
||||
|
||||
if (q->q_owner != NULL)
|
||||
{
|
||||
if (owner == NULL)
|
||||
{
|
||||
if (tTd(13, 40))
|
||||
printf(" ... First owner = \"%s\"\n",
|
||||
q->q_owner);
|
||||
owner = q->q_owner;
|
||||
}
|
||||
else if (owner != q->q_owner)
|
||||
{
|
||||
if (strcmp(owner, q->q_owner) == 0)
|
||||
{
|
||||
if (tTd(13, 40))
|
||||
printf(" ... Same owner = \"%s\"\n",
|
||||
owner);
|
||||
|
||||
/* make future comparisons cheap */
|
||||
q->q_owner = owner;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tTd(13, 40))
|
||||
printf(" ... Another owner \"%s\"\n",
|
||||
q->q_owner);
|
||||
otherowners++;
|
||||
}
|
||||
owner = q->q_owner;
|
||||
}
|
||||
else if (tTd(13, 40))
|
||||
printf(" ... Same owner = \"%s\"\n",
|
||||
owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tTd(13, 40))
|
||||
printf(" ... Null owner\n");
|
||||
otherowners++;
|
||||
}
|
||||
|
||||
@ -273,8 +306,8 @@ sendall(e, mode)
|
||||
(void) queuename(ee, '\0');
|
||||
|
||||
if (tTd(13, 1))
|
||||
printf("sendall: split %s into %s\n",
|
||||
e->e_id, ee->e_id);
|
||||
printf("sendall: split %s into %s, owner = \"%s\", otherowners = %d\n",
|
||||
e->e_id, ee->e_id, owner, otherowners);
|
||||
|
||||
ee->e_header = copyheader(e->e_header);
|
||||
ee->e_sendqueue = copyqueue(e->e_sendqueue);
|
||||
@ -299,7 +332,10 @@ sendall(e, mode)
|
||||
if (q->q_owner == owner)
|
||||
{
|
||||
q->q_flags |= QDONTSEND;
|
||||
q->q_flags &= ~QQUEUEUP;
|
||||
q->q_flags &= ~(QQUEUEUP|QBADADDR);
|
||||
if (tTd(13, 6))
|
||||
printf("\t... stripping %s from original envelope\n",
|
||||
q->q_paddr);
|
||||
}
|
||||
}
|
||||
for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
|
||||
@ -307,13 +343,19 @@ sendall(e, mode)
|
||||
if (q->q_owner != owner)
|
||||
{
|
||||
q->q_flags |= QDONTSEND;
|
||||
q->q_flags &= ~QQUEUEUP;
|
||||
q->q_flags &= ~(QQUEUEUP|QBADADDR);
|
||||
if (tTd(13, 6))
|
||||
printf("\t... dropping %s from cloned envelope\n",
|
||||
q->q_paddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear DSN parameters */
|
||||
q->q_flags &= ~(QHASNOTIFY|QPINGONSUCCESS);
|
||||
q->q_flags |= QPINGONFAILURE|QPINGONDELAY;
|
||||
q->q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
|
||||
q->q_flags |= DefaultNotify & ~QPINGONSUCCESS;
|
||||
if (tTd(13, 6))
|
||||
printf("\t... moving %s to cloned envelope\n",
|
||||
q->q_paddr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,6 +410,7 @@ sendall(e, mode)
|
||||
e->e_from.q_flags |= QDONTSEND;
|
||||
e->e_errormode = EM_MAIL;
|
||||
e->e_flags |= EF_NORECEIPT;
|
||||
e->e_flags &= ~EF_FATALERRS;
|
||||
}
|
||||
|
||||
/* if nothing to be delivered, just queue up everything */
|
||||
@ -382,7 +425,7 @@ sendall(e, mode)
|
||||
# ifdef QUEUE
|
||||
if ((mode == SM_QUEUE || mode == SM_DEFER || mode == SM_FORK ||
|
||||
(mode != SM_VERIFY && SuperSafe)) &&
|
||||
!bitset(EF_INQUEUE, e->e_flags))
|
||||
(!bitset(EF_INQUEUE, e->e_flags) || splitenv != NULL))
|
||||
{
|
||||
/* be sure everything is instantiated in the queue */
|
||||
queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
|
||||
@ -391,12 +434,31 @@ sendall(e, mode)
|
||||
}
|
||||
#endif /* QUEUE */
|
||||
|
||||
if (tTd(62, 10))
|
||||
checkfds("after envelope splitting");
|
||||
|
||||
/*
|
||||
** If we belong in background, fork now.
|
||||
*/
|
||||
|
||||
if (tTd(13, 20))
|
||||
{
|
||||
printf("sendall: final mode = %c\n", mode);
|
||||
if (tTd(13, 21))
|
||||
{
|
||||
printf("\n================ Final Send Queue(s) =====================\n");
|
||||
printf("\n *** Envelope %s, e_from=%s ***\n",
|
||||
e->e_id, e->e_from.q_paddr);
|
||||
printaddr(e->e_sendqueue, TRUE);
|
||||
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
|
||||
{
|
||||
printf("\n *** Envelope %s, e_from=%s ***\n",
|
||||
ee->e_id, ee->e_from.q_paddr);
|
||||
printaddr(ee->e_sendqueue, TRUE);
|
||||
}
|
||||
printf("==========================================================\n\n");
|
||||
}
|
||||
}
|
||||
switch (mode)
|
||||
{
|
||||
case SM_VERIFY:
|
||||
@ -428,15 +490,26 @@ sendall(e, mode)
|
||||
|
||||
/* now drop the envelope in the parent */
|
||||
e->e_flags |= EF_INQUEUE;
|
||||
dropenvelope(e);
|
||||
dropenvelope(e, FALSE);
|
||||
|
||||
/* and reacquire in the child */
|
||||
(void) dowork(qid, TRUE, FALSE, e);
|
||||
/* arrange to reacquire lock after fork */
|
||||
e->e_id = qid;
|
||||
}
|
||||
|
||||
return;
|
||||
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
|
||||
{
|
||||
/* save id for future use */
|
||||
char *qid = ee->e_id;
|
||||
|
||||
# else /* HASFLOCK */
|
||||
/* drop envelope in parent */
|
||||
ee->e_flags |= EF_INQUEUE;
|
||||
dropenvelope(ee, FALSE);
|
||||
|
||||
/* and save qid for reacquisition */
|
||||
ee->e_id = qid;
|
||||
}
|
||||
|
||||
# endif /* !HASFLOCK */
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
@ -445,6 +518,7 @@ sendall(e, mode)
|
||||
}
|
||||
else if (pid > 0)
|
||||
{
|
||||
# if HASFLOCK
|
||||
/* be sure we leave the temp files to our child */
|
||||
/* can't call unlockqueue to avoid unlink of xfp */
|
||||
if (e->e_lockfp != NULL)
|
||||
@ -456,8 +530,11 @@ sendall(e, mode)
|
||||
if (e->e_dfp != NULL)
|
||||
(void) xfclose(e->e_dfp, "sendenvelope dfp", e->e_id);
|
||||
e->e_dfp = NULL;
|
||||
e->e_id = NULL;
|
||||
e->e_flags &= ~EF_HAS_DF;
|
||||
# endif
|
||||
|
||||
/* make sure the parent doesn't own the envelope */
|
||||
e->e_id = NULL;
|
||||
|
||||
/* catch intermediate zombie */
|
||||
(void) waitfor(pid);
|
||||
@ -491,31 +568,33 @@ sendall(e, mode)
|
||||
|
||||
mci_flush(FALSE, NULL);
|
||||
|
||||
# endif /* HASFLOCK */
|
||||
|
||||
# if HASFLOCK
|
||||
break;
|
||||
# else
|
||||
|
||||
/*
|
||||
** Now reacquire and run the various queue files.
|
||||
*/
|
||||
|
||||
for (ee = splitenv; ee != NULL; ee = e->e_sibling)
|
||||
(void) dowork(ee->e_id, FALSE, FALSE, ee);
|
||||
(void) dowork(e->e_id, FALSE, FALSE, e);
|
||||
finis();
|
||||
# endif /* !HASFLOCK */
|
||||
}
|
||||
|
||||
if (splitenv != NULL)
|
||||
{
|
||||
if (tTd(13, 2))
|
||||
{
|
||||
printf("\nsendall: Split queue; remaining queue:\n");
|
||||
printaddr(e->e_sendqueue, TRUE);
|
||||
}
|
||||
|
||||
sendenvelope(e, mode);
|
||||
dropenvelope(e, TRUE);
|
||||
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
|
||||
{
|
||||
CurEnv = ee;
|
||||
if (mode != SM_VERIFY)
|
||||
openxscript(ee);
|
||||
sendenvelope(ee, mode);
|
||||
dropenvelope(ee);
|
||||
dropenvelope(ee, TRUE);
|
||||
}
|
||||
|
||||
CurEnv = e;
|
||||
}
|
||||
sendenvelope(e, mode);
|
||||
|
||||
Verbose = oldverbose;
|
||||
if (mode == SM_FORK)
|
||||
finis();
|
||||
@ -563,6 +642,8 @@ sendenvelope(e, mode)
|
||||
|
||||
e->e_nsent = 0;
|
||||
e->e_flags |= EF_GLOBALERRS;
|
||||
define(macid("{envid}", NULL), e->e_envid, e);
|
||||
define(macid("{bodytype}", NULL), e->e_bodytype, e);
|
||||
didany = FALSE;
|
||||
|
||||
/* now run through the queue */
|
||||
@ -593,6 +674,8 @@ sendenvelope(e, mode)
|
||||
}
|
||||
else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
|
||||
{
|
||||
extern int deliver __P((ENVELOPE *, ADDRESS *));
|
||||
|
||||
# ifdef QUEUE
|
||||
/*
|
||||
** Checkpoint the send list every few addresses
|
||||
@ -704,6 +787,13 @@ dofork()
|
||||
** The standard input is passed off to someone.
|
||||
*/
|
||||
|
||||
#ifndef NO_UID
|
||||
# define NO_UID ((uid_t) -1)
|
||||
#endif
|
||||
#ifndef NO_GID
|
||||
# define NO_GID ((gid_t) -1)
|
||||
#endif
|
||||
|
||||
int
|
||||
deliver(e, firstto)
|
||||
register ENVELOPE *e;
|
||||
@ -716,6 +806,7 @@ deliver(e, firstto)
|
||||
register char *p;
|
||||
register MAILER *m; /* mailer for this recipient */
|
||||
ADDRESS *volatile ctladdr;
|
||||
ADDRESS *volatile contextaddr = NULL;
|
||||
register MCI *volatile mci;
|
||||
register ADDRESS *to = firstto;
|
||||
volatile bool clever = FALSE; /* running user smtp to this mailer */
|
||||
@ -724,7 +815,9 @@ deliver(e, firstto)
|
||||
char *firstsig; /* signature of firstto */
|
||||
int pid = -1;
|
||||
char *volatile curhost;
|
||||
register volatile u_short port = 0;
|
||||
time_t xstart;
|
||||
bool suidwarn;
|
||||
int mpvect[2];
|
||||
int rpvect[2];
|
||||
char *pv[MAXPV+1];
|
||||
@ -738,6 +831,8 @@ deliver(e, firstto)
|
||||
if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags))
|
||||
return (0);
|
||||
|
||||
suidwarn = geteuid() == 0;
|
||||
|
||||
#if NAMED_BIND
|
||||
/* unless interactive, try twice, over a minute */
|
||||
if (OpMode == MD_DAEMON || OpMode == MD_SMTP)
|
||||
@ -888,7 +983,7 @@ deliver(e, firstto)
|
||||
|
||||
/* compute effective uid/gid when sending */
|
||||
if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
|
||||
ctladdr = getctladdr(to);
|
||||
contextaddr = ctladdr = getctladdr(to);
|
||||
|
||||
if (tTd(10, 2))
|
||||
{
|
||||
@ -921,7 +1016,15 @@ deliver(e, firstto)
|
||||
#if NAMED_BIND
|
||||
h_errno = 0;
|
||||
#endif
|
||||
|
||||
/* do config file checking of compatibility */
|
||||
rcode = rscheck("check_compat",
|
||||
e->e_from.q_paddr, to->q_paddr, e);
|
||||
if (rcode == EX_OK)
|
||||
{
|
||||
/* do in-code checking */
|
||||
rcode = checkcompat(to, e);
|
||||
}
|
||||
if (rcode != EX_OK)
|
||||
{
|
||||
markfailure(e, to, NULL, rcode);
|
||||
@ -956,9 +1059,6 @@ deliver(e, firstto)
|
||||
if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
|
||||
continue;
|
||||
|
||||
/* save statistics.... */
|
||||
markstats(e, to);
|
||||
|
||||
/*
|
||||
** See if this user name is "special".
|
||||
** If the user name has a slash in it, assume that this
|
||||
@ -975,9 +1075,9 @@ deliver(e, firstto)
|
||||
if (rcode == EX_OK)
|
||||
{
|
||||
to->q_flags |= QSENT;
|
||||
markstats(e, to);
|
||||
if (bitnset(M_LOCALMAILER, m->m_flags) &&
|
||||
(e->e_receiptto != NULL ||
|
||||
bitset(QPINGONSUCCESS, to->q_flags)))
|
||||
bitset(QPINGONSUCCESS, to->q_flags))
|
||||
{
|
||||
to->q_flags |= QDELIVERED;
|
||||
to->q_status = "2.1.5";
|
||||
@ -1114,6 +1214,9 @@ deliver(e, firstto)
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
if (tTd(62, 8))
|
||||
checkfds("before delivery");
|
||||
|
||||
/* check for Local Person Communication -- not for mortals!!! */
|
||||
if (strcmp(m->m_mailer, "[LPC]") == 0)
|
||||
{
|
||||
@ -1129,7 +1232,6 @@ deliver(e, firstto)
|
||||
{
|
||||
#ifdef DAEMON
|
||||
register int i;
|
||||
register volatile u_short port = 0;
|
||||
|
||||
if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
|
||||
{
|
||||
@ -1172,11 +1274,12 @@ deliver(e, firstto)
|
||||
{
|
||||
register char *p;
|
||||
static char hostbuf[MAXNAME + 1];
|
||||
extern int makeconnection __P((char *, u_short, MCI *, ENVELOPE *));
|
||||
|
||||
/* pull the next host from the signature */
|
||||
p = strchr(curhost, ':');
|
||||
if (p == NULL)
|
||||
p = &curhost[strlen(curhost)];
|
||||
p = (char *) &curhost[strlen(curhost)];
|
||||
if (p == curhost)
|
||||
{
|
||||
syserr("deliver: null host name in signature");
|
||||
@ -1209,12 +1312,21 @@ deliver(e, firstto)
|
||||
if (mci->mci_exitstat != EX_OK)
|
||||
continue;
|
||||
|
||||
if (mci_lock_host(mci) != EX_OK)
|
||||
{
|
||||
mci->mci_exitstat = EX_TEMPFAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* try the connection */
|
||||
setproctitle("%s %s: %s", e->e_id, hostbuf, "user open");
|
||||
if (port == 0)
|
||||
message("Connecting to %s via %s...",
|
||||
hostbuf, m->m_name);
|
||||
i = makeconnection(hostbuf, port, mci,
|
||||
bitnset(M_SECURE_PORT, m->m_flags));
|
||||
else
|
||||
message("Connecting to %s port %d via %s...",
|
||||
hostbuf, port, m->m_name);
|
||||
i = makeconnection(hostbuf, port, mci, e);
|
||||
mci->mci_lastuse = curtime();
|
||||
mci->mci_exitstat = i;
|
||||
mci->mci_errno = errno;
|
||||
@ -1226,13 +1338,17 @@ deliver(e, firstto)
|
||||
mci->mci_state = MCIS_OPENING;
|
||||
mci_cache(mci);
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%05d == CONNECT %s\n",
|
||||
fprintf(TrafficLogFile, "%05d === CONNECT %s\n",
|
||||
getpid(), hostbuf);
|
||||
break;
|
||||
}
|
||||
else if (tTd(11, 1))
|
||||
else
|
||||
{
|
||||
if (tTd(11, 1))
|
||||
printf("openmailer: makeconnection => stat=%d, errno=%d\n",
|
||||
i, errno);
|
||||
mci_unlock_host(mci);
|
||||
}
|
||||
|
||||
/* enter status of this host */
|
||||
setstat(i);
|
||||
@ -1242,7 +1358,7 @@ deliver(e, firstto)
|
||||
if (mci == NULL)
|
||||
{
|
||||
syserr("deliver: no host name");
|
||||
rcode = EX_OSERR;
|
||||
rcode = EX_SOFTWARE;
|
||||
goto give_up;
|
||||
}
|
||||
mci->mci_pid = 0;
|
||||
@ -1274,6 +1390,10 @@ deliver(e, firstto)
|
||||
fprintf(TrafficLogFile, "\n");
|
||||
}
|
||||
|
||||
#if XDEBUG
|
||||
checkfd012("before creating mail pipe");
|
||||
#endif
|
||||
|
||||
/* create a pipe to shove the mail through */
|
||||
if (pipe(mpvect) < 0)
|
||||
{
|
||||
@ -1285,9 +1405,44 @@ deliver(e, firstto)
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
#if XDEBUG
|
||||
/* make sure we didn't get one of the standard I/O files */
|
||||
if (mpvect[0] < 3 || mpvect[1] < 3)
|
||||
{
|
||||
syserr("%s... openmailer(%s): bogus mpvect %d %d",
|
||||
shortenstring(e->e_to, 203), m->m_name,
|
||||
mpvect[0], mpvect[1]);
|
||||
printopenfds(TRUE);
|
||||
if (tTd(11, 1))
|
||||
printf("openmailer: NULL\n");
|
||||
rcode = EX_OSERR;
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
/* make sure system call isn't dead meat */
|
||||
checkfdopen(mpvect[0], "mpvect[0]");
|
||||
checkfdopen(mpvect[1], "mpvect[1]");
|
||||
if (mpvect[0] == mpvect[1] ||
|
||||
(e->e_lockfp != NULL &&
|
||||
(mpvect[0] == fileno(e->e_lockfp) ||
|
||||
mpvect[1] == fileno(e->e_lockfp))))
|
||||
{
|
||||
if (e->e_lockfp == NULL)
|
||||
syserr("%s... openmailer(%s): overlapping mpvect %d %d",
|
||||
shortenstring(e->e_to, 203), m->m_name,
|
||||
mpvect[0], mpvect[1]);
|
||||
else
|
||||
syserr("%s... openmailer(%s): overlapping mpvect %d %d, lockfp = %d",
|
||||
shortenstring(e->e_to, 203), m->m_name,
|
||||
mpvect[0], mpvect[1], fileno(e->e_lockfp));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if this mailer speaks smtp, create a return pipe */
|
||||
#ifdef SMTP
|
||||
if (clever && pipe(rpvect) < 0)
|
||||
if (clever)
|
||||
{
|
||||
if (pipe(rpvect) < 0)
|
||||
{
|
||||
syserr("%s... openmailer(%s): pipe (from mailer)",
|
||||
shortenstring(e->e_to, 203), m->m_name);
|
||||
@ -1298,6 +1453,11 @@ deliver(e, firstto)
|
||||
rcode = EX_OSERR;
|
||||
goto give_up;
|
||||
}
|
||||
# if XDEBUG
|
||||
checkfdopen(rpvect[0], "rpvect[0]");
|
||||
checkfdopen(rpvect[1], "rpvect[1]");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1339,6 +1499,9 @@ deliver(e, firstto)
|
||||
{
|
||||
int i;
|
||||
int saveerrno;
|
||||
uid_t new_euid = NO_UID;
|
||||
uid_t new_ruid = NO_UID;
|
||||
gid_t new_gid = NO_GID;
|
||||
struct stat stb;
|
||||
extern int DtableSize;
|
||||
|
||||
@ -1353,58 +1516,96 @@ deliver(e, firstto)
|
||||
if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
|
||||
stb.st_mode = 0;
|
||||
|
||||
#if HASSETUSERCONTEXT
|
||||
/*
|
||||
** Set user resources.
|
||||
*/
|
||||
|
||||
if (contextaddr != NULL)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
|
||||
if (contextaddr->q_ruser != NULL)
|
||||
pwd = sm_getpwnam(contextaddr->q_ruser);
|
||||
else
|
||||
pwd = sm_getpwnam(contextaddr->q_user);
|
||||
if (pwd != NULL)
|
||||
(void) setusercontext(NULL,
|
||||
pwd, pwd->m_uid,
|
||||
LOGIN_SETRESOURCES|LOGIN_SETPRIORITY);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tweak niceness */
|
||||
if (m->m_nice != 0)
|
||||
nice(m->m_nice);
|
||||
|
||||
/* reset group id */
|
||||
if (bitnset(M_SPECIFIC_UID, m->m_flags))
|
||||
(void) setgid(m->m_gid);
|
||||
new_gid = m->m_gid;
|
||||
else if (bitset(S_ISGID, stb.st_mode))
|
||||
(void) setgid(stb.st_gid);
|
||||
new_gid = stb.st_gid;
|
||||
else if (ctladdr != NULL && ctladdr->q_gid != 0)
|
||||
{
|
||||
if (!DontInitGroups)
|
||||
(void) initgroups(ctladdr->q_ruser != NULL ?
|
||||
ctladdr->q_ruser : ctladdr->q_user,
|
||||
ctladdr->q_gid);
|
||||
(void) setgid(ctladdr->q_gid);
|
||||
new_gid = ctladdr->q_gid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!DontInitGroups)
|
||||
(void) initgroups(DefUser, DefGid);
|
||||
if (m->m_gid == 0)
|
||||
(void) setgid(DefGid);
|
||||
new_gid = DefGid;
|
||||
else
|
||||
(void) setgid(m->m_gid);
|
||||
new_gid = m->m_gid;
|
||||
}
|
||||
if (new_gid != NO_GID && setgid(new_gid) < 0 && suidwarn)
|
||||
syserr("openmailer: setgid(%ld) failed",
|
||||
(long) new_gid);
|
||||
|
||||
/* reset user id */
|
||||
endpwent();
|
||||
if (bitnset(M_SPECIFIC_UID, m->m_flags))
|
||||
{
|
||||
#if USESETEUID
|
||||
(void) seteuid(m->m_uid);
|
||||
#else
|
||||
# if HASSETREUID
|
||||
(void) setreuid(-1, m->m_uid);
|
||||
# else
|
||||
if (m->m_uid != geteuid())
|
||||
(void) setuid(m->m_uid);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
else if (bitset(S_ISUID, stb.st_mode))
|
||||
(void) setuid(stb.st_uid);
|
||||
new_euid = m->m_uid;
|
||||
if (bitset(S_ISUID, stb.st_mode))
|
||||
new_ruid = stb.st_uid;
|
||||
else if (ctladdr != NULL && ctladdr->q_uid != 0)
|
||||
(void) setuid(ctladdr->q_uid);
|
||||
new_ruid = ctladdr->q_uid;
|
||||
else
|
||||
{
|
||||
if (m->m_uid == 0)
|
||||
(void) setuid(DefUid);
|
||||
new_ruid = DefUid;
|
||||
else
|
||||
(void) setuid(m->m_uid);
|
||||
new_ruid = m->m_uid;
|
||||
}
|
||||
if (new_euid != NO_UID)
|
||||
{
|
||||
vendor_set_uid(new_euid);
|
||||
#if USESETEUID
|
||||
if (seteuid(new_euid) < 0 && suidwarn)
|
||||
syserr("openmailer: seteuid(%ld) failed",
|
||||
(long) new_euid);
|
||||
#else
|
||||
# if HASSETREUID
|
||||
if (setreuid(new_ruid, new_euid) < 0 && suidwarn)
|
||||
syserr("openmailer: setreuid(%ld, %ld) failed",
|
||||
(long) new_ruid, (long) new_euid);
|
||||
# else
|
||||
if (new_euid != geteuid() && setuid(new_euid) < 0 && suidwarn)
|
||||
syserr("openmailer: setuid(%ld) failed",
|
||||
(long) new_euid);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
else if (new_ruid != NO_UID)
|
||||
{
|
||||
vendor_set_uid(new_ruid);
|
||||
if (setuid(new_ruid) < 0 && suidwarn)
|
||||
syserr("openmailer: setuid(%ld) failed",
|
||||
(long) new_ruid);
|
||||
}
|
||||
|
||||
if (tTd(11, 2))
|
||||
@ -1559,7 +1760,11 @@ deliver(e, firstto)
|
||||
mci->mci_flags |= MCIF_7BIT;
|
||||
#ifdef SMTP
|
||||
if (clever && mci->mci_state != MCIS_CLOSED)
|
||||
{
|
||||
extern void smtpinit __P((MAILER *, MCI *, ENVELOPE *));
|
||||
|
||||
smtpinit(m, mci, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bitset(EF_HAS8BIT, e->e_flags) &&
|
||||
@ -1569,6 +1774,22 @@ deliver(e, firstto)
|
||||
else
|
||||
mci->mci_flags &= ~MCIF_CVT8TO7;
|
||||
|
||||
#if MIME7TO8
|
||||
if (bitnset(M_MAKE8BIT, m->m_flags) &&
|
||||
!bitset(MCIF_7BIT, mci->mci_flags) &&
|
||||
(p = hvalue("Content-Transfer-Encoding", e->e_header)) != NULL &&
|
||||
(strcasecmp(p, "quoted-printable") == 0 ||
|
||||
strcasecmp(p, "base64") == 0) &&
|
||||
(p = hvalue("Content-Type", e->e_header)) != NULL)
|
||||
{
|
||||
/* may want to convert 7 -> 8 */
|
||||
/* XXX should really parse it here -- and use a class XXX */
|
||||
if (strncasecmp(p, "text/plain", 10) == 0 &&
|
||||
(p[10] == '\0' || p[10] == ' ' || p[10] == ';'))
|
||||
mci->mci_flags |= MCIF_CVT7TO8;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tTd(11, 1))
|
||||
{
|
||||
printf("openmailer: ");
|
||||
@ -1586,8 +1807,10 @@ deliver(e, firstto)
|
||||
if (rcode == EX_OK)
|
||||
{
|
||||
/* shouldn't happen */
|
||||
syserr("554 deliver: rcode=%d, mci_state=%d, sig=%s",
|
||||
rcode, mci->mci_state, firstsig);
|
||||
syserr("554 deliver: mci=%lx rcode=%d errno=%d state=%d sig=%s",
|
||||
(long) mci, rcode, errno, mci->mci_state,
|
||||
firstsig);
|
||||
mci_dump_all(TRUE);
|
||||
rcode = EX_SOFTWARE;
|
||||
}
|
||||
#ifdef DAEMON
|
||||
@ -1614,6 +1837,10 @@ deliver(e, firstto)
|
||||
else
|
||||
#ifdef SMTP
|
||||
{
|
||||
extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *));
|
||||
extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
|
||||
extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *));
|
||||
|
||||
/*
|
||||
** Send the MAIL FROM: protocol
|
||||
*/
|
||||
@ -1661,7 +1888,7 @@ deliver(e, firstto)
|
||||
if (!bitset(MCIF_CACHED, mci->mci_flags))
|
||||
smtpquit(m, mci, e);
|
||||
}
|
||||
if (rcode != EX_OK && curhost != NULL && *curhost != '\0')
|
||||
if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
|
||||
{
|
||||
/* try next MX site */
|
||||
goto tryhost;
|
||||
@ -1679,13 +1906,8 @@ deliver(e, firstto)
|
||||
_res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
|
||||
#endif
|
||||
|
||||
/* arrange a return receipt if requested */
|
||||
if (rcode == EX_OK && e->e_receiptto != NULL &&
|
||||
bitnset(M_LOCALMAILER, m->m_flags))
|
||||
{
|
||||
e->e_flags |= EF_SENDRECEIPT;
|
||||
/* do we want to send back more info? */
|
||||
}
|
||||
if (tTd(62, 1))
|
||||
checkfds("after delivery");
|
||||
|
||||
/*
|
||||
** Do final status disposal.
|
||||
@ -1697,6 +1919,10 @@ deliver(e, firstto)
|
||||
give_up:
|
||||
if (tobuf[0] != '\0')
|
||||
giveresponse(rcode, m, mci, ctladdr, xstart, e);
|
||||
if (rcode == EX_OK)
|
||||
markstats(e, tochain);
|
||||
mci_store_persistent(mci);
|
||||
|
||||
for (to = tochain; to != NULL; to = to->q_tchain)
|
||||
{
|
||||
/* see if address already marked */
|
||||
@ -1715,8 +1941,7 @@ deliver(e, firstto)
|
||||
to->q_statdate = curtime();
|
||||
e->e_nsent++;
|
||||
if (bitnset(M_LOCALMAILER, m->m_flags) &&
|
||||
(e->e_receiptto != NULL ||
|
||||
bitset(QPINGONSUCCESS, to->q_flags)))
|
||||
bitset(QPINGONSUCCESS, to->q_flags))
|
||||
{
|
||||
to->q_flags |= QDELIVERED;
|
||||
to->q_status = "2.1.5";
|
||||
@ -1798,11 +2023,17 @@ markfailure(e, q, mci, rcode)
|
||||
}
|
||||
|
||||
/* find most specific error code possible */
|
||||
if (q->q_status == NULL && mci != NULL)
|
||||
if (mci != NULL && mci->mci_status != NULL)
|
||||
{
|
||||
q->q_status = mci->mci_status;
|
||||
if (q->q_status == NULL)
|
||||
q->q_rstatus = mci->mci_rstatus;
|
||||
}
|
||||
else if (e->e_status != NULL)
|
||||
{
|
||||
q->q_status = e->e_status;
|
||||
if (q->q_status == NULL)
|
||||
q->q_rstatus = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (rcode)
|
||||
{
|
||||
@ -1903,6 +2134,10 @@ endmailer(mci, e, pv)
|
||||
if (mci->mci_pid == 0)
|
||||
return (EX_OK);
|
||||
|
||||
#ifdef FFR_TIMEOUT_WAIT
|
||||
put a timeout around the wait
|
||||
#endif
|
||||
|
||||
/* wait for the mailer process to die and collect status */
|
||||
st = waitfor(mci->mci_pid);
|
||||
if (st == -1)
|
||||
@ -2239,7 +2474,7 @@ logdelivery(m, mci, stat, ctladdr, xstart, e)
|
||||
|
||||
l = SYSLOG_BUFSIZE - 85;
|
||||
p = e->e_to;
|
||||
while (strlen(p) >= l)
|
||||
while (strlen(p) >= (SIZE_T) l)
|
||||
{
|
||||
register char *q = strchr(p + l, ',');
|
||||
|
||||
@ -2342,6 +2577,7 @@ putfromline(mci, e)
|
||||
{
|
||||
char *template = UnixFromLine;
|
||||
char buf[MAXLINE];
|
||||
char xbuf[MAXLINE];
|
||||
|
||||
if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
|
||||
return;
|
||||
@ -2349,14 +2585,29 @@ putfromline(mci, e)
|
||||
if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
|
||||
{
|
||||
char *bang;
|
||||
char xbuf[MAXLINE];
|
||||
|
||||
expand("\201g", buf, sizeof buf, e);
|
||||
bang = strchr(buf, '!');
|
||||
if (bang == NULL)
|
||||
{
|
||||
errno = 0;
|
||||
syserr("554 No ! in UUCP From address! (%s given)", buf);
|
||||
char *at;
|
||||
char hname[MAXNAME];
|
||||
|
||||
/*
|
||||
** If we can construct a UUCP path, do so
|
||||
*/
|
||||
|
||||
at = strrchr(buf, '@');
|
||||
if (at == NULL)
|
||||
{
|
||||
expand( "\201k", hname, sizeof hname, e);
|
||||
at = hname;
|
||||
}
|
||||
else
|
||||
*at++ = '\0';
|
||||
(void) snprintf(xbuf, sizeof xbuf,
|
||||
"From %.800s \201d remote from %.100s\n",
|
||||
buf, at);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2461,6 +2712,12 @@ putbody(mci, e, separator)
|
||||
boundaries[0] = NULL;
|
||||
mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
|
||||
}
|
||||
# if MIME7TO8
|
||||
else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
|
||||
{
|
||||
mime7to8(mci, e->e_header, e);
|
||||
}
|
||||
# endif
|
||||
else
|
||||
#endif
|
||||
{
|
||||
@ -2593,6 +2850,7 @@ putbody(mci, e, separator)
|
||||
/* had a naked carriage return */
|
||||
*pbp++ = c;
|
||||
c = '\r';
|
||||
ostate = OS_INLINE;
|
||||
goto putch;
|
||||
|
||||
case OS_INLINE:
|
||||
@ -2631,8 +2889,10 @@ putbody(mci, e, separator)
|
||||
{
|
||||
*bp = '\0';
|
||||
fputs(buf, mci->mci_out);
|
||||
fputs(mci->mci_mailer->m_eol, mci->mci_out);
|
||||
pos += bp - buf;
|
||||
}
|
||||
if (pos > 0)
|
||||
fputs(mci->mci_mailer->m_eol, mci->mci_out);
|
||||
}
|
||||
|
||||
if (ferror(e->e_dfp))
|
||||
@ -2693,6 +2953,7 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
register FILE *f;
|
||||
register int pid = -1;
|
||||
int mode;
|
||||
bool suidwarn = geteuid() == 0;
|
||||
|
||||
if (tTd(11, 1))
|
||||
{
|
||||
@ -2703,6 +2964,14 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
if (e->e_xfp != NULL)
|
||||
fflush(e->e_xfp);
|
||||
|
||||
/*
|
||||
** Special case /dev/null. This allows us to restrict file
|
||||
** delivery to regular files only.
|
||||
*/
|
||||
|
||||
if (strcmp(filename, "/dev/null") == 0)
|
||||
return EX_OK;
|
||||
|
||||
/*
|
||||
** Fork so we can change permissions here.
|
||||
** Note that we MUST use fork, not vfork, because of
|
||||
@ -2717,7 +2986,6 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
{
|
||||
/* child -- actually write to file */
|
||||
struct stat stb;
|
||||
struct stat fsb;
|
||||
MCI mcibuf;
|
||||
int oflags = O_WRONLY|O_APPEND;
|
||||
|
||||
@ -2816,12 +3084,9 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
RealGid = DefGid;
|
||||
}
|
||||
|
||||
/* now set the group and user ids */
|
||||
endpwent();
|
||||
/* set group id list (needs /etc/group access) */
|
||||
if (RealUserName != NULL && !DontInitGroups)
|
||||
(void) initgroups(RealUserName, RealGid);
|
||||
(void) setgid(RealGid);
|
||||
(void) setuid(RealUid);
|
||||
|
||||
/* if you have a safe environment, go into it */
|
||||
if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
|
||||
@ -2841,6 +3106,14 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
if (chdir("/") < 0)
|
||||
syserr("mailfile: cannot chdir(/)");
|
||||
|
||||
/* now reset the group and user ids */
|
||||
endpwent();
|
||||
if (setgid(RealGid) < 0 && suidwarn)
|
||||
syserr("mailfile: setgid(%ld) failed", (long) RealGid);
|
||||
vendor_set_uid(RealUid);
|
||||
if (setuid(RealUid) < 0 && suidwarn)
|
||||
syserr("mailfile: setuid(%ld) failed", (long) RealUid);
|
||||
|
||||
sfflags |= SFF_NOPATHCHECK;
|
||||
sfflags &= ~SFF_OPENASROOT;
|
||||
f = safefopen(filename, oflags, FileMode, sfflags);
|
||||
@ -2897,6 +3170,7 @@ mailfile(filename, ctladdr, sfflags, e)
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return EX_UNAVAILABLE; /* avoid compiler warning on IRIX */
|
||||
}
|
||||
/*
|
||||
** HOSTSIGNATURE -- return the "signature" for a host.
|
||||
@ -2929,7 +3203,6 @@ hostsignature(m, host, e)
|
||||
int len;
|
||||
#if NAMED_BIND
|
||||
int nmx;
|
||||
auto int rcode;
|
||||
char *hp;
|
||||
char *endp;
|
||||
int oldoptions = _res.options;
|
||||
@ -2969,8 +3242,17 @@ hostsignature(m, host, e)
|
||||
if (endp != NULL)
|
||||
*endp = '\0';
|
||||
|
||||
nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
|
||||
if (bitnset(M_NOMX, m->m_flags))
|
||||
{
|
||||
/* skip MX lookups */
|
||||
nmx = 1;
|
||||
mxhosts[0] = hp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto int rcode;
|
||||
|
||||
nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
|
||||
if (nmx <= 0)
|
||||
{
|
||||
register MCI *mci;
|
||||
@ -2982,10 +3264,11 @@ hostsignature(m, host, e)
|
||||
mci->mci_errno = errno;
|
||||
mci->mci_herrno = h_errno;
|
||||
|
||||
/* and return the original host name as the signature */
|
||||
/* use the original host name as signature */
|
||||
nmx = 1;
|
||||
mxhosts[0] = hp;
|
||||
}
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < nmx; i++)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1986, 1995 Eric P. Allman
|
||||
* Copyright (c) 1986, 1995, 1996 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.54.1.2 (Berkeley) 9/16/96 (with name server)";
|
||||
static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name server)";
|
||||
static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -46,6 +46,7 @@ static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name s
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef union
|
||||
{
|
||||
@ -53,7 +54,11 @@ typedef union
|
||||
u_char qb2[PACKETSZ];
|
||||
} querybuf;
|
||||
|
||||
static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
|
||||
#ifndef MXHOSTBUFSIZE
|
||||
# define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
|
||||
#endif
|
||||
|
||||
static char MXHostBuf[MXHOSTBUFSIZE];
|
||||
|
||||
#ifndef MAXDNSRCH
|
||||
# define MAXDNSRCH 6 /* number of possible domains to search */
|
||||
@ -114,33 +119,22 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
|
||||
u_short pref, type;
|
||||
u_short localpref = 256;
|
||||
char *fallbackMX = FallBackMX;
|
||||
static bool firsttime = TRUE;
|
||||
bool trycanon = FALSE;
|
||||
int (*resfunc)();
|
||||
extern int res_query(), res_search();
|
||||
u_short prefer[MAXMXHOSTS];
|
||||
int weight[MAXMXHOSTS];
|
||||
extern bool getcanonname();
|
||||
extern int mxrand __P((char *));
|
||||
|
||||
if (tTd(8, 2))
|
||||
printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost);
|
||||
|
||||
if (fallbackMX != NULL)
|
||||
{
|
||||
if (firsttime &&
|
||||
res_query(FallBackMX, C_IN, T_A,
|
||||
(u_char *) &answer, sizeof answer) < 0)
|
||||
{
|
||||
/* this entry is bogus */
|
||||
fallbackMX = FallBackMX = NULL;
|
||||
}
|
||||
else if (droplocalhost && wordinclass(fallbackMX, 'w'))
|
||||
if (fallbackMX != NULL && droplocalhost &&
|
||||
wordinclass(fallbackMX, 'w'))
|
||||
{
|
||||
/* don't use fallback for this pass */
|
||||
fallbackMX = NULL;
|
||||
}
|
||||
firsttime = FALSE;
|
||||
}
|
||||
|
||||
*rcode = EX_OK;
|
||||
|
||||
@ -356,8 +350,11 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
|
||||
if (p != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
if (inet_addr(&MXHostBuf[1]) != -1)
|
||||
if (inet_addr(&MXHostBuf[1]) != INADDR_NONE)
|
||||
{
|
||||
nmx++;
|
||||
*p = ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
trycanon = TRUE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 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[] = "@(#)headers.c 8.82.1.2 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)headers.c 8.100 (Berkeley) 9/15/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include <errno.h>
|
||||
@ -74,7 +74,6 @@ chompheader(line, def, hdrp, e)
|
||||
bool cond = FALSE;
|
||||
bool headeronly;
|
||||
BITMAP mopts;
|
||||
char buf[MAXNAME + 1];
|
||||
|
||||
if (tTd(31, 6))
|
||||
{
|
||||
@ -158,7 +157,6 @@ chompheader(line, def, hdrp, e)
|
||||
if (bitset(H_EOH, hi->hi_flags))
|
||||
return (hi->hi_flags);
|
||||
|
||||
#ifdef LOTUS_NOTES_HACK
|
||||
/*
|
||||
** Horrible hack to work around problem with Lotus Notes SMTP
|
||||
** mail gateway, which generates From: headers with newlines in
|
||||
@ -172,7 +170,6 @@ chompheader(line, def, hdrp, e)
|
||||
while ((p = strchr(fvalue, '\n')) != NULL)
|
||||
*p = ' ';
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Drop explicit From: if same as what we would generate.
|
||||
@ -195,46 +192,6 @@ chompheader(line, def, hdrp, e)
|
||||
(strcmp(fvalue, e->e_from.q_paddr) == 0 ||
|
||||
strcmp(fvalue, e->e_from.q_user) == 0))
|
||||
return (hi->hi_flags);
|
||||
#ifdef MAYBENEXTRELEASE /* XXX UNTESTED XXX UNTESTED XXX UNTESTED XXX */
|
||||
#if USERDB
|
||||
else
|
||||
{
|
||||
auto ADDRESS a;
|
||||
char *fancy;
|
||||
bool oldSuprErrs = SuprErrs;
|
||||
extern char *crackaddr();
|
||||
extern char *udbsender();
|
||||
|
||||
/*
|
||||
** Try doing USERDB rewriting even on fully commented
|
||||
** names; this saves the "comment" information (such
|
||||
** as full name) and rewrites the electronic part.
|
||||
**
|
||||
** XXX This code doesn't belong here -- parsing should
|
||||
** XXX not be done during collect() phase because
|
||||
** XXX error messages can confuse the SMTP phase.
|
||||
** XXX Setting SuprErrs is a crude hack around this
|
||||
** XXX problem.
|
||||
*/
|
||||
|
||||
if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
|
||||
SuprErrs = TRUE;
|
||||
fancy = crackaddr(fvalue);
|
||||
if (parseaddr(fvalue, &a, RF_COPYNONE, '\0', NULL, e) != NULL &&
|
||||
bitnset(M_CHECKUDB, a.q_mailer->m_flags) &&
|
||||
(p = udbsender(a.q_user)) != NULL)
|
||||
{
|
||||
char *oldg = macvalue('g', e);
|
||||
|
||||
define('g', p, e);
|
||||
expand(fancy, buf, sizeof buf, e);
|
||||
define('g', oldg, e);
|
||||
fvalue = buf;
|
||||
}
|
||||
SuprErrs = oldSuprErrs;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* delete default value for this header */
|
||||
@ -433,6 +390,7 @@ eatheader(e, full)
|
||||
int hopcnt = 0;
|
||||
char *msgid;
|
||||
char buf[MAXLINE];
|
||||
extern int priencode __P((char *));
|
||||
|
||||
/*
|
||||
** Set up macros for possible expansion in headers.
|
||||
@ -522,10 +480,6 @@ eatheader(e, full)
|
||||
while (isascii(*msgid) && isspace(*msgid))
|
||||
msgid++;
|
||||
}
|
||||
|
||||
/* see if this is a return-receipt header */
|
||||
if (bitset(H_RECEIPTTO, h->h_flags))
|
||||
e->e_receiptto = h->h_value;
|
||||
}
|
||||
if (tTd(32, 1))
|
||||
printf("----------------------------\n");
|
||||
@ -558,11 +512,11 @@ eatheader(e, full)
|
||||
if (p != NULL)
|
||||
{
|
||||
/* (this should be in the configuration file) */
|
||||
if (strcasecmp(p, "urgent"))
|
||||
if (strcasecmp(p, "urgent") == 0)
|
||||
e->e_timeoutclass = TOC_URGENT;
|
||||
else if (strcasecmp(p, "normal"))
|
||||
else if (strcasecmp(p, "normal") == 0)
|
||||
e->e_timeoutclass = TOC_NORMAL;
|
||||
else if (strcasecmp(p, "non-urgent"))
|
||||
else if (strcasecmp(p, "non-urgent") == 0)
|
||||
e->e_timeoutclass = TOC_NONURGENT;
|
||||
}
|
||||
|
||||
@ -807,6 +761,7 @@ crackaddr(addr)
|
||||
int realcmtlev;
|
||||
int anglelev, realanglelev;
|
||||
int copylev;
|
||||
int bracklev;
|
||||
bool qmode;
|
||||
bool realqmode;
|
||||
bool skipping;
|
||||
@ -833,9 +788,10 @@ crackaddr(addr)
|
||||
*/
|
||||
|
||||
bp = bufhead = buf;
|
||||
buflim = &buf[sizeof buf - 5];
|
||||
buflim = &buf[sizeof buf - 6];
|
||||
p = addrhead = addr;
|
||||
copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0;
|
||||
bracklev = 0;
|
||||
qmode = realqmode = FALSE;
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
@ -892,6 +848,7 @@ crackaddr(addr)
|
||||
realcmtlev++;
|
||||
if (copylev++ <= 0)
|
||||
{
|
||||
if (bp != bufhead)
|
||||
*bp++ = ' ';
|
||||
*bp++ = c;
|
||||
}
|
||||
@ -918,20 +875,33 @@ crackaddr(addr)
|
||||
bp--;
|
||||
}
|
||||
|
||||
/* count nesting on [ ... ] (for IPv6 domain literals) */
|
||||
if (c == '[')
|
||||
bracklev++;
|
||||
else if (c == ']')
|
||||
bracklev--;
|
||||
|
||||
/* check for group: list; syntax */
|
||||
if (c == ':' && anglelev <= 0 && !gotcolon && !ColonOkInAddr)
|
||||
if (c == ':' && anglelev <= 0 && bracklev <= 0 &&
|
||||
!gotcolon && !ColonOkInAddr)
|
||||
{
|
||||
register char *q;
|
||||
|
||||
if (*p == ':')
|
||||
/*
|
||||
** Check for DECnet phase IV ``::'' (host::user)
|
||||
** or ** DECnet phase V ``:.'' syntaxes. The latter
|
||||
** covers ``user@DEC:.tay.myhost'' and
|
||||
** ``DEC:.tay.myhost::user'' syntaxes (bletch).
|
||||
*/
|
||||
|
||||
if (*p == ':' || *p == '.')
|
||||
{
|
||||
/* special case -- :: syntax */
|
||||
if (cmtlev <= 0 && !qmode)
|
||||
quoteit = TRUE;
|
||||
if (copylev > 0 && !skipping)
|
||||
{
|
||||
*bp++ = c;
|
||||
*bp++ = c;
|
||||
*bp++ = *p;
|
||||
}
|
||||
p++;
|
||||
goto putg;
|
||||
@ -1086,6 +1056,8 @@ crackaddr(addr)
|
||||
putg:
|
||||
if (copylev <= 0 && !putgmac)
|
||||
{
|
||||
if (bp > bufhead && bp[-1] == ')')
|
||||
*bp++ = ' ';
|
||||
*bp++ = MACROEXPAND;
|
||||
*bp++ = 'g';
|
||||
putgmac = TRUE;
|
||||
@ -1102,7 +1074,11 @@ crackaddr(addr)
|
||||
*bp++ = '\0';
|
||||
|
||||
if (tTd(33, 1))
|
||||
printf("crackaddr=>`%s'\n", buf);
|
||||
{
|
||||
printf("crackaddr=>`");
|
||||
xputs(buf);
|
||||
printf("'\n");
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
@ -1129,11 +1105,12 @@ crackaddr(addr)
|
||||
#endif
|
||||
|
||||
void
|
||||
putheader(mci, h, e)
|
||||
putheader(mci, hdr, e)
|
||||
register MCI *mci;
|
||||
register HDR *h;
|
||||
HDR *hdr;
|
||||
register ENVELOPE *e;
|
||||
{
|
||||
register HDR *h;
|
||||
char buf[MAX(MAXLINE,BUFSIZ)];
|
||||
char obuf[MAXLINE];
|
||||
|
||||
@ -1142,7 +1119,7 @@ putheader(mci, h, e)
|
||||
mci->mci_mailer->m_name);
|
||||
|
||||
mci->mci_flags |= MCIF_INHEADER;
|
||||
for (; h != NULL; h = h->h_link)
|
||||
for (h = hdr; h != NULL; h = h->h_link)
|
||||
{
|
||||
register char *p = h->h_value;
|
||||
extern bool bitintersect();
|
||||
@ -1155,7 +1132,7 @@ putheader(mci, h, e)
|
||||
|
||||
/* suppress Content-Transfer-Encoding: if we are MIMEing */
|
||||
if (bitset(H_CTE, h->h_flags) &&
|
||||
bitset(MCIF_CVT8TO7|MCIF_INMIME, mci->mci_flags))
|
||||
bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags))
|
||||
{
|
||||
if (tTd(34, 11))
|
||||
printf(" (skipped (content-transfer-encoding))\n");
|
||||
@ -1166,7 +1143,8 @@ putheader(mci, h, e)
|
||||
{
|
||||
if (tTd(34, 11))
|
||||
printf("\n");
|
||||
goto vanilla;
|
||||
put_vanilla_header(h, p, mci);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bitset(H_CHECK|H_ACHECK, h->h_flags) &&
|
||||
@ -1239,31 +1217,7 @@ putheader(mci, h, e)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* vanilla header line */
|
||||
register char *nlp;
|
||||
register char *obp;
|
||||
|
||||
vanilla:
|
||||
obp = obuf;
|
||||
(void) snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ",
|
||||
h->h_field);
|
||||
obp = obuf + strlen(obuf);
|
||||
while ((nlp = strchr(p, '\n')) != NULL)
|
||||
{
|
||||
|
||||
*nlp = '\0';
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
|
||||
sizeof obuf - (obp - obuf) - 1, p);
|
||||
*nlp = '\n';
|
||||
putline(obuf, mci);
|
||||
p = ++nlp;
|
||||
obp = obuf;
|
||||
if (*p != ' ' && *p != '\t')
|
||||
*obp++ = ' ';
|
||||
}
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
|
||||
sizeof obuf - (obp - obuf) - 1, p);
|
||||
putline(obuf, mci);
|
||||
put_vanilla_header(h, p, mci);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1277,7 +1231,7 @@ putheader(mci, h, e)
|
||||
bitset(EF_HAS8BIT, e->e_flags) &&
|
||||
!bitset(EF_DONT_MIME, e->e_flags) &&
|
||||
!bitnset(M_8BITS, mci->mci_mailer->m_flags) &&
|
||||
!bitset(MCIF_CVT8TO7, mci->mci_flags))
|
||||
!bitset(MCIF_CVT8TO7|MCIF_CVT7TO8, mci->mci_flags))
|
||||
{
|
||||
if (hvalue("MIME-Version", e->e_header) == NULL)
|
||||
putline("MIME-Version: 1.0", mci);
|
||||
@ -1294,6 +1248,49 @@ putheader(mci, h, e)
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
** PUT_VANILLA_HEADER -- output a fairly ordinary header
|
||||
**
|
||||
** Parameters:
|
||||
** h -- the structure describing this header
|
||||
** v -- the value of this header
|
||||
** mci -- the connection info for output
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
put_vanilla_header(h, v, mci)
|
||||
HDR *h;
|
||||
char *v;
|
||||
MCI *mci;
|
||||
{
|
||||
register char *nlp;
|
||||
register char *obp;
|
||||
char obuf[MAXLINE];
|
||||
|
||||
(void) snprintf(obuf, sizeof obuf, "%.200s: ", h->h_field);
|
||||
obp = obuf + strlen(obuf);
|
||||
while ((nlp = strchr(v, '\n')) != NULL)
|
||||
{
|
||||
int l;
|
||||
|
||||
l = nlp - v;
|
||||
if (sizeof obuf - (obp - obuf) < l)
|
||||
l = sizeof obuf - (obp - obuf);
|
||||
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
|
||||
putline(obuf, mci);
|
||||
v += l + 1;
|
||||
obp = obuf;
|
||||
if (*v != ' ' && *v != '\t')
|
||||
*obp++ = ' ';
|
||||
}
|
||||
snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
|
||||
sizeof obuf - (obp - obuf) - 1, v);
|
||||
putline(obuf, mci);
|
||||
}
|
||||
/*
|
||||
** COMMAIZE -- output a header field, making a comma-translated list.
|
||||
**
|
||||
** Parameters:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -39,12 +39,13 @@ static char copyright[] =
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 8.162.1.3 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96";
|
||||
#endif /* not lint */
|
||||
|
||||
#define _DEFINE
|
||||
|
||||
#include "sendmail.h"
|
||||
#include <arpa/inet.h>
|
||||
#if NAMED_BIND
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
@ -75,14 +76,16 @@ char edata, end;
|
||||
** See the associated documentation for details.
|
||||
**
|
||||
** Author:
|
||||
** Eric Allman, UCB/INGRES (until 10/81)
|
||||
** Eric Allman, UCB/INGRES (until 10/81).
|
||||
** Britton-Lee, Inc., purveyors of fine
|
||||
** database computers (from 11/81)
|
||||
** Now back at UCB at the Mammoth project.
|
||||
** The support of the INGRES Project and Britton-Lee is
|
||||
** gratefully acknowledged. Britton-Lee in
|
||||
** particular had absolutely nothing to gain from
|
||||
** my involvement in this project.
|
||||
** database computers (11/81 - 10/88).
|
||||
** International Computer Science Institute
|
||||
** (11/88 - 9/89).
|
||||
** UCB/Mammoth Project (10/89 - 7/95).
|
||||
** InReference, Inc. (8/95 - present).
|
||||
** 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.
|
||||
*/
|
||||
|
||||
|
||||
@ -97,6 +100,8 @@ bool Warn_Q_option = FALSE; /* warn about Q option use */
|
||||
char **SaveArgv; /* argument vector for re-execing */
|
||||
|
||||
static void obsolete();
|
||||
extern void printmailer __P((MAILER *));
|
||||
extern void tTflag __P((char *));
|
||||
|
||||
#ifdef DAEMON
|
||||
#ifndef SMTP
|
||||
@ -104,7 +109,7 @@ ERROR %%%% Cannot have daemon mode without SMTP %%%% ERROR
|
||||
#endif /* SMTP */
|
||||
#endif /* DAEMON */
|
||||
|
||||
#define MAXCONFIGLEVEL 6 /* highest config version level known */
|
||||
#define MAXCONFIGLEVEL 7 /* highest config version level known */
|
||||
|
||||
int
|
||||
main(argc, argv, envp)
|
||||
@ -124,26 +129,40 @@ main(argc, argv, envp)
|
||||
bool safecf = TRUE;
|
||||
bool warn_C_flag = FALSE;
|
||||
char warn_f_flag = '\0';
|
||||
bool run_in_foreground = FALSE; /* -bD mode */
|
||||
static bool reenter = FALSE;
|
||||
struct passwd *pw;
|
||||
struct stat stb;
|
||||
struct hostent *hp;
|
||||
bool nullserver;
|
||||
char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */
|
||||
static char rnamebuf[MAXNAME]; /* holds RealUserName */
|
||||
char *emptyenviron[1];
|
||||
extern int DtableSize;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern char *optarg;
|
||||
extern char **environ;
|
||||
extern time_t convtime();
|
||||
extern void intsig();
|
||||
extern struct hostent *myhostname();
|
||||
extern char *arpadate();
|
||||
extern char *getauthinfo();
|
||||
extern char *getcfname();
|
||||
extern char *optarg;
|
||||
extern char **environ;
|
||||
extern void sigusr1();
|
||||
extern void sighup();
|
||||
extern void initmacros __P((ENVELOPE *));
|
||||
extern void init_md __P((int, char **));
|
||||
extern int getdtsize __P((void));
|
||||
extern void tTsetup __P((u_char *, int, char *));
|
||||
extern void setdefaults __P((ENVELOPE *));
|
||||
extern void initsetproctitle __P((int, char **, char **));
|
||||
extern void init_vendor_macros __P((ENVELOPE *));
|
||||
extern void load_if_names __P((void));
|
||||
extern void vendor_pre_defaults __P((ENVELOPE *));
|
||||
extern void vendor_post_defaults __P((ENVELOPE *));
|
||||
extern void readcf __P((char *, bool, ENVELOPE *));
|
||||
extern void printqueue __P((void));
|
||||
extern void sendtoargv __P((char **, ENVELOPE *));
|
||||
extern void resetlimits __P((void));
|
||||
|
||||
/*
|
||||
@ -159,6 +178,9 @@ main(argc, argv, envp)
|
||||
}
|
||||
reenter = TRUE;
|
||||
|
||||
/* avoid null pointer dereferences */
|
||||
TermEscape.te_rv_on = TermEscape.te_rv_off = "";
|
||||
|
||||
/* do machine-dependent initializations */
|
||||
init_md(argc, argv);
|
||||
|
||||
@ -205,6 +227,42 @@ main(argc, argv, envp)
|
||||
|
||||
tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
|
||||
|
||||
/* Handle any non-getoptable constructions. */
|
||||
obsolete(argv);
|
||||
|
||||
/*
|
||||
** Do a quick prescan of the argument list.
|
||||
*/
|
||||
|
||||
#if defined(__osf__) || defined(_AIX3)
|
||||
# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mN:nO:o:p:q:R:r:sTtUV:vX:x"
|
||||
#endif
|
||||
#if defined(sony_news)
|
||||
# define OPTIONS "B:b:C:cd:E:e:F:f:h:IiJ:M:mN:nO:o:p:q:R:r:sTtUV:vX:"
|
||||
#endif
|
||||
#ifndef OPTIONS
|
||||
# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mN:nO:o:p:q:R:r:sTtUV:vX:"
|
||||
#endif
|
||||
opterr = 0;
|
||||
while ((j = getopt(argc, argv, OPTIONS)) != EOF)
|
||||
{
|
||||
switch (j)
|
||||
{
|
||||
case 'd':
|
||||
/* hack attack -- see if should use ANSI mode */
|
||||
if (strcmp(optarg, "ANSI") == 0)
|
||||
{
|
||||
TermEscape.te_rv_on = "\033[7m";
|
||||
TermEscape.te_rv_off = "\033[0m";
|
||||
break;
|
||||
}
|
||||
tTflag(optarg);
|
||||
setbuf(stdout, (char *) NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
opterr = 1;
|
||||
|
||||
/* set up the blank envelope */
|
||||
BlankEnvelope.e_puthdr = putheader;
|
||||
BlankEnvelope.e_putbody = putbody;
|
||||
@ -247,35 +305,6 @@ main(argc, argv, envp)
|
||||
}
|
||||
SaveArgv[i] = NULL;
|
||||
|
||||
/* Handle any non-getoptable constructions. */
|
||||
obsolete(argv);
|
||||
|
||||
/*
|
||||
** Do a quick prescan of the argument list.
|
||||
*/
|
||||
|
||||
#if defined(__osf__) || defined(_AIX3)
|
||||
# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:x"
|
||||
#endif
|
||||
#if defined(sony_news)
|
||||
# define OPTIONS "B:b:C:cd:E:e:F:f:h:IiJ:M:mnO:o:p:q:r:sTtvX:"
|
||||
#endif
|
||||
#ifndef OPTIONS
|
||||
# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:"
|
||||
#endif
|
||||
opterr = 0;
|
||||
while ((j = getopt(argc, argv, OPTIONS)) != EOF)
|
||||
{
|
||||
switch (j)
|
||||
{
|
||||
case 'd':
|
||||
tTflag(optarg);
|
||||
setbuf(stdout, (char *) NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
opterr = 1;
|
||||
|
||||
if (tTd(0, 1))
|
||||
{
|
||||
int ll;
|
||||
@ -308,7 +337,7 @@ main(argc, argv, envp)
|
||||
int ll;
|
||||
extern char *OsCompileOptions[];
|
||||
|
||||
printf(" OS Defines:", Version);
|
||||
printf(" OS Defines:");
|
||||
av = OsCompileOptions;
|
||||
ll = 7;
|
||||
while (*av != NULL)
|
||||
@ -332,7 +361,7 @@ main(argc, argv, envp)
|
||||
#ifdef _PATH_UNIX
|
||||
printf("Kernel symbols:\t%s\n", _PATH_UNIX);
|
||||
#endif
|
||||
printf(" Config file:\t%s\n", getcfname());
|
||||
printf(" Def Conf file:\t%s\n", getcfname());
|
||||
printf(" Pid file:\t%s\n", PidFile);
|
||||
}
|
||||
|
||||
@ -342,6 +371,11 @@ main(argc, argv, envp)
|
||||
/* initialize for setproctitle */
|
||||
initsetproctitle(argc, argv, envp);
|
||||
|
||||
/* clear sendmail's environment */
|
||||
ExternalEnviron = environ;
|
||||
emptyenviron[0] = NULL;
|
||||
environ = emptyenviron;
|
||||
|
||||
/* prime the child environment */
|
||||
setuserenv("AGENT", "sendmail");
|
||||
|
||||
@ -351,7 +385,7 @@ main(argc, argv, envp)
|
||||
(void) setsignal(SIGPIPE, SIG_IGN);
|
||||
OldUmask = umask(022);
|
||||
OpMode = MD_DELIVER;
|
||||
FullName = getenv("NAME");
|
||||
FullName = getextenv("NAME");
|
||||
|
||||
#if NAMED_BIND
|
||||
if (tTd(8, 8))
|
||||
@ -393,6 +427,8 @@ main(argc, argv, envp)
|
||||
while (p != NULL && strchr(&p[1], '.') != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
if (tTd(0, 4))
|
||||
printf("\ta.k.a.: %s\n", jbuf);
|
||||
setclass('w', jbuf);
|
||||
*p++ = '.';
|
||||
p = strchr(p, '.');
|
||||
@ -448,13 +484,6 @@ main(argc, argv, envp)
|
||||
/* current time */
|
||||
define('b', arpadate((char *) NULL), CurEnv);
|
||||
|
||||
/*
|
||||
** Find our real host name for future logging.
|
||||
*/
|
||||
|
||||
p = getauthinfo(STDIN_FILENO);
|
||||
define('_', p, CurEnv);
|
||||
|
||||
/*
|
||||
** Crack argv.
|
||||
*/
|
||||
@ -469,6 +498,10 @@ main(argc, argv, envp)
|
||||
OpMode = MD_PRINT;
|
||||
else if (strcmp(p, "smtpd") == 0)
|
||||
OpMode = MD_DAEMON;
|
||||
else if (strcmp(p, "hoststat") == 0)
|
||||
OpMode = MD_HOSTSTAT;
|
||||
else if (strcmp(p, "purgestat") == 0)
|
||||
OpMode = MD_PURGESTAT;
|
||||
|
||||
optind = 1;
|
||||
while ((j = getopt(argc, argv, OPTIONS)) != EOF)
|
||||
@ -479,12 +512,15 @@ main(argc, argv, envp)
|
||||
switch (j = *optarg)
|
||||
{
|
||||
case MD_DAEMON:
|
||||
case MD_FGDAEMON:
|
||||
# ifdef DAEMON
|
||||
if (RealUid != 0) {
|
||||
if (RealUid != 0)
|
||||
{
|
||||
usrerr("Permission denied");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
(void) unsetenv("HOSTALIASES");
|
||||
vendor_daemon_setup(CurEnv);
|
||||
/* fall through ... */
|
||||
# else
|
||||
usrerr("Daemon mode not implemented");
|
||||
ExitStat = EX_USAGE;
|
||||
@ -496,11 +532,16 @@ main(argc, argv, envp)
|
||||
ExitStat = EX_USAGE;
|
||||
break;
|
||||
# endif /* SMTP */
|
||||
|
||||
case MD_INITALIAS:
|
||||
/* fall through ... */
|
||||
|
||||
case MD_DELIVER:
|
||||
case MD_VERIFY:
|
||||
case MD_TEST:
|
||||
case MD_INITALIAS:
|
||||
case MD_PRINT:
|
||||
case MD_HOSTSTAT:
|
||||
case MD_PURGESTAT:
|
||||
case MD_ARPAFTP:
|
||||
OpMode = j;
|
||||
break;
|
||||
@ -557,7 +598,6 @@ main(argc, argv, envp)
|
||||
{
|
||||
usrerr("Bad hop count (%s)", optarg);
|
||||
ExitStat = EX_USAGE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -565,6 +605,29 @@ main(argc, argv, envp)
|
||||
NoAlias = TRUE;
|
||||
break;
|
||||
|
||||
case 'N': /* delivery status notifications */
|
||||
DefaultNotify |= QHASNOTIFY;
|
||||
if (strcasecmp(optarg, "never") == 0)
|
||||
break;
|
||||
for (p = optarg; p != NULL; optarg = p)
|
||||
{
|
||||
p = strchr(p, ',');
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
if (strcasecmp(optarg, "success") == 0)
|
||||
DefaultNotify |= QPINGONSUCCESS;
|
||||
else if (strcasecmp(optarg, "failure") == 0)
|
||||
DefaultNotify |= QPINGONFAILURE;
|
||||
else if (strcasecmp(optarg, "delay") == 0)
|
||||
DefaultNotify |= QPINGONDELAY;
|
||||
else
|
||||
{
|
||||
usrerr("Invalid -N argument");
|
||||
ExitStat = EX_USAGE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o': /* set option */
|
||||
setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv);
|
||||
break;
|
||||
@ -595,7 +658,6 @@ main(argc, argv, envp)
|
||||
|
||||
case 'q': /* run queue files at intervals */
|
||||
# ifdef QUEUE
|
||||
(void) unsetenv("HOSTALIASES");
|
||||
FullName = NULL;
|
||||
queuemode = TRUE;
|
||||
switch (optarg[0])
|
||||
@ -622,10 +684,41 @@ main(argc, argv, envp)
|
||||
# endif /* QUEUE */
|
||||
break;
|
||||
|
||||
case 'R': /* DSN RET: what to return */
|
||||
if (bitset(EF_RET_PARAM, CurEnv->e_flags))
|
||||
{
|
||||
usrerr("Duplicate -R flag");
|
||||
ExitStat = EX_USAGE;
|
||||
break;
|
||||
}
|
||||
CurEnv->e_flags |= EF_RET_PARAM;
|
||||
if (strcasecmp(optarg, "hdrs") == 0)
|
||||
CurEnv->e_flags |= EF_NO_BODY_RETN;
|
||||
else if (strcasecmp(optarg, "full") != 0)
|
||||
{
|
||||
usrerr("Invalid -R value");
|
||||
ExitStat = EX_USAGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't': /* read recipients from message */
|
||||
GrabTo = TRUE;
|
||||
break;
|
||||
|
||||
case 'U': /* initial (user) submission */
|
||||
UserSubmission = TRUE;
|
||||
break;
|
||||
|
||||
case 'V': /* DSN ENVID: set "original" envelope id */
|
||||
if (!xtextok(optarg))
|
||||
{
|
||||
usrerr("Invalid syntax in -V flag");
|
||||
ExitStat = EX_USAGE;
|
||||
}
|
||||
else
|
||||
CurEnv->e_envid = newstr(optarg);
|
||||
break;
|
||||
|
||||
case 'X': /* traffic log file */
|
||||
endpwent();
|
||||
setgid(RealGid);
|
||||
@ -634,6 +727,7 @@ main(argc, argv, envp)
|
||||
if (TrafficLogFile == NULL)
|
||||
{
|
||||
syserr("cannot open %s", optarg);
|
||||
ExitStat = EX_CANTCREAT;
|
||||
break;
|
||||
}
|
||||
#ifdef HASSETVBUF
|
||||
@ -706,11 +800,28 @@ main(argc, argv, envp)
|
||||
#endif
|
||||
vendor_pre_defaults(CurEnv);
|
||||
readcf(getcfname(), safecf, CurEnv);
|
||||
ConfigFileRead = TRUE;
|
||||
vendor_post_defaults(CurEnv);
|
||||
|
||||
/* avoid denial-of-service attacks */
|
||||
resetlimits();
|
||||
|
||||
if (OpMode != MD_DAEMON && OpMode != MD_FGDAEMON)
|
||||
{
|
||||
/* drop privileges -- daemon mode done after socket/bind */
|
||||
if (RunAsGid != 0)
|
||||
(void) setgid(RunAsGid);
|
||||
if (RunAsUid != 0)
|
||||
(void) setuid(RunAsUid);
|
||||
}
|
||||
|
||||
/*
|
||||
** Find our real host name for future logging.
|
||||
*/
|
||||
|
||||
p = getauthinfo(STDIN_FILENO);
|
||||
define('_', p, CurEnv);
|
||||
|
||||
/* suppress error printing if errors mailed back or whatever */
|
||||
if (CurEnv->e_errormode != EM_PRINT)
|
||||
HoldErrs = TRUE;
|
||||
@ -770,6 +881,10 @@ main(argc, argv, envp)
|
||||
CurEnv->e_bodytype = NULL;
|
||||
}
|
||||
|
||||
/* tweak default DSN notifications */
|
||||
if (DefaultNotify == 0)
|
||||
DefaultNotify = QPINGONFAILURE|QPINGONDELAY;
|
||||
|
||||
/* Enforce use of local time (null string overrides this) */
|
||||
if (TimeZoneSpec == NULL)
|
||||
unsetenv("TZ");
|
||||
@ -786,18 +901,49 @@ main(argc, argv, envp)
|
||||
ConfigLevel, MAXCONFIGLEVEL);
|
||||
}
|
||||
|
||||
/* need MCI cache to have persistence */
|
||||
if (HostStatDir != NULL && MaxMciCache == 0)
|
||||
{
|
||||
HostStatDir = NULL;
|
||||
printf("Warning: HostStatusDirectory disabled with ConnectionCacheSize = 0\n");
|
||||
}
|
||||
|
||||
/* need HostStatusDir in order to have SingleThreadDelivery */
|
||||
if (SingleThreadDelivery && HostStatDir == NULL)
|
||||
{
|
||||
SingleThreadDelivery = FALSE;
|
||||
printf("Warning: HostStatusDirectory required for SingleThreadDelivery\n");
|
||||
}
|
||||
|
||||
if (MeToo)
|
||||
BlankEnvelope.e_flags |= EF_METOO;
|
||||
|
||||
switch (OpMode)
|
||||
{
|
||||
case MD_TEST:
|
||||
/* don't have persistent host status in test mode */
|
||||
HostStatDir = NULL;
|
||||
break;
|
||||
|
||||
case MD_FGDAEMON:
|
||||
run_in_foreground = TRUE;
|
||||
OpMode = MD_DAEMON;
|
||||
/* fall through ... */
|
||||
|
||||
case MD_DAEMON:
|
||||
/* remove things that don't make sense in daemon mode */
|
||||
FullName = NULL;
|
||||
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
|
||||
setsignal(SIGHUP, sighup);
|
||||
|
||||
/* workaround: can't seem to release the signal in the parent */
|
||||
releasesignal(SIGHUP);
|
||||
break;
|
||||
|
||||
case MD_INITALIAS:
|
||||
@ -908,11 +1054,20 @@ main(argc, argv, envp)
|
||||
setuserenv("ISP", NULL);
|
||||
setuserenv("SYSTYPE", NULL);
|
||||
}
|
||||
if (ConfigLevel < 7)
|
||||
{
|
||||
if (LocalMailer != NULL)
|
||||
setbitn(M_VRFY250, LocalMailer->m_flags);
|
||||
if (ProgMailer != NULL)
|
||||
setbitn(M_VRFY250, ProgMailer->m_flags);
|
||||
if (FileMailer != NULL)
|
||||
setbitn(M_VRFY250, FileMailer->m_flags);
|
||||
}
|
||||
|
||||
/* MIME Content-Types that cannot be transfer encoded */
|
||||
setclass('n', "multipart/signed");
|
||||
|
||||
/* MIME message/* subtypes that can be treated as messages */
|
||||
/* MIME message/xxx subtypes that can be treated as messages */
|
||||
setclass('s', "rfc822");
|
||||
|
||||
/* MIME Content-Transfer-Encodings that can be encoded */
|
||||
@ -920,11 +1075,36 @@ main(argc, argv, envp)
|
||||
setclass('e', "8bit");
|
||||
setclass('e', "binary");
|
||||
|
||||
#ifdef USE_B_CLASS
|
||||
/* MIME Content-Types that should be treated as binary */
|
||||
setclass('b', "image");
|
||||
setclass('b', "audio");
|
||||
setclass('b', "video");
|
||||
setclass('b', "application/octet-stream");
|
||||
#endif
|
||||
|
||||
/* operate in queue directory */
|
||||
if (OpMode != MD_TEST && chdir(QueueDir) < 0)
|
||||
if (OpMode == MD_TEST)
|
||||
/* nothing -- just avoid further if clauses */ ;
|
||||
else if (QueueDir == NULL)
|
||||
{
|
||||
syserr("QueueDirectory (Q) option must be set");
|
||||
ExitStat = EX_CONFIG;
|
||||
}
|
||||
else if (chdir(QueueDir) < 0)
|
||||
{
|
||||
syserr("cannot chdir(%s)", QueueDir);
|
||||
ExitStat = EX_SOFTWARE;
|
||||
ExitStat = EX_CONFIG;
|
||||
}
|
||||
|
||||
/* check host status directory for validity */
|
||||
if (HostStatDir != NULL && !path_is_dir(HostStatDir, FALSE))
|
||||
{
|
||||
/* cannot use this value */
|
||||
if (tTd(0, 2))
|
||||
printf("Cannot use HostStatusDirectory = %s: %s\n",
|
||||
HostStatDir, errstring(errno));
|
||||
HostStatDir = NULL;
|
||||
}
|
||||
|
||||
# ifdef QUEUE
|
||||
@ -965,7 +1145,7 @@ main(argc, argv, envp)
|
||||
case MD_PRINT:
|
||||
/* print the queue */
|
||||
#ifdef QUEUE
|
||||
dropenvelope(CurEnv);
|
||||
dropenvelope(CurEnv, TRUE);
|
||||
printqueue();
|
||||
endpwent();
|
||||
setuid(RealUid);
|
||||
@ -975,15 +1155,33 @@ main(argc, argv, envp)
|
||||
finis();
|
||||
#endif /* QUEUE */
|
||||
|
||||
case MD_HOSTSTAT:
|
||||
mci_traverse_persistent(mci_print_persistent, NULL);
|
||||
exit(EX_OK);
|
||||
break;
|
||||
|
||||
case MD_PURGESTAT:
|
||||
mci_traverse_persistent(mci_purge_persistent, NULL);
|
||||
exit(EX_OK);
|
||||
break;
|
||||
|
||||
case MD_INITALIAS:
|
||||
/* initialize alias database */
|
||||
initmaps(TRUE, CurEnv);
|
||||
endpwent();
|
||||
setuid(RealUid);
|
||||
exit(EX_OK);
|
||||
exit(ExitStat);
|
||||
|
||||
case MD_SMTP:
|
||||
nullserver = FALSE;
|
||||
/* fall through... */
|
||||
|
||||
case MD_DAEMON:
|
||||
case MD_SMTP:
|
||||
/* reset DSN parameters */
|
||||
DefaultNotify = QPINGONFAILURE|QPINGONDELAY;
|
||||
CurEnv->e_envid = NULL;
|
||||
CurEnv->e_flags &= ~(EF_RET_PARAM|EF_NO_BODY_RETN);
|
||||
|
||||
/* don't open alias database -- done in srvrsmtp */
|
||||
break;
|
||||
|
||||
@ -995,6 +1193,8 @@ main(argc, argv, envp)
|
||||
|
||||
if (tTd(0, 15))
|
||||
{
|
||||
extern void printrules __P((void));
|
||||
|
||||
/* print configuration table (or at least part of it) */
|
||||
if (tTd(0, 90))
|
||||
printrules();
|
||||
@ -1075,8 +1275,9 @@ main(argc, argv, envp)
|
||||
if (OpMode == MD_DAEMON || QueueIntvl != 0)
|
||||
{
|
||||
char dtype[200];
|
||||
extern bool getrequests __P((ENVELOPE *));
|
||||
|
||||
if (!tTd(99, 100))
|
||||
if (!run_in_foreground && !tTd(99, 100))
|
||||
{
|
||||
/* put us in background */
|
||||
i = fork();
|
||||
@ -1116,10 +1317,16 @@ main(argc, argv, envp)
|
||||
pause();
|
||||
}
|
||||
# endif /* QUEUE */
|
||||
dropenvelope(CurEnv);
|
||||
dropenvelope(CurEnv, TRUE);
|
||||
|
||||
#ifdef DAEMON
|
||||
getrequests();
|
||||
nullserver = getrequests(CurEnv);
|
||||
|
||||
/* drop privileges */
|
||||
if (RunAsGid != 0)
|
||||
(void) setgid(RunAsGid);
|
||||
if (RunAsUid != 0)
|
||||
(void) setuid(RunAsUid);
|
||||
|
||||
/* at this point we are in a child: reset state */
|
||||
(void) newenvelope(CurEnv, CurEnv);
|
||||
@ -1129,8 +1336,7 @@ main(argc, argv, envp)
|
||||
*/
|
||||
|
||||
p = getauthinfo(fileno(InChannel));
|
||||
define('_', p, CurEnv);
|
||||
|
||||
define('_', p, &BlankEnvelope);
|
||||
#endif /* DAEMON */
|
||||
}
|
||||
|
||||
@ -1141,14 +1347,34 @@ main(argc, argv, envp)
|
||||
*/
|
||||
|
||||
if (OpMode == MD_SMTP || OpMode == MD_DAEMON)
|
||||
smtp(CurEnv);
|
||||
{
|
||||
char pbuf[20];
|
||||
extern void smtp __P((bool, ENVELOPE *));
|
||||
|
||||
/*
|
||||
** Save some macros for check_* rulesets.
|
||||
*/
|
||||
|
||||
define(macid("{client_name}", NULL), RealHostName, &BlankEnvelope);
|
||||
define(macid("{client_addr}", NULL),
|
||||
newstr(anynet_ntoa(&RealHostAddr)), &BlankEnvelope);
|
||||
if (RealHostAddr.sa.sa_family == AF_INET)
|
||||
snprintf(pbuf, sizeof pbuf, "%d", RealHostAddr.sin.sin_port);
|
||||
else
|
||||
snprintf(pbuf, sizeof pbuf, "0");
|
||||
define(macid("{client_port}", NULL), newstr(pbuf), &BlankEnvelope);
|
||||
|
||||
smtp(nullserver, CurEnv);
|
||||
}
|
||||
# endif /* SMTP */
|
||||
|
||||
clearenvelope(CurEnv, FALSE);
|
||||
if (OpMode == MD_VERIFY)
|
||||
{
|
||||
CurEnv->e_sendmode = SM_VERIFY;
|
||||
CurEnv->e_errormode = EM_QUIET;
|
||||
CurEnv->e_errormode = EM_PRINT;
|
||||
PostMasterCopy = NULL;
|
||||
HoldErrs = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1224,6 +1450,8 @@ main(argc, argv, envp)
|
||||
*/
|
||||
|
||||
finis();
|
||||
/*NOTREACHED*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -1264,7 +1492,8 @@ finis()
|
||||
|
||||
/* clean up temp files */
|
||||
CurEnv->e_to = NULL;
|
||||
dropenvelope(CurEnv);
|
||||
if (CurEnv->e_id != NULL)
|
||||
dropenvelope(CurEnv, TRUE);
|
||||
|
||||
/* flush any cached connections */
|
||||
mci_flush(TRUE, NULL);
|
||||
@ -1307,6 +1536,11 @@ finis()
|
||||
void
|
||||
intsig()
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel > 79)
|
||||
syslog(LOG_DEBUG, "%s: interrupt",
|
||||
CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id);
|
||||
#endif
|
||||
FileName = NULL;
|
||||
unlockqueue(CurEnv);
|
||||
#ifdef XLA
|
||||
@ -1338,24 +1572,24 @@ intsig()
|
||||
struct metamac MetaMacros[] =
|
||||
{
|
||||
/* LHS pattern matching characters */
|
||||
'*', MATCHZANY, '+', MATCHANY, '-', MATCHONE,
|
||||
'=', MATCHCLASS, '~', MATCHNCLASS,
|
||||
{ '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE },
|
||||
{ '=', MATCHCLASS }, { '~', MATCHNCLASS },
|
||||
|
||||
/* these are RHS metasymbols */
|
||||
'#', CANONNET, '@', CANONHOST, ':', CANONUSER,
|
||||
'>', CALLSUBR,
|
||||
{ '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER },
|
||||
{ '>', CALLSUBR },
|
||||
|
||||
/* the conditional operations */
|
||||
'?', CONDIF, '|', CONDELSE, '.', CONDFI,
|
||||
{ '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI },
|
||||
|
||||
/* the hostname lookup characters */
|
||||
'[', HOSTBEGIN, ']', HOSTEND,
|
||||
'(', LOOKUPBEGIN, ')', LOOKUPEND,
|
||||
{ '[', HOSTBEGIN }, { ']', HOSTEND },
|
||||
{ '(', LOOKUPBEGIN }, { ')', LOOKUPEND },
|
||||
|
||||
/* miscellaneous control characters */
|
||||
'&', MACRODEXPAND,
|
||||
{ '&', MACRODEXPAND },
|
||||
|
||||
'\0'
|
||||
{ '\0' }
|
||||
};
|
||||
|
||||
#define MACBINDING(name, mid) \
|
||||
@ -1427,6 +1661,11 @@ 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
|
||||
|
||||
/* be sure we don't get nasty signals */
|
||||
(void) setsignal(SIGINT, SIG_IGN);
|
||||
@ -1576,7 +1815,7 @@ auth_warning(e, msg, va_alist)
|
||||
(void) snprintf(buf, sizeof buf, "%s: ", hostbuf);
|
||||
p = &buf[strlen(buf)];
|
||||
VA_START(msg);
|
||||
vsnprintf(p, sizeof buf - (p - buf), msg, ap);
|
||||
vsnprintf(p, SPACELEFT(buf, p), msg, ap);
|
||||
VA_END;
|
||||
addheader("X-Authentication-Warning", buf, &e->e_header);
|
||||
#ifdef LOG
|
||||
@ -1587,6 +1826,31 @@ auth_warning(e, msg, va_alist)
|
||||
}
|
||||
}
|
||||
/*
|
||||
** GETEXTENV -- get from external environment
|
||||
**
|
||||
** Parameters:
|
||||
** envar -- the name of the variable to retrieve
|
||||
**
|
||||
** Returns:
|
||||
** The value, if any.
|
||||
*/
|
||||
|
||||
char *
|
||||
getextenv(envar)
|
||||
const char *envar;
|
||||
{
|
||||
char **envp;
|
||||
int l;
|
||||
|
||||
l = strlen(envar);
|
||||
for (envp = ExternalEnviron; *envp != NULL; envp++)
|
||||
{
|
||||
if (strncmp(*envp, envar, l) == 0 && (*envp)[l] == '=')
|
||||
return &(*envp)[l + 1];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
** SETUSERENV -- set an environment in the propogated environment
|
||||
**
|
||||
** Parameters:
|
||||
@ -1611,7 +1875,7 @@ setuserenv(envar, value)
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
value = getenv(envar);
|
||||
value = getextenv(envar);
|
||||
if (value == NULL)
|
||||
return;
|
||||
}
|
||||
@ -1650,6 +1914,7 @@ dumpstate(when)
|
||||
{
|
||||
#ifdef LOG
|
||||
register char *j = macvalue('j', CurEnv);
|
||||
int rs;
|
||||
|
||||
syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
|
||||
when,
|
||||
@ -1664,15 +1929,17 @@ dumpstate(when)
|
||||
printopenfds(TRUE);
|
||||
syslog(LOG_DEBUG, "--- connection cache: ---");
|
||||
mci_dump_all(TRUE);
|
||||
if (RewriteRules[89] != NULL)
|
||||
rs = strtorwset("debug_dumpstate", NULL, ST_FIND);
|
||||
if (rs > 0)
|
||||
{
|
||||
int stat;
|
||||
register char **pvp;
|
||||
char *pv[MAXATOM + 1];
|
||||
|
||||
pv[0] = NULL;
|
||||
stat = rewrite(pv, 89, 0, CurEnv);
|
||||
syslog(LOG_DEBUG, "--- ruleset 89 returns stat %d, pv: ---",
|
||||
stat = rewrite(pv, rs, 0, CurEnv);
|
||||
syslog(LOG_DEBUG,
|
||||
"--- ruleset debug_dumpstate returns stat %d, pv: ---",
|
||||
stat);
|
||||
for (pvp = pv; *pvp != NULL; pvp++)
|
||||
syslog(LOG_DEBUG, "%s", *pvp);
|
||||
@ -1739,6 +2006,7 @@ testmodeline(line, e)
|
||||
extern char *crackaddr __P((char *));
|
||||
extern void dump_class __P((STAB *, int));
|
||||
extern void translate_dollars __P((char *));
|
||||
extern void help __P((char *));
|
||||
|
||||
switch (line[0])
|
||||
{
|
||||
@ -1805,7 +2073,10 @@ testmodeline(line, e)
|
||||
case 'S': /* dump rule set */
|
||||
rs = strtorwset(&line[2], NULL, ST_FIND);
|
||||
if (rs < 0)
|
||||
{
|
||||
printf("Undefined ruleset %s\n", &line[2]);
|
||||
return;
|
||||
}
|
||||
rw = RewriteRules[rs];
|
||||
if (rw == NULL)
|
||||
return;
|
||||
@ -1827,7 +2098,7 @@ testmodeline(line, e)
|
||||
putchar(' ');
|
||||
}
|
||||
putchar('\n');
|
||||
} while (rw = rw->r_next);
|
||||
} while ((rw = rw->r_next) != NULL);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
@ -1926,7 +2197,6 @@ testmodeline(line, e)
|
||||
}
|
||||
else if (strcasecmp(&line[1], "canon") == 0)
|
||||
{
|
||||
auto int rcode = EX_OK;
|
||||
char host[MAXHOSTNAMELEN];
|
||||
|
||||
if (*p == '\0')
|
||||
@ -1940,9 +2210,8 @@ testmodeline(line, e)
|
||||
return;
|
||||
}
|
||||
strcpy(host, p);
|
||||
getcanonname(host, sizeof(host), HasWildcardMX, &rcode);
|
||||
printf("getcanonname(%s) returns %s (%d)\n",
|
||||
p, host, rcode);
|
||||
(void) getcanonname(host, sizeof(host), HasWildcardMX);
|
||||
printf("getcanonname(%s) returns %s\n", p, host);
|
||||
}
|
||||
else if (strcasecmp(&line[1], "map") == 0)
|
||||
{
|
||||
@ -2006,6 +2275,7 @@ testmodeline(line, e)
|
||||
p = remotename(q, m, tryflags, &rcode, CurEnv);
|
||||
printf("Rcode = %d, addr = %s\n",
|
||||
rcode, p == NULL ? "<NULL>" : p);
|
||||
e->e_to = NULL;
|
||||
}
|
||||
else if (strcasecmp(&line[1], "tryflags") == 0)
|
||||
{
|
||||
@ -2061,6 +2331,7 @@ testmodeline(line, e)
|
||||
else
|
||||
printf("mailer %s, user %s\n",
|
||||
a.q_mailer->m_name, a.q_user);
|
||||
e->e_to = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2098,7 +2369,10 @@ testmodeline(line, e)
|
||||
int rs = strtorwset(p, NULL, ST_FIND);
|
||||
|
||||
if (rs < 0)
|
||||
{
|
||||
printf("Undefined ruleset %s\n", p);
|
||||
break;
|
||||
}
|
||||
stat = rewrite(pvp, rs, 0, e);
|
||||
if (stat != EX_OK)
|
||||
printf("== Ruleset %s (%d) status %d\n",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)parseaddr.c 8.87.1.1 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)parseaddr.c 8.114 (Berkeley) 9/20/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
@ -169,7 +169,7 @@ parseaddr(addr, a, flags, delim, delimptr, e)
|
||||
** If there was a parsing failure, mark it for queueing.
|
||||
*/
|
||||
|
||||
if (queueup)
|
||||
if (queueup && OpMode != MD_INITALIAS)
|
||||
{
|
||||
char *msg = "Transient parse error -- message queued for future delivery";
|
||||
|
||||
@ -220,14 +220,6 @@ invalidaddr(addr, delimptr)
|
||||
if (savedelim != '\0')
|
||||
*delimptr = '\0';
|
||||
}
|
||||
#if 0
|
||||
/* for testing.... */
|
||||
if (strcmp(addr, "INvalidADDR") == 0)
|
||||
{
|
||||
usrerr("553 INvalid ADDRess");
|
||||
goto addrfailure;
|
||||
}
|
||||
#endif
|
||||
for (; *addr != '\0'; addr++)
|
||||
{
|
||||
if ((*addr & 0340) == 0200)
|
||||
@ -241,7 +233,6 @@ invalidaddr(addr, delimptr)
|
||||
}
|
||||
setstat(EX_USAGE);
|
||||
usrerr("553 Address contained invalid control characters");
|
||||
addrfailure:
|
||||
if (delimptr != NULL && savedelim != '\0')
|
||||
*delimptr = savedelim;
|
||||
return TRUE;
|
||||
@ -343,12 +334,12 @@ allocaddr(a, flags, paddr)
|
||||
static short StateTab[NSTATES][NSTATES] =
|
||||
{
|
||||
/* oldst chtype> OPR ATM QST SPC ONE ILL */
|
||||
/*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB,
|
||||
/*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB,
|
||||
/*QST*/ QST, QST, OPR, QST, QST, QST,
|
||||
/*SPC*/ OPR, ATM, QST, SPC|M, ONE, ILL|MB,
|
||||
/*ONE*/ OPR, OPR, OPR, OPR, OPR, ILL|MB,
|
||||
/*ILL*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M,
|
||||
/*OPR*/ { OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB },
|
||||
/*ATM*/ { OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB },
|
||||
/*QST*/ { QST, QST, OPR, QST, QST, QST },
|
||||
/*SPC*/ { OPR, ATM, QST, SPC|M, ONE, ILL|MB },
|
||||
/*ONE*/ { OPR, OPR, OPR, OPR, OPR, ILL|MB },
|
||||
/*ILL*/ { OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M },
|
||||
};
|
||||
|
||||
/* token type table -- it gets modified with $o characters */
|
||||
@ -444,6 +435,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
register int c;
|
||||
char **avp;
|
||||
bool bslashmode;
|
||||
bool route_syntax;
|
||||
int cmntcnt;
|
||||
int anglecnt;
|
||||
char *tok;
|
||||
@ -483,6 +475,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
|
||||
q = pvpbuf;
|
||||
bslashmode = FALSE;
|
||||
route_syntax = FALSE;
|
||||
cmntcnt = 0;
|
||||
anglecnt = 0;
|
||||
avp = av;
|
||||
@ -510,7 +503,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
if (q >= &pvpbuf[pvpbsize - 5])
|
||||
{
|
||||
usrerr("553 Address too long");
|
||||
if (strlen(addr) > MAXNAME)
|
||||
if (strlen(addr) > (SIZE_T) MAXNAME)
|
||||
addr[MAXNAME] = '\0';
|
||||
returnnull:
|
||||
if (delimptr != NULL)
|
||||
@ -548,10 +541,20 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
|
||||
p--;
|
||||
}
|
||||
else if (c == delim && anglecnt <= 0 &&
|
||||
cmntcnt <= 0 && state != QST)
|
||||
else if (c == delim && cmntcnt <= 0 && state != QST)
|
||||
{
|
||||
if (anglecnt <= 0)
|
||||
break;
|
||||
|
||||
/* special case for better error management */
|
||||
if (delim == ',' && !route_syntax)
|
||||
{
|
||||
usrerr("653 Unbalanced '<'");
|
||||
c = '>';
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
if (tTd(22, 101))
|
||||
printf("c=%c, s=%d; ", c, state);
|
||||
|
||||
@ -600,7 +603,15 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
else if (cmntcnt > 0)
|
||||
c = NOCHAR;
|
||||
else if (c == '<')
|
||||
{
|
||||
char *q = p;
|
||||
|
||||
anglecnt++;
|
||||
while (isascii(*q) && isspace(*q))
|
||||
q++;
|
||||
if (*q == '@')
|
||||
route_syntax = TRUE;
|
||||
}
|
||||
else if (c == '>')
|
||||
{
|
||||
if (anglecnt <= 0)
|
||||
@ -610,6 +621,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
|
||||
}
|
||||
else
|
||||
anglecnt--;
|
||||
route_syntax = FALSE;
|
||||
}
|
||||
else if (delim == ' ' && isascii(c) && isspace(c))
|
||||
c = ' ';
|
||||
@ -743,10 +755,11 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
int loopcount;
|
||||
struct match mlist[MAXMATCH]; /* stores match on LHS */
|
||||
char *npvp[MAXATOM+1]; /* temporary space for rebuild */
|
||||
extern int callsubr __P((char**, int, ENVELOPE *));
|
||||
|
||||
if (OpMode == MD_TEST || tTd(21, 1))
|
||||
{
|
||||
printf("rewrite: ruleset %2d input:", ruleset);
|
||||
printf("rewrite: ruleset %3d input:", ruleset);
|
||||
printav(pvp);
|
||||
}
|
||||
if (ruleset < 0 || ruleset >= MAXRWSETS)
|
||||
@ -772,6 +785,12 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
loopcount = 0;
|
||||
for (rwr = RewriteRules[ruleset]; rwr != NULL; )
|
||||
{
|
||||
int stat;
|
||||
|
||||
/* if already canonical, quit now */
|
||||
if (pvp[0] != NULL && (pvp[0][0] & 0377) == CANONNET)
|
||||
break;
|
||||
|
||||
if (tTd(21, 12))
|
||||
{
|
||||
printf("-----trying rule:");
|
||||
@ -1002,8 +1021,6 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
rvp++;
|
||||
rwr = NULL;
|
||||
}
|
||||
else if ((*rp & 0377) == CANONNET)
|
||||
rwr = NULL;
|
||||
|
||||
/* substitute */
|
||||
for (avp = npvp; *rvp != NULL; rvp++)
|
||||
@ -1091,6 +1108,7 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
char *argvect[10];
|
||||
char pvpbuf[PSBUFSIZE];
|
||||
char *nullpvp[1];
|
||||
extern char *map_lookup __P((STAB *, char *, char **, int *, ENVELOPE *));
|
||||
|
||||
if ((**rvp & 0377) != HOSTBEGIN &&
|
||||
(**rvp & 0377) != LOOKUPBEGIN)
|
||||
@ -1173,55 +1191,7 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
/* look it up */
|
||||
cataddr(key_rvp, NULL, buf, sizeof buf, '\0');
|
||||
argvect[0] = buf;
|
||||
if (e->e_sendmode == SM_DEFER)
|
||||
{
|
||||
/* don't do any map lookups */
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) => DEFERRED\n",
|
||||
mapname, buf);
|
||||
replac = NULL;
|
||||
rstat = EX_TEMPFAIL;
|
||||
}
|
||||
else if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags))
|
||||
{
|
||||
auto int stat = EX_OK;
|
||||
|
||||
if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags))
|
||||
stripquotes(buf);
|
||||
|
||||
/* XXX should try to auto-open the map here */
|
||||
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) => ",
|
||||
mapname, buf);
|
||||
replac = (*map->s_map.map_class->map_lookup)(&map->s_map,
|
||||
buf, argvect, &stat);
|
||||
if (tTd(60, 1))
|
||||
printf("%s (%d)\n",
|
||||
replac ? replac : "NOT FOUND",
|
||||
stat);
|
||||
|
||||
/* should recover if stat == EX_TEMPFAIL */
|
||||
if (stat == EX_TEMPFAIL)
|
||||
{
|
||||
rstat = EX_TEMPFAIL;
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) tempfail: errno=%d\n",
|
||||
mapname, buf, errno);
|
||||
if (e->e_message == NULL)
|
||||
{
|
||||
char mbuf[300];
|
||||
|
||||
snprintf(mbuf, sizeof mbuf,
|
||||
"%.80s map: lookup (%s): deferred",
|
||||
mapname,
|
||||
shortenstring(buf, 203));
|
||||
e->e_message = newstr(mbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
replac = NULL;
|
||||
replac = map_lookup(map, buf, argvect, &rstat, e);
|
||||
|
||||
/* if no replacement, use default */
|
||||
if (replac == NULL && default_rvp != NULL)
|
||||
@ -1273,38 +1243,16 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
** Check for subroutine calls.
|
||||
*/
|
||||
|
||||
if (*npvp != NULL && (**npvp & 0377) == CALLSUBR)
|
||||
{
|
||||
int stat;
|
||||
|
||||
if (npvp[1] == NULL)
|
||||
{
|
||||
syserr("parseaddr: NULL subroutine call in ruleset %d, rule %d",
|
||||
ruleset, ruleno);
|
||||
*pvp = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ruleset;
|
||||
STAB *s;
|
||||
|
||||
bcopy((char *) &npvp[2], (char *) pvp,
|
||||
(int) (avp - npvp - 2) * sizeof *avp);
|
||||
if (tTd(21, 3))
|
||||
printf("-----callsubr %s\n", npvp[1]);
|
||||
ruleset = strtorwset(npvp[1], NULL, ST_FIND);
|
||||
stat = rewrite(pvp, ruleset, reclevel, e);
|
||||
stat = callsubr(npvp, reclevel, e);
|
||||
if (rstat == EX_OK || stat == EX_TEMPFAIL)
|
||||
rstat = stat;
|
||||
if (*pvp != NULL && (**pvp & 0377) == CANONNET)
|
||||
rwr = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* copy vector back into original space. */
|
||||
for (avp = npvp; *avp++ != NULL;)
|
||||
continue;
|
||||
bcopy((char *) npvp, (char *) pvp,
|
||||
(int) (avp - npvp) * sizeof *avp);
|
||||
}
|
||||
|
||||
if (tTd(21, 4))
|
||||
{
|
||||
printf("rewritten as:");
|
||||
@ -1314,13 +1262,192 @@ rewrite(pvp, ruleset, reclevel, e)
|
||||
|
||||
if (OpMode == MD_TEST || tTd(21, 1))
|
||||
{
|
||||
printf("rewrite: ruleset %2d returns:", ruleset);
|
||||
printf("rewrite: ruleset %3d returns:", ruleset);
|
||||
printav(pvp);
|
||||
}
|
||||
|
||||
return rstat;
|
||||
}
|
||||
/*
|
||||
** CALLSUBR -- call subroutines in rewrite vector
|
||||
**
|
||||
** Parameters:
|
||||
** pvp -- pointer to token vector.
|
||||
** reclevel -- the current recursion level.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** The status from the subroutine call.
|
||||
**
|
||||
** Side Effects:
|
||||
** pvp is modified.
|
||||
*/
|
||||
|
||||
int
|
||||
callsubr(pvp, reclevel, e)
|
||||
char **pvp;
|
||||
int reclevel;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
char **avp;
|
||||
char **rvp;
|
||||
register int i;
|
||||
int subr;
|
||||
int stat;
|
||||
int rstat = EX_OK;
|
||||
char *tpvp[MAXATOM + 1];
|
||||
|
||||
for (avp = pvp; *avp != NULL; avp++)
|
||||
{
|
||||
if ((**avp & 0377) == CALLSUBR && avp[1] != NULL)
|
||||
{
|
||||
subr = strtorwset(avp[1], NULL, ST_FIND);
|
||||
if (subr < 0)
|
||||
{
|
||||
syserr("Unknown ruleset %s", avp[1]);
|
||||
return EX_CONFIG;
|
||||
}
|
||||
|
||||
if (tTd(21, 3))
|
||||
printf("-----callsubr %s (%d)\n", avp[1], subr);
|
||||
|
||||
/*
|
||||
** Take care of possible inner calls first.
|
||||
** use a full size temporary buffer to avoid
|
||||
** overflows in rewrite, but strip off the
|
||||
** subroutine call.
|
||||
*/
|
||||
|
||||
for (i = 2; avp[i] != NULL; i++)
|
||||
tpvp[i - 2] = avp[i];
|
||||
tpvp[i - 2] = NULL;
|
||||
|
||||
stat = callsubr(tpvp, reclevel, e);
|
||||
if (rstat == EX_OK || stat == EX_TEMPFAIL)
|
||||
rstat = stat;
|
||||
|
||||
/*
|
||||
** Now we need to call the ruleset specified for
|
||||
** the subroutine. we can do this with the
|
||||
** temporary buffer that we set up earlier,
|
||||
** since it has all the data we want to rewrite.
|
||||
*/
|
||||
|
||||
stat = rewrite(tpvp, subr, reclevel, e);
|
||||
if (rstat == EX_OK || stat == EX_TEMPFAIL)
|
||||
rstat = stat;
|
||||
|
||||
/*
|
||||
** Find length of tpvp and current offset into
|
||||
** pvp, if the total is greater than MAXATOM,
|
||||
** then it would overflow the buffer if we copied
|
||||
** it back in to pvp, in which case we throw a
|
||||
** fit.
|
||||
*/
|
||||
|
||||
for (rvp = tpvp; *rvp != NULL; rvp++)
|
||||
continue;
|
||||
if (((rvp - tpvp) + (avp - pvp)) > MAXATOM)
|
||||
{
|
||||
syserr("554 callsubr: expansion too long");
|
||||
return EX_DATAERR;
|
||||
}
|
||||
|
||||
/*
|
||||
** Now we can copy the rewritten code over
|
||||
** the initial subroutine call in the buffer.
|
||||
*/
|
||||
|
||||
for (i = 0; tpvp[i] != NULL; i++)
|
||||
avp[i] = tpvp[i];
|
||||
avp[i] = NULL;
|
||||
|
||||
/*
|
||||
** If we got this far, we've processed the left
|
||||
** most subroutine, and recursively called ourselves
|
||||
** to handle any other subroutines. We're done.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rstat;
|
||||
}
|
||||
/*
|
||||
** MAP_LOOKUP -- do lookup in map
|
||||
**
|
||||
** Parameters:
|
||||
** map -- the map to use for the lookup.
|
||||
** key -- the key to look up.
|
||||
** argvect -- arguments to pass to the map lookup.
|
||||
** pstat -- a pointer to an integer in which to store the
|
||||
** status from the lookup.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** The result of the lookup.
|
||||
** NULL -- if there was no data for the given key.
|
||||
*/
|
||||
|
||||
char *
|
||||
map_lookup(map, key, argvect, pstat, e)
|
||||
STAB *map;
|
||||
char key[];
|
||||
char **argvect;
|
||||
int *pstat;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
auto int stat = EX_OK;
|
||||
char *replac;
|
||||
|
||||
if (e->e_sendmode == SM_DEFER)
|
||||
{
|
||||
/* don't do any map lookups */
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) => DEFERRED\n",
|
||||
map->s_name, key);
|
||||
*pstat = EX_TEMPFAIL;
|
||||
return NULL;
|
||||
}
|
||||
if (map == NULL || !bitset(MF_OPEN, map->s_map.map_mflags))
|
||||
return NULL;
|
||||
|
||||
if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags))
|
||||
stripquotes(key);
|
||||
|
||||
/* XXX should try to auto-open the map here */
|
||||
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) => ",
|
||||
map->s_name, key);
|
||||
replac = (*map->s_map.map_class->map_lookup)(&map->s_map,
|
||||
key, argvect, &stat);
|
||||
if (tTd(60, 1))
|
||||
printf("%s (%d)\n",
|
||||
replac != NULL ? replac : "NOT FOUND",
|
||||
stat);
|
||||
|
||||
/* should recover if stat == EX_TEMPFAIL */
|
||||
if (stat == EX_TEMPFAIL && !bitset(MF_NODEFER, map->s_map.map_mflags))
|
||||
{
|
||||
*pstat = EX_TEMPFAIL;
|
||||
if (tTd(60, 1))
|
||||
printf("map_lookup(%s, %s) tempfail: errno=%d\n",
|
||||
map->s_name, key, errno);
|
||||
if (e->e_message == NULL)
|
||||
{
|
||||
char mbuf[300];
|
||||
|
||||
snprintf(mbuf, sizeof mbuf,
|
||||
"%.80s map: lookup (%s): deferred",
|
||||
map->s_name,
|
||||
shortenstring(key, 203));
|
||||
e->e_message = newstr(mbuf);
|
||||
}
|
||||
}
|
||||
return replac;
|
||||
}
|
||||
/*
|
||||
** BUILDADDR -- build address from token vector.
|
||||
**
|
||||
** Parameters:
|
||||
@ -1345,17 +1472,17 @@ struct errcodes
|
||||
int ec_code; /* numeric code */
|
||||
} ErrorCodes[] =
|
||||
{
|
||||
"usage", EX_USAGE,
|
||||
"nouser", EX_NOUSER,
|
||||
"nohost", EX_NOHOST,
|
||||
"unavailable", EX_UNAVAILABLE,
|
||||
"software", EX_SOFTWARE,
|
||||
"tempfail", EX_TEMPFAIL,
|
||||
"protocol", EX_PROTOCOL,
|
||||
{ "usage", EX_USAGE },
|
||||
{ "nouser", EX_NOUSER },
|
||||
{ "nohost", EX_NOHOST },
|
||||
{ "unavailable", EX_UNAVAILABLE },
|
||||
{ "software", EX_SOFTWARE },
|
||||
{ "tempfail", EX_TEMPFAIL },
|
||||
{ "protocol", EX_PROTOCOL },
|
||||
#ifdef EX_CONFIG
|
||||
"config", EX_CONFIG,
|
||||
{ "config", EX_CONFIG },
|
||||
#endif
|
||||
NULL, EX_UNAVAILABLE,
|
||||
{ NULL, EX_UNAVAILABLE }
|
||||
};
|
||||
|
||||
ADDRESS *
|
||||
@ -1386,7 +1513,7 @@ buildaddr(tv, a, flags, e)
|
||||
bzero((char *) a, sizeof *a);
|
||||
|
||||
/* set up default error return flags */
|
||||
a->q_flags |= QPINGONFAILURE|QPINGONDELAY;
|
||||
a->q_flags |= DefaultNotify;
|
||||
|
||||
/* figure out what net/mailer to use */
|
||||
if (*tv == NULL || (**tv & 0377) != CANONNET)
|
||||
@ -1407,7 +1534,7 @@ buildaddr(tv, a, flags, e)
|
||||
mname = *++tv;
|
||||
|
||||
/* extract host and user portions */
|
||||
if ((**++tv & 0377) == CANONHOST)
|
||||
if (*++tv != NULL && (**tv & 0377) == CANONHOST)
|
||||
hostp = ++tv;
|
||||
else
|
||||
hostp = NULL;
|
||||
@ -1433,6 +1560,8 @@ buildaddr(tv, a, flags, e)
|
||||
|
||||
if (strchr(hbuf, '.') != NULL)
|
||||
{
|
||||
extern int dsntoexitstat __P((char *));
|
||||
|
||||
a->q_status = newstr(hbuf);
|
||||
setstat(dsntoexitstat(hbuf));
|
||||
}
|
||||
@ -1703,27 +1832,27 @@ struct qflags
|
||||
|
||||
struct qflags AddressFlags[] =
|
||||
{
|
||||
"QDONTSEND", QDONTSEND,
|
||||
"QBADADDR", QBADADDR,
|
||||
"QGOODUID", QGOODUID,
|
||||
"QPRIMARY", QPRIMARY,
|
||||
"QQUEUEUP", QQUEUEUP,
|
||||
"QSENT", QSENT,
|
||||
"QNOTREMOTE", QNOTREMOTE,
|
||||
"QSELFREF", QSELFREF,
|
||||
"QVERIFIED", QVERIFIED,
|
||||
"QBOGUSSHELL", QBOGUSSHELL,
|
||||
"QUNSAFEADDR", QUNSAFEADDR,
|
||||
"QPINGONSUCCESS", QPINGONSUCCESS,
|
||||
"QPINGONFAILURE", QPINGONFAILURE,
|
||||
"QPINGONDELAY", QPINGONDELAY,
|
||||
"QHASNOTIFY", QHASNOTIFY,
|
||||
"QRELAYED", QRELAYED,
|
||||
"QEXPANDED", QEXPANDED,
|
||||
"QDELIVERED", QDELIVERED,
|
||||
"QDELAYED", QDELAYED,
|
||||
"QTHISPASS", QTHISPASS,
|
||||
NULL
|
||||
{ "QDONTSEND", QDONTSEND },
|
||||
{ "QBADADDR", QBADADDR },
|
||||
{ "QGOODUID", QGOODUID },
|
||||
{ "QPRIMARY", QPRIMARY },
|
||||
{ "QQUEUEUP", QQUEUEUP },
|
||||
{ "QSENT", QSENT },
|
||||
{ "QNOTREMOTE", QNOTREMOTE },
|
||||
{ "QSELFREF", QSELFREF },
|
||||
{ "QVERIFIED", QVERIFIED },
|
||||
{ "QBOGUSSHELL", QBOGUSSHELL },
|
||||
{ "QUNSAFEADDR", QUNSAFEADDR },
|
||||
{ "QPINGONSUCCESS", QPINGONSUCCESS },
|
||||
{ "QPINGONFAILURE", QPINGONFAILURE },
|
||||
{ "QPINGONDELAY", QPINGONDELAY },
|
||||
{ "QHASNOTIFY", QHASNOTIFY },
|
||||
{ "QRELAYED", QRELAYED },
|
||||
{ "QEXPANDED", QEXPANDED },
|
||||
{ "QDELIVERED", QDELIVERED },
|
||||
{ "QDELAYED", QDELAYED },
|
||||
{ "QTHISPASS", QTHISPASS },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void
|
||||
@ -1781,10 +1910,14 @@ printaddr(a, follow)
|
||||
a->q_owner == NULL ? "(none)" : a->q_owner,
|
||||
a->q_home == NULL ? "(none)" : a->q_home,
|
||||
a->q_fullname == NULL ? "(none)" : a->q_fullname);
|
||||
printf("\torcpt=\"%s\", statmta=%s, rstatus=%s\n",
|
||||
printf("\torcpt=\"%s\", statmta=%s, status=%s\n",
|
||||
a->q_orcpt == NULL ? "(none)" : a->q_orcpt,
|
||||
a->q_statmta == NULL ? "(none)" : a->q_statmta,
|
||||
a->q_status == NULL ? "(none)" : a->q_status);
|
||||
printf("\trstatus=\"%s\"\n",
|
||||
a->q_rstatus == NULL ? "(none)" : a->q_rstatus);
|
||||
printf("\tspecificity=%d, statdate=%s\n",
|
||||
a->q_specificity, ctime(&a->q_statdate));
|
||||
|
||||
if (!follow)
|
||||
return;
|
||||
@ -1993,7 +2126,12 @@ maplocaluser(a, sendq, aliaslevel, e)
|
||||
if (pvp == NULL)
|
||||
return;
|
||||
|
||||
(void) rewrite(pvp, 5, 0, e);
|
||||
if (rewrite(pvp, 5, 0, e) == EX_TEMPFAIL)
|
||||
{
|
||||
a->q_flags |= QQUEUEUP;
|
||||
a->q_status = "4.4.3";
|
||||
return;
|
||||
}
|
||||
if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
|
||||
return;
|
||||
|
||||
@ -2154,5 +2292,111 @@ dequote_map(map, name, av, statp)
|
||||
quotemode || quotecnt <= 0 || spacecnt != 0)
|
||||
return NULL;
|
||||
*q++ = '\0';
|
||||
return name;
|
||||
return map_rewrite(map, name, strlen(name), NULL);
|
||||
}
|
||||
/*
|
||||
** RSCHECK -- check string(s) for validity using rewriting sets
|
||||
**
|
||||
** Parameters:
|
||||
** rwset -- the rewriting set to use.
|
||||
** p1 -- the first string to check.
|
||||
** p2 -- the second string to check -- may be null.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** EX_OK -- if the rwset doesn't resolve to $#error
|
||||
** else -- the failure status (message printed)
|
||||
*/
|
||||
|
||||
int
|
||||
rscheck(rwset, p1, p2, e)
|
||||
char *rwset;
|
||||
char *p1;
|
||||
char *p2;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
char *buf;
|
||||
int bufsize;
|
||||
int saveexitstat;
|
||||
int rstat;
|
||||
char **pvp;
|
||||
int rsno;
|
||||
auto ADDRESS a1;
|
||||
bool saveQuickAbort = QuickAbort;
|
||||
char buf0[MAXLINE];
|
||||
char pvpbuf[PSBUFSIZE];
|
||||
extern char MsgBuf[];
|
||||
|
||||
if (tTd(48, 2))
|
||||
printf("rscheck(%s, %s, %s)\n", rwset, p1,
|
||||
p2 == NULL ? "(NULL)" : p2);
|
||||
|
||||
rsno = strtorwset(rwset, NULL, ST_FIND);
|
||||
if (rsno < 0)
|
||||
return EX_OK;
|
||||
|
||||
if (p2 != NULL)
|
||||
{
|
||||
bufsize = strlen(p1) + strlen(p2) + 2;
|
||||
if (bufsize > sizeof buf0)
|
||||
buf = xalloc(bufsize);
|
||||
else
|
||||
{
|
||||
buf = buf0;
|
||||
bufsize = sizeof buf0;
|
||||
}
|
||||
(void) snprintf(buf, bufsize, "%s%c%s", p1, CONDELSE, p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
bufsize = strlen(p1) + 1;
|
||||
if (bufsize > sizeof buf0)
|
||||
buf = xalloc(bufsize);
|
||||
else
|
||||
{
|
||||
buf = buf0;
|
||||
bufsize = sizeof buf0;
|
||||
}
|
||||
(void) snprintf(buf, bufsize, "%s", p1);
|
||||
}
|
||||
pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
|
||||
if (pvp == NULL)
|
||||
{
|
||||
rstat = EX_DATAERR;
|
||||
goto finis;
|
||||
}
|
||||
(void) rewrite(pvp, rsno, 0, e);
|
||||
if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET ||
|
||||
pvp[1] == NULL || strcmp(pvp[1], "error") != 0)
|
||||
return EX_OK;
|
||||
|
||||
/* got an error -- process it */
|
||||
saveexitstat = ExitStat;
|
||||
QuickAbort = FALSE;
|
||||
(void) buildaddr(pvp, &a1, 0, e);
|
||||
QuickAbort = saveQuickAbort;
|
||||
rstat = ExitStat;
|
||||
ExitStat = saveexitstat;
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 4)
|
||||
{
|
||||
if (p2 == NULL)
|
||||
syslog(LOG_NOTICE, "Ruleset %s (%s) rejection: %s",
|
||||
rwset, p1, MsgBuf);
|
||||
else
|
||||
syslog(LOG_NOTICE, "Ruleset %s (%s, %s) rejection: %s",
|
||||
rwset, p1, p2, MsgBuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (QuickAbort)
|
||||
longjmp(TopFrame, 2);
|
||||
|
||||
/* clean up */
|
||||
finis:
|
||||
setstat(rstat);
|
||||
if (buf != buf0)
|
||||
free(buf);
|
||||
return rstat;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)readcf.c 8.139 (Berkeley) 11/29/95";
|
||||
static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
@ -112,10 +112,11 @@ readcf(cfname, safe, e)
|
||||
char exbuf[MAXLINE];
|
||||
char pvpbuf[MAXLINE + MAXATOM];
|
||||
static char *null_list[1] = { NULL };
|
||||
extern char *munchstring __P((char *, char **));
|
||||
extern char *munchstring __P((char *, char **, int));
|
||||
extern void fileclass __P((int, char *, char *, bool, bool));
|
||||
extern void toomany __P((int, int));
|
||||
extern void translate_dollars __P((char *));
|
||||
extern void inithostmaps __P((void));
|
||||
|
||||
FileName = cfname;
|
||||
LineNumber = 0;
|
||||
@ -246,10 +247,6 @@ readcf(cfname, safe, e)
|
||||
botch = "$?";
|
||||
break;
|
||||
|
||||
case CONDELSE:
|
||||
botch = "$|";
|
||||
break;
|
||||
|
||||
case CONDFI:
|
||||
botch = "$.";
|
||||
break;
|
||||
@ -354,16 +351,17 @@ readcf(cfname, safe, e)
|
||||
rwp = RewriteRules[ruleset];
|
||||
if (rwp != NULL)
|
||||
{
|
||||
if (OpMode == MD_TEST || tTd(37, 1))
|
||||
printf("WARNING: Ruleset %s has multiple definitions\n",
|
||||
&bp[1]);
|
||||
while (rwp->r_next != NULL)
|
||||
rwp = rwp->r_next;
|
||||
fprintf(stderr, "WARNING: Ruleset %s redefined\n",
|
||||
&bp[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D': /* macro definition */
|
||||
mid = macid(&bp[1], &ep);
|
||||
p = munchstring(ep, NULL);
|
||||
p = munchstring(ep, NULL, '\0');
|
||||
define(mid, newstr(p), e);
|
||||
break;
|
||||
|
||||
@ -441,6 +439,13 @@ readcf(cfname, safe, e)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef SUN_EXTENSIONS
|
||||
case 'L': /* lookup macro */
|
||||
case 'G': /* lookup class */
|
||||
/* reserved for Sun -- NIS+ database lookup */
|
||||
goto badline;
|
||||
#endif
|
||||
|
||||
case 'M': /* define mailer */
|
||||
makemailer(&bp[1]);
|
||||
break;
|
||||
@ -499,6 +504,8 @@ readcf(cfname, safe, e)
|
||||
|
||||
if (*ep++ == '/')
|
||||
{
|
||||
extern bool setvendor __P((char *));
|
||||
|
||||
/* extract vendor code */
|
||||
for (p = ep; isascii(*p) && isalpha(*p); )
|
||||
p++;
|
||||
@ -837,13 +844,11 @@ makemailer(line)
|
||||
auto char *endp;
|
||||
extern int NextMailer;
|
||||
extern char **makeargv();
|
||||
extern char *munchstring();
|
||||
extern char *munchstring __P((char *, char **, int));
|
||||
|
||||
/* allocate a mailer and set up defaults */
|
||||
m = (struct mailer *) xalloc(sizeof *m);
|
||||
bzero((char *) m, sizeof *m);
|
||||
m->m_eol = "\n";
|
||||
m->m_uid = m->m_gid = 0;
|
||||
|
||||
/* collect the mailer name */
|
||||
for (p = line; *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); p++)
|
||||
@ -875,7 +880,7 @@ makemailer(line)
|
||||
p++;
|
||||
|
||||
/* p now points to the field body */
|
||||
p = munchstring(p, &delimptr);
|
||||
p = munchstring(p, &delimptr, ',');
|
||||
|
||||
/* install the field into the mailer struct */
|
||||
switch (fcode)
|
||||
@ -1089,6 +1094,29 @@ makemailer(line)
|
||||
m->m_diagtype = "smtp";
|
||||
}
|
||||
|
||||
if (m->m_eol == NULL)
|
||||
{
|
||||
char **pp;
|
||||
|
||||
/* default for SMTP is \r\n; use \n for local delivery */
|
||||
for (pp = m->m_argv; *pp != NULL; pp++)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = *pp; *p != '\0'; )
|
||||
{
|
||||
if ((*p++ & 0377) == MACROEXPAND && *p == 'u')
|
||||
break;
|
||||
}
|
||||
if (*p != '\0')
|
||||
break;
|
||||
}
|
||||
if (*pp == NULL)
|
||||
m->m_eol = "\r\n";
|
||||
else
|
||||
m->m_eol = "\n";
|
||||
}
|
||||
|
||||
/* enter the mailer into the symbol table */
|
||||
s = stab(m->m_name, ST_MAILER, ST_ENTER);
|
||||
if (s->s_mailer != NULL)
|
||||
@ -1110,15 +1138,17 @@ makemailer(line)
|
||||
** p -- the string to munch.
|
||||
** delimptr -- if non-NULL, set to the pointer of the
|
||||
** field delimiter character.
|
||||
** delim -- the delimiter for the field.
|
||||
**
|
||||
** Returns:
|
||||
** the munched string.
|
||||
*/
|
||||
|
||||
char *
|
||||
munchstring(p, delimptr)
|
||||
munchstring(p, delimptr, delim)
|
||||
register char *p;
|
||||
char **delimptr;
|
||||
int delim;
|
||||
{
|
||||
register char *q;
|
||||
bool backslash = FALSE;
|
||||
@ -1157,7 +1187,7 @@ munchstring(p, delimptr)
|
||||
backslash = TRUE;
|
||||
else if (*p == '"')
|
||||
quotemode = !quotemode;
|
||||
else if (quotemode || *p != ',')
|
||||
else if (quotemode || *p != delim)
|
||||
*q++ = *p;
|
||||
else
|
||||
break;
|
||||
@ -1322,17 +1352,17 @@ struct resolverflags
|
||||
long rf_bits; /* bits to set/clear */
|
||||
} ResolverFlags[] =
|
||||
{
|
||||
"debug", RES_DEBUG,
|
||||
"aaonly", RES_AAONLY,
|
||||
"usevc", RES_USEVC,
|
||||
"primary", RES_PRIMARY,
|
||||
"igntc", RES_IGNTC,
|
||||
"recurse", RES_RECURSE,
|
||||
"defnames", RES_DEFNAMES,
|
||||
"stayopen", RES_STAYOPEN,
|
||||
"dnsrch", RES_DNSRCH,
|
||||
"true", 0, /* to avoid error on old syntax */
|
||||
NULL, 0
|
||||
{ "debug", RES_DEBUG },
|
||||
{ "aaonly", RES_AAONLY },
|
||||
{ "usevc", RES_USEVC },
|
||||
{ "primary", RES_PRIMARY },
|
||||
{ "igntc", RES_IGNTC },
|
||||
{ "recurse", RES_RECURSE },
|
||||
{ "defnames", RES_DEFNAMES },
|
||||
{ "stayopen", RES_STAYOPEN },
|
||||
{ "dnsrch", RES_DNSRCH },
|
||||
{ "true", 0 }, /* avoid error on old syntax */
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1344,108 +1374,112 @@ struct optioninfo
|
||||
bool o_safe; /* safe for random people to use */
|
||||
} OptionTab[] =
|
||||
{
|
||||
"SevenBitInput", '7', TRUE,
|
||||
{ "SevenBitInput", '7', TRUE },
|
||||
#if MIME8TO7
|
||||
"EightBitMode", '8', TRUE,
|
||||
{ "EightBitMode", '8', TRUE },
|
||||
#endif
|
||||
"AliasFile", 'A', FALSE,
|
||||
"AliasWait", 'a', FALSE,
|
||||
"BlankSub", 'B', FALSE,
|
||||
"MinFreeBlocks", 'b', TRUE,
|
||||
"CheckpointInterval", 'C', TRUE,
|
||||
"HoldExpensive", 'c', FALSE,
|
||||
"AutoRebuildAliases", 'D', FALSE,
|
||||
"DeliveryMode", 'd', TRUE,
|
||||
"ErrorHeader", 'E', FALSE,
|
||||
"ErrorMode", 'e', TRUE,
|
||||
"TempFileMode", 'F', FALSE,
|
||||
"SaveFromLine", 'f', FALSE,
|
||||
"MatchGECOS", 'G', FALSE,
|
||||
"HelpFile", 'H', FALSE,
|
||||
"MaxHopCount", 'h', FALSE,
|
||||
"ResolverOptions", 'I', FALSE,
|
||||
"IgnoreDots", 'i', TRUE,
|
||||
"ForwardPath", 'J', FALSE,
|
||||
"SendMimeErrors", 'j', TRUE,
|
||||
"ConnectionCacheSize", 'k', FALSE,
|
||||
"ConnectionCacheTimeout", 'K', FALSE,
|
||||
"UseErrorsTo", 'l', FALSE,
|
||||
"LogLevel", 'L', FALSE,
|
||||
"MeToo", 'm', TRUE,
|
||||
"CheckAliases", 'n', FALSE,
|
||||
"OldStyleHeaders", 'o', TRUE,
|
||||
"DaemonPortOptions", 'O', FALSE,
|
||||
"PrivacyOptions", 'p', TRUE,
|
||||
"PostmasterCopy", 'P', FALSE,
|
||||
"QueueFactor", 'q', FALSE,
|
||||
"QueueDirectory", 'Q', FALSE,
|
||||
"DontPruneRoutes", 'R', FALSE,
|
||||
"Timeout", 'r', TRUE,
|
||||
"StatusFile", 'S', FALSE,
|
||||
"SuperSafe", 's', TRUE,
|
||||
"QueueTimeout", 'T', FALSE,
|
||||
"TimeZoneSpec", 't', FALSE,
|
||||
"UserDatabaseSpec", 'U', FALSE,
|
||||
"DefaultUser", 'u', FALSE,
|
||||
"FallbackMXhost", 'V', FALSE,
|
||||
"Verbose", 'v', TRUE,
|
||||
"TryNullMXList", 'w', TRUE,
|
||||
"QueueLA", 'x', FALSE,
|
||||
"RefuseLA", 'X', FALSE,
|
||||
"RecipientFactor", 'y', FALSE,
|
||||
"ForkEachJob", 'Y', FALSE,
|
||||
"ClassFactor", 'z', FALSE,
|
||||
"RetryFactor", 'Z', FALSE,
|
||||
{ "AliasFile", 'A', FALSE },
|
||||
{ "AliasWait", 'a', FALSE },
|
||||
{ "BlankSub", 'B', FALSE },
|
||||
{ "MinFreeBlocks", 'b', TRUE },
|
||||
{ "CheckpointInterval", 'C', TRUE },
|
||||
{ "HoldExpensive", 'c', FALSE },
|
||||
{ "AutoRebuildAliases", 'D', FALSE },
|
||||
{ "DeliveryMode", 'd', TRUE },
|
||||
{ "ErrorHeader", 'E', FALSE },
|
||||
{ "ErrorMode", 'e', TRUE },
|
||||
{ "TempFileMode", 'F', FALSE },
|
||||
{ "SaveFromLine", 'f', FALSE },
|
||||
{ "MatchGECOS", 'G', FALSE },
|
||||
{ "HelpFile", 'H', FALSE },
|
||||
{ "MaxHopCount", 'h', FALSE },
|
||||
{ "ResolverOptions", 'I', FALSE },
|
||||
{ "IgnoreDots", 'i', TRUE },
|
||||
{ "ForwardPath", 'J', FALSE },
|
||||
{ "SendMimeErrors", 'j', TRUE },
|
||||
{ "ConnectionCacheSize", 'k', FALSE },
|
||||
{ "ConnectionCacheTimeout", 'K', FALSE },
|
||||
{ "UseErrorsTo", 'l', FALSE },
|
||||
{ "LogLevel", 'L', TRUE },
|
||||
{ "MeToo", 'm', TRUE },
|
||||
{ "CheckAliases", 'n', FALSE },
|
||||
{ "OldStyleHeaders", 'o', TRUE },
|
||||
{ "DaemonPortOptions", 'O', FALSE },
|
||||
{ "PrivacyOptions", 'p', TRUE },
|
||||
{ "PostmasterCopy", 'P', FALSE },
|
||||
{ "QueueFactor", 'q', FALSE },
|
||||
{ "QueueDirectory", 'Q', FALSE },
|
||||
{ "DontPruneRoutes", 'R', FALSE },
|
||||
{ "Timeout", 'r', FALSE },
|
||||
{ "StatusFile", 'S', FALSE },
|
||||
{ "SuperSafe", 's', TRUE },
|
||||
{ "QueueTimeout", 'T', FALSE },
|
||||
{ "TimeZoneSpec", 't', FALSE },
|
||||
{ "UserDatabaseSpec", 'U', FALSE },
|
||||
{ "DefaultUser", 'u', FALSE },
|
||||
{ "FallbackMXhost", 'V', FALSE },
|
||||
{ "Verbose", 'v', TRUE },
|
||||
{ "TryNullMXList", 'w', TRUE },
|
||||
{ "QueueLA", 'x', FALSE },
|
||||
{ "RefuseLA", 'X', FALSE },
|
||||
{ "RecipientFactor", 'y', FALSE },
|
||||
{ "ForkEachJob", 'Y', FALSE },
|
||||
{ "ClassFactor", 'z', FALSE },
|
||||
{ "RetryFactor", 'Z', FALSE },
|
||||
#define O_QUEUESORTORD 0x81
|
||||
"QueueSortOrder", O_QUEUESORTORD, TRUE,
|
||||
{ "QueueSortOrder", O_QUEUESORTORD, TRUE },
|
||||
#define O_HOSTSFILE 0x82
|
||||
"HostsFile", O_HOSTSFILE, FALSE,
|
||||
{ "HostsFile", O_HOSTSFILE, FALSE },
|
||||
#define O_MQA 0x83
|
||||
"MinQueueAge", O_MQA, TRUE,
|
||||
#define O_MHSA 0x84
|
||||
/*
|
||||
"MaxHostStatAge", O_MHSA, TRUE,
|
||||
*/
|
||||
{ "MinQueueAge", O_MQA, TRUE },
|
||||
#define O_DEFCHARSET 0x85
|
||||
"DefaultCharSet", O_DEFCHARSET, TRUE,
|
||||
{ "DefaultCharSet", O_DEFCHARSET, TRUE },
|
||||
#define O_SSFILE 0x86
|
||||
"ServiceSwitchFile", O_SSFILE, FALSE,
|
||||
{ "ServiceSwitchFile", O_SSFILE, FALSE },
|
||||
#define O_DIALDELAY 0x87
|
||||
"DialDelay", O_DIALDELAY, TRUE,
|
||||
{ "DialDelay", O_DIALDELAY, TRUE },
|
||||
#define O_NORCPTACTION 0x88
|
||||
"NoRecipientAction", O_NORCPTACTION, TRUE,
|
||||
{ "NoRecipientAction", O_NORCPTACTION, TRUE },
|
||||
#define O_SAFEFILEENV 0x89
|
||||
"SafeFileEnvironment", O_SAFEFILEENV, FALSE,
|
||||
{ "SafeFileEnvironment", O_SAFEFILEENV, FALSE },
|
||||
#define O_MAXMSGSIZE 0x8a
|
||||
"MaxMessageSize", O_MAXMSGSIZE, FALSE,
|
||||
{ "MaxMessageSize", O_MAXMSGSIZE, FALSE },
|
||||
#define O_COLONOKINADDR 0x8b
|
||||
"ColonOkInAddr", O_COLONOKINADDR, TRUE,
|
||||
{ "ColonOkInAddr", O_COLONOKINADDR, TRUE },
|
||||
#define O_MAXQUEUERUN 0x8c
|
||||
"MaxQueueRunSize", O_MAXQUEUERUN, TRUE,
|
||||
{ "MaxQueueRunSize", O_MAXQUEUERUN, TRUE },
|
||||
#define O_MAXCHILDREN 0x8d
|
||||
/*
|
||||
"MaxDaemonChildren", O_MAXCHILDREN, FALSE,
|
||||
*/
|
||||
{ "MaxDaemonChildren", O_MAXCHILDREN, FALSE },
|
||||
#define O_KEEPCNAMES 0x8e
|
||||
"DontExpandCnames", O_KEEPCNAMES, FALSE,
|
||||
{ "DontExpandCnames", O_KEEPCNAMES, FALSE },
|
||||
#define O_MUSTQUOTE 0x8f
|
||||
/*
|
||||
"MustQuoteChars", O_MUSTQUOTE, FALSE,
|
||||
*/
|
||||
{ "MustQuoteChars", O_MUSTQUOTE, FALSE },
|
||||
#define O_SMTPGREETING 0x90
|
||||
"SmtpGreetingMessage", O_SMTPGREETING, FALSE,
|
||||
{ "SmtpGreetingMessage", O_SMTPGREETING, FALSE },
|
||||
#define O_UNIXFROM 0x91
|
||||
"UnixFromLine", O_UNIXFROM, FALSE,
|
||||
{ "UnixFromLine", O_UNIXFROM, FALSE },
|
||||
#define O_OPCHARS 0x92
|
||||
"OperatorChars", O_OPCHARS, FALSE,
|
||||
{ "OperatorChars", O_OPCHARS, FALSE },
|
||||
#define O_DONTINITGRPS 0x93
|
||||
"DontInitGroups", O_DONTINITGRPS, TRUE,
|
||||
{ "DontInitGroups", O_DONTINITGRPS, TRUE },
|
||||
#define O_SLFH 0x94
|
||||
#ifdef LOTUS_NOTES_HACK
|
||||
"SingleLineFromHeader", O_SLFH, TRUE,
|
||||
#endif
|
||||
{ "SingleLineFromHeader", O_SLFH, TRUE },
|
||||
#define O_ABH 0x95
|
||||
{ "AllowBogusHELO", O_ABH, TRUE },
|
||||
#define O_CONNTHROT 0x97
|
||||
{ "ConnectionRateThrottle", O_CONNTHROT, FALSE },
|
||||
#define O_UGW 0x99
|
||||
{ "UnsafeGroupWrites", O_UGW, FALSE },
|
||||
#define O_DBLBOUNCE 0x9a
|
||||
{ "DoubleBounceAddress", O_DBLBOUNCE, FALSE },
|
||||
#define O_HSDIR 0x9b
|
||||
{ "HostStatusDirectory", O_HSDIR, FALSE },
|
||||
#define O_SINGTHREAD 0x9c
|
||||
{ "SingleThreadDelivery", O_SINGTHREAD, FALSE },
|
||||
#define O_RUNASUSER 0x9d
|
||||
{ "RunAsUser", O_RUNASUSER, FALSE },
|
||||
|
||||
NULL, '\0', FALSE,
|
||||
{ NULL, '\0', FALSE }
|
||||
};
|
||||
|
||||
|
||||
@ -1461,12 +1495,18 @@ setoption(opt, val, safe, sticky, e)
|
||||
register char *p;
|
||||
register struct optioninfo *o;
|
||||
char *subopt;
|
||||
int mid;
|
||||
auto char *ep;
|
||||
char buf[50];
|
||||
extern bool atobool();
|
||||
extern time_t convtime();
|
||||
extern int QueueLA;
|
||||
extern int RefuseLA;
|
||||
extern bool Warn_Q_option;
|
||||
extern void setalias __P((char *));
|
||||
extern int atooct __P((char *));
|
||||
extern void setdefuser __P((void));
|
||||
extern void setdaemonoptions __P((char *));
|
||||
|
||||
errno = 0;
|
||||
if (opt == ' ')
|
||||
@ -1843,10 +1883,11 @@ setoption(opt, val, safe, sticky, e)
|
||||
break;
|
||||
|
||||
case 'M': /* define macro */
|
||||
p = newstr(&val[1]);
|
||||
mid = macid(val, &ep);
|
||||
p = newstr(ep);
|
||||
if (!safe)
|
||||
cleanstrcpy(p, p, MAXNAME);
|
||||
define(val[0], p, CurEnv);
|
||||
define(mid, p, CurEnv);
|
||||
sticky = FALSE;
|
||||
break;
|
||||
|
||||
@ -1986,6 +2027,14 @@ setoption(opt, val, safe, sticky, e)
|
||||
DefGid = pw->pw_gid;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UID_MAX
|
||||
if (DefUid > UID_MAX)
|
||||
{
|
||||
syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored",
|
||||
DefUid, UID_MAX);
|
||||
}
|
||||
#endif
|
||||
setdefuser();
|
||||
|
||||
/* handle the group if it is there */
|
||||
@ -1995,6 +2044,7 @@ setoption(opt, val, safe, sticky, e)
|
||||
goto g_opt;
|
||||
|
||||
case 'V': /* fallback MX host */
|
||||
if (val[0] != '\0')
|
||||
FallBackMX = newstr(val);
|
||||
break;
|
||||
|
||||
@ -2045,6 +2095,11 @@ setoption(opt, val, safe, sticky, e)
|
||||
QueueSortOrder = QS_BYPRIORITY;
|
||||
break;
|
||||
|
||||
case 't': /* Submission time */
|
||||
case 'T':
|
||||
QueueSortOrder = QS_BYTIME;
|
||||
break;
|
||||
|
||||
default:
|
||||
syserr("Invalid queue sort order \"%s\"", val);
|
||||
}
|
||||
@ -2058,10 +2113,6 @@ setoption(opt, val, safe, sticky, e)
|
||||
MinQueueAge = convtime(val, 'm');
|
||||
break;
|
||||
|
||||
case O_MHSA: /* maximum age of cached host status */
|
||||
MaxHostStatAge = convtime(val, 'm');
|
||||
break;
|
||||
|
||||
case O_DEFCHARSET: /* default character set for mimefying */
|
||||
DefaultCharSet = newstr(denlstring(val, TRUE, TRUE));
|
||||
break;
|
||||
@ -2115,21 +2166,21 @@ setoption(opt, val, safe, sticky, e)
|
||||
|
||||
case O_MUSTQUOTE: /* must quote these characters in phrases */
|
||||
strcpy(buf, "@,;:\\()[]");
|
||||
if (strlen(val) < sizeof buf - 10)
|
||||
if (strlen(val) < (SIZE_T) sizeof buf - 10)
|
||||
strcat(buf, val);
|
||||
MustQuoteChars = newstr(buf);
|
||||
break;
|
||||
|
||||
case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */
|
||||
SmtpGreeting = newstr(munchstring(val, NULL));
|
||||
SmtpGreeting = newstr(munchstring(val, NULL, '\0'));
|
||||
break;
|
||||
|
||||
case O_UNIXFROM: /* UNIX From_ line (old $l macro) */
|
||||
UnixFromLine = newstr(munchstring(val, NULL));
|
||||
UnixFromLine = newstr(munchstring(val, NULL, '\0'));
|
||||
break;
|
||||
|
||||
case O_OPCHARS: /* operator characters (old $o macro) */
|
||||
OperatorChars = newstr(munchstring(val, NULL));
|
||||
OperatorChars = newstr(munchstring(val, NULL, '\0'));
|
||||
break;
|
||||
|
||||
case O_DONTINITGRPS: /* don't call initgroups(3) */
|
||||
@ -2140,6 +2191,75 @@ setoption(opt, val, safe, sticky, e)
|
||||
SingleLineFromHeader = atobool(val);
|
||||
break;
|
||||
|
||||
case O_ABH: /* allow HELO commands with syntax errors */
|
||||
AllowBogusHELO = atobool(val);
|
||||
break;
|
||||
|
||||
case O_CONNTHROT: /* connection rate throttle */
|
||||
ConnRateThrottle = atoi(val);
|
||||
break;
|
||||
|
||||
case O_UGW: /* group writable files are unsafe */
|
||||
UnsafeGroupWrites = atobool(val);
|
||||
break;
|
||||
|
||||
case O_DBLBOUNCE: /* address to which to send double bounces */
|
||||
if (val[0] != '\0')
|
||||
DoubleBounceAddr = newstr(val);
|
||||
else
|
||||
syserr("readcf: option DoubleBounceAddress: value required");
|
||||
break;
|
||||
|
||||
case O_HSDIR: /* persistent host status directory */
|
||||
if (val[0] != '\0')
|
||||
HostStatDir = newstr(val);
|
||||
break;
|
||||
|
||||
case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */
|
||||
SingleThreadDelivery = atobool(val);
|
||||
break;
|
||||
|
||||
case O_RUNASUSER: /* run bulk of code as this user */
|
||||
for (p = val; *p != '\0'; p++)
|
||||
{
|
||||
if (*p == '.' || *p == '/' || *p == ':')
|
||||
{
|
||||
*p++ = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isascii(*val) && isdigit(*val))
|
||||
RunAsUid = atoi(val);
|
||||
else
|
||||
{
|
||||
register struct passwd *pw;
|
||||
|
||||
pw = sm_getpwnam(val);
|
||||
if (pw == NULL)
|
||||
syserr("readcf: option RunAsUser: unknown user %s", val);
|
||||
else
|
||||
{
|
||||
RunAsUid = pw->pw_uid;
|
||||
RunAsGid = pw->pw_gid;
|
||||
}
|
||||
}
|
||||
if (*p == '\0')
|
||||
break;
|
||||
if (isascii(*p) && isdigit(*p))
|
||||
DefGid = atoi(p);
|
||||
else
|
||||
{
|
||||
register struct group *gr;
|
||||
|
||||
gr = getgrnam(p);
|
||||
if (gr == NULL)
|
||||
syserr("readcf: option RunAsUser: unknown group %s",
|
||||
p);
|
||||
else
|
||||
RunAsGid = gr->gr_gid;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tTd(37, 1))
|
||||
{
|
||||
@ -2249,7 +2369,7 @@ makemapentry(line)
|
||||
|
||||
if (tTd(37, 5))
|
||||
{
|
||||
printf("map %s, class %s, flags %x, file %s,\n",
|
||||
printf("map %s, class %s, flags %lx, file %s,\n",
|
||||
s->s_map.map_mname, s->s_map.map_class->map_cname,
|
||||
s->s_map.map_mflags,
|
||||
s->s_map.map_file == NULL ? "(null)" : s->s_map.map_file);
|
||||
@ -2327,10 +2447,7 @@ strtorwset(p, endp, stabmode)
|
||||
*p = delim;
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
syserr("unknown ruleset %s", q);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stabmode == ST_ENTER && delim == '=')
|
||||
{
|
||||
@ -2368,7 +2485,7 @@ strtorwset(p, endp, stabmode)
|
||||
if (s->s_ruleset > 0 && ruleset >= 0 && ruleset != s->s_ruleset)
|
||||
{
|
||||
syserr("%s: ruleset changed value (old %d, new %d)",
|
||||
q, ruleset, s->s_ruleset);
|
||||
q, s->s_ruleset, ruleset);
|
||||
ruleset = s->s_ruleset;
|
||||
}
|
||||
else if (ruleset > 0)
|
||||
@ -2403,6 +2520,8 @@ inittimeouts(val)
|
||||
register char *p;
|
||||
extern time_t convtime();
|
||||
|
||||
if (tTd(37, 2))
|
||||
printf("inittimeouts(%s)\n", val == NULL ? "<NULL>" : val);
|
||||
if (val == NULL)
|
||||
{
|
||||
TimeOuts.to_connect = (time_t) 0 SECONDS;
|
||||
@ -2423,6 +2542,24 @@ inittimeouts(val)
|
||||
TimeOuts.to_ident = (time_t) 0 SECONDS;
|
||||
#endif
|
||||
TimeOuts.to_fileopen = (time_t) 60 SECONDS;
|
||||
if (tTd(37, 5))
|
||||
{
|
||||
printf("Timeouts:\n");
|
||||
printf(" connect = %ld\n", TimeOuts.to_connect);
|
||||
printf(" initial = %ld\n", TimeOuts.to_initial);
|
||||
printf(" helo = %ld\n", TimeOuts.to_helo);
|
||||
printf(" mail = %ld\n", TimeOuts.to_mail);
|
||||
printf(" rcpt = %ld\n", TimeOuts.to_rcpt);
|
||||
printf(" datainit = %ld\n", TimeOuts.to_datainit);
|
||||
printf(" datablock = %ld\n", TimeOuts.to_datablock);
|
||||
printf(" datafinal = %ld\n", TimeOuts.to_datafinal);
|
||||
printf(" rset = %ld\n", TimeOuts.to_rset);
|
||||
printf(" quit = %ld\n", TimeOuts.to_quit);
|
||||
printf(" nextcommand = %ld\n", TimeOuts.to_nextcommand);
|
||||
printf(" miscshort = %ld\n", TimeOuts.to_miscshort);
|
||||
printf(" ident = %ld\n", TimeOuts.to_ident);
|
||||
printf(" fileopen = %ld\n", TimeOuts.to_fileopen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2482,6 +2619,9 @@ settimeout(name, val)
|
||||
time_t to;
|
||||
extern time_t convtime();
|
||||
|
||||
if (tTd(37, 2))
|
||||
printf("settimeout(%s = %s)\n", name, val);
|
||||
|
||||
to = convtime(val, 'm');
|
||||
p = strchr(name, '.');
|
||||
if (p != NULL)
|
||||
@ -2515,6 +2655,8 @@ settimeout(name, val)
|
||||
TimeOuts.to_fileopen = to;
|
||||
else if (strcasecmp(name, "connect") == 0)
|
||||
TimeOuts.to_connect = to;
|
||||
else if (strcasecmp(name, "iconnect") == 0)
|
||||
TimeOuts.to_iconnect = to;
|
||||
else if (strcasecmp(name, "queuewarn") == 0)
|
||||
{
|
||||
to = convtime(val, 'h');
|
||||
@ -2551,6 +2693,8 @@ settimeout(name, val)
|
||||
else
|
||||
syserr("settimeout: invalid queuereturn subtimeout %s", p);
|
||||
}
|
||||
else if (strcasecmp(name, "hoststatus") == 0)
|
||||
MciInfoTimeout = convtime(val, 'm');
|
||||
else
|
||||
syserr("settimeout: invalid timeout %s", name);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)recipient.c 8.108.1.1 (Berkeley) 9/12/96";
|
||||
static char sccsid[] = "@(#)recipient.c 8.116 (Berkeley) 8/17/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
@ -241,7 +241,7 @@ recipient(a, sendq, aliaslevel, e)
|
||||
int i;
|
||||
char *buf;
|
||||
char buf0[MAXNAME + 1]; /* unquoted image of the user name */
|
||||
extern int safefile();
|
||||
extern void alias __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
|
||||
e->e_to = a->q_paddr;
|
||||
m = a->q_mailer;
|
||||
@ -267,7 +267,7 @@ recipient(a, sendq, aliaslevel, e)
|
||||
if (aliaslevel > MaxAliasRecursion)
|
||||
{
|
||||
a->q_status = "5.4.6";
|
||||
usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max",
|
||||
usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max)",
|
||||
aliaslevel, MaxAliasRecursion);
|
||||
return (a);
|
||||
}
|
||||
@ -482,6 +482,8 @@ recipient(a, sendq, aliaslevel, e)
|
||||
ConfigLevel >= 2 && RewriteRules[5] != NULL &&
|
||||
bitnset(M_TRYRULESET5, m->m_flags))
|
||||
{
|
||||
extern void maplocaluser __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
|
||||
maplocaluser(a, sendq, aliaslevel + 1, e);
|
||||
}
|
||||
|
||||
@ -495,7 +497,7 @@ recipient(a, sendq, aliaslevel, e)
|
||||
{
|
||||
auto bool fuzzy;
|
||||
register struct passwd *pw;
|
||||
extern struct passwd *finduser();
|
||||
extern void forward __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
|
||||
/* warning -- finduser may trash buf */
|
||||
pw = finduser(buf, &fuzzy);
|
||||
@ -738,8 +740,7 @@ finduser(name, fuzzyp)
|
||||
{
|
||||
if (tTd(29, 4))
|
||||
printf("found (case wrapped)\n");
|
||||
*fuzzyp = TRUE;
|
||||
return pw;
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
|
||||
@ -749,17 +750,22 @@ finduser(name, fuzzyp)
|
||||
if (tTd(29, 4))
|
||||
printf("fuzzy matches %s\n", pw->pw_name);
|
||||
message("sending to login name %s", pw->pw_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pw != NULL)
|
||||
*fuzzyp = TRUE;
|
||||
return (pw);
|
||||
}
|
||||
}
|
||||
if (tTd(29, 4))
|
||||
else if (tTd(29, 4))
|
||||
printf("no fuzzy match found\n");
|
||||
# if DEC_OSF_BROKEN_GETPWENT /* DEC OSF/1 3.2 or earlier */
|
||||
endpwent();
|
||||
# endif
|
||||
return pw;
|
||||
#else
|
||||
if (tTd(29, 4))
|
||||
printf("not found (fuzzy disabled)\n");
|
||||
return NULL;
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
** WRITABLE -- predicate returning if the file is writable.
|
||||
@ -1122,19 +1128,21 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
||||
/*
|
||||
** Check to see if some bad guy can write this file
|
||||
**
|
||||
** This should really do something clever with group
|
||||
** permissions; currently we just view world writable
|
||||
** as unsafe. Also, we don't check for writable
|
||||
** Group write checking could be more clever, e.g.,
|
||||
** guessing as to which groups are actually safe ("sys"
|
||||
** may be; "user" probably is not).
|
||||
** Also, we don't check for writable
|
||||
** directories in the path. We've got to leave
|
||||
** something for the local sysad to do.
|
||||
*/
|
||||
|
||||
if (bitset(S_IWOTH, st.st_mode))
|
||||
if (bitset(S_IWOTH | (UnsafeGroupWrites ? S_IWGRP : 0), st.st_mode))
|
||||
{
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 12)
|
||||
syslog(LOG_INFO, "%s: world writable %s file, marked unsafe",
|
||||
syslog(LOG_INFO, "%s: %s writable %s file, marked unsafe",
|
||||
shortenstring(fname, 203),
|
||||
bitset(S_IWOTH, st.st_mode) ? "world" : "group",
|
||||
forwarding ? "forward" : ":include:");
|
||||
#endif
|
||||
ctladdr->q_flags |= QUNSAFEADDR;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)savemail.c 8.87.1.2 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)savemail.c 8.100 (Berkeley) 9/27/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
@ -86,7 +86,7 @@ savemail(e, sendbody)
|
||||
auto ADDRESS *q = NULL;
|
||||
register char *p;
|
||||
MCI mcibuf;
|
||||
int sfflags;
|
||||
int flags;
|
||||
char buf[MAXLINE+1];
|
||||
extern char *ttypath();
|
||||
typedef int (*fnptr)();
|
||||
@ -283,7 +283,9 @@ savemail(e, sendbody)
|
||||
break;
|
||||
}
|
||||
if (returntosender(e->e_message, e->e_errorqueue,
|
||||
sendbody, e) == 0)
|
||||
sendbody ? RTSF_SEND_BODY
|
||||
: RTSF_NO_BODY,
|
||||
e) == 0)
|
||||
{
|
||||
state = ESM_DONE;
|
||||
break;
|
||||
@ -299,14 +301,17 @@ savemail(e, sendbody)
|
||||
*/
|
||||
|
||||
q = NULL;
|
||||
if (sendtolist("postmaster", NULL, &q, 0, e) <= 0)
|
||||
if (sendtolist(DoubleBounceAddr, NULL, &q, 0, e) <= 0)
|
||||
{
|
||||
syserr("553 cannot parse postmaster!");
|
||||
syserr("553 cannot parse %s!", DoubleBounceAddr);
|
||||
ExitStat = EX_SOFTWARE;
|
||||
state = ESM_USRTMP;
|
||||
break;
|
||||
}
|
||||
if (returntosender(e->e_message, q, sendbody, e) == 0)
|
||||
flags = RTSF_PM_BOUNCE;
|
||||
if (sendbody)
|
||||
flags |= RTSF_SEND_BODY;
|
||||
if (returntosender(e->e_message, q, flags, e) == 0)
|
||||
{
|
||||
state = ESM_DONE;
|
||||
break;
|
||||
@ -344,9 +349,9 @@ savemail(e, sendbody)
|
||||
/* we have a home directory; write dead.letter */
|
||||
define('z', p, e);
|
||||
expand("\201z/dead.letter", buf, sizeof buf, e);
|
||||
sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
|
||||
flags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
|
||||
e->e_to = buf;
|
||||
if (mailfile(buf, NULL, sfflags, e) == EX_OK)
|
||||
if (mailfile(buf, NULL, flags, e) == EX_OK)
|
||||
{
|
||||
bool oldverb = Verbose;
|
||||
|
||||
@ -378,10 +383,10 @@ savemail(e, sendbody)
|
||||
|
||||
snprintf(buf, sizeof buf, "%sdead.letter", _PATH_VARTMP);
|
||||
|
||||
sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT;
|
||||
if (!writable(buf, NULL, sfflags) ||
|
||||
flags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT;
|
||||
if (!writable(buf, NULL, flags) ||
|
||||
(fp = safefopen(buf, O_WRONLY|O_CREAT|O_APPEND,
|
||||
FileMode, sfflags)) == NULL)
|
||||
FileMode, flags)) == NULL)
|
||||
{
|
||||
state = ESM_PANIC;
|
||||
break;
|
||||
@ -398,7 +403,9 @@ savemail(e, sendbody)
|
||||
(*e->e_putbody)(&mcibuf, e, NULL);
|
||||
putline("\n", &mcibuf);
|
||||
(void) fflush(fp);
|
||||
if (!ferror(fp))
|
||||
if (ferror(fp))
|
||||
state = ESM_PANIC;
|
||||
else
|
||||
{
|
||||
bool oldverb = Verbose;
|
||||
|
||||
@ -410,9 +417,7 @@ savemail(e, sendbody)
|
||||
syslog(LOG_NOTICE, "Saved message in %s", buf);
|
||||
#endif
|
||||
state = ESM_DONE;
|
||||
break;
|
||||
}
|
||||
state = ESM_PANIC;
|
||||
(void) xfclose(fp, "savemail", buf);
|
||||
break;
|
||||
|
||||
@ -434,8 +439,10 @@ savemail(e, sendbody)
|
||||
** Parameters:
|
||||
** msg -- the explanatory message.
|
||||
** returnq -- the queue of people to send the message to.
|
||||
** sendbody -- if TRUE, also send back the body of the
|
||||
** message; otherwise just send the header.
|
||||
** flags -- flags tweaking the operation:
|
||||
** RTSF_SENDBODY -- include body of message (otherwise
|
||||
** just send the header).
|
||||
** RTSF_PMBOUNCE -- this is a postmaster bounce.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
@ -451,10 +458,10 @@ savemail(e, sendbody)
|
||||
#define ERRORFUDGE 100 /* nominal size of error message text */
|
||||
|
||||
int
|
||||
returntosender(msg, returnq, sendbody, e)
|
||||
returntosender(msg, returnq, flags, e)
|
||||
char *msg;
|
||||
ADDRESS *returnq;
|
||||
bool sendbody;
|
||||
int flags;
|
||||
register ENVELOPE *e;
|
||||
{
|
||||
register ENVELOPE *ee;
|
||||
@ -509,16 +516,21 @@ returntosender(msg, returnq, sendbody, e)
|
||||
ee->e_flags &= ~EF_OLDSTYLE;
|
||||
ee->e_sendqueue = returnq;
|
||||
ee->e_msgsize = ERRORFUDGE;
|
||||
if (sendbody)
|
||||
if (bitset(RTSF_SEND_BODY, flags))
|
||||
ee->e_msgsize += e->e_msgsize;
|
||||
else
|
||||
ee->e_flags |= EF_NO_BODY_RETN;
|
||||
initsys(ee);
|
||||
for (q = returnq; q != NULL; q = q->q_next)
|
||||
{
|
||||
extern bool pruneroute __P((char *));
|
||||
|
||||
if (bitset(QBADADDR, q->q_flags))
|
||||
continue;
|
||||
|
||||
q->q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
|
||||
q->q_flags |= QPINGONFAILURE;
|
||||
|
||||
if (!DontPruneRoutes && pruneroute(q->q_paddr))
|
||||
{
|
||||
register ADDRESS *p;
|
||||
@ -543,8 +555,10 @@ returntosender(msg, returnq, sendbody, e)
|
||||
{
|
||||
if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags))
|
||||
p = "return to sender";
|
||||
else
|
||||
else if (bitset(RTSF_PM_BOUNCE, flags))
|
||||
p = "postmaster notify";
|
||||
else
|
||||
p = "DSN";
|
||||
syslog(LOG_INFO, "%s: %s: %s: %s",
|
||||
e->e_id, ee->e_id, p, shortenstring(msg, 203));
|
||||
}
|
||||
@ -589,6 +603,13 @@ returntosender(msg, returnq, sendbody, e)
|
||||
addheader("Subject", msg, &ee->e_header);
|
||||
p = "return-receipt";
|
||||
}
|
||||
else if (bitset(RTSF_PM_BOUNCE, flags))
|
||||
{
|
||||
snprintf(buf, sizeof buf, "Postmaster notify: %.*s",
|
||||
sizeof buf - 20, msg);
|
||||
addheader("Subject", buf, &ee->e_header);
|
||||
p = "postmaster-notification";
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof buf, "Returned mail: %.*s",
|
||||
@ -608,6 +629,8 @@ returntosender(msg, returnq, sendbody, e)
|
||||
returndepth--;
|
||||
return (-1);
|
||||
}
|
||||
ee->e_from.q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
|
||||
ee->e_from.q_flags |= QPINGONFAILURE;
|
||||
ee->e_sender = ee->e_from.q_paddr;
|
||||
|
||||
/* push state into submessage */
|
||||
@ -623,7 +646,7 @@ returntosender(msg, returnq, sendbody, e)
|
||||
sendall(ee, SM_DEFAULT);
|
||||
|
||||
/* restore state */
|
||||
dropenvelope(ee);
|
||||
dropenvelope(ee, TRUE);
|
||||
CurEnv = oldcur;
|
||||
returndepth--;
|
||||
|
||||
@ -647,7 +670,6 @@ returntosender(msg, returnq, sendbody, e)
|
||||
** mci -- the mailer connection information.
|
||||
** e -- the envelope we are working in.
|
||||
** separator -- any possible MIME separator.
|
||||
** flags -- to modify the behaviour.
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
@ -667,8 +689,8 @@ errbody(mci, e, separator)
|
||||
register ADDRESS *q;
|
||||
bool printheader;
|
||||
bool sendbody;
|
||||
bool pm_notify;
|
||||
char buf[MAXLINE];
|
||||
extern char *xuntextify();
|
||||
|
||||
if (bitset(MCIF_INHEADER, mci->mci_flags))
|
||||
{
|
||||
@ -699,10 +721,17 @@ errbody(mci, e, separator)
|
||||
** Output introductory information.
|
||||
*/
|
||||
|
||||
pm_notify = FALSE;
|
||||
p = hvalue("subject", e->e_header);
|
||||
if (p != NULL && strncmp(p, "Postmaster ", 11) == 0)
|
||||
pm_notify = TRUE;
|
||||
else
|
||||
{
|
||||
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
|
||||
if (bitset(QBADADDR, q->q_flags))
|
||||
break;
|
||||
if (q == NULL &&
|
||||
}
|
||||
if (!pm_notify && q == NULL &&
|
||||
!bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
|
||||
{
|
||||
putline(" **********************************************",
|
||||
@ -757,16 +786,63 @@ errbody(mci, e, separator)
|
||||
printheader = TRUE;
|
||||
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
|
||||
{
|
||||
if (bitset(QBADADDR, q->q_flags))
|
||||
if (!bitset(QBADADDR, q->q_flags) ||
|
||||
!bitset(QPINGONFAILURE, q->q_flags))
|
||||
continue;
|
||||
|
||||
if (printheader)
|
||||
{
|
||||
if (!bitset(QPINGONFAILURE, q->q_flags))
|
||||
continue;
|
||||
p = "unrecoverable error";
|
||||
putline(" ----- The following addresses had permanent fatal errors -----",
|
||||
mci);
|
||||
printheader = FALSE;
|
||||
}
|
||||
else if (!bitset(QPRIMARY, q->q_flags))
|
||||
|
||||
snprintf(buf, sizeof buf, "%s", shortenstring(q->q_paddr, 203));
|
||||
putline(buf, mci);
|
||||
if (q->q_alias != NULL)
|
||||
{
|
||||
snprintf(buf, sizeof buf, " (expanded from: %s)",
|
||||
shortenstring(q->q_alias->q_paddr, 203));
|
||||
putline(buf, mci);
|
||||
}
|
||||
}
|
||||
if (!printheader)
|
||||
putline("", mci);
|
||||
|
||||
printheader = TRUE;
|
||||
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
|
||||
{
|
||||
if (bitset(QBADADDR, q->q_flags) ||
|
||||
!bitset(QPRIMARY, q->q_flags) ||
|
||||
!bitset(QDELAYED, q->q_flags))
|
||||
continue;
|
||||
|
||||
if (printheader)
|
||||
{
|
||||
putline(" ----- The following addresses had transient non-fatal errors -----",
|
||||
mci);
|
||||
printheader = FALSE;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof buf, "%s", shortenstring(q->q_paddr, 203));
|
||||
putline(buf, mci);
|
||||
if (q->q_alias != NULL)
|
||||
{
|
||||
snprintf(buf, sizeof buf, " (expanded from: %s)",
|
||||
shortenstring(q->q_alias->q_paddr, 203));
|
||||
putline(buf, mci);
|
||||
}
|
||||
}
|
||||
if (!printheader)
|
||||
putline("", mci);
|
||||
|
||||
printheader = TRUE;
|
||||
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
|
||||
{
|
||||
if (bitset(QBADADDR, q->q_flags) ||
|
||||
!bitset(QPRIMARY, q->q_flags) ||
|
||||
bitset(QDELAYED, q->q_flags))
|
||||
continue;
|
||||
else if (bitset(QDELAYED, q->q_flags))
|
||||
p = "transient failure";
|
||||
else if (!bitset(QPINGONSUCCESS, q->q_flags))
|
||||
continue;
|
||||
else if (bitset(QRELAYED, q->q_flags))
|
||||
@ -785,7 +861,7 @@ errbody(mci, e, separator)
|
||||
|
||||
if (printheader)
|
||||
{
|
||||
putline(" ----- The following addresses have delivery notifications -----",
|
||||
putline(" ----- The following addresses had successful delivery notifications -----",
|
||||
mci);
|
||||
printheader = FALSE;
|
||||
}
|
||||
@ -801,7 +877,7 @@ errbody(mci, e, separator)
|
||||
}
|
||||
}
|
||||
if (!printheader)
|
||||
putline("\n", mci);
|
||||
putline("", mci);
|
||||
|
||||
/*
|
||||
** Output transcript of errors
|
||||
@ -1164,14 +1240,16 @@ smtptodsn(smtpstat)
|
||||
**
|
||||
** Parameters:
|
||||
** t -- the text to convert.
|
||||
** taboo -- additional characters that must be encoded.
|
||||
**
|
||||
** Returns:
|
||||
** The xtext-ified version of the same string.
|
||||
*/
|
||||
|
||||
char *
|
||||
xtextify(t)
|
||||
xtextify(t, taboo)
|
||||
register char *t;
|
||||
char *taboo;
|
||||
{
|
||||
register char *p;
|
||||
int l;
|
||||
@ -1179,6 +1257,9 @@ xtextify(t)
|
||||
static char *bp = NULL;
|
||||
static int bplen = 0;
|
||||
|
||||
if (taboo == NULL)
|
||||
taboo = "";
|
||||
|
||||
/* figure out how long this xtext will have to be */
|
||||
nbogus = l = 0;
|
||||
for (p = t; *p != '\0'; p++)
|
||||
@ -1186,7 +1267,8 @@ xtextify(t)
|
||||
register int c = (*p & 0xff);
|
||||
|
||||
/* ASCII dependence here -- this is the way the spec words it */
|
||||
if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
|
||||
if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(' ||
|
||||
strchr(taboo, c) != NULL)
|
||||
nbogus++;
|
||||
l++;
|
||||
}
|
||||
@ -1209,7 +1291,8 @@ xtextify(t)
|
||||
register int c = (*t++ & 0xff);
|
||||
|
||||
/* ASCII dependence here -- this is the way the spec words it */
|
||||
if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
|
||||
if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(' ||
|
||||
strchr(taboo, c) != NULL)
|
||||
{
|
||||
*p++ = '+';
|
||||
*p++ = "0123456789abcdef"[c >> 4];
|
||||
@ -1298,6 +1381,7 @@ xuntextify(t)
|
||||
c -= 'a' - 10;
|
||||
*p++ |= c;
|
||||
}
|
||||
*p = '\0';
|
||||
return bp;
|
||||
}
|
||||
/*
|
||||
|
@ -29,14 +29,14 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)sendmail.8 8.6 (Berkeley) 5/27/95
|
||||
.\" @(#)sendmail.8 8.10 (Berkeley) 9/20/96
|
||||
.\"
|
||||
.Dd May 27, 1995
|
||||
.Dd September 20, 1996
|
||||
.Dt SENDMAIL 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm sendmail
|
||||
.Nd send mail over the internet
|
||||
.Nd an electronic mail transport agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm sendmail
|
||||
.Op Ar flags
|
||||
@ -108,6 +108,14 @@ listening on socket 25 for incoming
|
||||
connections.
|
||||
This is normally run from
|
||||
.Pa /etc/rc .
|
||||
.It Fl bD
|
||||
Same as
|
||||
.Fl bd
|
||||
except runs in foreground.
|
||||
.It Fl bh
|
||||
Print the persistent host status database.
|
||||
.It Fl bH
|
||||
Purge the persistent host status database.
|
||||
.It Fl bi
|
||||
Initialize the alias database.
|
||||
.It Fl bm
|
||||
@ -165,14 +173,41 @@ the mail is returned with an error message,
|
||||
the victim of an aliasing loop.
|
||||
If not specified,
|
||||
``Received:'' lines in the message are counted.
|
||||
.It Fl i
|
||||
Ignore dots alone on lines by themselves in incoming messages.
|
||||
This should be set if you are reading data from a file.
|
||||
.It Fl N Ar dsn
|
||||
Set delivery status notification conditions to
|
||||
.Ar dsn,
|
||||
which can be
|
||||
.Ql never
|
||||
for no notifications
|
||||
or a comma separated list of the values
|
||||
.Ql failure
|
||||
to be notified if delivery failed,
|
||||
.Ql delay
|
||||
to be notified if delivery is delayed, and
|
||||
.Ql success
|
||||
to be notified when the message is successfully delivered.
|
||||
.It Fl n
|
||||
Don't do aliasing.
|
||||
.It Fl O Ar option Ns = Ns Em value
|
||||
Set option
|
||||
.Ar option
|
||||
to the specified
|
||||
.Em value .
|
||||
This form uses long names.
|
||||
See below for more details.
|
||||
.It Fl o Ns Ar x Em value
|
||||
Set option
|
||||
.Ar x
|
||||
to the specified
|
||||
.Em value .
|
||||
Options are described below.
|
||||
This form uses single character names only.
|
||||
The short names are not described in this manual page;
|
||||
see the
|
||||
.%T "Sendmail Installation and Operation Guide"
|
||||
for details.
|
||||
.It Fl p Ns Ar protocol
|
||||
Set the name of the protocol used to receive the message.
|
||||
This can be a simple protocol name such as ``UUCP''
|
||||
@ -221,6 +256,16 @@ as a substring of one of the recipients.
|
||||
Limit processed jobs to those containing
|
||||
.Ar substr
|
||||
as a substring of the sender.
|
||||
.It Fl R Ar return
|
||||
Set the amount of the message to be returned
|
||||
if the message bounces.
|
||||
The
|
||||
.Ar return
|
||||
parameter can be
|
||||
.Ql full
|
||||
to return the entire message or
|
||||
.Ql hdrs
|
||||
to return only the headers.
|
||||
.It Fl r Ns Ar name
|
||||
An alternate and obsolete form of the
|
||||
.Fl f
|
||||
@ -234,6 +279,22 @@ that is,
|
||||
they will
|
||||
.Em not
|
||||
receive copies even if listed in the message header.
|
||||
.It Fl U
|
||||
Initial (user) submission.
|
||||
This should
|
||||
.Em always
|
||||
be set when called from a user agent such as
|
||||
.Nm Mail
|
||||
or
|
||||
.Nm exmh
|
||||
and
|
||||
.Em never
|
||||
be set when called by a network delivery agent such as
|
||||
.Nm rmail .
|
||||
.It Fl V Ar envid
|
||||
Set the original envelope id.
|
||||
This is propogated across SMTP to servers that support DSNs
|
||||
and is returned in DSN-compliant error messages.
|
||||
.It Fl v
|
||||
Go into verbose mode.
|
||||
Alias expansions will be announced, etc.
|
||||
@ -249,22 +310,25 @@ Normally these will only be used by a system administrator.
|
||||
Options may be set either on the command line
|
||||
using the
|
||||
.Fl o
|
||||
flag
|
||||
flag (for short names),
|
||||
the
|
||||
.Fl O
|
||||
flag (for long names),
|
||||
or in the configuration file.
|
||||
This is a partial list;
|
||||
This is a partial list limited to those options that are likely to be useful
|
||||
on the command line
|
||||
and only shows the long names;
|
||||
for a complete list (and details), consult the
|
||||
.%T "Sendmail Installation and Operation Guide" .
|
||||
The options are:
|
||||
.Bl -tag -width Fl
|
||||
.It Li A Ns Ar file
|
||||
.It Li AliasFile= Ns Ar file
|
||||
Use alternate alias file.
|
||||
.It Li b Ns Ar nblocks
|
||||
The minimum number of free blocks needed on the spool filesystem.
|
||||
.It Li c
|
||||
.It Li HoldExpensive
|
||||
On mailers that are considered ``expensive'' to connect to,
|
||||
don't initiate immediate connection.
|
||||
This requires queueing.
|
||||
.It Li C Ar N
|
||||
.It Li CheckpointInterval= Ns Ar N
|
||||
Checkpoint the queue file after every
|
||||
.Ar N
|
||||
successful deliveries (default 10).
|
||||
@ -272,7 +336,7 @@ This avoids excessive duplicate deliveries
|
||||
when sending to long mailing lists
|
||||
interrupted by system crashes.
|
||||
.ne 1i
|
||||
.It Li d Ns Ar x
|
||||
.It Li DeliveryMode= Ns Ar x
|
||||
Set the delivery mode to
|
||||
.Ar x .
|
||||
Delivery modes are
|
||||
@ -280,14 +344,14 @@ Delivery modes are
|
||||
for interactive (synchronous) delivery,
|
||||
.Ql b
|
||||
for background (asynchronous) delivery,
|
||||
and
|
||||
.Ql q
|
||||
for queue only \- i.e.,
|
||||
actual delivery is done the next time the queue is run.
|
||||
.It Li D
|
||||
Try to automatically rebuild the alias database
|
||||
if necessary.
|
||||
.It Li e Ns Ar x
|
||||
actual delivery is done the next time the queue is run, and
|
||||
.Ql d
|
||||
for deferred \- the same as
|
||||
.Ql q
|
||||
except that database lookups (notably DNS and NIS lookups) are avoided.
|
||||
.It Li ErrorMode= Ns Ar x
|
||||
Set error processing to mode
|
||||
.Ar x .
|
||||
Valid modes are
|
||||
@ -315,41 +379,33 @@ and if the sender is local to this machine,
|
||||
a copy of the message is appended to the file
|
||||
.Pa dead.letter
|
||||
in the sender's home directory.
|
||||
.It Li f
|
||||
.It Li SaveFromLine
|
||||
Save
|
||||
.Tn UNIX Ns \-style
|
||||
From lines at the front of messages.
|
||||
.It Li G
|
||||
Match local mail names against the GECOS portion of the password file.
|
||||
.It Li g Ar N
|
||||
The default group id to use when calling mailers.
|
||||
.It Li H Ns Ar file
|
||||
The
|
||||
.Tn SMTP
|
||||
help file.
|
||||
.It Li h Ar N
|
||||
.It Li MaxHopCount= Ar N
|
||||
The maximum number of times a message is allowed to ``hop''
|
||||
before we decide it is in a loop.
|
||||
.It Li i
|
||||
.It Li IgnoreDots
|
||||
Do not take dots on a line by themselves
|
||||
as a message terminator.
|
||||
.It Li j
|
||||
.It Li SendMimeErrors
|
||||
Send error messages in MIME format.
|
||||
.It Li K Ns Ar timeout
|
||||
If not set, the DSN (Delivery Status Notification) SMTP extension
|
||||
is disabled.
|
||||
.It Li ConnectionCacheTimeout= Ns Ar timeout
|
||||
Set connection cache timeout.
|
||||
.It Li k Ns Ar N
|
||||
.It Li ConnectionCacheSize= Ns Ar N
|
||||
Set connection cache size.
|
||||
.It Li L Ns Ar n
|
||||
.It Li LogLevel= Ns Ar n
|
||||
The log level.
|
||||
.It Li l
|
||||
Pay attention to the Errors-To: header.
|
||||
.It Li m
|
||||
.It Li MeToo
|
||||
Send to ``me'' (the sender) also if I am in an alias expansion.
|
||||
.It Li n
|
||||
.It Li CheckAliases
|
||||
Validate the right hand side of aliases during a
|
||||
.Xr newaliases 1
|
||||
command.
|
||||
.It Li o
|
||||
.It Li OldStyleHeaders
|
||||
If set, this message may have
|
||||
old style headers.
|
||||
If not set,
|
||||
@ -357,24 +413,18 @@ this message is guaranteed to have new style headers
|
||||
(i.e., commas instead of spaces between addresses).
|
||||
If set, an adaptive algorithm is used that will correctly
|
||||
determine the header format in most cases.
|
||||
.It Li Q Ns Ar queuedir
|
||||
.It Li QueueDirectory= Ns Ar queuedir
|
||||
Select the directory in which to queue messages.
|
||||
.It Li S Ns Ar file
|
||||
.It Li StatusFile= Ns Ar file
|
||||
Save statistics in the named file.
|
||||
.It Li s
|
||||
Always instantiate the queue file,
|
||||
even under circumstances where it is not strictly necessary.
|
||||
This provides safety against system crashes during delivery.
|
||||
.It Li T Ns Ar time
|
||||
.It Li Timeout.queuereturn= Ns Ar time
|
||||
Set the timeout on undelivered messages in the queue to the specified time.
|
||||
After delivery has failed
|
||||
(e.g., because of a host being down)
|
||||
for this amount of time,
|
||||
failed messages will be returned to the sender.
|
||||
The default is three days.
|
||||
.It Li t Ns Ar stz , Ar dtz
|
||||
Set the name of the time zone.
|
||||
.It Li U Ns Ar userdatabase
|
||||
The default is five days.
|
||||
.It Li UserDatabaseSpec= Ns Ar userdatabase
|
||||
If set, a user database is consulted to get forwarding information.
|
||||
You can consider this an adjunct to the aliasing mechanism,
|
||||
except that the database is intended to be distributed;
|
||||
@ -382,13 +432,54 @@ aliases are local to a particular host.
|
||||
This may not be available if your sendmail does not have the
|
||||
.Dv USERDB
|
||||
option compiled in.
|
||||
.It Li u Ns Ar N
|
||||
Set the default user id for mailers.
|
||||
.It Li Y
|
||||
.It Li ForkEachJob
|
||||
Fork each job during queue runs.
|
||||
May be convenient on memory-poor machines.
|
||||
.It Li 7
|
||||
.It Li SevenBitInput
|
||||
Strip incoming messages to seven bits.
|
||||
.It Li EightBitMode= Ns Ar mode
|
||||
Set the handling of eight bit input to seven bit destinations to
|
||||
.Ar mode :
|
||||
.Li m
|
||||
(mimefy) will convert to seven-bit MIME format,
|
||||
.Li p
|
||||
(pass) will pass it as eight bits (but violates protocols),
|
||||
and
|
||||
.Li s
|
||||
(strict) will bounce the message.
|
||||
.It Li MinQueueAge= Ns Ar timeout
|
||||
Sets how long a job must ferment in the queue between attempts to send it.
|
||||
.It Li DefaultCharSet= Ns Ar charset
|
||||
Sets the default character set used to label 8-bit data
|
||||
that is not otherwise labelled.
|
||||
.It Li DialDelay= Ns Ar sleeptime
|
||||
If opening a connection fails,
|
||||
sleep for
|
||||
.Ar sleeptime
|
||||
seconds and try again.
|
||||
Useful on dial-on-demand sites.
|
||||
.It Li NoRecipientAction= Ns Ar action
|
||||
Set the behaviour when there are no recipient headers (To:, Cc: or Bcc:)
|
||||
in the message to
|
||||
.Ar action :
|
||||
.Li none
|
||||
leaves the message unchanged,
|
||||
.Li add-to
|
||||
adds a To: header with the envelope recipients,
|
||||
.Li add-apparently-to
|
||||
adds an Apparently-To: header with the envelope recipients,
|
||||
.Li add-bcc
|
||||
adds an empty Bcc: header, and
|
||||
.Li add-to-undisclosed
|
||||
adds a header reading
|
||||
.Ql "To: undisclosed-recipients:;" .
|
||||
.It Li MaxDaemonChildren= Ns Ar N
|
||||
Sets the maximum number of children that an incoming SMTP daemon
|
||||
will allow to spawn at any time to
|
||||
.Ar N .
|
||||
.It Li ConnectionRateThrottle= Ns Ar N
|
||||
Sets the maximum number of connections per second to the SMTP port to
|
||||
.Ar N .
|
||||
.El
|
||||
.Pp
|
||||
In aliases,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -31,7 +31,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sendmail.h 8.159.1.3 (Berkeley) 9/16/96
|
||||
* @(#)sendmail.h 8.206 (Berkeley) 10/17/96
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,7 +41,7 @@
|
||||
# ifdef _DEFINE
|
||||
# define EXTERN
|
||||
# ifndef lint
|
||||
static char SmailSccsId[] = "@(#)sendmail.h 8.159.1.3 9/16/96";
|
||||
static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96";
|
||||
# endif
|
||||
# else /* _DEFINE */
|
||||
# define EXTERN extern
|
||||
@ -179,12 +179,15 @@ typedef struct address ADDRESS;
|
||||
# define QEXPANDED 0x00020000 /* DSN: undergone list expansion */
|
||||
# define QDELIVERED 0x00040000 /* DSN: successful final delivery */
|
||||
# define QDELAYED 0x00080000 /* DSN: message delayed */
|
||||
# define QTHISPASS 0x80000000 /* temp: address set this pass */
|
||||
# define QTHISPASS 0x40000000 /* temp: address set this pass */
|
||||
|
||||
# define Q_PINGFLAGS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY)
|
||||
|
||||
# define NULLADDR ((ADDRESS *) NULL)
|
||||
|
||||
/* functions */
|
||||
extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
|
||||
extern ADDRESS *buildaddr __P((char **, ADDRESS *, int, ENVELOPE *));
|
||||
extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern char **prescan __P((char *, int, char[], int, char **, u_char *));
|
||||
extern int rewrite __P((char **, int, int, ENVELOPE *));
|
||||
@ -250,6 +253,7 @@ struct mailer
|
||||
# define M_INTERNAL 'I' /* SMTP to another sendmail site */
|
||||
# define M_UDBRECIPIENT 'j' /* do udbsender rewriting on recipient lines */
|
||||
# define M_NOLOOPCHECK 'k' /* don't check for loops in HELO command */
|
||||
# define M_CHUNKING 'K' /* CHUNKING: reserved for future use */
|
||||
# define M_LOCALMAILER 'l' /* delivery is to this host */
|
||||
# define M_LIMITS 'L' /* must enforce SMTP line limits */
|
||||
# define M_MUSER 'm' /* can handle multiple users at once */
|
||||
@ -259,6 +263,7 @@ struct mailer
|
||||
# define M_RUNASRCPT 'o' /* always run mailer as recipient */
|
||||
# define M_FROMPATH 'p' /* use reverse-path in MAIL FROM: */
|
||||
/* 'P' CF: include Return-Path: */
|
||||
# define M_VRFY250 'q' /* VRFY command returns 250 instead of 252 */
|
||||
# define M_ROPT 'r' /* mailer takes picky -r flag */
|
||||
# define M_SECURE_PORT 'R' /* try to send on a reserved TCP port */
|
||||
# define M_STRIPQ 's' /* strip quote chars from user/host */
|
||||
@ -270,6 +275,7 @@ struct mailer
|
||||
# define M_HASPWENT 'w' /* check for /etc/passwd entry */
|
||||
/* 'x' CF: include Full-Name: */
|
||||
# define M_XDOT 'X' /* use hidden-dot algorithm */
|
||||
# define M_NOMX '0' /* turn off MX lookups */
|
||||
# define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
|
||||
# define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
|
||||
# define M_7BITS '7' /* use 7-bit path */
|
||||
@ -279,6 +285,7 @@ struct mailer
|
||||
# define M_CHECKPROG '|' /* check for |program addresses */
|
||||
# define M_CHECKFILE '/' /* check for /file addresses */
|
||||
# define M_CHECKUDB '@' /* user can be user database key */
|
||||
# define M_CHECKHDIR '~' /* SGI: check for valid home directory */
|
||||
|
||||
EXTERN MAILER *Mailer[MAXMAILERS+1];
|
||||
|
||||
@ -287,6 +294,75 @@ EXTERN MAILER *ProgMailer; /* ptr to program mailer */
|
||||
EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
|
||||
EXTERN MAILER *InclMailer; /* ptr to *include* mailer */
|
||||
/*
|
||||
** Information about currently open connections to mailers, or to
|
||||
** hosts that we have looked up recently.
|
||||
*/
|
||||
|
||||
# define MCI struct mailer_con_info
|
||||
|
||||
MCI
|
||||
{
|
||||
short mci_flags; /* flag bits, see below */
|
||||
short mci_errno; /* error number on last connection */
|
||||
short mci_herrno; /* h_errno from last DNS lookup */
|
||||
short mci_exitstat; /* exit status from last connection */
|
||||
short mci_state; /* SMTP state */
|
||||
long mci_maxsize; /* max size this server will accept */
|
||||
FILE *mci_in; /* input side of connection */
|
||||
FILE *mci_out; /* output side of connection */
|
||||
int mci_pid; /* process id of subordinate proc */
|
||||
char *mci_phase; /* SMTP phase string */
|
||||
struct mailer *mci_mailer; /* ptr to the mailer for this conn */
|
||||
char *mci_host; /* host name */
|
||||
char *mci_status; /* DSN status to be copied to addrs */
|
||||
char *mci_rstatus; /* SMTP status to be copied to addrs */
|
||||
time_t mci_lastuse; /* last usage time */
|
||||
FILE *mci_statfile; /* long term status file */
|
||||
};
|
||||
|
||||
|
||||
/* flag bits */
|
||||
#define MCIF_VALID 0x0001 /* this entry is valid */
|
||||
#define MCIF_TEMP 0x0002 /* don't cache this connection */
|
||||
#define MCIF_CACHED 0x0004 /* currently in open cache */
|
||||
#define MCIF_ESMTP 0x0008 /* this host speaks ESMTP */
|
||||
#define MCIF_EXPN 0x0010 /* EXPN command supported */
|
||||
#define MCIF_SIZE 0x0020 /* SIZE option supported */
|
||||
#define MCIF_8BITMIME 0x0040 /* BODY=8BITMIME supported */
|
||||
#define MCIF_7BIT 0x0080 /* strip this message to 7 bits */
|
||||
#define MCIF_MULTSTAT 0x0100 /* MAIL11V3: handles MULT status */
|
||||
#define MCIF_INHEADER 0x0200 /* currently outputing header */
|
||||
#define MCIF_CVT8TO7 0x0400 /* convert from 8 to 7 bits */
|
||||
#define MCIF_DSN 0x0800 /* DSN extension supported */
|
||||
#define MCIF_8BITOK 0x1000 /* OK to send 8 bit characters */
|
||||
#define MCIF_CVT7TO8 0x2000 /* convert from 7 to 8 bits */
|
||||
#define MCIF_INMIME 0x4000 /* currently reading MIME header */
|
||||
|
||||
/* states */
|
||||
#define MCIS_CLOSED 0 /* no traffic on this connection */
|
||||
#define MCIS_OPENING 1 /* sending initial protocol */
|
||||
#define MCIS_OPEN 2 /* open, initial protocol sent */
|
||||
#define MCIS_ACTIVE 3 /* message being sent */
|
||||
#define MCIS_QUITING 4 /* running quit protocol */
|
||||
#define MCIS_SSD 5 /* service shutting down */
|
||||
#define MCIS_ERROR 6 /* I/O error on connection */
|
||||
|
||||
/* functions */
|
||||
extern MCI *mci_get __P((char *, MAILER *));
|
||||
extern void mci_cache __P((MCI *));
|
||||
extern void mci_flush __P((bool, MCI *));
|
||||
extern void mci_dump __P((MCI *, bool));
|
||||
extern void mci_dump_all __P((bool));
|
||||
extern MCI **mci_scan __P((MCI *));
|
||||
extern int mci_traverse_persistent __P((int (), char *));
|
||||
extern int mci_print_persistent __P((char *, char *));
|
||||
extern int mci_purge_persistent __P((char *, char *));
|
||||
extern int mci_lock_host __P((MCI *));
|
||||
extern void mci_unlock_host __P((MCI *));
|
||||
extern int mci_lock_host_statfile __P((MCI *));
|
||||
extern void mci_store_persistent __P((MCI *));
|
||||
extern int mci_read_persistent __P((FILE *, MCI *));
|
||||
/*
|
||||
** Header structure.
|
||||
** This structure is used internally to store header items.
|
||||
*/
|
||||
@ -332,62 +408,15 @@ extern struct hdrinfo HdrInfo[];
|
||||
# define H_CTE 0x1000 /* this field is a content-transfer-encoding */
|
||||
# define H_CTYPE 0x2000 /* this is a content-type field */
|
||||
# define H_BCC 0x4000 /* Bcc: header: strip value or delete */
|
||||
/*
|
||||
** Information about currently open connections to mailers, or to
|
||||
** hosts that we have looked up recently.
|
||||
*/
|
||||
|
||||
# define MCI struct mailer_con_info
|
||||
|
||||
MCI
|
||||
{
|
||||
short mci_flags; /* flag bits, see below */
|
||||
short mci_errno; /* error number on last connection */
|
||||
short mci_herrno; /* h_errno from last DNS lookup */
|
||||
short mci_exitstat; /* exit status from last connection */
|
||||
short mci_state; /* SMTP state */
|
||||
long mci_maxsize; /* max size this server will accept */
|
||||
FILE *mci_in; /* input side of connection */
|
||||
FILE *mci_out; /* output side of connection */
|
||||
int mci_pid; /* process id of subordinate proc */
|
||||
char *mci_phase; /* SMTP phase string */
|
||||
struct mailer *mci_mailer; /* ptr to the mailer for this conn */
|
||||
char *mci_host; /* host name */
|
||||
char *mci_status; /* DSN status to be copied to addrs */
|
||||
time_t mci_lastuse; /* last usage time */
|
||||
};
|
||||
|
||||
|
||||
/* flag bits */
|
||||
#define MCIF_VALID 0x0001 /* this entry is valid */
|
||||
#define MCIF_TEMP 0x0002 /* don't cache this connection */
|
||||
#define MCIF_CACHED 0x0004 /* currently in open cache */
|
||||
#define MCIF_ESMTP 0x0008 /* this host speaks ESMTP */
|
||||
#define MCIF_EXPN 0x0010 /* EXPN command supported */
|
||||
#define MCIF_SIZE 0x0020 /* SIZE option supported */
|
||||
#define MCIF_8BITMIME 0x0040 /* BODY=8BITMIME supported */
|
||||
#define MCIF_7BIT 0x0080 /* strip this message to 7 bits */
|
||||
#define MCIF_MULTSTAT 0x0100 /* MAIL11V3: handles MULT status */
|
||||
#define MCIF_INHEADER 0x0200 /* currently outputing header */
|
||||
#define MCIF_CVT8TO7 0x0400 /* convert from 8 to 7 bits */
|
||||
#define MCIF_DSN 0x0800 /* DSN extension supported */
|
||||
#define MCIF_8BITOK 0x1000 /* OK to send 8 bit characters */
|
||||
#define MCIF_CVT7TO8 0x2000 /* convert from 7 to 8 bits */
|
||||
#define MCIF_INMIME 0x4000 /* currently reading MIME header */
|
||||
|
||||
/* states */
|
||||
#define MCIS_CLOSED 0 /* no traffic on this connection */
|
||||
#define MCIS_OPENING 1 /* sending initial protocol */
|
||||
#define MCIS_OPEN 2 /* open, initial protocol sent */
|
||||
#define MCIS_ACTIVE 3 /* message being sent */
|
||||
#define MCIS_QUITING 4 /* running quit protocol */
|
||||
#define MCIS_SSD 5 /* service shutting down */
|
||||
#define MCIS_ERROR 6 /* I/O error on connection */
|
||||
# define H_ENCODABLE 0x8000 /* field can be RFC 1522 encoded */
|
||||
|
||||
/* functions */
|
||||
extern MCI *mci_get __P((char *, MAILER *));
|
||||
extern void mci_cache __P((MCI *));
|
||||
extern void mci_flush __P((bool, MCI *));
|
||||
extern void addheader __P((char *, char *, HDR **));
|
||||
extern char *hvalue __P((char *, HDR *));
|
||||
extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
|
||||
extern void put_vanilla_header __P((HDR *, char *, MCI *));
|
||||
extern void eatheader __P((ENVELOPE *e, bool));
|
||||
extern int chompheader __P((char *, bool, HDR **, ENVELOPE *));
|
||||
/*
|
||||
** Envelope structure.
|
||||
** This structure defines the message itself. There is usually
|
||||
@ -403,7 +432,6 @@ struct envelope
|
||||
long e_msgpriority; /* adjusted priority of this message */
|
||||
time_t e_ctime; /* time message appeared in the queue */
|
||||
char *e_to; /* the target person */
|
||||
char *e_receiptto; /* return receipt address */
|
||||
ADDRESS e_from; /* the person it is from */
|
||||
char *e_sender; /* e_from.q_paddr w comments stripped */
|
||||
char **e_fromdomain; /* the domain part of the sender */
|
||||
@ -472,7 +500,7 @@ EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
|
||||
|
||||
/* functions */
|
||||
extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *));
|
||||
extern void dropenvelope __P((ENVELOPE *));
|
||||
extern void dropenvelope __P((ENVELOPE *, bool));
|
||||
extern void clearenvelope __P((ENVELOPE *, bool));
|
||||
|
||||
extern void putheader __P((MCI *, HDR *, ENVELOPE *));
|
||||
@ -636,7 +664,8 @@ MAP
|
||||
char *map_domain; /* the (nominal) NIS domain */
|
||||
char *map_rebuild; /* program to run to do auto-rebuild */
|
||||
time_t map_mtime; /* last database modification time */
|
||||
short map_specificity; /* specificity of alaases */
|
||||
int map_lockfd; /* auxiliary lock file descriptor */
|
||||
short map_specificity; /* specificity of aliases */
|
||||
MAP *map_stack[MAXMAPSTACK]; /* list for stacked maps */
|
||||
short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */
|
||||
};
|
||||
@ -659,6 +688,7 @@ MAP
|
||||
# define MF_UNSAFEDB 0x00004000 /* this map is world writable */
|
||||
# define MF_APPEND 0x00008000 /* append new entry on rebuiled */
|
||||
# define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */
|
||||
# define MF_NODEFER 0x00020000 /* don't defer if map lookup fails */
|
||||
|
||||
/* indices for map_actions */
|
||||
# define MA_NOTFOUND 0 /* member map returned "not found" */
|
||||
@ -695,6 +725,7 @@ MAPCLASS
|
||||
/* functions */
|
||||
extern char *map_rewrite __P((MAP *, char *, int, char **));
|
||||
extern MAP *makemapentry __P((char *));
|
||||
extern void initmaps __P((bool, ENVELOPE *));
|
||||
/*
|
||||
** Symbol table definitions
|
||||
*/
|
||||
@ -702,7 +733,8 @@ extern MAP *makemapentry __P((char *));
|
||||
struct symtab
|
||||
{
|
||||
char *s_name; /* name to be entered */
|
||||
char s_type; /* general type (see below) */
|
||||
short s_type; /* general type (see below) */
|
||||
short s_len; /* length of this entry */
|
||||
struct symtab *s_next; /* pointer to next in chain */
|
||||
union
|
||||
{
|
||||
@ -717,6 +749,7 @@ struct symtab
|
||||
NAMECANON sv_namecanon; /* canonical name cache */
|
||||
int sv_macro; /* macro name => id mapping */
|
||||
int sv_ruleset; /* ruleset index */
|
||||
char *sv_service[MAXMAPSTACK]; /* service switch */
|
||||
} s_value;
|
||||
};
|
||||
|
||||
@ -734,6 +767,7 @@ typedef struct symtab STAB;
|
||||
# define ST_NAMECANON 8 /* cached canonical name */
|
||||
# define ST_MACRO 9 /* macro name to id mapping */
|
||||
# define ST_RULESET 10 /* ruleset index */
|
||||
# define ST_SERVICE 11 /* service switch entry */
|
||||
# define ST_MCI 16 /* mailer connection info (offset) */
|
||||
|
||||
# define s_class s_value.sv_class
|
||||
@ -747,6 +781,7 @@ typedef struct symtab STAB;
|
||||
# define s_namecanon s_value.sv_namecanon
|
||||
# define s_macro s_value.sv_macro
|
||||
# define s_ruleset s_value.sv_ruleset
|
||||
# define s_service s_value.sv_service
|
||||
|
||||
extern STAB *stab __P((char *, int, int));
|
||||
extern void stabapply __P((void (*)(STAB *, int), int));
|
||||
@ -802,12 +837,14 @@ EXTERN char OpMode; /* operation mode, see below */
|
||||
#define MD_SMTP 's' /* run SMTP on standard input */
|
||||
#define MD_ARPAFTP 'a' /* obsolete ARPANET mode (Grey Book) */
|
||||
#define MD_DAEMON 'd' /* run as a daemon */
|
||||
#define MD_FGDAEMON 'D' /* run daemon in foreground */
|
||||
#define MD_VERIFY 'v' /* verify: don't collect or deliver */
|
||||
#define MD_TEST 't' /* test mode: resolve addrs only */
|
||||
#define MD_INITALIAS 'i' /* initialize alias database */
|
||||
#define MD_PRINT 'p' /* print the queue */
|
||||
#define MD_FREEZE 'z' /* freeze the configuration file */
|
||||
|
||||
#define MD_HOSTSTAT 'h' /* print persistent host stat info */
|
||||
#define MD_PURGESTAT 'H' /* purge persistent host stat info */
|
||||
|
||||
/* values for e_sendmode -- send modes */
|
||||
#define SM_DELIVER 'i' /* interactive delivery */
|
||||
@ -841,6 +878,7 @@ EXTERN int QueueSortOrder;
|
||||
|
||||
#define QS_BYPRIORITY 0 /* sort by message priority */
|
||||
#define QS_BYHOST 1 /* sort by first host name */
|
||||
#define QS_BYTIME 2 /* sort by submission time */
|
||||
|
||||
|
||||
/* how to handle messages without any recipient addresses */
|
||||
@ -856,7 +894,7 @@ EXTERN int NoRecipientAction;
|
||||
/* flags to putxline */
|
||||
#define PXLF_NOTHINGSPECIAL 0 /* no special mapping */
|
||||
#define PXLF_MAPFROM 0x0001 /* map From_ to >From_ */
|
||||
#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit *e
|
||||
#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit */
|
||||
/*
|
||||
** Additional definitions
|
||||
*/
|
||||
@ -918,6 +956,9 @@ struct prival
|
||||
/* flags that are actually specific to safefopen */
|
||||
#define SFF_OPENASROOT 0x1000 /* open as root instead of real user */
|
||||
|
||||
/* functions */
|
||||
extern int safefile __P((char *, UID_T, GID_T, char *, int, int, struct stat *));
|
||||
|
||||
|
||||
/*
|
||||
** Flags passed to mime8to7.
|
||||
@ -928,6 +969,15 @@ struct prival
|
||||
#define M87F_DIGEST 0x0002 /* processing multipart/digest */
|
||||
|
||||
|
||||
/*
|
||||
** Flags passed to returntosender.
|
||||
*/
|
||||
|
||||
#define RTSF_NO_BODY 0 /* send headers only */
|
||||
#define RTSF_SEND_BODY 0x0001 /* include body of message in return */
|
||||
#define RTSF_PM_BOUNCE 0x0002 /* this is a postmaster bounce */
|
||||
|
||||
|
||||
/*
|
||||
** Regular UNIX sockaddrs are too small to handle ISO addresses, so
|
||||
** we are forced to declare a supertype here.
|
||||
@ -957,6 +1007,8 @@ union bigsockaddr
|
||||
#define SOCKADDR union bigsockaddr
|
||||
|
||||
EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */
|
||||
|
||||
extern char *hostnamebyanyaddr __P((SOCKADDR *));
|
||||
extern char *anynet_ntoa __P((SOCKADDR *));
|
||||
|
||||
#endif
|
||||
@ -983,6 +1035,34 @@ extern char *anynet_ntoa __P((SOCKADDR *));
|
||||
#define VENDOR_IBM 4 /* IBM specific config syntax */
|
||||
|
||||
EXTERN int VendorCode; /* vendor-specific operation enhancements */
|
||||
|
||||
/* prototypes for vendor-specific hook routines */
|
||||
extern void vendor_set_uid __P((UID_T));
|
||||
extern void vendor_daemon_setup __P((ENVELOPE *));
|
||||
|
||||
|
||||
/*
|
||||
** Terminal escape codes.
|
||||
**
|
||||
** To make debugging output clearer.
|
||||
*/
|
||||
|
||||
struct termescape
|
||||
{
|
||||
char *te_rv_on; /* turn reverse-video on */
|
||||
char *te_rv_off; /* turn reverse-video off */
|
||||
};
|
||||
|
||||
EXTERN struct termescape TermEscape;
|
||||
|
||||
|
||||
/*
|
||||
** Error return from inet_addr(3), in case not defined in /usr/include.
|
||||
*/
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
# define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
/*
|
||||
** Global variables.
|
||||
*/
|
||||
@ -1005,6 +1085,7 @@ EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */
|
||||
EXTERN bool UseHesiod; /* using Hesiod -- interpret Hesiod errors */
|
||||
EXTERN bool SevenBitInput; /* force 7-bit data on input */
|
||||
EXTERN bool HasEightBits; /* has at least one eight bit input byte */
|
||||
EXTERN bool ConfigFileRead; /* configuration file has been read */
|
||||
EXTERN time_t SafeAlias; /* interval to wait until @:@ in alias file */
|
||||
EXTERN FILE *InChannel; /* input connection */
|
||||
EXTERN FILE *OutChannel; /* output connection */
|
||||
@ -1061,11 +1142,11 @@ EXTERN char *ForwardPath; /* path to search for .forward files */
|
||||
EXTERN long MinBlocksFree; /* min # of blocks free on queue fs */
|
||||
EXTERN char *FallBackMX; /* fall back MX host */
|
||||
EXTERN long MaxMessageSize; /* advertised max size we will accept */
|
||||
EXTERN time_t MaxHostStatAge; /* max age of cached host status info */
|
||||
EXTERN time_t MinQueueAge; /* min delivery interval */
|
||||
EXTERN time_t DialDelay; /* delay between dial-on-demand tries */
|
||||
EXTERN char *SafeFileEnv; /* chroot location for file delivery */
|
||||
EXTERN char *HostsFile; /* path to /etc/hosts file */
|
||||
EXTERN char *HostStatDir; /* location of host status information */
|
||||
EXTERN int MaxQueueRun; /* maximum number of jobs in one queue run */
|
||||
EXTERN int MaxChildren; /* maximum number of daemonic children */
|
||||
EXTERN int CurChildren; /* current number of daemonic children */
|
||||
@ -1073,8 +1154,17 @@ EXTERN char *SmtpGreeting; /* SMTP greeting message (old $e macro) */
|
||||
EXTERN char *UnixFromLine; /* UNIX From_ line (old $l macro) */
|
||||
EXTERN char *OperatorChars; /* operators (old $o macro) */
|
||||
EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
|
||||
EXTERN int DefaultNotify; /* default DSN notification flags */
|
||||
EXTERN bool AllowBogusHELO; /* allow syntax errors on HELO command */
|
||||
EXTERN bool UserSubmission; /* initial (user) mail submission */
|
||||
EXTERN uid_t RunAsUid; /* UID to become for bulk of run */
|
||||
EXTERN gid_t RunAsGid; /* GID to become for bulk of run */
|
||||
EXTERN bool SingleThreadDelivery; /* single thread hosts on delivery */
|
||||
EXTERN bool UnsafeGroupWrites; /* group-writable files are unsafe */
|
||||
EXTERN bool SingleLineFromHeader; /* force From: header to be one line */
|
||||
EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */
|
||||
EXTERN int MaxAliasRecursion; /* maximum depth of alias recursion */
|
||||
EXTERN int MaxMacroRecursion; /* maximum depth of macro recursion */
|
||||
EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */
|
||||
EXTERN char *MustQuoteChars; /* quote these characters in phrases */
|
||||
EXTERN char *ServiceSwitchFile; /* backup service switch */
|
||||
@ -1085,12 +1175,16 @@ EXTERN int CheckpointInterval; /* queue file checkpoint interval */
|
||||
EXTERN bool DontPruneRoutes; /* don't prune source routes */
|
||||
EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */
|
||||
EXTERN int MaxMciCache; /* maximum entries in MCI cache */
|
||||
EXTERN time_t ServiceCacheTime; /* time service switch was cached */
|
||||
EXTERN time_t ServiceCacheMaxAge; /* refresh interval for cache */
|
||||
EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */
|
||||
EXTERN time_t MciInfoTimeout; /* how long 'til we retry down hosts */
|
||||
EXTERN char *QueueLimitRecipient; /* limit queue runs to this recipient */
|
||||
EXTERN char *QueueLimitSender; /* limit queue runs to this sender */
|
||||
EXTERN char *QueueLimitId; /* limit queue runs to this id */
|
||||
EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */
|
||||
EXTERN char *DoubleBounceAddr; /* where to send double bounces */
|
||||
EXTERN char **ExternalEnviron; /* input environment */
|
||||
EXTERN char *UserEnviron[MAXUSERENVIRON + 1];
|
||||
/* saved user environment */
|
||||
extern int errno;
|
||||
@ -1113,7 +1207,8 @@ EXTERN struct
|
||||
time_t to_datafinal; /* DATA completion [10m] */
|
||||
time_t to_nextcommand; /* next command [5m] */
|
||||
/* following timeouts are not mentioned in RFC 1123 */
|
||||
time_t to_connect; /* initial connection timeout */
|
||||
time_t to_iconnect; /* initial connection timeout (first try) */
|
||||
time_t to_connect; /* initial connection timeout (later tries) */
|
||||
time_t to_rset; /* RSET command */
|
||||
time_t to_helo; /* HELO command */
|
||||
time_t to_quit; /* QUIT command */
|
||||
@ -1161,6 +1256,7 @@ EXTERN u_char tTdvect[100];
|
||||
#define STRUCTCOPY(s, d) d = s
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Declarations of useful functions
|
||||
*/
|
||||
@ -1181,8 +1277,6 @@ extern void openxscript __P((ENVELOPE *));
|
||||
extern void closexscript __P((ENVELOPE *));
|
||||
extern char *shortenstring __P((const char *, int));
|
||||
extern bool usershellok __P((char *, char *));
|
||||
extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
|
||||
extern char *hvalue __P((char *, HDR *));
|
||||
extern char *defcharset __P((ENVELOPE *));
|
||||
extern bool wordinclass __P((char *, int));
|
||||
extern char *denlstring __P((char *, bool, bool));
|
||||
@ -1197,6 +1291,7 @@ extern void logsender __P((ENVELOPE *, char *));
|
||||
extern void smtprset __P((MAILER *, MCI *, ENVELOPE *));
|
||||
extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *));
|
||||
extern void setuserenv __P((const char *, const char *));
|
||||
extern char *getextenv __P((const char *));
|
||||
extern void disconnect __P((int, ENVELOPE *));
|
||||
extern void putxline __P((char *, MCI *, int));
|
||||
extern void dumpfd __P((int, bool, bool));
|
||||
@ -1208,15 +1303,66 @@ extern void inittimeouts __P((char *));
|
||||
extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *));
|
||||
extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *));
|
||||
extern void buildfname __P((char *, char *, char *, int));
|
||||
extern void mci_setstat __P((MCI *, char *, char *));
|
||||
extern char *smtptodsn __P((int));
|
||||
extern int rscheck __P((char *, char *, char *, ENVELOPE *e));
|
||||
extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *));
|
||||
extern int mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int));
|
||||
extern void xfclose __P((FILE *, char *, char *));
|
||||
extern int switch_map_find __P((char *, char *[], short []));
|
||||
extern void shorten_hostname __P((char []));
|
||||
extern int waitfor __P((pid_t));
|
||||
extern void proc_list_add __P((pid_t));
|
||||
extern void proc_list_drop __P((pid_t));
|
||||
extern void buffer_errors __P((void));
|
||||
extern void flush_errors __P((bool));
|
||||
extern void putline __P((char *, MCI *));
|
||||
extern void putxline __P((char *, MCI *, int));
|
||||
extern bool xtextok __P((char *));
|
||||
extern char *xtextify __P((char *, char *));
|
||||
extern char *xuntextify __P((char *));
|
||||
extern void cleanstrcpy __P((char *, char *, int));
|
||||
extern int getmxrr __P((char *, char **, bool, int *));
|
||||
extern int strtorwset __P((char *, char **, int));
|
||||
extern void printav __P((char **));
|
||||
extern void printopenfds __P((bool));
|
||||
extern int endmailer __P((MCI *, ENVELOPE *, char **));
|
||||
extern void fixcrlf __P((char *, bool));
|
||||
extern int dofork __P((void));
|
||||
extern void initsys __P((ENVELOPE *));
|
||||
extern void collect __P((FILE *, bool, bool, HDR **, ENVELOPE *));
|
||||
extern void stripquotes __P((char *));
|
||||
extern int include __P((char *, bool, ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern void unlockqueue __P((ENVELOPE *));
|
||||
extern void xunlink __P((char *));
|
||||
extern void runqueue __P((bool));
|
||||
extern int getla __P((void));
|
||||
extern void sendall __P((ENVELOPE *, int));
|
||||
extern void queueup __P((ENVELOPE *, bool));
|
||||
extern void checkfds __P((char *));
|
||||
extern int returntosender __P((char *, ADDRESS *, int, ENVELOPE *));
|
||||
extern void markstats __P((ENVELOPE *, ADDRESS *));
|
||||
extern void poststats __P((char *));
|
||||
extern char *arpadate __P((char *));
|
||||
extern int mailfile __P((char *, ADDRESS *, int, ENVELOPE *));
|
||||
extern void loseqfile __P((ENVELOPE *, char *));
|
||||
extern int prog_open __P((char **, int *, ENVELOPE *));
|
||||
extern bool getcanonname __P((char *, int, bool));
|
||||
extern bool validate_connection __P((SOCKADDR *, char *, ENVELOPE *));
|
||||
extern bool path_is_dir __P((char *, bool));
|
||||
extern pid_t dowork __P((char *, bool, bool, ENVELOPE *));
|
||||
|
||||
extern const char *errstring __P((int));
|
||||
extern sigfunc_t setsignal __P((int, sigfunc_t));
|
||||
extern int releasesignal __P((int));
|
||||
extern struct hostent *sm_gethostbyname __P((char *));
|
||||
extern struct hostent *sm_gethostbyaddr __P((char *, int, int));
|
||||
extern struct passwd *sm_getpwnam __P((char *));
|
||||
extern struct passwd *sm_getpwuid __P((UID_T));
|
||||
extern struct passwd *finduser __P((char *, bool *));
|
||||
|
||||
#ifdef XDEBUG
|
||||
extern void checkfdopen __P((int, char *));
|
||||
extern void checkfd012 __P((char *));
|
||||
#endif
|
||||
|
||||
@ -1227,12 +1373,14 @@ extern void syserr(const char *, ...);
|
||||
extern void usrerr(const char *, ...);
|
||||
extern void message(const char *, ...);
|
||||
extern void nmessage(const char *, ...);
|
||||
extern void setproctitle(const char *fmt, ...);
|
||||
#else
|
||||
extern void auth_warning();
|
||||
extern void syserr();
|
||||
extern void usrerr();
|
||||
extern void message();
|
||||
extern void nmessage();
|
||||
extern void setproctitle();
|
||||
#endif
|
||||
|
||||
#if !HASSNPRINTF
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -36,9 +36,9 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifdef SMTP
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (with SMTP)";
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (without SMTP)";
|
||||
static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -79,9 +79,11 @@ struct cmd
|
||||
# define CMDHELO 9 /* helo -- be polite */
|
||||
# define CMDHELP 10 /* help -- give usage info */
|
||||
# define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */
|
||||
# define CMDETRN 12 /* etrn -- flush queue */
|
||||
/* non-standard commands */
|
||||
# define CMDONEX 16 /* onex -- sending one transaction only */
|
||||
# define CMDVERB 17 /* verb -- go into verbose mode */
|
||||
# define CMDXUSR 18 /* xusr -- initial (user) submission */
|
||||
/* use this to catch and log "door handle" attempts on your system */
|
||||
# define CMDLOGBOGUS 23 /* bogus command that should be logged */
|
||||
/* debugging-only commands, only enabled if SMTPDEBUG is defined */
|
||||
@ -90,27 +92,27 @@ struct cmd
|
||||
|
||||
static struct cmd CmdTab[] =
|
||||
{
|
||||
"mail", CMDMAIL,
|
||||
"rcpt", CMDRCPT,
|
||||
"data", CMDDATA,
|
||||
"rset", CMDRSET,
|
||||
"vrfy", CMDVRFY,
|
||||
"expn", CMDEXPN,
|
||||
"help", CMDHELP,
|
||||
"noop", CMDNOOP,
|
||||
"quit", CMDQUIT,
|
||||
"helo", CMDHELO,
|
||||
"ehlo", CMDEHLO,
|
||||
"verb", CMDVERB,
|
||||
"onex", CMDONEX,
|
||||
/*
|
||||
* remaining commands are here only
|
||||
* to trap and log attempts to use them
|
||||
*/
|
||||
"showq", CMDDBGQSHOW,
|
||||
"debug", CMDDBGDEBUG,
|
||||
"wiz", CMDLOGBOGUS,
|
||||
NULL, CMDERROR,
|
||||
{ "mail", CMDMAIL },
|
||||
{ "rcpt", CMDRCPT },
|
||||
{ "data", CMDDATA },
|
||||
{ "rset", CMDRSET },
|
||||
{ "vrfy", CMDVRFY },
|
||||
{ "expn", CMDEXPN },
|
||||
{ "help", CMDHELP },
|
||||
{ "noop", CMDNOOP },
|
||||
{ "quit", CMDQUIT },
|
||||
{ "helo", CMDHELO },
|
||||
{ "ehlo", CMDEHLO },
|
||||
{ "etrn", CMDETRN },
|
||||
{ "verb", CMDVERB },
|
||||
{ "onex", CMDONEX },
|
||||
{ "xusr", CMDXUSR },
|
||||
/* remaining commands are here only to trap and log attempts to use them */
|
||||
{ "showq", CMDDBGQSHOW },
|
||||
{ "debug", CMDDBGDEBUG },
|
||||
{ "wiz", CMDLOGBOGUS },
|
||||
|
||||
{ NULL, CMDERROR }
|
||||
};
|
||||
|
||||
bool OneXact = FALSE; /* one xaction only this run */
|
||||
@ -122,7 +124,8 @@ static char *skipword();
|
||||
#define MAXBADCOMMANDS 25 /* maximum number of bad commands */
|
||||
|
||||
void
|
||||
smtp(e)
|
||||
smtp(nullserver, e)
|
||||
bool nullserver;
|
||||
register ENVELOPE *volatile e;
|
||||
{
|
||||
register char *p;
|
||||
@ -141,10 +144,15 @@ smtp(e)
|
||||
volatile int nrcpts = 0; /* number of RCPT commands */
|
||||
bool doublequeue;
|
||||
volatile int badcommands = 0; /* count of bad commands */
|
||||
volatile int nverifies = 0; /* count of VRFY/EXPN commands */
|
||||
volatile int n_etrn = 0; /* count of ETRN commands */
|
||||
char inp[MAXLINE];
|
||||
char cmdbuf[MAXLINE];
|
||||
extern ENVELOPE BlankEnvelope;
|
||||
extern void help __P((char *));
|
||||
extern void settime __P((ENVELOPE *));
|
||||
extern bool enoughdiskspace __P((long));
|
||||
extern int runinchild __P((char *, ENVELOPE *));
|
||||
|
||||
if (fileno(OutChannel) != fileno(stdout))
|
||||
{
|
||||
@ -253,6 +261,11 @@ smtp(e)
|
||||
if (e->e_xfp != NULL)
|
||||
fprintf(e->e_xfp, "<<< %s\n", inp);
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel >= 15)
|
||||
syslog(LOG_INFO, "<-- %s", inp);
|
||||
#endif
|
||||
|
||||
if (e->e_id == NULL)
|
||||
setproctitle("%s: %.80s", CurSmtpClient, inp);
|
||||
else
|
||||
@ -282,7 +295,20 @@ smtp(e)
|
||||
/* reset errors */
|
||||
errno = 0;
|
||||
|
||||
/* process command */
|
||||
/*
|
||||
** Process command.
|
||||
**
|
||||
** If we are running as a null server, return 550
|
||||
** to everything.
|
||||
*/
|
||||
|
||||
if (nullserver && c->cmdcode != CMDQUIT)
|
||||
{
|
||||
message("550 Access denied");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* non-null server */
|
||||
switch (c->cmdcode)
|
||||
{
|
||||
case CMDHELO: /* hello -- introduce yourself */
|
||||
@ -299,7 +325,7 @@ smtp(e)
|
||||
}
|
||||
|
||||
/* check for valid domain name (re 1123 5.2.5) */
|
||||
if (*p == '\0')
|
||||
if (*p == '\0' && !AllowBogusHELO)
|
||||
{
|
||||
message("501 %s requires domain address",
|
||||
cmdbuf);
|
||||
@ -325,11 +351,23 @@ smtp(e)
|
||||
}
|
||||
if (*q != '\0')
|
||||
{
|
||||
if (!AllowBogusHELO)
|
||||
message("501 Invalid domain name");
|
||||
else
|
||||
message("250 %s Invalid domain name, accepting anyway",
|
||||
MyHostName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for duplicate HELO/EHLO per RFC 1651 4.2 */
|
||||
if (gothello)
|
||||
{
|
||||
message("503 %s Duplicate HELO/EHLO",
|
||||
MyHostName);
|
||||
break;
|
||||
}
|
||||
|
||||
sendinghost = newstr(p);
|
||||
gothello = TRUE;
|
||||
if (c->cmdcode != CMDEHLO)
|
||||
@ -344,7 +382,10 @@ smtp(e)
|
||||
message("250-%s Hello %s, pleased to meet you",
|
||||
MyHostName, CurSmtpClient);
|
||||
if (!bitset(PRIV_NOEXPN, PrivacyFlags))
|
||||
{
|
||||
message("250-EXPN");
|
||||
message("250-VERB");
|
||||
}
|
||||
#if MIME8TO7
|
||||
message("250-8BITMIME");
|
||||
#endif
|
||||
@ -356,8 +397,9 @@ smtp(e)
|
||||
if (SendMIMEErrors)
|
||||
message("250-DSN");
|
||||
#endif
|
||||
message("250-VERB");
|
||||
message("250-ONEX");
|
||||
message("250-ETRN");
|
||||
message("250-XUSR");
|
||||
message("250 HELP");
|
||||
break;
|
||||
|
||||
@ -391,13 +433,17 @@ smtp(e)
|
||||
finis();
|
||||
}
|
||||
|
||||
p = skipword(p, "from");
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
/* fork a subprocess to process this command */
|
||||
if (runinchild("SMTP-MAIL", e) > 0)
|
||||
break;
|
||||
if (!gothello)
|
||||
{
|
||||
auth_warning(e,
|
||||
"Host %s didn't use HELO protocol",
|
||||
"%s didn't use HELO protocol",
|
||||
CurSmtpClient);
|
||||
}
|
||||
#ifdef PICKY_HELO_CHECK
|
||||
@ -420,12 +466,10 @@ smtp(e)
|
||||
setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp);
|
||||
|
||||
/* child -- go do the processing */
|
||||
p = skipword(p, "from");
|
||||
if (p == NULL)
|
||||
break;
|
||||
if (setjmp(TopFrame) > 0)
|
||||
{
|
||||
/* this failed -- undo work */
|
||||
undo_subproc:
|
||||
if (InChild)
|
||||
{
|
||||
QuickAbort = FALSE;
|
||||
@ -440,9 +484,12 @@ smtp(e)
|
||||
/* must parse sender first */
|
||||
delimptr = NULL;
|
||||
setsender(p, e, &delimptr, FALSE);
|
||||
p = delimptr;
|
||||
if (p != NULL && *p != '\0')
|
||||
*p++ = '\0';
|
||||
if (delimptr != NULL && *delimptr != '\0')
|
||||
*delimptr++ = '\0';
|
||||
|
||||
/* do config file checking of the sender */
|
||||
if (rscheck("check_mail", p, NULL, e) != EX_OK)
|
||||
goto undo_subproc;
|
||||
|
||||
/* check for possible spoofing */
|
||||
if (RealUid != 0 && OpMode == MD_SMTP &&
|
||||
@ -456,6 +503,7 @@ smtp(e)
|
||||
|
||||
/* now parse ESMTP arguments */
|
||||
e->e_msgsize = 0;
|
||||
p = delimptr;
|
||||
while (p != NULL && *p != '\0')
|
||||
{
|
||||
char *kp;
|
||||
@ -470,7 +518,7 @@ smtp(e)
|
||||
kp = p;
|
||||
|
||||
/* skip to the value portion */
|
||||
while (isascii(*p) && isalnum(*p) || *p == '-')
|
||||
while ((isascii(*p) && isalnum(*p)) || *p == '-')
|
||||
p++;
|
||||
if (*p == '=')
|
||||
{
|
||||
@ -534,9 +582,15 @@ smtp(e)
|
||||
a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, e);
|
||||
if (a == NULL)
|
||||
break;
|
||||
p = delimptr;
|
||||
if (delimptr != NULL && *delimptr != '\0')
|
||||
*delimptr++ = '\0';
|
||||
|
||||
/* do config file checking of the recipient */
|
||||
if (rscheck("check_rcpt", p, NULL, e) != EX_OK)
|
||||
break;
|
||||
|
||||
/* now parse ESMTP arguments */
|
||||
p = delimptr;
|
||||
while (p != NULL && *p != '\0')
|
||||
{
|
||||
char *kp;
|
||||
@ -551,7 +605,7 @@ smtp(e)
|
||||
kp = p;
|
||||
|
||||
/* skip to the value portion */
|
||||
while (isascii(*p) && isalnum(*p) || *p == '-')
|
||||
while ((isascii(*p) && isalnum(*p)) || *p == '-')
|
||||
p++;
|
||||
if (*p == '=')
|
||||
{
|
||||
@ -582,7 +636,7 @@ smtp(e)
|
||||
break;
|
||||
|
||||
/* no errors during parsing, but might be a duplicate */
|
||||
e->e_to = p;
|
||||
e->e_to = a->q_paddr;
|
||||
if (!bitset(QBADADDR, a->q_flags))
|
||||
{
|
||||
message("250 Recipient ok%s",
|
||||
@ -698,7 +752,7 @@ smtp(e)
|
||||
|
||||
/* clean up a bit */
|
||||
gotmail = FALSE;
|
||||
dropenvelope(e);
|
||||
dropenvelope(e, TRUE);
|
||||
CurEnv = e = newenvelope(e, CurEnv);
|
||||
e->e_flags = BlankEnvelope.e_flags;
|
||||
break;
|
||||
@ -714,12 +768,24 @@ smtp(e)
|
||||
|
||||
/* clean up a bit */
|
||||
gotmail = FALSE;
|
||||
dropenvelope(e);
|
||||
dropenvelope(e, TRUE);
|
||||
CurEnv = e = newenvelope(e, CurEnv);
|
||||
break;
|
||||
|
||||
case CMDVRFY: /* vrfy -- verify address */
|
||||
case CMDEXPN: /* expn -- expand address */
|
||||
if (++nverifies >= MAXBADCOMMANDS)
|
||||
{
|
||||
#ifdef LOG
|
||||
if (nverifies == MAXBADCOMMANDS &&
|
||||
LogLevel > 5)
|
||||
{
|
||||
syslog(LOG_INFO, "%.100s: VRFY attack?",
|
||||
CurSmtpClient);
|
||||
}
|
||||
#endif
|
||||
sleep(1);
|
||||
}
|
||||
vrfy = c->cmdcode == CMDVRFY;
|
||||
if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN,
|
||||
PrivacyFlags))
|
||||
@ -778,20 +844,47 @@ smtp(e)
|
||||
}
|
||||
while (vrfyqueue != NULL)
|
||||
{
|
||||
extern void printvrfyaddr __P((ADDRESS *, bool));
|
||||
extern void printvrfyaddr __P((ADDRESS *, bool, bool));
|
||||
|
||||
a = vrfyqueue;
|
||||
while ((a = a->q_next) != NULL &&
|
||||
bitset(QDONTSEND|QBADADDR, a->q_flags))
|
||||
continue;
|
||||
if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags))
|
||||
printvrfyaddr(vrfyqueue, a == NULL);
|
||||
printvrfyaddr(vrfyqueue, a == NULL, vrfy);
|
||||
vrfyqueue = vrfyqueue->q_next;
|
||||
}
|
||||
if (InChild)
|
||||
finis();
|
||||
break;
|
||||
|
||||
case CMDETRN: /* etrn -- force queue flush */
|
||||
if (strlen(p) <= 0)
|
||||
{
|
||||
message("500 Parameter required");
|
||||
break;
|
||||
}
|
||||
|
||||
/* crude way to avoid denial-of-service attacks */
|
||||
if (n_etrn++ >= 3)
|
||||
sleep(3);
|
||||
id = p;
|
||||
if (*id == '@')
|
||||
id++;
|
||||
else
|
||||
*--id = '@';
|
||||
#ifdef LOG
|
||||
if (LogLevel > 5)
|
||||
syslog(LOG_INFO, "%.100s: ETRN %s",
|
||||
CurSmtpClient,
|
||||
shortenstring(id, 203));
|
||||
#endif
|
||||
QueueLimitRecipient = id;
|
||||
runqueue(TRUE);
|
||||
QueueLimitRecipient = NULL;
|
||||
message("250 Queuing for node %s started", p);
|
||||
break;
|
||||
|
||||
case CMDHELP: /* help -- give user info */
|
||||
help(p);
|
||||
break;
|
||||
@ -831,6 +924,11 @@ smtp(e)
|
||||
message("250 Only one transaction");
|
||||
break;
|
||||
|
||||
case CMDXUSR: /* initial (user) submission */
|
||||
UserSubmission = TRUE;
|
||||
message("250 Initial submission");
|
||||
break;
|
||||
|
||||
# ifdef SMTPDEBUG
|
||||
case CMDDBGQSHOW: /* show queues */
|
||||
printf("Send Queue=");
|
||||
@ -1112,6 +1210,7 @@ rcpt_esmtp_args(a, kp, vp, e)
|
||||
** Parameters:
|
||||
** a -- the address to print
|
||||
** last -- set if this is the last one.
|
||||
** vrfy -- set if this is a VRFY command.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
@ -1121,12 +1220,17 @@ rcpt_esmtp_args(a, kp, vp, e)
|
||||
*/
|
||||
|
||||
void
|
||||
printvrfyaddr(a, last)
|
||||
printvrfyaddr(a, last, vrfy)
|
||||
register ADDRESS *a;
|
||||
bool last;
|
||||
bool vrfy;
|
||||
{
|
||||
char fmtbuf[20];
|
||||
|
||||
if (vrfy && a->q_mailer != NULL &&
|
||||
!bitnset(M_VRFY250, a->q_mailer->m_flags))
|
||||
strcpy(fmtbuf, "252");
|
||||
else
|
||||
strcpy(fmtbuf, "250");
|
||||
fmtbuf[3] = last ? ' ' : '-';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -36,9 +36,9 @@
|
||||
|
||||
#ifndef lint
|
||||
#if USERDB
|
||||
static char sccsid [] = "@(#)udb.c 8.33.1.2 (Berkeley) 9/16/96 (with USERDB)";
|
||||
static char sccsid [] = "@(#)udb.c 8.42 (Berkeley) 9/18/96 (with USERDB)";
|
||||
#else
|
||||
static char sccsid [] = "@(#)udb.c 8.33.1.2 (Berkeley) 9/16/96 (without USERDB)";
|
||||
static char sccsid [] = "@(#)udb.c 8.42 (Berkeley) 9/18/96 (without USERDB)";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -119,6 +119,8 @@ struct option
|
||||
char *name;
|
||||
char *val;
|
||||
};
|
||||
|
||||
extern int _udbx_init __P((void));
|
||||
/*
|
||||
** UDBEXPAND -- look up user in database and expand
|
||||
**
|
||||
@ -159,7 +161,6 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
int keylen;
|
||||
int naddrs;
|
||||
char keybuf[MAXKEY];
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if (tTd(28, 1))
|
||||
printf("udbexpand(%s)\n", a->q_paddr);
|
||||
@ -172,8 +173,6 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
/* on first call, locate the database */
|
||||
if (!UdbInitialized)
|
||||
{
|
||||
extern int _udbx_init();
|
||||
|
||||
if (_udbx_init() == EX_TEMPFAIL)
|
||||
return EX_TEMPFAIL;
|
||||
}
|
||||
@ -187,7 +186,7 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
return EX_OK;
|
||||
|
||||
/* if name is too long, assume it won't match */
|
||||
if (strlen(a->q_user) > sizeof keybuf - 12)
|
||||
if (strlen(a->q_user) > (SIZE_T) sizeof keybuf - 12)
|
||||
return EX_OK;
|
||||
|
||||
/* if name begins with a colon, it indicates our metadata */
|
||||
@ -203,6 +202,16 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
for (up = UdbEnts; !breakout; up++)
|
||||
{
|
||||
char *user;
|
||||
int usersize;
|
||||
int userleft;
|
||||
char userbuf[MEMCHUNKSIZE];
|
||||
#if defined(HESIOD) && defined(HES_GETMAILHOST)
|
||||
char pobuf[MAXNAME];
|
||||
#endif
|
||||
|
||||
user = userbuf;
|
||||
usersize = sizeof userbuf;
|
||||
userleft = sizeof userbuf - 1;
|
||||
|
||||
/*
|
||||
** Select action based on entry type.
|
||||
@ -227,17 +236,18 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
if (tTd(28, 2))
|
||||
printf("udbexpand: no match on %s (%d)\n",
|
||||
keybuf, keylen);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (tTd(28, 80))
|
||||
printf("udbexpand: match %.*s: %.*s\n",
|
||||
key.size, key.data, info.size, info.data);
|
||||
|
||||
naddrs = 0;
|
||||
a->q_flags &= ~QSELFREF;
|
||||
while (i == 0 && key.size == keylen &&
|
||||
bcmp(key.data, keybuf, keylen) == 0)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (bitset(EF_VRFYONLY, e->e_flags))
|
||||
{
|
||||
a->q_flags |= QVERIFIED;
|
||||
@ -245,12 +255,34 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
}
|
||||
|
||||
breakout = TRUE;
|
||||
if (info.size < sizeof buf)
|
||||
user = buf;
|
||||
else
|
||||
user = xalloc(info.size + 1);
|
||||
if (info.size >= userleft - 1)
|
||||
{
|
||||
char *nuser = xalloc(usersize + MEMCHUNKSIZE);
|
||||
|
||||
bcopy(user, nuser, usersize);
|
||||
if (user != userbuf)
|
||||
free(user);
|
||||
user = nuser;
|
||||
usersize += MEMCHUNKSIZE;
|
||||
userleft += MEMCHUNKSIZE;
|
||||
}
|
||||
p = &user[strlen(user)];
|
||||
if (p != user)
|
||||
{
|
||||
*p++ = ',';
|
||||
userleft--;
|
||||
}
|
||||
bcopy(info.data, user, info.size);
|
||||
user[info.size] = '\0';
|
||||
userleft -= info.size;
|
||||
|
||||
/* get the next record */
|
||||
i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT);
|
||||
}
|
||||
|
||||
/* if nothing ever matched, try next database */
|
||||
if (!breakout)
|
||||
break;
|
||||
|
||||
message("expanded to %s", user);
|
||||
#ifdef LOG
|
||||
@ -259,19 +291,7 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
e->e_id, e->e_to,
|
||||
shortenstring(user, 203));
|
||||
#endif
|
||||
naddrs += sendtolist(user, a, sendq, aliaslevel + 1, e);
|
||||
|
||||
if (user != buf)
|
||||
free(user);
|
||||
|
||||
/* get the next record */
|
||||
i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT);
|
||||
}
|
||||
|
||||
/* if nothing ever matched, try next database */
|
||||
if (!breakout)
|
||||
continue;
|
||||
|
||||
naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
|
||||
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
|
||||
{
|
||||
if (tTd(28, 5))
|
||||
@ -357,13 +377,24 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
if (tTd(28, 2))
|
||||
printf("hes_getmailhost(%s): %d\n",
|
||||
a->q_user, hes_error());
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (strlen(hp->po_name) + strlen(hp->po_host) >
|
||||
sizeof pobuf - 2)
|
||||
{
|
||||
if (tTd(28, 2))
|
||||
printf("hes_getmailhost(%s): expansion too long: %.30s@%.30s\n",
|
||||
a->q_user,
|
||||
hp->po_name,
|
||||
hp->po_host);
|
||||
break;
|
||||
}
|
||||
info.data = pobuf;
|
||||
snprintf(pobuf, sizeof pobuf, "%s@%s",
|
||||
hp->po_name, hp->po_host);
|
||||
info.size = strlen(info.data);
|
||||
#else
|
||||
continue;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (tTd(28, 80))
|
||||
@ -378,9 +409,7 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
}
|
||||
|
||||
breakout = TRUE;
|
||||
if (info.size < sizeof buf)
|
||||
user = buf;
|
||||
else
|
||||
if (info.size >= usersize)
|
||||
user = xalloc(info.size + 1);
|
||||
bcopy(info.data, user, info.size);
|
||||
user[info.size] = '\0';
|
||||
@ -394,9 +423,6 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
#endif
|
||||
naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
|
||||
|
||||
if (user != buf)
|
||||
free(user);
|
||||
|
||||
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
|
||||
{
|
||||
if (tTd(28, 5))
|
||||
@ -428,17 +454,18 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
|
||||
case UDB_REMOTE:
|
||||
/* not yet implemented */
|
||||
continue;
|
||||
break;
|
||||
|
||||
case UDB_FORWARD:
|
||||
if (bitset(EF_VRFYONLY, e->e_flags))
|
||||
return EX_OK;
|
||||
i = strlen(up->udb_fwdhost) + strlen(a->q_user) + 1;
|
||||
if (i < sizeof buf)
|
||||
user = buf;
|
||||
else
|
||||
user = xalloc(i + 1);
|
||||
(void) snprintf(user, i, "%s@%s",
|
||||
if (i >= usersize)
|
||||
{
|
||||
usersize = i + 1;
|
||||
user = xalloc(usersize);
|
||||
}
|
||||
(void) snprintf(user, usersize, "%s@%s",
|
||||
a->q_user, up->udb_fwdhost);
|
||||
message("expanded to %s", user);
|
||||
a->q_flags &= ~QSELFREF;
|
||||
@ -452,19 +479,19 @@ udbexpand(a, sendq, aliaslevel, e)
|
||||
}
|
||||
a->q_flags |= QDONTSEND;
|
||||
}
|
||||
if (user != buf)
|
||||
free(user);
|
||||
breakout = TRUE;
|
||||
break;
|
||||
|
||||
case UDB_EOLIST:
|
||||
breakout = TRUE;
|
||||
continue;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown entry type */
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (user != userbuf)
|
||||
free(user);
|
||||
}
|
||||
return EX_OK;
|
||||
}
|
||||
@ -798,6 +825,7 @@ _udbx_init()
|
||||
char *mxhosts[MAXMXHOSTS + 1];
|
||||
# endif
|
||||
struct option opts[MAXUDBOPTS + 1];
|
||||
extern int _udb_parsespec __P((char *, struct option [], int));
|
||||
|
||||
while (*p == ' ' || *p == '\t' || *p == ',')
|
||||
p++;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -36,9 +36,9 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifdef SMTP
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.65.1.2 (Berkeley) 9/16/96 (with SMTP)";
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)";
|
||||
#else
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.65.1.2 (Berkeley) 9/16/96 (without SMTP)";
|
||||
static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -64,6 +64,7 @@ int SmtpPid; /* pid of mailer */
|
||||
bool SmtpNeedIntro; /* need "while talking" in transcript */
|
||||
|
||||
extern void smtpmessage __P((char *f, MAILER *m, MCI *mci, ...));
|
||||
extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)()));
|
||||
/*
|
||||
** SMTPINIT -- initialize SMTP.
|
||||
**
|
||||
@ -83,7 +84,7 @@ extern void smtpmessage __P((char *f, MAILER *m, MCI *mci, ...));
|
||||
|
||||
void
|
||||
smtpinit(m, mci, e)
|
||||
struct mailer *m;
|
||||
MAILER *m;
|
||||
register MCI *mci;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
@ -327,7 +328,7 @@ helo_options(line, firstline, m, mci, e)
|
||||
|
||||
int
|
||||
smtpmailfrom(m, mci, e)
|
||||
struct mailer *m;
|
||||
MAILER *m;
|
||||
MCI *mci;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
@ -383,14 +384,16 @@ smtpmailfrom(m, mci, e)
|
||||
else if (!bitset(MM_PASS8BIT, MimeMode))
|
||||
{
|
||||
/* cannot just send a 8-bit version */
|
||||
extern char MsgBuf[];
|
||||
|
||||
usrerr("%s does not support 8BITMIME", mci->mci_host);
|
||||
mci->mci_status = "5.6.3";
|
||||
mci_setstat(mci, "5.6.3", MsgBuf);
|
||||
return EX_DATAERR;
|
||||
}
|
||||
|
||||
if (bitset(MCIF_DSN, mci->mci_flags))
|
||||
{
|
||||
if (e->e_envid != NULL && strlen(e->e_envid) < (SIZE_T) l)
|
||||
if (e->e_envid != NULL && strlen(e->e_envid) < (SIZE_T) (l - 7))
|
||||
{
|
||||
strcat(optbuf, " ENVID=");
|
||||
strcat(optbuf, e->e_envid);
|
||||
@ -454,6 +457,7 @@ smtpmailfrom(m, mci, e)
|
||||
}
|
||||
else if (REPLYTYPE(r) == 4)
|
||||
{
|
||||
mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
|
||||
return EX_TEMPFAIL;
|
||||
}
|
||||
else if (REPLYTYPE(r) == 2)
|
||||
@ -463,24 +467,25 @@ smtpmailfrom(m, mci, e)
|
||||
else if (r == 501)
|
||||
{
|
||||
/* syntax error in arguments */
|
||||
mci->mci_status = "5.5.2";
|
||||
mci_setstat(mci, "5.5.2", SmtpReplyBuffer);
|
||||
return EX_DATAERR;
|
||||
}
|
||||
else if (r == 553)
|
||||
{
|
||||
/* mailbox name not allowed */
|
||||
mci->mci_status = "5.1.3";
|
||||
mci_setstat(mci, "5.1.3", SmtpReplyBuffer);
|
||||
return EX_DATAERR;
|
||||
}
|
||||
else if (r == 552)
|
||||
{
|
||||
/* exceeded storage allocation */
|
||||
mci->mci_status = "5.2.2";
|
||||
mci_setstat(mci, "5.2.2", SmtpReplyBuffer);
|
||||
return EX_UNAVAILABLE;
|
||||
}
|
||||
else if (REPLYTYPE(r) == 5)
|
||||
{
|
||||
/* unknown error */
|
||||
mci_setstat(mci, "5.0.0", SmtpReplyBuffer);
|
||||
return EX_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@ -494,6 +499,7 @@ smtpmailfrom(m, mci, e)
|
||||
#endif
|
||||
|
||||
/* protocol error -- close up */
|
||||
mci_setstat(mci, "5.5.1", SmtpReplyBuffer);
|
||||
smtpquit(m, mci, e);
|
||||
return EX_PROTOCOL;
|
||||
}
|
||||
@ -523,7 +529,6 @@ smtprcpt(to, m, mci, e)
|
||||
register int r;
|
||||
int l;
|
||||
char optbuf[MAXLINE];
|
||||
extern char *smtptodsn();
|
||||
|
||||
strcpy(optbuf, "");
|
||||
l = sizeof optbuf - 1;
|
||||
@ -581,10 +586,25 @@ smtprcpt(to, m, mci, e)
|
||||
return EX_TEMPFAIL;
|
||||
else if (REPLYTYPE(r) == 2)
|
||||
return EX_OK;
|
||||
else if (r == 550 || r == 551 || r == 553)
|
||||
else if (r == 550)
|
||||
{
|
||||
to->q_status = "5.1.1";
|
||||
return EX_NOUSER;
|
||||
}
|
||||
else if (r == 551)
|
||||
{
|
||||
to->q_status = "5.1.6";
|
||||
return EX_NOUSER;
|
||||
}
|
||||
else if (r == 553)
|
||||
{
|
||||
to->q_status = "5.1.3";
|
||||
return EX_NOUSER;
|
||||
}
|
||||
else if (REPLYTYPE(r) == 5)
|
||||
{
|
||||
return EX_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
@ -616,7 +636,7 @@ static void datatimeout();
|
||||
|
||||
int
|
||||
smtpdata(m, mci, e)
|
||||
struct mailer *m;
|
||||
MAILER *m;
|
||||
register MCI *mci;
|
||||
register ENVELOPE *e;
|
||||
{
|
||||
@ -723,6 +743,7 @@ smtpdata(m, mci, e)
|
||||
return EX_TEMPFAIL;
|
||||
}
|
||||
mci->mci_state = MCIS_OPEN;
|
||||
mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
|
||||
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
|
||||
if (REPLYTYPE(r) == 4)
|
||||
return EX_TEMPFAIL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1995 Eric P. Allman
|
||||
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)util.c 8.84.1.4 (Berkeley) 9/16/96";
|
||||
static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96";
|
||||
#endif /* not lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
@ -260,50 +260,71 @@ xputs(s)
|
||||
{
|
||||
register int c;
|
||||
register struct metamac *mp;
|
||||
bool shiftout = FALSE;
|
||||
extern struct metamac MetaMacros[];
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
printf("<null>");
|
||||
printf("%s<null>%s", TermEscape.te_rv_on, TermEscape.te_rv_off);
|
||||
return;
|
||||
}
|
||||
while ((c = (*s++ & 0377)) != '\0')
|
||||
{
|
||||
if (shiftout)
|
||||
{
|
||||
printf("%s", TermEscape.te_rv_off);
|
||||
shiftout = FALSE;
|
||||
}
|
||||
if (!isascii(c))
|
||||
{
|
||||
if (c == MATCHREPL)
|
||||
{
|
||||
putchar('$');
|
||||
printf("%s$", TermEscape.te_rv_on);
|
||||
shiftout = TRUE;
|
||||
if (*s == '\0')
|
||||
continue;
|
||||
c = *s++ & 0377;
|
||||
goto printchar;
|
||||
}
|
||||
if (c == MACROEXPAND)
|
||||
{
|
||||
putchar('$');
|
||||
printf("%s$", TermEscape.te_rv_on);
|
||||
shiftout = TRUE;
|
||||
if (strchr("=~&?", *s) != NULL)
|
||||
putchar(*s++);
|
||||
if (bitset(0200, *s))
|
||||
printf("{%s}", macname(*s++ & 0377));
|
||||
else
|
||||
printf("%c", *s++);
|
||||
continue;
|
||||
}
|
||||
for (mp = MetaMacros; mp->metaname != '\0'; mp++)
|
||||
{
|
||||
if ((mp->metaval & 0377) == c)
|
||||
{
|
||||
printf("$%c", mp->metaname);
|
||||
printf("%s$%c",
|
||||
TermEscape.te_rv_on,
|
||||
mp->metaname);
|
||||
shiftout = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == MATCHCLASS || c == MATCHNCLASS)
|
||||
{
|
||||
if (!bitset(0200, *s))
|
||||
continue;
|
||||
if (bitset(0200, *s))
|
||||
printf("{%s}", macname(*s++ & 0377));
|
||||
else
|
||||
printf("%c", *s++);
|
||||
}
|
||||
if (mp->metaname != '\0')
|
||||
continue;
|
||||
(void) putchar('\\');
|
||||
|
||||
/* unrecognized meta character */
|
||||
printf("%sM-", TermEscape.te_rv_on);
|
||||
shiftout = TRUE;
|
||||
c &= 0177;
|
||||
}
|
||||
printchar:
|
||||
if (isprint(c))
|
||||
{
|
||||
putchar(c);
|
||||
@ -324,15 +345,25 @@ xputs(s)
|
||||
case '\t':
|
||||
c = 't';
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) putchar('^');
|
||||
(void) putchar(c ^ 0100);
|
||||
continue;
|
||||
}
|
||||
if (!shiftout)
|
||||
{
|
||||
printf("%s", TermEscape.te_rv_on);
|
||||
shiftout = TRUE;
|
||||
}
|
||||
if (isprint(c))
|
||||
{
|
||||
(void) putchar('\\');
|
||||
(void) putchar(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) putchar('^');
|
||||
(void) putchar(c ^ 0100);
|
||||
}
|
||||
}
|
||||
if (shiftout)
|
||||
printf("%s", TermEscape.te_rv_off);
|
||||
(void) fflush(stdout);
|
||||
}
|
||||
/*
|
||||
@ -397,27 +428,18 @@ buildfname(gecos, login, buf, buflen)
|
||||
if (*gecos == '*')
|
||||
gecos++;
|
||||
|
||||
/* find length of final string */
|
||||
l = 0;
|
||||
/* copy gecos, interpolating & to be full name */
|
||||
for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
|
||||
{
|
||||
if (*p == '&')
|
||||
l += strlen(login);
|
||||
else
|
||||
l++;
|
||||
}
|
||||
if (l > buflen - 1)
|
||||
if (bp >= &buf[buflen - 1])
|
||||
{
|
||||
/* not a good sign */
|
||||
snprintf(buf, buflen, "%s", gecos);
|
||||
/* buffer overflow -- just use login name */
|
||||
snprintf(buf, buflen, "%s", login);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now fill in buf */
|
||||
for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
|
||||
{
|
||||
if (*p == '&')
|
||||
{
|
||||
/* interpolate full name */
|
||||
snprintf(bp, buflen - (bp - buf), "%s", login);
|
||||
*bp = toupper(*bp);
|
||||
bp += strlen(bp);
|
||||
@ -470,8 +492,8 @@ buildfname(gecos, login, buf, buflen)
|
||||
int
|
||||
safefile(fn, uid, gid, uname, flags, mode, st)
|
||||
char *fn;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
UID_T uid;
|
||||
GID_T gid;
|
||||
char *uname;
|
||||
int flags;
|
||||
int mode;
|
||||
@ -552,7 +574,7 @@ safefile(fn, uid, gid, uname, flags, mode, st)
|
||||
bitset(S_IXGRP, stbuf.st_mode))
|
||||
continue;
|
||||
#ifndef NO_GROUP_SET
|
||||
if (uname != NULL &&
|
||||
if (uname != NULL && !DontInitGroups &&
|
||||
((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
|
||||
(gr = getgrgid(stbuf.st_gid)) != NULL))
|
||||
{
|
||||
@ -651,7 +673,7 @@ safefile(fn, uid, gid, uname, flags, mode, st)
|
||||
if (st->st_gid == gid)
|
||||
;
|
||||
#ifndef NO_GROUP_SET
|
||||
else if (uname != NULL &&
|
||||
else if (uname != NULL && !DontInitGroups &&
|
||||
((gr != NULL && gr->gr_gid == st->st_gid) ||
|
||||
(gr = getgrgid(st->st_gid)) != NULL))
|
||||
{
|
||||
@ -815,12 +837,12 @@ struct omodes
|
||||
char *farg;
|
||||
} OpenModes[] =
|
||||
{
|
||||
O_ACCMODE, O_RDONLY, "r",
|
||||
O_ACCMODE|O_APPEND, O_WRONLY, "w",
|
||||
O_ACCMODE|O_APPEND, O_WRONLY|O_APPEND, "a",
|
||||
O_TRUNC, 0, "w+",
|
||||
O_APPEND, O_APPEND, "a+",
|
||||
0, 0, "r+",
|
||||
{ O_ACCMODE, O_RDONLY, "r" },
|
||||
{ O_ACCMODE|O_APPEND, O_WRONLY, "w" },
|
||||
{ O_ACCMODE|O_APPEND, O_WRONLY|O_APPEND, "a" },
|
||||
{ O_TRUNC, 0, "w+" },
|
||||
{ O_APPEND, O_APPEND, "a+" },
|
||||
{ 0, 0, "r+" },
|
||||
};
|
||||
|
||||
FILE *
|
||||
@ -1109,9 +1131,11 @@ sfgets(buf, siz, fp, timeout, during)
|
||||
if (setjmp(CtxReadTimeout) != 0)
|
||||
{
|
||||
# ifdef LOG
|
||||
if (LogLevel > 1)
|
||||
syslog(LOG_NOTICE,
|
||||
"timeout waiting for input from %.100s during %s",
|
||||
CurHostName? CurHostName: "local", during);
|
||||
CurHostName ? CurHostName : "local",
|
||||
during);
|
||||
# endif
|
||||
errno = 0;
|
||||
usrerr("451 timeout waiting for input during %s",
|
||||
@ -1339,19 +1363,21 @@ atooct(s)
|
||||
|
||||
int
|
||||
waitfor(pid)
|
||||
int pid;
|
||||
pid_t pid;
|
||||
{
|
||||
#ifdef WAITUNION
|
||||
union wait st;
|
||||
#else
|
||||
auto int st;
|
||||
#endif
|
||||
int i;
|
||||
pid_t i;
|
||||
|
||||
do
|
||||
{
|
||||
errno = 0;
|
||||
i = wait(&st);
|
||||
if (i > 0)
|
||||
proc_list_drop(i);
|
||||
} while ((i >= 0 || errno == EINTR) && i != pid);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
@ -1470,7 +1496,7 @@ checkfd012(where)
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (fstat(i, &stbuf) < 0 && errno != EOPNOTSUPP)
|
||||
if (fstat(i, &stbuf) < 0 && errno == EBADF)
|
||||
{
|
||||
/* oops.... */
|
||||
int fd;
|
||||
@ -1487,6 +1513,90 @@ checkfd012(where)
|
||||
#endif /* XDEBUG */
|
||||
}
|
||||
/*
|
||||
** CHECKFDOPEN -- make sure file descriptor is open -- for extended debugging
|
||||
**
|
||||
** Parameters:
|
||||
** fd -- file descriptor to check.
|
||||
** where -- tag to print on failure.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
checkfdopen(fd, where)
|
||||
int fd;
|
||||
char *where;
|
||||
{
|
||||
#if XDEBUG
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0 && errno == EBADF)
|
||||
{
|
||||
syserr("checkfdopen(%d): %s not open as expected!", fd, where);
|
||||
printopenfds(TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
** CHECKFDS -- check for new or missing file descriptors
|
||||
**
|
||||
** Parameters:
|
||||
** where -- tag for printing. If null, take a base line.
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
**
|
||||
** Side Effects:
|
||||
** If where is set, shows changes since the last call.
|
||||
*/
|
||||
|
||||
void
|
||||
checkfds(where)
|
||||
char *where;
|
||||
{
|
||||
int maxfd;
|
||||
register int fd;
|
||||
bool printhdr = TRUE;
|
||||
int save_errno = errno;
|
||||
static BITMAP baseline;
|
||||
extern int DtableSize;
|
||||
|
||||
if (DtableSize > 256)
|
||||
maxfd = 256;
|
||||
else
|
||||
maxfd = DtableSize;
|
||||
if (where == NULL)
|
||||
clrbitmap(baseline);
|
||||
|
||||
for (fd = 0; fd < maxfd; fd++)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
||||
if (fstat(fd, &stbuf) < 0 && errno != EOPNOTSUPP)
|
||||
{
|
||||
if (!bitnset(fd, baseline))
|
||||
continue;
|
||||
clrbitn(fd, baseline);
|
||||
}
|
||||
else if (!bitnset(fd, baseline))
|
||||
setbitn(fd, baseline);
|
||||
else
|
||||
continue;
|
||||
|
||||
/* file state has changed */
|
||||
if (where == NULL)
|
||||
continue;
|
||||
if (printhdr)
|
||||
{
|
||||
syslog(LOG_DEBUG, "%s: changed fds:", where);
|
||||
printhdr = FALSE;
|
||||
}
|
||||
dumpfd(fd, TRUE, TRUE);
|
||||
}
|
||||
errno = save_errno;
|
||||
}
|
||||
/*
|
||||
** PRINTOPENFDS -- print the open file descriptors (for debugging)
|
||||
**
|
||||
** Parameters:
|
||||
@ -1542,12 +1652,17 @@ dumpfd(fd, printclosed, logit)
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
{
|
||||
if (printclosed || errno != EBADF)
|
||||
if (errno != EBADF)
|
||||
{
|
||||
snprintf(p, SPACELEFT(buf, p), "CANNOT STAT (%s)",
|
||||
errstring(errno));
|
||||
goto printit;
|
||||
}
|
||||
else if (printclosed)
|
||||
{
|
||||
snprintf(p, SPACELEFT(buf, p), "CLOSED");
|
||||
goto printit;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1812,8 +1927,10 @@ prog_open(argv, pfd, e)
|
||||
|
||||
/* run as default user */
|
||||
endpwent();
|
||||
setgid(DefGid);
|
||||
setuid(DefUid);
|
||||
if (setgid(DefGid) < 0)
|
||||
syserr("prog_open: setgid(%ld) failed", (long) DefGid);
|
||||
if (setuid(DefUid) < 0)
|
||||
syserr("prog_open: setuid(%ld) failed", (long) DefUid);
|
||||
|
||||
/* run in some directory */
|
||||
if (ProgMailer != NULL)
|
||||
@ -1856,6 +1973,7 @@ prog_open(argv, pfd, e)
|
||||
if (transienterror(saveerrno))
|
||||
_exit(EX_OSERR);
|
||||
_exit(EX_CONFIG);
|
||||
return -1; /* avoid compiler warning on IRIX */
|
||||
}
|
||||
/*
|
||||
** GET_COLUMN -- look up a Column in a line buffer
|
||||
@ -1904,7 +2022,7 @@ get_column(line, col, delim, buf, buflen)
|
||||
|
||||
if (col == 0 && delim == '\0')
|
||||
{
|
||||
while (*begin && isspace(*begin))
|
||||
while (*begin != '\0' && isascii(*begin) && isspace(*begin))
|
||||
begin++;
|
||||
}
|
||||
|
||||
@ -1915,14 +2033,14 @@ get_column(line, col, delim, buf, buflen)
|
||||
begin++;
|
||||
if (delim == '\0')
|
||||
{
|
||||
while (*begin && isspace(*begin))
|
||||
while (*begin != '\0' && isascii(*begin) && isspace(*begin))
|
||||
begin++;
|
||||
}
|
||||
}
|
||||
|
||||
end = strpbrk(begin, delimbuf);
|
||||
if (end == NULL)
|
||||
i = strlen(buf);
|
||||
i = strlen(begin);
|
||||
else
|
||||
i = end - begin;
|
||||
if (i >= buflen)
|
||||
@ -2022,3 +2140,112 @@ denlstring(s, strict, logattacks)
|
||||
|
||||
return bp;
|
||||
}
|
||||
/*
|
||||
** PATH_IS_DIR -- check to see if file exists and is a directory.
|
||||
**
|
||||
** Parameters:
|
||||
** pathname -- pathname to check for directory-ness.
|
||||
** createflag -- if set, create directory if needed.
|
||||
**
|
||||
** Returns:
|
||||
** TRUE -- if the indicated pathname is a directory
|
||||
** FALSE -- otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
path_is_dir(pathname, createflag)
|
||||
char *pathname;
|
||||
bool createflag;
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(pathname, &statbuf) < 0)
|
||||
{
|
||||
if (errno != ENOENT || !createflag)
|
||||
return FALSE;
|
||||
if (mkdir(pathname, 0755) < 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
if (!S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
** PROC_LIST_ADD -- add process id to list of our children
|
||||
**
|
||||
** Parameters:
|
||||
** pid -- pid to add to list.
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
*/
|
||||
|
||||
static pid_t *ProcListVec = NULL;
|
||||
static int ProcListSize = 0;
|
||||
|
||||
#define NO_PID ((pid_t) 0)
|
||||
#ifndef PROC_LIST_SEG
|
||||
# define PROC_LIST_SEG 32 /* number of pids to alloc at a time */
|
||||
#endif
|
||||
|
||||
void
|
||||
proc_list_add(pid)
|
||||
pid_t pid;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ProcListSize; i++)
|
||||
{
|
||||
if (ProcListVec[i] == NO_PID)
|
||||
break;
|
||||
}
|
||||
if (i >= ProcListSize)
|
||||
{
|
||||
/* grow process list */
|
||||
pid_t *npv;
|
||||
|
||||
npv = (pid_t *) xalloc(sizeof (pid_t) * (ProcListSize + PROC_LIST_SEG));
|
||||
if (ProcListSize > 0)
|
||||
{
|
||||
bcopy(ProcListVec, npv, ProcListSize * sizeof (pid_t));
|
||||
free(ProcListVec);
|
||||
}
|
||||
for (i = ProcListSize; i < ProcListSize + PROC_LIST_SEG; i++)
|
||||
npv[i] = NO_PID;
|
||||
i = ProcListSize;
|
||||
ProcListSize += PROC_LIST_SEG;
|
||||
ProcListVec = npv;
|
||||
}
|
||||
ProcListVec[i] = pid;
|
||||
CurChildren++;
|
||||
}
|
||||
/*
|
||||
** PROC_LIST_DROP -- drop pid from process list
|
||||
**
|
||||
** Parameters:
|
||||
** pid -- pid to drop
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
proc_list_drop(pid)
|
||||
pid_t pid;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ProcListSize; i++)
|
||||
{
|
||||
if (ProcListVec[i] == pid)
|
||||
{
|
||||
ProcListVec[i] = NO_PID;
|
||||
CurChildren--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user