diff options
author | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
---|---|---|
committer | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
commit | 8449595fe97f4474b9b9a7e4edee1ef35dcff393 (patch) | |
tree | e7a33b132264d449a512ddf4a8685df097669c1d /contrib/sendmail/mail.local | |
parent | 289b381b31415647269c7520d881017e2dcb27f1 (diff) | |
download | FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.zip FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.tar.gz |
Import sendmail 8.12.2
Diffstat (limited to 'contrib/sendmail/mail.local')
-rw-r--r-- | contrib/sendmail/mail.local/Makefile.m4 | 5 | ||||
-rw-r--r-- | contrib/sendmail/mail.local/README | 8 | ||||
-rw-r--r-- | contrib/sendmail/mail.local/mail.local.8 | 33 | ||||
-rw-r--r-- | contrib/sendmail/mail.local/mail.local.c | 614 |
4 files changed, 330 insertions, 330 deletions
diff --git a/contrib/sendmail/mail.local/Makefile.m4 b/contrib/sendmail/mail.local/Makefile.m4 index 516850f..63a81a2 100644 --- a/contrib/sendmail/mail.local/Makefile.m4 +++ b/contrib/sendmail/mail.local/Makefile.m4 @@ -1,14 +1,15 @@ include(confBUILDTOOLSDIR`/M4/switch.m4') +define(`confREQUIRE_LIBSM', `true') # sendmail dir SMSRCDIR= ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail') PREPENDDEF(`confENVDEF', `confMAPDEF') PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ') bldPRODUCT_START(`executable', `mail.local') -define(`bldNO_INSTALL') +define(`bldNO_INSTALL', `true') define(`bldSOURCES', `mail.local.c ') -bldPUSH_SMLIB(`smutil') +bldPUSH_SMLIB(`sm') bldPRODUCT_END bldPRODUCT_START(`manpage', `mail.local') diff --git a/contrib/sendmail/mail.local/README b/contrib/sendmail/mail.local/README index 56dac40..651de4b 100644 --- a/contrib/sendmail/mail.local/README +++ b/contrib/sendmail/mail.local/README @@ -2,8 +2,8 @@ This directory contains the source files for mail.local. This is not intended to be used on *stock* System V derived systems such as Solaris or HP-UX, since they use a totally different approach to mailboxes -(essentially, they have a setgid program rather than setuid, and they rely -on the ability to "give away" files to do their work). +(essentially, they have a set-group-ID program rather than set-user-ID, and +they rely on the ability to "give away" files to do their work). If you choose to run *this* mail.local on these systems then you may also need to replace the existing MUAs, as well as IMAP and POP servers, with @@ -29,11 +29,11 @@ your site.config.m4 file with: APPENDDEF(`conf_mail_local_ENVDEF', `-DMAILGID=6') -mail.local will not be installed setuid root. To use it as local +mail.local will not be installed set-user-ID root. To use it as local delivery agent without LMTP mode, use: MODIFY_MAILER_FLAGS(`LOCAL', `+S') in the .mc file. -$Revision: 8.8 $, Last updated $Date: 1999/09/10 01:49:41 $ +$Revision: 8.10 $, Last updated $Date: 2001/09/08 01:21:04 $ diff --git a/contrib/sendmail/mail.local/mail.local.8 b/contrib/sendmail/mail.local/mail.local.8 index 939d772..5cd1c13 100644 --- a/contrib/sendmail/mail.local/mail.local.8 +++ b/contrib/sendmail/mail.local/mail.local.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -8,18 +8,22 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: mail.local.8,v 8.14.14.5 2000/12/29 18:12:16 gshapiro Exp $ +.\" $Id: mail.local.8,v 8.23 2001/04/05 23:27:35 gshapiro Exp $ .\" -.TH MAIL.LOCAL 8 "$Date: 2000/12/29 18:12:16 $" +.TH MAIL.LOCAL 8 "$Date: 2001/04/05 23:27:35 $" .SH NAME mail.local \- store mail in a mailbox .SH SYNOPSIS .B mail.local -.RB [ \-7 "] [" \-b "] [" \-d "] [" \-l "] [" \-f -.IR from "] " -.RB [ \-r -.IR from "] " "user ..." +.RB [ \-7 "] [" \-b "] [" \-d "] [" \-D +.IR mbdb ] +.RB [ \-l "] [" \-f +\fIfrom\fR|\fB\-r\fR +.IR from ] +.RB [ \-h +\fIfilename\fR ] +.I "user ..." .SH DESCRIPTION .B Mail.local reads the standard input up to an end-of-file and appends it to each @@ -40,6 +44,12 @@ if a mailbox exceeds quota. .TP .B \-d Specify this is a delivery (for backward compatibility). +This option has no effect. +.TP +.BI \-D " mbdb" +Specify the name of the mailbox database +which is used to look up local recipient names. +This option defaults to "pw", which means use getpwnam(). .TP .BI \-f " from" Specify the sender's name. @@ -49,6 +59,11 @@ Turn on LMTP mode. .TP .BI \-r " from" Specify the sender's name (for backward compatibility). +Same as \-f. +.TP +.BI \-h " filename" +Store incoming mail in \fIfilename\fR in the user's home directory instead +of a system mail spool directory. .PP Individual mail messages in the mailbox are delimited by an empty line followed by a line beginning with the string ``From ''. @@ -86,10 +101,10 @@ Used to set the appropriate time zone on the timestamp. temporary files .TP /var/mail/user -user's mailbox directory +user's default mailbox directory .TP /var/mail/user.lock -lock file for a user's mailbox +lock file for a user's default mailbox .PD .SH SEE ALSO mail(1), diff --git a/contrib/sendmail/mail.local/mail.local.c b/contrib/sendmail/mail.local/mail.local.c index cd96c5e..8a93f01 100644 --- a/contrib/sendmail/mail.local/mail.local.c +++ b/contrib/sendmail/mail.local/mail.local.c @@ -10,232 +10,111 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1990, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") + +SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.235 2001/12/30 04:59:39 gshapiro Exp $") -#ifndef lint -static char id[] = "@(#)$Id: mail.local.c,v 8.143.4.58 2001/06/01 05:33:31 gshapiro Exp $"; -#endif /* ! lint */ +#include <stdlib.h> +#include <sm/errstring.h> +#include <sm/io.h> +#include <sm/limits.h> +# include <unistd.h> +# ifdef EX_OK +# undef EX_OK /* unistd.h may have another use for this */ +# endif /* EX_OK */ +#include <sm/mbdb.h> +#include <sm/sysexits.h> /* ** This is not intended to work on System V derived systems ** such as Solaris or HP-UX, since they use a totally different -** approach to mailboxes (essentially, they have a setgid program -** rather than setuid, and they rely on the ability to "give away" +** approach to mailboxes (essentially, they have a set-group-ID program +** rather than set-user-ID, and they rely on the ability to "give away" ** files to do their work). IT IS NOT A BUG that this doesn't ** work on such architectures. */ -/* additional mode for open() */ -# define EXTRA_MODE 0 - -# include <sys/types.h> -# include <sys/param.h> -# include <sys/stat.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <stdlib.h> # include <sys/socket.h> # include <sys/file.h> - # include <netinet/in.h> # include <arpa/nameser.h> - -# include <fcntl.h> # include <netdb.h> -# include <pwd.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <syslog.h> -# include <time.h> -# include <unistd.h> -# ifdef EX_OK -# undef EX_OK /* unistd.h may have another use for this */ -# endif /* EX_OK */ -# include <sysexits.h> -# include <ctype.h> +# include <pwd.h> -# ifndef __P -# include "sendmail/cdefs.h" -# endif /* ! __P */ -# include "sendmail/useful.h" - -extern size_t strlcpy __P((char *, const char *, size_t)); -extern size_t strlcat __P((char *, const char *, size_t)); - -# 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) */ - -# include "sendmail/errstring.h" - -# ifndef LOCKTO_RM -# define LOCKTO_RM 300 /* timeout for stale lockfile removal */ -# endif /* ! LOCKTO_RM */ -# ifndef LOCKTO_GLOB -# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */ -# endif /* ! LOCKTO_GLOB */ - -# ifdef __STDC__ -# include <stdarg.h> -# define REALLOC(ptr, size) realloc(ptr, size) -# else /* __STDC__ */ -# include <varargs.h> -/* define a realloc() which works for NULL pointers */ -# define REALLOC(ptr, size) (((ptr) == NULL) ? malloc(size) : realloc(ptr, size)) -# endif /* __STDC__ */ - -# if (defined(sun) && defined(__svr4__)) || defined(__SVR4) -# define USE_LOCKF 1 -# define USE_SETEUID 1 -# define _PATH_MAILDIR "/var/mail" -# endif /* (defined(sun) && defined(__svr4__)) || defined(__SVR4) */ - -# ifdef NCR_MP_RAS3 -# define USE_LOCKF 1 -# define HASSNPRINTF 1 -# define _PATH_MAILDIR "/var/mail" -# endif /* NCR_MP_RAS3 */ - -# if defined(_AIX) -# define USE_LOCKF 1 -# define USE_SETEUID 1 -# endif /* defined(_AIX) */ - -# if defined(__hpux) -# define USE_LOCKF 1 -# define USE_SETRESUID 1 -# endif /* defined(__hpux) */ - -# ifdef DGUX -# define HASSNPRINTF 1 -# define USE_LOCKF 1 -# endif /* DGUX */ - -# if defined(_CRAY) -# if !defined(MAXPATHLEN) -# define MAXPATHLEN PATHSIZE -# endif /* !defined(MAXPATHLEN) */ -# define _PATH_MAILDIR "/usr/spool/mail" -# endif /* defined(_CRAY) */ - -# if defined(NeXT) && !defined(__APPLE__) -# include <libc.h> -# define _PATH_MAILDIR "/usr/spool/mail" -# define S_IRUSR S_IREAD -# define S_IWUSR S_IWRITE -# endif /* defined(NeXT) && !defined(__APPLE__) */ - -# if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) -# include <paths.h> -# endif /* defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ +#include <sm/string.h> +#include <syslog.h> +#include <ctype.h> -/* - * If you don't have flock, you could try using lockf instead. - */ +#include <sm/conf.h> +#include <sendmail/pathnames.h> -# ifdef USE_LOCKF -# define flock(a, b) lockf(a, b, 0) -# ifdef LOCK_EX -# undef LOCK_EX -# endif /* LOCK_EX */ -# define LOCK_EX F_LOCK -# endif /* USE_LOCKF */ - -# ifndef LOCK_EX -# include <sys/file.h> -# endif /* ! LOCK_EX */ - -# if defined(BSD4_4) || defined(__GLIBC__) -# include <paths.h> -# define _PATH_LOCTMP "/tmp/local.XXXXXX" -# endif /* defined(BSD4_4) || defined(__GLIBC__) */ - -# ifdef BSD4_4 -# define HAS_ST_GEN 1 -# else /* BSD4_4 */ -# ifndef _BSD_VA_LIST_ -# define _BSD_VA_LIST_ va_list -# endif /* ! _BSD_VA_LIST_ */ -# endif /* BSD4_4 */ - -# if defined(BSD4_4) || defined(linux) -# define HASSNPRINTF 1 -# else /* defined(BSD4_4) || defined(linux) */ -# ifndef ultrix -extern FILE *fdopen __P((int, const char *)); -# endif /* ! ultrix */ -# endif /* defined(BSD4_4) || defined(linux) */ - -# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) -# define CONTENTLENGTH 1 /* Needs the Content-Length header */ -# endif /* SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) */ - -# if SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) -# define HASSNPRINTF 1 /* has snprintf starting in 2.6 */ -# endif /* SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) */ - -# ifdef HPUX11 -# define HASSNPRINTF 1 /* has snprintf starting in 11.X */ -# endif /* HPUX11 */ - -# if _AIX4 >= 40300 -# define HASSNPRINTF 1 /* has snprintf starting in 4.3 */ -# endif /* _AIX4 >= 40300 */ - -# if !HASSNPRINTF && !SFIO -extern int snprintf __P((char *, size_t, const char *, ...)); -# ifndef _CRAY -extern int vsnprintf __P((char *, size_t, const char *, ...)); -# endif /* ! _CRAY */ -# endif /* !HASSNPRINTF && !SFIO */ -/* -** If you don't have setreuid, and you have saved uids, and you have -** a seteuid() call that doesn't try to emulate using setuid(), then -** you can try defining USE_SETEUID. -*/ +/* additional mode for open() */ +# define EXTRA_MODE 0 + -# ifdef USE_SETEUID -# define setreuid(r, e) seteuid(e) -# endif /* USE_SETEUID */ +#ifndef LOCKTO_RM +# define LOCKTO_RM 300 /* timeout for stale lockfile removal */ +#endif /* ! LOCKTO_RM */ +#ifndef LOCKTO_GLOB +# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */ +#endif /* ! LOCKTO_GLOB */ + +/* define a realloc() which works for NULL pointers */ +#define REALLOC(ptr, size) (((ptr) == NULL) ? malloc(size) : realloc(ptr, size)) /* -** And of course on hpux you have setresuid() +** If you don't have flock, you could try using lockf instead. */ -# ifdef USE_SETRESUID -# define setreuid(r, e) setresuid(-1, e, -1) -# endif /* USE_SETRESUID */ +#ifdef LDA_USE_LOCKF +# define flock(a, b) lockf(a, b, 0) +# ifdef LOCK_EX +# undef LOCK_EX +# endif /* LOCK_EX */ +# define LOCK_EX F_LOCK +#endif /* LDA_USE_LOCKF */ -# ifndef _PATH_LOCTMP -# define _PATH_LOCTMP "/tmp/local.XXXXXX" -# endif /* ! _PATH_LOCTMP */ -# ifndef _PATH_MAILDIR -# define _PATH_MAILDIR "/var/spool/mail" -# endif /* ! _PATH_MAILDIR */ +#ifndef LOCK_EX +# include <sys/file.h> +#endif /* ! LOCK_EX */ -# ifndef S_ISREG -# define S_ISREG(mode) (((mode) & _S_IFMT) == S_IFREG) -# endif /* ! S_ISREG */ +/* +** If you don't have setreuid, and you have saved uids, and you have +** a seteuid() call that doesn't try to emulate using setuid(), then +** you can try defining LDA_USE_SETEUID. +*/ -# ifdef MAILLOCK -# include <maillock.h> -# endif /* MAILLOCK */ +#ifdef LDA_USE_SETEUID +# define setreuid(r, e) seteuid(e) +#endif /* LDA_USE_SETEUID */ -# define U_UID pw->pw_uid -# define U_GID pw->pw_gid +#ifdef LDA_CONTENTLENGTH +# define CONTENTLENGTH 1 +#endif /* LDA_CONTENTLENGTH */ #ifndef INADDRSZ # define INADDRSZ 4 /* size of an IPv4 address in bytes */ #endif /* ! INADDRSZ */ +#ifdef MAILLOCK +# include <maillock.h> +#endif /* MAILLOCK */ + #ifndef MAILER_DAEMON # define MAILER_DAEMON "MAILER-DAEMON" #endif /* ! MAILER_DAEMON */ @@ -246,17 +125,18 @@ off_t HeaderLength; off_t BodyLength; #endif /* CONTENTLENGTH */ -bool EightBitMime = TRUE; /* advertise 8BITMIME in LMTP */ +bool EightBitMime = true; /* advertise 8BITMIME in LMTP */ char ErrBuf[10240]; /* error buffer */ int ExitVal = EX_OK; /* sysexits.h error value. */ -bool HoldErrs = FALSE; /* Hold errors in ErrBuf */ -bool LMTPMode = FALSE; -bool BounceQuota = FALSE; /* permanent error when over quota */ +bool HoldErrs = false; /* Hold errors in ErrBuf */ +bool LMTPMode = false; +bool BounceQuota = false; /* permanent error when over quota */ +char *HomeMailFile = NULL; /* store mail in homedir */ void deliver __P((int, char *)); int e_to_sys __P((int)); void notifybiff __P((char *)); -int store __P((char *, int, bool *)); +int store __P((char *, bool *)); void usage __P((void)); int lockmbox __P((char *)); void unlockmbox __P((void)); @@ -273,6 +153,8 @@ main(argc, argv) int ch, fd; uid_t uid; char *from; + char *mbdbname = "pw"; + int err; extern char *optarg; extern int optind; @@ -291,21 +173,25 @@ main(argc, argv) # endif /* LOG_MAIL */ from = NULL; - while ((ch = getopt(argc, argv, "7bdf:r:l")) != -1) + while ((ch = getopt(argc, argv, "7bdD:f:h:r:l")) != -1) { switch(ch) { case '7': /* Do not advertise 8BITMIME */ - EightBitMime = FALSE; + EightBitMime = false; break; case 'b': /* bounce mail when over quota. */ - BounceQuota = TRUE; + BounceQuota = true; break; case 'd': /* Backward compatible. */ break; + case 'D': /* mailbox database type */ + mbdbname = optarg; + break; + case 'f': case 'r': /* Backward compatible. */ if (from != NULL) @@ -316,8 +202,18 @@ main(argc, argv) from = optarg; break; + case 'h': + if (optarg != NULL || *optarg != '\0') + HomeMailFile = optarg; + else + { + mailerr(NULL, "-h: missing filename"); + usage(); + } + break; + case 'l': - LMTPMode = TRUE; + LMTPMode = true; break; case '?': @@ -331,6 +227,19 @@ main(argc, argv) /* initialize biff structures */ notifybiff(NULL); + err = sm_mbdb_initialize(mbdbname); + if (err != EX_OK) + { + char *errcode = "521"; + + if (err == EX_TEMPFAIL) + errcode = "421"; + + mailerr(errcode, "Can not open mailbox database %s: %s", + mbdbname, sm_strexit(err)); + exit(err); + } + if (LMTPMode) { extern void dolmtp __P((void)); @@ -357,7 +266,6 @@ main(argc, argv) */ uid = getuid(); - if (from == NULL && ((from = getlogin()) == NULL || (pw = getpwnam(from)) == NULL || pw->pw_uid != uid)) @@ -373,9 +281,9 @@ main(argc, argv) ** at the expense of repeated failures and multiple deliveries. */ - HoldErrs = TRUE; - fd = store(from, 0, NULL); - HoldErrs = FALSE; + HoldErrs = true; + fd = store(from, NULL); + HoldErrs = false; if (fd < 0) { flush_error(); @@ -467,6 +375,8 @@ parseaddr(s, rcpt) s = MAILER_DAEMON; l = strlen(s) + 1; + if (l < 0) + return NULL; p = malloc(l); if (p == NULL) { @@ -474,7 +384,7 @@ parseaddr(s, rcpt) exit(EX_TEMPFAIL); } - (void) strlcpy(p, s, l); + (void) sm_strlcpy(p, s, l); return p; } @@ -482,9 +392,22 @@ char * process_recipient(addr) char *addr; { - if (getpwnam(addr) == NULL) + SM_MBDB_T user; + + switch (sm_mbdb_lookup(addr, &user)) + { + case EX_OK: + return NULL; + + case EX_NOUSER: return "550 5.1.1 User unknown"; - return NULL; + + case EX_TEMPFAIL: + return "451 4.3.0 User database failure; retry later"; + + default: + return "550 5.3.0 User database failure"; + } } #define RCPT_GROW 30 @@ -496,7 +419,7 @@ dolmtp() char **rcpt_addr = NULL; int rcpt_num = 0; int rcpt_alloc = 0; - bool gotlhlo = FALSE; + bool gotlhlo = false; char *err; int msgfd; char *p; @@ -507,7 +430,7 @@ dolmtp() memset(myhostname, '\0', sizeof myhostname); (void) gethostname(myhostname, sizeof myhostname - 1); if (myhostname[0] == '\0') - strlcpy(myhostname, "localhost", sizeof myhostname); + sm_strlcpy(myhostname, "localhost", sizeof myhostname); printf("220 %s LMTP ready\r\n", myhostname); for (;;) @@ -525,18 +448,18 @@ dolmtp() { case 'd': case 'D': - if (strcasecmp(buf, "data") == 0) + if (sm_strcasecmp(buf, "data") == 0) { - bool inbody = FALSE; + bool inbody = false; if (rcpt_num == 0) { mailerr("503 5.5.1", "No recipients"); continue; } - HoldErrs = TRUE; - msgfd = store(return_path, rcpt_num, &inbody); - HoldErrs = FALSE; + HoldErrs = true; + msgfd = store(return_path, &inbody); + HoldErrs = false; if (msgfd < 0 && !inbody) { flush_error(); @@ -566,7 +489,7 @@ dolmtp() case 'l': case 'L': - if (strncasecmp(buf, "lhlo ", 5) == 0) + if (sm_strncasecmp(buf, "lhlo ", 5) == 0) { /* check for duplicate per RFC 1651 4.2 */ if (gotlhlo) @@ -575,7 +498,7 @@ dolmtp() myhostname); continue; } - gotlhlo = TRUE; + gotlhlo = true; printf("250-%s\r\n", myhostname); if (EightBitMime) printf("250-8BITMIME\r\n"); @@ -589,7 +512,7 @@ dolmtp() case 'm': case 'M': - if (strncasecmp(buf, "mail ", 5) == 0) + if (sm_strncasecmp(buf, "mail ", 5) == 0) { if (return_path != NULL) { @@ -597,9 +520,9 @@ dolmtp() "Nested MAIL command"); continue; } - if (strncasecmp(buf+5, "from:", 5) != 0 || + if (sm_strncasecmp(buf+5, "from:", 5) != 0 || ((return_path = parseaddr(buf + 10, - FALSE)) == NULL)) + false)) == NULL)) { mailerr("501 5.5.4", "Syntax error in parameters"); @@ -614,7 +537,7 @@ dolmtp() case 'n': case 'N': - if (strcasecmp(buf, "noop") == 0) + if (sm_strcasecmp(buf, "noop") == 0) { printf("250 2.0.0 Ok\r\n"); continue; @@ -625,7 +548,7 @@ dolmtp() case 'q': case 'Q': - if (strcasecmp(buf, "quit") == 0) + if (sm_strcasecmp(buf, "quit") == 0) { printf("221 2.0.0 Bye\r\n"); exit(EX_OK); @@ -636,7 +559,7 @@ dolmtp() case 'r': case 'R': - if (strncasecmp(buf, "rcpt ", 5) == 0) + if (sm_strncasecmp(buf, "rcpt ", 5) == 0) { if (return_path == NULL) { @@ -658,9 +581,9 @@ dolmtp() exit(EX_TEMPFAIL); } } - if (strncasecmp(buf + 5, "to:", 3) != 0 || + if (sm_strncasecmp(buf + 5, "to:", 3) != 0 || ((rcpt_addr[rcpt_num] = parseaddr(buf + 8, - TRUE)) == NULL)) + true)) == NULL)) { mailerr("501 5.5.4", "Syntax error in parameters"); @@ -676,7 +599,7 @@ dolmtp() printf("250 2.1.5 Ok\r\n"); continue; } - else if (strcasecmp(buf, "rset") == 0) + else if (sm_strcasecmp(buf, "rset") == 0) { printf("250 2.0.0 Ok\r\n"); @@ -694,7 +617,7 @@ rset: case 'v': case 'V': - if (strncasecmp(buf, "vrfy ", 5) == 0) + if (sm_strncasecmp(buf, "vrfy ", 5) == 0) { printf("252 2.3.3 Try RCPT to attempt delivery\r\n"); continue; @@ -714,25 +637,24 @@ rset: } int -store(from, lmtprcpts, inbody) +store(from, inbody) char *from; - int lmtprcpts; bool *inbody; { FILE *fp = NULL; time_t tval; - bool eline; - bool fullline = TRUE; /* current line is terminated */ + bool eline; /* previous line was empty */ + bool fullline = true; /* current line is terminated */ bool prevfl; /* previous line was terminated */ char line[2048]; int fd; char tmpbuf[sizeof _PATH_LOCTMP + 1]; if (inbody != NULL) - *inbody = FALSE; + *inbody = false; (void) umask(0077); - (void) strlcpy(tmpbuf, _PATH_LOCTMP, sizeof tmpbuf); + (void) sm_strlcpy(tmpbuf, _PATH_LOCTMP, sizeof tmpbuf); if ((fd = mkstemp(tmpbuf)) < 0 || (fp = fdopen(fd, "w+")) == NULL) { mailerr("451 4.3.0", "Unable to open temporary file"); @@ -746,7 +668,7 @@ store(from, lmtprcpts, inbody) (void) fflush(stdout); } if (inbody != NULL) - *inbody = TRUE; + *inbody = true; (void) time(&tval); (void) fprintf(fp, "From %s %s", from, ctime(&tval)); @@ -757,7 +679,7 @@ store(from, lmtprcpts, inbody) #endif /* CONTENTLENGTH */ line[0] = '\0'; - eline = TRUE; + eline = true; while (fgets(line, sizeof(line), stdin) != (char *) NULL) { size_t line_len = 0; @@ -779,7 +701,7 @@ store(from, lmtprcpts, inbody) } /* Check to see if we have the full line from fgets() */ - fullline = FALSE; + fullline = false; if (line_len > 0) { if (line[line_len - 1] == '\n') @@ -791,7 +713,7 @@ store(from, lmtprcpts, inbody) line[line_len - 1] = '\0'; line_len--; } - fullline = TRUE; + fullline = true; } else if (line[line_len - 1] == '\r') { @@ -800,19 +722,19 @@ store(from, lmtprcpts, inbody) if (peek == '\n') { line[line_len - 1] = '\n'; - fullline = TRUE; + fullline = true; } else (void) ungetc(peek, stdin); } } else - fullline = TRUE; + fullline = true; #ifdef CONTENTLENGTH if (prevfl && line[0] == '\n' && HeaderLength == 0) { - eline = FALSE; + eline = false; if (fp != NULL) HeaderLength = ftell(fp); if (HeaderLength <= 0) @@ -827,7 +749,7 @@ store(from, lmtprcpts, inbody) } #else /* CONTENTLENGTH */ if (prevfl && line[0] == '\n') - eline = TRUE; + eline = true; #endif /* CONTENTLENGTH */ else { @@ -835,12 +757,12 @@ store(from, lmtprcpts, inbody) fp != NULL && !memcmp(line, "From ", 5)) (void) putc('>', fp); - eline = FALSE; + eline = false; #ifdef CONTENTLENGTH /* discard existing "Content-Length:" headers */ if (prevfl && HeaderLength == 0 && (line[0] == 'C' || line[0] == 'c') && - strncasecmp(line, ContentHdr, 15) == 0) + sm_strncasecmp(line, ContentHdr, 15) == 0) { /* ** be paranoid: clear the line @@ -895,15 +817,10 @@ store(from, lmtprcpts, inbody) if (HeaderLength > 0 && BodyLength >= 0) { - extern char *quad_to_string(); - - if (sizeof BodyLength > sizeof(long)) - snprintf(line, sizeof line, "%s\n", - quad_to_string(BodyLength)); - else - snprintf(line, sizeof line, "%ld\n", - (long) BodyLength); - strlcpy(&ContentHdr[16], line, sizeof(ContentHdr) - 16); + (void) sm_snprintf(line, sizeof line, "%lld\n", + (LONGLONG_T) BodyLength); + (void) sm_strlcpy(&ContentHdr[16], line, + sizeof(ContentHdr) - 16); } else BodyLength = -1; /* Something is wrong here */ @@ -930,9 +847,9 @@ deliver(fd, name) { struct stat fsb; struct stat sb; - struct passwd *pw; char path[MAXPATHLEN]; int mbfd = -1, nr = 0, nw, off; + int exitval; char *p; char *errcode; off_t curoff; @@ -941,26 +858,42 @@ deliver(fd, name) int readamount; #endif /* CONTENTLENGTH */ char biffmsg[100], buf[8*1024]; - extern char *quad_to_string(); - + SM_MBDB_T user; /* ** Disallow delivery to unknown names -- special mailboxes can be ** handled in the sendmail aliases file. */ - if ((pw = getpwnam(name)) == NULL) + exitval = sm_mbdb_lookup(name, &user); + switch (exitval) { - if (ExitVal == EX_TEMPFAIL) - errcode = "451 4.3.0"; - else - { - ExitVal = EX_UNAVAILABLE; - errcode = "550 5.1.1"; - } - mailerr(errcode, "Unknown name: %s", name); + case EX_OK: + break; + + case EX_NOUSER: + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: User unknown", name); + break; + + case EX_TEMPFAIL: + mailerr("451 4.3.0", "%s: User database failure; retry later", + name); + break; + + default: + exitval = EX_UNAVAILABLE; + mailerr("550 5.3.0", "%s: User database failure", name); + break; + } + + if (exitval != EX_OK) + { + if (ExitVal != EX_TEMPFAIL) + ExitVal = exitval; return; } + endpwent(); /* @@ -982,7 +915,29 @@ deliver(fd, name) } - (void) snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, name); + if (HomeMailFile == NULL) + { + if (sm_snprintf(path, sizeof(path), "%s/%s", + _PATH_MAILDIR, name) >= sizeof(path)) + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: Invalid mailbox path", name); + return; + } + } + else if (*user.mbdb_homedir == '\0') + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: User missing home directory", name); + return; + } + else if (sm_snprintf(path, sizeof(path), "%s/%s", + user.mbdb_homedir, HomeMailFile) >= sizeof(path)) + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: Invalid mailbox path", name); + return; + } /* @@ -1024,7 +979,7 @@ tryagain: errcode = "551 5.3.0"; mailerr(errcode, "lockmailbox %s failed; error code %d %s", - p, off, errno > 0 ? errstring(errno) : ""); + p, off, errno > 0 ? sm_errstring(errno) : ""); return; } @@ -1032,7 +987,7 @@ tryagain: { int save_errno; int mode = S_IRUSR|S_IWUSR; - gid_t gid = U_GID; + gid_t gid = user.mbdb_gid; #ifdef MAILGID (void) umask(0007); @@ -1058,13 +1013,13 @@ tryagain: /* open failed, don't try again */ mailerr("450 4.2.0", "%s: %s", path, - errstring(save_errno)); + sm_errstring(save_errno)); goto err0; } - else if (fchown(mbfd, U_UID, gid) < 0) + else if (fchown(mbfd, user.mbdb_uid, gid) < 0) { mailerr("451 4.3.0", "chown %u.%u: %s", - U_UID, gid, name); + user.mbdb_uid, gid, name); goto err1; } else @@ -1076,7 +1031,7 @@ tryagain: ** is no longer valid; better safe than sorry. */ - sb.st_uid = U_UID; + sb.st_uid = user.mbdb_uid; (void) close(mbfd); mbfd = -1; } @@ -1086,28 +1041,29 @@ tryagain: mailerr("550 5.2.0", "%s: irregular file", path); goto err0; } - else if (sb.st_uid != U_UID) + else if (sb.st_uid != user.mbdb_uid) { ExitVal = EX_CANTCREAT; mailerr("550 5.2.0", "%s: wrong ownership (%d)", - path, sb.st_uid); + path, (int) sb.st_uid); goto err0; } /* change UID for quota checks */ - if (setreuid(0, U_UID) < 0) + if (setreuid(0, user.mbdb_uid) < 0) { mailerr("450 4.2.0", "setreuid(0, %d): %s (r=%d, e=%d)", - U_UID, errstring(errno), getuid(), geteuid()); + (int) user.mbdb_uid, sm_errstring(errno), + (int) getuid(), (int) geteuid()); goto err1; } #ifdef DEBUG - fprintf(stderr, "new euid = %d\n", geteuid()); + fprintf(stderr, "new euid = %d\n", (int) geteuid()); #endif /* DEBUG */ mbfd = open(path, O_APPEND|O_WRONLY|EXTRA_MODE, 0); if (mbfd < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); goto err0; } else if (fstat(mbfd, &fsb) < 0 || @@ -1127,32 +1083,65 @@ tryagain: goto err1; } +#if 0 + /* + ** This code could be reused if we decide to add a + ** per-user quota field to the sm_mbdb interface. + */ + + /* + ** Fail if the user has a quota specified, and delivery of this + ** message would exceed that quota. We bounce such failures using + ** EX_UNAVAILABLE, unless there were internal problems, since + ** storing immense messages for later retries can cause queueing + ** issues. + */ + + if (ui.quota > 0) + { + struct stat dsb; + + if (fstat(fd, &dsb) < 0) + { + ExitVal = EX_TEMPFAIL; + mailerr("451 4.3.0", + "%s: fstat: can't stat temporary storage: %s", + ui.mailspool, sm_errstring(errno)); + goto err1; + } + + if (dsb.st_size + sb.st_size + 1 > ui.quota) + { + ExitVal = EX_UNAVAILABLE; + mailerr("551 5.2.2", + "%s: Mailbox full or quota exceeded", + ui.mailspool); + goto err1; + } + } +#endif /* 0 */ /* Wait until we can get a lock on the file. */ if (flock(mbfd, LOCK_EX) < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); goto err1; } /* Get the starting offset of the new message for biff. */ curoff = lseek(mbfd, (off_t) 0, SEEK_END); - if (sizeof curoff > sizeof(long)) - (void) snprintf(biffmsg, sizeof(biffmsg), "%s@%s\n", - name, quad_to_string(curoff)); - else - (void) snprintf(biffmsg, sizeof(biffmsg), "%s@%ld\n", - name, (long) curoff); + (void) sm_snprintf(biffmsg, sizeof(biffmsg), "%s@%lld\n", + name, (LONGLONG_T) curoff); /* Copy the message into the file. */ if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) { mailerr("450 4.2.0", "Temporary file: %s", - errstring(errno)); + sm_errstring(errno)); goto err1; } #ifdef DEBUG - fprintf(stderr, "before writing: euid = %d\n", geteuid()); + fprintf(stderr, "before writing: euid = %d\n", (int) geteuid()); #endif /* DEBUG */ #ifdef CONTENTLENGTH headerbytes = (BodyLength >= 0) ? HeaderLength : -1 ; @@ -1160,7 +1149,7 @@ tryagain: { if (headerbytes == 0) { - snprintf(buf, sizeof buf, "%s", ContentHdr); + (void) sm_snprintf(buf, sizeof buf, "%s", ContentHdr); nr = strlen(buf); headerbytes = -1; readamount = 0; @@ -1190,7 +1179,7 @@ tryagain: errcode = "552 5.2.2"; #endif /* EDQUOT */ mailerr(errcode, "%s: %s", - path, errstring(errno)); + path, sm_errstring(errno)); goto err3; } } @@ -1198,18 +1187,18 @@ tryagain: if (nr < 0) { mailerr("450 4.2.0", "Temporary file: %s", - errstring(errno)); + sm_errstring(errno)); goto err3; } /* Flush to disk, don't wait for update. */ if (fsync(mbfd) < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); err3: (void) setreuid(0, 0); #ifdef DEBUG - fprintf(stderr, "reset euid = %d\n", geteuid()); + fprintf(stderr, "reset euid = %d\n", (int) geteuid()); #endif /* DEBUG */ (void) ftruncate(mbfd, curoff); err1: if (mbfd >= 0) @@ -1226,7 +1215,7 @@ err0: unlockmbox(); if (errno == EDQUOT && BounceQuota) errcode = "552 5.2.2"; #endif /* EDQUOT */ - mailerr(errcode, "%s: %s", path, errstring(errno)); + mailerr(errcode, "%s: %s", path, sm_errstring(errno)); (void) truncate(path, curoff); } else @@ -1235,11 +1224,11 @@ err0: unlockmbox(); if (setreuid(0, 0) < 0) { mailerr("450 4.2.0", "setreuid(0, 0): %s", - errstring(errno)); + sm_errstring(errno)); goto err0; } #ifdef DEBUG - fprintf(stderr, "reset euid = %d\n", geteuid()); + fprintf(stderr, "reset euid = %d\n", (int) geteuid()); #endif /* DEBUG */ unlockmbox(); if (LMTPMode) @@ -1253,7 +1242,7 @@ err0: unlockmbox(); ** EPA 11/94. */ -bool Locked = FALSE; +bool Locked = false; #ifdef MAILLOCK int @@ -1266,7 +1255,7 @@ lockmbox(name) return 0; if ((r = maillock(name, 15)) == L_SUCCESS) { - Locked = TRUE; + Locked = true; return 0; } switch (r) @@ -1293,7 +1282,7 @@ unlockmbox() { if (Locked) mailunlock(); - Locked = FALSE; + Locked = false; } #else /* MAILLOCK */ @@ -1310,7 +1299,7 @@ lockmbox(path) return 0; if (strlen(path) + 6 > sizeof LockName) return EX_SOFTWARE; - (void) snprintf(LockName, sizeof LockName, "%s.lock", path); + (void) sm_snprintf(LockName, sizeof LockName, "%s.lock", path); (void) time(&start); for (; ; sleep(5)) { @@ -1330,7 +1319,7 @@ lockmbox(path) { /* defeat lock checking programs which test pid */ (void) write(fd, "0", 2); - Locked = TRUE; + Locked = true; (void) close(fd); return 0; } @@ -1360,7 +1349,7 @@ unlockmbox() if (!Locked) return; (void) unlink(LockName); - Locked = FALSE; + Locked = false; } #endif /* MAILLOCK */ @@ -1368,7 +1357,7 @@ void notifybiff(msg) char *msg; { - static bool initialized = FALSE; + static bool initialized = false; static int f = -1; struct hostent *hp; struct servent *sp; @@ -1377,7 +1366,7 @@ notifybiff(msg) if (!initialized) { - initialized = TRUE; + initialized = true; /* Be silent if biff service not available. */ if ((sp = getservbyname("biff", "udp")) == NULL || @@ -1408,11 +1397,12 @@ void usage() { ExitVal = EX_USAGE; - mailerr(NULL, "usage: mail.local [-7] [-b] [-l] [-f from] user ..."); + mailerr(NULL, "usage: mail.local [-7] [-b] [-d] [-l] [-f from|-r from] [-h filename] user ..."); exit(ExitVal); } void +/*VARARGS2*/ #ifdef __STDC__ mailerr(const char *hdr, const char *fmt, ...) #else /* __STDC__ */ @@ -1423,25 +1413,19 @@ mailerr(hdr, fmt, va_alist) #endif /* __STDC__ */ { size_t len = 0; - va_list ap; + SM_VA_LOCAL_DECL (void) e_to_sys(errno); -#ifdef __STDC__ - va_start(ap, fmt); -#else /* __STDC__ */ - va_start(ap); -#endif /* __STDC__ */ + SM_VA_START(ap, fmt); - if (LMTPMode) + if (LMTPMode && hdr != NULL) { - if (hdr != NULL) - { - snprintf(ErrBuf, sizeof ErrBuf, "%s ", hdr); - len = strlen(ErrBuf); - } + sm_snprintf(ErrBuf, sizeof ErrBuf, "%s ", hdr); + len = strlen(ErrBuf); } - (void) vsnprintf(&ErrBuf[len], sizeof ErrBuf - len, fmt, ap); + (void) sm_vsnprintf(&ErrBuf[len], sizeof ErrBuf - len, fmt, ap); + SM_VA_END(ap); if (!HoldErrs) flush_error(); @@ -1630,7 +1614,7 @@ _gettemp(path, doopen) extern int errno; register char *start, *trv; struct stat sbuf; - u_int pid; + unsigned int pid; pid = getpid(); for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ |