summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/mail.local
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2002-02-17 21:58:34 +0000
committergshapiro <gshapiro@FreeBSD.org>2002-02-17 21:58:34 +0000
commitabfa0083ecf0cbde95c81f59afd36870955aeb56 (patch)
tree7491d7ffbd831bb5ee83a1c7ccf996022f5538a5 /contrib/sendmail/mail.local
parent514d1553cc1f49dd008e6e432664359124af60a9 (diff)
downloadFreeBSD-src-abfa0083ecf0cbde95c81f59afd36870955aeb56.zip
FreeBSD-src-abfa0083ecf0cbde95c81f59afd36870955aeb56.tar.gz
Resolve conflicts from sendmail 8.12.2 import
Diffstat (limited to 'contrib/sendmail/mail.local')
-rw-r--r--contrib/sendmail/mail.local/mail.local.833
-rw-r--r--contrib/sendmail/mail.local/mail.local.c618
2 files changed, 325 insertions, 326 deletions
diff --git a/contrib/sendmail/mail.local/mail.local.8 b/contrib/sendmail/mail.local/mail.local.8
index 2b23c31..2720578 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,20 +8,24 @@
.\" 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 $
.\"
.\" $FreeBSD$
.\"
-.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 "] [" \-b "] [" \-d "] [" \-l "] [" \-s "] [" \-f
-.IR from "] "
-.RB [ \-r
-.IR from "] " "user ..."
+.RB [ \-7 "] [" \-B "] [" \-b "] [" \-d "] [" \-D
+.IR mbdb ]
+.RB [ \-l "] [" \-s "] [" \-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
@@ -47,6 +51,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.
@@ -63,6 +73,11 @@ status.
.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 ''.
@@ -100,10 +115,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 5eca2e4..cd13f44 100644
--- a/contrib/sendmail/mail.local/mail.local.c
+++ b/contrib/sendmail/mail.local/mail.local.c
@@ -10,234 +10,113 @@
*
*/
-#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>
/* $FreeBSD$ */
/*
** 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 "/var/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 "/var/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 */
@@ -248,19 +127,20 @@ 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 nobiff = FALSE;
-bool nofsync = FALSE;
+bool nobiff = false;
+bool nofsync = false;
+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));
@@ -277,6 +157,8 @@ main(argc, argv)
int ch, fd;
uid_t uid;
char *from;
+ char *mbdbname = "pw";
+ int err;
extern char *optarg;
extern int optind;
@@ -295,12 +177,12 @@ main(argc, argv)
# endif /* LOG_MAIL */
from = NULL;
- while ((ch = getopt(argc, argv, "7Bbdf:r:ls")) != -1)
+ while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1)
{
switch(ch)
{
case '7': /* Do not advertise 8BITMIME */
- EightBitMime = FALSE;
+ EightBitMime = false;
break;
case 'B':
@@ -308,12 +190,16 @@ main(argc, argv)
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)
@@ -324,8 +210,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 's':
@@ -344,6 +240,19 @@ main(argc, argv)
if (!nobiff)
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));
@@ -370,7 +279,6 @@ main(argc, argv)
*/
uid = getuid();
-
if (from == NULL && ((from = getlogin()) == NULL ||
(pw = getpwnam(from)) == NULL ||
pw->pw_uid != uid))
@@ -386,9 +294,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();
@@ -480,6 +388,8 @@ parseaddr(s, rcpt)
s = MAILER_DAEMON;
l = strlen(s) + 1;
+ if (l < 0)
+ return NULL;
p = malloc(l);
if (p == NULL)
{
@@ -487,7 +397,7 @@ parseaddr(s, rcpt)
exit(EX_TEMPFAIL);
}
- (void) strlcpy(p, s, l);
+ (void) sm_strlcpy(p, s, l);
return p;
}
@@ -495,9 +405,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
@@ -509,7 +432,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;
@@ -520,7 +443,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 (;;)
@@ -538,18 +461,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();
@@ -579,7 +502,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)
@@ -588,7 +511,7 @@ dolmtp()
myhostname);
continue;
}
- gotlhlo = TRUE;
+ gotlhlo = true;
printf("250-%s\r\n", myhostname);
if (EightBitMime)
printf("250-8BITMIME\r\n");
@@ -602,7 +525,7 @@ dolmtp()
case 'm':
case 'M':
- if (strncasecmp(buf, "mail ", 5) == 0)
+ if (sm_strncasecmp(buf, "mail ", 5) == 0)
{
if (return_path != NULL)
{
@@ -610,9 +533,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");
@@ -627,7 +550,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;
@@ -638,7 +561,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);
@@ -649,7 +572,7 @@ dolmtp()
case 'r':
case 'R':
- if (strncasecmp(buf, "rcpt ", 5) == 0)
+ if (sm_strncasecmp(buf, "rcpt ", 5) == 0)
{
if (return_path == NULL)
{
@@ -671,9 +594,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");
@@ -689,7 +612,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");
@@ -707,7 +630,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;
@@ -727,25 +650,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");
@@ -759,7 +681,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));
@@ -770,7 +692,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;
@@ -792,7 +714,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')
@@ -804,7 +726,7 @@ store(from, lmtprcpts, inbody)
line[line_len - 1] = '\0';
line_len--;
}
- fullline = TRUE;
+ fullline = true;
}
else if (line[line_len - 1] == '\r')
{
@@ -813,19 +735,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)
@@ -840,7 +762,7 @@ store(from, lmtprcpts, inbody)
}
#else /* CONTENTLENGTH */
if (prevfl && line[0] == '\n')
- eline = TRUE;
+ eline = true;
#endif /* CONTENTLENGTH */
else
{
@@ -848,12 +770,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
@@ -908,15 +830,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 */
@@ -943,9 +860,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;
@@ -954,26 +871,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();
/*
@@ -995,7 +928,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;
+ }
/*
@@ -1037,7 +992,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;
}
@@ -1045,7 +1000,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);
@@ -1071,13 +1026,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
@@ -1089,7 +1044,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;
}
@@ -1099,28 +1054,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 ||
@@ -1140,11 +1096,48 @@ 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;
}
@@ -1152,23 +1145,19 @@ tryagain:
{
/* 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 ;
@@ -1176,7 +1165,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;
@@ -1206,7 +1195,7 @@ tryagain:
errcode = "552 5.2.2";
#endif /* EDQUOT */
mailerr(errcode, "%s: %s",
- path, errstring(errno));
+ path, sm_errstring(errno));
goto err3;
}
}
@@ -1214,18 +1203,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 (!nofsync && 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)
@@ -1242,7 +1231,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 if (!nobiff)
@@ -1251,11 +1240,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)
@@ -1269,7 +1258,7 @@ err0: unlockmbox();
** EPA 11/94.
*/
-bool Locked = FALSE;
+bool Locked = false;
#ifdef MAILLOCK
int
@@ -1282,7 +1271,7 @@ lockmbox(name)
return 0;
if ((r = maillock(name, 15)) == L_SUCCESS)
{
- Locked = TRUE;
+ Locked = true;
return 0;
}
switch (r)
@@ -1309,7 +1298,7 @@ unlockmbox()
{
if (Locked)
mailunlock();
- Locked = FALSE;
+ Locked = false;
}
#else /* MAILLOCK */
@@ -1326,7 +1315,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))
{
@@ -1346,7 +1335,7 @@ lockmbox(path)
{
/* defeat lock checking programs which test pid */
(void) write(fd, "0", 2);
- Locked = TRUE;
+ Locked = true;
(void) close(fd);
return 0;
}
@@ -1376,7 +1365,7 @@ unlockmbox()
if (!Locked)
return;
(void) unlink(LockName);
- Locked = FALSE;
+ Locked = false;
}
#endif /* MAILLOCK */
@@ -1384,7 +1373,7 @@ void
notifybiff(msg)
char *msg;
{
- static bool initialized = FALSE;
+ static bool initialized = false;
static int f = -1;
struct hostent *hp;
struct servent *sp;
@@ -1393,7 +1382,7 @@ notifybiff(msg)
if (!initialized)
{
- initialized = TRUE;
+ initialized = true;
/* Be silent if biff service not available. */
if ((sp = getservbyname("biff", "udp")) == NULL ||
@@ -1424,11 +1413,12 @@ void
usage()
{
ExitVal = EX_USAGE;
- mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-l] [-f from] [-s] user ...");
+ mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] user ...");
exit(ExitVal);
}
void
+/*VARARGS2*/
#ifdef __STDC__
mailerr(const char *hdr, const char *fmt, ...)
#else /* __STDC__ */
@@ -1439,25 +1429,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();
@@ -1646,7 +1630,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 */
OpenPOWER on IntegriCloud