summaryrefslogtreecommitdiff
path: root/src/usersmtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usersmtp.c')
-rw-r--r--src/usersmtp.c189
1 files changed, 75 insertions, 114 deletions
diff --git a/src/usersmtp.c b/src/usersmtp.c
index b088d60..c82942b 100644
--- a/src/usersmtp.c
+++ b/src/usersmtp.c
@@ -1,44 +1,22 @@
/*
- * Copyright (c) 1983, 1995-1997 Eric P. Allman
+ * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+ * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
+ * 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.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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 DAMAGE.
*/
# include "sendmail.h"
#ifndef lint
#if SMTP
-static char sccsid[] = "@(#)usersmtp.c 8.88 (Berkeley) 10/20/97 (with SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.111 (Berkeley) 2/3/1999 (with SMTP)";
#else
-static char sccsid[] = "@(#)usersmtp.c 8.88 (Berkeley) 10/20/97 (without SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.111 (Berkeley) 2/3/1999 (without SMTP)";
#endif
#endif /* not lint */
@@ -89,8 +67,8 @@ smtpinit(m, mci, e)
{
register int r;
register char *p;
- extern void esmtp_check();
- extern void helo_options();
+ extern void esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
+ extern void helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
if (tTd(18, 1))
{
@@ -140,7 +118,7 @@ smtpinit(m, mci, e)
*/
SmtpPhase = mci->mci_phase = "client greeting";
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check);
if (r < 0)
goto tempfail1;
@@ -154,24 +132,16 @@ smtpinit(m, mci, e)
** My mother taught me to always introduce myself.
*/
-#if _FFR_LMTP
if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags))
-#else
- if (bitnset(M_ESMTP, m->m_flags))
-#endif
mci->mci_flags |= MCIF_ESMTP;
tryhelo:
-#if _FFR_LMTP
if (bitnset(M_LMTP, m->m_flags))
{
smtpmessage("LHLO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client LHLO";
}
else if (bitset(MCIF_ESMTP, mci->mci_flags))
-#else
- if (bitset(MCIF_ESMTP, mci->mci_flags))
-#endif
{
smtpmessage("EHLO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client EHLO";
@@ -181,18 +151,14 @@ tryhelo:
smtpmessage("HELO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client HELO";
}
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_helo, helo_options);
if (r < 0)
goto tempfail1;
else if (REPLYTYPE(r) == 5)
{
-#if _FFR_LMTP
if (bitset(MCIF_ESMTP, mci->mci_flags) &&
!bitnset(M_LMTP, m->m_flags))
-#else
- if (bitset(MCIF_ESMTP, mci->mci_flags))
-#endif
{
/* try old SMTP instead */
mci->mci_flags &= ~MCIF_ESMTP;
@@ -213,13 +179,11 @@ tryhelo:
if (p != NULL)
*p = '\0';
if (!bitnset(M_NOLOOPCHECK, m->m_flags) &&
-#if _FFR_LMTP
!bitnset(M_LMTP, m->m_flags) &&
-#endif
strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
{
syserr("553 %s config error: mail loops back to me (MX problem?)",
- mci->mci_host);
+ CurHostName);
mci_setstat(mci, EX_CONFIG, NULL, NULL);
mci->mci_errno = 0;
smtpquit(m, mci, e);
@@ -363,7 +327,6 @@ smtpmailfrom(m, mci, e)
ENVELOPE *e;
{
int r;
- int l;
char *bufp;
char *bodytype;
char buf[MAXNAME + 1];
@@ -373,11 +336,12 @@ smtpmailfrom(m, mci, e)
printf("smtpmailfrom: CurHost=%s\n", CurHostName);
/* set up appropriate options to include */
+ bufp = optbuf;
if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0)
snprintf(optbuf, sizeof optbuf, " SIZE=%ld", e->e_msgsize);
else
strcpy(optbuf, "");
- l = sizeof optbuf - strlen(optbuf) - 1;
+ bufp = &optbuf[strlen(optbuf)];
bodytype = e->e_bodytype;
if (bitset(MCIF_8BITMIME, mci->mci_flags))
@@ -388,11 +352,12 @@ smtpmailfrom(m, mci, e)
!bitset(EF_DONT_MIME, e->e_flags) &&
!bitnset(M_8BITS, m->m_flags))
bodytype = "8BITMIME";
- if (bodytype != NULL && strlen(bodytype) + 7 < l)
+ if (bodytype != NULL &&
+ SPACELEFT(optbuf, bufp) > strlen(bodytype) + 7)
{
- strcat(optbuf, " BODY=");
- strcat(optbuf, bodytype);
- l -= strlen(optbuf);
+ snprintf(bufp, SPACELEFT(optbuf, bufp),
+ " BODY=%s", bodytype);
+ bufp += strlen(bufp);
}
}
else if (bitnset(M_8BITS, m->m_flags) ||
@@ -416,29 +381,30 @@ smtpmailfrom(m, mci, e)
/* cannot just send a 8-bit version */
extern char MsgBuf[];
- usrerr("%s does not support 8BITMIME", mci->mci_host);
+ usrerr("%s does not support 8BITMIME", CurHostName);
mci_setstat(mci, EX_NOTSTICKY, "5.6.3", MsgBuf);
return EX_DATAERR;
}
if (bitset(MCIF_DSN, mci->mci_flags))
{
- if (e->e_envid != NULL && strlen(e->e_envid) < (SIZE_T) (l - 7))
+ if (e->e_envid != NULL &&
+ SPACELEFT(optbuf, bufp) > strlen(e->e_envid) + 7)
{
- strcat(optbuf, " ENVID=");
- strcat(optbuf, e->e_envid);
- l -= strlen(optbuf);
+ snprintf(bufp, SPACELEFT(optbuf, bufp),
+ " ENVID=%s", e->e_envid);
+ bufp += strlen(bufp);
}
/* RET= parameter */
- if (bitset(EF_RET_PARAM, e->e_flags) && l >= 9)
+ if (bitset(EF_RET_PARAM, e->e_flags) &&
+ SPACELEFT(optbuf, bufp) > 9)
{
- strcat(optbuf, " RET=");
- if (bitset(EF_NO_BODY_RETN, e->e_flags))
- strcat(optbuf, "HDRS");
- else
- strcat(optbuf, "FULL");
- l -= 9;
+ snprintf(bufp, SPACELEFT(optbuf, bufp),
+ " RET=%s",
+ bitset(EF_NO_BODY_RETN, e->e_flags) ?
+ "HDRS" : "FULL");
+ bufp += strlen(bufp);
}
}
@@ -475,7 +441,7 @@ smtpmailfrom(m, mci, e)
*bufp == '@' ? ',' : ':', bufp, optbuf);
}
SmtpPhase = mci->mci_phase = "client MAIL";
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_mail, NULL);
if (r < 0)
{
@@ -492,15 +458,9 @@ smtpmailfrom(m, mci, e)
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
- else if (r == 452 && bitset(MCIF_SIZE, mci->mci_flags) &&
- e->e_msgsize > 0)
- {
- mci_setstat(mci, EX_NOTSTICKY, smtptodsn(r), SmtpReplyBuffer);
- return EX_TEMPFAIL;
- }
else if (REPLYTYPE(r) == 4)
{
- mci_setstat(mci, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer);
+ mci_setstat(mci, EX_NOTSTICKY, smtptodsn(r), SmtpReplyBuffer);
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 2)
@@ -522,7 +482,7 @@ smtpmailfrom(m, mci, e)
else if (r == 552)
{
/* exceeded storage allocation */
- mci_setstat(mci, EX_NOTSTICKY, "5.2.2", SmtpReplyBuffer);
+ mci_setstat(mci, EX_NOTSTICKY, "5.3.4", SmtpReplyBuffer);
if (bitset(MCIF_SIZE, mci->mci_flags))
e->e_flags |= EF_NO_BODY_RETN;
return EX_UNAVAILABLE;
@@ -538,7 +498,7 @@ smtpmailfrom(m, mci, e)
{
sm_syslog(LOG_CRIT, e->e_id,
"%.100s: SMTP MAIL protocol error: %s",
- mci->mci_host,
+ CurHostName,
shortenstring(SmtpReplyBuffer, 403));
}
@@ -571,11 +531,11 @@ smtprcpt(to, m, mci, e)
ENVELOPE *e;
{
register int r;
- int l;
+ char *bufp;
char optbuf[MAXLINE];
strcpy(optbuf, "");
- l = sizeof optbuf - 1;
+ bufp = &optbuf[strlen(optbuf)];
if (bitset(MCIF_DSN, mci->mci_flags))
{
/* NOTIFY= parameter */
@@ -585,44 +545,45 @@ smtprcpt(to, m, mci, e)
{
bool firstone = TRUE;
- strcat(optbuf, " NOTIFY=");
+ strcat(bufp, " NOTIFY=");
if (bitset(QPINGONSUCCESS, to->q_flags))
{
- strcat(optbuf, "SUCCESS");
+ strcat(bufp, "SUCCESS");
firstone = FALSE;
}
if (bitset(QPINGONFAILURE, to->q_flags))
{
if (!firstone)
- strcat(optbuf, ",");
- strcat(optbuf, "FAILURE");
+ strcat(bufp, ",");
+ strcat(bufp, "FAILURE");
firstone = FALSE;
}
if (bitset(QPINGONDELAY, to->q_flags))
{
if (!firstone)
- strcat(optbuf, ",");
- strcat(optbuf, "DELAY");
+ strcat(bufp, ",");
+ strcat(bufp, "DELAY");
firstone = FALSE;
}
if (firstone)
- strcat(optbuf, "NEVER");
- l -= strlen(optbuf);
+ strcat(bufp, "NEVER");
+ bufp += strlen(bufp);
}
/* ORCPT= parameter */
- if (to->q_orcpt != NULL && strlen(to->q_orcpt) + 7 < l)
+ if (to->q_orcpt != NULL &&
+ SPACELEFT(optbuf, bufp) > strlen(to->q_orcpt) + 7)
{
- strcat(optbuf, " ORCPT=");
- strcat(optbuf, to->q_orcpt);
- l -= strlen(optbuf);
+ snprintf(bufp, SPACELEFT(optbuf, bufp),
+ " ORCPT=%s", to->q_orcpt);
+ bufp += strlen(bufp);
}
}
smtpmessage("RCPT To:<%s>%s", m, mci, to->q_user, optbuf);
SmtpPhase = mci->mci_phase = "client RCPT";
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_rcpt, NULL);
to->q_rstatus = newstr(SmtpReplyBuffer);
to->q_status = smtptodsn(r);
@@ -655,7 +616,7 @@ smtprcpt(to, m, mci, e)
{
sm_syslog(LOG_CRIT, e->e_id,
"%.100s: SMTP RCPT protocol error: %s",
- mci->mci_host,
+ CurHostName,
shortenstring(SmtpReplyBuffer, 403));
}
@@ -678,7 +639,7 @@ smtprcpt(to, m, mci, e)
*/
static jmp_buf CtxDataTimeout;
-static void datatimeout();
+static void datatimeout __P((void));
int
smtpdata(m, mci, e)
@@ -703,7 +664,7 @@ smtpdata(m, mci, e)
/* send the command and check ok to proceed */
smtpmessage("DATA", m, mci);
SmtpPhase = mci->mci_phase = "client DATA 354";
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_datainit, NULL);
if (r < 0 || REPLYTYPE(r) == 4)
{
@@ -715,13 +676,13 @@ smtpdata(m, mci, e)
smtprset(m, mci, e);
return EX_UNAVAILABLE;
}
- else if (r != 354)
+ else if (REPLYTYPE(r) != 3)
{
if (LogLevel > 1)
{
sm_syslog(LOG_CRIT, e->e_id,
"%.100s: SMTP DATA-1 protocol error: %s",
- mci->mci_host,
+ CurHostName,
shortenstring(SmtpReplyBuffer, 403));
}
smtprset(m, mci, e);
@@ -740,7 +701,7 @@ smtpdata(m, mci, e)
mci->mci_errno = errno;
mci->mci_state = MCIS_ERROR;
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
- syserr("451 timeout writing message to %s", mci->mci_host);
+ syserr("451 timeout writing message to %s", CurHostName);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
@@ -755,7 +716,7 @@ smtpdata(m, mci, e)
** Output the actual message.
*/
- (*e->e_puthdr)(mci, e->e_header, e);
+ (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
(*e->e_putbody)(mci, e, NULL);
/*
@@ -783,11 +744,9 @@ smtpdata(m, mci, e)
/* check for the results of the transaction */
SmtpPhase = mci->mci_phase = "client DATA status";
- setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
-#if _FFR_LMTP
+ sm_setproctitle(TRUE, "%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
if (bitnset(M_LMTP, m->m_flags))
return EX_OK;
-#endif
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
if (r < 0)
{
@@ -818,7 +777,7 @@ smtpdata(m, mci, e)
{
sm_syslog(LOG_CRIT, e->e_id,
"%.100s: SMTP DATA-2 protocol error: %s",
- mci->mci_host,
+ CurHostName,
shortenstring(SmtpReplyBuffer, 403));
}
return rstat;
@@ -842,8 +801,6 @@ datatimeout()
** The exit status corresponding to the reply code.
*/
-#if _FFR_LMTP
-
int
smtpgetstat(m, mci, e)
MAILER *m;
@@ -871,18 +828,18 @@ smtpgetstat(m, mci, e)
stat = EX_OK;
else if (REPLYTYPE(r) == 5)
stat = EX_UNAVAILABLE;
+ else
+ stat = EX_PROTOCOL;
mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer);
if (LogLevel > 1 && stat == EX_PROTOCOL)
{
sm_syslog(LOG_CRIT, e->e_id,
"%.100s: SMTP DATA-3 protocol error: %s",
- mci->mci_host,
+ CurHostName,
shortenstring(SmtpReplyBuffer, 403));
}
return stat;
}
-
-#endif
/*
** SMTPQUIT -- close the SMTP connection.
**
@@ -1020,7 +977,6 @@ reply(m, mci, e, timeout, pfunc)
for (;;)
{
register char *p;
- extern time_t curtime();
/* actually do the read */
if (e->e_xfp != NULL)
@@ -1053,8 +1009,11 @@ reply(m, mci, e, timeout, pfunc)
mci->mci_errno = errno;
oldholderrs = HoldErrs;
HoldErrs = TRUE;
- usrerr("451 reply: read error from %s", mci->mci_host);
- mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
+ usrerr("451 reply: read error from %s", CurHostName);
+
+ /* errors on QUIT should not be persistent */
+ if (strncmp(SmtpMsgBuffer, "QUIT", 4) != 0)
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
/* if debugging, pause so we can see state */
if (tTd(18, 100))
@@ -1072,13 +1031,14 @@ reply(m, mci, e, timeout, pfunc)
int plen;
snprintf(p, wbufleft, "%s... ",
- shortenstring(e->e_to, 203));
+ shortenstring(e->e_to, MAXSHORTSTR));
plen = strlen(p);
p += plen;
wbufleft -= plen;
}
snprintf(p, wbufleft, "reply(%.100s) during %s",
- mci->mci_host, SmtpPhase);
+ CurHostName == NULL ? "NO_HOST" : CurHostName,
+ SmtpPhase);
checkfd012(wbuf);
}
#endif
@@ -1116,7 +1076,7 @@ reply(m, mci, e, timeout, pfunc)
if (!(isascii(bufp[0]) && isdigit(bufp[0])) ||
!(isascii(bufp[1]) && isdigit(bufp[1])) ||
!(isascii(bufp[2]) && isdigit(bufp[2])) ||
- !(bufp[3] == ' ' || bufp[3] == '-'))
+ !(bufp[3] == ' ' || bufp[3] == '-' || bufp[3] == '\0'))
continue;
/* process the line */
@@ -1146,7 +1106,8 @@ reply(m, mci, e, timeout, pfunc)
*/
/* save temporary failure messages for posterity */
- if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
+ if (SmtpReplyBuffer[0] == '4' &&
+ (bitnset(M_LMTP, m->m_flags) || SmtpError[0] == '\0'))
snprintf(SmtpError, sizeof SmtpError, "%s", SmtpReplyBuffer);
/* reply code 421 is "Service Shutting Down" */