1c2aa98e2SPeter Wemm /* 2d0cef73dSGregory Neil Shapiro * Copyright (c) 1998-2003, 2006 Sendmail, 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 16d0cef73dSGregory Neil Shapiro SM_RCSID("@(#)$Id: envelope.c,v 8.302 2006/11/10 23:12:52 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 # if _FFR_TLS_1 4613bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{alg_bits}"), ""); 4713bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cn_issuer}"), ""); 4813bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{cn_subject}"), ""); 4913bd1963SGregory Neil Shapiro # endif /* _FFR_TLS_1 */ 5013bd1963SGregory Neil Shapiro #endif /* STARTTLS */ 5113bd1963SGregory Neil Shapiro } 52c2aa98e2SPeter Wemm 53c2aa98e2SPeter Wemm /* 5440266059SGregory Neil Shapiro ** NEWENVELOPE -- fill in a new envelope 55c2aa98e2SPeter Wemm ** 56c2aa98e2SPeter Wemm ** Supports inheritance. 57c2aa98e2SPeter Wemm ** 58c2aa98e2SPeter Wemm ** Parameters: 59c2aa98e2SPeter Wemm ** e -- the new envelope to fill in. 60c2aa98e2SPeter Wemm ** parent -- the envelope to be the parent of e. 6140266059SGregory Neil Shapiro ** rpool -- either NULL, or a pointer to a resource pool 6240266059SGregory Neil Shapiro ** from which envelope memory is allocated, and 6340266059SGregory Neil Shapiro ** to which envelope resources are attached. 64c2aa98e2SPeter Wemm ** 65c2aa98e2SPeter Wemm ** Returns: 66c2aa98e2SPeter Wemm ** e. 67c2aa98e2SPeter Wemm ** 68c2aa98e2SPeter Wemm ** Side Effects: 69c2aa98e2SPeter Wemm ** none. 70c2aa98e2SPeter Wemm */ 71c2aa98e2SPeter Wemm 72c2aa98e2SPeter Wemm ENVELOPE * 7340266059SGregory Neil Shapiro newenvelope(e, parent, rpool) 74c2aa98e2SPeter Wemm register ENVELOPE *e; 75c2aa98e2SPeter Wemm register ENVELOPE *parent; 7640266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 77c2aa98e2SPeter Wemm { 784e4196cbSGregory Neil Shapiro int sendmode; 794e4196cbSGregory Neil Shapiro 8040266059SGregory Neil Shapiro /* 8140266059SGregory Neil Shapiro ** This code used to read: 8240266059SGregory Neil Shapiro ** if (e == parent && e->e_parent != NULL) 8340266059SGregory Neil Shapiro ** parent = e->e_parent; 8440266059SGregory Neil Shapiro ** So if e == parent && e->e_parent == NULL then we would 8540266059SGregory Neil Shapiro ** set e->e_parent = e, which creates a loop in the e_parent chain. 8640266059SGregory Neil Shapiro ** This meant macvalue() could go into an infinite loop. 8740266059SGregory Neil Shapiro */ 8840266059SGregory Neil Shapiro 894e4196cbSGregory Neil Shapiro if (parent != NULL) 904e4196cbSGregory Neil Shapiro sendmode = parent->e_sendmode; 914e4196cbSGregory Neil Shapiro else 924e4196cbSGregory Neil Shapiro sendmode = DM_NOTSET; 934e4196cbSGregory Neil Shapiro 9440266059SGregory Neil Shapiro if (e == parent) 95c2aa98e2SPeter Wemm parent = e->e_parent; 9640266059SGregory Neil Shapiro clearenvelope(e, true, rpool); 97c2aa98e2SPeter Wemm if (e == CurEnv) 9806f25ae9SGregory Neil Shapiro memmove((char *) &e->e_from, 9906f25ae9SGregory Neil Shapiro (char *) &NullAddress, 100d0cef73dSGregory Neil Shapiro sizeof(e->e_from)); 101c2aa98e2SPeter Wemm else 10206f25ae9SGregory Neil Shapiro memmove((char *) &e->e_from, 10306f25ae9SGregory Neil Shapiro (char *) &CurEnv->e_from, 104d0cef73dSGregory Neil Shapiro sizeof(e->e_from)); 105c2aa98e2SPeter Wemm e->e_parent = parent; 10606f25ae9SGregory Neil Shapiro assign_queueid(e); 107c2aa98e2SPeter Wemm e->e_ctime = curtime(); 108c2aa98e2SPeter Wemm if (parent != NULL) 10940266059SGregory Neil Shapiro { 110c2aa98e2SPeter Wemm e->e_msgpriority = parent->e_msgsize; 11140266059SGregory Neil Shapiro if (parent->e_quarmsg == NULL) 11240266059SGregory Neil Shapiro { 11340266059SGregory Neil Shapiro e->e_quarmsg = NULL; 11440266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 11540266059SGregory Neil Shapiro macid("{quarantine}"), ""); 11640266059SGregory Neil Shapiro } 11740266059SGregory Neil Shapiro else 11840266059SGregory Neil Shapiro { 11940266059SGregory Neil Shapiro e->e_quarmsg = sm_rpool_strdup_x(rpool, 12040266059SGregory Neil Shapiro parent->e_quarmsg); 12140266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 12240266059SGregory Neil Shapiro macid("{quarantine}"), e->e_quarmsg); 12340266059SGregory Neil Shapiro } 12440266059SGregory Neil Shapiro } 125c2aa98e2SPeter Wemm e->e_puthdr = putheader; 126c2aa98e2SPeter Wemm e->e_putbody = putbody; 127c2aa98e2SPeter Wemm if (CurEnv->e_xfp != NULL) 12840266059SGregory Neil Shapiro (void) sm_io_flush(CurEnv->e_xfp, SM_TIME_DEFAULT); 1294e4196cbSGregory Neil Shapiro if (sendmode != DM_NOTSET) 1304e4196cbSGregory Neil Shapiro e->e_sendmode = sendmode; 131c2aa98e2SPeter Wemm 13206f25ae9SGregory Neil Shapiro return e; 133c2aa98e2SPeter Wemm } 13440266059SGregory Neil Shapiro 13540266059SGregory Neil Shapiro /* values for msg_timeout, see also IS_* below for usage (bit layout) */ 13640266059SGregory Neil Shapiro #define MSG_T_O 0x01 /* normal timeout */ 13740266059SGregory Neil Shapiro #define MSG_T_O_NOW 0x02 /* NOW timeout */ 13840266059SGregory Neil Shapiro #define MSG_NOT_BY 0x04 /* Deliver-By time exceeded, mode R */ 13940266059SGregory Neil Shapiro #define MSG_WARN 0x10 /* normal queue warning */ 14040266059SGregory Neil Shapiro #define MSG_WARN_BY 0x20 /* Deliver-By time exceeded, mode N */ 14140266059SGregory Neil Shapiro 14240266059SGregory Neil Shapiro #define IS_MSG_ERR(x) (((x) & 0x0f) != 0) /* return an error */ 14340266059SGregory Neil Shapiro 14440266059SGregory Neil Shapiro /* immediate return */ 14540266059SGregory Neil Shapiro #define IS_IMM_RET(x) (((x) & (MSG_T_O_NOW|MSG_NOT_BY)) != 0) 14640266059SGregory Neil Shapiro #define IS_MSG_WARN(x) (((x) & 0xf0) != 0) /* return a warning */ 14740266059SGregory Neil Shapiro 14840266059SGregory Neil Shapiro /* 149c2aa98e2SPeter Wemm ** DROPENVELOPE -- deallocate an envelope. 150c2aa98e2SPeter Wemm ** 151c2aa98e2SPeter Wemm ** Parameters: 152c2aa98e2SPeter Wemm ** e -- the envelope to deallocate. 153c2aa98e2SPeter Wemm ** fulldrop -- if set, do return receipts. 15440266059SGregory Neil Shapiro ** split -- if true, split by recipient if message is queued up 155c2aa98e2SPeter Wemm ** 156c2aa98e2SPeter Wemm ** Returns: 157c2aa98e2SPeter Wemm ** none. 158c2aa98e2SPeter Wemm ** 159c2aa98e2SPeter Wemm ** Side Effects: 160c2aa98e2SPeter Wemm ** housekeeping necessary to dispose of an envelope. 161c2aa98e2SPeter Wemm ** Unlocks this queue file. 162c2aa98e2SPeter Wemm */ 163c2aa98e2SPeter Wemm 164c2aa98e2SPeter Wemm void 16540266059SGregory Neil Shapiro dropenvelope(e, fulldrop, split) 166c2aa98e2SPeter Wemm register ENVELOPE *e; 167c2aa98e2SPeter Wemm bool fulldrop; 16840266059SGregory Neil Shapiro bool split; 169c2aa98e2SPeter Wemm { 17040266059SGregory Neil Shapiro bool panic = false; 17140266059SGregory Neil Shapiro bool queueit = false; 17240266059SGregory Neil Shapiro int msg_timeout = 0; 17340266059SGregory Neil Shapiro bool failure_return = false; 17440266059SGregory Neil Shapiro bool delay_return = false; 17540266059SGregory Neil Shapiro bool success_return = false; 17606f25ae9SGregory Neil Shapiro bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags); 17740266059SGregory Neil Shapiro bool done = false; 178c2aa98e2SPeter Wemm register ADDRESS *q; 179c2aa98e2SPeter Wemm char *id = e->e_id; 180193538b7SGregory Neil Shapiro time_t now; 181c2aa98e2SPeter Wemm char buf[MAXLINE]; 182c2aa98e2SPeter Wemm 183c2aa98e2SPeter Wemm if (tTd(50, 1)) 184c2aa98e2SPeter Wemm { 18540266059SGregory Neil Shapiro sm_dprintf("dropenvelope %p: id=", e); 186e92d3f3fSGregory Neil Shapiro xputs(sm_debug_file(), e->e_id); 18740266059SGregory Neil Shapiro sm_dprintf(", flags="); 188c2aa98e2SPeter Wemm printenvflags(e); 189c2aa98e2SPeter Wemm if (tTd(50, 10)) 190c2aa98e2SPeter Wemm { 19140266059SGregory Neil Shapiro sm_dprintf("sendq="); 192e92d3f3fSGregory Neil Shapiro printaddr(sm_debug_file(), e->e_sendqueue, true); 193c2aa98e2SPeter Wemm } 194c2aa98e2SPeter Wemm } 195c2aa98e2SPeter Wemm 196c2aa98e2SPeter Wemm if (LogLevel > 84) 197c2aa98e2SPeter Wemm sm_syslog(LOG_DEBUG, id, 19806f25ae9SGregory Neil Shapiro "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d", 19940266059SGregory Neil Shapiro e->e_flags, OpMode, (int) CurrentPid); 200c2aa98e2SPeter Wemm 201c2aa98e2SPeter Wemm /* we must have an id to remove disk files */ 202c2aa98e2SPeter Wemm if (id == NULL) 203c2aa98e2SPeter Wemm return; 204c2aa98e2SPeter Wemm 205c2aa98e2SPeter Wemm /* if verify-only mode, we can skip most of this */ 206c2aa98e2SPeter Wemm if (OpMode == MD_VERIFY) 207c2aa98e2SPeter Wemm goto simpledrop; 208c2aa98e2SPeter Wemm 209c2aa98e2SPeter Wemm if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 210c2aa98e2SPeter Wemm logsender(e, NULL); 211c2aa98e2SPeter Wemm e->e_flags &= ~EF_LOGSENDER; 212c2aa98e2SPeter Wemm 213c2aa98e2SPeter Wemm /* post statistics */ 214c2aa98e2SPeter Wemm poststats(StatFile); 215c2aa98e2SPeter Wemm 216c2aa98e2SPeter Wemm /* 217c2aa98e2SPeter Wemm ** Extract state information from dregs of send list. 218c2aa98e2SPeter Wemm */ 219c2aa98e2SPeter Wemm 220193538b7SGregory Neil Shapiro now = curtime(); 2218774250cSGregory Neil Shapiro if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 22240266059SGregory Neil Shapiro msg_timeout = MSG_T_O; 22340266059SGregory Neil Shapiro if (IS_DLVR_RETURN(e) && e->e_deliver_by > 0 && 22440266059SGregory Neil Shapiro now >= e->e_ctime + e->e_deliver_by && 22506f25ae9SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags)) 22606f25ae9SGregory Neil Shapiro { 22740266059SGregory Neil Shapiro msg_timeout = MSG_NOT_BY; 22840266059SGregory Neil Shapiro e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 22940266059SGregory Neil Shapiro } 23040266059SGregory Neil Shapiro else if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW && 23140266059SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags)) 23240266059SGregory Neil Shapiro { 23340266059SGregory Neil Shapiro msg_timeout = MSG_T_O_NOW; 23406f25ae9SGregory Neil Shapiro e->e_flags |= EF_FATALERRS|EF_CLRQUEUE; 23506f25ae9SGregory Neil Shapiro } 23606f25ae9SGregory Neil Shapiro 237c2aa98e2SPeter Wemm e->e_flags &= ~EF_QUEUERUN; 238c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 239c2aa98e2SPeter Wemm { 24006f25ae9SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state)) 24140266059SGregory Neil Shapiro queueit = true; 242c2aa98e2SPeter Wemm 243c2aa98e2SPeter Wemm /* see if a notification is needed */ 244c2aa98e2SPeter Wemm if (bitset(QPINGONFAILURE, q->q_flags) && 24540266059SGregory Neil Shapiro ((IS_MSG_ERR(msg_timeout) && 24640266059SGregory Neil Shapiro QS_IS_UNDELIVERED(q->q_state)) || 24706f25ae9SGregory Neil Shapiro QS_IS_BADADDR(q->q_state) || 24840266059SGregory Neil Shapiro IS_IMM_RET(msg_timeout))) 249c2aa98e2SPeter Wemm { 25040266059SGregory Neil Shapiro failure_return = true; 25106f25ae9SGregory Neil Shapiro if (!done && q->q_owner == NULL && 25206f25ae9SGregory Neil Shapiro !emptyaddr(&e->e_from)) 25306f25ae9SGregory Neil Shapiro { 254c2aa98e2SPeter Wemm (void) sendtolist(e->e_from.q_paddr, NULLADDR, 255c2aa98e2SPeter Wemm &e->e_errorqueue, 0, e); 25640266059SGregory Neil Shapiro done = true; 25706f25ae9SGregory Neil Shapiro } 258c2aa98e2SPeter Wemm } 25940266059SGregory Neil Shapiro else if ((bitset(QPINGONSUCCESS, q->q_flags) && 26006f25ae9SGregory Neil Shapiro ((QS_IS_SENT(q->q_state) && 261c2aa98e2SPeter Wemm bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) || 26240266059SGregory Neil Shapiro bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags))) || 26340266059SGregory Neil Shapiro bitset(QBYTRACE, q->q_flags) || 26440266059SGregory Neil Shapiro bitset(QBYNRELAY, q->q_flags)) 265c2aa98e2SPeter Wemm { 26640266059SGregory Neil Shapiro success_return = true; 267c2aa98e2SPeter Wemm } 268c2aa98e2SPeter Wemm } 269c2aa98e2SPeter Wemm 270c2aa98e2SPeter Wemm if (e->e_class < 0) 271c2aa98e2SPeter Wemm e->e_flags |= EF_NO_BODY_RETN; 272c2aa98e2SPeter Wemm 273c2aa98e2SPeter Wemm /* 274c2aa98e2SPeter Wemm ** See if the message timed out. 275c2aa98e2SPeter Wemm */ 276c2aa98e2SPeter Wemm 277c2aa98e2SPeter Wemm if (!queueit) 27806f25ae9SGregory Neil Shapiro /* EMPTY */ 279c2aa98e2SPeter Wemm /* nothing to do */ ; 28040266059SGregory Neil Shapiro else if (IS_MSG_ERR(msg_timeout)) 281c2aa98e2SPeter Wemm { 282c2aa98e2SPeter Wemm if (failure_return) 283c2aa98e2SPeter Wemm { 28440266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 28540266059SGregory Neil Shapiro { 286d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 28740266059SGregory Neil Shapiro "delivery time expired %lds", 28840266059SGregory Neil Shapiro e->e_deliver_by); 28940266059SGregory Neil Shapiro } 29040266059SGregory Neil Shapiro else 29140266059SGregory Neil Shapiro { 292d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 29306f25ae9SGregory Neil Shapiro "Cannot send message for %s", 29440266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 29540266059SGregory Neil Shapiro false)); 29640266059SGregory Neil Shapiro } 29740266059SGregory Neil Shapiro 29840266059SGregory Neil Shapiro /* don't free, allocated from e_rpool */ 29940266059SGregory Neil Shapiro e->e_message = sm_rpool_strdup_x(e->e_rpool, buf); 300c2aa98e2SPeter Wemm message(buf); 301c2aa98e2SPeter Wemm e->e_flags |= EF_CLRQUEUE; 302c2aa98e2SPeter Wemm } 30340266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 30440266059SGregory Neil Shapiro { 30540266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 30640266059SGregory Neil Shapiro "Delivery time (%lds) expired\n", 30740266059SGregory Neil Shapiro e->e_deliver_by); 30840266059SGregory Neil Shapiro } 30940266059SGregory Neil Shapiro else 31040266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 31140266059SGregory Neil Shapiro "Message could not be delivered for %s\n", 31240266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 31340266059SGregory Neil Shapiro false)); 31440266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 31540266059SGregory Neil Shapiro "Message will be deleted from queue\n"); 316c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 317c2aa98e2SPeter Wemm { 31806f25ae9SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state)) 319c2aa98e2SPeter Wemm { 32006f25ae9SGregory Neil Shapiro q->q_state = QS_BADADDR; 32140266059SGregory Neil Shapiro if (msg_timeout == MSG_NOT_BY) 32240266059SGregory Neil Shapiro q->q_status = "5.4.7"; 32340266059SGregory Neil Shapiro else 324c2aa98e2SPeter Wemm q->q_status = "4.4.7"; 325c2aa98e2SPeter Wemm } 326c2aa98e2SPeter Wemm } 327c2aa98e2SPeter Wemm } 32840266059SGregory Neil Shapiro else 32940266059SGregory Neil Shapiro { 33040266059SGregory Neil Shapiro if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 33140266059SGregory Neil Shapiro now >= e->e_ctime + 33240266059SGregory Neil Shapiro TimeOuts.to_q_warning[e->e_timeoutclass]) 33340266059SGregory Neil Shapiro msg_timeout = MSG_WARN; 33440266059SGregory Neil Shapiro else if (IS_DLVR_NOTIFY(e) && 33540266059SGregory Neil Shapiro e->e_deliver_by > 0 && 33640266059SGregory Neil Shapiro now >= e->e_ctime + e->e_deliver_by) 33740266059SGregory Neil Shapiro msg_timeout = MSG_WARN_BY; 33840266059SGregory Neil Shapiro 33940266059SGregory Neil Shapiro if (IS_MSG_WARN(msg_timeout)) 340c2aa98e2SPeter Wemm { 341c2aa98e2SPeter Wemm if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 342c2aa98e2SPeter Wemm e->e_class >= 0 && 343c2aa98e2SPeter Wemm e->e_from.q_paddr != NULL && 344c2aa98e2SPeter Wemm strcmp(e->e_from.q_paddr, "<>") != 0 && 34540266059SGregory Neil Shapiro sm_strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 34640266059SGregory Neil Shapiro (strlen(e->e_from.q_paddr) <= 8 || 34740266059SGregory Neil Shapiro sm_strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], 34840266059SGregory Neil Shapiro "-request") != 0)) 349c2aa98e2SPeter Wemm { 35040266059SGregory Neil Shapiro for (q = e->e_sendqueue; q != NULL; 35140266059SGregory Neil Shapiro q = q->q_next) 352c2aa98e2SPeter Wemm { 35340266059SGregory Neil Shapiro if (QS_IS_UNDELIVERED(q->q_state) 35406f25ae9SGregory Neil Shapiro #if _FFR_NODELAYDSN_ON_HOLD 35540266059SGregory Neil Shapiro && !bitnset(M_HOLD, 35640266059SGregory Neil Shapiro q->q_mailer->m_flags) 35706f25ae9SGregory Neil Shapiro #endif /* _FFR_NODELAYDSN_ON_HOLD */ 35840266059SGregory Neil Shapiro ) 35940266059SGregory Neil Shapiro { 36040266059SGregory Neil Shapiro if (msg_timeout == 36140266059SGregory Neil Shapiro MSG_WARN_BY && 36240266059SGregory Neil Shapiro (bitset(QPINGONDELAY, 36340266059SGregory Neil Shapiro q->q_flags) || 36440266059SGregory Neil Shapiro !bitset(QHASNOTIFY, 36540266059SGregory Neil Shapiro q->q_flags)) 36640266059SGregory Neil Shapiro ) 36740266059SGregory Neil Shapiro { 36840266059SGregory Neil Shapiro q->q_flags |= QBYNDELAY; 36940266059SGregory Neil Shapiro delay_return = true; 37040266059SGregory Neil Shapiro } 37140266059SGregory Neil Shapiro if (bitset(QPINGONDELAY, 37240266059SGregory Neil Shapiro q->q_flags)) 373c2aa98e2SPeter Wemm { 374c2aa98e2SPeter Wemm q->q_flags |= QDELAYED; 37540266059SGregory Neil Shapiro delay_return = true; 37640266059SGregory Neil Shapiro } 377c2aa98e2SPeter Wemm } 378c2aa98e2SPeter Wemm } 379c2aa98e2SPeter Wemm } 380c2aa98e2SPeter Wemm if (delay_return) 381c2aa98e2SPeter Wemm { 38240266059SGregory Neil Shapiro if (msg_timeout == MSG_WARN_BY) 38340266059SGregory Neil Shapiro { 384d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 38540266059SGregory Neil Shapiro "Warning: Delivery time (%lds) exceeded", 38640266059SGregory Neil Shapiro e->e_deliver_by); 38740266059SGregory Neil Shapiro } 38840266059SGregory Neil Shapiro else 389d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), 390c2aa98e2SPeter Wemm "Warning: could not send message for past %s", 39140266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 39240266059SGregory Neil Shapiro false)); 39340266059SGregory Neil Shapiro 39440266059SGregory Neil Shapiro /* don't free, allocated from e_rpool */ 39540266059SGregory Neil Shapiro e->e_message = sm_rpool_strdup_x(e->e_rpool, 39640266059SGregory Neil Shapiro buf); 397c2aa98e2SPeter Wemm message(buf); 398c2aa98e2SPeter Wemm e->e_flags |= EF_WARNING; 399c2aa98e2SPeter Wemm } 40040266059SGregory Neil Shapiro if (msg_timeout == MSG_WARN_BY) 40140266059SGregory Neil Shapiro { 40240266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 40340266059SGregory Neil Shapiro "Warning: Delivery time (%lds) exceeded\n", 40440266059SGregory Neil Shapiro e->e_deliver_by); 40540266059SGregory Neil Shapiro } 40640266059SGregory Neil Shapiro else 40740266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 408c2aa98e2SPeter Wemm "Warning: message still undelivered after %s\n", 40940266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], 41040266059SGregory Neil Shapiro false)); 41140266059SGregory Neil Shapiro (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 41240266059SGregory Neil Shapiro "Will keep trying until message is %s old\n", 41340266059SGregory Neil Shapiro pintvl(TimeOuts.to_q_return[e->e_timeoutclass], 41440266059SGregory Neil Shapiro false)); 41540266059SGregory Neil Shapiro } 416c2aa98e2SPeter Wemm } 417c2aa98e2SPeter Wemm 418c2aa98e2SPeter Wemm if (tTd(50, 2)) 41940266059SGregory Neil Shapiro sm_dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n", 420c2aa98e2SPeter Wemm failure_return, delay_return, success_return, queueit); 421c2aa98e2SPeter Wemm 422c2aa98e2SPeter Wemm /* 423c2aa98e2SPeter Wemm ** If we had some fatal error, but no addresses are marked as 424c2aa98e2SPeter Wemm ** bad, mark them _all_ as bad. 425c2aa98e2SPeter Wemm */ 426c2aa98e2SPeter Wemm 427c2aa98e2SPeter Wemm if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 428c2aa98e2SPeter Wemm { 429c2aa98e2SPeter Wemm for (q = e->e_sendqueue; q != NULL; q = q->q_next) 430c2aa98e2SPeter Wemm { 43106f25ae9SGregory Neil Shapiro if ((QS_IS_OK(q->q_state) || 43206f25ae9SGregory Neil Shapiro QS_IS_VERIFIED(q->q_state)) && 433c2aa98e2SPeter Wemm bitset(QPINGONFAILURE, q->q_flags)) 434c2aa98e2SPeter Wemm { 43540266059SGregory Neil Shapiro failure_return = true; 43606f25ae9SGregory Neil Shapiro q->q_state = QS_BADADDR; 437c2aa98e2SPeter Wemm } 438c2aa98e2SPeter Wemm } 439c2aa98e2SPeter Wemm } 440c2aa98e2SPeter Wemm 441c2aa98e2SPeter Wemm /* 442c2aa98e2SPeter Wemm ** Send back return receipts as requested. 443c2aa98e2SPeter Wemm */ 444c2aa98e2SPeter Wemm 445c2aa98e2SPeter Wemm if (success_return && !failure_return && !delay_return && fulldrop && 446c2aa98e2SPeter Wemm !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 447c2aa98e2SPeter Wemm strcmp(e->e_from.q_paddr, "<>") != 0) 448c2aa98e2SPeter Wemm { 449c2aa98e2SPeter Wemm auto ADDRESS *rlist = NULL; 450c2aa98e2SPeter Wemm 451c2aa98e2SPeter Wemm if (tTd(50, 8)) 45240266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): sending return receipt\n", 45306f25ae9SGregory Neil Shapiro id); 454c2aa98e2SPeter Wemm e->e_flags |= EF_SENDRECEIPT; 455c2aa98e2SPeter Wemm (void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e); 456c2aa98e2SPeter Wemm (void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e); 457c2aa98e2SPeter Wemm } 458c2aa98e2SPeter Wemm e->e_flags &= ~EF_SENDRECEIPT; 459c2aa98e2SPeter Wemm 460c2aa98e2SPeter Wemm /* 461c2aa98e2SPeter Wemm ** Arrange to send error messages if there are fatal errors. 462c2aa98e2SPeter Wemm */ 463c2aa98e2SPeter Wemm 464c2aa98e2SPeter Wemm if ((failure_return || delay_return) && e->e_errormode != EM_QUIET) 465c2aa98e2SPeter Wemm { 466c2aa98e2SPeter Wemm if (tTd(50, 8)) 46740266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): saving mail\n", id); 46840266059SGregory Neil Shapiro panic = savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); 469c2aa98e2SPeter Wemm } 470c2aa98e2SPeter Wemm 471c2aa98e2SPeter Wemm /* 472c2aa98e2SPeter Wemm ** Arrange to send warning messages to postmaster as requested. 473c2aa98e2SPeter Wemm */ 474c2aa98e2SPeter Wemm 47506f25ae9SGregory Neil Shapiro if ((failure_return || pmnotify) && 476c2aa98e2SPeter Wemm PostMasterCopy != NULL && 47706f25ae9SGregory Neil Shapiro !bitset(EF_RESPONSE, e->e_flags) && 47806f25ae9SGregory Neil Shapiro e->e_class >= 0) 479c2aa98e2SPeter Wemm { 480c2aa98e2SPeter Wemm auto ADDRESS *rlist = NULL; 48106f25ae9SGregory Neil Shapiro char pcopy[MAXNAME]; 48206f25ae9SGregory Neil Shapiro 48306f25ae9SGregory Neil Shapiro if (failure_return) 48406f25ae9SGregory Neil Shapiro { 485d0cef73dSGregory Neil Shapiro expand(PostMasterCopy, pcopy, sizeof(pcopy), e); 486c2aa98e2SPeter Wemm 487c2aa98e2SPeter Wemm if (tTd(50, 8)) 48840266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): sending postmaster copy to %s\n", 48906f25ae9SGregory Neil Shapiro id, pcopy); 49006f25ae9SGregory Neil Shapiro (void) sendtolist(pcopy, NULLADDR, &rlist, 0, e); 49106f25ae9SGregory Neil Shapiro } 49206f25ae9SGregory Neil Shapiro if (pmnotify) 49306f25ae9SGregory Neil Shapiro (void) sendtolist("postmaster", NULLADDR, 49406f25ae9SGregory Neil Shapiro &rlist, 0, e); 49506f25ae9SGregory Neil Shapiro (void) returntosender(e->e_message, rlist, 49606f25ae9SGregory Neil Shapiro RTSF_PM_BOUNCE|RTSF_NO_BODY, e); 497c2aa98e2SPeter Wemm } 498c2aa98e2SPeter Wemm 499c2aa98e2SPeter Wemm /* 500c2aa98e2SPeter Wemm ** Instantiate or deinstantiate the queue. 501c2aa98e2SPeter Wemm */ 502c2aa98e2SPeter Wemm 503c2aa98e2SPeter Wemm simpledrop: 504c2aa98e2SPeter Wemm if (tTd(50, 8)) 50540266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): at simpledrop, queueit=%d\n", 506c2aa98e2SPeter Wemm id, queueit); 507c2aa98e2SPeter Wemm if (!queueit || bitset(EF_CLRQUEUE, e->e_flags)) 508c2aa98e2SPeter Wemm { 509c2aa98e2SPeter Wemm if (tTd(50, 1)) 510c2aa98e2SPeter Wemm { 51140266059SGregory Neil Shapiro sm_dprintf("\n===== Dropping queue files for %s... queueit=%d, e_flags=", 512c2aa98e2SPeter Wemm e->e_id, queueit); 513c2aa98e2SPeter Wemm printenvflags(e); 514c2aa98e2SPeter Wemm } 51540266059SGregory Neil Shapiro if (!panic) 516af9557fdSGregory Neil Shapiro { 517af9557fdSGregory Neil Shapiro if (e->e_dfp != NULL) 518af9557fdSGregory Neil Shapiro { 519af9557fdSGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 520af9557fdSGregory Neil Shapiro e->e_dfp = NULL; 521af9557fdSGregory Neil Shapiro } 52240266059SGregory Neil Shapiro (void) xunlink(queuename(e, DATAFL_LETTER)); 523af9557fdSGregory Neil Shapiro } 52440266059SGregory Neil Shapiro if (panic && QueueMode == QM_LOST) 52540266059SGregory Neil Shapiro { 52640266059SGregory Neil Shapiro /* 52740266059SGregory Neil Shapiro ** leave the Qf file behind as 52840266059SGregory Neil Shapiro ** the delivery attempt failed. 52940266059SGregory Neil Shapiro */ 53040266059SGregory Neil Shapiro 53140266059SGregory Neil Shapiro /* EMPTY */ 53240266059SGregory Neil Shapiro } 53340266059SGregory Neil Shapiro else 53440266059SGregory Neil Shapiro if (xunlink(queuename(e, ANYQFL_LETTER)) == 0) 53540266059SGregory Neil Shapiro { 53640266059SGregory Neil Shapiro /* add to available space in filesystem */ 53713d88268SGregory Neil Shapiro updfs(e, -1, panic ? 0 : -1, "dropenvelope"); 53840266059SGregory Neil Shapiro } 539c2aa98e2SPeter Wemm 54006f25ae9SGregory Neil Shapiro if (e->e_ntries > 0 && LogLevel > 9) 54106f25ae9SGregory Neil Shapiro sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d", 54240266059SGregory Neil Shapiro pintvl(curtime() - e->e_ctime, true), 54306f25ae9SGregory Neil Shapiro e->e_ntries); 544c2aa98e2SPeter Wemm } 545c2aa98e2SPeter Wemm else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 546c2aa98e2SPeter Wemm { 54740266059SGregory Neil Shapiro if (!split) 54840266059SGregory Neil Shapiro queueup(e, false, true); 54940266059SGregory Neil Shapiro else 55040266059SGregory Neil Shapiro { 55140266059SGregory Neil Shapiro ENVELOPE *oldsib; 55240266059SGregory Neil Shapiro ENVELOPE *ee; 55340266059SGregory Neil Shapiro 55440266059SGregory Neil Shapiro /* 55540266059SGregory Neil Shapiro ** Save old sibling and set it to NULL to avoid 55640266059SGregory Neil Shapiro ** queueing up the same envelopes again. 55740266059SGregory Neil Shapiro ** This requires that envelopes in that list have 55840266059SGregory Neil Shapiro ** been take care of before (or at some other place). 55940266059SGregory Neil Shapiro */ 56040266059SGregory Neil Shapiro 56140266059SGregory Neil Shapiro oldsib = e->e_sibling; 56240266059SGregory Neil Shapiro e->e_sibling = NULL; 56340266059SGregory Neil Shapiro if (!split_by_recipient(e) && 56440266059SGregory Neil Shapiro bitset(EF_FATALERRS, e->e_flags)) 56540266059SGregory Neil Shapiro { 56640266059SGregory Neil Shapiro syserr("!dropenvelope(%s): cannot commit data file %s, uid=%d", 56740266059SGregory Neil Shapiro e->e_id, queuename(e, DATAFL_LETTER), 56894c01205SGregory Neil Shapiro (int) geteuid()); 56940266059SGregory Neil Shapiro } 57040266059SGregory Neil Shapiro for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 57140266059SGregory Neil Shapiro queueup(ee, false, true); 57240266059SGregory Neil Shapiro queueup(e, false, true); 57340266059SGregory Neil Shapiro 57440266059SGregory Neil Shapiro /* clean up */ 57540266059SGregory Neil Shapiro for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) 57640266059SGregory Neil Shapiro { 57740266059SGregory Neil Shapiro /* now unlock the job */ 57840266059SGregory Neil Shapiro if (tTd(50, 8)) 57940266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): unlocking job\n", 58040266059SGregory Neil Shapiro ee->e_id); 58140266059SGregory Neil Shapiro closexscript(ee); 58240266059SGregory Neil Shapiro unlockqueue(ee); 58340266059SGregory Neil Shapiro 58440266059SGregory Neil Shapiro /* this envelope is marked unused */ 58540266059SGregory Neil Shapiro if (ee->e_dfp != NULL) 58640266059SGregory Neil Shapiro { 58740266059SGregory Neil Shapiro (void) sm_io_close(ee->e_dfp, 58840266059SGregory Neil Shapiro SM_TIME_DEFAULT); 58940266059SGregory Neil Shapiro ee->e_dfp = NULL; 59040266059SGregory Neil Shapiro } 59140266059SGregory Neil Shapiro ee->e_id = NULL; 59240266059SGregory Neil Shapiro ee->e_flags &= ~EF_HAS_DF; 59340266059SGregory Neil Shapiro } 59440266059SGregory Neil Shapiro e->e_sibling = oldsib; 59540266059SGregory Neil Shapiro } 596c2aa98e2SPeter Wemm } 597c2aa98e2SPeter Wemm 598c2aa98e2SPeter Wemm /* now unlock the job */ 599c2aa98e2SPeter Wemm if (tTd(50, 8)) 60040266059SGregory Neil Shapiro sm_dprintf("dropenvelope(%s): unlocking job\n", id); 601c2aa98e2SPeter Wemm closexscript(e); 602c2aa98e2SPeter Wemm unlockqueue(e); 603c2aa98e2SPeter Wemm 604c2aa98e2SPeter Wemm /* make sure that this envelope is marked unused */ 605c2aa98e2SPeter Wemm if (e->e_dfp != NULL) 60640266059SGregory Neil Shapiro { 60740266059SGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 608c2aa98e2SPeter Wemm e->e_dfp = NULL; 60940266059SGregory Neil Shapiro } 610c2aa98e2SPeter Wemm e->e_id = NULL; 611c2aa98e2SPeter Wemm e->e_flags &= ~EF_HAS_DF; 612c2aa98e2SPeter Wemm } 61340266059SGregory Neil Shapiro /* 614c2aa98e2SPeter Wemm ** CLEARENVELOPE -- clear an envelope without unlocking 615c2aa98e2SPeter Wemm ** 616c2aa98e2SPeter Wemm ** This is normally used by a child process to get a clean 617c2aa98e2SPeter Wemm ** envelope without disturbing the parent. 618c2aa98e2SPeter Wemm ** 619c2aa98e2SPeter Wemm ** Parameters: 620c2aa98e2SPeter Wemm ** e -- the envelope to clear. 621c2aa98e2SPeter Wemm ** fullclear - if set, the current envelope is total 622c2aa98e2SPeter Wemm ** garbage and should be ignored; otherwise, 623c2aa98e2SPeter Wemm ** release any resources it may indicate. 62440266059SGregory Neil Shapiro ** rpool -- either NULL, or a pointer to a resource pool 62540266059SGregory Neil Shapiro ** from which envelope memory is allocated, and 62640266059SGregory Neil Shapiro ** to which envelope resources are attached. 627c2aa98e2SPeter Wemm ** 628c2aa98e2SPeter Wemm ** Returns: 629c2aa98e2SPeter Wemm ** none. 630c2aa98e2SPeter Wemm ** 631c2aa98e2SPeter Wemm ** Side Effects: 632c2aa98e2SPeter Wemm ** Closes files associated with the envelope. 633c2aa98e2SPeter Wemm ** Marks the envelope as unallocated. 634c2aa98e2SPeter Wemm */ 635c2aa98e2SPeter Wemm 636c2aa98e2SPeter Wemm void 63740266059SGregory Neil Shapiro clearenvelope(e, fullclear, rpool) 638c2aa98e2SPeter Wemm register ENVELOPE *e; 639c2aa98e2SPeter Wemm bool fullclear; 64040266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 641c2aa98e2SPeter Wemm { 642c2aa98e2SPeter Wemm register HDR *bh; 643c2aa98e2SPeter Wemm register HDR **nhp; 644c2aa98e2SPeter Wemm extern ENVELOPE BlankEnvelope; 64540266059SGregory Neil Shapiro char **p; 646c2aa98e2SPeter Wemm 647c2aa98e2SPeter Wemm if (!fullclear) 648c2aa98e2SPeter Wemm { 649c2aa98e2SPeter Wemm /* clear out any file information */ 650c2aa98e2SPeter Wemm if (e->e_xfp != NULL) 65140266059SGregory Neil Shapiro (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); 652c2aa98e2SPeter Wemm if (e->e_dfp != NULL) 65340266059SGregory Neil Shapiro (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 654c2aa98e2SPeter Wemm e->e_xfp = e->e_dfp = NULL; 655c2aa98e2SPeter Wemm } 656c2aa98e2SPeter Wemm 65740266059SGregory Neil Shapiro /* 65840266059SGregory Neil Shapiro ** Copy BlankEnvelope into *e. 65940266059SGregory Neil Shapiro ** It is not safe to simply copy pointers to strings; 66040266059SGregory Neil Shapiro ** the strings themselves must be copied (or set to NULL). 66140266059SGregory Neil Shapiro ** The problem is that when we assign a new string value to 66240266059SGregory Neil Shapiro ** a member of BlankEnvelope, we free the old string. 66340266059SGregory Neil Shapiro ** We did not need to do this copying in sendmail 8.11 :-( 66440266059SGregory Neil Shapiro ** and it is a potential performance hit. Reference counted 66540266059SGregory Neil Shapiro ** strings are one way out. 66640266059SGregory Neil Shapiro */ 66740266059SGregory Neil Shapiro 66840266059SGregory Neil Shapiro *e = BlankEnvelope; 669c2aa98e2SPeter Wemm e->e_message = NULL; 67040266059SGregory Neil Shapiro e->e_qfletter = '\0'; 67140266059SGregory Neil Shapiro e->e_quarmsg = NULL; 67240266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); 67340266059SGregory Neil Shapiro 67440266059SGregory Neil Shapiro /* 67540266059SGregory Neil Shapiro ** Copy the macro table. 67640266059SGregory Neil Shapiro ** We might be able to avoid this by zeroing the macro table 67740266059SGregory Neil Shapiro ** and always searching BlankEnvelope.e_macro after e->e_macro 67840266059SGregory Neil Shapiro ** in macvalue(). 67940266059SGregory Neil Shapiro */ 68040266059SGregory Neil Shapiro 68140266059SGregory Neil Shapiro for (p = &e->e_macro.mac_table[0]; 68240266059SGregory Neil Shapiro p <= &e->e_macro.mac_table[MAXMACROID]; 68340266059SGregory Neil Shapiro ++p) 68440266059SGregory Neil Shapiro { 68540266059SGregory Neil Shapiro if (*p != NULL) 68640266059SGregory Neil Shapiro *p = sm_rpool_strdup_x(rpool, *p); 68740266059SGregory Neil Shapiro } 68840266059SGregory Neil Shapiro 68940266059SGregory Neil Shapiro /* 69040266059SGregory Neil Shapiro ** XXX There are many strings in the envelope structure 69140266059SGregory Neil Shapiro ** XXX that we are not attempting to copy here. 69240266059SGregory Neil Shapiro ** XXX Investigate this further. 69340266059SGregory Neil Shapiro */ 69440266059SGregory Neil Shapiro 69540266059SGregory Neil Shapiro e->e_rpool = rpool; 69640266059SGregory Neil Shapiro e->e_macro.mac_rpool = rpool; 697c2aa98e2SPeter Wemm if (Verbose) 69806f25ae9SGregory Neil Shapiro set_delivery_mode(SM_DELIVER, e); 699c2aa98e2SPeter Wemm bh = BlankEnvelope.e_header; 700c2aa98e2SPeter Wemm nhp = &e->e_header; 701c2aa98e2SPeter Wemm while (bh != NULL) 702c2aa98e2SPeter Wemm { 703d0cef73dSGregory Neil Shapiro *nhp = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*bh)); 704d0cef73dSGregory Neil Shapiro memmove((char *) *nhp, (char *) bh, sizeof(*bh)); 705c2aa98e2SPeter Wemm bh = bh->h_link; 706c2aa98e2SPeter Wemm nhp = &(*nhp)->h_link; 707c2aa98e2SPeter Wemm } 708c2aa98e2SPeter Wemm } 70940266059SGregory Neil Shapiro /* 710c2aa98e2SPeter Wemm ** INITSYS -- initialize instantiation of system 711c2aa98e2SPeter Wemm ** 712c2aa98e2SPeter Wemm ** In Daemon mode, this is done in the child. 713c2aa98e2SPeter Wemm ** 714c2aa98e2SPeter Wemm ** Parameters: 71506f25ae9SGregory Neil Shapiro ** e -- the envelope to use. 716c2aa98e2SPeter Wemm ** 717c2aa98e2SPeter Wemm ** Returns: 718c2aa98e2SPeter Wemm ** none. 719c2aa98e2SPeter Wemm ** 720c2aa98e2SPeter Wemm ** Side Effects: 721c2aa98e2SPeter Wemm ** Initializes the system macros, some global variables, 722c2aa98e2SPeter Wemm ** etc. In particular, the current time in various 723c2aa98e2SPeter Wemm ** forms is set. 724c2aa98e2SPeter Wemm */ 725c2aa98e2SPeter Wemm 726c2aa98e2SPeter Wemm void 727c2aa98e2SPeter Wemm initsys(e) 728c2aa98e2SPeter Wemm register ENVELOPE *e; 729c2aa98e2SPeter Wemm { 73040266059SGregory Neil Shapiro char buf[10]; 731c2aa98e2SPeter Wemm #ifdef TTYNAME 732c2aa98e2SPeter Wemm static char ybuf[60]; /* holds tty id */ 733c2aa98e2SPeter Wemm register char *p; 734c2aa98e2SPeter Wemm extern char *ttyname(); 735c2aa98e2SPeter Wemm #endif /* TTYNAME */ 736c2aa98e2SPeter Wemm 737c2aa98e2SPeter Wemm /* 738c2aa98e2SPeter Wemm ** Give this envelope a reality. 739c2aa98e2SPeter Wemm ** I.e., an id, a transcript, and a creation time. 74040266059SGregory Neil Shapiro ** We don't select the queue until all of the recipients are known. 741c2aa98e2SPeter Wemm */ 742c2aa98e2SPeter Wemm 743c2aa98e2SPeter Wemm openxscript(e); 744c2aa98e2SPeter Wemm e->e_ctime = curtime(); 74540266059SGregory Neil Shapiro e->e_qfletter = '\0'; 746c2aa98e2SPeter Wemm 747c2aa98e2SPeter Wemm /* 748c2aa98e2SPeter Wemm ** Set OutChannel to something useful if stdout isn't it. 749c2aa98e2SPeter Wemm ** This arranges that any extra stuff the mailer produces 750c2aa98e2SPeter Wemm ** gets sent back to the user on error (because it is 751c2aa98e2SPeter Wemm ** tucked away in the transcript). 752c2aa98e2SPeter Wemm */ 753c2aa98e2SPeter Wemm 754c2aa98e2SPeter Wemm if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 755c2aa98e2SPeter Wemm e->e_xfp != NULL) 756c2aa98e2SPeter Wemm OutChannel = e->e_xfp; 757c2aa98e2SPeter Wemm 758c2aa98e2SPeter Wemm /* 759c2aa98e2SPeter Wemm ** Set up some basic system macros. 760c2aa98e2SPeter Wemm */ 761c2aa98e2SPeter Wemm 762c2aa98e2SPeter Wemm /* process id */ 763d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d", (int) CurrentPid); 76440266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'p', buf); 765c2aa98e2SPeter Wemm 766c2aa98e2SPeter Wemm /* hop count */ 767d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount); 76840266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'c', buf); 769c2aa98e2SPeter Wemm 770c2aa98e2SPeter Wemm /* time as integer, unix time, arpa time */ 771c2aa98e2SPeter Wemm settime(e); 772c2aa98e2SPeter Wemm 77306f25ae9SGregory Neil Shapiro /* Load average */ 77440266059SGregory Neil Shapiro sm_getla(); 77506f25ae9SGregory Neil Shapiro 776c2aa98e2SPeter Wemm #ifdef TTYNAME 777c2aa98e2SPeter Wemm /* tty name */ 778c2aa98e2SPeter Wemm if (macvalue('y', e) == NULL) 779c2aa98e2SPeter Wemm { 780c2aa98e2SPeter Wemm p = ttyname(2); 781c2aa98e2SPeter Wemm if (p != NULL) 782c2aa98e2SPeter Wemm { 783c2aa98e2SPeter Wemm if (strrchr(p, '/') != NULL) 784c2aa98e2SPeter Wemm p = strrchr(p, '/') + 1; 785d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(ybuf, sizeof(ybuf), p); 78640266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'y', ybuf); 787c2aa98e2SPeter Wemm } 788c2aa98e2SPeter Wemm } 789c2aa98e2SPeter Wemm #endif /* TTYNAME */ 790c2aa98e2SPeter Wemm } 79140266059SGregory Neil Shapiro /* 792c2aa98e2SPeter Wemm ** SETTIME -- set the current time. 793c2aa98e2SPeter Wemm ** 794c2aa98e2SPeter Wemm ** Parameters: 79506f25ae9SGregory Neil Shapiro ** e -- the envelope in which the macros should be set. 796c2aa98e2SPeter Wemm ** 797c2aa98e2SPeter Wemm ** Returns: 798c2aa98e2SPeter Wemm ** none. 799c2aa98e2SPeter Wemm ** 800c2aa98e2SPeter Wemm ** Side Effects: 801c2aa98e2SPeter Wemm ** Sets the various time macros -- $a, $b, $d, $t. 802c2aa98e2SPeter Wemm */ 803c2aa98e2SPeter Wemm 804c2aa98e2SPeter Wemm void 805c2aa98e2SPeter Wemm settime(e) 806c2aa98e2SPeter Wemm register ENVELOPE *e; 807c2aa98e2SPeter Wemm { 808c2aa98e2SPeter Wemm register char *p; 809c2aa98e2SPeter Wemm auto time_t now; 81040266059SGregory Neil Shapiro char buf[30]; 811c2aa98e2SPeter Wemm register struct tm *tm; 812c2aa98e2SPeter Wemm 813c2aa98e2SPeter Wemm now = curtime(); 814d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%ld", (long) now); 815e92d3f3fSGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, macid("{time}"), buf); 816c2aa98e2SPeter Wemm tm = gmtime(&now); 817d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d", 81840266059SGregory Neil Shapiro tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 81940266059SGregory Neil Shapiro tm->tm_hour, tm->tm_min); 82040266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 't', buf); 821d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(buf, ctime(&now), sizeof(buf)); 82240266059SGregory Neil Shapiro p = strchr(buf, '\n'); 823c2aa98e2SPeter Wemm if (p != NULL) 824c2aa98e2SPeter Wemm *p = '\0'; 82540266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'd', buf); 82640266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'b', arpadate(buf)); 827c2aa98e2SPeter Wemm if (macvalue('a', e) == NULL) 82840266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'a', macvalue('b', e)); 829c2aa98e2SPeter Wemm } 83040266059SGregory Neil Shapiro /* 831c2aa98e2SPeter Wemm ** OPENXSCRIPT -- Open transcript file 832c2aa98e2SPeter Wemm ** 833c2aa98e2SPeter Wemm ** Creates a transcript file for possible eventual mailing or 834c2aa98e2SPeter Wemm ** sending back. 835c2aa98e2SPeter Wemm ** 836c2aa98e2SPeter Wemm ** Parameters: 837c2aa98e2SPeter Wemm ** e -- the envelope to create the transcript in/for. 838c2aa98e2SPeter Wemm ** 839c2aa98e2SPeter Wemm ** Returns: 840c2aa98e2SPeter Wemm ** none 841c2aa98e2SPeter Wemm ** 842c2aa98e2SPeter Wemm ** Side Effects: 843c2aa98e2SPeter Wemm ** Creates the transcript file. 844c2aa98e2SPeter Wemm */ 845c2aa98e2SPeter Wemm 846c2aa98e2SPeter Wemm #ifndef O_APPEND 847c2aa98e2SPeter Wemm # define O_APPEND 0 84806f25ae9SGregory Neil Shapiro #endif /* ! O_APPEND */ 849c2aa98e2SPeter Wemm 850c2aa98e2SPeter Wemm void 851c2aa98e2SPeter Wemm openxscript(e) 852c2aa98e2SPeter Wemm register ENVELOPE *e; 853c2aa98e2SPeter Wemm { 854c2aa98e2SPeter Wemm register char *p; 855c2aa98e2SPeter Wemm 856c2aa98e2SPeter Wemm if (e->e_xfp != NULL) 857c2aa98e2SPeter Wemm return; 85806f25ae9SGregory Neil Shapiro 85906f25ae9SGregory Neil Shapiro #if 0 86006f25ae9SGregory Neil Shapiro if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags)) 86106f25ae9SGregory Neil Shapiro syserr("openxscript: job not locked"); 86206f25ae9SGregory Neil Shapiro #endif /* 0 */ 86306f25ae9SGregory Neil Shapiro 86440266059SGregory Neil Shapiro p = queuename(e, XSCRPT_LETTER); 86506f25ae9SGregory Neil Shapiro e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize, 86606f25ae9SGregory Neil Shapiro SFF_NOTEXCL|SFF_OPENASROOT); 86706f25ae9SGregory Neil Shapiro 86806f25ae9SGregory Neil Shapiro if (e->e_xfp == NULL) 869c2aa98e2SPeter Wemm { 870c2aa98e2SPeter Wemm syserr("Can't create transcript file %s", p); 87140266059SGregory Neil Shapiro e->e_xfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, 87240266059SGregory Neil Shapiro SM_PATH_DEVNULL, SM_IO_RDWR, NULL); 87306f25ae9SGregory Neil Shapiro if (e->e_xfp == NULL) 87440266059SGregory Neil Shapiro syserr("!Can't open %s", SM_PATH_DEVNULL); 875c2aa98e2SPeter Wemm } 87640266059SGregory Neil Shapiro (void) sm_io_setvbuf(e->e_xfp, SM_TIME_DEFAULT, NULL, SM_IO_LBF, 0); 877c2aa98e2SPeter Wemm if (tTd(46, 9)) 878c2aa98e2SPeter Wemm { 87940266059SGregory Neil Shapiro sm_dprintf("openxscript(%s):\n ", p); 88040266059SGregory Neil Shapiro dumpfd(sm_io_getinfo(e->e_xfp, SM_IO_WHAT_FD, NULL), true, 88140266059SGregory Neil Shapiro false); 882c2aa98e2SPeter Wemm } 883c2aa98e2SPeter Wemm } 88440266059SGregory Neil Shapiro /* 885c2aa98e2SPeter Wemm ** CLOSEXSCRIPT -- close the transcript file. 886c2aa98e2SPeter Wemm ** 887c2aa98e2SPeter Wemm ** Parameters: 888c2aa98e2SPeter Wemm ** e -- the envelope containing the transcript to close. 889c2aa98e2SPeter Wemm ** 890c2aa98e2SPeter Wemm ** Returns: 891c2aa98e2SPeter Wemm ** none. 892c2aa98e2SPeter Wemm ** 893c2aa98e2SPeter Wemm ** Side Effects: 894c2aa98e2SPeter Wemm ** none. 895c2aa98e2SPeter Wemm */ 896c2aa98e2SPeter Wemm 897c2aa98e2SPeter Wemm void 898c2aa98e2SPeter Wemm closexscript(e) 899c2aa98e2SPeter Wemm register ENVELOPE *e; 900c2aa98e2SPeter Wemm { 901c2aa98e2SPeter Wemm if (e->e_xfp == NULL) 902c2aa98e2SPeter Wemm return; 90306f25ae9SGregory Neil Shapiro #if 0 90406f25ae9SGregory Neil Shapiro if (e->e_lockfp == NULL) 90506f25ae9SGregory Neil Shapiro syserr("closexscript: job not locked"); 90606f25ae9SGregory Neil Shapiro #endif /* 0 */ 90740266059SGregory Neil Shapiro (void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT); 908c2aa98e2SPeter Wemm e->e_xfp = NULL; 909c2aa98e2SPeter Wemm } 91040266059SGregory Neil Shapiro /* 911c2aa98e2SPeter Wemm ** SETSENDER -- set the person who this message is from 912c2aa98e2SPeter Wemm ** 913c2aa98e2SPeter Wemm ** Under certain circumstances allow the user to say who 914c2aa98e2SPeter Wemm ** s/he is (using -f or -r). These are: 915c2aa98e2SPeter Wemm ** 1. The user's uid is zero (root). 916c2aa98e2SPeter Wemm ** 2. The user's login name is in an approved list (typically 917c2aa98e2SPeter Wemm ** from a network server). 918c2aa98e2SPeter Wemm ** 3. The address the user is trying to claim has a 919c2aa98e2SPeter Wemm ** "!" character in it (since #2 doesn't do it for 920c2aa98e2SPeter Wemm ** us if we are dialing out for UUCP). 921c2aa98e2SPeter Wemm ** A better check to replace #3 would be if the 922c2aa98e2SPeter Wemm ** effective uid is "UUCP" -- this would require me 923c2aa98e2SPeter Wemm ** to rewrite getpwent to "grab" uucp as it went by, 924c2aa98e2SPeter Wemm ** make getname more nasty, do another passwd file 925c2aa98e2SPeter Wemm ** scan, or compile the UID of "UUCP" into the code, 926c2aa98e2SPeter Wemm ** all of which are reprehensible. 927c2aa98e2SPeter Wemm ** 928c2aa98e2SPeter Wemm ** Assuming all of these fail, we figure out something 929c2aa98e2SPeter Wemm ** ourselves. 930c2aa98e2SPeter Wemm ** 931c2aa98e2SPeter Wemm ** Parameters: 932c2aa98e2SPeter Wemm ** from -- the person we would like to believe this message 933c2aa98e2SPeter Wemm ** is from, as specified on the command line. 934c2aa98e2SPeter Wemm ** e -- the envelope in which we would like the sender set. 935c2aa98e2SPeter Wemm ** delimptr -- if non-NULL, set to the location of the 936c2aa98e2SPeter Wemm ** trailing delimiter. 937c2aa98e2SPeter Wemm ** delimchar -- the character that will delimit the sender 938c2aa98e2SPeter Wemm ** address. 939c2aa98e2SPeter Wemm ** internal -- set if this address is coming from an internal 940c2aa98e2SPeter Wemm ** source such as an owner alias. 941c2aa98e2SPeter Wemm ** 942c2aa98e2SPeter Wemm ** Returns: 943c2aa98e2SPeter Wemm ** none. 944c2aa98e2SPeter Wemm ** 945c2aa98e2SPeter Wemm ** Side Effects: 946c2aa98e2SPeter Wemm ** sets sendmail's notion of who the from person is. 947c2aa98e2SPeter Wemm */ 948c2aa98e2SPeter Wemm 949c2aa98e2SPeter Wemm void 950c2aa98e2SPeter Wemm setsender(from, e, delimptr, delimchar, internal) 951c2aa98e2SPeter Wemm char *from; 952c2aa98e2SPeter Wemm register ENVELOPE *e; 953c2aa98e2SPeter Wemm char **delimptr; 954c2aa98e2SPeter Wemm int delimchar; 955c2aa98e2SPeter Wemm bool internal; 956c2aa98e2SPeter Wemm { 957c2aa98e2SPeter Wemm register char **pvp; 958c2aa98e2SPeter Wemm char *realname = NULL; 959c2aa98e2SPeter Wemm char *bp; 960c2aa98e2SPeter Wemm char buf[MAXNAME + 2]; 961c2aa98e2SPeter Wemm char pvpbuf[PSBUFSIZE]; 962c2aa98e2SPeter Wemm extern char *FullName; 963c2aa98e2SPeter Wemm 964c2aa98e2SPeter Wemm if (tTd(45, 1)) 96540266059SGregory Neil Shapiro sm_dprintf("setsender(%s)\n", from == NULL ? "" : from); 966c2aa98e2SPeter Wemm 96713bd1963SGregory Neil Shapiro /* may be set from earlier calls */ 96813bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'x', ""); 96913bd1963SGregory Neil Shapiro 970c2aa98e2SPeter Wemm /* 971c2aa98e2SPeter Wemm ** Figure out the real user executing us. 972c2aa98e2SPeter Wemm ** Username can return errno != 0 on non-errors. 973c2aa98e2SPeter Wemm */ 974c2aa98e2SPeter Wemm 975c2aa98e2SPeter Wemm if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 976c2aa98e2SPeter Wemm OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 977c2aa98e2SPeter Wemm realname = from; 978c2aa98e2SPeter Wemm if (realname == NULL || realname[0] == '\0') 979c2aa98e2SPeter Wemm realname = username(); 980c2aa98e2SPeter Wemm 981c2aa98e2SPeter Wemm if (ConfigLevel < 2) 98240266059SGregory Neil Shapiro SuprErrs = true; 983c2aa98e2SPeter Wemm 98440266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 98540266059SGregory Neil Shapiro 98606f25ae9SGregory Neil Shapiro /* preset state for then clause in case from == NULL */ 98706f25ae9SGregory Neil Shapiro e->e_from.q_state = QS_BADADDR; 98806f25ae9SGregory Neil Shapiro e->e_from.q_flags = 0; 989c2aa98e2SPeter Wemm if (from == NULL || 990c2aa98e2SPeter Wemm parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 99140266059SGregory Neil Shapiro delimchar, delimptr, e, false) == NULL || 99206f25ae9SGregory Neil Shapiro QS_IS_BADADDR(e->e_from.q_state) || 993c2aa98e2SPeter Wemm e->e_from.q_mailer == ProgMailer || 994c2aa98e2SPeter Wemm e->e_from.q_mailer == FileMailer || 995c2aa98e2SPeter Wemm e->e_from.q_mailer == InclMailer) 996c2aa98e2SPeter Wemm { 997c2aa98e2SPeter Wemm /* log garbage addresses for traceback */ 998c2aa98e2SPeter Wemm if (from != NULL && LogLevel > 2) 999c2aa98e2SPeter Wemm { 1000c2aa98e2SPeter Wemm char *p; 1001c2aa98e2SPeter Wemm char ebuf[MAXNAME * 2 + 2]; 1002c2aa98e2SPeter Wemm 1003c2aa98e2SPeter Wemm p = macvalue('_', e); 1004c2aa98e2SPeter Wemm if (p == NULL) 1005c2aa98e2SPeter Wemm { 1006c2aa98e2SPeter Wemm char *host = RealHostName; 1007c2aa98e2SPeter Wemm 1008c2aa98e2SPeter Wemm if (host == NULL) 1009c2aa98e2SPeter Wemm host = MyHostName; 1010d0cef73dSGregory Neil Shapiro (void) sm_snprintf(ebuf, sizeof(ebuf), 101140266059SGregory Neil Shapiro "%.*s@%.*s", MAXNAME, 101240266059SGregory Neil Shapiro realname, MAXNAME, host); 1013c2aa98e2SPeter Wemm p = ebuf; 1014c2aa98e2SPeter Wemm } 1015c2aa98e2SPeter Wemm sm_syslog(LOG_NOTICE, e->e_id, 101606f25ae9SGregory Neil Shapiro "setsender: %s: invalid or unparsable, received from %s", 1017c2aa98e2SPeter Wemm shortenstring(from, 83), p); 1018c2aa98e2SPeter Wemm } 1019c2aa98e2SPeter Wemm if (from != NULL) 1020c2aa98e2SPeter Wemm { 102106f25ae9SGregory Neil Shapiro if (!QS_IS_BADADDR(e->e_from.q_state)) 1022c2aa98e2SPeter Wemm { 1023c2aa98e2SPeter Wemm /* it was a bogus mailer in the from addr */ 1024c2aa98e2SPeter Wemm e->e_status = "5.1.7"; 102506f25ae9SGregory Neil Shapiro usrerrenh(e->e_status, 102606f25ae9SGregory Neil Shapiro "553 Invalid sender address"); 1027c2aa98e2SPeter Wemm } 102840266059SGregory Neil Shapiro SuprErrs = true; 1029c2aa98e2SPeter Wemm } 1030c2aa98e2SPeter Wemm if (from == realname || 103140266059SGregory Neil Shapiro parseaddr(from = realname, 103240266059SGregory Neil Shapiro &e->e_from, RF_COPYALL|RF_SENDERADDR, ' ', 103340266059SGregory Neil Shapiro NULL, e, false) == NULL) 1034c2aa98e2SPeter Wemm { 1035c2aa98e2SPeter Wemm char nbuf[100]; 1036c2aa98e2SPeter Wemm 103740266059SGregory Neil Shapiro SuprErrs = true; 1038d0cef73dSGregory Neil Shapiro expand("\201n", nbuf, sizeof(nbuf), e); 103940266059SGregory Neil Shapiro from = sm_rpool_strdup_x(e->e_rpool, nbuf); 104040266059SGregory Neil Shapiro if (parseaddr(from, &e->e_from, RF_COPYALL, ' ', 104140266059SGregory Neil Shapiro NULL, e, false) == NULL && 1042c2aa98e2SPeter Wemm parseaddr(from = "postmaster", &e->e_from, 104340266059SGregory Neil Shapiro RF_COPYALL, ' ', NULL, e, false) == NULL) 104406f25ae9SGregory Neil Shapiro syserr("553 5.3.0 setsender: can't even parse postmaster!"); 1045c2aa98e2SPeter Wemm } 1046c2aa98e2SPeter Wemm } 1047c2aa98e2SPeter Wemm else 104840266059SGregory Neil Shapiro FromFlag = true; 104906f25ae9SGregory Neil Shapiro e->e_from.q_state = QS_SENDER; 1050c2aa98e2SPeter Wemm if (tTd(45, 5)) 1051c2aa98e2SPeter Wemm { 105240266059SGregory Neil Shapiro sm_dprintf("setsender: QS_SENDER "); 1053e92d3f3fSGregory Neil Shapiro printaddr(sm_debug_file(), &e->e_from, false); 1054c2aa98e2SPeter Wemm } 105540266059SGregory Neil Shapiro SuprErrs = false; 1056c2aa98e2SPeter Wemm 1057c2aa98e2SPeter Wemm #if USERDB 1058c2aa98e2SPeter Wemm if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 1059c2aa98e2SPeter Wemm { 1060c2aa98e2SPeter Wemm register char *p; 1061c2aa98e2SPeter Wemm 106240266059SGregory Neil Shapiro p = udbsender(e->e_from.q_user, e->e_rpool); 1063c2aa98e2SPeter Wemm if (p != NULL) 1064c2aa98e2SPeter Wemm from = p; 1065c2aa98e2SPeter Wemm } 1066c2aa98e2SPeter Wemm #endif /* USERDB */ 1067c2aa98e2SPeter Wemm 1068c2aa98e2SPeter Wemm if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 1069c2aa98e2SPeter Wemm { 107040266059SGregory Neil Shapiro SM_MBDB_T user; 107140266059SGregory Neil Shapiro 1072c2aa98e2SPeter Wemm if (!internal) 1073c2aa98e2SPeter Wemm { 1074c2aa98e2SPeter Wemm /* if the user already given fullname don't redefine */ 1075c2aa98e2SPeter Wemm if (FullName == NULL) 1076c2aa98e2SPeter Wemm FullName = macvalue('x', e); 1077605302a5SGregory Neil Shapiro if (FullName != NULL) 1078605302a5SGregory Neil Shapiro { 1079605302a5SGregory Neil Shapiro if (FullName[0] == '\0') 1080c2aa98e2SPeter Wemm FullName = NULL; 1081605302a5SGregory Neil Shapiro else 1082605302a5SGregory Neil Shapiro FullName = newstr(FullName); 1083605302a5SGregory Neil Shapiro } 1084c2aa98e2SPeter Wemm } 1085c2aa98e2SPeter Wemm 1086c2aa98e2SPeter Wemm if (e->e_from.q_user[0] != '\0' && 108740266059SGregory Neil Shapiro sm_mbdb_lookup(e->e_from.q_user, &user) == EX_OK) 1088c2aa98e2SPeter Wemm { 1089c2aa98e2SPeter Wemm /* 1090c2aa98e2SPeter Wemm ** Process passwd file entry. 1091c2aa98e2SPeter Wemm */ 1092c2aa98e2SPeter Wemm 1093c2aa98e2SPeter Wemm /* extract home directory */ 109440266059SGregory Neil Shapiro if (*user.mbdb_homedir == '\0') 109542e5d165SGregory Neil Shapiro e->e_from.q_home = NULL; 109640266059SGregory Neil Shapiro else if (strcmp(user.mbdb_homedir, "/") == 0) 109740266059SGregory Neil Shapiro e->e_from.q_home = ""; 1098c2aa98e2SPeter Wemm else 109940266059SGregory Neil Shapiro e->e_from.q_home = sm_rpool_strdup_x(e->e_rpool, 110040266059SGregory Neil Shapiro user.mbdb_homedir); 110140266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'z', e->e_from.q_home); 1102c2aa98e2SPeter Wemm 1103c2aa98e2SPeter Wemm /* extract user and group id */ 110440266059SGregory Neil Shapiro if (user.mbdb_uid != SM_NO_UID) 110540266059SGregory Neil Shapiro { 110640266059SGregory Neil Shapiro e->e_from.q_uid = user.mbdb_uid; 110740266059SGregory Neil Shapiro e->e_from.q_gid = user.mbdb_gid; 1108c2aa98e2SPeter Wemm e->e_from.q_flags |= QGOODUID; 110940266059SGregory Neil Shapiro } 1110c2aa98e2SPeter Wemm 1111c2aa98e2SPeter Wemm /* extract full name from passwd file */ 111240266059SGregory Neil Shapiro if (FullName == NULL && !internal && 111340266059SGregory Neil Shapiro user.mbdb_fullname[0] != '\0' && 111440266059SGregory Neil Shapiro strcmp(user.mbdb_name, e->e_from.q_user) == 0) 1115c2aa98e2SPeter Wemm { 111640266059SGregory Neil Shapiro FullName = newstr(user.mbdb_fullname); 1117c2aa98e2SPeter Wemm } 1118c2aa98e2SPeter Wemm } 1119c2aa98e2SPeter Wemm else 1120c2aa98e2SPeter Wemm { 112106f25ae9SGregory Neil Shapiro e->e_from.q_home = NULL; 1122c2aa98e2SPeter Wemm } 1123c2aa98e2SPeter Wemm if (FullName != NULL && !internal) 112413bd1963SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'x', FullName); 1125c2aa98e2SPeter Wemm } 11262e43090eSPeter Wemm else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP) 1127c2aa98e2SPeter Wemm { 1128c2aa98e2SPeter Wemm if (e->e_from.q_home == NULL) 1129c2aa98e2SPeter Wemm { 1130c2aa98e2SPeter Wemm e->e_from.q_home = getenv("HOME"); 113142e5d165SGregory Neil Shapiro if (e->e_from.q_home != NULL) 113242e5d165SGregory Neil Shapiro { 113342e5d165SGregory Neil Shapiro if (*e->e_from.q_home == '\0') 113442e5d165SGregory Neil Shapiro e->e_from.q_home = NULL; 113542e5d165SGregory Neil Shapiro else if (strcmp(e->e_from.q_home, "/") == 0) 1136c2aa98e2SPeter Wemm e->e_from.q_home++; 1137c2aa98e2SPeter Wemm } 113842e5d165SGregory Neil Shapiro } 1139c2aa98e2SPeter Wemm e->e_from.q_uid = RealUid; 1140c2aa98e2SPeter Wemm e->e_from.q_gid = RealGid; 1141c2aa98e2SPeter Wemm e->e_from.q_flags |= QGOODUID; 1142c2aa98e2SPeter Wemm } 1143c2aa98e2SPeter Wemm 1144c2aa98e2SPeter Wemm /* 1145c2aa98e2SPeter Wemm ** Rewrite the from person to dispose of possible implicit 1146c2aa98e2SPeter Wemm ** links in the net. 1147c2aa98e2SPeter Wemm */ 1148c2aa98e2SPeter Wemm 1149d0cef73dSGregory Neil Shapiro pvp = prescan(from, delimchar, pvpbuf, sizeof(pvpbuf), NULL, 1150d0cef73dSGregory Neil Shapiro IntTokenTab, false); 1151c2aa98e2SPeter Wemm if (pvp == NULL) 1152c2aa98e2SPeter Wemm { 1153c2aa98e2SPeter Wemm /* don't need to give error -- prescan did that already */ 1154c2aa98e2SPeter Wemm if (LogLevel > 2) 1155c2aa98e2SPeter Wemm sm_syslog(LOG_NOTICE, e->e_id, 1156c2aa98e2SPeter Wemm "cannot prescan from (%s)", 1157c2aa98e2SPeter Wemm shortenstring(from, MAXSHORTSTR)); 115840266059SGregory Neil Shapiro finis(true, true, ExitStat); 1159c2aa98e2SPeter Wemm } 116040266059SGregory Neil Shapiro (void) REWRITE(pvp, 3, e); 116140266059SGregory Neil Shapiro (void) REWRITE(pvp, 1, e); 116240266059SGregory Neil Shapiro (void) REWRITE(pvp, 4, e); 116340266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); 1164c2aa98e2SPeter Wemm bp = buf + 1; 1165d0cef73dSGregory Neil Shapiro cataddr(pvp, NULL, bp, sizeof(buf) - 2, '\0', false); 1166c2aa98e2SPeter Wemm if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 1167c2aa98e2SPeter Wemm { 1168c2aa98e2SPeter Wemm /* heuristic: route-addr: add angle brackets */ 1169d0cef73dSGregory Neil Shapiro (void) sm_strlcat(bp, ">", sizeof(buf) - 1); 1170c2aa98e2SPeter Wemm *--bp = '<'; 1171c2aa98e2SPeter Wemm } 117240266059SGregory Neil Shapiro e->e_sender = sm_rpool_strdup_x(e->e_rpool, bp); 117340266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, 'f', e->e_sender); 1174c2aa98e2SPeter Wemm 1175c2aa98e2SPeter Wemm /* save the domain spec if this mailer wants it */ 1176c2aa98e2SPeter Wemm if (e->e_from.q_mailer != NULL && 1177c2aa98e2SPeter Wemm bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 1178c2aa98e2SPeter Wemm { 1179c2aa98e2SPeter Wemm char **lastat; 1180c2aa98e2SPeter Wemm 1181c2aa98e2SPeter Wemm /* get rid of any pesky angle brackets */ 118240266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); 118340266059SGregory Neil Shapiro (void) REWRITE(pvp, 3, e); 118440266059SGregory Neil Shapiro (void) REWRITE(pvp, 1, e); 118540266059SGregory Neil Shapiro (void) REWRITE(pvp, 4, e); 118640266059SGregory Neil Shapiro macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL); 1187c2aa98e2SPeter Wemm 1188c2aa98e2SPeter Wemm /* strip off to the last "@" sign */ 1189c2aa98e2SPeter Wemm for (lastat = NULL; *pvp != NULL; pvp++) 1190e92d3f3fSGregory Neil Shapiro { 1191c2aa98e2SPeter Wemm if (strcmp(*pvp, "@") == 0) 1192c2aa98e2SPeter Wemm lastat = pvp; 1193e92d3f3fSGregory Neil Shapiro } 1194c2aa98e2SPeter Wemm if (lastat != NULL) 1195c2aa98e2SPeter Wemm { 119640266059SGregory Neil Shapiro e->e_fromdomain = copyplist(lastat, true, e->e_rpool); 1197c2aa98e2SPeter Wemm if (tTd(45, 3)) 1198c2aa98e2SPeter Wemm { 119940266059SGregory Neil Shapiro sm_dprintf("Saving from domain: "); 1200e92d3f3fSGregory Neil Shapiro printav(sm_debug_file(), e->e_fromdomain); 1201c2aa98e2SPeter Wemm } 1202c2aa98e2SPeter Wemm } 1203c2aa98e2SPeter Wemm } 1204c2aa98e2SPeter Wemm } 120540266059SGregory Neil Shapiro /* 1206c2aa98e2SPeter Wemm ** PRINTENVFLAGS -- print envelope flags for debugging 1207c2aa98e2SPeter Wemm ** 1208c2aa98e2SPeter Wemm ** Parameters: 1209c2aa98e2SPeter Wemm ** e -- the envelope with the flags to be printed. 1210c2aa98e2SPeter Wemm ** 1211c2aa98e2SPeter Wemm ** Returns: 1212c2aa98e2SPeter Wemm ** none. 1213c2aa98e2SPeter Wemm */ 1214c2aa98e2SPeter Wemm 1215c2aa98e2SPeter Wemm struct eflags 1216c2aa98e2SPeter Wemm { 1217c2aa98e2SPeter Wemm char *ef_name; 121840266059SGregory Neil Shapiro unsigned long ef_bit; 1219c2aa98e2SPeter Wemm }; 1220c2aa98e2SPeter Wemm 122106f25ae9SGregory Neil Shapiro static struct eflags EnvelopeFlags[] = 1222c2aa98e2SPeter Wemm { 1223c2aa98e2SPeter Wemm { "OLDSTYLE", EF_OLDSTYLE }, 1224c2aa98e2SPeter Wemm { "INQUEUE", EF_INQUEUE }, 1225c2aa98e2SPeter Wemm { "NO_BODY_RETN", EF_NO_BODY_RETN }, 1226c2aa98e2SPeter Wemm { "CLRQUEUE", EF_CLRQUEUE }, 1227c2aa98e2SPeter Wemm { "SENDRECEIPT", EF_SENDRECEIPT }, 1228c2aa98e2SPeter Wemm { "FATALERRS", EF_FATALERRS }, 1229c2aa98e2SPeter Wemm { "DELETE_BCC", EF_DELETE_BCC }, 1230c2aa98e2SPeter Wemm { "RESPONSE", EF_RESPONSE }, 1231c2aa98e2SPeter Wemm { "RESENT", EF_RESENT }, 1232c2aa98e2SPeter Wemm { "VRFYONLY", EF_VRFYONLY }, 1233c2aa98e2SPeter Wemm { "WARNING", EF_WARNING }, 1234c2aa98e2SPeter Wemm { "QUEUERUN", EF_QUEUERUN }, 1235c2aa98e2SPeter Wemm { "GLOBALERRS", EF_GLOBALERRS }, 1236c2aa98e2SPeter Wemm { "PM_NOTIFY", EF_PM_NOTIFY }, 1237c2aa98e2SPeter Wemm { "METOO", EF_METOO }, 1238c2aa98e2SPeter Wemm { "LOGSENDER", EF_LOGSENDER }, 1239c2aa98e2SPeter Wemm { "NORECEIPT", EF_NORECEIPT }, 1240c2aa98e2SPeter Wemm { "HAS8BIT", EF_HAS8BIT }, 1241c2aa98e2SPeter Wemm { "NL_NOT_EOL", EF_NL_NOT_EOL }, 1242c2aa98e2SPeter Wemm { "CRLF_NOT_EOL", EF_CRLF_NOT_EOL }, 1243c2aa98e2SPeter Wemm { "RET_PARAM", EF_RET_PARAM }, 1244c2aa98e2SPeter Wemm { "HAS_DF", EF_HAS_DF }, 1245c2aa98e2SPeter Wemm { "IS_MIME", EF_IS_MIME }, 1246c2aa98e2SPeter Wemm { "DONT_MIME", EF_DONT_MIME }, 124740266059SGregory Neil Shapiro { "DISCARD", EF_DISCARD }, 124840266059SGregory Neil Shapiro { "TOOBIG", EF_TOOBIG }, 124940266059SGregory Neil Shapiro { "SPLIT", EF_SPLIT }, 125040266059SGregory Neil Shapiro { "UNSAFE", EF_UNSAFE }, 1251193538b7SGregory Neil Shapiro { NULL, 0 } 1252c2aa98e2SPeter Wemm }; 1253c2aa98e2SPeter Wemm 1254c2aa98e2SPeter Wemm void 1255c2aa98e2SPeter Wemm printenvflags(e) 1256c2aa98e2SPeter Wemm register ENVELOPE *e; 1257c2aa98e2SPeter Wemm { 1258c2aa98e2SPeter Wemm register struct eflags *ef; 125940266059SGregory Neil Shapiro bool first = true; 1260c2aa98e2SPeter Wemm 1261e92d3f3fSGregory Neil Shapiro sm_dprintf("%lx", e->e_flags); 1262c2aa98e2SPeter Wemm for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) 1263c2aa98e2SPeter Wemm { 1264c2aa98e2SPeter Wemm if (!bitset(ef->ef_bit, e->e_flags)) 1265c2aa98e2SPeter Wemm continue; 1266c2aa98e2SPeter Wemm if (first) 1267e92d3f3fSGregory Neil Shapiro sm_dprintf("<%s", ef->ef_name); 1268c2aa98e2SPeter Wemm else 1269e92d3f3fSGregory Neil Shapiro sm_dprintf(",%s", ef->ef_name); 127040266059SGregory Neil Shapiro first = false; 1271c2aa98e2SPeter Wemm } 1272c2aa98e2SPeter Wemm if (!first) 1273e92d3f3fSGregory Neil Shapiro sm_dprintf(">\n"); 1274c2aa98e2SPeter Wemm } 1275