aboutsummaryrefslogtreecommitdiff
path: root/contrib/sendmail/src/deliver.c
diff options
context:
space:
mode:
authorGregory Neil Shapiro <gshapiro@FreeBSD.org>2015-07-07 02:59:02 +0000
committerGregory Neil Shapiro <gshapiro@FreeBSD.org>2015-07-07 02:59:02 +0000
commitda7d7b9c861cf98e912c0bd1e549752d2dae4fb6 (patch)
treeb950e36c98456b5e5c9357435be1027c1bb6e875 /contrib/sendmail/src/deliver.c
parent7f78865ba0f11da6de1c58ac31169a0503f38172 (diff)
parent934381a7c5686d9a7b36335b9b325efde4cff4ef (diff)
downloadsrc-da7d7b9c861cf98e912c0bd1e549752d2dae4fb6.tar.gz
src-da7d7b9c861cf98e912c0bd1e549752d2dae4fb6.zip
Notes
Diffstat (limited to 'contrib/sendmail/src/deliver.c')
-rw-r--r--contrib/sendmail/src/deliver.c135
1 files changed, 99 insertions, 36 deletions
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 39c484c1a09f..62d02b168b7f 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -37,7 +37,7 @@ static void sendenvelope __P((ENVELOPE *, int));
static int coloncmp __P((const char *, const char *));
#if STARTTLS
-# include <openssl/err.h>
+# include <openssl/err.h>
static int starttls __P((MAILER *, MCI *, ENVELOPE *));
static int endtlsclt __P((MCI *));
#endif /* STARTTLS */
@@ -1223,6 +1223,7 @@ should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status)
}
return false;
}
+
/*
** DELIVER -- Deliver a message to a list of addresses.
**
@@ -1392,6 +1393,8 @@ deliver(e, firstto)
else
p = e->e_from.q_paddr;
rpath = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e);
+ if (rcode != EX_OK && bitnset(M_xSMTP, m->m_flags))
+ goto cleanup;
if (strlen(rpath) > MAXNAME)
{
rpath = shortenstring(rpath, MAXSHORTSTR);
@@ -1468,6 +1471,7 @@ deliver(e, firstto)
/* running LMTP or SMTP */
clever = true;
*pvp = NULL;
+ setbitn(M_xSMTP, m->m_flags);
}
else if (bitnset(M_LMTP, m->m_flags))
{
@@ -1600,7 +1604,7 @@ deliver(e, firstto)
quarantine = (e->e_quarmsg != NULL);
rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr,
e, RSF_RMCOMM|RSF_COUNT, 3, NULL,
- e->e_id, NULL);
+ e->e_id, NULL, NULL);
if (rcode == EX_OK)
{
/* do in-code checking if not discarding */
@@ -2465,8 +2469,8 @@ tryhost:
ctladdr->q_gid) == -1
&& suidwarn)
{
- syserr("openmailer: initgroups(%s, %d) failed",
- user, ctladdr->q_gid);
+ syserr("openmailer: initgroups(%s, %ld) failed",
+ user, (long) ctladdr->q_gid);
exit(EX_TEMPFAIL);
}
}
@@ -2492,8 +2496,8 @@ tryhost:
if (initgroups(DefUser, DefGid) == -1 &&
suidwarn)
{
- syserr("openmailer: initgroups(%s, %d) failed",
- DefUser, DefGid);
+ syserr("openmailer: initgroups(%s, %ld) failed",
+ DefUser, (long) DefGid);
exit(EX_TEMPFAIL);
}
}
@@ -2522,9 +2526,9 @@ tryhost:
new_gid != getegid())
{
/* Only root can change the gid */
- syserr("openmailer: insufficient privileges to change gid, RunAsUid=%d, new_gid=%d, gid=%d, egid=%d",
- (int) RunAsUid, (int) new_gid,
- (int) getgid(), (int) getegid());
+ syserr("openmailer: insufficient privileges to change gid, RunAsUid=%ld, new_gid=%ld, gid=%ld, egid=%ld",
+ (long) RunAsUid, (long) new_gid,
+ (long) getgid(), (long) getegid());
exit(EX_TEMPFAIL);
}
@@ -2619,8 +2623,8 @@ tryhost:
if (RunAsUid != 0 && new_euid != RunAsUid)
{
/* Only root can change the uid */
- syserr("openmailer: insufficient privileges to change uid, new_euid=%d, RunAsUid=%d",
- (int) new_euid, (int) RunAsUid);
+ syserr("openmailer: insufficient privileges to change uid, new_euid=%ld, RunAsUid=%ld",
+ (long) new_euid, (long) RunAsUid);
exit(EX_TEMPFAIL);
}
@@ -2662,9 +2666,9 @@ tryhost:
}
if (tTd(11, 2))
- sm_dprintf("openmailer: running as r/euid=%d/%d, r/egid=%d/%d\n",
- (int) getuid(), (int) geteuid(),
- (int) getgid(), (int) getegid());
+ sm_dprintf("openmailer: running as r/euid=%ld/%ld, r/egid=%ld/%ld\n",
+ (long) getuid(), (long) geteuid(),
+ (long) getgid(), (long) getegid());
/* move into some "safe" directory */
if (m->m_execdir != NULL)
@@ -2964,8 +2968,8 @@ reconnect: /* after switching to an encrypted connection */
QuickAbort = false;
SuprErrs = true;
if (rscheck("try_tls", host, NULL, e,
- RSF_RMCOMM, 7, host, NOQID, NULL)
- != EX_OK
+ RSF_RMCOMM, 7, host, NOQID, NULL,
+ NULL) != EX_OK
|| Errors > olderrors)
{
usetls = false;
@@ -3039,7 +3043,7 @@ reconnect: /* after switching to an encrypted connection */
if (rscheck("tls_server",
macvalue(macid("{verify}"), e),
NULL, e, RSF_RMCOMM|RSF_COUNT, 5,
- host, NOQID, NULL) != EX_OK ||
+ host, NOQID, NULL, NULL) != EX_OK ||
Errors > olderrors ||
rcode == EX_SOFTWARE)
{
@@ -3364,7 +3368,7 @@ do_transfer:
# if STARTTLS
i = rscheck("tls_rcpt", to->q_user, NULL, e,
RSF_RMCOMM|RSF_COUNT, 3,
- mci->mci_host, e->e_id, NULL);
+ mci->mci_host, e->e_id, NULL, NULL);
if (i != EX_OK)
{
markfailure(e, to, mci, i, false);
@@ -3590,7 +3594,7 @@ do_transfer:
if (tobuf[0] != '\0')
{
- giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, tochain);
+ giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, NULL);
#if 0
/*
** This code is disabled for now because I am not
@@ -4166,14 +4170,13 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
/*
** Final cleanup.
- ** Log a record of the transaction. Compute the new
- ** ExitStat -- if we already had an error, stick with
- ** that.
+ ** Log a record of the transaction. Compute the new ExitStat
+ ** -- if we already had an error, stick with that.
*/
if (OpMode != MD_VERIFY && !bitset(EF_VRFYONLY, e->e_flags) &&
LogLevel > ((status == EX_TEMPFAIL) ? 8 : (status == EX_OK) ? 7 : 6))
- logdelivery(m, mci, dsn, statmsg + off, ctladdr, xstart, e);
+ logdelivery(m, mci, dsn, statmsg + off, ctladdr, xstart, e, to, status);
if (tTd(11, 2))
sm_dprintf("giveresponse: status=%d, dsn=%s, e->e_message=%s, errnum=%d\n",
@@ -4215,6 +4218,8 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
** xstart -- the transaction start time, used for
** computing transaction delay.
** e -- the current envelope.
+** to -- the current recipient (NULL if none).
+** rcode -- status code
**
** Returns:
** none
@@ -4224,7 +4229,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
*/
void
-logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
+logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
MAILER *m;
register MCI *mci;
char *dsn;
@@ -4232,6 +4237,8 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
ADDRESS *ctladdr;
time_t xstart;
register ENVELOPE *e;
+ ADDRESS *to;
+ int rcode;
{
register char *bp;
register char *p;
@@ -4276,6 +4283,16 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
bp += strlen(bp);
}
+# if _FFR_LOG_MORE2
+# if STARTTLS
+ p = macvalue(macid("{verify}"), e);
+ if (p == NULL || *p == '\0')
+ p = "NONE";
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", tls_verify=%.20s", p);
+ bp += strlen(bp);
+# endif /* STARTTLS */
+# endif /* _FFR_LOG_MORE2 */
+
/* pri: changes with each delivery attempt */
(void) sm_snprintf(bp, SPACELEFT(buf, bp), ", pri=%ld",
PRT_NONNEGL(e->e_msgpriority));
@@ -4342,6 +4359,43 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
# define STATLEN 203
# endif /* (STATLEN) > 203 */
+#if _FFR_LOGREPLY
+ /*
+ ** Notes:
+ ** per-rcpt status: to->q_rstatus
+ ** global status: e->e_text
+ **
+ ** We (re)use STATLEN here, is that a good choice?
+ **
+ ** stat=Deferred: ...
+ ** has sometimes the same text?
+ **
+ ** Note: this doesn't show the stage at which the error happened.
+ ** can/should we log that?
+ ** XS_* in reply() basically encodes the state.
+ */
+
+ /* only show errors */
+ if (rcode != EX_OK && to != NULL && to->q_rstatus != NULL &&
+ *to->q_rstatus != '\0')
+ {
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp),
+ ", reply=%s",
+ shortenstring(to->q_rstatus, STATLEN));
+ bp += strlen(bp);
+ }
+ else if (rcode != EX_OK && e->e_text != NULL)
+ {
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp),
+ ", reply=%d %s%s%s",
+ e->e_rcode,
+ e->e_renhsc,
+ (e->e_renhsc[0] != '\0') ? " " : "",
+ shortenstring(e->e_text, STATLEN));
+ bp += strlen(bp);
+ }
+#endif
+
/* stat: max 210 bytes */
if ((bp - buf) > (sizeof(buf) - ((STATLEN) + 20)))
{
@@ -4368,6 +4422,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
for (q = p + l; q > p; q--)
{
+ /* XXX a comma in an address will break this! */
if (*q == ',')
break;
}
@@ -5327,8 +5382,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
if (RunAsUid != 0 && RealUid != RunAsUid)
{
/* Only root can change the uid */
- syserr("mailfile: insufficient privileges to change uid, RunAsUid=%d, RealUid=%d",
- (int) RunAsUid, (int) RealUid);
+ syserr("mailfile: insufficient privileges to change uid, RunAsUid=%ld, RealUid=%ld",
+ (long) RunAsUid, (long) RealUid);
RETURN(EX_TEMPFAIL);
}
}
@@ -5368,9 +5423,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
RealGid != getegid()))
{
/* Only root can change the gid */
- syserr("mailfile: insufficient privileges to change gid, RealGid=%d, RunAsUid=%d, gid=%d, egid=%d",
- (int) RealGid, (int) RunAsUid,
- (int) getgid(), (int) getegid());
+ syserr("mailfile: insufficient privileges to change gid, RealGid=%ld, RunAsUid=%ld, gid=%ld, egid=%ld",
+ (long) RealGid, (long) RunAsUid,
+ (long) getgid(), (long) getegid());
RETURN(EX_TEMPFAIL);
}
}
@@ -5411,8 +5466,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
{
if (initgroups(RealUserName, RealGid) == -1 && suidwarn)
{
- syserr("mailfile: initgroups(%s, %d) failed",
- RealUserName, RealGid);
+ syserr("mailfile: initgroups(%s, %ld) failed",
+ RealUserName, (long) RealGid);
RETURN(EX_TEMPFAIL);
}
}
@@ -5474,9 +5529,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
if (tTd(11, 2))
- sm_dprintf("mailfile: running as r/euid=%d/%d, r/egid=%d/%d\n",
- (int) getuid(), (int) geteuid(),
- (int) getgid(), (int) getegid());
+ sm_dprintf("mailfile: running as r/euid=%ld/%ld, r/egid=%ld/%ld\n",
+ (long) getuid(), (long) geteuid(),
+ (long) getgid(), (long) getegid());
/* move into some "safe" directory */
@@ -6163,11 +6218,18 @@ starttls(m, mci, e)
}
return EX_SOFTWARE;
}
+ /* SSL_clear(clt_ssl); ? */
+
+ if (get_tls_se_options(e, clt_ssl, false) != 0)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=client, get_tls_se_options=fail");
+ return EX_SOFTWARE;
+ }
rfd = sm_io_getinfo(mci->mci_in, SM_IO_WHAT_FD, NULL);
wfd = sm_io_getinfo(mci->mci_out, SM_IO_WHAT_FD, NULL);
- /* SSL_clear(clt_ssl); ? */
if (rfd < 0 || wfd < 0 ||
(result = SSL_set_rfd(clt_ssl, rfd)) != 1 ||
(result = SSL_set_wfd(clt_ssl, wfd)) != 1)
@@ -6189,6 +6251,7 @@ ssl_retry:
if ((result = SSL_connect(clt_ssl)) <= 0)
{
int i, ssl_err;
+ int save_errno = errno;
ssl_err = SSL_get_error(clt_ssl, result);
i = tls_retry(clt_ssl, rfd, wfd, tlsstart,
@@ -6206,7 +6269,7 @@ ssl_retry:
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=client, error: connect failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d",
result, sr == NULL ? "unknown" : sr, ssl_err,
- errno, i);
+ save_errno, i);
if (LogLevel > 9)
tlslogerr(LOG_WARNING, "client");
}