From f1cb96b2ca44e4aa70b57abc58ffc615af6b0583 Mon Sep 17 00:00:00 2001 From: glass Date: Mon, 31 Jan 1994 02:38:08 +0000 Subject: upgrade to version 8.6.5 --- usr.sbin/sendmail/src/Makefile | 7 +- usr.sbin/sendmail/src/Makefile.AIX | 18 +- usr.sbin/sendmail/src/Makefile.BSD44 | 4 +- usr.sbin/sendmail/src/Makefile.IRIX | 2 +- usr.sbin/sendmail/src/Makefile.Linux | 11 +- usr.sbin/sendmail/src/Makefile.NetBSD | 6 +- usr.sbin/sendmail/src/Makefile.OSF1 | 10 +- usr.sbin/sendmail/src/Makefile.Solaris | 18 +- usr.sbin/sendmail/src/Makefile.SunOS | 6 +- usr.sbin/sendmail/src/Makefile.ULTRIX | 2 +- usr.sbin/sendmail/src/Makefile.Utah | 4 +- usr.sbin/sendmail/src/Makefile.dist | 10 +- usr.sbin/sendmail/src/READ_ME | 381 +++++++++++++++++++++++++------ usr.sbin/sendmail/src/alias.c | 6 +- usr.sbin/sendmail/src/aliases.5 | 6 +- usr.sbin/sendmail/src/cdefs.h | 68 ++++-- usr.sbin/sendmail/src/clock.c | 13 +- usr.sbin/sendmail/src/collect.c | 14 +- usr.sbin/sendmail/src/conf.c | 396 +++++++++++++++++++++++++++++++-- usr.sbin/sendmail/src/conf.h | 371 +++++++++++++++++++++++++----- usr.sbin/sendmail/src/daemon.c | 57 +++-- usr.sbin/sendmail/src/deliver.c | 213 ++++++++++++++---- usr.sbin/sendmail/src/domain.c | 74 +++++- usr.sbin/sendmail/src/envelope.c | 34 +-- usr.sbin/sendmail/src/err.c | 44 ++-- usr.sbin/sendmail/src/headers.c | 158 ++++++++----- usr.sbin/sendmail/src/main.c | 109 +++++++-- usr.sbin/sendmail/src/map.c | 57 +++-- usr.sbin/sendmail/src/mci.c | 9 +- usr.sbin/sendmail/src/parseaddr.c | 200 ++++++++++------- usr.sbin/sendmail/src/queue.c | 80 ++++--- usr.sbin/sendmail/src/readcf.c | 17 +- usr.sbin/sendmail/src/recipient.c | 241 +++++++++++++++----- usr.sbin/sendmail/src/savemail.c | 24 +- usr.sbin/sendmail/src/sendmail.8 | 5 +- usr.sbin/sendmail/src/sendmail.h | 64 ++++-- usr.sbin/sendmail/src/srvrsmtp.c | 39 ++-- usr.sbin/sendmail/src/udb.c | 6 +- usr.sbin/sendmail/src/usersmtp.c | 49 +++- usr.sbin/sendmail/src/util.c | 142 ++++++++++-- usr.sbin/sendmail/src/version.c | 4 +- 41 files changed, 2342 insertions(+), 637 deletions(-) (limited to 'usr.sbin/sendmail/src') diff --git a/usr.sbin/sendmail/src/Makefile b/usr.sbin/sendmail/src/Makefile index c001728ae16..412ddd5f463 100644 --- a/usr.sbin/sendmail/src/Makefile +++ b/usr.sbin/sendmail/src/Makefile @@ -1,3 +1,7 @@ +# +# NetBSD Makefile +# +# $Id: Makefile,v 1.16 1994/01/31 02:40:00 glass Exp $ # @(#)Makefile 8.2 (Berkeley) 8/15/93 PROG= sendmail @@ -21,6 +25,7 @@ SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \ mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \ stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \ util.c version.c +LDSTATIC= -static MAN1= newaliases.0 MAN5= aliases.0 MAN8= sendmail.0 @@ -34,7 +39,7 @@ BINMODE=6555 beforeinstall: # install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ # ${DESTDIR}/etc/sendmail.fc - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${DESTDIR}/var/log/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \ ${DESTDIR}/usr/share/misc diff --git a/usr.sbin/sendmail/src/Makefile.AIX b/usr.sbin/sendmail/src/Makefile.AIX index 89808114f3f..5a5bda2fde7 100644 --- a/usr.sbin/sendmail/src/Makefile.AIX +++ b/usr.sbin/sendmail/src/Makefile.AIX @@ -5,7 +5,7 @@ # old make program (I recommend that you get and port the new make if you # are going to be doing any signficant work on sendmail). # -# This has been tested on AIX 3.1.5. +# This has been tested on AIX 3.1.5 and 3.2.3e. # # use O=-O (usual) or O=-g (debugging) @@ -19,6 +19,9 @@ O= -g # See READ_ME for a description of how these flags interact. # DBMDEF= -DNDBM -DNEWDB +# +# If you did not install the NEWDB on your AIX platform, use: +#DBMDEF=-DNDBM # environment definitions (e.g., -D_AIX3) ENVDEF= -D_AIX3 @@ -33,6 +36,9 @@ ENVDEF= -D_AIX3 # libraries required on your system LIBS= -ldbm -ldb +# +# If you did not install the NEWDB on your AIX platform, use: +#LIBS= -ldbm # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}/usr/sbin @@ -41,11 +47,13 @@ BINDIR= ${DESTDIR}/usr/sbin STDIR= ${DESTDIR}/var/log # location of sendmail.hf file (usually /usr/share/misc or /usr/lib) -HFDIR= ${DESTDIR}/usr/share/misc +HFDIR= ${DESTDIR}/usr/lib # additional .o files needed OBJADD= +INSTALL=/usr/ucb/install + ################### end of user configuration flags ###################### CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF} @@ -80,11 +88,11 @@ sendmail.0: sendmail.8 install: install-sendmail install-docs install-sendmail: sendmail - install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} + ${INSTALL} -O ${BINOWN} -G ${BINGRP} -M ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + ${INSTALL} -c -O ${BINOWN} -G ${BINGRP} -M 644 /dev/null \ ${STDIR}/sendmail.st - install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} + ${INSTALL} -c -O ${BINOWN} -G ${BINGRP} -M 444 sendmail.hf ${HFDIR} # doesn't actually install them -- you may want to install pre-nroff versions install-docs: aliases.0 newaliases.0 sendmail.0 diff --git a/usr.sbin/sendmail/src/Makefile.BSD44 b/usr.sbin/sendmail/src/Makefile.BSD44 index 7439d1e7b69..877c96046f4 100644 --- a/usr.sbin/sendmail/src/Makefile.BSD44 +++ b/usr.sbin/sendmail/src/Makefile.BSD44 @@ -1,4 +1,4 @@ -# @(#)Makefile 8.2 (Berkeley) 8/15/93 +# @(#)Makefile 8.3 (Berkeley) 12/20/93 PROG= sendmail @@ -34,7 +34,7 @@ BINMODE=6555 beforeinstall: # install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ # ${DESTDIR}/etc/sendmail.fc - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${DESTDIR}/var/log/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \ ${DESTDIR}/usr/share/misc diff --git a/usr.sbin/sendmail/src/Makefile.IRIX b/usr.sbin/sendmail/src/Makefile.IRIX index 733aaec6781..9ddd03021fc 100644 --- a/usr.sbin/sendmail/src/Makefile.IRIX +++ b/usr.sbin/sendmail/src/Makefile.IRIX @@ -83,7 +83,7 @@ install: install-sendmail install-docs install-sendmail: sendmail install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} diff --git a/usr.sbin/sendmail/src/Makefile.Linux b/usr.sbin/sendmail/src/Makefile.Linux index f93bb2ddeab..0edcb4f56f3 100644 --- a/usr.sbin/sendmail/src/Makefile.Linux +++ b/usr.sbin/sendmail/src/Makefile.Linux @@ -21,7 +21,7 @@ O= -O DBMDEF= -DNDBM # environment definitions (e.g., -D_AIX3) -ENVDEF= -D__USE_BSD -U__USE_POSIX2 +ENVDEF= -D__USE_BSD # see also conf.h for additional compilation flags @@ -47,7 +47,7 @@ HFDIR= ${DESTDIR}/usr/lib OBJADD= # additional pseudo-sources needed -BEFORE= +BEFORE= features.h ################### end of user configuration flags ###################### @@ -59,7 +59,7 @@ OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \ savemail.o srvrsmtp.o stab.o stats.o sysexits.o \ trace.o udb.o usersmtp.o util.o version.o ${OBJADD} -LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq +LINKS= ${DESTDIR}/usr/bin/newaliases ${DESTDIR}/usr/bin/mailq BINOWN= root BINGRP= kmem BINMODE=6555 @@ -78,6 +78,9 @@ dirent.h: echo "#include " > dirent.h echo "#define dirent direct" >> dirent.h +features.h: + ln features.linux.h $@ + NROFF= nroff aliases.0: aliases.5 @@ -94,7 +97,7 @@ install: install-sendmail install-docs install-sendmail: sendmail install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} diff --git a/usr.sbin/sendmail/src/Makefile.NetBSD b/usr.sbin/sendmail/src/Makefile.NetBSD index 7def6f669da..bba5a3d4b92 100644 --- a/usr.sbin/sendmail/src/Makefile.NetBSD +++ b/usr.sbin/sendmail/src/Makefile.NetBSD @@ -1,7 +1,7 @@ # # NetBSD Makefile # - +# $Id: Makefile.NetBSD,v 1.2 1994/01/31 02:40:16 glass Exp $ # @(#)Makefile 8.2 (Berkeley) 8/15/93 PROG= sendmail @@ -14,7 +14,7 @@ PROG= sendmail # databases are read, but the new format will be used on any rebuilds. On # really gnarly systems, you can set this to null; it will crawl like a high # spiral snail, but it will work. -DBMDEF= -DNEWDB -DNDBM +DBMDEF= -DNEWDB -DNIS #nasty warning about gcc 2.4.x caused bugs CFLAGS=-I${.CURDIR} ${DBMDEF} -DNETISO @@ -25,8 +25,6 @@ SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \ mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \ stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \ util.c version.c -DPADD= $(LIBUTIL) -LDADD= -lutil MAN1= newaliases.0 MAN5= aliases.0 MAN8= sendmail.0 diff --git a/usr.sbin/sendmail/src/Makefile.OSF1 b/usr.sbin/sendmail/src/Makefile.OSF1 index ddc5f56793f..8a442648418 100644 --- a/usr.sbin/sendmail/src/Makefile.OSF1 +++ b/usr.sbin/sendmail/src/Makefile.OSF1 @@ -29,7 +29,7 @@ ENVDEF= -Olimit 1000 INCDIRS=-I/usr/sww/include/db # library directories -LIBDIRS=-L/usr/sww/lib +LIBDIRS=-L/usr/sww/lib -L/usr/shlib -L/usr/lib # libraries required on your system LIBS= -ldbm @@ -47,7 +47,7 @@ HFDIR= ${DESTDIR}/usr/share/lib OBJADD= # additional link flags -LDADD= -non_shared +#LDADD= -non_shared ################### end of user configuration flags ###################### @@ -69,7 +69,7 @@ ALL= sendmail aliases.0 newaliases.0 sendmail.0 all: ${ALL} sendmail: ${BEFORE} ${OBJS} - ${CC} -o sendmail ${LDFLAGS} ${OBJS} ${LIBDIRS} ${LIBS} + ${CC} -o sendmail ${LDADD} ${OBJS} ${LIBDIRS} ${LIBS} aliases.0: aliases.5 nroff -h -mandoc aliases.5 > aliases.0 @@ -86,8 +86,8 @@ install-sendmail: sendmail installbsd -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done cp /dev/null ${STDIR}/sendmail.st - chmod ${BINMOD} ${STDIR}/sendmail.st - chown ${BINGRP}.${BINGRP} ${STDIR}/sendmail.st + chmod 644 ${STDIR}/sendmail.st + chown ${BINOWN}.${BINGRP} ${STDIR}/sendmail.st installbsd -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} rm -f /usr/sbin/smtpd diff --git a/usr.sbin/sendmail/src/Makefile.Solaris b/usr.sbin/sendmail/src/Makefile.Solaris index 3b58393e616..1e006fdfb36 100644 --- a/usr.sbin/sendmail/src/Makefile.Solaris +++ b/usr.sbin/sendmail/src/Makefile.Solaris @@ -9,9 +9,10 @@ # # use O=-O (usual) or O=-g (debugging) -O= -O +# warning: do not use -O with gcc +O= -CC= gcc -V2.3.3 +CC= gcc # define the database mechanism used for alias lookups: # -DNDBM -- use new DBM @@ -20,30 +21,31 @@ CC= gcc -V2.3.3 # The really old (V7) DBM library is no longer supported. # See READ_ME for a description of how these flags interact. # -DBMDEF= -DNDBM +DBMDEF= -DNDBM -DNIS # environment definitions (e.g., -D_AIX3) +# include -DSOLARIS_2_3 for version 2.3 and higher ENVDEF= -DSOLARIS # see also conf.h for additional compilation flags # include directories -INCDIRS=-I/usr/sww/include/db +INCDIRS=-I/usr/sww/include/db -I. # library directories -LIBDIRS=-L/usr/sww/lib -L/usr/ucblib +LIBDIRS=-L/usr/sww/lib # libraries required on your system LIBS= -lresolv -lsocket -lnsl -lelf # location of sendmail binary (usually /usr/sbin or /usr/lib) -BINDIR= ${DESTDIR}/usr/sbin +BINDIR= ${DESTDIR}/usr/lib # location of sendmail.st file (usually /var/log or /usr/lib) STDIR= ${DESTDIR}/var/log # location of sendmail.hf file (usually /usr/share/misc or /usr/lib) -HFDIR= ${DESTDIR}/usr/share/misc +HFDIR= ${DESTDIR}/etc/mail # additional .o files needed OBJADD= @@ -85,7 +87,7 @@ install: install-sendmail install-docs install-sendmail: sendmail ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} diff --git a/usr.sbin/sendmail/src/Makefile.SunOS b/usr.sbin/sendmail/src/Makefile.SunOS index faa9882279d..93409317348 100644 --- a/usr.sbin/sendmail/src/Makefile.SunOS +++ b/usr.sbin/sendmail/src/Makefile.SunOS @@ -6,6 +6,9 @@ # are going to be doing any signficant work on sendmail). # # This has been tested on SunOS 4.1.[12]. +# For SunOS 4.0.3, add -DSUNOS403 to the ENVDEF macro, and +# create empty files stdlib.h and stddef.h in your +# compile directory. # # use O=-O (usual) or O=-g (debugging) @@ -21,6 +24,7 @@ O= -O DBMDEF= -DNDBM -DNEWDB -DNIS # environment definitions (e.g., -D_AIX3) +# need to add -DSUNOS403 if you are on a SunOS 4.0.3 system ENVDEF= # see also conf.h for additional compilation flags @@ -85,7 +89,7 @@ install: install-sendmail install-docs install-sendmail: sendmail install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} diff --git a/usr.sbin/sendmail/src/Makefile.ULTRIX b/usr.sbin/sendmail/src/Makefile.ULTRIX index d8d3fa8e0eb..66c73fa4e27 100644 --- a/usr.sbin/sendmail/src/Makefile.ULTRIX +++ b/usr.sbin/sendmail/src/Makefile.ULTRIX @@ -85,7 +85,7 @@ install: install-sendmail install-docs install-sendmail: sendmail install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} diff --git a/usr.sbin/sendmail/src/Makefile.Utah b/usr.sbin/sendmail/src/Makefile.Utah index 5246b3fe149..bc3ad393d16 100644 --- a/usr.sbin/sendmail/src/Makefile.Utah +++ b/usr.sbin/sendmail/src/Makefile.Utah @@ -31,9 +31,7 @@ BINGRP= kmem BINMODE=6555 beforeinstall: -# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ -# ${DESTDIR}/etc/sendmail.fc - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${DESTDIR}/var/log/sendmail.st install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \ ${DESTDIR}/usr/share/misc diff --git a/usr.sbin/sendmail/src/Makefile.dist b/usr.sbin/sendmail/src/Makefile.dist index e289a7d065b..127e6a7bd7f 100644 --- a/usr.sbin/sendmail/src/Makefile.dist +++ b/usr.sbin/sendmail/src/Makefile.dist @@ -5,7 +5,7 @@ # old make program (I recommend that you get and port the new make if you # are going to be doing any signficant work on sendmail). # -# @(#)Makefile.dist 8.7 (Berkeley) 9/3/93 +# @(#)Makefile.dist 8.9 (Berkeley) 12/20/93 # # use O=-O (usual) or O=-g (debugging) @@ -80,14 +80,16 @@ newaliases.0: newaliases.1 sendmail.0: sendmail.8 nroff -h -mandoc sendmail.8 > sendmail.0 +INSTALL=install + install: install-sendmail install-docs install-sendmail: sendmail - install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} + ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR} for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done - install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \ + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \ ${STDIR}/sendmail.st - install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR} # doesn't actually install them -- you may want to install pre-nroff versions install-docs: aliases.0 newaliases.0 sendmail.0 diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME index b599928b23d..a2e7ad793bf 100644 --- a/usr.sbin/sendmail/src/READ_ME +++ b/usr.sbin/sendmail/src/READ_ME @@ -30,7 +30,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)READ_ME 8.31 (Berkeley) 10/31/93 +# @(#)READ_ME 8.47 (Berkeley) 1/12/94 # This directory contains the source files for sendmail. @@ -39,35 +39,86 @@ For detailed instructions, please read the document ../doc/op.me: eqn ../doc/op.me | pic | ditroff -me -The Makefile is for the new (4.4BSD) Berkeley make, available from -ftp.uu.net in the directory /systems/unix/bsd-sources/usr.bin/make. -(Paul Southworth published a description of porting -this make in comp.unix.bsd.) This Makefile has assumptions about the -4.4 file system layout built in. +The Makefile is for the new (4.4BSD) Berkeley make and uses syntax +that is not recognized by older makes. It also has assumptions +about the 4.4 file system layout built in. See below for details +about other Makefiles. There is also a Makefile.dist which is much less clever, but works on the old traditional make. You can use this using: make -f Makefile.dist -There are a bunch of other Makefiles for other systems -- these are -the ones that I use, they have "Berkeley quirks" in them, and I don't -guarantee that they will work unmodified in your environment. However, -they are all designed for the old make and can be used to help you get -started. They have names like "Makefile.HPUX". Many of them include --I/usr/sww/include/db and -L/usr/sww/lib -- this is Berkeley's -location for the new database libraries, described below. +************************************************** +** Read below for more details of Makefiles. ** +************************************************** There is also a shell script (makesendmail) that tries to be clever about using object subdirectories. It's pretty straightforward, and may help if you share a source tree among different architectures. -IMPORTANT: DO NOT USE OPTIMIZATION (``-O'') IF YOU ARE RUNNING GCC -2.4.x. THERE IS A BUG IN THE GCC OPTIMIZER THAT CAUSES SENDMAIL TO -FAIL MISERABLY. +************************************************************************** +** IMPORTANT: DO NOT USE OPTIMIZATION (``-O'') IF YOU ARE RUNNING ** +** GCC 2.4.x or 2.5.x. THERE IS A BUG IN THE GCC OPTIMIZER THAT ** +** CAUSES SENDMAIL COMPILES TO FAIL MISERABLY. ** +************************************************************************** + +Jim Wilson of Cygnus believes he has found the problem -- it will +probably be fixed in GCC 2.5.6 -- but until this is verified, be +very suspicious of gcc -O. + +************************************************************************** +** IMPORTANT: Read the appropriate paragraphs in the section on ** +** ``Operating System and Compile Quirks''. ** +************************************************************************** + + ++-----------+ +| MAKEFILES | ++-----------+ + +The "Makefile"s in these directories are from 4.4 BSD, and hence +really only work properly if you are on a 4.4 system. In particular, +they use new syntax that will not be recognized on old make programs, +and some of them do things like ``.include ../../Makefile.inc'' to +pick up some system defines. If you are getting sendmail separately, +these files won't be included in the distribution, as they are +outside of the sendmail tree. + +Instead, you should use one of the other Makefiles, such as +Makefile.SunOS for a SunOS system, and so forth. These should +work with the version of make that is appropriate for that +system. + +There are a bunch of other Makefiles for other systems with names +like Makefile.HPUX for an HP-UX system. They use the version of +make that is native for that system. These are the Makefiles that +I use, and they have "Berkeley quirks" in them. I can't guarantee +that they will work unmodified in your environment. Many of them +include -I/usr/sww/include/db and -L/usr/sww/lib -- this is Berkeley's +location (the ``Software Warehouse'') for the new database libraries, +described below. You don't have to remove these definitions if you +don't have these directories. + +Please look for an appropriate Makefile before you start trying to +compile with Makefile or Makefile.dist. + +If you want to port the new Berkeley make, you can get it from +ftp.uu.net in the directory /systems/unix/bsd-sources/usr.bin/make. +Diffs and instructions for building this version of make under +SunOS 4.1.x are available on ftp.css.itd.umich.edu in +/pub/systems/sun/Net2-make.sun4.diff.Z. Diffs and instructions +for building this version of make under IBM AIX 3.2.4 are available +on ftp.uni-stuttgart.de in /sw/src/patches/bsd-make-rus-patches. +Paul Southworth published a description of porting +this make in comp.unix.bsd. + +The complete text of the Makefile.inc that is in the parent of the +sendmail directory is: + + # @(#)Makefile.inc 8.1 (Berkeley) 6/6/93 -IMPORTANT: Read the appropriate paragraphs in the section on -``Operating System and Compile Quirks''. + BINDIR?= /usr/sbin +----------------------+ @@ -83,7 +134,9 @@ older DBM implementation -- the very old V7 implementation is no longer supported), and NIS (Network Information Services). Used alone these just include the support they indicate. [If you are using NEWDB, get the latest version from FTP.CS.Berkeley.EDU in /ucb/4bsd. DO NOT -use the version from the Net2 distribution!] +use the version from the Net2 distribution! However, if you are on +BSD/386 or 386BSD-based systems, use the one that already exists +on your system. You may need to define OLD_NEWDB to do this.] If NEWDB and NDBM are defined (but not NIS), then sendmail will read NDBM format alias files, but the next time a newaliases is run the @@ -119,19 +172,22 @@ symbols availble, requiring the following compilation flags in the Makefile: SOLARIS Define this if you are running Solaris 2.0 or higher. +SOLARIS_2_3 Define this if you are running Solaris 2.3 or higher. +SUNOS403 Define this if you are running SunOS 4.0.3. NeXT Define this if you are on a NeXT box. (This one may be pre-defined for you.) There are other hacks you have to make -- see below. _AIX3 Define this if you are IBM AIX 3.x. RISCOS Define this if you are running RISC/os from MIPS. _SCO_unix_ Define this if you are on SCO UNIX. +_SCO_unix_4_2 Define this if you are on SCO Open Server 3.2v4. If you are a system that sendmail has already been ported to, you probably won't have to touch these. But if you are porting, you may have to tweak the following compilation flags in conf.h in order to get it to compile and link properly: -SYSTEM5 Adjust for System V. +SYSTEM5 Adjust for System V (not necessarily Release 4). SYS5SIGNALS Use System V signal semantics -- the signal handler is automatically dropped when the signal is caught. If this is not set, use POSIX/BSD semantics, where the @@ -166,12 +222,40 @@ HASSETREUID Define this if you have setreuid(2) ***AND*** root can your system has setresuid(2), (for example, on HP-UX) in which case you will also have to #define setreuid(r, e) to be the appropriate call. Some systems (such as Solaris) - have a compatibility routine that doesn't work properly. + have a compatibility routine that doesn't work properly, + but may have "saved user ids" properly implemented so you + can ``#define setreuid(r, e) seteuid(e)'' and have it work. The important thing is that you have a call that will set - the effective uid independently of the real or saved uid. - Setting this improves the security somewhat, since - sendmail doesn't have to read .forward and :include: files - as root. + the effective uid independently of the real or saved uid + and be able to set the effective uid back again when done. + There's a test program in ../test/t_setreuid.c that will + try things on your system. Setting this improves the + security, since sendmail doesn't have to read .forward + and :include: files as root. There are certain attacks + that may be unpreventable without this call. +HASLSTAT Define this if you have symbolic links (and thus the + lstat(2) system call). This improves security. Unlike + most other options, this one is on by default, so you + need to #undef it in conf.h if you don't have symbolic + links (these days everyone does). +NEEDGETOPT Define this if you need a reimplementation of getopt(3). + On some systems, getopt does very odd things if called + to scan the arguments twice. This flag will ask sendmail + to compile in a local version of getopt that works + properly. +NEEDSTRTOL Define this if your standard C library does not define + strtol(3). This will compile in a local version. +NEEDVPRINTF Define this if your standard C library does not define + vprintf(3). Note that the resulting fake implementation + is not very elegant and may not even work on some + architectures. +HASGETUSERSHELL Define this to 1 if you have getusershell(3) in your + standard C library. If this is not defined, or is defined + to be 0, sendmail will scan the /etc/shells file (no + NIS-style support, defaults to /bin/sh and /bin/csh if + that file does not exist) to get a list of unrestricted + user shells. This is used to determine whether users + are allowed to forward their mail to a program or a file. GIDSET_T The type of entries in a gidset passed as the second argument to getgroups(2). Historically this has been an int, so this is the default, but some systems (such as @@ -206,6 +290,17 @@ ERRLIST_PREDEFINED WAITUNION The wait(2) routine takes a "union wait" argument instead of an integer argument. This is for compatibility with old versions of BSD. +SCANF You can set this to extend the F command to accept a + scanf string -- this gives you a primitive parser for + class definitions -- BUT it can make you vulnerable to + core dumps if the target file is poorly formed. +SYSLOG_BUFSIZE You can define this to be the size of the buffer that + syslog accepts. If it is not defined, it assumes a + 1024-byte buffer. If the buffer is very small (under + 256 bytes) the log message format changes -- each + e-mail message will log many more messages, since it + will log each piece of information as a separate line + in syslog. +-----------------------+ @@ -226,10 +321,11 @@ NIS Define this to get NIS (YP) support for aliases and maps. Normally defined in the Makefile. USERDB Include support for the User Information Database. Implied by NEWDB in conf.h. -IDENTPROTO Define this to get IDENT (RFC 1413) protocol support. +IDENTPROTO Define this as 1 to get IDENT (RFC 1413) protocol support. This is assumed unless you are running on Ultrix or HP-UX, both of which have a problem in the UDP - implementation. + implementation. You can define it to be 0 to explicitly + turn off IDENT protocol support. MIME Include support for MIME-encapsulated error messages. LOG Set this to get syslog(3) support. Defined by default in conf.h. You want this if at all possible. @@ -256,10 +352,69 @@ SETPROCTITLE Try to set the string printed by "ps" to something default in conf.h. ++---------------------+ +| DNS/RESOLVER ISSUES | ++---------------------+ + +Many systems have old versions of the resolver library. At a minimum, +you should be running BIND 4.8.3; older versions may compile, but they +have known bugs that should give you pause. + +Common problems in old versions include "undefined" errors for +dn_skipname. + +Some people have had a problem with BIND 4.9; it uses some routines +that it expects to be externally defined such as strerror(). It may +help to link with "-l44bsd" to solve this problem. + +!PLEASE! be sure to link with the same version of the resolver as +the header files you used -- some people have used the 4.9 headers +and linked with BIND 4.8 or vice versa, and it doesn't work. +Unfortunately, it doesn't fail in an obvious way -- things just +subtlely don't work. + + +-------------------------------------+ | OPERATING SYSTEM AND COMPILE QUIRKS | +-------------------------------------+ +GCC 2.5.x problems *** IMPORTANT *** + Date: Mon, 29 Nov 93 19:08:44 PST + From: wilson@cygnus.com (Jim Wilson) + Message-Id: <9311300308.AA04608@cygnus.com> + To: kenner@vlsi1.ultra.nyu.edu + Subject: [cattelan@thebarn.com: gcc 2.5.4-2.5.5 -O bug] + Cc: cattelan@thebarn.com, rms@gnu.ai.mit.edu, sendmail@cs.berkeley.edu + + This fixes a problem that occurs when gcc 2.5.5 is used to compile + sendmail 8.6.4 with optimization on a sparc. + + Mon Nov 29 19:00:14 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * reload.c (find_reloads_toplev): Replace obsolete reference to + BYTE_LOADS_*_EXTEND with LOAD_EXTEND_OP. + + *** clean-ss-931128/reload.c Sun Nov 14 16:20:01 1993 + --- ss-931128/reload.c Mon Nov 29 18:52:55 1993 + *************** find_reloads_toplev (x, opnum, type, ind + *** 3888,3894 **** + force a reload in that case. So we should not do anything here. */ + + else if (regno >= FIRST_PSEUDO_REGISTER + ! #if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND) + && (GET_MODE_SIZE (GET_MODE (x)) + <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + #endif + --- 3888,3894 ---- + force a reload in that case. So we should not do anything here. */ + + else if (regno >= FIRST_PSEUDO_REGISTER + ! #ifdef LOAD_EXTEND_OP + && (GET_MODE_SIZE (GET_MODE (x)) + <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + #endif + + SunOS 4.x (Solaris 1.x) You may have to use -lresolv on SunOS. However, beware that this links in a new version of gethostbyname that does not @@ -268,7 +423,8 @@ SunOS 4.x (Solaris 1.x) Some people have reported problems with the SunOS version of -lresolv and/or in.named, and suggest that you get a newer version. The symptoms are delays when you connect to the - SMTP server on a SunOS machine. There is a version of BIND + SMTP server on a SunOS machine or having your domain added to + addresses inappropriately. There is a version of BIND version 4.9 on gatekeeper.DEC.COM in pub/BSD/bind/4.9. There is substantial disagreement about whether you can make @@ -299,15 +455,21 @@ Solaris 2.x (SunOS 5.x) The Solaris "syslog" function is apparently limited to something about 90 characters because of a kernel limitation. If you have - source code, you can probably up this number. Bill Wisner - was able to get an unofficial, unsupported - patch. + source code, you can probably up this number. The syslogd patch + is included in kernel jumbo patch for Solaris 2.2 as of revision + -39 or so. At least one person is running with patch 100999-45 + and their long lost sendmail logging is finally showing up. At + least one other person is running with patch 101318 installed + under Solaris 2.3 with success. OSF/1 - If you are compiling on OSF/1 (DEC Alpha), you must use -lmld - and -non_shared (otherwise it core dumps on startup). Also, - the enclosed makefile removed /usr/sbin/smtpd; if you need it, - just create the link to the sendmail binary. + If you are compiling on OSF/1 (DEC Alpha), you must use + -L/usr/shlib (otherwise it core dumps on startup). You may also + need -mld to get the nlist() function, although some versions + apparently don't need this. + + Also, the enclosed makefile removed /usr/sbin/smtpd; if you need + it, just create the link to the sendmail binary. NeXT If you are compiling on NeXT, you will have to create an empty @@ -329,9 +491,31 @@ NeXT You may have to use -DNeXT. -BSDI (BSD/386) - I have reports that the "m4" from BSDI won't handle the config - files properly. I haven't had a chance to test this myself. +BSDI (BSD/386) 1.0, NetBSD 0.9, FreeBSD 1.0 + The "m4" from BSDI won't handle the config files properly. + I haven't had a chance to test this myself. + + The M4 shipped in FreeBSD and NetBSD 0.9 don't handle the config + files properly. One must use either GNU m4 1.1 or the PD-M4 + recently posted in comp.os.386bsd.bugs (and maybe others). + NetBSD-current includes the PD-M4 (as stated in the NetBSD file + CHANGES). + + FreeBSD 1.0 RELEASE has uname(2) now. Use -DUSEUNAME in order to + use it (look into Makefile.FreeBSD). NetBSD-current may have + it too but it has not been verified. + + You cannot port the latest version of the Berkeley db library + and use it with sendmail without recompiling the world. This + is because C library routines use the older version which have + incompatible header files -- the result is that it can't read + other system files, such as /etc/passwd, unless you use the + new db format throughout your system. You should normally just + use the version of db supplied in your release. You may need + to use -DOLD_NEWDB to make this work -- this turns off some + new interface calls (for file locking) that are not in older + versions of db. You'll get compile errors if you need this + flag and don't have it set. 4.3BSD If you are running a "virgin" version of 4.3BSD, you'll have @@ -346,31 +530,6 @@ BSDI (BSD/386) copy ../contrib/oldbind.compat.c into src and add oldbind.compat.o to OBJADD in the Makefile. -Linux - From: Karl London - Subject: Little bit to add to a readme for Linux for 8.6 - Date: Fri, 10 Sep 1993 20:16:05 +0100 (BST) - - Below is a copy of a section of the /usr/include/unistd.h from - linux libc-4.4.1 which needs changing because of a bug in the - header files. Should be fixed for future releases.. - - Karl - - The #if 0 and #endif are new!! - - ------- - - If OPTS begins with `--', then non-option arguments - are treated as arguments to the option '\0'. - This behavior is specific to the GNU `getopt'. */ - #if 0 - extern int getopt __P ((int __argc, char *__const * __argv, - __const char *__opts)); - #endif - extern int opterr; - extern int optind; - A/UX Date: Tue, 12 Oct 1993 18:28:28 -0400 (EDT) From: "Eric C. Hagberg" @@ -401,6 +560,64 @@ DG/UX DG/UX -- the person who has this working, Douglas Anderson , used procmail instead. +System V Release 4 Based Systems + There is a single Makefile that is intended for all SVR4-based + systems (called Makefile.SVR4). It defines __svr4__, which is + predefined by some compilers. If your compiler already defines + this compile variable, you can delete the definition from the + Makefile. + + It's been tested on Dell Issue 2.2. + +DELL SVR4 + Date: Mon, 06 Dec 1993 10:42:29 EST + From: "Kimmo Suominen" + Message-ID: <2d0352f9.lento29@lento29.UUCP> + To: eric@cs.berkeley.edu + Cc: sendmail@cs.berkeley.edu + Subject: Notes for DELL SVR4 + + Eric, + + Here are some notes for compiling Sendmail 8.6.4 on DELL SVR4. I ran + across these things when helping out some people who contacted me by + e-mail. + + 1) Use gcc 2.4.5 (or later?). Dell distributes gcc 2.1 with their + Issue 2.2 Unix. It is too old, and gives you problems with + clock.c, because sigset_t won't get defined in . + This is due to a problematic protection rule in there, and is + fixed with gcc 2.4.5. + + 2) If you don't use the new Berkeley DB (-DNEWDB), then you need + to add "-lc -lucb" to the libraries to link with. This is because + the -ldbm distributed by Dell needs the bcopy, bcmp and bzero + functions. It is important that you specify both libraries in + the given order to be sure you only get the BSTRING functions + from the UCB library (and not the signal routines etc.). + + 3) Don't leave out "-lelf" even if compiling with "-lc -lucb". + The UCB library also has another copy of the nlist routines, + but we do want the ones from "-lelf". + + If anyone needs a compiled gcc 2.4.5 and/or a ported DB library, they + can use anonymous ftp to fetch them from lut.fi in the /kim directory. + They are copies of what I use on grendel.lut.fi, and offering them + does not imply that I would also support them. I have sent the DB + port for SVR4 back to Keith Bostic for inclusion in the official + distribution, but I haven't heard anything from him as of today. + + - gcc-2.4.5-svr4.tar.gz (gcc 2.4.5 and the corresponding libg++) + - db-1.72.tar.gz (with source, objects and a installed copy) + + Cheers + + Kim + -- + * Kimmo.Suominen@lut.fi * SysVr4 enthusiast at GRENDEL.LUT.FI * + * KIM@FINFILES.BITNET * Postmaster and Hostmaster at LUT.FI * + * + 358 200 865 718 * Unix area moderator at NIC.FUNET.FI * + + Non-DNS based sites This version of sendmail always tries to connect to the Domain Name System (DNS) to resolve names, regardless of the setting @@ -426,6 +643,42 @@ GNU getopt by the double call. Use the version in conf.c instead. ++--------------+ +| MANUAL PAGES | ++--------------+ + +The manual pages have been written against the -mandoc macros +instead of the -man macros. The latest version of groff has them +included. You can also get a copy from FTP.UU.NET in directory +/systems/unix/bsd-sources/share/tmac. + + ++-----------------+ +| DEBUGGING HOOKS | ++-----------------+ + +As of 8.6.5, sendmail daemons will catch a SIGUSR1 signal and log +some debugging output (logged at LOG_DEBUG severity). The +information dumped is: + + * The value of the $j macro. + * A warning if $j is not in the set $=w. + * A list of the open file descriptors. + * The contents of the connection cache. + * If ruleset 89 is defined, it is evaluated and the results printed. + +This allows you to get information regarding the runtime state of the +daemon on the fly. This should not be done too frequently, since +the process of rewriting may lose memory which will not be recovered. +Also, ruleset 89 may call non-reentrant routines, so there is a small +non-zero probability that this will cause other problems. It is +really only for debugging serious problems. + +A typical formulation of ruleset 89 would be: + + R$* $@ $>0 some test address + + +-----------------------------+ | DESCRIPTION OF SOURCE FILES | +-----------------------------+ @@ -489,4 +742,4 @@ version.c The version number and information about this Eric Allman -(Version 8.31, last update 10/31/93 11:32:52) +(Version 8.47, last update 1/12/94 05:59:56) diff --git a/usr.sbin/sendmail/src/alias.c b/usr.sbin/sendmail/src/alias.c index a89e27301f1..66d81d77bf6 100644 --- a/usr.sbin/sendmail/src/alias.c +++ b/usr.sbin/sendmail/src/alias.c @@ -36,7 +36,7 @@ # include #ifndef lint -static char sccsid[] = "@(#)alias.c 8.19 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)alias.c 8.21 (Berkeley) 12/11/93"; #endif /* not lint */ @@ -144,7 +144,7 @@ alias(a, sendq, e) owner = aliaslookup(obuf, e); if (owner != NULL) { - if (strchr(owner, ',') != NULL) + if (strpbrk(owner, ",:/|\"") != NULL) owner = obuf; a->q_owner = newstr(owner); } @@ -570,7 +570,7 @@ readaliases(map, af, automatic) } if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv) == NULL) { - syserr("554 %s... illegal alias name", al.q_paddr); + syserr("554 %.40s... illegal alias name", line); continue; } diff --git a/usr.sbin/sendmail/src/aliases.5 b/usr.sbin/sendmail/src/aliases.5 index 39f380516ec..f40f64de10b 100644 --- a/usr.sbin/sendmail/src/aliases.5 +++ b/usr.sbin/sendmail/src/aliases.5 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)aliases.5 8.1 (Berkeley) 6/16/93 +.\" @(#)aliases.5 8.2 (Berkeley) 12/11/93 .\" -.Dd June 16, 1993 +.Dd December 11, 1993 .Dt ALIASES 5 .Os BSD 4 .Sh NAME @@ -94,7 +94,7 @@ change to take effect. If you have compiled .Xr sendmail with DBM support instead of NEWDB, -you may have encounter problems in +you may have encountered problems in .Xr dbm 3 restricting a single alias to about 1000 bytes of information. You can get longer aliases by ``chaining''; that is, make the last name in diff --git a/usr.sbin/sendmail/src/cdefs.h b/usr.sbin/sendmail/src/cdefs.h index c4157bcd1a8..afc1a68ef19 100644 --- a/usr.sbin/sendmail/src/cdefs.h +++ b/usr.sbin/sendmail/src/cdefs.h @@ -2,6 +2,9 @@ * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)cdefs.h 8.2 (Berkeley) 10/4/93 + * @(#)cdefs.h 8.5 (Berkeley) 1/4/94 */ #ifndef _CDEFS_H_ @@ -56,43 +59,64 @@ #define __CONCAT(x,y) x ## y #define __STRING(x) #x -#if !defined(__GNUC__) && !defined(__cplusplus) -#define inline -#endif +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#ifndef __GNUC__ +#define __inline /* delete GCC keyword */ +#endif /* !__GNUC__ */ +#endif /* !__cplusplus */ #else /* !(__STDC__ || __cplusplus) */ #define __P(protos) () /* traditional C preprocessor */ #define __CONCAT(x,y) x/**/y #define __STRING(x) "x" -#ifdef __GNUC__ -#define const __const /* GCC: ANSI C with -traditional */ -#define inline __inline -#define signed __signed -#define volatile __volatile - -#else /* !__GNUC__ */ +#ifndef __GNUC__ +#define __const /* delete pseudo-ANSI C keywords */ +#define __inline +#define __signed +#define __volatile +/* + * In non-ANSI C environments, new programs will want ANSI-only C keywords + * deleted from the program and old programs will want them left alone. + * When using a compiler other than gcc, programs using the ANSI C keywords + * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. + * When using "gcc -traditional", we assume that this is the intent; if + * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. + */ +#ifndef NO_ANSI_KEYWORDS #define const /* delete ANSI C keywords */ #define inline #define signed #define volatile +#endif #endif /* !__GNUC__ */ #endif /* !(__STDC__ || __cplusplus) */ /* - * GCC has extensions for declaring functions as `pure' (always returns - * the same value given the same inputs, i.e., has no external state and - * no side effects) and `dead' (nonreturning). These mainly affect - * optimization and warnings. Unfortunately, GCC complains if these are - * used under strict ANSI mode (`gcc -ansi -pedantic'), hence we need to - * define them only if compiling without this. + * GCC1 and some versions of GCC2 declare dead (non-returning) and + * pure (no side effects) functions using "volatile" and "const"; + * unfortunately, these then cause warnings under "-ansi -pedantic". + * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of + * these work for GNU C++ (modulo a slight glitch in the C++ grammar + * in the distribution version of 2.5.5). */ +#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5 +#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ #if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define __dead __volatile -#define __pure __const -#else -#define __dead -#define __pure +#define __dead __volatile +#define __pure __const +#endif +#endif + +/* Delete pseudo-keywords wherever they are not available or needed. */ +#ifndef __dead +#define __dead +#define __pure #endif #endif /* !_CDEFS_H_ */ diff --git a/usr.sbin/sendmail/src/clock.c b/usr.sbin/sendmail/src/clock.c index 8c78bc182c5..45ef1c2782c 100644 --- a/usr.sbin/sendmail/src/clock.c +++ b/usr.sbin/sendmail/src/clock.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)clock.c 8.7 (Berkeley) 10/21/93"; +static char sccsid[] = "@(#)clock.c 8.8 (Berkeley) 1/12/94"; #endif /* not lint */ # include "sendmail.h" @@ -60,7 +60,7 @@ static char sccsid[] = "@(#)clock.c 8.7 (Berkeley) 10/21/93"; ** none. */ -static void tick(); +static void tick __P((int)); EVENT * setevent(intvl, func, arg) @@ -101,7 +101,7 @@ setevent(intvl, func, arg) printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n", intvl, now + intvl, func, arg, ev); - tick(); + tick(0); return (ev); } /* @@ -143,7 +143,7 @@ clrevent(ev) } /* restore clocks and pick up anything spare */ - tick(); + tick(0); } /* ** TICK -- take a clock tick @@ -151,7 +151,7 @@ clrevent(ev) ** Called by the alarm clock. This routine runs events as needed. ** ** Parameters: -** none. +** One that is ignored; for compatibility with signal handlers. ** ** Returns: ** none. @@ -161,7 +161,8 @@ clrevent(ev) */ static void -tick() +tick(arg) + int arg; { register time_t now; register EVENT *ev; diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c index fba8c776913..e0eb672358b 100644 --- a/usr.sbin/sendmail/src/collect.c +++ b/usr.sbin/sendmail/src/collect.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)collect.c 8.6 (Berkeley) 10/27/93"; +static char sccsid[] = "@(#)collect.c 8.8 (Berkeley) 1/8/94"; #endif /* not lint */ # include @@ -160,7 +160,10 @@ collect(smtpmode, requeueflag, e) if (sfgets(freebuf, MAXLINE, InChannel, TimeOuts.to_datablock, "message header read") == NULL) - goto readerr; + { + freebuf[0] = '\0'; + break; + } /* is this a continuation line? */ if (*freebuf != ' ' && *freebuf != '\t') @@ -257,7 +260,8 @@ collect(smtpmode, requeueflag, e) break; /* check for transparent dot */ - if (OpMode == MD_SMTP && bp[0] == '.' && bp[1] == '.') + if ((OpMode == MD_SMTP || OpMode == MD_DAEMON) && + bp[0] == '.' && bp[1] == '.') bp++; /* @@ -278,6 +282,8 @@ collect(smtpmode, requeueflag, e) if (feof(InChannel) || ferror(InChannel)) { readerr: + if (tTd(30, 1)) + printf("collect: read error\n"); inputerr = TRUE; } @@ -290,7 +296,7 @@ readerr: } /* An EOF when running SMTP is an error */ - if (inputerr && OpMode == MD_SMTP) + if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) { char *host; char *problem; diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c index 4ae6d84ad52..cc6605a66c1 100644 --- a/usr.sbin/sendmail/src/conf.c +++ b/usr.sbin/sendmail/src/conf.c @@ -33,13 +33,14 @@ */ #ifndef lint -static char sccsid[] = "@(#)conf.c 8.42 (Berkeley) 10/21/93"; +static char sccsid[] = "@(#)conf.c 8.62 (Berkeley) 1/9/94"; #endif /* not lint */ # include "sendmail.h" # include "pathnames.h" # include # include +# include # include /* @@ -597,7 +598,9 @@ rlsesigs() # include #endif -init_md() +init_md(argc, argv) + int argc; + char **argv; { #ifdef _AUX_SOURCE setcompat(getcompat() | COMPAT_BSDPROT); @@ -792,10 +795,14 @@ getla() #if LA_TYPE == LA_MACH /* -** This has been tested on NeXT release 2.1. +** This has been tested on NEXTSTEP release 2.1/3.X. */ -#include +#if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 +# include +#else +# include +#endif getla() { @@ -910,6 +917,7 @@ refuseconnections() # include # ifdef __bsdi__ # undef PS_STRINGS /* BSDI 1.0 doesn't do PS_STRINGS as we expect */ +# define PROCTITLEPAD '\0' # endif # ifdef PS_STRINGS # define SETPROC_STATIC static @@ -920,6 +928,10 @@ refuseconnections() # endif #endif +#ifndef PROCTITLEPAD +# define PROCTITLEPAD ' ' +#endif + /*VARARGS1*/ #ifdef __STDC__ setproctitle(char *fmt, ...) @@ -969,7 +981,7 @@ setproctitle(fmt, va_alist) (void) strcpy(Argv[0], buf); p = &Argv[0][i]; while (p < LastArgv) - *p++ = ' '; + *p++ = PROCTITLEPAD; # endif # endif # endif /* SETPROCTITLE */ @@ -1258,9 +1270,13 @@ static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86"; /* * get option letter from argument vector */ -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ +#ifdef _CONVEX_SOURCE +extern int optind, opterr; +#else +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +#endif +int optopt; /* character checked for validity */ char *optarg; /* argument associated with option */ #define BADCH (int)'?' @@ -1269,9 +1285,9 @@ char *optarg; /* argument associated with option */ fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);} getopt(nargc,nargv,ostr) -int nargc; -char **nargv, - *ostr; + int nargc; + char *const *nargv; + const char *ostr; { static char *place = EMSG; /* option letter processing */ static char atend = 0; @@ -1356,6 +1372,97 @@ vsprintf(s, fmt, ap) #endif /* +** USERSHELLOK -- tell if a user's shell is ok for unrestricted use +** +** Parameters: +** shell -- the user's shell from /etc/passwd +** +** Returns: +** TRUE -- if it is ok to use this for unrestricted access. +** FALSE -- if the shell is restricted. +*/ + +#if !HASGETUSERSHELL + +# ifndef _PATH_SHELLS +# define _PATH_SHELLS "/etc/shells" +# endif + +char *DefaultUserShells[] = +{ + "/bin/sh", + "/usr/bin/sh", + "/bin/csh", + "/usr/bin/csh", +#ifdef __hpux + "/bin/rsh", + "/bin/ksh", + "/bin/rksh", + "/bin/pam", + "/usr/bin/keysh", + "/bin/posix/sh", +#endif + NULL +}; + +#endif + +bool +usershellok(shell) + char *shell; +{ +#if HASGETUSERSHELL + register char *p; + extern char *getusershell(); + + setusershell(); + while ((p = getusershell()) != NULL) + if (strcmp(p, shell) == 0 || strcmp(p, "*") == 0) + break; + endusershell(); + return p != NULL; +#else + register FILE *shellf; + char buf[MAXLINE]; + + shellf = fopen(_PATH_SHELLS, "r"); + if (shellf == NULL) + { + /* no /etc/shells; see if it is one of the std shells */ + char **d; + + for (d = DefaultUserShells; *d != NULL; d++) + { + if (strcmp(shell, *d) == 0) + return TRUE; + } + return FALSE; + } + + while (fgets(buf, sizeof buf, shellf) != NULL) + { + register char *p, *q; + + p = buf; + while (*p != '\0' && *p != '#' && *p != '/') + p++; + if (*p == '#' || *p == '\0') + continue; + q = p; + while (*p != '\0' && *p != '#' && !isspace(*p)) + p++; + *p = '\0'; + if (strcmp(shell, q) == 0 || strcmp("*", q) == 0) + { + fclose(shellf); + return TRUE; + } + } + fclose(shellf); + return FALSE; +#endif +} + /* ** FREESPACE -- see how much free space is on the queue filesystem ** ** Only implemented if you have statfs. @@ -1382,10 +1489,10 @@ vsprintf(s, fmt, ap) #endif #ifdef HASSTATFS -# if defined(IRIX) || defined(apollo) || defined(_SCO_unix_) || defined(UMAXV) || defined(DGUX) +# if defined(IRIX) || defined(apollo) || defined(_SCO_unix_) || defined(UMAXV) || defined(DGUX) || defined(_AIX3) # include # else -# if (defined(sun) && !defined(BSD)) || defined(__hpux) || defined(_CONVEX_SOURCE) || defined(NeXT) || defined(_AUX_SOURCE) +# if (defined(sun) && !defined(BSD)) || defined(__hpux) || defined(_CONVEX_SOURCE) || defined(NeXT) || defined(_AUX_SOURCE) || defined(MACH386) # include # else # include @@ -1726,6 +1833,16 @@ getcfname() { if (ConfFile != NULL) return ConfFile; +#ifdef NETINFO + { + extern char *ni_propval(); + char *cflocation; + + cflocation = ni_propval("/locations/sendmail", "sendmail.cf"); + if (cflocation != NULL) + return cflocation; + } +#endif return _PATH_SENDMAILCF; } /* @@ -1737,11 +1854,262 @@ getcfname() ** Returns: ** TRUE -- if ok. ** FALSE -- if vendor code could not be processed. +** +** Side Effects: +** It is reasonable to set mode flags here to tweak +** processing in other parts of the code if necessary. +** For example, if you are a vendor that uses $%y to +** indicate YP lookups, you could enable that here. */ bool setvendor(vendor) char *vendor; { - return (strcasecmp(vendor, "Berkeley") == 0); + if (strcasecmp(vendor, "Berkeley") == 0) + return TRUE; + + /* add vendor extensions here */ + + return FALSE; } + /* +** STRTOL -- convert string to long integer +** +** For systems that don't have it in the C library. +*/ + +#ifdef NEEDSTRTOL + +long +strtol(p, ep, b) + char *p; + char **ep; + int b; +{ + long l = 0; + char c; + char maxd; + int neg = 1; + + maxd = (b > 10) ? '9' : b + '0'; + + if (p && *p == '-') { + neg = -1; + p++; + } + while (p && (c = *p)) { + if (c >= '0' && c <= maxd) { + l = l*b + *p++ - '0'; + continue; + } + if (c >= 'A' && c <= 'Z') + c -= 'A' + 'a'; + c = c - 'a' + 10; + if (b > c) { + l = l*b + c; + p++; + continue; + } + break; + } + l *= neg; + if (ep) + *ep = p; + return l; +} + +#endif + /* +** SOLARIS_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX +** +** Solaris versions prior through 2.3 don't properly deliver a +** canonical h_name field. This tries to work around it. +*/ + +#ifdef SOLARIS + +struct hostent * +solaris_gethostbyname(name) + const char *name; +{ +# ifdef SOLARIS_2_3 + static struct hostent hp; + static char buf[1000]; + extern struct hostent *_switch_gethostbyname_r(); + + return _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); +# else + extern struct hostent *__switch_gethostbyname(); + + return __switch_gethostbyname(name); +# endif +} + +struct hostent * +solaris_gethostbyaddr(addr, len, type) + const char *addr; + int len; + int type; +{ +# ifdef SOLARIS_2_3 + static struct hostent hp; + static char buf[1000]; + extern struct hostent *_switch_gethostbyaddr_r(); + + return _switch_gethostbyaddr_r(addr, len, type, &hp, buf, sizeof(buf), &h_errno); +# else + extern struct hostent *__switch_gethostbyaddr(); + + return __switch_gethostbyaddr(addr, len, type); +# endif +} + +#endif + /* +** NI_PROPVAL -- netinfo property value lookup routine +** +** Parameters: +** directory -- the Netinfo directory name. +** propname -- the Netinfo property name. +** +** Returns: +** NULL -- if: +** 1. the directory is not found +** 2. the property name is not found +** 3. the property contains multiple values +** 4. some error occured +** else -- the location of the config file. +** +** Notes: +** Caller should free the return value of ni_proval +*/ + +#ifdef NETINFO + +# include + +# define LOCAL_NETINFO_DOMAIN "." +# define PARENT_NETINFO_DOMAIN ".." +# define MAX_NI_LEVELS 256 + +char * +ni_propval(directory, propname) + char *directory; + char *propname; +{ + char *propval; + int i; + void *ni = NULL; + void *lastni = NULL; + ni_status nis; + ni_id nid; + ni_namelist ninl; + + /* + ** If the passed directory and property name are found + ** in one of netinfo domains we need to search (starting + ** from the local domain moving all the way back to the + ** root domain) set propval to the property's value + ** and return it. + */ + + for (i = 0; i < MAX_NI_LEVELS; ++i) + { + if (i == 0) + { + nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni); + } + else + { + if (lastni != NULL) + ni_free(lastni); + lastni = ni; + nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni); + } + + /* + ** Don't bother if we didn't get a handle on a + ** proper domain. This is not necessarily an error. + ** We would get a positive ni_status if, for instance + ** we never found the directory or property and tried + ** to open the parent of the root domain! + */ + + if (nis != 0) + break; + + /* + ** Find the path to the server information. + */ + + if (ni_pathsearch(ni, &nid, directory) != 0) + continue; + + /* + ** Find "host" information. + */ + + if (ni_lookupprop(ni, &nid, propname, &ninl) != 0) + continue; + + /* + ** If there's only one name in + ** the list, assume we've got + ** what we want. + */ + + if (ninl.ni_namelist_len == 1) + { + propval = ni_name_dup(ninl.ni_namelist_val[0]); + break; + } + } + + /* + ** Clean up. + */ + + if (ni != NULL) + ni_free(ni); + if (lastni != NULL && ni != lastni) + ni_free(lastni); + + return propval; +} + +#endif /* NETINFO */ + /* +** HARD_SYSLOG -- call syslog repeatedly until it works +** +** Needed on HP-UX, which apparently doesn't guarantee that +** syslog succeeds during interrupt handlers. +*/ + +#ifdef __hpux + +# define MAXSYSLOGTRIES 100 +# undef syslog + +# ifdef __STDC__ +hard_syslog(int pri, char *msg, ...) +# else +hard_syslog(pri, msg, va_alist) + int pri; + char *msg; + va_dcl +# endif +{ + int i; + char buf[SYSLOG_BUFSIZE * 2]; + VA_LOCAL_DECL; + + VA_START(msg); + vsprintf(buf, msg, ap); + VA_END; + + for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, "%s", buf) < 0; ) + continue; +} + +#endif diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h index fdf7af44713..a06738c0fb8 100644 --- a/usr.sbin/sendmail/src/conf.h +++ b/usr.sbin/sendmail/src/conf.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)conf.h 8.44 (Berkeley) 10/29/93 + * @(#)conf.h 8.75 (Berkeley) 1/8/94 */ /* @@ -64,7 +64,6 @@ # define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */ # define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */ # define MAXALIASDB 12 /* max # of alias databases */ -# define PSBUFSIZE (MAXLINE + MAXATOM) /* size of prescan buffer */ # ifndef QUEUESIZE # define QUEUESIZE 1000 /* max # of jobs per queue run */ @@ -78,6 +77,7 @@ # define LOG 1 /* enable logging */ # define UGLYUUCP 1 /* output ugly UUCP From lines */ +# define NETUNIX 1 /* include unix domain support */ # define NETINET 1 /* include internet support */ # define SETPROCTITLE 1 /* munge argv to display current status */ # define NAMED_BIND 1 /* use Berkeley Internet Domain Server */ @@ -89,17 +89,26 @@ # endif /* -** Due to a "feature" in some operating systems such as Ultrix 4.3 and -** HPUX 8.0, if you receive a "No route to host" message (ICMP message -** ICMP_UNREACH_HOST) on _any_ connection, all connections to that host -** are closed. Some firewalls return this error if you try to connect -** to the IDENT port (113), so you can't receive email from these hosts -** on these systems. The firewall really should use a more specific -** message such as ICMP_UNREACH_PROTOCOL or _PORT or _NET_PROHIB. This -** will get #undefed below as needed. +** Most systems have symbolic links today, so default them on. You +** can turn them off by #undef'ing this below. */ -# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */ +# define HASLSTAT 1 /* has lstat(2) call */ + +/* +** General "standard C" defines. +** +** These may be undone later, to cope with systems that claim to +** be Standard C but aren't. Gcc is the biggest offender -- it +** doesn't realize that the library is part of the language. +** +** Life would be much easier if we could get rid of this sort +** of bozo problems. +*/ + +#ifdef __STDC__ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ +#endif /********************************************************************** ** Operating system configuration. @@ -114,7 +123,7 @@ /* -** HP-UX -- tested for 8.07 +** HP-UX -- tested for 8.07, 9.00, and 9.01. */ # ifdef __hpux @@ -126,8 +135,21 @@ # define HASSETREUID 1 /* has setreuid(2) call */ # define setreuid(r, e) setresuid(r, e, -1) # define LA_TYPE LA_FLOAT +# define GIDSET_T gid_t # define _PATH_UNIX "/hp-ux" -# undef IDENTPROTO /* TCP/IP implementation is broken */ +# ifndef _PATH_SENDMAILCF +# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" +# endif +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ +# endif +# define syslog hard_syslog +# ifdef __STDC__ +extern int syslog(int, char *, ...); +# endif # endif @@ -137,6 +159,9 @@ # ifdef _AIX3 # define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASSTATFS 1 /* has the statfs(2) syscall */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ # define FORK fork /* no vfork primitive available */ # undef SETPROCTITLE /* setproctitle confuses AIX */ # endif @@ -153,6 +178,7 @@ # define HASSETREUID 1 /* has setreuid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ # define HASSTATFS 1 /* has the statfs(2) syscall */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ # define FORK fork /* no vfork primitive available */ # define WAITUNION 1 /* use "union wait" as wait argument type */ # define setpgid BSDsetpgrp @@ -161,24 +187,35 @@ /* -** SunOS +** SunOS and Solaris +** +** Tested on SunOS 4.1.x (a.k.a. Solaris 1.1.x) and +** Solaris 2.2 (a.k.a. SunOS 5.2). */ #if defined(sun) && !defined(BSD) # define LA_TYPE LA_INT -# define HASSETREUID 1 /* has setreuid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASUNAME 1 /* use System V uname(2) system call */ +# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ + +# ifdef SOLARIS_2_3 +# define SOLARIS +# endif # ifdef SOLARIS /* Solaris 2.x (a.k.a. SunOS 5.x) */ -# define SYSTEM5 1 /* use System V definitions */ -# define setreuid(r, e) seteuid(e) -# include +# ifndef __svr4__ +# define __svr4__ /* use all System V Releae 4 defines below */ +# endif # include -# define gethostbyname __switch_gethostbyname /* get working version */ -# define gethostbyaddr __switch_gethostbyaddr /* get working version */ -# define _PATH_UNIX "/kernel/unix" +# define gethostbyname solaris_gethostbyname /* get working version */ +# define gethostbyaddr solaris_gethostbyaddr /* get working version */ +# define GIDSET_T gid_t +# ifndef _PATH_UNIX +# define _PATH_UNIX "/kernel/unix" +# endif # ifndef _PATH_SENDMAILCF # define _PATH_SENDMAILCF "/etc/mail/sendmail.cf" # endif @@ -187,16 +224,32 @@ # endif # else - /* SunOS 4.1.x */ + /* SunOS 4.0.3 or 4.1.x */ +# define HASSETREUID 1 /* has setreuid(2) call */ # define HASSTATFS 1 /* has the statfs(2) syscall */ -/* # define HASFLOCK 1 /* has flock(2) call */ +# define HASFLOCK 1 /* has flock(2) call */ # include +# ifdef SUNOS403 + /* special tweaking for SunOS 4.0.3 */ +# include +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# undef WIFEXITED +# undef WEXITSTATUS +# undef HASUNAME +# define setpgid setpgrp +typedef int pid_t; +extern char *getenv(); + +# endif # endif #endif /* -** DG/UX 5.4.2 +** DG/UX +** +** Tested on 5.4.2 */ #ifdef DGUX @@ -207,9 +260,15 @@ # define HASUNAME 1 /* use System V uname(2) system call */ # define HASSETSID 1 /* has Posix setsid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ -# undef IDENTPROTO /* TCP/IP implementation is broken */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif # undef SETPROCTITLE + +/* these include files must be included early on DG/UX */ +# include +# include + # define inet_addr dgux_inet_addr extern long dgux_inet_addr(); #endif @@ -229,9 +288,16 @@ extern long dgux_inet_addr(); # define HASUNSETENV 1 /* has unsetenv(3) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ # define HASFLOCK 1 /* has flock(2) call */ -# define LA_TYPE LA_INT -# define LA_AVENRUN "avenrun" -# undef IDENTPROTO /* TCP/IP implementation is broken */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# ifdef vax +# define LA_TYPE LA_FLOAT +# else +# define LA_TYPE LA_INT +# define LA_AVENRUN "avenrun" +# endif +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif #endif @@ -244,8 +310,11 @@ extern long dgux_inet_addr(); # define HASUNSETENV 1 /* has unsetenv(3) call */ # define HASSETREUID 1 /* has setreuid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ -/* # define HASFLOCK 1 /* has flock(2) call */ +# define HASFLOCK 1 /* has flock(2) call */ # define LA_TYPE LA_INT +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/var/run/sendmail.pid" +# endif #endif @@ -280,6 +349,8 @@ typedef int pid_t; /* ** 4.4 BSD +** +** See also BSD defines. */ #ifdef BSD4_4 @@ -297,6 +368,8 @@ typedef int pid_t; ** 386BSD / FreeBSD 1.0E / NetBSD (all architectures, all versions) ** ** 4.3BSD clone, closer to 4.4BSD +** +** See also BSD defines. */ #if defined(__386BSD__) || defined(__FreeBSD__) || defined(__NetBSD__) @@ -311,6 +384,36 @@ typedef int pid_t; #endif +/* +** Mach386 +** +** For mt Xinu's Mach386 system. +*/ + +#if defined(MACH) && defined(i386) +# define MACH386 1 +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASFLOCK 1 /* has flock(2) call */ +# define HASSTATFS 1 /* has the statfs(2) syscall */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ +# define NEEDSTRTOL 1 /* need the strtol() function */ +# define setpgid setpgrp +# ifndef LA_TYPE +# define LA_TYPE LA_FLOAT +# endif +# undef HASSETVBUF /* don't actually have setvbuf(3) */ +# undef WEXITSTATUS +# undef WIFEXITED +# ifndef _PATH_SENDMAILCF +# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" +# endif +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + + /* ** 4.3 BSD -- this is for very old systems ** @@ -329,21 +432,45 @@ typedef int pid_t; # ifndef _PATH_SENDMAILCF # define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" # endif -# undef IDENTPROTO /* TCP/IP implementation is broken */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif +# undef WEXITSTATUS +# undef WIFEXITED +typedef short pid_t; +extern int errno; #endif /* ** SCO Unix +** +** This includes two parts -- the first is for SCO Open Server 3.2v4 +** (contributed by Philippe Brand ). +** The second is, I believe, for an older version. */ +#ifdef _SCO_unix_4_2 +# define _SCO_unix_ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define _PATH_UNIX "/unix" +# ifndef _PATH_SENDMAILCF +# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" +# endif +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/etc/sendmail.pid" +# endif +#endif + #ifdef _SCO_unix_ # define SYSTEM5 1 /* include all the System V defines */ # define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ # define HASSTATFS 1 /* has the statfs(2) syscall */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ # define FORK fork # define MAXPATHLEN PATHSIZE # define LA_TYPE LA_SHORT +# undef NETUNIX /* no unix domain socket support */ #endif @@ -358,22 +485,38 @@ typedef int pid_t; # define HASSETSID 1 /* has POSIX setsid(2) call */ # define NEEDGETOPT 1 /* need replacement for getopt(3) */ # define LA_TYPE LA_FLOAT -# undef IDENTPROTO +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif #endif /* -** RISC/os 4.51 +** RISC/os 4.52 ** -** Untested... +** Gives a ton of warning messages, but otherwise compiles. */ #ifdef RISCOS + # define HASUNSETENV 1 /* has unsetenv(3) call */ -/* # define HASFLOCK 1 /* has flock(2) call */ +# define HASFLOCK 1 /* has flock(2) call */ +# define WAITUNION 1 /* use "union wait" as wait argument type */ +# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ # define LA_TYPE LA_INT # define LA_AVENRUN "avenrun" # define _PATH_UNIX "/unix" +# undef WIFEXITED + +# define setpgid setpgrp + +extern int errno; +typedef int pid_t; +#define SIGFUNC_DEFINED +typedef int (*sigfunc_t)(); +extern char *getenv(); +extern void *malloc(); + #endif @@ -391,6 +534,7 @@ typedef int pid_t; # define LA_TYPE LA_FLOAT # endif # include +# define GIDSET_T gid_t #endif @@ -400,19 +544,15 @@ typedef int pid_t; ** ** It's on #ifdef DELL_SVR4 because Solaris also gets __svr4__ ** defined, and the definitions conflict. +** +** Peter Wemm claims that the setreuid +** trick works on DELL 2.2 (SVR4.0/386 version 4.0) and ESIX 4.0.3A +** (SVR4.0/386 version 3.0). */ #ifdef DELL_SVR4 -# define SYSTEM5 1 -/* # define setreuid(r, e) seteuid(e) */ -/* # include */ -# define _PATH_UNIX "/unix" -# ifndef _PATH_SENDMAILCF -# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf" -# endif -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" -# endif + /* no changes necessary */ + /* see general __svr4__ defines below */ #endif @@ -428,7 +568,9 @@ typedef int pid_t; # define HASUSTAT 1 /* use System V ustat(2) syscall */ # define HASSETVBUF 1 /* we have setvbuf(3) in libc */ # define SIGFUNC_DEFINED /* sigfunc_t already defined */ -# undef IDENTPROTO /* TCP/IP implementation is broken */ +# ifndef IDENTPROTO +# define IDENTPROTO 0 /* TCP/IP implementation is broken */ +# endif # define FORK fork # ifndef _PATH_SENDMAILCF # define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" @@ -453,6 +595,7 @@ typedef int pid_t; # define HASSTATFS 1 /* has the statfs(2) syscall */ # define HASSETVBUF 1 /* we have setvbuf(3) in libc */ # define HASINITGROUPS 1 /* has initgroups(3) call */ +# 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 */ @@ -464,6 +607,61 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid(); #endif +/* +** Stardent Titan 3000 running TitanOS 4.2. +** +** Must be compiled in "cc -43" mode. +** +** From Kate Hedstrom . +** +** Note the tweaking below after the BSD defines are set. +*/ + +#ifdef titan +# define setpgid setpgrp +typedef int pid_t; +# undef WIFEXITED +# undef WEXITSTATUS +#endif + + +/* +** Sequent DYNIX 3.2.0 +** +** From Jim Davis . +*/ + +#ifdef sequent +# define BSD 1 +# define HASUNSETENV 1 +# define BSD4_3 1 /* to get signal() in conf.c */ +# define WAITUNION 1 +# define LA_TYPE LA_FLOAT +# ifdef _POSIX_VERSION +# undef _POSIX_VERSION /* set in */ +# endif +# undef HASSETVBUF /* don't actually have setvbuf(3) */ +# define setpgid setpgrp + +/* Have to redefine WIFEXITED to take an int, to work with waitfor() */ +# undef WIFEXITED +# define WIFEXITED(s) (((union wait*)&(s))->w_stopval != WSTOPPED && \ + ((union wait*)&(s))->w_termsig == 0) +# define WEXITSTATUS(s) (((union wait*)&(s))->w_retcode) +typedef int pid_t; +# define isgraph(c) (isprint(c) && (c != ' ')) + +# ifndef _PATH_UNIX +# define _PATH_UNIX "/dynix" +# endif +# ifndef _PATH_SENDMAILCF +# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf" +# endif + +#endif + + + /********************************************************************** ** End of Per-Operating System defines @@ -481,11 +679,36 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid(); # define HASFLOCK 1 /* has flock(2) call */ #endif +/* general System V Release 4 defines */ +#ifdef __svr4__ +# define SYSTEM5 1 +# define HASSETREUID 1 /* has seteuid(2) call & working saved uids */ +# ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# endif +# define setreuid(r, e) seteuid(e) + +# ifndef _PATH_UNIX +# define _PATH_UNIX "/unix" +# endif +# ifndef _PATH_SENDMAILCF +# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf" +# endif +# ifndef _PATH_SENDMAILPID +# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" +# endif +# ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 128 +# endif +#endif + /* general System V defines */ # ifdef SYSTEM5 +# include # define HASUNAME 1 /* use System V uname(2) system call */ # define HASUSTAT 1 /* use System V ustat(2) syscall */ # define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ +# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ # ifndef LA_TYPE # define LA_TYPE LA_INT # endif @@ -494,11 +717,6 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid(); # define bcmp(s, d, l) (memcmp((s), (d), (l))) # endif -/* general "standard C" defines */ -#if defined(__STDC__) || defined(SYSTEM5) -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ -#endif - /* general POSIX defines */ #ifdef _POSIX_VERSION # define HASSETSID 1 /* has Posix setsid(2) call */ @@ -515,6 +733,34 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid(); # define GIDSET_T int #endif +/* +** Tweaking for systems that (for example) claim to be BSD but +** don't have all the standard BSD routines (boo hiss). +*/ + +#ifdef titan +# undef HASINITGROUPS /* doesn't have initgroups(3) call */ +#endif + +/* +** Due to a "feature" in some operating systems such as Ultrix 4.3 and +** HPUX 8.0, if you receive a "No route to host" message (ICMP message +** ICMP_UNREACH_HOST) on _any_ connection, all connections to that host +** are closed. Some firewalls return this error if you try to connect +** to the IDENT port (113), so you can't receive email from these hosts +** on these systems. The firewall really should use a more specific +** message such as ICMP_UNREACH_PROTOCOL or _PORT or _NET_PROHIB. If +** not explicitly set to zero above, default it on. +*/ + +#ifndef IDENTPROTO +# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */ +#endif + +#ifndef HASGETUSERSHELL +# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */ +#endif + /********************************************************************** ** Remaining definitions should never have to be changed. They are @@ -524,7 +770,10 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid(); /* System 5 compatibility */ #ifndef S_ISREG -#define S_ISREG(foo) ((foo & S_IFREG) == S_IFREG) +# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISLNK) && defined(S_IFLNK) +# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK) #endif #ifndef S_IWGRP #define S_IWGRP 020 @@ -656,6 +905,11 @@ struct utsname typedef void (*sigfunc_t) __P((int)); #endif +/* size of syslog buffer */ +#ifndef SYSLOG_BUFSIZE +# define SYSLOG_BUFSIZE 1024 +#endif + /* ** Size of tobuf (deliver.c) ** Tweak this to match your syslog implementation. It will have to @@ -663,9 +917,20 @@ typedef void (*sigfunc_t) __P((int)); */ #ifndef TOBUFSIZE -# define TOBUFSIZE (1024 - 256) +# if (SYSLOG_BUFSIZE) > 512 +# define TOBUFSIZE (SYSLOG_BUFSIZE - 256) +# else +# define TOBUFSIZE 256 +# endif #endif +/* +** Size of prescan buffer. +** Despite comments in the _sendmail_ book, this probably should +** not be changed; there are some hard-to-define dependencies. +*/ + +# 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 */ diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c index a1a51f95fb8..8e5f55540f9 100644 --- a/usr.sbin/sendmail/src/daemon.c +++ b/usr.sbin/sendmail/src/daemon.c @@ -37,9 +37,9 @@ #ifndef lint #ifdef DAEMON -static char sccsid[] = "@(#)daemon.c 8.21 (Berkeley) 10/31/93 (with daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.30 (Berkeley) 1/8/94 (with daemon mode)"; #else -static char sccsid[] = "@(#)daemon.c 8.21 (Berkeley) 10/31/93 (without daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.30 (Berkeley) 1/8/94 (without daemon mode)"; #endif #endif /* not lint */ @@ -110,10 +110,10 @@ int TcpSndBufferSize = 0; /* size of TCP send buffer */ getrequests() { int t; - register struct servent *sp; int on = 1; bool refusingconnections = TRUE; FILE *pidf; + int socksize; extern void reapchild(); /* @@ -126,13 +126,16 @@ getrequests() DaemonAddr.sin.sin_addr.s_addr = INADDR_ANY; if (DaemonAddr.sin.sin_port == 0) { + register struct servent *sp; + sp = getservbyname("smtp", "tcp"); if (sp == NULL) { syserr("554 service \"smtp\" unknown"); - goto severe; + DaemonAddr.sin.sin_port = htons(25); } - DaemonAddr.sin.sin_port = sp->s_port; + else + DaemonAddr.sin.sin_port = sp->s_port; } /* @@ -177,22 +180,22 @@ getrequests() { # ifdef NETINET case AF_INET: - t = sizeof DaemonAddr.sin; + socksize = sizeof DaemonAddr.sin; break; # endif # ifdef NETISO case AF_ISO: - t = sizeof DaemonAddr.siso; + socksize = sizeof DaemonAddr.siso; break; # endif default: - t = sizeof DaemonAddr; + socksize = sizeof DaemonAddr; break; } - if (bind(DaemonSocket, &DaemonAddr.sa, t) < 0) + if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0) { syserr("getrequests: cannot bind"); (void) close(DaemonSocket); @@ -260,7 +263,7 @@ getrequests() do { errno = 0; - lotherend = sizeof RealHostAddr; + lotherend = socksize; t = accept(DaemonSocket, (struct sockaddr *)&RealHostAddr, &lotherend); } while (t < 0 && errno == EINTR); @@ -299,7 +302,6 @@ getrequests() */ (void) setsignal(SIGCHLD, SIG_DFL); - OpMode = MD_SMTP; /* determine host name */ p = hostnamebyanyaddr(&RealHostAddr); @@ -613,7 +615,7 @@ gothostent: case AF_INET: bcopy(hp->h_addr, &addr.sin.sin_addr, - hp->h_length); + sizeof addr.sin.sin_addr); break; #endif @@ -639,9 +641,10 @@ gothostent: if (sp == NULL) { syserr("554 makeconnection: service \"smtp\" unknown"); - return (EX_OSERR); + port = htons(25); } - port = sp->s_port; + else + port = sp->s_port; } switch (addr.sa.sa_family) @@ -742,7 +745,7 @@ gothostent: case AF_INET: bcopy(hp->h_addr_list[i++], &addr.sin.sin_addr, - hp->h_length); + sizeof addr.sin.sin_addr); break; #endif @@ -846,7 +849,7 @@ myhostname(hostbuf, size) ** Sets RealHostName to the name of the host at the other end. */ -#ifdef IDENTPROTO +#if IDENTPROTO static jmp_buf CtxAuthTimeout; @@ -865,7 +868,7 @@ getauthinfo(fd) SOCKADDR fa; int falen; register char *p; -#ifdef IDENTPROTO +#if IDENTPROTO SOCKADDR la; int lalen; register struct servent *sp; @@ -878,7 +881,8 @@ getauthinfo(fd) extern char RealUserName[]; /* main.c */ falen = sizeof fa; - if (getpeername(fd, &fa.sa, &falen) < 0 || falen <= 0) + if (getpeername(fd, &fa.sa, &falen) < 0 || falen <= 0 || + fa.sa.sa_family == 0) { RealHostName = "localhost"; (void) sprintf(hbuf, "%s@localhost", RealUserName); @@ -891,7 +895,7 @@ getauthinfo(fd) RealHostName = newstr(p); RealHostAddr = fa; -#ifdef IDENTPROTO +#if IDENTPROTO lalen = sizeof la; if (fa.sa.sa_family != AF_INET || getsockname(fd, &la.sa, &lalen) < 0 || lalen <= 0 || @@ -1049,7 +1053,6 @@ host_map_lookup(map, name, av, statp) char *cp; int i; register STAB *s; - char *timeoutmsg = "Recipient domain nameserver timed out"; char hbuf[MAXNAME]; extern struct hostent *gethostbyaddr(); extern int h_errno; @@ -1069,7 +1072,11 @@ host_map_lookup(map, name, av, statp) h_errno = s->s_namecanon.nc_herrno; *statp = s->s_namecanon.nc_stat; if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL) - CurEnv->e_message = newstr(timeoutmsg); + { + sprintf(hbuf, "%s: Name server timeout", + shortenstring(name, 33)); + CurEnv->e_message = newstr(hbuf); + } return s->s_namecanon.nc_cname; } @@ -1109,9 +1116,11 @@ host_map_lookup(map, name, av, statp) case TRY_AGAIN: if (UseNameServer) { - message(timeoutmsg); + sprintf(hbuf, "%s: Name server timeout", + shortenstring(name, 33)); + message("%s", hbuf); if (CurEnv->e_message == NULL) - CurEnv->e_message = newstr(timeoutmsg); + CurEnv->e_message = newstr(hbuf); } *statp = EX_TEMPFAIL; break; @@ -1200,6 +1209,7 @@ anynet_ntoa(sap) switch (sap->sa.sa_family) { #ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/ +#ifdef NETUNIX case AF_UNIX: if (sap->sunix.sun_path[0] != '\0') sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path); @@ -1207,6 +1217,7 @@ anynet_ntoa(sap) sprintf(buf, "[UNIX: localhost]"); return buf; #endif +#endif #ifdef NETINET case AF_INET: diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c index 62d6b8812e4..d627395bee9 100644 --- a/usr.sbin/sendmail/src/deliver.c +++ b/usr.sbin/sendmail/src/deliver.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 8.37 (Berkeley) 10/29/93"; +static char sccsid[] = "@(#)deliver.c 8.62 (Berkeley) 1/12/94"; #endif /* not lint */ #include "sendmail.h" @@ -46,6 +46,8 @@ static char sccsid[] = "@(#)deliver.c 8.37 (Berkeley) 10/29/93"; extern int h_errno; #endif +extern char SmtpError[]; + /* ** SENDALL -- actually send all the messages. ** @@ -82,13 +84,15 @@ sendall(e, mode) ** addresses to be sent. */ - if (bitset(EF_FATALERRS, e->e_flags) && OpMode == MD_SMTP) + if (bitset(EF_FATALERRS, e->e_flags) && + (OpMode == MD_SMTP || OpMode == MD_DAEMON)) { e->e_flags |= EF_CLRQUEUE; return; } /* determine actual delivery mode */ + CurrentLA = getla(); if (mode == SM_DEFAULT) { mode = e->e_sendmode; @@ -333,7 +337,8 @@ sendenvelope(e, mode) ** addresses to be sent. */ - if (bitset(EF_FATALERRS, e->e_flags) && OpMode == MD_SMTP) + if (bitset(EF_FATALERRS, e->e_flags) && + (OpMode == MD_SMTP || OpMode == MD_DAEMON)) { e->e_flags |= EF_CLRQUEUE; return; @@ -447,10 +452,15 @@ sendenvelope(e, mode) e->e_to = q->q_paddr; if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) { - message("deliverable: mailer %s, host %s, user %s", - q->q_mailer->m_name, - q->q_host, - q->q_user); + if (q->q_host != NULL && q->q_host[0] != '\0') + message("deliverable: mailer %s, host %s, user %s", + q->q_mailer->m_name, + q->q_host, + q->q_user); + else + message("deliverable: mailer %s, user %s", + q->q_mailer->m_name, + q->q_user); } } else if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) @@ -589,7 +599,6 @@ deliver(e, firstto) char buf[MAXNAME]; char rpathbuf[MAXNAME]; /* translated return path */ extern int checkcompat(); - extern char SmtpError[]; errno = 0; if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags)) @@ -597,7 +606,8 @@ deliver(e, firstto) #ifdef NAMED_BIND /* unless interactive, try twice, over a minute */ - if (OpMode == MD_DAEMON || OpMode == MD_SMTP) { + if (OpMode == MD_DAEMON || OpMode == MD_SMTP) + { _res.retrans = 30; _res.retry = 2; } @@ -759,7 +769,9 @@ deliver(e, firstto) } /* compute effective uid/gid when sending */ - if (to->q_mailer == ProgMailer) + /* XXX perhaps this should be to->q_mailer != LocalMailer ?? */ + /* XXX perhaps it should be a mailer flag? */ + if (to->q_mailer == ProgMailer || to->q_mailer == FileMailer) ctladdr = getctladdr(to); user = to->q_user; @@ -831,10 +843,8 @@ deliver(e, firstto) if (m == FileMailer) { - ADDRESS *caddr = getctladdr(to); - - rcode = mailfile(user, caddr, e); - giveresponse(rcode, m, NULL, caddr, e); + rcode = mailfile(user, ctladdr, e); + giveresponse(rcode, m, NULL, ctladdr, e); if (rcode == EX_OK) to->q_flags |= QSENT; continue; @@ -905,8 +915,10 @@ deliver(e, firstto) ** If we are running SMTP, we just need to clean up. */ - if (ctladdr == NULL && m != ProgMailer) + /*XXX this seems a bit wierd */ + if (ctladdr == NULL && bitset(QGOODUID, e->e_from.q_flags)) ctladdr = &e->e_from; + #ifdef NAMED_BIND if (ConfigLevel < 2) _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ @@ -961,12 +973,19 @@ deliver(e, firstto) register int i; register u_short port; + if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0') + { + syserr("null host name for %s mailer", m->m_mailer); + rcode = EX_CONFIG; + goto give_up; + } + CurHostName = pv[1]; curhost = hostsignature(m, pv[1], e); if (curhost == NULL || curhost[0] == '\0') { - syserr("null signature"); + syserr("null host signature for %s", pv[1]); rcode = EX_OSERR; goto give_up; } @@ -1153,6 +1172,7 @@ tryhost: if (ctladdr == NULL || ctladdr->q_uid == 0) { (void) initgroups(DefUser, DefGid); + (void) setgid(DefGid); (void) setuid(DefUid); } else @@ -1160,6 +1180,7 @@ tryhost: (void) initgroups(ctladdr->q_ruser? ctladdr->q_ruser: ctladdr->q_user, ctladdr->q_gid); + (void) setgid(ctladdr->q_gid); (void) setuid(ctladdr->q_uid); } } @@ -1202,7 +1223,7 @@ tryhost: } (void) close(rpvect[1]); } - else if (OpMode == MD_SMTP || HoldErrs) + else if (OpMode == MD_SMTP || OpMode == MD_DAEMON || HoldErrs) { /* put mailer output in transcript */ if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0) @@ -1333,7 +1354,7 @@ tryhost: rcode, mci->mci_state, firstsig); rcode = EX_SOFTWARE; } - else if (rcode == EX_TEMPFAIL && *curhost != '\0') + else if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0') { /* try next MX site */ goto tryhost; @@ -1403,7 +1424,7 @@ tryhost: if (!bitset(MCIF_CACHED, mci->mci_flags)) smtpquit(m, mci, e); } - if (rcode != EX_OK && *curhost != '\0') + if (rcode != EX_OK && curhost != NULL && *curhost != '\0') { /* try next MX site */ goto tryhost; @@ -1500,12 +1521,21 @@ markfailure(e, q, rcode) { char buf[MAXLINE]; - if (rcode == EX_OK) - return; - else if (rcode == EX_TEMPFAIL) + switch (rcode) + { + case EX_OK: + break; + + case EX_TEMPFAIL: + case EX_IOERR: + case EX_OSERR: q->q_flags |= QQUEUEUP; - else if (rcode != EX_IOERR && rcode != EX_OSERR) + break; + + default: q->q_flags |= QBADADDR; + break; + } } /* ** ENDMAILER -- Wait for mailer to terminate. @@ -1537,9 +1567,9 @@ endmailer(mci, e, pv) /* close any connections */ if (mci->mci_in != NULL) - (void) xfclose(mci->mci_in, pv[0], "mci_in"); + (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in"); if (mci->mci_out != NULL) - (void) xfclose(mci->mci_out, pv[0], "mci_out"); + (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out"); mci->mci_in = mci->mci_out = NULL; mci->mci_state = MCIS_CLOSED; @@ -1562,10 +1592,11 @@ endmailer(mci, e, pv) } /* it died a horrid death */ - syserr("mailer %s died with signal %o", pv[0], st); + syserr("451 mailer %s died with signal %o", + mci->mci_mailer->m_name, st); /* log the arguments */ - if (e->e_xfp != NULL) + if (pv != NULL && e->e_xfp != NULL) { register char **av; @@ -1647,8 +1678,6 @@ giveresponse(stat, m, mci, ctladdr, e) else { #ifdef SMTP - extern char SmtpError[]; - statmsg = SmtpError; #else /* SMTP */ statmsg = NULL; @@ -1710,7 +1739,7 @@ giveresponse(stat, m, mci, ctladdr, e) if (stat != EX_TEMPFAIL) setstat(stat); - if (stat != EX_OK) + if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL)) { if (e->e_message != NULL) free(e->e_message); @@ -1724,6 +1753,10 @@ giveresponse(stat, m, mci, ctladdr, e) /* ** LOGDELIVERY -- log the delivery in the system log ** +** Care is taken to avoid logging lines that are too long, because +** some versions of syslog have an unfortunate proclivity for core +** dumping. This is a hack, to be sure, that is at best empirical. +** ** Parameters: ** m -- the mailer info. Can be NULL for initial queue. ** mci -- the mailer connection info -- can be NULL if the @@ -1748,13 +1781,16 @@ logdelivery(m, mci, stat, ctladdr, e) { # ifdef LOG register char *bp; + register char *p; + int l; char buf[512]; +# if (SYSLOG_BUFSIZE) >= 256 bp = buf; if (ctladdr != NULL) { strcpy(bp, ", ctladdr="); - strcat(bp, ctladdr->q_paddr); + strcat(bp, shortenstring(ctladdr->q_paddr, 83)); bp += strlen(bp); if (bitset(QGOODUID, ctladdr->q_flags)) { @@ -1799,9 +1835,111 @@ logdelivery(m, mci, stat, ctladdr, e) (void) strcat(bp, p); } } + bp += strlen(bp); + +#define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4) +#if (STATLEN) < 63 +# undef STATLEN +# define STATLEN 63 +#endif +#if (STATLEN) > 203 +# undef STATLEN +# define STATLEN 203 +#endif + + if ((bp - buf) > (sizeof buf - ((STATLEN) + 20))) + { + /* desperation move -- truncate data */ + bp = buf + sizeof buf - ((STATLEN) + 17); + strcpy(bp, "..."); + bp += 3; + } + + (void) strcpy(bp, ", stat="); + bp += strlen(bp); + + (void) strcpy(bp, shortenstring(stat, (STATLEN))); - syslog(LOG_INFO, "%s: to=%s%s, stat=%s", - e->e_id, e->e_to, buf, stat); + l = SYSLOG_BUFSIZE - 100 - strlen(buf); + p = e->e_to; + while (strlen(p) >= l) + { + register char *q = strchr(p + l, ','); + + if (q == NULL) + break; + syslog(LOG_INFO, "%s: to=%.*s [more]%s", + e->e_id, ++q - p, p, buf); + p = q; + } + syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf); + +# else /* we have a very short log buffer size */ + + l = SYSLOG_BUFSIZE - 80; + p = e->e_to; + while (strlen(p) >= l) + { + register char *q = strchr(p + l, ','); + + if (q == NULL) + break; + syslog(LOG_INFO, "%s: to=%.*s [more]", + e->e_id, ++q - p, p); + p = q; + } + syslog(LOG_INFO, "%s: to=%s", e->e_id, p); + + if (ctladdr != NULL) + { + bp = buf; + strcpy(buf, "ctladdr="); + bp += strlen(buf); + strcpy(bp, shortenstring(ctladdr->q_paddr, 83)); + bp += strlen(buf); + if (bitset(QGOODUID, ctladdr->q_flags)) + { + (void) sprintf(bp, " (%d/%d)", + ctladdr->q_uid, ctladdr->q_gid); + bp += strlen(bp); + } + syslog(LOG_INFO, "%s: %s", e->e_id, buf); + } + bp = buf; + sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE)); + bp += strlen(bp); + + if (m != NULL) + { + sprintf(bp, ", mailer=%s", m->m_name); + bp += strlen(bp); + } + + if (mci != NULL && mci->mci_host != NULL) + { +# ifdef DAEMON + extern SOCKADDR CurHostAddr; +# endif + + sprintf(bp, ", relay=%s", mci->mci_host); + +# ifdef DAEMON + (void) strcat(bp, " ("); + (void) strcat(bp, anynet_ntoa(&CurHostAddr)); + (void) strcat(bp, ")"); +# endif + } + else + { + char *p = macvalue('h', e); + + if (p != NULL && p[0] != '\0') + sprintf(bp, ", relay=%s", p); + } + syslog(LOG_INFO, "%s: %s", e->e_id, buf); + + syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63)); +# endif /* short log buffer */ # endif /* LOG */ } /* @@ -2013,9 +2151,7 @@ mailfile(filename, ctladdr, e) if (bitset(0111, stb.st_mode)) exit(EX_CANTCREAT); - if (ctladdr == NULL) - ctladdr = &e->e_from; - else + if (ctladdr != NULL) { /* ignore setuid and setgid bits */ mode &= ~(S_ISGID|S_ISUID); @@ -2034,7 +2170,7 @@ mailfile(filename, ctladdr, e) if (!bitset(S_ISGID, mode) || setgid(stb.st_gid) < 0) { - if (ctladdr->q_uid == 0) + if (ctladdr == NULL || ctladdr->q_uid == 0) { (void) initgroups(DefUser, DefGid); } @@ -2047,7 +2183,7 @@ mailfile(filename, ctladdr, e) } if (!bitset(S_ISUID, mode) || setuid(stb.st_uid) < 0) { - if (ctladdr->q_uid == 0) + if (ctladdr == NULL || ctladdr->q_uid == 0) (void) setuid(DefUid); else (void) setuid(ctladdr->q_uid); @@ -2174,7 +2310,6 @@ hostsignature(m, host, e) if (nmx <= 0) { register MCI *mci; - extern int errno; /* update the connection info for this host */ mci = mci_get(hp, m); diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c index 496859aaa65..ab2f7ff5c4d 100644 --- a/usr.sbin/sendmail/src/domain.c +++ b/usr.sbin/sendmail/src/domain.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef NAMED_BIND -static char sccsid[] = "@(#)domain.c 8.8 (Berkeley) 9/29/93 (with name server)"; +static char sccsid[] = "@(#)domain.c 8.10 (Berkeley) 12/21/93 (with name server)"; #else -static char sccsid[] = "@(#)domain.c 8.8 (Berkeley) 9/29/93 (without name server)"; +static char sccsid[] = "@(#)domain.c 8.10 (Berkeley) 12/21/93 (without name server)"; #endif #endif /* not lint */ @@ -158,6 +158,12 @@ getmxrr(host, mxhosts, droplocalhost, rcode) case HOST_NOT_FOUND: /* the host just doesn't exist */ *rcode = EX_NOHOST; + + if (!UseNameServer) + { + /* might exist in /etc/hosts */ + goto punt; + } break; case TRY_AGAIN: @@ -419,8 +425,10 @@ getcanonname(host, hbsize, trymx) bool gotmx; int qtype; int loopcnt; + char *xp; char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; + extern char *gethostalias(); if (tTd(8, 2)) printf("getcanonname(%s)\n", host); @@ -444,6 +452,20 @@ cnameloop: if (*cp == '.') n++; + if (n == 0 && (xp = gethostalias(host)) != NULL) + { + if (loopcnt++ > MAXCNAMEDEPTH) + { + syserr("loop in ${HOSTALIASES} file"); + } + else + { + strncpy(host, xp, hbsize); + host[hbsize - 1] = '\0'; + goto cnameloop; + } + } + dp = searchlist; if (n > 0) *dp++ = ""; @@ -637,6 +659,54 @@ cnameloop: return TRUE; } + +char * +gethostalias(host) + char *host; +{ + char *fname; + FILE *fp; + register char *p; + char buf[MAXLINE]; + static char hbuf[MAXDNAME]; + + fname = getenv("HOSTALIASES"); + if (fname == NULL || (fp = fopen(fname, "r")) == NULL) + return NULL; + while (fgets(buf, sizeof buf, fp) != NULL) + { + for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++) + continue; + if (*p == 0) + { + /* syntax error */ + continue; + } + *p++ = '\0'; + if (strcasecmp(buf, host) == 0) + break; + } + + if (feof(fp)) + { + /* no match */ + fclose(fp); + return NULL; + } + + /* got a match; extract the equivalent name */ + while (*p != '\0' && isascii(*p) && isspace(*p)) + p++; + host = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + *p = '\0'; + strncpy(hbuf, host, sizeof hbuf - 1); + hbuf[sizeof hbuf - 1] = '\0'; + return hbuf; +} + + #else /* not NAMED_BIND */ #include diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c index 29879575a6e..3048ac3dc3a 100644 --- a/usr.sbin/sendmail/src/envelope.c +++ b/usr.sbin/sendmail/src/envelope.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.17 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)envelope.c 8.28 (Berkeley) 1/9/94"; #endif /* not lint */ #include "sendmail.h" @@ -110,7 +110,7 @@ dropenvelope(e) { printf("dropenvelope %x: id=", e); xputs(e->e_id); - printf(", flags=%o\n", e->e_flags); + printf(", flags=0x%x\n", e->e_flags); if (tTd(50, 10)) { printf("sendq="); @@ -123,10 +123,13 @@ dropenvelope(e) return; #ifdef LOG + if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) + logsender(e, NULL); if (LogLevel > 84) - syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d", + syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d", id, e->e_flags, getpid()); #endif /* LOG */ + e->e_flags &= ~EF_LOGSENDER; /* post statistics */ poststats(StatFile); @@ -214,6 +217,7 @@ dropenvelope(e) (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e); (void) returntosender("Return receipt", rlist, FALSE, e); + e->e_flags &= ~EF_SENDRECEIPT; } /* @@ -272,9 +276,6 @@ dropenvelope(e) (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); e->e_dfp = NULL; e->e_id = e->e_df = NULL; -#ifdef XDEBUG - checkfd012("dropenvelope"); -#endif } /* ** CLEARENVELOPE -- clear an envelope without unlocking @@ -583,7 +584,8 @@ setsender(from, e, delimptr, internal) ** Username can return errno != 0 on non-errors. */ - if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP) + if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || + OpMode == MD_DAEMON) realname = from; if (realname == NULL || realname[0] == '\0') realname = username(); @@ -619,7 +621,7 @@ setsender(from, e, delimptr, internal) } syslog(LOG_NOTICE, "setsender: %s: invalid or unparseable, received from %s", - from, p); + shortenstring(from, 83), p); } # endif /* LOG */ if (from != NULL) @@ -681,7 +683,7 @@ setsender(from, e, delimptr, internal) ** We have an alternate address for the sender */ - pvp = prescan(p, '\0', pvpbuf, NULL); + pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL); } # endif /* USERDB */ } @@ -700,6 +702,7 @@ setsender(from, e, delimptr, internal) /* extract user and group id */ e->e_from.q_uid = pw->pw_uid; e->e_from.q_gid = pw->pw_gid; + e->e_from.q_flags |= QGOODUID; /* extract full name from passwd file */ if (FullName == NULL && pw->pw_gecos != NULL && @@ -714,12 +717,13 @@ setsender(from, e, delimptr, internal) if (FullName != NULL && !internal) define('x', FullName, e); } - else if (!internal) + else if (!internal && OpMode != MD_DAEMON) { if (e->e_from.q_home == NULL) e->e_from.q_home = getenv("HOME"); e->e_from.q_uid = RealUid; e->e_from.q_gid = RealGid; + e->e_from.q_flags |= QGOODUID; } /* @@ -728,7 +732,7 @@ setsender(from, e, delimptr, internal) */ if (pvp == NULL) - pvp = prescan(from, '\0', pvpbuf, NULL); + pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); if (pvp == NULL) { /* don't need to give error -- prescan did that already */ @@ -738,9 +742,9 @@ setsender(from, e, delimptr, internal) # endif finis(); } - (void) rewrite(pvp, 3, e); - (void) rewrite(pvp, 1, e); - (void) rewrite(pvp, 4, e); + (void) rewrite(pvp, 3, 0, e); + (void) rewrite(pvp, 1, 0, e); + (void) rewrite(pvp, 4, 0, e); bp = buf + 1; cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); if (*bp == '@') @@ -753,7 +757,7 @@ setsender(from, e, delimptr, internal) define('f', e->e_sender, e); /* save the domain spec if this mailer wants it */ - if (!internal && e->e_from.q_mailer != NULL && + if (e->e_from.q_mailer != NULL && bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) { extern char **copyplist(); diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c index 64ae3eb6660..60e78e3b7c5 100644 --- a/usr.sbin/sendmail/src/err.c +++ b/usr.sbin/sendmail/src/err.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)err.c 8.14 (Berkeley) 10/29/93"; +static char sccsid[] = "@(#)err.c 8.19 (Berkeley) 1/8/94"; #endif /* not lint */ # include "sendmail.h" @@ -159,8 +159,6 @@ usrerr(fmt, va_alist) #endif { VA_LOCAL_DECL - extern char SuprErrs; - extern int errno; if (SuprErrs) return; @@ -287,13 +285,13 @@ putoutmsg(msg, holdmsg) msg[0] = '5'; (void) fflush(stdout); - if (OpMode == MD_SMTP) + if (OpMode == MD_SMTP || OpMode == MD_DAEMON) fprintf(OutChannel, "%s\r\n", msg); else fprintf(OutChannel, "%s\n", &msg[4]); if (TrafficLogFile != NULL) fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), - OpMode == MD_SMTP ? msg : &msg[4]); + (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]); if (msg[3] == ' ') (void) fflush(OutChannel); if (!ferror(OutChannel)) @@ -449,6 +447,7 @@ const char * errstring(errno) int errno; { + char *dnsmsg; static char buf[MAXLINE]; # ifndef ERRLIST_PREDEFINED extern char *sys_errlist[]; @@ -458,16 +457,16 @@ errstring(errno) extern char *SmtpPhase; # endif /* SMTP */ -# ifdef DAEMON -# ifdef ETIMEDOUT /* ** Handle special network error codes. ** ** These are 4.2/4.3bsd specific; they should be in daemon.c. */ + dnsmsg = NULL; switch (errno) { +# if defined(DAEMON) && defined(ETIMEDOUT) case ETIMEDOUT: case ECONNRESET: (void) strcpy(buf, sys_errlist[errno]); @@ -494,26 +493,45 @@ errstring(errno) break; (void) sprintf(buf, "Connection refused by %s", CurHostName); return (buf); +# endif case EOPENTIMEOUT: return "Timeout on file open"; # ifdef NAMED_BIND case HOST_NOT_FOUND + E_DNSBASE: - return ("Name server: host not found"); + dnsmsg = "host not found"; + break; case TRY_AGAIN + E_DNSBASE: - return ("Name server: host name lookup failure"); + dnsmsg = "host name lookup failure"; + break; case NO_RECOVERY + E_DNSBASE: - return ("Name server: non-recoverable error"); + dnsmsg = "non-recoverable error"; + break; case NO_DATA + E_DNSBASE: - return ("Name server: no data known for name"); + dnsmsg = "no data known"; + break; # endif + + case EPERM: + /* SunOS gives "Not owner" -- this is the POSIX message */ + return "Operation not permitted"; + } + + if (dnsmsg != NULL) + { + (void) strcpy(buf, "Name server: "); + if (CurHostName != NULL) + { + (void) strcat(buf, CurHostName); + (void) strcat(buf, ": "); + } + (void) strcat(buf, dnsmsg); + return buf; } -# endif -# endif if (errno > 0 && errno < sys_nerr) return (sys_errlist[errno]); diff --git a/usr.sbin/sendmail/src/headers.c b/usr.sbin/sendmail/src/headers.c index 1fea6396d80..b05876bf20e 100644 --- a/usr.sbin/sendmail/src/headers.c +++ b/usr.sbin/sendmail/src/headers.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)headers.c 8.13 (Berkeley) 10/24/93"; +static char sccsid[] = "@(#)headers.c 8.22 (Berkeley) 1/13/94"; #endif /* not lint */ # include @@ -371,6 +371,11 @@ eatheader(e, full) else define('u', NULL, e); + /* full name of from person */ + p = hvalue("full-name", e); + if (p != NULL) + define('x', p, e); + if (tTd(32, 1)) printf("----- collected header -----\n"); msgid = ""; @@ -395,7 +400,11 @@ eatheader(e, full) } if (tTd(32, 1)) - printf("%s: %s\n", h->h_field, h->h_value); + { + printf("%s: ", h->h_field); + xputs(h->h_value); + printf("\n"); + } /* count the number of times it has been processed */ if (bitset(H_TRACE, h->h_flags)) @@ -453,11 +462,6 @@ eatheader(e, full) - e->e_class * WkClassFact + e->e_nrcpts * WkRecipFact; - /* full name of from person */ - p = hvalue("full-name", e); - if (p != NULL) - define('x', p, e); - /* date message originated */ p = hvalue("posted-date", e); if (p == NULL) @@ -471,48 +475,97 @@ eatheader(e, full) # ifdef LOG if (full && LogLevel > 4) + logsender(e, msgid); +# endif /* LOG */ + e->e_flags &= ~EF_LOGSENDER; +} + /* +** LOGSENDER -- log sender information +** +** Parameters: +** e -- the envelope to log +** msgid -- the message id +** +** Returns: +** none +*/ + +logsender(e, msgid) + register ENVELOPE *e; + char *msgid; +{ + char *name; + register char *sbp; + register char *p; + char hbuf[MAXNAME]; + char sbuf[MAXLINE]; + + if (bitset(EF_RESPONSE, e->e_flags)) + name = "[RESPONSE]"; + else if ((name = macvalue('_', e)) != NULL) + ; + else if (RealHostName[0] == '[') + name = RealHostName; + else { - char *name; - register char *sbp; - char hbuf[MAXNAME]; - char sbuf[MAXLINE]; - - if (bitset(EF_RESPONSE, e->e_flags)) - name = "[RESPONSE]"; - else if ((name = macvalue('_', e)) != NULL) - ; - else if (RealHostName[0] == '[') - name = RealHostName; - else + name = hbuf; + (void) sprintf(hbuf, "%.80s", RealHostName); + if (RealHostAddr.sa.sa_family != 0) { - name = hbuf; - (void) sprintf(hbuf, "%.80s", RealHostName); - if (RealHostAddr.sa.sa_family != 0) - { - p = &hbuf[strlen(hbuf)]; - (void) sprintf(p, " (%s)", - anynet_ntoa(&RealHostAddr)); - } + p = &hbuf[strlen(hbuf)]; + (void) sprintf(p, " (%s)", + anynet_ntoa(&RealHostAddr)); } + } - /* some versions of syslog only take 5 printf args */ - sbp = sbuf; - sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d, msgid=%.100s", - e->e_from.q_paddr, e->e_msgsize, e->e_class, - e->e_msgpriority, e->e_nrcpts, msgid); + /* some versions of syslog only take 5 printf args */ +# if (SYSLOG_BUFSIZE) >= 256 + sbp = sbuf; + sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d", + e->e_from.q_paddr, e->e_msgsize, e->e_class, + e->e_msgpriority, e->e_nrcpts); + sbp += strlen(sbp); + if (msgid != NULL) + { + sprintf(sbp, ", msgid=%.100s", msgid); sbp += strlen(sbp); - if (e->e_bodytype != NULL) - { - (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype); - sbp += strlen(sbp); - } - p = macvalue('r', e); - if (p != NULL) - (void) sprintf(sbp, ", proto=%.20s", p); - syslog(LOG_INFO, "%s: %s, relay=%s", - e->e_id, sbuf, name); } -# endif /* LOG */ + if (e->e_bodytype != NULL) + { + (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + (void) sprintf(sbp, ", proto=%.20s", p); + syslog(LOG_INFO, "%s: %s, relay=%s", + e->e_id, sbuf, name); + +# else /* short syslog buffer */ + + syslog(LOG_INFO, "%s: from=%s", + e->e_id, shortenstring(e->e_from.q_paddr, 83)); + syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d", + e->e_id, e->e_msgsize, e->e_class, + e->e_msgpriority, e->e_nrcpts); + if (msgid != NULL) + syslog(LOG_INFO, "%s: msgid=%s", e->e_id, msgid); + sbp = sbuf; + sprintf(sbp, "%s:", e->e_id); + sbp += strlen(sbp); + if (e->e_bodytype != NULL) + { + sprintf(sbp, " bodytype=%s,", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + { + sprintf(sbp, " proto=%s,", p); + sbp += strlen(sbp); + } + syslog(LOG_INFO, "%s relay=%s", sbuf, name); +# endif } /* ** PRIENCODE -- encode external priority names into internal values. @@ -639,7 +692,7 @@ crackaddr(addr) } /* check for quoted strings */ - if (c == '"') + if (c == '"' && cmtlev <= 0) { qmode = !qmode; if (copylev > 0 && !skipping) @@ -683,11 +736,10 @@ crackaddr(addr) else if (c == ')') { /* syntax error: unmatched ) */ - if (!skipping) + if (copylev > 0 && !skipping) bp--; } - /* check for characters that may have to be quoted */ if (strchr(".'@,;:\\()[]", c) != NULL) { @@ -864,19 +916,24 @@ putheader(fp, m, e) printf(" (skipped (resent))\n"); continue; } - if (tTd(34, 11)) - printf("\n"); + /* macro expand value if generated internally */ p = h->h_value; if (bitset(H_DEFAULT, h->h_flags)) { - /* macro expand value if generated internally */ expand(p, buf, &buf[sizeof buf], e); p = buf; if (p == NULL || *p == '\0') + { + if (tTd(34, 11)) + printf(" (skipped -- null value)\n"); continue; + } } + if (tTd(34, 11)) + printf("\n"); + if (bitset(H_FROM|H_RCPT, h->h_flags)) { /* address field */ @@ -980,7 +1037,8 @@ commaize(h, p, fp, oldstyle, m, e) auto char *oldp; char pvpbuf[PSBUFSIZE]; - (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, &oldp); + (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, + sizeof pvpbuf, &oldp); p = oldp; /* look to see if we have an at sign */ diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c index 5db6935d629..d05f13da46c 100644 --- a/usr.sbin/sendmail/src/main.c +++ b/usr.sbin/sendmail/src/main.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.33 (Berkeley) 10/24/93"; +static char sccsid[] = "@(#)main.c 8.46 (Berkeley) 1/9/94"; #endif /* not lint */ #define _DEFINE @@ -155,6 +155,7 @@ main(argc, argv, envp) extern char *getcfname(); extern char *optarg; extern char **environ; + extern void dumpstate(); /* ** Check to see if we reentered. @@ -170,7 +171,12 @@ main(argc, argv, envp) reenter = TRUE; /* do machine-dependent initializations */ - init_md(); + init_md(argc, argv); + + /* arrange to dump state on signal */ +#ifdef SIGUSR1 + setsignal(SIGUSR1, dumpstate); +#endif /* in 4.4BSD, the table can be huge; impose a reasonable limit */ DtableSize = getdtsize(); @@ -253,12 +259,15 @@ main(argc, argv, envp) #if defined(__osf__) || defined(_AIX3) # define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:x" -#else -# if defined(ultrix) -# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mno:p:q:r:sTtvX:" -# else -# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:" -# endif +#endif +#if defined(ultrix) +# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mno:p:q:r:sTtvX:" +#endif +#if defined(NeXT) +# define OPTIONS "B:b:C:cd:e:F:f:h:IimnOo:p:q:r:sTtvX:" +#endif +#ifndef OPTIONS +# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:" #endif while ((j = getopt(argc, argv, OPTIONS)) != EOF) { @@ -334,10 +343,9 @@ main(argc, argv, envp) if (tTd(0, 4)) printf("canonical name: %s\n", jbuf); - p = newstr(jbuf); define('w', newstr(jbuf), CurEnv); /* must be new string */ - define('j', p, CurEnv); - setclass('w', p); + define('j', newstr(jbuf), CurEnv); + setclass('w', jbuf); p = strchr(jbuf, '.'); if (p != NULL) @@ -360,6 +368,8 @@ main(argc, argv, envp) p = utsname.nodename; else { + if (tTd(0, 22)) + printf("uname failed (%s)\n", errstring(errno)); makelower(jbuf); p = jbuf; } @@ -367,6 +377,7 @@ main(argc, argv, envp) printf("UUCP nodename: %s\n", p); p = newstr(p); define('k', p, CurEnv); + setclass('k', p); setclass('w', p); } while (av != NULL && *av != NULL) @@ -586,6 +597,10 @@ main(argc, argv, envp) case 'x': /* random flag that OSF/1 & AIX mailx passes */ break; # endif +# if defined(NeXT) + case 'O': /* random flag that NeXT Mail.app passes */ + break; +# endif default: ExitStat = EX_USAGE; @@ -601,6 +616,9 @@ main(argc, argv, envp) ** Extract special fields for local use. */ +#ifdef XDEBUG + checkfd012("before readcf"); +#endif readcf(getcfname(), safecf, CurEnv); if (tTd(0, 1)) @@ -761,6 +779,10 @@ main(argc, argv, envp) exit(ExitStat); } +#ifdef XDEBUG + checkfd012("before main() initmaps"); +#endif + /* ** Do operation-mode-dependent initialization. */ @@ -899,7 +921,8 @@ main(argc, argv, envp) { char pvpbuf[PSBUFSIZE]; - pvp = prescan(++p, ',', pvpbuf, &delimptr); + pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, + &delimptr); if (pvp == NULL) continue; p = q; @@ -907,7 +930,7 @@ main(argc, argv, envp) { int stat; - stat = rewrite(pvp, atoi(p), CurEnv); + stat = rewrite(pvp, atoi(p), 0, CurEnv); if (stat != EX_OK) printf("== Ruleset %s status %d\n", p, stat); @@ -1005,7 +1028,7 @@ main(argc, argv, envp) ** commands. This will never return. */ - if (OpMode == MD_SMTP) + if (OpMode == MD_SMTP || OpMode == MD_DAEMON) smtp(CurEnv); # endif /* SMTP */ @@ -1325,7 +1348,8 @@ static void obsolete(argv) char *argv[]; { - char *ap; + register char *ap; + register char *op; while ((ap = *++argv) != NULL) { @@ -1333,10 +1357,18 @@ obsolete(argv) if (ap[0] != '-' || ap[1] == '-') return; + /* skip over options that do have a value */ + op = strchr(OPTIONS, ap[1]); + if (op != NULL && *++op == ':' && ap[2] == '\0' && + argv[1] != NULL && argv[1][0] != '-') + { + argv++; + continue; + } + /* If -C doesn't have an argument, use sendmail.cf. */ #define __DEFPATH "sendmail.cf" - if (ap[1] == 'C' && ap[2] == '\0' && - (argv[1] == NULL || argv[1][0] == '-')) + if (ap[1] == 'C' && ap[2] == '\0') { *argv = xalloc(sizeof(__DEFPATH) + 2); argv[0][0] = '-'; @@ -1345,13 +1377,11 @@ obsolete(argv) } /* If -q doesn't have an argument, run it once. */ - if (ap[1] == 'q' && ap[2] == '\0' && - (argv[1] == NULL || argv[1][0] == '-')) + if (ap[1] == 'q' && ap[2] == '\0') *argv = "-q0"; /* if -d doesn't have an argument, use 0-99.1 */ - if (ap[1] == 'd' && ap[2] == '\0' && - (argv[1] == NULL || !isdigit(argv[1][0]))) + if (ap[1] == 'd' && ap[2] == '\0') *argv = "-d0-99.1"; } } @@ -1397,3 +1427,40 @@ auth_warning(e, msg, va_alist) addheader("X-Authentication-Warning", buf, e); } } + /* +** DUMPSTATE -- dump state on user signal +** +** For debugging. +*/ + +void +dumpstate() +{ +#ifdef LOG + register char *j = macvalue('j', CurEnv); + register STAB *s; + + syslog(LOG_DEBUG, "--- dumping state on user signal: $j = %s ---", j); + s = stab(j, ST_CLASS, ST_FIND); + if (s == NULL || !bitnset('w', s->s_class)) + syslog(LOG_DEBUG, "*** $j not in $=w ***"); + syslog(LOG_DEBUG, "--- open file descriptors: ---"); + printopenfds(TRUE); + syslog(LOG_DEBUG, "--- connection cache: ---"); + mci_dump_all(TRUE); + if (RewriteRules[89] != NULL) + { + 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); + for (pvp = pv; *pvp != NULL; pvp++) + syslog(LOG_DEBUG, "%s", *pvp); + } + syslog(LOG_DEBUG, "--- end of state dump ---"); +#endif +} diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c index 0ee24f81d70..7a3bdc0c002 100644 --- a/usr.sbin/sendmail/src/map.c +++ b/usr.sbin/sendmail/src/map.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)map.c 8.17 (Berkeley) 10/15/93"; +static char sccsid[] = "@(#)map.c 8.20 (Berkeley) 12/11/93"; #endif /* not lint */ #include "sendmail.h" @@ -336,7 +336,15 @@ initmaps(rebuild, e) checkfd012("entering initmaps"); #endif CurEnv = e; - stabapply(map_init, rebuild); + if (rebuild) + { + stabapply(map_init, 1); + stabapply(map_init, 2); + } + else + { + stabapply(map_init, 0); + } #ifdef XDEBUG checkfd012("exiting initmaps"); #endif @@ -358,10 +366,19 @@ map_init(s, rebuild) return; if (tTd(38, 2)) - printf("map_init(%s:%s)\n", + printf("map_init(%s:%s, %d)\n", map->map_class->map_cname == NULL ? "NULL" : map->map_class->map_cname, - map->map_file == NULL ? "NULL" : map->map_file); + map->map_file == NULL ? "NULL" : map->map_file, + rebuild); + + if (rebuild == (bitset(MF_ALIAS, map->map_mflags) && + bitset(MCF_REBUILDABLE, map->map_class->map_cflags) ? 1 : 2)) + { + if (tTd(38, 3)) + printf("\twrong pass\n"); + return; + } /* if already open, close it (for nested open) */ if (bitset(MF_OPEN, map->map_mflags)) @@ -370,18 +387,16 @@ map_init(s, rebuild) map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); } - if (rebuild) + if (rebuild == 2) { - if (bitset(MF_ALIAS, map->map_mflags) && - bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) - rebuildaliases(map, FALSE); + rebuildaliases(map, FALSE); } else { if (map->map_class->map_open(map, O_RDONLY)) { if (tTd(38, 4)) - printf("%s:%s: valid\n", + printf("\t%s:%s: valid\n", map->map_class->map_cname == NULL ? "NULL" : map->map_class->map_cname, map->map_file == NULL ? "NULL" : @@ -389,7 +404,7 @@ map_init(s, rebuild) map->map_mflags |= MF_OPEN; } else if (tTd(38, 4)) - printf("%s:%s: invalid: %s\n", + printf("\t%s:%s: invalid: %s\n", map->map_class->map_cname == NULL ? "NULL" : map->map_class->map_cname, map->map_file == NULL ? "NULL" : @@ -434,9 +449,22 @@ ndbm_map_open(map, mode) return FALSE; } map->map_db1 = (void *) dbm; - if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags)) - if (!aliaswait(map, ".pag", TRUE)) + if (mode == O_RDONLY) + { + if (bitset(MF_ALIAS, map->map_mflags) && + !aliaswait(map, ".pag", TRUE)) return FALSE; + } + else + { + int fd; + + /* exclusive lock for duration of rebuild */ + fd = dbm_dirfno((DBM *) map->map_db1); + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags) && + lockfile(fd, map->map_file, ".dir", LOCK_EX)) + map->map_mflags |= MF_LOCKED; + } if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0) map->map_mtime = st.st_mtime; return TRUE; @@ -559,7 +587,7 @@ ndbm_map_close(map) (void) sprintf(buf, "%010ld", curtime()); ndbm_map_store(map, "YP_LAST_MODIFIED", buf); - (void) myhostname(buf, sizeof buf); + (void) gethostname(buf, sizeof buf); ndbm_map_store(map, "YP_MASTER_NAME", buf); if (inclnull) @@ -1237,6 +1265,9 @@ impl_map_open(map, mode) #if defined(NEWDB) || defined(NDBM) if (Verbose) message("WARNING: cannot open alias database %s", map->map_file); +#else + if (mode != O_RDONLY) + usrerr("Cannot rebuild aliases: no database format defined"); #endif return stab_map_open(map, mode); diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c index 46f8c9596d8..68a98dd3a67 100644 --- a/usr.sbin/sendmail/src/mci.c +++ b/usr.sbin/sendmail/src/mci.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mci.c 8.6 (Berkeley) 10/23/93"; +static char sccsid[] = "@(#)mci.c 8.9 (Berkeley) 12/1/93"; #endif /* not lint */ #include "sendmail.h" @@ -275,6 +275,8 @@ mci_get(host, m) bzero(&CurHostAddr, sizeof CurHostAddr); #endif + if (m->m_mno < 0) + syserr("negative mno %d (%s)", m->m_mno, m->m_name); s = stab(host, ST_MCI + m->m_mno, ST_ENTER); mci = &s->s_mci; mci->mci_host = s->s_name; @@ -348,7 +350,7 @@ mci_dump(mci, logit) ctime(&mci->mci_lastuse)); printit: if (logit) - syslog(LOG_INFO, "%s", buf); + syslog(LOG_DEBUG, "%s", buf); else printf("%s\n", buf); } @@ -368,6 +370,9 @@ mci_dump_all(logit) { register int i; + if (MciCache == NULL) + return; + for (i = 0; i < MaxMciCache; i++) mci_dump(MciCache[i], logit); } diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c index ea8e180ebae..13274dab7c6 100644 --- a/usr.sbin/sendmail/src/parseaddr.c +++ b/usr.sbin/sendmail/src/parseaddr.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)parseaddr.c 8.17 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)parseaddr.c 8.29 (Berkeley) 1/5/94"; #endif /* not lint */ # include "sendmail.h" @@ -103,7 +103,7 @@ parseaddr(addr, a, flags, delim, delimptr, e) if (delimptr == NULL) delimptr = &delimptrbuf; - pvp = prescan(addr, delim, pvpbuf, delimptr); + pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr); if (pvp == NULL) { if (tTd(20, 1)) @@ -143,9 +143,9 @@ parseaddr(addr, a, flags, delim, delimptr, e) */ queueup = FALSE; - if (rewrite(pvp, 3, e) == EX_TEMPFAIL) + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) queueup = TRUE; - if (rewrite(pvp, 0, e) == EX_TEMPFAIL) + if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL) queueup = TRUE; @@ -308,6 +308,7 @@ allocaddr(a, flags, paddr) ** If '\t' then we are reading the .cf file. ** pvpbuf -- place to put the saved text -- note that ** the pointers are static. +** pvpbsize -- size of pvpbuf. ** delimptr -- if non-NULL, set to the location of the ** terminating delimiter. ** @@ -341,10 +342,34 @@ static short StateTab[NSTATES][NSTATES] = /*ONE*/ OPR, OPR, OPR, OPR, OPR, }; +/* token type table -- it gets modified with $o characters */ +static TokTypeTab[256] = +{ + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM,ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, +}; + +#define toktype(c) ((int) TokTypeTab[(c) & 0xff]) + + # define NOCHAR -1 /* signal nothing in lookahead token */ char ** -prescan(addr, delim, pvpbuf, delimptr) +prescan(addr, delim, pvpbuf, pvpbsize, delimptr) char *addr; char delim; char pvpbuf[]; @@ -362,8 +387,24 @@ prescan(addr, delim, pvpbuf, delimptr) int newstate; char *saveto = CurEnv->e_to; static char *av[MAXATOM+1]; + static char firsttime = TRUE; extern int errno; + if (firsttime) + { + /* initialize the token type table */ + char obuf[50]; + + firsttime = FALSE; + expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv); + strcat(obuf, DELIMCHARS); + for (p = obuf; *p != '\0'; p++) + { + if (TokTypeTab[*p & 0xff] == ATM) + TokTypeTab[*p & 0xff] = OPR; + } + } + /* make sure error messages don't have garbage on them */ errno = 0; @@ -393,9 +434,10 @@ prescan(addr, delim, pvpbuf, delimptr) if (c != NOCHAR && !bslashmode) { /* see if there is room */ - if (q >= &pvpbuf[PSBUFSIZE - 5]) + if (q >= &pvpbuf[pvpbsize - 5]) { usrerr("553 Address too long"); + returnnull: if (delimptr != NULL) *delimptr = p; CurEnv->e_to = saveto; @@ -527,10 +569,12 @@ prescan(addr, delim, pvpbuf, delimptr) if (avp >= &av[MAXATOM]) { syserr("553 prescan: too many tokens"); - if (delimptr != NULL) - *delimptr = p; - CurEnv->e_to = saveto; - return (NULL); + goto returnnull; + } + if (q - tok > MAXNAME) + { + syserr("553 prescan: token too long"); + goto returnnull; } *avp++ = tok; } @@ -546,50 +590,12 @@ prescan(addr, delim, pvpbuf, delimptr) } CurEnv->e_to = saveto; if (av[0] == NULL) - return (NULL); - return (av); -} - /* -** TOKTYPE -- return token type -** -** Parameters: -** c -- the character in question. -** -** Returns: -** Its type. -** -** Side Effects: -** none. -*/ - -toktype(c) - register int c; -{ - static char buf[50]; - static bool firstime = TRUE; - - if (firstime) { - firstime = FALSE; - expand("\201o", buf, &buf[sizeof buf - 1], CurEnv); - (void) strcat(buf, DELIMCHARS); + if (tTd(22, 1)) + printf("prescan: null leading token\n"); + return (NULL); } - c &= 0377; - if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS) - return (ONE); - if (c == MACRODEXPAND) - return (ONE); - if (c == '"') - return (QST); - if ((c & 0340) == 0200) - return (OPR); - if (!isascii(c)) - return (ATM); - if (isspace(c) || c == ')') - return (SPC); - if (strchr(buf, c) != NULL) - return (OPR); - return (ATM); + return (av); } /* ** REWRITE -- apply rewrite rules to token vector. @@ -616,6 +622,7 @@ toktype(c) ** Parameters: ** pvp -- pointer to token vector. ** ruleset -- the ruleset to use for rewriting. +** reclevel -- recursion level (to catch loops). ** e -- the current envelope. ** ** Returns: @@ -635,11 +642,16 @@ struct match # define MAXMATCH 9 /* max params per rewrite */ +# ifndef MAXRULERECURSION +# define MAXRULERECURSION 50 /* max recursion depth */ +# endif + int -rewrite(pvp, ruleset, e) +rewrite(pvp, ruleset, reclevel, e) char **pvp; int ruleset; + int reclevel; register ENVELOPE *e; { register char *ap; /* address pointer */ @@ -664,6 +676,11 @@ rewrite(pvp, ruleset, e) syserr("554 rewrite: illegal ruleset number %d", ruleset); return EX_CONFIG; } + if (reclevel++ > MAXRULERECURSION) + { + syserr("rewrite: infinite recursion, ruleset %d", ruleset); + return EX_CONFIG; + } if (pvp == NULL) return EX_USAGE; @@ -1124,7 +1141,8 @@ rewrite(pvp, ruleset, e) else { /* scan the new replacement */ - xpvp = prescan(replac, '\0', pvpbuf, NULL); + xpvp = prescan(replac, '\0', pvpbuf, + sizeof pvpbuf, NULL); if (xpvp == NULL) { /* prescan already printed error */ @@ -1156,15 +1174,24 @@ rewrite(pvp, ruleset, e) { int stat; - bcopy((char *) &npvp[2], (char *) pvp, - (int) (avp - npvp - 2) * sizeof *avp); - if (tTd(21, 3)) - printf("-----callsubr %s\n", npvp[1]); - stat = rewrite(pvp, atoi(npvp[1]), e); - if (rstat == EX_OK || stat == EX_TEMPFAIL) - rstat = stat; - if ((**pvp & 0377) == CANONNET) + if (npvp[1] == NULL) + { + syserr("parseaddr: NULL subroutine call in ruleset %d, rule %d", + ruleset, ruleno); + *pvp = NULL; + } + else + { + bcopy((char *) &npvp[2], (char *) pvp, + (int) (avp - npvp - 2) * sizeof *avp); + if (tTd(21, 3)) + printf("-----callsubr %s\n", npvp[1]); + stat = rewrite(pvp, atoi(npvp[1]), reclevel, e); + if (rstat == EX_OK || stat == EX_TEMPFAIL) + rstat = stat; + if (*pvp != NULL && (**pvp & 0377) == CANONNET) rwr = NULL; + } } else { @@ -1285,6 +1312,8 @@ badaddr: } tv++; } + else + setstat(EX_UNAVAILABLE); if ((**tv & 0377) != CANONUSER) syserr("554 buildaddr: error: no user"); cataddr(++tv, NULL, buf, sizeof buf, ' '); @@ -1402,11 +1431,11 @@ badaddr: if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags)) { /* sender addresses done later */ - (void) rewrite(tv, 2, e); + (void) rewrite(tv, 2, 0, e); if (m->m_re_rwset > 0) - (void) rewrite(tv, m->m_re_rwset, e); + (void) rewrite(tv, m->m_re_rwset, 0, e); } - (void) rewrite(tv, 4, e); + (void) rewrite(tv, 4, 0, e); /* save the result for the command line/RCPT argument */ cataddr(tv, NULL, buf, sizeof buf, '\0'); @@ -1500,6 +1529,8 @@ sameaddr(a, b) register ADDRESS *a; register ADDRESS *b; { + register ADDRESS *ca, *cb; + /* if they don't have the same mailer, forget it */ if (a->q_mailer != b->q_mailer) return (FALSE); @@ -1508,9 +1539,16 @@ sameaddr(a, b) if (strcmp(a->q_user, b->q_user) != 0) return (FALSE); - /* if we have good uids for both but the differ, these are different */ - if (bitset(QGOODUID, a->q_flags & b->q_flags) && a->q_uid != b->q_uid) - return (FALSE); + /* if we have good uids for both but they differ, these are different */ + if (a->q_mailer == ProgMailer) + { + ca = getctladdr(a); + cb = getctladdr(b); + if (ca != NULL && cb != NULL && + bitset(QGOODUID, ca->q_flags & cb->q_flags) && + ca->q_uid != cb->q_uid) + return (FALSE); + } /* otherwise compare hosts (but be careful for NULL ptrs) */ if (a->q_host == b->q_host) @@ -1655,10 +1693,10 @@ remotename(name, m, flags, pstat, e) ** domain will be appended. */ - pvp = prescan(name, '\0', pvpbuf, NULL); + pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL); if (pvp == NULL) return (name); - if (rewrite(pvp, 3, e) == EX_TEMPFAIL) + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL) { @@ -1675,7 +1713,7 @@ remotename(name, m, flags, pstat, e) while ((*pxp++ = *qxq++) != NULL) continue; - if (rewrite(pvp, 3, e) == EX_TEMPFAIL) + if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; } } @@ -1689,17 +1727,17 @@ remotename(name, m, flags, pstat, e) if (bitset(RF_SENDERADDR, flags)) { - if (rewrite(pvp, 1, e) == EX_TEMPFAIL) + if (rewrite(pvp, 1, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; } else { - if (rewrite(pvp, 2, e) == EX_TEMPFAIL) + if (rewrite(pvp, 2, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; } if (rwset > 0) { - if (rewrite(pvp, rwset, e) == EX_TEMPFAIL) + if (rewrite(pvp, rwset, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; } @@ -1710,7 +1748,7 @@ remotename(name, m, flags, pstat, e) ** may be used as a default to the above rules. */ - if (rewrite(pvp, 4, e) == EX_TEMPFAIL) + if (rewrite(pvp, 4, 0, e) == EX_TEMPFAIL) *pstat = EX_TEMPFAIL; /* @@ -1719,7 +1757,13 @@ remotename(name, m, flags, pstat, e) cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0'); define('g', lbuf, e); - expand(fancy, buf, &buf[sizeof buf - 1], e); + + /* need to make sure route-addrs have */ + if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@') + expand("<\201g>", buf, &buf[sizeof buf - 1], e); + else + expand(fancy, buf, &buf[sizeof buf - 1], e); + define('g', oldg, e); if (tTd(12, 1)) @@ -1753,11 +1797,11 @@ maplocaluser(a, sendq, e) printf("maplocaluser: "); printaddr(a, FALSE); } - pvp = prescan(a->q_user, '\0', pvpbuf, &delimptr); + pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr); if (pvp == NULL) return; - (void) rewrite(pvp, 5, e); + (void) rewrite(pvp, 5, 0, e); if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET) return; diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c index 5c4a0277192..e2cad4cf51d 100644 --- a/usr.sbin/sendmail/src/queue.c +++ b/usr.sbin/sendmail/src/queue.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 8.27 (Berkeley) 10/29/93 (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.36 (Berkeley) 1/9/94 (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.27 (Berkeley) 10/29/93 (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.36 (Berkeley) 1/9/94 (without queueing)"; #endif #endif /* not lint */ @@ -121,21 +121,21 @@ queueup(e, queueall, announce) break; #ifdef LOG if (LogLevel > 0 && (i % 32) == 0) - syslog(LOG_ALERT, "queueup: cannot create %s: %s", - tf, errstring(errno)); + syslog(LOG_ALERT, "queueup: cannot create %s, uid=%d: %s", + tf, geteuid(), errstring(errno)); #endif - continue; } - - if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB)) - break; + else + { + if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB)) + break; #ifdef LOG - else if (LogLevel > 0 && (i % 32) == 0) - syslog(LOG_ALERT, "queueup: cannot lock %s: %s", - tf, errstring(errno)); + else if (LogLevel > 0 && (i % 32) == 0) + syslog(LOG_ALERT, "queueup: cannot lock %s: %s", + tf, errstring(errno)); #endif - - close(fd); + close(fd); + } if ((i % 32) == 31) { @@ -146,7 +146,11 @@ queueup(e, queueall, announce) sleep(i % 32); } if (fd < 0 || (tfp = fdopen(fd, "w")) == NULL) - syserr("!queueup: cannot create queue temp file %s", tf); + { + printopenfds(TRUE); + syserr("!queueup: cannot create queue temp file %s, uid=%d", + tf, geteuid()); + } } if (tTd(40, 1)) @@ -176,8 +180,8 @@ queueup(e, queueall, announce) e->e_df = newstr(e->e_df); fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode); if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL) - syserr("!queueup: cannot create data temp file %s", - e->e_df); + syserr("!queueup: cannot create data temp file %s, uid=%d", + e->e_df, geteuid()); (*e->e_putbody)(dfp, FileMailer, e, NULL); (void) xfclose(dfp, "queueup dfp", e->e_id); e->e_putbody = putbody; @@ -272,7 +276,7 @@ queueup(e, queueall, announce) bzero((char *) &nullmailer, sizeof nullmailer); nullmailer.m_re_rwset = nullmailer.m_rh_rwset = - nullmailer.m_se_rwset = nullmailer.m_sh_rwset = 0; + nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1; nullmailer.m_eol = "\n"; define('g', "\201f", e); @@ -288,6 +292,14 @@ queueup(e, queueall, announce) if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) continue; + /* expand macros; if null, don't output header at all */ + if (bitset(H_DEFAULT, h->h_flags)) + { + (void) expand(h->h_value, buf, &buf[sizeof buf], e); + if (buf[0] == '\0') + continue; + } + /* output this header */ fprintf(tfp, "H"); @@ -306,7 +318,6 @@ queueup(e, queueall, announce) /* output the header: expand macros, convert addresses */ if (bitset(H_DEFAULT, h->h_flags)) { - (void) expand(h->h_value, buf, &buf[sizeof buf], e); fprintf(tfp, "%s: %s\n", h->h_field, buf); } else if (bitset(H_FROM|H_RCPT, h->h_flags)) @@ -345,7 +356,8 @@ queueup(e, queueall, announce) /* rename (locked) tf to be (locked) qf */ qf = queuename(e, 'q'); if (rename(tf, qf) < 0) - syserr("cannot rename(%s, %s), df=%s", tf, qf, e->e_df); + syserr("cannot rename(%s, %s), df=%s, uid=%d", + tf, qf, e->e_df, geteuid()); /* close and unlock old (locked) qf */ if (e->e_lockfp != NULL) @@ -461,17 +473,18 @@ runqueue(forkflag) if (forkflag) { int pid; +#ifdef SIGCHLD + extern void reapchild(); + + (void) setsignal(SIGCHLD, reapchild); +#endif pid = dofork(); if (pid != 0) { - extern void reapchild(); - /* parent -- pick up intermediate zombie */ #ifndef SIGCHLD (void) waitfor(pid); -#else /* SIGCHLD */ - (void) setsignal(SIGCHLD, reapchild); #endif /* SIGCHLD */ if (QueueIntvl != 0) (void) setevent(QueueIntvl, runqueue, TRUE); @@ -850,6 +863,11 @@ dowork(id, forkflag, requeueflag, e) syserr("dowork: cannot fork"); return 0; } + else if (pid > 0) + { + /* parent -- clean out connection cache */ + mci_flush(FALSE, NULL); + } } else { @@ -888,7 +906,7 @@ dowork(id, forkflag, requeueflag, e) e->e_header = NULL; /* read the queue control file -- return if locked */ - if (!readqf(e, !requeueflag)) + if (!readqf(e)) { if (tTd(40, 4)) printf("readqf(%s) failed\n", e->e_id); @@ -921,8 +939,6 @@ dowork(id, forkflag, requeueflag, e) ** ** Parameters: ** e -- the envelope of the job to run. -** announcefile -- if set, announce the name of the queue -** file in error messages. ** ** Returns: ** TRUE if it successfully read the queue file. @@ -933,9 +949,8 @@ dowork(id, forkflag, requeueflag, e) */ bool -readqf(e, announcefile) +readqf(e) register ENVELOPE *e; - bool announcefile; { register FILE *qfp; ADDRESS *ctladdr; @@ -1031,9 +1046,8 @@ readqf(e, announcefile) /* do basic system initialization */ initsys(e); + define('i', e->e_id, e); - if (announcefile) - FileName = qf; LineNumber = 0; e->e_flags |= EF_GLOBALERRS; OpMode = MD_DELIVER; @@ -1121,8 +1135,8 @@ readqf(e, announcefile) break; default: - syserr("readqf: bad line \"%s\"", e->e_id, - LineNumber, bp); + syserr("readqf: %s: line %s: bad line \"%s\"", + qf, LineNumber, bp); fclose(qfp); rename(qf, queuename(e, 'Q')); return FALSE; @@ -1132,8 +1146,6 @@ readqf(e, announcefile) free(bp); } - FileName = NULL; - /* ** If we haven't read any lines, this queue file is empty. ** Arrange to remove it without referencing any null pointers. diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c index eb52247aa1c..0d8d6fddf3a 100644 --- a/usr.sbin/sendmail/src/readcf.c +++ b/usr.sbin/sendmail/src/readcf.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)readcf.c 8.14 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)readcf.c 8.18 (Berkeley) 1/9/94"; #endif /* not lint */ # include "sendmail.h" @@ -109,7 +109,7 @@ readcf(cfname, safe, e) extern char **copyplist(); struct stat statb; char exbuf[MAXLINE]; - char pvpbuf[PSBUFSIZE]; + char pvpbuf[MAXLINE + MAXATOM]; extern char *munchstring(); extern void makemapentry(); @@ -241,7 +241,8 @@ readcf(cfname, safe, e) /* expand and save the LHS */ *p = '\0'; expand(&bp[1], exbuf, &exbuf[sizeof exbuf], e); - rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, NULL); + rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, + sizeof pvpbuf, NULL); nfuzzy = 0; if (rwp->r_lhs != NULL) { @@ -325,7 +326,8 @@ readcf(cfname, safe, e) p++; *p = '\0'; expand(q, exbuf, &exbuf[sizeof exbuf], e); - rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, NULL); + rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, + sizeof pvpbuf, NULL); if (rwp->r_rhs != NULL) { register char **ap; @@ -540,8 +542,10 @@ readcf(cfname, safe, e) { /* user didn't initialize: set up host map */ strcpy(buf, "host host"); +#ifdef NAMED_BIND if (ConfigLevel >= 2) strcat(buf, " -a."); +#endif makemapentry(buf); } } @@ -1020,6 +1024,7 @@ struct resolverflags "defnames", RES_DEFNAMES, "stayopen", RES_STAYOPEN, "dnsrch", RES_DNSRCH, + "true", 0, /* to avoid error on old syntax */ NULL, 0 }; @@ -1239,7 +1244,9 @@ setoption(opt, val, safe, sticky, e) if (strcasecmp(q, rfp->rf_name) == 0) break; } - if (clearmode) + if (rfp->rf_name == NULL) + syserr("readcf: I option value %s unrecognized", q); + else if (clearmode) _res.options &= ~rfp->rf_bits; else _res.options |= rfp->rf_bits; diff --git a/usr.sbin/sendmail/src/recipient.c b/usr.sbin/sendmail/src/recipient.c index e80c6b5fb9a..706fddc82c4 100644 --- a/usr.sbin/sendmail/src/recipient.c +++ b/usr.sbin/sendmail/src/recipient.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)recipient.c 8.21 (Berkeley) 10/29/93"; +static char sccsid[] = "@(#)recipient.c 8.39 (Berkeley) 1/10/94"; #endif /* not lint */ # include "sendmail.h" @@ -222,10 +222,25 @@ recipient(a, sendq, e) stripquotes(buf); /* check for direct mailing to restricted mailers */ - if (a->q_alias == NULL && m == ProgMailer) + if (m == ProgMailer) { - a->q_flags |= QBADADDR; - usrerr("550 Cannot mail directly to programs"); + if (a->q_alias == NULL) + { + a->q_flags |= QBADADDR; + usrerr("550 Cannot mail directly to programs"); + } + else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs", + a->q_alias->q_ruser, MyHostName); + } + else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + usrerr("550 Address %s is unsafe for mailing to programs", + a->q_alias->q_paddr); + } } /* @@ -252,6 +267,8 @@ recipient(a, sendq, e) message("duplicate suppressed"); q->q_flags |= a->q_flags; } + else if (bitset(QSELFREF, q->q_flags)) + q->q_flags |= a->q_flags & ~QDONTSEND; a = q; goto testselfdestruct; } @@ -294,6 +311,7 @@ recipient(a, sendq, e) e->e_id, a->q_user, errstring(ret)); #endif a->q_flags |= QQUEUEUP; + a->q_flags &= ~QDONTSEND; usrerr("451 Cannot open %s: %s", a->q_user, errstring(ret)); } @@ -307,18 +325,27 @@ recipient(a, sendq, e) } else if (m == FileMailer) { - struct stat stb; extern bool writable(); - p = strrchr(buf, '/'); /* check if writable or creatable */ if (a->q_alias == NULL) { a->q_flags |= QBADADDR; usrerr("550 Cannot mail directly to files"); } - else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) : - (*p = '\0', safefile(buf, RealUid, RealGid, NULL, TRUE, S_IWRITE|S_IEXEC) != 0)) + else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + usrerr("550 User %s@%s doesn't have a valid shell for mailing to files", + a->q_alias->q_ruser, MyHostName); + } + else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) + { + a->q_flags |= QBADADDR; + usrerr("550 Address %s is unsafe for mailing to files", + a->q_alias->q_paddr); + } + else if (!writable(buf, getctladdr(a), SFF_ANYFILE)) { a->q_flags |= QBADADDR; giveresponse(EX_CANTCREAT, m, NULL, a->q_alias, e); @@ -340,7 +367,6 @@ recipient(a, sendq, e) if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags)) { extern int udbexpand(); - extern int errno; if (udbexpand(a, sendq, e) == EX_TEMPFAIL) { @@ -429,6 +455,11 @@ recipient(a, sendq, e) buildfname(pw->pw_gecos, pw->pw_name, nbuf); if (nbuf[0] != '\0') a->q_fullname = newstr(nbuf); + if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0' && + !usershellok(pw->pw_shell)) + { + a->q_flags |= QBOGUSSHELL; + } if (!quoted) forward(a, sendq, e); } @@ -563,7 +594,9 @@ finduser(name, fuzzyp) ** not writable. This is also enforced by mailfile. ** ** Parameters: -** s -- pointer to a stat struct for the file. +** filename -- the file name to check. +** ctladdr -- the controlling address for this file. +** flags -- SFF_* flags to control the function. ** ** Returns: ** TRUE -- if we will be able to write this file. @@ -574,35 +607,98 @@ finduser(name, fuzzyp) */ bool -writable(s) - register struct stat *s; +writable(filename, ctladdr, flags) + char *filename; + ADDRESS *ctladdr; + int flags; { uid_t euid; gid_t egid; int bits; + register char *p; + char *uname; + struct stat stb; + extern char RealUserName[]; - if (bitset(0111, s->st_mode)) - return (FALSE); - euid = RealUid; - egid = RealGid; - if (geteuid() == 0) + if (tTd(29, 5)) + printf("writable(%s, %x)\n", filename, flags); + +#ifdef HASLSTAT + if ((bitset(SFF_NOSLINK, flags) ? lstat(filename, &stb) + : stat(filename, &stb)) < 0) +#else + if (stat(filename, &stb) < 0) +#endif { - if (bitset(S_ISUID, s->st_mode)) - euid = s->st_uid; - if (bitset(S_ISGID, s->st_mode)) - egid = s->st_gid; + /* file does not exist -- see if directory is safe */ + p = strrchr(filename, '/'); + if (p == NULL) + { + errno = ENOTDIR; + return FALSE; + } + *p = '\0'; + errno = safefile(filename, RealUid, RealGid, RealUserName, + SFF_MUSTOWN, S_IWRITE|S_IEXEC); + *p = '/'; + return errno == 0; } +#ifdef SUID_ROOT_FILES_OK + /* really ought to be passed down -- and not a good idea */ + flags |= SFF_ROOTOK; +#endif + + /* + ** File does exist -- check that it is writable. + */ + + if (bitset(0111, stb.st_mode)) + { + if (tTd(29, 5)) + printf("failed (mode %o: x bits)\n", stb.st_mode); + errno = EPERM; + return (FALSE); + } + + if (ctladdr != NULL && geteuid() == 0) + { + euid = ctladdr->q_uid; + egid = ctladdr->q_gid; + uname = ctladdr->q_user; + } + else + { + euid = RealUid; + egid = RealGid; + uname = RealUserName; + } if (euid == 0) - return (TRUE); - bits = S_IWRITE; - if (euid != s->st_uid) { - bits >>= 3; - if (egid != s->st_gid) - bits >>= 3; + euid = DefUid; + uname = DefUser; } - return ((s->st_mode & bits) != 0); + if (egid == 0) + egid = DefGid; + if (geteuid() == 0) + { + if (bitset(S_ISUID, stb.st_mode) && + (stb.st_uid != 0 || bitset(SFF_ROOTOK, flags))) + { + euid = stb.st_uid; + uname = NULL; + } + if (bitset(S_ISGID, stb.st_mode) && + (stb.st_gid != 0 || bitset(SFF_ROOTOK, flags))) + egid = stb.st_gid; + } + + if (tTd(29, 5)) + printf("\teu/gid=%d/%d, st_u/gid=%d/%d\n", + euid, egid, stb.st_uid, stb.st_gid); + + errno = safefile(filename, euid, egid, uname, flags, S_IWRITE); + return errno == 0; } /* ** INCLUDE -- handle :include: specification. @@ -628,6 +724,10 @@ writable(s) static jmp_buf CtxIncludeTimeout; static int includetimeout(); +#ifndef S_IWOTH +# define S_IWOTH (S_IWRITE >> 6) +#endif + int include(fname, forwarding, ctladdr, sendq, e) char *fname; @@ -647,6 +747,8 @@ include(fname, forwarding, ctladdr, sendq, e) gid_t savedgid, gid; char *uname; int rval = 0; + int sfflags = forwarding ? SFF_MUSTOWN : SFF_ANYFILE; + struct stat st; char buf[MAXLINE]; if (tTd(27, 2)) @@ -665,9 +767,9 @@ include(fname, forwarding, ctladdr, sendq, e) ca = getctladdr(ctladdr); if (ca == NULL) { - uid = 0; - gid = 0; - uname = NULL; + uid = DefUid; + gid = DefGid; + uname = DefUser; saveduid = -1; } else @@ -699,7 +801,6 @@ include(fname, forwarding, ctladdr, sendq, e) { ctladdr->q_flags |= QQUEUEUP; errno = 0; - usrerr("451 open timeout on %s", fname); /* return pseudo-error code */ rval = EOPENTIMEOUT; @@ -708,41 +809,24 @@ include(fname, forwarding, ctladdr, sendq, e) ev = setevent((time_t) 60, includetimeout, 0); /* the input file must be marked safe */ - rval = safefile(fname, uid, gid, uname, forwarding, S_IREAD); + rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD); if (rval != 0) { /* don't use this :include: file */ - clrevent(ev); if (tTd(27, 4)) printf("include: not safe (uid=%d): %s\n", uid, errstring(rval)); - goto resetuid; } - - fp = fopen(fname, "r"); - if (fp == NULL) - { - rval = errno; - if (tTd(27, 4)) - printf("include: open: %s\n", errstring(rval)); - } - else if (ca == NULL) + else { - struct stat st; - - if (fstat(fileno(fp), &st) < 0) + fp = fopen(fname, "r"); + if (fp == NULL) { rval = errno; - syserr("Cannot fstat %s!", fname); - } - else - { - ctladdr->q_uid = st.st_uid; - ctladdr->q_gid = st.st_gid; - ctladdr->q_flags |= QGOODUID; + if (tTd(27, 4)) + printf("include: open: %s\n", errstring(rval)); } } - clrevent(ev); resetuid: @@ -761,9 +845,43 @@ resetuid: if (tTd(27, 9)) printf("include: reset uid = %d/%d\n", getuid(), geteuid()); + if (rval == EOPENTIMEOUT) + usrerr("451 open timeout on %s", fname); + if (fp == NULL) return rval; + if (fstat(fileno(fp), &st) < 0) + { + rval = errno; + syserr("Cannot fstat %s!", fname); + return rval; + } + + if (ca == NULL) + { + ctladdr->q_uid = st.st_uid; + ctladdr->q_gid = st.st_gid; + ctladdr->q_flags |= QGOODUID; + } + if (ca != NULL && ca->q_uid == st.st_uid) + { + /* optimization -- avoid getpwuid if we already have info */ + ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; + ctladdr->q_ruser = ca->q_ruser; + } + else + { + register struct passwd *pw; + + pw = getpwuid(st.st_uid); + if (pw == NULL || !usershellok(pw->pw_shell)) + { + ctladdr->q_ruser = newstr(pw->pw_name); + ctladdr->q_flags |= QBOGUSSHELL; + } + } + if (bitset(EF_VRFYONLY, e->e_flags)) { /* don't do any more now */ @@ -773,6 +891,19 @@ resetuid: return rval; } + /* + ** 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 + ** directories in the path. We've got to leave + ** something for the local sysad to do. + */ + + if (bitset(S_IWOTH, st.st_mode)) + ctladdr->q_flags |= QUNSAFEADDR; + /* read the file -- each line is a comma-separated list. */ FileName = fname; LineNumber = 0; diff --git a/usr.sbin/sendmail/src/savemail.c b/usr.sbin/sendmail/src/savemail.c index 99e33c58e7d..2d09594b3c7 100644 --- a/usr.sbin/sendmail/src/savemail.c +++ b/usr.sbin/sendmail/src/savemail.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)savemail.c 8.17 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)savemail.c 8.24 (Berkeley) 12/18/93"; #endif /* not lint */ # include "sendmail.h" @@ -69,6 +69,10 @@ static char sccsid[] = "@(#)savemail.c 8.17 (Berkeley) 10/31/93"; # define ESM_PANIC 6 /* leave the locked queue/transcript files */ # define ESM_DONE 7 /* the message is successfully delivered */ +# ifndef _PATH_VARTMP +# define _PATH_VARTMP "/usr/tmp/" +# endif + savemail(e) register ENVELOPE *e; @@ -82,6 +86,7 @@ savemail(e) register char *p; extern char *ttypath(); typedef int (*fnptr)(); + extern bool writable(); if (tTd(6, 1)) { @@ -374,8 +379,14 @@ savemail(e) break; } - fp = dfopen("/usr/tmp/dead.letter", - O_WRONLY|O_CREAT|O_APPEND, FileMode); + strcpy(buf, _PATH_VARTMP); + strcat(buf, "dead.letter"); + if (!writable(buf, NULLADDR, SFF_NOSLINK)) + { + state = ESM_PANIC; + break; + } + fp = dfopen(buf, O_WRONLY|O_CREAT|O_APPEND, FileMode); if (fp == NULL) { state = ESM_PANIC; @@ -399,8 +410,7 @@ savemail(e) case ESM_PANIC: /* leave the locked queue & transcript files around */ - syserr("554 savemail: cannot save rejected email anywhere"); - exit(EX_SOFTWARE); + syserr("!554 savemail: cannot save rejected email anywhere"); } } } @@ -466,6 +476,7 @@ returntosender(msg, returnq, sendbody, e) SendBody = sendbody; define('g', e->e_from.q_paddr, e); + define('u', NULL, e); ee = newenvelope(&errenvelope, e); define('a', "\201b", ee); define('r', "internal", ee); @@ -602,7 +613,8 @@ errbody(fp, m, e) for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) if (bitset(QBADADDR, q->q_flags)) break; - if (q == NULL && !bitset(EF_FATALERRS, e->e_parent->e_flags)) + if (q == NULL && + !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags)) { putline(" **********************************************", fp, m); diff --git a/usr.sbin/sendmail/src/sendmail.8 b/usr.sbin/sendmail/src/sendmail.8 index ee176f3c77a..ee0f700d83a 100644 --- a/usr.sbin/sendmail/src/sendmail.8 +++ b/usr.sbin/sendmail/src/sendmail.8 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)sendmail.8 8.3 (Berkeley) 8/20/93 +.\" @(#)sendmail.8 8.4 (Berkeley) 12/11/93 .\" -.Dd August 20, 1993 +.Dd December 11, 1993 .Dt SENDMAIL 8 .Os BSD 4 .Sh NAME @@ -139,6 +139,7 @@ refuses to run as root if an alternate configuration file is specified. .It Fl d Ns Ar X Set debugging value to .Ar X . +.ne 1i .It Fl F Ns Ar fullname Set the full name of the sender. .It Fl f Ns Ar name diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h index 558137777ea..e68ffe09889 100644 --- a/usr.sbin/sendmail/src/sendmail.h +++ b/usr.sbin/sendmail/src/sendmail.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)sendmail.h 8.26 (Berkeley) 10/31/93 + * @(#)sendmail.h 8.38 (Berkeley) 1/5/94 */ /* @@ -41,7 +41,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 8.26 10/31/93"; +static char SmailSccsId[] = "@(#)sendmail.h 8.38 1/5/94"; # endif # else /* _DEFINE */ # define EXTERN extern @@ -57,7 +57,6 @@ static char SmailSccsId[] = "@(#)sendmail.h 8.26 10/31/93"; # include # include # include -# include # include "conf.h" # include "useful.h" @@ -69,6 +68,9 @@ static char SmailSccsId[] = "@(#)sendmail.h 8.26 10/31/93"; # ifdef DAEMON # include # endif +# ifdef NETUNIX +# include +# endif # ifdef NETINET # include # endif @@ -148,6 +150,8 @@ typedef struct address ADDRESS; # define QSELFREF 000200 /* this address references itself */ # define QVERIFIED 000400 /* verified, but not expanded */ # define QREPORT 001000 /* report this address in return message */ +# define QBOGUSSHELL 002000 /* this entry has an invalid shell listed */ +# define QUNSAFEADDR 004000 /* address aquired through an unsafe path */ # define NULLADDR ((ADDRESS *) NULL) /* @@ -287,9 +291,9 @@ ENVELOPE ADDRESS *e_sendqueue; /* list of message recipients */ ADDRESS *e_errorqueue; /* the queue for error responses */ long e_msgsize; /* size of the message in bytes */ + long e_flags; /* flags, see below */ int e_nrcpts; /* number of recipients */ short e_class; /* msg class (priority, junk, etc.) */ - short e_flags; /* flags, see below */ short e_hopcount; /* number of times processed */ short e_nsent; /* number of sends since checkpoint */ short e_sendmode; /* message send mode */ @@ -314,20 +318,21 @@ ENVELOPE }; /* values for e_flags */ -#define EF_OLDSTYLE 000001 /* use spaces (not commas) in hdrs */ -#define EF_INQUEUE 000002 /* this message is fully queued */ -#define EF_CLRQUEUE 000010 /* disk copy is no longer needed */ -#define EF_SENDRECEIPT 000020 /* send a return receipt */ -#define EF_FATALERRS 000040 /* fatal errors occured */ -#define EF_KEEPQUEUE 000100 /* keep queue files always */ -#define EF_RESPONSE 000200 /* this is an error or return receipt */ -#define EF_RESENT 000400 /* this message is being forwarded */ -#define EF_VRFYONLY 001000 /* verify only (don't expand aliases) */ -#define EF_WARNING 002000 /* warning message has been sent */ -#define EF_QUEUERUN 004000 /* this envelope is from queue */ -#define EF_GLOBALERRS 010000 /* treat errors as global */ -#define EF_PM_NOTIFY 020000 /* send return mail to postmaster */ -#define EF_METOO 040000 /* send to me too */ +#define EF_OLDSTYLE 0x0000001 /* use spaces (not commas) in hdrs */ +#define EF_INQUEUE 0x0000002 /* this message is fully queued */ +#define EF_CLRQUEUE 0x0000008 /* disk copy is no longer needed */ +#define EF_SENDRECEIPT 0x0000010 /* send a return receipt */ +#define EF_FATALERRS 0x0000020 /* fatal errors occured */ +#define EF_KEEPQUEUE 0x0000040 /* keep queue files always */ +#define EF_RESPONSE 0x0000080 /* this is an error or return receipt */ +#define EF_RESENT 0x0000100 /* this message is being forwarded */ +#define EF_VRFYONLY 0x0000200 /* verify only (don't expand aliases) */ +#define EF_WARNING 0x0000400 /* warning message has been sent */ +#define EF_QUEUERUN 0x0000800 /* this envelope is from queue */ +#define EF_GLOBALERRS 0x0001000 /* treat errors as global */ +#define EF_PM_NOTIFY 0x0002000 /* send return mail to postmaster */ +#define EF_METOO 0x0004000 /* send to me too */ +#define EF_LOGSENDER 0x0008000 /* need to log the sender */ EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */ /* @@ -722,6 +727,17 @@ struct prival #define RF_COPYALL (RF_COPYPARSE|RF_COPYPADDR) #define RF_COPYNONE 0 + +/* +** Flags passed to safefile. +*/ + +#define SFF_ANYFILE 0 /* no special restrictions */ +#define SFF_MUSTOWN 0x0001 /* user must own this file */ +#define SFF_NOSLINK 0x0002 /* file cannot be a symbolic link */ +#define SFF_ROOTOK 0x0004 /* ok for root to own this file */ + + /* ** Regular UNIX sockaddrs are too small to handle ISO addresses, so ** we are forced to declare a supertype here. @@ -730,7 +746,9 @@ struct prival union bigsockaddr { struct sockaddr sa; /* general version */ +#ifdef NETUNIX struct sockaddr_un sunix; /* UNIX family */ +#endif #ifdef NETINET struct sockaddr_in sin; /* INET family */ #endif @@ -804,7 +822,7 @@ EXTERN bool SendMIMEErrors; /* send error messages in MIME format */ EXTERN bool MatchGecos; /* look for user names in gecos field */ EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */ EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */ -EXTERN bool CheckLoopBack; /* check for loopback on HELO packet */ +extern bool CheckLoopBack; /* check for loopback on HELO packet */ EXTERN bool InChild; /* true if running in an SMTP subprocess */ EXTERN char SpaceSub; /* substitution for */ EXTERN int PrivacyFlags; /* privacy flags */ @@ -825,13 +843,14 @@ EXTERN long MaxMessageSize; /* advertised max size we will accept */ EXTERN char *PostMasterCopy; /* address to get errs cc's */ EXTERN int CheckpointInterval; /* queue file checkpoint interval */ EXTERN bool DontPruneRoutes; /* don't prune source routes */ -EXTERN bool BrokenSmtpPeers; /* peers can't handle 2-line greeting */ +extern bool BrokenSmtpPeers; /* peers can't handle 2-line greeting */ EXTERN int MaxMciCache; /* maximum entries in MCI cache */ EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */ 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 int errno; /* @@ -909,7 +928,8 @@ extern const char *errstring __P((int)); extern void expand __P((char *, char *, char *, ENVELOPE *)); extern void define __P((int, char *, ENVELOPE *)); extern char *macvalue __P((int, ENVELOPE *)); -extern char **prescan __P((char *, int, char[], char **)); +extern char **prescan __P((char *, int, char[], int, char **)); +extern int rewrite __P((char **, int, int, ENVELOPE *)); extern char *fgetfolded __P((char *, int, FILE *)); extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, ENVELOPE *)); extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *)); @@ -928,6 +948,8 @@ extern char *hostsignature __P((MAILER *, char *, ENVELOPE *)); extern void openxscript __P((ENVELOPE *)); extern void closexscript __P((ENVELOPE *)); extern sigfunc_t setsignal __P((int, sigfunc_t)); +extern char *shortenstring __P((char *, int)); +extern bool usershellok __P((char *)); /* ellipsis is a different case though */ #ifdef __STDC__ diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c index 4474cd56d38..2966f80af6e 100644 --- a/usr.sbin/sendmail/src/srvrsmtp.c +++ b/usr.sbin/sendmail/src/srvrsmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)srvrsmtp.c 8.18 (Berkeley) 10/28/93 (with SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.23 (Berkeley) 12/21/93 (with SMTP)"; #else -static char sccsid[] = "@(#)srvrsmtp.c 8.18 (Berkeley) 10/28/93 (without SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.23 (Berkeley) 12/21/93 (without SMTP)"; #endif #endif /* not lint */ @@ -114,6 +114,7 @@ static struct cmd CmdTab[] = }; bool OneXact = FALSE; /* one xaction only this run */ +char *CurSmtpClient; /* who's at the other end of channel */ static char *skipword(); @@ -147,7 +148,11 @@ smtp(e) } settime(e); CurHostName = RealHostName; - setproctitle("server %s startup", CurHostName); + CurSmtpClient = macvalue('_', e); + if (CurSmtpClient == NULL) + CurSmtpClient = RealHostName; + + setproctitle("server %s startup", CurSmtpClient); expand("\201e", inp, &inp[sizeof inp], e); if (BrokenSmtpPeers) { @@ -192,11 +197,11 @@ smtp(e) { /* end of file, just die */ message("421 %s Lost input channel from %s", - MyHostName, CurHostName); + MyHostName, CurSmtpClient); #ifdef LOG if (LogLevel > (gotmail ? 1 : 19)) syslog(LOG_NOTICE, "lost input channel from %s", - CurHostName); + CurSmtpClient); #endif if (InChild) ExitStat = EX_QUIT; @@ -211,9 +216,9 @@ smtp(e) fprintf(e->e_xfp, "<<< %s\n", inp); if (e->e_id == NULL) - setproctitle("%s: %s", CurHostName, inp); + setproctitle("%s: %.80s", CurSmtpClient, inp); else - setproctitle("%s %s: %s", e->e_id, CurHostName, inp); + setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp); /* break off command */ for (p = inp; isascii(*p) && isspace(*p); p++) @@ -262,16 +267,13 @@ smtp(e) auth_warning(e, "Host %s claimed to be %s", RealHostName, p); } - p = macvalue('_', e); - if (p == NULL) - p = RealHostName; gothello = TRUE; if (c->cmdcode != CMDEHLO) { /* print old message and be done with it */ message("250 %s Hello %s, pleased to meet you", - MyHostName, p); + MyHostName, CurSmtpClient); break; } @@ -332,7 +334,8 @@ smtp(e) define('s', sendinghost, e); initsys(e); nrcpts = 0; - setproctitle("%s %s: %s", e->e_id, CurHostName, inp); + e->e_flags |= EF_LOGSENDER; + setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp); /* child -- go do the processing */ p = skipword(p, "from"); @@ -626,7 +629,12 @@ smtp(e) if (vrfy) message("252 Who's to say?"); else - message("502 That's none of your business"); + message("502 Sorry, we do not allow this operation"); +#ifdef LOG + if (LogLevel > 5) + syslog(LOG_INFO, "%s: %s [rejected]", + CurSmtpClient, inp); +#endif break; } else if (!gothello && @@ -640,7 +648,7 @@ smtp(e) break; #ifdef LOG if (LogLevel > 5) - syslog(LOG_INFO, "%s: %s", CurHostName, inp); + syslog(LOG_INFO, "%s: %s", CurSmtpClient, inp); #endif vrfyqueue = NULL; QuickAbort = TRUE; @@ -942,6 +950,9 @@ runinchild(label, e) st = waitfor(childpid); if (st == -1) syserr("%s: lost child", label); + else if (!WIFEXITED(st)) + syserr("%s: died on signal %d", + label, st & 0177); /* if we exited on a QUIT command, complete the process */ if (st == (EX_QUIT << 8)) diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c index f079b44bce3..46b9d658453 100644 --- a/usr.sbin/sendmail/src/udb.c +++ b/usr.sbin/sendmail/src/udb.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef USERDB -static char sccsid [] = "@(#)udb.c 8.3 (Berkeley) 8/25/93 (with USERDB)"; +static char sccsid [] = "@(#)udb.c 8.4 (Berkeley) 11/25/93 (with USERDB)"; #else -static char sccsid [] = "@(#)udb.c 8.3 (Berkeley) 8/25/93 (without USERDB)"; +static char sccsid [] = "@(#)udb.c 8.4 (Berkeley) 11/25/93 (without USERDB)"; #endif #endif @@ -603,7 +603,7 @@ _udbx_init() up->udb_addr.sin_family = h->h_addrtype; bcopy(h->h_addr_list[0], (char *) &up->udb_addr.sin_addr, - h->h_length); + sizeof up->udb_addr.sin_addr); up->udb_addr.sin_port = UdbPort; up->udb_timeout = UdbTimeout; up++; diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c index 18510e4b3d2..14b2f7fda72 100644 --- a/usr.sbin/sendmail/src/usersmtp.c +++ b/usr.sbin/sendmail/src/usersmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 8.13 (Berkeley) 10/24/93 (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.17 (Berkeley) 1/5/94 (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 8.13 (Berkeley) 10/24/93 (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.17 (Berkeley) 1/5/94 (without SMTP)"; #endif #endif /* not lint */ @@ -218,8 +218,13 @@ tryhelo: goto tempfail2; } - mci->mci_state = MCIS_OPEN; - return; + if (mci->mci_state != MCIS_CLOSED) + { + mci->mci_state = MCIS_OPEN; + return; + } + + /* got a 421 error code during startup */ tempfail1: tempfail2: @@ -317,6 +322,7 @@ smtpmailfrom(m, mci, e) ENVELOPE *e; { int r; + char *bufp; char buf[MAXNAME]; char optbuf[MAXLINE]; @@ -341,15 +347,25 @@ smtpmailfrom(m, mci, e) (void) strcpy(buf, ""); else expand("\201g", buf, &buf[sizeof buf - 1], e); + if (buf[0] == '<') + { + /* strip off (put back on below) */ + bufp = &buf[strlen(buf) - 1]; + if (*bufp == '>') + *bufp = '\0'; + bufp = &buf[1]; + } + else + bufp = buf; if (e->e_from.q_mailer == LocalMailer || !bitnset(M_FROMPATH, m->m_flags)) { - smtpmessage("MAIL From:<%s>%s", m, mci, buf, optbuf); + smtpmessage("MAIL From:<%s>%s", m, mci, bufp, optbuf); } else { smtpmessage("MAIL From:<@%s%c%s>%s", m, mci, MyHostName, - buf[0] == '@' ? ',' : ':', buf, optbuf); + *bufp == '@' ? ',' : ':', bufp, optbuf); } SmtpPhase = mci->mci_phase = "client MAIL"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); @@ -594,7 +610,16 @@ smtpquit(m, mci, e) register MCI *mci; ENVELOPE *e; { - int i; + bool oldSuprErrs = SuprErrs; + + /* + ** Suppress errors here -- we may be processing a different + ** job when we do the quit connection, and we don't want the + ** new job to be penalized for something that isn't it's + ** problem. + */ + + SuprErrs = TRUE; /* send the quit message if we haven't gotten I/O error */ if (mci->mci_state != MCIS_ERROR) @@ -602,14 +627,18 @@ smtpquit(m, mci, e) SmtpPhase = "client QUIT"; smtpmessage("QUIT", m, mci); (void) reply(m, mci, e, TimeOuts.to_quit, NULL); + SuprErrs = oldSuprErrs; if (mci->mci_state == MCIS_CLOSED) + { + SuprErrs = oldSuprErrs; return; + } } /* now actually close the connection and pick up the zombie */ - i = endmailer(mci, e, m->m_argv); - if (i != EX_OK) - syserr("451 smtpquit %s: stat %d", m->m_argv[0], i); + (void) endmailer(mci, e, NULL); + + SuprErrs = oldSuprErrs; } /* ** SMTPRSET -- send a RSET (reset) command diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c index f296513df3b..85e0f04dd34 100644 --- a/usr.sbin/sendmail/src/util.c +++ b/usr.sbin/sendmail/src/util.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)util.c 8.15 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)util.c 8.28 (Berkeley) 1/4/94"; #endif /* not lint */ # include "sendmail.h" @@ -407,7 +407,9 @@ buildfname(gecos, login, buf) ** gid -- group id to compare against. ** uname -- user name to compare against (used for group ** sets). -** mustown -- to be safe, this uid must own the file. +** flags -- modifiers: +** SFF_MUSTOWN -- "uid" must own this file. +** SFF_NOSLINK -- file cannot be a symbolic link. ** mode -- mode bits that must match. ** ** Returns: @@ -433,12 +435,12 @@ buildfname(gecos, login, buf) #endif int -safefile(fn, uid, gid, uname, mustown, mode) +safefile(fn, uid, gid, uname, flags, mode) char *fn; uid_t uid; gid_t gid; char *uname; - bool mustown; + int flags; int mode; { register char *p; @@ -446,8 +448,8 @@ safefile(fn, uid, gid, uname, mustown, mode) struct stat stbuf; if (tTd(54, 4)) - printf("safefile(%s, uid=%d, gid=%d, mustown=%d, mode=%o):\n", - fn, uid, gid, mustown, mode); + printf("safefile(%s, uid=%d, gid=%d, flags=%x, mode=%o):\n", + fn, uid, gid, flags, mode); errno = 0; for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/') @@ -455,6 +457,12 @@ safefile(fn, uid, gid, uname, mustown, mode) *p = '\0'; if (stat(fn, &stbuf) < 0) break; + if (uid == 0 && !bitset(SFF_ROOTOK, flags)) + { + if (bitset(S_IXOTH, stbuf.st_mode)) + continue; + break; + } if (stbuf.st_uid == uid && bitset(S_IXUSR, stbuf.st_mode)) continue; if (stbuf.st_gid == gid && bitset(S_IXGRP, stbuf.st_mode)) @@ -488,7 +496,12 @@ safefile(fn, uid, gid, uname, mustown, mode) return ret; } +#ifdef HASLSTAT + if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, &stbuf) + : stat(fn, &stbuf)) < 0) +#else if (stat(fn, &stbuf) < 0) +#endif { int ret = errno; @@ -498,7 +511,17 @@ safefile(fn, uid, gid, uname, mustown, mode) errno = 0; return ret; } - if (uid == 0) + +#ifdef S_ISLNK + if (bitset(SFF_NOSLINK, flags) && S_ISLNK(stbuf.st_mode)) + { + if (tTd(54, 4)) + printf("\t[slink mode %o]\tEPERM\n", stbuf.st_mode); + return EPERM; + } +#endif + + if (uid == 0 && !bitset(SFF_ROOTOK, flags)) mode >>= 6; else if (stbuf.st_uid != uid) { @@ -525,7 +548,8 @@ safefile(fn, uid, gid, uname, mustown, mode) if (tTd(54, 4)) printf("\t[uid %d, stat %o, mode %o] ", stbuf.st_uid, stbuf.st_mode, mode); - if ((stbuf.st_uid == uid || uid == 0 || !mustown) && + if ((stbuf.st_uid == uid || stbuf.st_uid == 0 || + !bitset(SFF_MUSTOWN, flags)) && (stbuf.st_mode & mode) == mode) { if (tTd(54, 4)) @@ -836,12 +860,13 @@ sfgets(buf, siz, fp, timeout, during) /* try to read */ p = NULL; - while (p == NULL && !feof(fp) && !ferror(fp)) + while (!feof(fp) && !ferror(fp)) { errno = 0; p = fgets(buf, siz, fp); - if (errno == EINTR) - clearerr(fp); + if (p != NULL || errno != EINTR) + break; + clearerr(fp); } /* clear the event if it has not sprung */ @@ -1120,18 +1145,23 @@ strcontainedin(a, b) register char *a; register char *b; { - int l; - - l = strlen(a); - for (;;) + int la; + int lb; + int c; + + la = strlen(a); + lb = strlen(b); + c = *a; + if (isascii(c) && isupper(c)) + c = tolower(c); + for (; lb-- >= la; b++) { - b = strchr(b, a[0]); - if (b == NULL) - return FALSE; - if (strncmp(a, b, l) == 0) + if (*b != c && isascii(*b) && isupper(*b) && tolower(*b) != c) + continue; + if (strncasecmp(a, b, la) == 0) return TRUE; - b++; } + return FALSE; } /* ** CHECKFD012 -- check low numbered file descriptors @@ -1279,6 +1309,27 @@ dumpfd(fd, printclosed, logit) p += strlen(p); goto defprint; +#ifdef S_IFIFO + case S_IFIFO: + sprintf(p, "FIFO: "); + p += strlen(p); + goto defprint; +#endif + +#ifdef S_IFDIR + case S_IFDIR: + sprintf(p, "DIR: "); + p += strlen(p); + goto defprint; +#endif + +#ifdef S_IFLNK + case S_IFLNK: + sprintf(p, "LNK: "); + p += strlen(p); + goto defprint; +#endif + default: defprint: sprintf(p, "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld", @@ -1289,7 +1340,56 @@ defprint: printit: if (logit) - syslog(LOG_INFO, "%s", buf); + syslog(LOG_DEBUG, "%s", buf); else printf("%s\n", buf); } + /* +** SHORTENSTRING -- return short version of a string +** +** If the string is already short, just return it. If it is too +** long, return the head and tail of the string. +** +** Parameters: +** s -- the string to shorten. +** m -- the max length of the string. +** +** Returns: +** Either s or a short version of s. +*/ + +#ifndef MAXSHORTSTR +# define MAXSHORTSTR 203 +#endif + +char * +shortenstring(s, m) + register char *s; + int m; +{ + int l; + static char buf[MAXSHORTSTR + 1]; + + l = strlen(s); + if (l < m) + return s; + if (m > MAXSHORTSTR) + m = MAXSHORTSTR; + else if (m < 10) + { + if (m < 5) + { + strncpy(buf, s, m); + buf[m] = '\0'; + return buf; + } + strncpy(buf, s, m - 3); + strcpy(buf + m - 3, "..."); + return buf; + } + m = (m - 3) / 2; + strncpy(buf, s, m); + strcpy(buf + m, "..."); + strcpy(buf + m + 3, s + l - m); + return buf; +} diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c index 77760efff39..3169f6ac937 100644 --- a/usr.sbin/sendmail/src/version.c +++ b/usr.sbin/sendmail/src/version.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)version.c 8.6.1.4 (Berkeley) 10/31/93"; +static char sccsid[] = "@(#)version.c 8.6.1.5 (Berkeley) 1/13/94"; #endif /* not lint */ -char Version[] = "8.6.4"; +char Version[] = "8.6.5"; -- cgit