1c2aa98e2SPeter Wemm /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 1998-2003, 2006 Proofpoint, Inc. and its suppliers. 306f25ae9SGregory Neil Shapiro * All rights reserved. 4c2aa98e2SPeter Wemm * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5c2aa98e2SPeter Wemm * Copyright (c) 1988, 1993 6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved. 7c2aa98e2SPeter Wemm * 8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set 9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of 10c2aa98e2SPeter Wemm * the sendmail distribution. 11c2aa98e2SPeter Wemm * 12c2aa98e2SPeter Wemm */ 13c2aa98e2SPeter Wemm 1406f25ae9SGregory Neil Shapiro #include <sendmail.h> 1506f25ae9SGregory Neil Shapiro 164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: envelope.c,v 8.313 2013-11-22 20:51:55 ca Exp $") 1713bd1963SGregory Neil Shapiro 1813bd1963SGregory Neil Shapiro /* 1913bd1963SGregory Neil Shapiro ** CLRSESSENVELOPE -- clear session oriented data in an envelope 2013bd1963SGregory Neil Shapiro ** 2113bd1963SGregory Neil Shapiro ** Parameters: 2213bd1963SGregory Neil Shapiro ** e -- the envelope to clear. 2313bd1963SGregory Neil Shapiro ** 2413bd1963SGregory Neil Shapiro ** Returns: 2513bd1963SGregory Neil Shapiro ** none. 2613bd1963SGregory Neil Shapiro */ 2713bd1963SGregory Neil Shapiro 2813bd1963SGregory Neil Shapiro void 2913bd1963SGregory Neil Shapiro clrsessenvelope(e) 3013bd1963SGregory Neil Shapiro ENVELOPE *e; 3113bd1963SGregory Neil Shapiro { 3213bd1963SGregory Neil Shapiro #if SASL 3313bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{auth_type}"), ""); 3413bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{auth_authen}"), ""); 3513bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{auth_author}"), ""); 3613bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{auth_ssf}"), ""); 3713bd1963SGregory Neil Shapiro #endif /* SASL */ 3813bd1963SGregory Neil Shapiro #if STARTTLS 3913bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cert_issuer}"), ""); 4013bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cert_subject}"), ""); 4113bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cipher_bits}"), ""); 4213bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cipher}"), ""); 4313bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{tls_version}"), ""); 4413bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{verify}"), ""); 4513bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{alg_bits}"), ""); 4613bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cn_issuer}"), ""); 4713bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cn_subject}"), ""); 4813bd1963SGregory Neil Shapiro #endif /* STARTTLS */ 4913bd1963SGregory Neil Shapiro } 50c2aa98e2SPeter Wemm 51c2aa98e2SPeter Wemm /* 5240266059SGregory Neil Shapiro ** NEWENVELOPE -- fill in a new envelope 53c2aa98e2SPeter Wemm ** 54c2aa98e2SPeter Wemm ** Supports inheritance. 55c2aa98e2SPeter Wemm ** 56c2aa98e2SPeter Wemm ** Parameters: 57c2aa98e2SPeter Wemm ** e -- the new envelope to fill in. 58c2aa98e2SPeter Wemm ** parent -- the envelope to be the parent of e. 5940266059SGregory Neil Shapiro ** rpool -- either NULL, or a pointer to a resource pool 6040266059SGregory Neil Shapiro ** from which envelope memory is allocated, and 6140266059SGregory Neil Shapiro ** to which envelope resources are attached. 62c2aa98e2SPeter Wemm ** 63c2aa98e2SPeter Wemm ** Returns: 64c2aa98e2SPeter Wemm ** e. 65c2aa98e2SPeter Wemm ** 66c2aa98e2SPeter Wemm ** Side Effects: 67c2aa98e2SPeter Wemm ** none. 68c2aa98e2SPeter Wemm */ 69c2aa98e2SPeter Wemm 70c2aa98e2SPeter Wemm ENVELOPE * 7140266059SGregory Neil Shapiro newenvelope(e, parent, rpool) 72c2aa98e2SPeter Wemm register ENVELOPE *e; 73c2aa98e2SPeter Wemm register ENVELOPE *parent; 7440266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 75c2aa98e2SPeter Wemm { 76e3793f76SGregory Neil Shapiro int sendmode; 774e4196cbSGregory Neil Shapiro 7840266059SGregory Neil Shapiro /* 7940266059SGregory Neil Shapiro ** This code used to read: 8040266059SGregory Neil Shapiro ** if (e == parent && e->e_parent != NULL) 8140266059SGregory Neil Shapiro ** parent = e->e_parent; 8240266059SGregory Neil Shapiro ** So if e == parent && e->e_parent == NULL then we would 8340266059SGregory Neil Shapiro ** set e->e_parent = e, which creates a loop in the e_parent chain. 8440266059SGregory Neil Shapiro ** This meant macvalue() could go into an infinite loop. 8540266059SGregory Neil Shapiro */ 8640266059SGregory Neil Shapiro 874e4196cbSGregory Neil Shapiro if (parent != NULL) 884e4196cbSGregory Neil Shapiro sendmode = parent->e_sendmode; 894e4196cbSGregory Neil Shapiro else 904e4196cbSGregory Neil Shapiro sendmode = DM_NOTSET; 914e4196cbSGregory Neil Shapiro 9240266059SGregory Neil Shapiro if (e == parent) 93c2aa98e2SPeter Wemm parent = e->e_parent; 9440266059SGregory Neil Shapiro clearenvelope(e, true, rpool); 95c2aa98e2SPeter Wemm if (e == CurEnv) 9606f25ae9SGregory Neil Shapiro memmove((char *) &e->e_from, 9706f25ae9SGregory Neil Shapiro (char *) &NullAddress, 98d0cef73dSGregory Neil Shapiro sizeof(e->e_from)); 99c2aa98e2SPeter Wemm else 10006f25ae9SGregory Neil Shapiro memmove((char *) &e->e_from, 10106f25ae9SGregory Neil Shapiro (char *) &CurEnv->e_from, 102d0cef73dSGregory Neil Shapiro sizeof(e->e_from)); 103c2aa98e2SPeter Wemm e->e_parent = parent; 10406f25ae9SGregory Neil Shapiro assign_queueid(e); 105c2aa98e2SPeter Wemm e->e_ctime = curtime(); 106ffb83623SGregory Neil Shapiro #if _FFR_SESSID 107ffb83623SGregory Neil Shapiro e->e_sessid = e->e_id; 108*5b0945b5SGregory Neil Shapiro #endif 109c2aa98e2SPeter Wemm if (parent != NULL) 11040266059SGregory Neil Shapiro { 111c2aa98e2SPeter Wemm e->e_msgpriority = parent->e_msgsize; 112ffb83623SGregory Neil Shapiro #if _FFR_SESSID 113ffb83623SGregory Neil Shapiro if (parent->e_sessid != NULL) 114ffb83623SGregory Neil Shapiro e->e_sessid = sm_rpool_strdup_x(rpool, 115ffb83623SGregory Neil Shapiro parent->e_sessid); 116*5b0945b5SGregory Neil Shapiro #endif 117ffb83623SGregory Neil Shapiro 11840266059SGregory Neil Shapiro if (parent->e_quarmsg == NULL) 11940266059SGregory Neil Shapiro { 12040266059SGregory Neil Shapiro e->e_quarmsg = NULL; 12140266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 12240266059SGregory Neil Shapiro macid("{quarantine}"), ""); 12340266059SGregory Neil Shapiro } 12440266059SGregory Neil Shapiro else 12540266059SGregory Neil Shapiro { 12640266059SGregory Neil Shapiro e->e_quarmsg = sm_rpool_strdup_x(rpool, 12740266059SGregory Neil Shapiro parent->e_quarmsg); 12840266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 12940266059SGregory Neil Shapiro macid("{quarantine}"), e->e_quarmsg); 13040266059SGregory Neil Shapiro } 13140266059SGregory Neil Shapiro } 132c2aa98e2SPeter Wemm e->e_puthdr = putheader; 133c2aa98e2SPeter Wemm e->e_putbody = putbody; 134c2aa98e2SPeter Wemm if (CurEnv->e_xfp != NULL) 13540266059SGregory Neil Shapiro (void) sm_io_flush(CurEnv->e_xfp, SM_TIME_DEFAULT); 1364e4196cbSGregory Neil Shapiro if (sendmode != DM_NOTSET) 137e3793f76SGregory Neil Shapiro set_delivery_mode(sendmode, e); 138c2aa98e2SPeter Wemm 13906f25ae9SGregory Neil Shapiro return e; 140c2aa98e2SPeter Wemm } 14140266059SGregory Neil Shapiro 14240266059SGregory Neil Shapiro /* values for msg_timeout, see also IS_* below for usage (bit layout) */ 14340266059SGregory Neil Shapiro #define MSG_T_O 0x01 /* normal timeout */ 14440266059SGregory Neil Shapiro #define MSG_T_O_NOW 0x02 /* NOW timeout */ 14540266059SGregory Neil Shapiro #define MSG_NOT_BY 0x04 /* Deliver-By time exceeded, mode R */ 14640266059SGregory Neil Shapiro #define MSG_WARN 0x10 /* normal queue warning */ 14740266059SGregory Neil Shapiro #define MSG_WARN_BY 0x20 /* Deliver-By time exceeded, mode N */ 14840266059SGregory Neil Shapiro 14940266059SGregory Neil Shapiro #define IS_MSG_ERR(x) (((x) & 0x0f) != 0) /* return an error */ 15040266059SGregory Neil Shapiro 15140266059SGregory Neil Shapiro /* immediate return */ 15240266059SGregory Neil Shapiro #define IS_IMM_RET(x) (((x) & (MSG_T_O_NOW|MSG_NOT_BY)) != 0) 15340266059SGregory Neil Shapiro #define IS_MSG_WARN(x) (((x) & 0xf0) != 0) /* return a warning */ 15440266059SGregory Neil Shapiro 15540266059SGregory Neil Shapiro /* 156c2aa98e2SPeter Wemm ** DROPENVELOPE -- deallocate an envelope. 157c2aa98e2SPeter Wemm ** 158c2aa98e2SPeter Wemm ** Parameters: 159c2aa98e2SPeter Wemm ** e -- the envelope to deallocate. 160c2aa98e2SPeter Wemm ** fulldrop -- if set, do return receipts. 16140266059SGregory Neil Shapiro ** split -- if true, split by recipient if message is queued up 162c2aa98e2SPeter Wemm ** 163c2aa98e2SPeter Wemm ** Returns: 1649bd497b8SGregory Neil Shapiro ** EX_* status (currently: 0: success, EX_IOERR on panic) 165c2aa98e2SPeter Wemm ** 166c2aa98e2SPeter Wemm ** Side Effects: 167c2aa98e2SPeter Wemm ** housekeeping necessary to dispose of an envelope. 168c2aa98e2SPeter Wemm ** Unlocks this queue file. 169c2aa98e2SPeter Wemm */ 170c2aa98e2SPeter Wemm 1719bd497b8SGregory Neil Shapiro int 17240266059SGregory Neil Shapiro dropenvelope(e, fulldrop, split) 173c2aa98e2SPeter Wemm register ENVELOPE *e; 174c2aa98e2SPeter Wemm bool fulldrop; 17540266059SGregory Neil Shapiro bool split; 176c2aa98e2SPeter Wemm { 17740266059SGregory Neil Shapiro bool panic = false; 17840266059SGregory Neil Shapiro bool queueit = false; 17940266059SGregory Neil Shapiro int msg_timeout = 0; 18040266059SGregory Neil Shapiro bool failure_return = false; 18140266059SGregory Neil Shapiro bool delay_return = false; 18240266059SGregory Neil Shapiro bool success_return = false; 18306f25ae9SGregory Neil Shapiro bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags); 18440266059SGregory Neil Shapiro bool done = false; 185c2aa98e2SPeter Wemm register ADDRESS *q; 186c2aa98e2SPeter Wemm char *id = e->e_id; 187193538b7SGregory Neil Shapiro time_t now; 188c2aa98e2SPeter Wemm char buf[MAXLINE]; 189c2aa98e2SPeter Wemm 190c2aa98e2SPeter Wemm if (tTd(50, 1)) 191c2aa98e2SPeter Wemm { 192*5b0945b5SGregory Neil Shapiro sm_dprintf("dropenvelope %p: id=", (void *)e); 193e92d3f3fSGregory Neil Shapiro xputs(sm_debug_file(), e->e_id); 19440266059SGregory Neil Shapiro sm_dprintf(", flags="); 195c2aa98e2SPeter Wemm printenvflags(e); 196c2aa98e2SPeter Wemm if (tTd(50, 10)) 197c2aa98e2SPeter Wemm { 19840266059SGregory Neil Shapiro sm_dprintf("sendq="); 199e92d3f3fSGregory Neil Shapiro printaddr(sm_debug_file(), e->e_sendqueue, true); 200c2aa98e2SPeter Wemm } 201c2aa98e2SPeter Wemm } 202c2aa98e2SPeter Wemm 203c2aa98e2SPeter Wemm if (LogLevel > 84) 204c2aa98e2SPeter Wemm sm_syslog(LOG_DEBUG, id, 20506f25ae9SGregory Neil Shapiro "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d", 20640266059SGregory Neil Shapiro e->e_flags, OpMode, (int) CurrentPid); 207c2aa98e2SPeter Wemm 208c2aa98e2SPeter Wemm /* we must have an id to remove disk files */ 209c2aa98e2SPeter Wemm if (id == NULL) 2109bd497b8SGregory Neil Shapiro return EX_OK; 211c2aa98e2SPeter Wemm 212c2aa98e2SPeter Wemm /* if verify-only mode, we can skip most of this */ 213c2aa98e2SPeter Wemm if (OpMode == MD_VERIFY) 214c2aa98e2SPeter Wemm goto simpledrop; 215c2aa98e2SPeter Wemm 2169bd497b8SGregory Neil Shapiro if (tTd(92, 2)) 2179bd497b8SGregory Neil Shapiro sm_dprintf("dropenvelope: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", 2189bd497b8SGregory Neil Shapiro e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); 219c2aa98e2SPeter Wemm if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 220c2aa98e2SPeter Wemm logsender(e, NULL); 221c2aa98e2SPeter Wemm e->e_flags &= ~EF_LOGSENDER; 222c2aa98e2SPeter Wemm 223c2aa98e2SPeter Wemm /* post statistics */ 224c2aa98e2SPeter Wemm poststats(StatFile); 225c2aa98e2SPeter Wemm 226c2aa98e2SPeter Wemm /* 227c2aa98e2SPeter Wemm ** Extract state information from dregs of send list. 228c2aa98e2SPeter Wemm */ 229c2aa98e2SPeter Wemm 230193538b7SGregory Neil Shapiro now = curtime(); 2318774250cSGregory Neil Shapiro if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 23240266059SGregory Neil Shapiro msg_timeout = MSG_T_O; 23340266059SGregory Neil Shapiro if (IS_DLVR_RETURN(e) && e->e_deliver_by > 0 && 23440266059SGregory Neil Shapiro now >= e->e_ctime + e->e_deliver_by && 23506f25ae9SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags)) 23606f25ae9SGregory Neil Shapiro { 23740266059SGregory Neil Shapiro msg_timeout = MSG_NOT_BY; 23840266059SGregory Neil Shapiro e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 23940266059SGregory Neil Shapiro } 24040266059SGregory Neil Shapiro else if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW && 24140266059SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags)) 24240266059SGregory Neil Shapiro { 24340266059SGregory Neil Shapiro msg_timeout = MSG_T_O_NOW; 24406f25ae9SGregory Neil Shapiro e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 24506f25ae9SGregory Neil Shapiro } 24606f25ae9SGregory Neil Shapiro 247da7d7b9cSGregory Neil Shapiro #if _FFR_PROXY 248da7d7b9cSGregory Neil Shapiro if (tTd(87, 2)) 249da7d7b9cSGregory Neil Shapiro { 250da7d7b9cSGregory Neil Shapiro q = e->e_sendqueue; 251da7d7b9cSGregory Neil Shapiro sm_dprintf("dropenvelope: mode=%c, e=%p, sibling=%p, nrcpts=%d, sendqueue=%p, next=%p, state=%d\n", 252da7d7b9cSGregory Neil Shapiro e->e_sendmode, e, e->e_sibling, e->e_nrcpts, q, 253da7d7b9cSGregory Neil Shapiro (q == NULL) ? (void *)0 : q->q_next, 254da7d7b9cSGregory Neil Shapiro (q == NULL) ? -1 : q->q_state); 255da7d7b9cSGregory Neil Shapiro } 256da7d7b9cSGregory Neil Shapiro #endif /* _FFR_PROXY */ 2576f9c8e5bSGregory Neil Shapiro 258c2aa98e2SPeter Wemm e->e_flags &= ~EF_QUEUERUN; 259c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 260c2aa98e2SPeter Wemm { 26106f25ae9SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state)) 26240266059SGregory Neil Shapiro queueit = true; 263c2aa98e2SPeter Wemm 264da7d7b9cSGregory Neil Shapiro #if _FFR_PROXY 265da7d7b9cSGregory Neil Shapiro if (queueit && e->e_sendmode == SM_PROXY) 266da7d7b9cSGregory Neil Shapiro queueit = false; 267*5b0945b5SGregory Neil Shapiro #endif 2686f9c8e5bSGregory Neil Shapiro 269c2aa98e2SPeter Wemm /* see if a notification is needed */ 270c2aa98e2SPeter Wemm if (bitset(QPINGONFAILURE, q->q_flags) && 27140266059SGregory Neil Shapiro ((IS_MSG_ERR(msg_timeout) && 27240266059SGregory Neil Shapiro QS_IS_UNDELIVERED(q->q_state)) || 27306f25ae9SGregory Neil Shapiro QS_IS_BADADDR(q->q_state) || 27440266059SGregory Neil Shapiro IS_IMM_RET(msg_timeout))) 275c2aa98e2SPeter Wemm { 27640266059SGregory Neil Shapiro failure_return = true; 27706f25ae9SGregory Neil Shapiro if (!done && q->q_owner == NULL && 27806f25ae9SGregory Neil Shapiro !emptyaddr(&e->e_from)) 27906f25ae9SGregory Neil Shapiro { 280c2aa98e2SPeter Wemm (void) sendtolist(e->e_from.q_paddr, NULLADDR, 281c2aa98e2SPeter Wemm &e->e_errorqueue, 0, e); 28240266059SGregory Neil Shapiro done = true; 28306f25ae9SGregory Neil Shapiro } 284c2aa98e2SPeter Wemm } 28540266059SGregory Neil Shapiro else if ((bitset(QPINGONSUCCESS, q->q_flags) && 28606f25ae9SGregory Neil Shapiro ((QS_IS_SENT(q->q_state) && 287c2aa98e2SPeter Wemm bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) || 28840266059SGregory Neil Shapiro bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags))) || 28940266059SGregory Neil Shapiro bitset(QBYTRACE, q->q_flags) || 29040266059SGregory Neil Shapiro bitset(QBYNRELAY, q->q_flags)) 291c2aa98e2SPeter Wemm { 29240266059SGregory Neil Shapiro success_return = true; 293c2aa98e2SPeter Wemm } 294c2aa98e2SPeter Wemm } 295c2aa98e2SPeter Wemm 296c2aa98e2SPeter Wemm if (e->e_class < 0) 297c2aa98e2SPeter Wemm e->e_flags |= EF_NO_BODY_RETN; 298c2aa98e2SPeter Wemm 299c2aa98e2SPeter Wemm /* 300c2aa98e2SPeter Wemm ** See if the message timed out. 301c2aa98e2SPeter Wemm */ 302c2aa98e2SPeter Wemm 303c2aa98e2SPeter Wemm if (!queueit) 30406f25ae9SGregory Neil Shapiro /* EMPTY */ 305c2aa98e2SPeter Wemm /* nothing to do */ ; 30640266059SGregory Neil Shapiro else if (IS_MSG_ERR(msg_timeout)) 307c2aa98e2SPeter Wemm { 308c2aa98e2SPeter Wemm if (failure_return) 309c2aa98e2SPeter Wemm { 31040266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 31140266059SGregory Neil Shapiro { 312d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 31340266059SGregory Neil Shapiro "delivery time expired %lds", 31440266059SGregory Neil Shapiro e->e_deliver_by); 31540266059SGregory Neil Shapiro } 31640266059SGregory Neil Shapiro else 31740266059SGregory Neil Shapiro { 318d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 31906f25ae9SGregory Neil Shapiro "Cannot send message for %s", 32040266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 32140266059SGregory Neil Shapiro false)); 32240266059SGregory Neil Shapiro } 32340266059SGregory Neil Shapiro 32440266059SGregory Neil Shapiro /* don't free, allocated from e_rpool */ 32540266059SGregory Neil Shapiro e->e_message = sm_rpool_strdup_x(e->e_rpool, buf); 326*5b0945b5SGregory Neil Shapiro message("%s", buf); 327c2aa98e2SPeter Wemm e->e_flags |= EF_CLRQUEUE; 328c2aa98e2SPeter Wemm } 32940266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 33040266059SGregory Neil Shapiro { 33140266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 33240266059SGregory Neil Shapiro "Delivery time (%lds) expired\n", 33340266059SGregory Neil Shapiro e->e_deliver_by); 33440266059SGregory Neil Shapiro } 33540266059SGregory Neil Shapiro else 33640266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 33740266059SGregory Neil Shapiro "Message could not be delivered for %s\n", 33840266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 33940266059SGregory Neil Shapiro false)); 34040266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 34140266059SGregory Neil Shapiro "Message will be deleted from queue\n"); 342c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 343c2aa98e2SPeter Wemm { 34406f25ae9SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state)) 345c2aa98e2SPeter Wemm { 34606f25ae9SGregory Neil Shapiro q->q_state = QS_BADADDR; 34740266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 34840266059SGregory Neil Shapiro q->q_status = "5.4.7"; 34940266059SGregory Neil Shapiro else 350c2aa98e2SPeter Wemm q->q_status = "4.4.7"; 351c2aa98e2SPeter Wemm } 352c2aa98e2SPeter Wemm } 353c2aa98e2SPeter Wemm } 35440266059SGregory Neil Shapiro else 35540266059SGregory Neil Shapiro { 35640266059SGregory Neil Shapiro if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 35740266059SGregory Neil Shapiro now >= e->e_ctime + 35840266059SGregory Neil Shapiro TimeOuts.to_q_warning[e->e_timeoutclass]) 35940266059SGregory Neil Shapiro msg_timeout = MSG_WARN; 36040266059SGregory Neil Shapiro else if (IS_DLVR_NOTIFY(e) && 36140266059SGregory Neil Shapiro e->e_deliver_by > 0 && 36240266059SGregory Neil Shapiro now >= e->e_ctime + e->e_deliver_by) 36340266059SGregory Neil Shapiro msg_timeout = MSG_WARN_BY; 36440266059SGregory Neil Shapiro 36540266059SGregory Neil Shapiro if (IS_MSG_WARN(msg_timeout)) 366c2aa98e2SPeter Wemm { 367c2aa98e2SPeter Wemm if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 368c2aa98e2SPeter Wemm e->e_class >= 0 && 369c2aa98e2SPeter Wemm e->e_from.q_paddr != NULL && 370c2aa98e2SPeter Wemm strcmp(e->e_from.q_paddr, "<>") != 0 && 37140266059SGregory Neil Shapiro sm_strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 37240266059SGregory Neil Shapiro (strlen(e->e_from.q_paddr) <= 8 || 37340266059SGregory Neil Shapiro sm_strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], 37440266059SGregory Neil Shapiro "-request") != 0)) 375c2aa98e2SPeter Wemm { 37640266059SGregory Neil Shapiro for (q = e->e_sendqueue; q != NULL; 37740266059SGregory Neil Shapiro q = q->q_next) 378c2aa98e2SPeter Wemm { 37940266059SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state) 38006f25ae9SGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD 38140266059SGregory Neil Shapiro && !bitnset(M_HOLD, 38240266059SGregory Neil Shapiro q->q_mailer->m_flags) 383*5b0945b5SGregory Neil Shapiro #endif 38440266059SGregory Neil Shapiro ) 38540266059SGregory Neil Shapiro { 38640266059SGregory Neil Shapiro if (msg_timeout == 38740266059SGregory Neil Shapiro MSG_WARN_BY && 38840266059SGregory Neil Shapiro (bitset(QPINGONDELAY, 38940266059SGregory Neil Shapiro q->q_flags) || 39040266059SGregory Neil Shapiro !bitset(QHASNOTIFY, 39140266059SGregory Neil Shapiro q->q_flags)) 39240266059SGregory Neil Shapiro ) 39340266059SGregory Neil Shapiro { 39440266059SGregory Neil Shapiro q->q_flags |= QBYNDELAY; 39540266059SGregory Neil Shapiro delay_return = true; 39640266059SGregory Neil Shapiro } 39740266059SGregory Neil Shapiro if (bitset(QPINGONDELAY, 39840266059SGregory Neil Shapiro q->q_flags)) 399c2aa98e2SPeter Wemm { 400c2aa98e2SPeter Wemm q->q_flags |= QDELAYED; 40140266059SGregory Neil Shapiro delay_return = true; 40240266059SGregory Neil Shapiro } 403c2aa98e2SPeter Wemm } 404c2aa98e2SPeter Wemm } 405c2aa98e2SPeter Wemm } 406c2aa98e2SPeter Wemm if (delay_return) 407c2aa98e2SPeter Wemm { 40840266059SGregory Neil Shapiro if (msg_timeout == MSG_WARN_BY) 40940266059SGregory Neil Shapiro { 410d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 41140266059SGregory Neil Shapiro "Warning: Delivery time (%lds) exceeded", 41240266059SGregory Neil Shapiro e->e_deliver_by); 41340266059SGregory Neil Shapiro } 41440266059SGregory Neil Shapiro else 415d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 416c2aa98e2SPeter Wemm "Warning: could not send message for past %s", 41740266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 41840266059SGregory Neil Shapiro false)); 41940266059SGregory Neil Shapiro 42040266059SGregory Neil Shapiro /* don't free, allocated from e_rpool */ 42140266059SGregory Neil Shapiro e->e_message = sm_rpool_strdup_x(e->e_rpool, 42240266059SGregory Neil Shapiro buf); 423*5b0945b5SGregory Neil Shapiro message("%s", buf); 424c2aa98e2SPeter Wemm e->e_flags |= EF_WARNING; 425c2aa98e2SPeter Wemm } 42640266059SGregory Neil Shapiro if (msg_timeout == MSG_WARN_BY) 42740266059SGregory Neil Shapiro { 42840266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 42940266059SGregory Neil Shapiro "Warning: Delivery time (%lds) exceeded\n", 43040266059SGregory Neil Shapiro e->e_deliver_by); 43140266059SGregory Neil Shapiro } 43240266059SGregory Neil Shapiro else 43340266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 434c2aa98e2SPeter Wemm "Warning: message still undelivered after %s\n", 43540266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 43640266059SGregory Neil Shapiro false)); 43740266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 43840266059SGregory Neil Shapiro "Will keep trying until message is %s old\n", 43940266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 44040266059SGregory Neil Shapiro false)); 44140266059SGregory Neil Shapiro } 442c2aa98e2SPeter Wemm } 443c2aa98e2SPeter Wemm 444c2aa98e2SPeter Wemm if (tTd(50, 2)) 44540266059SGregory Neil Shapiro sm_dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n", 446c2aa98e2SPeter Wemm failure_return, delay_return, success_return, queueit); 447c2aa98e2SPeter Wemm 448c2aa98e2SPeter Wemm /* 449*5b0945b5SGregory Neil Shapiro ** If we had some fatal error, but no addresses are marked as bad, 450*5b0945b5SGregory Neil Shapiro ** mark all OK/VERIFIED addresses as bad (if QPINGONFAILURE). 451c2aa98e2SPeter Wemm */ 452c2aa98e2SPeter Wemm 453c2aa98e2SPeter Wemm if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 454c2aa98e2SPeter Wemm { 455c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 456c2aa98e2SPeter Wemm { 45706f25ae9SGregory Neil Shapiro if ((QS_IS_OK(q->q_state) || 458*5b0945b5SGregory Neil Shapiro QS_IS_VERIFIED(q->q_state)) 459*5b0945b5SGregory Neil Shapiro && bitset(QPINGONFAILURE, q->q_flags) 460*5b0945b5SGregory Neil Shapiro 461*5b0945b5SGregory Neil Shapiro /* 462*5b0945b5SGregory Neil Shapiro ** do not mark an address as bad if 463*5b0945b5SGregory Neil Shapiro ** - the address itself is stored in the queue 464*5b0945b5SGregory Neil Shapiro ** - the DeliveryMode requires queueing 465*5b0945b5SGregory Neil Shapiro ** - the envelope is queued 466*5b0945b5SGregory Neil Shapiro */ 467*5b0945b5SGregory Neil Shapiro 468*5b0945b5SGregory Neil Shapiro && !(bitset(QQUEUED, q->q_flags) 469*5b0945b5SGregory Neil Shapiro && WILL_BE_QUEUED(e->e_sendmode) 470*5b0945b5SGregory Neil Shapiro && bitset(EF_INQUEUE, e->e_flags) 471*5b0945b5SGregory Neil Shapiro ) 472*5b0945b5SGregory Neil Shapiro ) 473c2aa98e2SPeter Wemm { 47440266059SGregory Neil Shapiro failure_return = true; 47506f25ae9SGregory Neil Shapiro q->q_state = QS_BADADDR; 476c2aa98e2SPeter Wemm } 477c2aa98e2SPeter Wemm } 478c2aa98e2SPeter Wemm } 479c2aa98e2SPeter Wemm 480c2aa98e2SPeter Wemm /* 481c2aa98e2SPeter Wemm ** Send back return receipts as requested. 482c2aa98e2SPeter Wemm */ 483c2aa98e2SPeter Wemm 484c2aa98e2SPeter Wemm if (success_return && !failure_return && !delay_return && fulldrop && 485c2aa98e2SPeter Wemm !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 486c2aa98e2SPeter Wemm strcmp(e->e_from.q_paddr, "<>") != 0) 487c2aa98e2SPeter Wemm { 488c2aa98e2SPeter Wemm auto ADDRESS *rlist = NULL; 489c2aa98e2SPeter Wemm 490c2aa98e2SPeter Wemm if (tTd(50, 8)) 49140266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): sending return receipt\n", 49206f25ae9SGregory Neil Shapiro id); 493c2aa98e2SPeter Wemm e->e_flags |= EF_SENDRECEIPT; 494c2aa98e2SPeter Wemm (void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e); 495c2aa98e2SPeter Wemm (void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e); 496c2aa98e2SPeter Wemm } 497c2aa98e2SPeter Wemm e->e_flags &= ~EF_SENDRECEIPT; 498c2aa98e2SPeter Wemm 499c2aa98e2SPeter Wemm /* 500c2aa98e2SPeter Wemm ** Arrange to send error messages if there are fatal errors. 501c2aa98e2SPeter Wemm */ 502c2aa98e2SPeter Wemm 503c2aa98e2SPeter Wemm if ((failure_return || delay_return) && e->e_errormode != EM_QUIET) 504c2aa98e2SPeter Wemm { 505c2aa98e2SPeter Wemm if (tTd(50, 8)) 50640266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): saving mail\n", id); 50740266059SGregory Neil Shapiro panic = savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); 508c2aa98e2SPeter Wemm } 509c2aa98e2SPeter Wemm 510c2aa98e2SPeter Wemm /* 511c2aa98e2SPeter Wemm ** Arrange to send warning messages to postmaster as requested. 512c2aa98e2SPeter Wemm */ 513c2aa98e2SPeter Wemm 51406f25ae9SGregory Neil Shapiro if ((failure_return || pmnotify) && 515c2aa98e2SPeter Wemm PostMasterCopy != NULL && 51606f25ae9SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags) && 51706f25ae9SGregory Neil Shapiro e->e_class >= 0) 518c2aa98e2SPeter Wemm { 519c2aa98e2SPeter Wemm auto ADDRESS *rlist = NULL; 52006f25ae9SGregory Neil Shapiro char pcopy[MAXNAME]; 52106f25ae9SGregory Neil Shapiro 52206f25ae9SGregory Neil Shapiro if (failure_return) 52306f25ae9SGregory Neil Shapiro { 524d0cef73dSGregory Neil Shapiro expand(PostMasterCopy, pcopy, sizeof(pcopy), e); 525c2aa98e2SPeter Wemm 526c2aa98e2SPeter Wemm if (tTd(50, 8)) 52740266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): sending postmaster copy to %s\n", 52806f25ae9SGregory Neil Shapiro id, pcopy); 52906f25ae9SGregory Neil Shapiro (void) sendtolist(pcopy, NULLADDR, &rlist, 0, e); 53006f25ae9SGregory Neil Shapiro } 53106f25ae9SGregory Neil Shapiro if (pmnotify) 53206f25ae9SGregory Neil Shapiro (void) sendtolist("postmaster", NULLADDR, 53306f25ae9SGregory Neil Shapiro &rlist, 0, e); 53406f25ae9SGregory Neil Shapiro (void) returntosender(e->e_message, rlist, 53506f25ae9SGregory Neil Shapiro RTSF_PM_BOUNCE|RTSF_NO_BODY, e); 536c2aa98e2SPeter Wemm } 537c2aa98e2SPeter Wemm 538c2aa98e2SPeter Wemm /* 539c2aa98e2SPeter Wemm ** Instantiate or deinstantiate the queue. 540c2aa98e2SPeter Wemm */ 541c2aa98e2SPeter Wemm 542c2aa98e2SPeter Wemm simpledrop: 543c2aa98e2SPeter Wemm if (tTd(50, 8)) 54440266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): at simpledrop, queueit=%d\n", 545c2aa98e2SPeter Wemm id, queueit); 546c2aa98e2SPeter Wemm if (!queueit || bitset(EF_CLRQUEUE, e->e_flags)) 547c2aa98e2SPeter Wemm { 548c2aa98e2SPeter Wemm if (tTd(50, 1)) 549c2aa98e2SPeter Wemm { 55040266059SGregory Neil Shapiro sm_dprintf("\n===== Dropping queue files for %s... queueit=%d, e_flags=", 551c2aa98e2SPeter Wemm e->e_id, queueit); 552c2aa98e2SPeter Wemm printenvflags(e); 553c2aa98e2SPeter Wemm } 55440266059SGregory Neil Shapiro if (!panic) 555af9557fdSGregory Neil Shapiro { 556af9557fdSGregory Neil Shapiro if (e->e_dfp != NULL) 557af9557fdSGregory Neil Shapiro { 558af9557fdSGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 559af9557fdSGregory Neil Shapiro e->e_dfp = NULL; 560af9557fdSGregory Neil Shapiro } 56140266059SGregory Neil Shapiro (void) xunlink(queuename(e, DATAFL_LETTER)); 562af9557fdSGregory Neil Shapiro } 56340266059SGregory Neil Shapiro if (panic && QueueMode == QM_LOST) 56440266059SGregory Neil Shapiro { 56540266059SGregory Neil Shapiro /* 56640266059SGregory Neil Shapiro ** leave the Qf file behind as 56740266059SGregory Neil Shapiro ** the delivery attempt failed. 56840266059SGregory Neil Shapiro */ 56940266059SGregory Neil Shapiro 57040266059SGregory Neil Shapiro /* EMPTY */ 57140266059SGregory Neil Shapiro } 57240266059SGregory Neil Shapiro else 57340266059SGregory Neil Shapiro if (xunlink(queuename(e, ANYQFL_LETTER)) == 0) 57440266059SGregory Neil Shapiro { 57540266059SGregory Neil Shapiro /* add to available space in filesystem */ 57613d88268SGregory Neil Shapiro updfs(e, -1, panic ? 0 : -1, "dropenvelope"); 57740266059SGregory Neil Shapiro } 578c2aa98e2SPeter Wemm 57906f25ae9SGregory Neil Shapiro if (e->e_ntries > 0 && LogLevel > 9) 58006f25ae9SGregory Neil Shapiro sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d", 58140266059SGregory Neil Shapiro pintvl(curtime() - e->e_ctime, true), 58206f25ae9SGregory Neil Shapiro e->e_ntries); 583c2aa98e2SPeter Wemm } 584c2aa98e2SPeter Wemm else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 585c2aa98e2SPeter Wemm { 58640266059SGregory Neil Shapiro if (!split) 58740266059SGregory Neil Shapiro queueup(e, false, true); 58840266059SGregory Neil Shapiro else 58940266059SGregory Neil Shapiro { 59040266059SGregory Neil Shapiro ENVELOPE *oldsib; 59140266059SGregory Neil Shapiro ENVELOPE *ee; 59240266059SGregory Neil Shapiro 59340266059SGregory Neil Shapiro /* 59440266059SGregory Neil Shapiro ** Save old sibling and set it to NULL to avoid 59540266059SGregory Neil Shapiro ** queueing up the same envelopes again. 59640266059SGregory Neil Shapiro ** This requires that envelopes in that list have 59740266059SGregory Neil Shapiro ** been take care of before (or at some other place). 59840266059SGregory Neil Shapiro */ 59940266059SGregory Neil Shapiro 60040266059SGregory Neil Shapiro oldsib = e->e_sibling; 60140266059SGregory Neil Shapiro e->e_sibling = NULL; 60240266059SGregory Neil Shapiro if (!split_by_recipient(e) && 60340266059SGregory Neil Shapiro bitset(EF_FATALERRS, e->e_flags)) 60440266059SGregory Neil Shapiro { 605da7d7b9cSGregory Neil Shapiro syserr("!dropenvelope(%s): cannot commit data file %s, uid=%ld", 60640266059SGregory Neil Shapiro e->e_id, queuename(e, DATAFL_LETTER), 607da7d7b9cSGregory Neil Shapiro (long) geteuid()); 60840266059SGregory Neil Shapiro } 60940266059SGregory Neil Shapiro for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 61040266059SGregory Neil Shapiro queueup(ee, false, true); 61140266059SGregory Neil Shapiro queueup(e, false, true); 61240266059SGregory Neil Shapiro 61340266059SGregory Neil Shapiro /* clean up */ 61440266059SGregory Neil Shapiro for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 61540266059SGregory Neil Shapiro { 61640266059SGregory Neil Shapiro /* now unlock the job */ 61740266059SGregory Neil Shapiro if (tTd(50, 8)) 61840266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): unlocking job\n", 61940266059SGregory Neil Shapiro ee->e_id); 62040266059SGregory Neil Shapiro closexscript(ee); 62140266059SGregory Neil Shapiro unlockqueue(ee); 62240266059SGregory Neil Shapiro 62340266059SGregory Neil Shapiro /* this envelope is marked unused */ 62440266059SGregory Neil Shapiro if (ee->e_dfp != NULL) 62540266059SGregory Neil Shapiro { 62640266059SGregory Neil Shapiro (void) sm_io_close(ee->e_dfp, 62740266059SGregory Neil Shapiro SM_TIME_DEFAULT); 62840266059SGregory Neil Shapiro ee->e_dfp = NULL; 62940266059SGregory Neil Shapiro } 63040266059SGregory Neil Shapiro ee->e_id = NULL; 63140266059SGregory Neil Shapiro ee->e_flags &= ~EF_HAS_DF; 63240266059SGregory Neil Shapiro } 63340266059SGregory Neil Shapiro e->e_sibling = oldsib; 63440266059SGregory Neil Shapiro } 635c2aa98e2SPeter Wemm } 636c2aa98e2SPeter Wemm 637c2aa98e2SPeter Wemm /* now unlock the job */ 638c2aa98e2SPeter Wemm if (tTd(50, 8)) 63940266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): unlocking job\n", id); 640c2aa98e2SPeter Wemm closexscript(e); 641c2aa98e2SPeter Wemm unlockqueue(e); 642c2aa98e2SPeter Wemm 643c2aa98e2SPeter Wemm /* make sure that this envelope is marked unused */ 644c2aa98e2SPeter Wemm if (e->e_dfp != NULL) 64540266059SGregory Neil Shapiro { 64640266059SGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 647c2aa98e2SPeter Wemm e->e_dfp = NULL; 64840266059SGregory Neil Shapiro } 649c2aa98e2SPeter Wemm e->e_id = NULL; 650c2aa98e2SPeter Wemm e->e_flags &= ~EF_HAS_DF; 6519bd497b8SGregory Neil Shapiro if (panic) 6529bd497b8SGregory Neil Shapiro return EX_IOERR; 6539bd497b8SGregory Neil Shapiro return EX_OK; 654c2aa98e2SPeter Wemm } 6559bd497b8SGregory Neil Shapiro 65640266059SGregory Neil Shapiro /* 657c2aa98e2SPeter Wemm ** CLEARENVELOPE -- clear an envelope without unlocking 658c2aa98e2SPeter Wemm ** 659c2aa98e2SPeter Wemm ** This is normally used by a child process to get a clean 660c2aa98e2SPeter Wemm ** envelope without disturbing the parent. 661c2aa98e2SPeter Wemm ** 662c2aa98e2SPeter Wemm ** Parameters: 663c2aa98e2SPeter Wemm ** e -- the envelope to clear. 664c2aa98e2SPeter Wemm ** fullclear - if set, the current envelope is total 665c2aa98e2SPeter Wemm ** garbage and should be ignored; otherwise, 666c2aa98e2SPeter Wemm ** release any resources it may indicate. 66740266059SGregory Neil Shapiro ** rpool -- either NULL, or a pointer to a resource pool 66840266059SGregory Neil Shapiro ** from which envelope memory is allocated, and 66940266059SGregory Neil Shapiro ** to which envelope resources are attached. 670c2aa98e2SPeter Wemm ** 671c2aa98e2SPeter Wemm ** Returns: 672c2aa98e2SPeter Wemm ** none. 673c2aa98e2SPeter Wemm ** 674c2aa98e2SPeter Wemm ** Side Effects: 675c2aa98e2SPeter Wemm ** Closes files associated with the envelope. 676c2aa98e2SPeter Wemm ** Marks the envelope as unallocated. 677c2aa98e2SPeter Wemm */ 678c2aa98e2SPeter Wemm 679c2aa98e2SPeter Wemm void 68040266059SGregory Neil Shapiro clearenvelope(e, fullclear, rpool) 681c2aa98e2SPeter Wemm register ENVELOPE *e; 682c2aa98e2SPeter Wemm bool fullclear; 68340266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 684c2aa98e2SPeter Wemm { 685c2aa98e2SPeter Wemm register HDR *bh; 686c2aa98e2SPeter Wemm register HDR **nhp; 687c2aa98e2SPeter Wemm extern ENVELOPE BlankEnvelope; 68840266059SGregory Neil Shapiro char **p; 689c2aa98e2SPeter Wemm 690c2aa98e2SPeter Wemm if (!fullclear) 691c2aa98e2SPeter Wemm { 692c2aa98e2SPeter Wemm /* clear out any file information */ 693c2aa98e2SPeter Wemm if (e->e_xfp != NULL) 69440266059SGregory Neil Shapiro (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); 695c2aa98e2SPeter Wemm if (e->e_dfp != NULL) 69640266059SGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 697c2aa98e2SPeter Wemm e->e_xfp = e->e_dfp = NULL; 698c2aa98e2SPeter Wemm } 699c2aa98e2SPeter Wemm 70040266059SGregory Neil Shapiro /* 70140266059SGregory Neil Shapiro ** Copy BlankEnvelope into *e. 70240266059SGregory Neil Shapiro ** It is not safe to simply copy pointers to strings; 70340266059SGregory Neil Shapiro ** the strings themselves must be copied (or set to NULL). 70440266059SGregory Neil Shapiro ** The problem is that when we assign a new string value to 70540266059SGregory Neil Shapiro ** a member of BlankEnvelope, we free the old string. 70640266059SGregory Neil Shapiro ** We did not need to do this copying in sendmail 8.11 :-( 70740266059SGregory Neil Shapiro ** and it is a potential performance hit. Reference counted 70840266059SGregory Neil Shapiro ** strings are one way out. 70940266059SGregory Neil Shapiro */ 71040266059SGregory Neil Shapiro 71140266059SGregory Neil Shapiro *e = BlankEnvelope; 712c2aa98e2SPeter Wemm e->e_message = NULL; 71340266059SGregory Neil Shapiro e->e_qfletter = '\0'; 71440266059SGregory Neil Shapiro e->e_quarmsg = NULL; 71540266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); 71640266059SGregory Neil Shapiro 71740266059SGregory Neil Shapiro /* 71840266059SGregory Neil Shapiro ** Copy the macro table. 71940266059SGregory Neil Shapiro ** We might be able to avoid this by zeroing the macro table 72040266059SGregory Neil Shapiro ** and always searching BlankEnvelope.e_macro after e->e_macro 72140266059SGregory Neil Shapiro ** in macvalue(). 72240266059SGregory Neil Shapiro */ 72340266059SGregory Neil Shapiro 72440266059SGregory Neil Shapiro for (p = &e->e_macro.mac_table[0]; 72540266059SGregory Neil Shapiro p <= &e->e_macro.mac_table[MAXMACROID]; 72640266059SGregory Neil Shapiro ++p) 72740266059SGregory Neil Shapiro { 72840266059SGregory Neil Shapiro if (*p != NULL) 72940266059SGregory Neil Shapiro *p = sm_rpool_strdup_x(rpool, *p); 73040266059SGregory Neil Shapiro } 73140266059SGregory Neil Shapiro 73240266059SGregory Neil Shapiro /* 73340266059SGregory Neil Shapiro ** XXX There are many strings in the envelope structure 73440266059SGregory Neil Shapiro ** XXX that we are not attempting to copy here. 73540266059SGregory Neil Shapiro ** XXX Investigate this further. 73640266059SGregory Neil Shapiro */ 73740266059SGregory Neil Shapiro 73840266059SGregory Neil Shapiro e->e_rpool = rpool; 73940266059SGregory Neil Shapiro e->e_macro.mac_rpool = rpool; 740c2aa98e2SPeter Wemm if (Verbose) 74106f25ae9SGregory Neil Shapiro set_delivery_mode(SM_DELIVER, e); 742c2aa98e2SPeter Wemm bh = BlankEnvelope.e_header; 743c2aa98e2SPeter Wemm nhp = &e->e_header; 744c2aa98e2SPeter Wemm while (bh != NULL) 745c2aa98e2SPeter Wemm { 746d0cef73dSGregory Neil Shapiro *nhp = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*bh)); 747d0cef73dSGregory Neil Shapiro memmove((char *) *nhp, (char *) bh, sizeof(*bh)); 748c2aa98e2SPeter Wemm bh = bh->h_link; 749c2aa98e2SPeter Wemm nhp = &(*nhp)->h_link; 750c2aa98e2SPeter Wemm } 7519bd497b8SGregory Neil Shapiro #if _FFR_MILTER_ENHSC 7529bd497b8SGregory Neil Shapiro e->e_enhsc[0] = '\0'; 753*5b0945b5SGregory Neil Shapiro #endif 754c2aa98e2SPeter Wemm } 75540266059SGregory Neil Shapiro /* 756c2aa98e2SPeter Wemm ** INITSYS -- initialize instantiation of system 757c2aa98e2SPeter Wemm ** 758c2aa98e2SPeter Wemm ** In Daemon mode, this is done in the child. 759c2aa98e2SPeter Wemm ** 760c2aa98e2SPeter Wemm ** Parameters: 76106f25ae9SGregory Neil Shapiro ** e -- the envelope to use. 762c2aa98e2SPeter Wemm ** 763c2aa98e2SPeter Wemm ** Returns: 764c2aa98e2SPeter Wemm ** none. 765c2aa98e2SPeter Wemm ** 766c2aa98e2SPeter Wemm ** Side Effects: 767c2aa98e2SPeter Wemm ** Initializes the system macros, some global variables, 768c2aa98e2SPeter Wemm ** etc. In particular, the current time in various 769c2aa98e2SPeter Wemm ** forms is set. 770c2aa98e2SPeter Wemm */ 771c2aa98e2SPeter Wemm 772c2aa98e2SPeter Wemm void 773c2aa98e2SPeter Wemm initsys(e) 774c2aa98e2SPeter Wemm register ENVELOPE *e; 775c2aa98e2SPeter Wemm { 77640266059SGregory Neil Shapiro char buf[10]; 777c2aa98e2SPeter Wemm #ifdef TTYNAME 778c2aa98e2SPeter Wemm static char ybuf[60]; /* holds tty id */ 779c2aa98e2SPeter Wemm register char *p; 780c2aa98e2SPeter Wemm extern char *ttyname(); 781c2aa98e2SPeter Wemm #endif /* TTYNAME */ 782c2aa98e2SPeter Wemm 783c2aa98e2SPeter Wemm /* 784c2aa98e2SPeter Wemm ** Give this envelope a reality. 785c2aa98e2SPeter Wemm ** I.e., an id, a transcript, and a creation time. 78640266059SGregory Neil Shapiro ** We don't select the queue until all of the recipients are known. 787c2aa98e2SPeter Wemm */ 788c2aa98e2SPeter Wemm 789c2aa98e2SPeter Wemm openxscript(e); 790c2aa98e2SPeter Wemm e->e_ctime = curtime(); 79140266059SGregory Neil Shapiro e->e_qfletter = '\0'; 792c2aa98e2SPeter Wemm 793c2aa98e2SPeter Wemm /* 794c2aa98e2SPeter Wemm ** Set OutChannel to something useful if stdout isn't it. 795c2aa98e2SPeter Wemm ** This arranges that any extra stuff the mailer produces 796c2aa98e2SPeter Wemm ** gets sent back to the user on error (because it is 797c2aa98e2SPeter Wemm ** tucked away in the transcript). 798c2aa98e2SPeter Wemm */ 799c2aa98e2SPeter Wemm 800c2aa98e2SPeter Wemm if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 801c2aa98e2SPeter Wemm e->e_xfp != NULL) 802c2aa98e2SPeter Wemm OutChannel = e->e_xfp; 803c2aa98e2SPeter Wemm 804c2aa98e2SPeter Wemm /* 805c2aa98e2SPeter Wemm ** Set up some basic system macros. 806c2aa98e2SPeter Wemm */ 807c2aa98e2SPeter Wemm 808c2aa98e2SPeter Wemm /* process id */ 809d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d", (int) CurrentPid); 81040266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'p', buf); 811c2aa98e2SPeter Wemm 812c2aa98e2SPeter Wemm /* hop count */ 813d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount); 81440266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'c', buf); 815c2aa98e2SPeter Wemm 816c2aa98e2SPeter Wemm /* time as integer, unix time, arpa time */ 817c2aa98e2SPeter Wemm settime(e); 818c2aa98e2SPeter Wemm 81906f25ae9SGregory Neil Shapiro /* Load average */ 82040266059SGregory Neil Shapiro sm_getla(); 82106f25ae9SGregory Neil Shapiro 822c2aa98e2SPeter Wemm #ifdef TTYNAME 823c2aa98e2SPeter Wemm /* tty name */ 824c2aa98e2SPeter Wemm if (macvalue('y', e) == NULL) 825c2aa98e2SPeter Wemm { 826c2aa98e2SPeter Wemm p = ttyname(2); 827c2aa98e2SPeter Wemm if (p != NULL) 828c2aa98e2SPeter Wemm { 829c2aa98e2SPeter Wemm if (strrchr(p, '/') != NULL) 830c2aa98e2SPeter Wemm p = strrchr(p, '/') + 1; 831d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(ybuf, sizeof(ybuf), p); 83240266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'y', ybuf); 833c2aa98e2SPeter Wemm } 834c2aa98e2SPeter Wemm } 835c2aa98e2SPeter Wemm #endif /* TTYNAME */ 836c2aa98e2SPeter Wemm } 83740266059SGregory Neil Shapiro /* 838c2aa98e2SPeter Wemm ** SETTIME -- set the current time. 839c2aa98e2SPeter Wemm ** 840c2aa98e2SPeter Wemm ** Parameters: 84106f25ae9SGregory Neil Shapiro ** e -- the envelope in which the macros should be set. 842c2aa98e2SPeter Wemm ** 843c2aa98e2SPeter Wemm ** Returns: 844c2aa98e2SPeter Wemm ** none. 845c2aa98e2SPeter Wemm ** 846c2aa98e2SPeter Wemm ** Side Effects: 847c2aa98e2SPeter Wemm ** Sets the various time macros -- $a, $b, $d, $t. 848c2aa98e2SPeter Wemm */ 849c2aa98e2SPeter Wemm 850c2aa98e2SPeter Wemm void 851c2aa98e2SPeter Wemm settime(e) 852c2aa98e2SPeter Wemm register ENVELOPE *e; 853c2aa98e2SPeter Wemm { 854c2aa98e2SPeter Wemm register char *p; 855c2aa98e2SPeter Wemm auto time_t now; 85640266059SGregory Neil Shapiro char buf[30]; 857c2aa98e2SPeter Wemm register struct tm *tm; 858c2aa98e2SPeter Wemm 859c2aa98e2SPeter Wemm now = curtime(); 860d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%ld", (long) now); 861e92d3f3fSGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, macid("{time}"), buf); 862c2aa98e2SPeter Wemm tm = gmtime(&now); 863d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d", 86440266059SGregory Neil Shapiro tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 86540266059SGregory Neil Shapiro tm->tm_hour, tm->tm_min); 86640266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 't', buf); 867d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(buf, ctime(&now), sizeof(buf)); 86840266059SGregory Neil Shapiro p = strchr(buf, '\n'); 869c2aa98e2SPeter Wemm if (p != NULL) 870c2aa98e2SPeter Wemm *p = '\0'; 87140266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'd', buf); 87240266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'b', arpadate(buf)); 873c2aa98e2SPeter Wemm if (macvalue('a', e) == NULL) 87440266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'a', macvalue('b', e)); 875c2aa98e2SPeter Wemm } 87640266059SGregory Neil Shapiro /* 877c2aa98e2SPeter Wemm ** OPENXSCRIPT -- Open transcript file 878c2aa98e2SPeter Wemm ** 879c2aa98e2SPeter Wemm ** Creates a transcript file for possible eventual mailing or 880c2aa98e2SPeter Wemm ** sending back. 881c2aa98e2SPeter Wemm ** 882c2aa98e2SPeter Wemm ** Parameters: 883c2aa98e2SPeter Wemm ** e -- the envelope to create the transcript in/for. 884c2aa98e2SPeter Wemm ** 885c2aa98e2SPeter Wemm ** Returns: 886c2aa98e2SPeter Wemm ** none 887c2aa98e2SPeter Wemm ** 888c2aa98e2SPeter Wemm ** Side Effects: 889c2aa98e2SPeter Wemm ** Creates the transcript file. 890c2aa98e2SPeter Wemm */ 891c2aa98e2SPeter Wemm 892c2aa98e2SPeter Wemm #ifndef O_APPEND 893c2aa98e2SPeter Wemm # define O_APPEND 0 894*5b0945b5SGregory Neil Shapiro #endif 895c2aa98e2SPeter Wemm 896c2aa98e2SPeter Wemm void 897c2aa98e2SPeter Wemm openxscript(e) 898c2aa98e2SPeter Wemm register ENVELOPE *e; 899c2aa98e2SPeter Wemm { 900c2aa98e2SPeter Wemm register char *p; 901c2aa98e2SPeter Wemm 902c2aa98e2SPeter Wemm if (e->e_xfp != NULL) 903c2aa98e2SPeter Wemm return; 90406f25ae9SGregory Neil Shapiro 90506f25ae9SGregory Neil Shapiro #if 0 90606f25ae9SGregory Neil Shapiro if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags)) 90706f25ae9SGregory Neil Shapiro syserr("openxscript: job not locked"); 908*5b0945b5SGregory Neil Shapiro #endif 90906f25ae9SGregory Neil Shapiro 91040266059SGregory Neil Shapiro p = queuename(e, XSCRPT_LETTER); 91106f25ae9SGregory Neil Shapiro e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize, 91206f25ae9SGregory Neil Shapiro SFF_NOTEXCL|SFF_OPENASROOT); 91306f25ae9SGregory Neil Shapiro 91406f25ae9SGregory Neil Shapiro if (e->e_xfp == NULL) 915c2aa98e2SPeter Wemm { 916c2aa98e2SPeter Wemm syserr("Can't create transcript file %s", p); 91740266059SGregory Neil Shapiro e->e_xfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, 91840266059SGregory Neil Shapiro SM_PATH_DEVNULL, SM_IO_RDWR, NULL); 91906f25ae9SGregory Neil Shapiro if (e->e_xfp == NULL) 92040266059SGregory Neil Shapiro syserr("!Can't open %s", SM_PATH_DEVNULL); 921c2aa98e2SPeter Wemm } 92240266059SGregory Neil Shapiro (void) sm_io_setvbuf(e->e_xfp, SM_TIME_DEFAULT, NULL, SM_IO_LBF, 0); 923c2aa98e2SPeter Wemm if (tTd(46, 9)) 924c2aa98e2SPeter Wemm { 92540266059SGregory Neil Shapiro sm_dprintf("openxscript(%s):\n ", p); 92640266059SGregory Neil Shapiro dumpfd(sm_io_getinfo(e->e_xfp, SM_IO_WHAT_FD, NULL), true, 92740266059SGregory Neil Shapiro false); 928c2aa98e2SPeter Wemm } 929c2aa98e2SPeter Wemm } 93040266059SGregory Neil Shapiro /* 931c2aa98e2SPeter Wemm ** CLOSEXSCRIPT -- close the transcript file. 932c2aa98e2SPeter Wemm ** 933c2aa98e2SPeter Wemm ** Parameters: 934c2aa98e2SPeter Wemm ** e -- the envelope containing the transcript to close. 935c2aa98e2SPeter Wemm ** 936c2aa98e2SPeter Wemm ** Returns: 937c2aa98e2SPeter Wemm ** none. 938c2aa98e2SPeter Wemm ** 939c2aa98e2SPeter Wemm ** Side Effects: 940c2aa98e2SPeter Wemm ** none. 941c2aa98e2SPeter Wemm */ 942c2aa98e2SPeter Wemm 943c2aa98e2SPeter Wemm void 944c2aa98e2SPeter Wemm closexscript(e) 945c2aa98e2SPeter Wemm register ENVELOPE *e; 946c2aa98e2SPeter Wemm { 947c2aa98e2SPeter Wemm if (e->e_xfp == NULL) 948c2aa98e2SPeter Wemm return; 94906f25ae9SGregory Neil Shapiro #if 0 95006f25ae9SGregory Neil Shapiro if (e->e_lockfp == NULL) 95106f25ae9SGregory Neil Shapiro syserr("closexscript: job not locked"); 952*5b0945b5SGregory Neil Shapiro #endif 95340266059SGregory Neil Shapiro (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); 954c2aa98e2SPeter Wemm e->e_xfp = NULL; 955c2aa98e2SPeter Wemm } 95640266059SGregory Neil Shapiro /* 957c2aa98e2SPeter Wemm ** SETSENDER -- set the person who this message is from 958c2aa98e2SPeter Wemm ** 959c2aa98e2SPeter Wemm ** Under certain circumstances allow the user to say who 960c2aa98e2SPeter Wemm ** s/he is (using -f or -r). These are: 961c2aa98e2SPeter Wemm ** 1. The user's uid is zero (root). 962c2aa98e2SPeter Wemm ** 2. The user's login name is in an approved list (typically 963c2aa98e2SPeter Wemm ** from a network server). 964c2aa98e2SPeter Wemm ** 3. The address the user is trying to claim has a 965c2aa98e2SPeter Wemm ** "!" character in it (since #2 doesn't do it for 966c2aa98e2SPeter Wemm ** us if we are dialing out for UUCP). 967c2aa98e2SPeter Wemm ** A better check to replace #3 would be if the 968c2aa98e2SPeter Wemm ** effective uid is "UUCP" -- this would require me 969c2aa98e2SPeter Wemm ** to rewrite getpwent to "grab" uucp as it went by, 970c2aa98e2SPeter Wemm ** make getname more nasty, do another passwd file 971c2aa98e2SPeter Wemm ** scan, or compile the UID of "UUCP" into the code, 972c2aa98e2SPeter Wemm ** all of which are reprehensible. 973c2aa98e2SPeter Wemm ** 974c2aa98e2SPeter Wemm ** Assuming all of these fail, we figure out something 975c2aa98e2SPeter Wemm ** ourselves. 976c2aa98e2SPeter Wemm ** 977c2aa98e2SPeter Wemm ** Parameters: 978c2aa98e2SPeter Wemm ** from -- the person we would like to believe this message 979c2aa98e2SPeter Wemm ** is from, as specified on the command line. 980c2aa98e2SPeter Wemm ** e -- the envelope in which we would like the sender set. 981c2aa98e2SPeter Wemm ** delimptr -- if non-NULL, set to the location of the 982c2aa98e2SPeter Wemm ** trailing delimiter. 983c2aa98e2SPeter Wemm ** delimchar -- the character that will delimit the sender 984c2aa98e2SPeter Wemm ** address. 985c2aa98e2SPeter Wemm ** internal -- set if this address is coming from an internal 986c2aa98e2SPeter Wemm ** source such as an owner alias. 987c2aa98e2SPeter Wemm ** 988c2aa98e2SPeter Wemm ** Returns: 989c2aa98e2SPeter Wemm ** none. 990c2aa98e2SPeter Wemm ** 991c2aa98e2SPeter Wemm ** Side Effects: 992c2aa98e2SPeter Wemm ** sets sendmail's notion of who the from person is. 993c2aa98e2SPeter Wemm */ 994c2aa98e2SPeter Wemm 995c2aa98e2SPeter Wemm void 996c2aa98e2SPeter Wemm setsender(from, e, delimptr, delimchar, internal) 997c2aa98e2SPeter Wemm char *from; 998c2aa98e2SPeter Wemm register ENVELOPE *e; 999c2aa98e2SPeter Wemm char **delimptr; 1000c2aa98e2SPeter Wemm int delimchar; 1001c2aa98e2SPeter Wemm bool internal; 1002c2aa98e2SPeter Wemm { 1003c2aa98e2SPeter Wemm register char **pvp; 1004c2aa98e2SPeter Wemm char *realname = NULL; 1005c2aa98e2SPeter Wemm char *bp; 1006c2aa98e2SPeter Wemm char buf[MAXNAME + 2]; 1007c2aa98e2SPeter Wemm char pvpbuf[PSBUFSIZE]; 1008c2aa98e2SPeter Wemm extern char *FullName; 1009c2aa98e2SPeter Wemm 1010c2aa98e2SPeter Wemm if (tTd(45, 1)) 101140266059SGregory Neil Shapiro sm_dprintf("setsender(%s)\n", from == NULL ? "" : from); 1012c2aa98e2SPeter Wemm 101313bd1963SGregory Neil Shapiro /* may be set from earlier calls */ 101413bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'x', ""); 101513bd1963SGregory Neil Shapiro 1016c2aa98e2SPeter Wemm /* 1017c2aa98e2SPeter Wemm ** Figure out the real user executing us. 1018c2aa98e2SPeter Wemm ** Username can return errno != 0 on non-errors. 1019c2aa98e2SPeter Wemm */ 1020c2aa98e2SPeter Wemm 1021c2aa98e2SPeter Wemm if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 1022c2aa98e2SPeter Wemm OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 1023c2aa98e2SPeter Wemm realname = from; 1024c2aa98e2SPeter Wemm if (realname == NULL || realname[0] == '\0') 1025c2aa98e2SPeter Wemm realname = username(); 1026c2aa98e2SPeter Wemm 1027c2aa98e2SPeter Wemm if (ConfigLevel < 2) 102840266059SGregory Neil Shapiro SuprErrs = true; 1029c2aa98e2SPeter Wemm 103040266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 103140266059SGregory Neil Shapiro 103206f25ae9SGregory Neil Shapiro /* preset state for then clause in case from == NULL */ 103306f25ae9SGregory Neil Shapiro e->e_from.q_state = QS_BADADDR; 103406f25ae9SGregory Neil Shapiro e->e_from.q_flags = 0; 1035c2aa98e2SPeter Wemm if (from == NULL || 1036c2aa98e2SPeter Wemm parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 103740266059SGregory Neil Shapiro delimchar, delimptr, e, false) == NULL || 103806f25ae9SGregory Neil Shapiro QS_IS_BADADDR(e->e_from.q_state) || 1039c2aa98e2SPeter Wemm e->e_from.q_mailer == ProgMailer || 1040c2aa98e2SPeter Wemm e->e_from.q_mailer == FileMailer || 1041c2aa98e2SPeter Wemm e->e_from.q_mailer == InclMailer) 1042c2aa98e2SPeter Wemm { 1043c2aa98e2SPeter Wemm /* log garbage addresses for traceback */ 1044c2aa98e2SPeter Wemm if (from != NULL && LogLevel > 2) 1045c2aa98e2SPeter Wemm { 1046c2aa98e2SPeter Wemm char *p; 1047c2aa98e2SPeter Wemm char ebuf[MAXNAME * 2 + 2]; 1048c2aa98e2SPeter Wemm 1049c2aa98e2SPeter Wemm p = macvalue('_', e); 1050c2aa98e2SPeter Wemm if (p == NULL) 1051c2aa98e2SPeter Wemm { 1052c2aa98e2SPeter Wemm char *host = RealHostName; 1053c2aa98e2SPeter Wemm 1054c2aa98e2SPeter Wemm if (host == NULL) 1055c2aa98e2SPeter Wemm host = MyHostName; 1056d0cef73dSGregory Neil Shapiro (void) sm_snprintf(ebuf, sizeof(ebuf), 105740266059SGregory Neil Shapiro "%.*s@%.*s", MAXNAME, 105840266059SGregory Neil Shapiro realname, MAXNAME, host); 1059c2aa98e2SPeter Wemm p = ebuf; 1060c2aa98e2SPeter Wemm } 1061c2aa98e2SPeter Wemm sm_syslog(LOG_NOTICE, e->e_id, 106206f25ae9SGregory Neil Shapiro "setsender: %s: invalid or unparsable, received from %s", 1063c2aa98e2SPeter Wemm shortenstring(from, 83), p); 1064c2aa98e2SPeter Wemm } 1065c2aa98e2SPeter Wemm if (from != NULL) 1066c2aa98e2SPeter Wemm { 106706f25ae9SGregory Neil Shapiro if (!QS_IS_BADADDR(e->e_from.q_state)) 1068c2aa98e2SPeter Wemm { 1069c2aa98e2SPeter Wemm /* it was a bogus mailer in the from addr */ 1070c2aa98e2SPeter Wemm e->e_status = "5.1.7"; 107106f25ae9SGregory Neil Shapiro usrerrenh(e->e_status, 107206f25ae9SGregory Neil Shapiro "553 Invalid sender address"); 1073c2aa98e2SPeter Wemm } 107440266059SGregory Neil Shapiro SuprErrs = true; 1075c2aa98e2SPeter Wemm } 1076c2aa98e2SPeter Wemm if (from == realname || 107740266059SGregory Neil Shapiro parseaddr(from = realname, 107840266059SGregory Neil Shapiro &e->e_from, RF_COPYALL|RF_SENDERADDR, ' ', 107940266059SGregory Neil Shapiro NULL, e, false) == NULL) 1080c2aa98e2SPeter Wemm { 1081c2aa98e2SPeter Wemm char nbuf[100]; 1082c2aa98e2SPeter Wemm 108340266059SGregory Neil Shapiro SuprErrs = true; 1084d0cef73dSGregory Neil Shapiro expand("\201n", nbuf, sizeof(nbuf), e); 108540266059SGregory Neil Shapiro from = sm_rpool_strdup_x(e->e_rpool, nbuf); 108640266059SGregory Neil Shapiro if (parseaddr(from, &e->e_from, RF_COPYALL, ' ', 108740266059SGregory Neil Shapiro NULL, e, false) == NULL && 1088c2aa98e2SPeter Wemm parseaddr(from = "postmaster", &e->e_from, 108940266059SGregory Neil Shapiro RF_COPYALL, ' ', NULL, e, false) == NULL) 109006f25ae9SGregory Neil Shapiro syserr("553 5.3.0 setsender: can't even parse postmaster!"); 1091c2aa98e2SPeter Wemm } 1092c2aa98e2SPeter Wemm } 1093c2aa98e2SPeter Wemm else 109440266059SGregory Neil Shapiro FromFlag = true; 109506f25ae9SGregory Neil Shapiro e->e_from.q_state = QS_SENDER; 1096c2aa98e2SPeter Wemm if (tTd(45, 5)) 1097c2aa98e2SPeter Wemm { 109840266059SGregory Neil Shapiro sm_dprintf("setsender: QS_SENDER "); 1099e92d3f3fSGregory Neil Shapiro printaddr(sm_debug_file(), &e->e_from, false); 1100c2aa98e2SPeter Wemm } 110140266059SGregory Neil Shapiro SuprErrs = false; 1102c2aa98e2SPeter Wemm 1103c2aa98e2SPeter Wemm #if USERDB 1104c2aa98e2SPeter Wemm if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 1105c2aa98e2SPeter Wemm { 1106c2aa98e2SPeter Wemm register char *p; 1107c2aa98e2SPeter Wemm 110840266059SGregory Neil Shapiro p = udbsender(e->e_from.q_user, e->e_rpool); 1109c2aa98e2SPeter Wemm if (p != NULL) 1110c2aa98e2SPeter Wemm from = p; 1111c2aa98e2SPeter Wemm } 1112c2aa98e2SPeter Wemm #endif /* USERDB */ 1113c2aa98e2SPeter Wemm 1114c2aa98e2SPeter Wemm if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 1115c2aa98e2SPeter Wemm { 111640266059SGregory Neil Shapiro SM_MBDB_T user; 111740266059SGregory Neil Shapiro 1118c2aa98e2SPeter Wemm if (!internal) 1119c2aa98e2SPeter Wemm { 1120c2aa98e2SPeter Wemm /* if the user already given fullname don't redefine */ 1121c2aa98e2SPeter Wemm if (FullName == NULL) 1122c2aa98e2SPeter Wemm FullName = macvalue('x', e); 1123605302a5SGregory Neil Shapiro if (FullName != NULL) 1124605302a5SGregory Neil Shapiro { 1125605302a5SGregory Neil Shapiro if (FullName[0] == '\0') 1126c2aa98e2SPeter Wemm FullName = NULL; 1127605302a5SGregory Neil Shapiro else 1128605302a5SGregory Neil Shapiro FullName = newstr(FullName); 1129605302a5SGregory Neil Shapiro } 1130c2aa98e2SPeter Wemm } 1131c2aa98e2SPeter Wemm 1132c2aa98e2SPeter Wemm if (e->e_from.q_user[0] != '\0' && 113340266059SGregory Neil Shapiro sm_mbdb_lookup(e->e_from.q_user, &user) == EX_OK) 1134c2aa98e2SPeter Wemm { 1135c2aa98e2SPeter Wemm /* 1136c2aa98e2SPeter Wemm ** Process passwd file entry. 1137c2aa98e2SPeter Wemm */ 1138c2aa98e2SPeter Wemm 1139c2aa98e2SPeter Wemm /* extract home directory */ 114040266059SGregory Neil Shapiro if (*user.mbdb_homedir == '\0') 114142e5d165SGregory Neil Shapiro e->e_from.q_home = NULL; 114240266059SGregory Neil Shapiro else if (strcmp(user.mbdb_homedir, "/") == 0) 114340266059SGregory Neil Shapiro e->e_from.q_home = ""; 1144c2aa98e2SPeter Wemm else 114540266059SGregory Neil Shapiro e->e_from.q_home = sm_rpool_strdup_x(e->e_rpool, 114640266059SGregory Neil Shapiro user.mbdb_homedir); 114740266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'z', e->e_from.q_home); 1148c2aa98e2SPeter Wemm 1149c2aa98e2SPeter Wemm /* extract user and group id */ 115040266059SGregory Neil Shapiro if (user.mbdb_uid != SM_NO_UID) 115140266059SGregory Neil Shapiro { 115240266059SGregory Neil Shapiro e->e_from.q_uid = user.mbdb_uid; 115340266059SGregory Neil Shapiro e->e_from.q_gid = user.mbdb_gid; 1154c2aa98e2SPeter Wemm e->e_from.q_flags |= QGOODUID; 115540266059SGregory Neil Shapiro } 1156c2aa98e2SPeter Wemm 1157c2aa98e2SPeter Wemm /* extract full name from passwd file */ 115840266059SGregory Neil Shapiro if (FullName == NULL && !internal && 115940266059SGregory Neil Shapiro user.mbdb_fullname[0] != '\0' && 116040266059SGregory Neil Shapiro strcmp(user.mbdb_name, e->e_from.q_user) == 0) 1161c2aa98e2SPeter Wemm { 116240266059SGregory Neil Shapiro FullName = newstr(user.mbdb_fullname); 1163c2aa98e2SPeter Wemm } 1164c2aa98e2SPeter Wemm } 1165c2aa98e2SPeter Wemm else 1166c2aa98e2SPeter Wemm { 116706f25ae9SGregory Neil Shapiro e->e_from.q_home = NULL; 1168c2aa98e2SPeter Wemm } 1169c2aa98e2SPeter Wemm if (FullName != NULL && !internal) 117013bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'x', FullName); 1171c2aa98e2SPeter Wemm } 11722e43090eSPeter Wemm else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP) 1173c2aa98e2SPeter Wemm { 1174c2aa98e2SPeter Wemm if (e->e_from.q_home == NULL) 1175c2aa98e2SPeter Wemm { 1176c2aa98e2SPeter Wemm e->e_from.q_home = getenv("HOME"); 117742e5d165SGregory Neil Shapiro if (e->e_from.q_home != NULL) 117842e5d165SGregory Neil Shapiro { 117942e5d165SGregory Neil Shapiro if (*e->e_from.q_home == '\0') 118042e5d165SGregory Neil Shapiro e->e_from.q_home = NULL; 118142e5d165SGregory Neil Shapiro else if (strcmp(e->e_from.q_home, "/") == 0) 1182c2aa98e2SPeter Wemm e->e_from.q_home++; 1183c2aa98e2SPeter Wemm } 118442e5d165SGregory Neil Shapiro } 1185c2aa98e2SPeter Wemm e->e_from.q_uid = RealUid; 1186c2aa98e2SPeter Wemm e->e_from.q_gid = RealGid; 1187c2aa98e2SPeter Wemm e->e_from.q_flags |= QGOODUID; 1188c2aa98e2SPeter Wemm } 1189c2aa98e2SPeter Wemm 1190c2aa98e2SPeter Wemm /* 1191c2aa98e2SPeter Wemm ** Rewrite the from person to dispose of possible implicit 1192c2aa98e2SPeter Wemm ** links in the net. 1193c2aa98e2SPeter Wemm */ 1194c2aa98e2SPeter Wemm 1195d0cef73dSGregory Neil Shapiro pvp = prescan(from, delimchar, pvpbuf, sizeof(pvpbuf), NULL, 1196d0cef73dSGregory Neil Shapiro IntTokenTab, false); 1197c2aa98e2SPeter Wemm if (pvp == NULL) 1198c2aa98e2SPeter Wemm { 1199c2aa98e2SPeter Wemm /* don't need to give error -- prescan did that already */ 1200c2aa98e2SPeter Wemm if (LogLevel > 2) 1201c2aa98e2SPeter Wemm sm_syslog(LOG_NOTICE, e->e_id, 1202c2aa98e2SPeter Wemm "cannot prescan from (%s)", 1203c2aa98e2SPeter Wemm shortenstring(from, MAXSHORTSTR)); 120440266059SGregory Neil Shapiro finis(true, true, ExitStat); 1205c2aa98e2SPeter Wemm } 120640266059SGregory Neil Shapiro (void) REWRITE(pvp, 3, e); 120740266059SGregory Neil Shapiro (void) REWRITE(pvp, 1, e); 120840266059SGregory Neil Shapiro (void) REWRITE(pvp, 4, e); 120940266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); 1210c2aa98e2SPeter Wemm bp = buf + 1; 1211d0cef73dSGregory Neil Shapiro cataddr(pvp, NULL, bp, sizeof(buf) - 2, '\0', false); 1212c2aa98e2SPeter Wemm if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 1213c2aa98e2SPeter Wemm { 1214c2aa98e2SPeter Wemm /* heuristic: route-addr: add angle brackets */ 1215d0cef73dSGregory Neil Shapiro (void) sm_strlcat(bp, ">", sizeof(buf) - 1); 1216c2aa98e2SPeter Wemm *--bp = '<'; 1217c2aa98e2SPeter Wemm } 121840266059SGregory Neil Shapiro e->e_sender = sm_rpool_strdup_x(e->e_rpool, bp); 121940266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'f', e->e_sender); 1220c2aa98e2SPeter Wemm 1221c2aa98e2SPeter Wemm /* save the domain spec if this mailer wants it */ 1222c2aa98e2SPeter Wemm if (e->e_from.q_mailer != NULL && 1223c2aa98e2SPeter Wemm bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 1224c2aa98e2SPeter Wemm { 1225c2aa98e2SPeter Wemm char **lastat; 1226c2aa98e2SPeter Wemm 1227c2aa98e2SPeter Wemm /* get rid of any pesky angle brackets */ 122840266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 122940266059SGregory Neil Shapiro (void) REWRITE(pvp, 3, e); 123040266059SGregory Neil Shapiro (void) REWRITE(pvp, 1, e); 123140266059SGregory Neil Shapiro (void) REWRITE(pvp, 4, e); 123240266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); 1233c2aa98e2SPeter Wemm 1234c2aa98e2SPeter Wemm /* strip off to the last "@" sign */ 1235c2aa98e2SPeter Wemm for (lastat = NULL; *pvp != NULL; pvp++) 1236e92d3f3fSGregory Neil Shapiro { 1237c2aa98e2SPeter Wemm if (strcmp(*pvp, "@") == 0) 1238c2aa98e2SPeter Wemm lastat = pvp; 1239e92d3f3fSGregory Neil Shapiro } 1240c2aa98e2SPeter Wemm if (lastat != NULL) 1241c2aa98e2SPeter Wemm { 124240266059SGregory Neil Shapiro e->e_fromdomain = copyplist(lastat, true, e->e_rpool); 1243c2aa98e2SPeter Wemm if (tTd(45, 3)) 1244c2aa98e2SPeter Wemm { 124540266059SGregory Neil Shapiro sm_dprintf("Saving from domain: "); 1246e92d3f3fSGregory Neil Shapiro printav(sm_debug_file(), e->e_fromdomain); 1247c2aa98e2SPeter Wemm } 1248c2aa98e2SPeter Wemm } 1249c2aa98e2SPeter Wemm } 1250c2aa98e2SPeter Wemm } 125140266059SGregory Neil Shapiro /* 1252c2aa98e2SPeter Wemm ** PRINTENVFLAGS -- print envelope flags for debugging 1253c2aa98e2SPeter Wemm ** 1254c2aa98e2SPeter Wemm ** Parameters: 1255c2aa98e2SPeter Wemm ** e -- the envelope with the flags to be printed. 1256c2aa98e2SPeter Wemm ** 1257c2aa98e2SPeter Wemm ** Returns: 1258c2aa98e2SPeter Wemm ** none. 1259c2aa98e2SPeter Wemm */ 1260c2aa98e2SPeter Wemm 1261c2aa98e2SPeter Wemm struct eflags 1262c2aa98e2SPeter Wemm { 1263c2aa98e2SPeter Wemm char *ef_name; 126440266059SGregory Neil Shapiro unsigned long ef_bit; 1265c2aa98e2SPeter Wemm }; 1266c2aa98e2SPeter Wemm 126706f25ae9SGregory Neil Shapiro static struct eflags EnvelopeFlags[] = 1268c2aa98e2SPeter Wemm { 1269c2aa98e2SPeter Wemm { "OLDSTYLE", EF_OLDSTYLE }, 1270c2aa98e2SPeter Wemm { "INQUEUE", EF_INQUEUE }, 1271c2aa98e2SPeter Wemm { "NO_BODY_RETN", EF_NO_BODY_RETN }, 1272c2aa98e2SPeter Wemm { "CLRQUEUE", EF_CLRQUEUE }, 1273c2aa98e2SPeter Wemm { "SENDRECEIPT", EF_SENDRECEIPT }, 1274c2aa98e2SPeter Wemm { "FATALERRS", EF_FATALERRS }, 1275c2aa98e2SPeter Wemm { "DELETE_BCC", EF_DELETE_BCC }, 1276c2aa98e2SPeter Wemm { "RESPONSE", EF_RESPONSE }, 1277c2aa98e2SPeter Wemm { "RESENT", EF_RESENT }, 1278c2aa98e2SPeter Wemm { "VRFYONLY", EF_VRFYONLY }, 1279c2aa98e2SPeter Wemm { "WARNING", EF_WARNING }, 1280c2aa98e2SPeter Wemm { "QUEUERUN", EF_QUEUERUN }, 1281c2aa98e2SPeter Wemm { "GLOBALERRS", EF_GLOBALERRS }, 1282c2aa98e2SPeter Wemm { "PM_NOTIFY", EF_PM_NOTIFY }, 1283c2aa98e2SPeter Wemm { "METOO", EF_METOO }, 1284c2aa98e2SPeter Wemm { "LOGSENDER", EF_LOGSENDER }, 1285c2aa98e2SPeter Wemm { "NORECEIPT", EF_NORECEIPT }, 1286c2aa98e2SPeter Wemm { "HAS8BIT", EF_HAS8BIT }, 1287c2aa98e2SPeter Wemm { "RET_PARAM", EF_RET_PARAM }, 1288c2aa98e2SPeter Wemm { "HAS_DF", EF_HAS_DF }, 1289c2aa98e2SPeter Wemm { "IS_MIME", EF_IS_MIME }, 1290c2aa98e2SPeter Wemm { "DONT_MIME", EF_DONT_MIME }, 129140266059SGregory Neil Shapiro { "DISCARD", EF_DISCARD }, 129240266059SGregory Neil Shapiro { "TOOBIG", EF_TOOBIG }, 129340266059SGregory Neil Shapiro { "SPLIT", EF_SPLIT }, 129440266059SGregory Neil Shapiro { "UNSAFE", EF_UNSAFE }, 1295*5b0945b5SGregory Neil Shapiro { "TOODEEP", EF_TOODEEP }, 1296*5b0945b5SGregory Neil Shapiro { "SECURE", EF_SECURE }, 1297193538b7SGregory Neil Shapiro { NULL, 0 } 1298c2aa98e2SPeter Wemm }; 1299c2aa98e2SPeter Wemm 1300c2aa98e2SPeter Wemm void 1301c2aa98e2SPeter Wemm printenvflags(e) 1302c2aa98e2SPeter Wemm register ENVELOPE *e; 1303c2aa98e2SPeter Wemm { 1304c2aa98e2SPeter Wemm register struct eflags *ef; 130540266059SGregory Neil Shapiro bool first = true; 1306c2aa98e2SPeter Wemm 1307e92d3f3fSGregory Neil Shapiro sm_dprintf("%lx", e->e_flags); 1308c2aa98e2SPeter Wemm for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) 1309c2aa98e2SPeter Wemm { 1310c2aa98e2SPeter Wemm if (!bitset(ef->ef_bit, e->e_flags)) 1311c2aa98e2SPeter Wemm continue; 1312c2aa98e2SPeter Wemm if (first) 1313e92d3f3fSGregory Neil Shapiro sm_dprintf("<%s", ef->ef_name); 1314c2aa98e2SPeter Wemm else 1315e92d3f3fSGregory Neil Shapiro sm_dprintf(",%s", ef->ef_name); 131640266059SGregory Neil Shapiro first = false; 1317c2aa98e2SPeter Wemm } 1318c2aa98e2SPeter Wemm if (!first) 1319e92d3f3fSGregory Neil Shapiro sm_dprintf(">\n"); 1320c2aa98e2SPeter Wemm } 1321