From: LaMont Jones Subject: Use sendmail's rmail Forwarded: not-needed Index: postfix/Makefile.in =================================================================== --- postfix.orig/Makefile.in +++ postfix/Makefile.in @@ -10,6 +10,7 @@ DIRS = src/util src/global src/dns src/t src/pipe src/showq src/postalias src/postcat src/postconf src/postdrop \ src/postkick src/postlock src/postlog src/postmap src/postqueue \ src/postsuper src/qmqpd src/spawn src/flush src/verify \ + rmail \ src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr \ src/postmulti src/postscreen src/dnsblog src/tlsproxy \ src/posttls-finger src/postlogd Index: postfix/conf/master.cf =================================================================== --- postfix.orig/conf/master.cf +++ postfix/conf/master.cf @@ -125,10 +125,8 @@ postlog unix-dgram n - n # # See the Postfix UUCP_README file for configuration details. # -#uucp unix - n n - - pipe -# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) -# -# ==================================================================== +uucp unix - n n - - pipe + flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) # # Other external delivery methods. # Index: postfix/rmail/LICENSE =================================================================== --- /dev/null +++ postfix/rmail/LICENSE @@ -0,0 +1,79 @@ + SENDMAIL LICENSE + +The following license terms and conditions apply, unless a different +license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor, +Emeryville, CA 94608, or by electronic mail at license@sendmail.com. + +License Terms: + +Use, Modification and Redistribution (including distribution of any +modified or derived work) in source and binary forms is permitted only if +each of the following conditions is met: + +1. Redistributions qualify as "freeware" or "Open Source Software" under + one of the following terms: + + (a) Redistributions are made at no charge beyond the reasonable cost of + materials and delivery. + + (b) Redistributions are accompanied by a copy of the Source Code or by an + irrevocable offer to provide a copy of the Source Code for up to three + years at the cost of materials and delivery. Such redistributions + must allow further use, modification, and redistribution of the Source + Code under substantially the same terms as this license. For the + purposes of redistribution "Source Code" means the complete compilable + and linkable source code of sendmail including all modifications. + +2. Redistributions of source code must retain the copyright notices as they + appear in each source code file, these license terms, and the + disclaimer/limitation of liability set forth as paragraph 6 below. + +3. Redistributions in binary form must reproduce the Copyright Notice, + these license terms, and the disclaimer/limitation of liability set + forth as paragraph 6 below, in the documentation and/or other materials + provided with the distribution. For the purposes of binary distribution + the "Copyright Notice" refers to the following language: + "Copyright (c) 1998-2000 Sendmail, Inc. All rights reserved." + +4. Neither the name of Sendmail, Inc. nor the University of California nor + the names of their contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. The name "sendmail" is a trademark of Sendmail, Inc. + +5. All redistributions must comply with the conditions imposed by the + University of California on certain embedded code, whose copyright + notice and conditions for redistribution are as follows: + + (a) Copyright (c) 1988, 1993 The Regents of the University of + California. All rights reserved. + + (b) Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + (i) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (ii) Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + (iii) Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +6. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY + SENDMAIL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL SENDMAIL, INC., THE REGENTS OF THE UNIVERSITY OF + CALIFORNIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +$Revision: 1.1.2.1 $, Last updated $Date: 2004/12/28 05:34:15 $ Index: postfix/rmail/Makefile.in =================================================================== --- /dev/null +++ postfix/rmail/Makefile.in @@ -0,0 +1,56 @@ +SHELL = /bin/sh +SRCS = rmail.c +OBJS = rmail.o +HDRS = +TESTSRC = +WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ + -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ + -Wunused +DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) -DHASSNPRINTF -DHASSTRERROR +CFLAGS = $(DEBUG) $(OPT) $(DEFS) +TESTPROG= +PROG = rmail +INC_DIR = +LIBS = + +.c.o:; $(CC) $(CFLAGS) -c $*.c + +$(PROG): $(OBJS) $(LIBS) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS) + +Makefile: Makefile.in + cat ../conf/makedefs.out $? >$@ + +test: $(TESTPROG) + +update: ../bin/$(PROG) + +../bin/$(PROG): $(PROG) + cp $(PROG) ../bin + +printfck: $(OBJS) $(PROG) + rm -rf printfck + mkdir printfck + sed '1,/^# do not edit/!d' Makefile >printfck/Makefile + set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done + cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o` + +lint: + lint $(DEFS) $(SRCS) $(LINTFIX) + +clean: + rm -f *.o *core $(PROG) $(TESTPROG) junk + rm -rf printfck + +tidy: clean + +depend: $(MAKES) + (sed '1,/^# do not edit/!d' Makefile.in; \ + set -e; for i in [a-z][a-z0-9]*.c; do \ + $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \ + -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \ + done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in + @make -f Makefile.in Makefile + +# do not edit below this line - it is generated by 'make depend' +rmail.o: rmail.c Index: postfix/rmail/rmail.8 =================================================================== --- /dev/null +++ postfix/rmail/rmail.8 @@ -0,0 +1,49 @@ +.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers. +.\" All rights reserved. +.\" Copyright (c) 1983, 1990 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" By using this file, you agree to the terms and conditions set +.\" forth in the LICENSE file which can be found at the top level of +.\" the sendmail distribution. +.\" +.\" +.\" $Id: 10rmail.dpatch,v 1.1.2.1 2004/12/28 05:34:15 lamont Exp $ +.\" +.TH RMAIL 8 "$Date: 2004/12/28 05:34:15 $" +.SH NAME +.B rmail +\- handle remote mail received via uucp +.SH SYNOPSIS +.B rmail +.I +user ... +.SH DESCRIPTION +.B Rmail +interprets incoming mail received via +uucp(1), +collapsing ``From'' lines in the form generated +by +mail.local(8) +into a single line of the form ``return-path!sender'', +and passing the processed mail on to +sendmail(8). +.PP +.B Rmail +is explicitly designed for use with +uucp +and +sendmail. +.SH SEE ALSO +uucp(1), +mail.local(8), +sendmail(8) +.SH HISTORY +The +.B rmail +program appeared in +4.2BSD. +.SH BUGS +.B Rmail +should not reside in +/bin. Index: postfix/rmail/rmail.c =================================================================== --- /dev/null +++ postfix/rmail/rmail.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. + * All rights reserved. + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + * + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\ + All rights reserved.\n\ + Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* ! lint */ + +#ifndef lint +static char id[] = "@(#)$Id: 10rmail.dpatch,v 1.1.2.1 2004/12/28 05:34:15 lamont Exp $"; +#endif /* ! lint */ + +/* + * RMAIL -- UUCP mail server. + * + * This program reads the >From ... remote from ... lines that UUCP is so + * fond of and turns them into something reasonable. It then execs sendmail + * with various options built from these lines. + * + * The expected syntax is: + * + * := [-a-z0-9]+ + * := ctime format + * := [-a-z0-9!]+ + * := "^\n$" + * := "From" + * [ "remote from" ] + * := ">" + * msg := * + * + * The output of rmail(8) compresses the lines into a single + * from path. + * + * The err(3) routine is included here deliberately to make this code + * a bit more portable. + */ + +#include +#include +#include +#include + +#include +#include +#ifdef BSD4_4 +# define FORK vfork +# include +#else /* BSD4_4 */ +# define FORK fork +# ifndef _PATH_SENDMAIL +# define _PATH_SENDMAIL "/usr/lib/sendmail" +# endif /* ! _PATH_SENDMAIL */ +#endif /* BSD4_4 */ +#include +#include +#include +#include +#ifdef EX_OK +# undef EX_OK /* unistd.h may have another use for this */ +#endif /* EX_OK */ +#include + +#ifndef MAX +# define MAX(a, b) ((a) < (b) ? (b) : (a)) +#endif /* ! MAX */ + +#ifndef __P +# ifdef __STDC__ +# define __P(protos) protos +# else /* __STDC__ */ +# define __P(protos) () +# define const +# endif /* __STDC__ */ +#endif /* ! __P */ + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif /* ! STDIN_FILENO */ + +#if defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300 || defined(HPUX11) +# define HASSNPRINTF 1 +#endif /* defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300 || defined(HPUX11) */ + +#if defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) +# define memmove(d, s, l) (bcopy((s), (d), (l))) +#endif /* defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) */ + +#if !HASSNPRINTF +extern int snprintf __P((char *, size_t, const char *, ...)); +#endif /* !HASSNPRINTF */ + +#if defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || defined(IRIX64) || defined(IRIX5) || defined(IRIX6) +# ifndef HASSTRERROR +# define HASSTRERROR 1 +# endif /* ! HASSTRERROR */ +#endif /* defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || + defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ + +#if defined(SUNOS403) || defined(NeXT) || (defined(MACH) && defined(i386) && !defined(__GNU__)) || defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) || defined(ALTOS_SYSTEM_V) || defined(RISCOS) || defined(_AUX_SOURCE) || defined(UMAXV) || defined(titan) || defined(UNIXWARE) || defined(sony_news) || defined(luna) || defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(__MAXION__) +# undef WIFEXITED +# undef WEXITSTATUS +# define WIFEXITED(st) (((st) & 0377) == 0) +# define WEXITSTATUS(st) (((st) >> 8) & 0377) +#endif /* defined(SUNOS403) || defined(NeXT) || (defined(MACH) && defined(i386) && !defined(__GNU__)) || defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) || defined(ALTOS_SYSTEM_V) || defined(RISCOS) || defined(_AUX_SOURCE) || defined(UMAXV) || defined(titan) || defined(UNIXWARE) || defined(sony_news) || defined(luna) || defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(__MAXION__) */ + +#include + +static void err __P((int, const char *, ...)); +static void usage __P((void)); +static char *xalloc __P((int)); + +#define newstr(s) strcpy(xalloc(strlen(s) + 1), s) + +static char * +xalloc(sz) + register int sz; +{ + register char *p; + + /* some systems can't handle size zero mallocs */ + if (sz <= 0) + sz = 1; + + p = malloc((unsigned) sz); + if (p == NULL) + err(EX_TEMPFAIL, "out of memory"); + return (p); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch, debug, i, pdes[2], pid, status; + size_t fplen = 0, fptlen = 0, len; + off_t offset; + FILE *fp; + char *addrp = NULL, *domain, *p, *t; + char *from_path, *from_sys, *from_user; + char **args, buf[2048], lbuf[2048]; + struct stat sb; + extern char *optarg; + extern int optind; + + debug = 0; + domain = "UUCP"; /* Default "domain". */ + while ((ch = getopt(argc, argv, "D:T")) != -1) + { + switch (ch) + { + case 'T': + debug = 1; + break; + + case 'D': + domain = optarg; + break; + + case '?': + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + from_path = from_sys = from_user = NULL; + for (offset = 0; ; ) + { + /* Get and nul-terminate the line. */ + if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) + exit(EX_DATAERR); + if ((p = strchr(lbuf, '\n')) == NULL) + err(EX_DATAERR, "line too long"); + *p = '\0'; + + /* Parse lines until reach a non-"From" line. */ + if (!strncmp(lbuf, "From ", 5)) + addrp = lbuf + 5; + else if (!strncmp(lbuf, ">From ", 6)) + addrp = lbuf + 6; + else if (offset == 0) + err(EX_DATAERR, + "missing or empty From line: %s", lbuf); + else + { + *p = '\n'; + break; + } + + if (addrp == NULL || *addrp == '\0') + err(EX_DATAERR, "corrupted From line: %s", lbuf); + + /* Use the "remote from" if it exists. */ + for (p = addrp; (p = strchr(p + 1, 'r')) != NULL; ) + { + if (!strncmp(p, "remote from ", 12)) + { + for (t = p += 12; *t != '\0'; ++t) + { + if (isascii(*t) && isspace(*t)) + break; + } + *t = '\0'; + if (debug) + fprintf(stderr, "remote from: %s\n", p); + break; + } + } + + /* Else use the string up to the last bang. */ + if (p == NULL) + { + if (*addrp == '!') + err(EX_DATAERR, "bang starts address: %s", + addrp); + else if ((t = strrchr(addrp, '!')) != NULL) + { + *t = '\0'; + p = addrp; + addrp = t + 1; + if (*addrp == '\0') + err(EX_DATAERR, + "corrupted From line: %s", lbuf); + if (debug) + fprintf(stderr, "bang: %s\n", p); + } + } + + /* 'p' now points to any system string from this line. */ + if (p != NULL) + { + /* Nul terminate it as necessary. */ + for (t = p; *t != '\0'; ++t) + { + if (isascii(*t) && isspace(*t)) + break; + } + *t = '\0'; + + /* If the first system, copy to the from_sys string. */ + if (from_sys == NULL) + { + from_sys = newstr(p); + if (debug) + fprintf(stderr, "from_sys: %s\n", + from_sys); + } + + /* Concatenate to the path string. */ + len = t - p; + if (from_path == NULL) + { + fplen = 0; + if ((from_path = malloc(fptlen = 256)) == NULL) + err(EX_TEMPFAIL, NULL); + } + if (fplen + len + 2 > fptlen) + { + fptlen += MAX(fplen + len + 2, 256); + if ((from_path = realloc(from_path, + fptlen)) == NULL) + err(EX_TEMPFAIL, NULL); + } + memmove(from_path + fplen, p, len); + fplen += len; + from_path[fplen++] = '!'; + from_path[fplen] = '\0'; + } + + /* Save off from user's address; the last one wins. */ + for (p = addrp; *p != '\0'; ++p) + { + if (isascii(*p) && isspace(*p)) + break; + } + *p = '\0'; + if (*addrp == '\0') + addrp = "<>"; + if (from_user != NULL) + free(from_user); + from_user = newstr(addrp); + + if (debug) + { + if (from_path != NULL) + fprintf(stderr, "from_path: %s\n", from_path); + fprintf(stderr, "from_user: %s\n", from_user); + } + + if (offset != -1) + offset = (off_t)ftell(stdin); + } + + + /* Allocate args (with room for sendmail args as well as recipients */ + args = (char **)xalloc(sizeof(*args) * (10 + argc)); + + i = 0; + args[i++] = _PATH_SENDMAIL; /* Build sendmail's argument list. */ + args[i++] = "-G"; /* relay submission */ + args[i++] = "-oee"; /* No errors, just status. */ + args[i++] = "-odq"; /* Queue it, don't try to deliver. */ + args[i++] = "-oi"; /* Ignore '.' on a line by itself. */ + + /* set from system and protocol used */ + if (from_sys == NULL) + snprintf(buf, sizeof(buf), "-p%s", domain); + else if (strchr(from_sys, '.') == NULL) + snprintf(buf, sizeof(buf), "-p%s:%s.%s", + domain, from_sys, domain); + else + snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys); + args[i++] = newstr(buf); + + /* Set name of ``from'' person. */ + snprintf(buf, sizeof(buf), "-f%s%s", + from_path ? from_path : "", from_user); + args[i++] = newstr(buf); + + /* + ** Don't copy arguments beginning with - as they will be + ** passed to sendmail and could be interpreted as flags. + ** To prevent confusion of sendmail wrap < and > around + ** the address (helps to pass addrs like @gw1,@gw2:aa@bb) + */ + + while (*argv != NULL) + { + if (**argv == '-') + err(EX_USAGE, "dash precedes argument: %s", *argv); + + if (strchr(*argv, ',') == NULL || strchr(*argv, '<') != NULL) + args[i++] = *argv; + else + { + len = strlen(*argv) + 3; + if ((args[i] = malloc(len)) == NULL) + err(EX_TEMPFAIL, "Cannot malloc"); + snprintf(args[i++], len, "<%s>", *argv); + } + argv++; + argc--; + + /* Paranoia check, argc used for args[] bound */ + if (argc < 0) + err(EX_SOFTWARE, "Argument count mismatch"); + } + args[i] = NULL; + + if (debug) + { + fprintf(stderr, "Sendmail arguments:\n"); + for (i = 0; args[i] != NULL; i++) + fprintf(stderr, "\t%s\n", args[i]); + } + + /* + ** If called with a regular file as standard input, seek to the right + ** position in the file and just exec sendmail. Could probably skip + ** skip the stat, but it's not unreasonable to believe that a failed + ** seek will cause future reads to fail. + */ + + if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode)) + { + if (lseek(STDIN_FILENO, offset, SEEK_SET) != offset) + err(EX_TEMPFAIL, "stdin seek"); + (void) execv(_PATH_SENDMAIL, args); + err(EX_OSERR, "%s", _PATH_SENDMAIL); + } + + if (pipe(pdes) < 0) + err(EX_OSERR, NULL); + + switch (pid = FORK()) + { + case -1: /* Err. */ + err(EX_OSERR, NULL); + /* NOTREACHED */ + + case 0: /* Child. */ + if (pdes[0] != STDIN_FILENO) + { + (void) dup2(pdes[0], STDIN_FILENO); + (void) close(pdes[0]); + } + (void) close(pdes[1]); + (void) execv(_PATH_SENDMAIL, args); + _exit(127); + /* NOTREACHED */ + } + + if ((fp = fdopen(pdes[1], "w")) == NULL) + err(EX_OSERR, NULL); + (void) close(pdes[0]); + + /* Copy the file down the pipe. */ + do + { + (void) fprintf(fp, "%s", lbuf); + } while (fgets(lbuf, sizeof(lbuf), stdin) != NULL); + + if (ferror(stdin)) + err(EX_TEMPFAIL, "stdin: %s", strerror(errno)); + + if (fclose(fp)) + err(EX_OSERR, NULL); + + if ((waitpid(pid, &status, 0)) == -1) + err(EX_OSERR, "%s", _PATH_SENDMAIL); + + if (!WIFEXITED(status)) + err(EX_OSERR, "%s: did not terminate normally", _PATH_SENDMAIL); + + if (WEXITSTATUS(status)) + err(status, "%s: terminated with %d (non-zero) status", + _PATH_SENDMAIL, WEXITSTATUS(status)); + exit(EX_OK); + /* NOTREACHED */ + return EX_OK; +} + +static void +usage() +{ + (void) fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n"); + exit(EX_USAGE); +} + +#ifdef __STDC__ +# include +#else /* __STDC__ */ +# include +#endif /* __STDC__ */ + +static void +#ifdef __STDC__ +err(int eval, const char *fmt, ...) +#else /* __STDC__ */ +err(eval, fmt, va_alist) + int eval; + const char *fmt; + va_dcl +#endif /* __STDC__ */ +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else /* __STDC__ */ + va_start(ap); +#endif /* __STDC__ */ + (void) fprintf(stderr, "rmail: "); + (void) vfprintf(stderr, fmt, ap); + va_end(ap); + (void) fprintf(stderr, "\n"); + exit(eval); +}