diff options
Diffstat (limited to 'src/usersmtp.c')
-rw-r--r-- | src/usersmtp.c | 189 |
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" */ |