122704Sdist /* 234921Sbostic * Copyright (c) 1983 Eric P. Allman 362525Sbostic * Copyright (c) 1988, 1993 462525Sbostic * The Regents of the University of California. All rights reserved. 533729Sbostic * 642826Sbostic * %sccs.include.redist.c% 733729Sbostic */ 822704Sdist 922704Sdist #ifndef lint 10*67939Seric static char sccsid[] = "@(#)envelope.c 8.43 (Berkeley) 11/20/94"; 1133729Sbostic #endif /* not lint */ 1222704Sdist 1358332Seric #include "sendmail.h" 149536Seric #include <pwd.h> 159536Seric 169536Seric /* 179536Seric ** NEWENVELOPE -- allocate a new envelope 189536Seric ** 199536Seric ** Supports inheritance. 209536Seric ** 219536Seric ** Parameters: 229536Seric ** e -- the new envelope to fill in. 2358179Seric ** parent -- the envelope to be the parent of e. 249536Seric ** 259536Seric ** Returns: 269536Seric ** e. 279536Seric ** 289536Seric ** Side Effects: 299536Seric ** none. 309536Seric */ 319536Seric 329536Seric ENVELOPE * 3358179Seric newenvelope(e, parent) 349536Seric register ENVELOPE *e; 3558179Seric register ENVELOPE *parent; 369536Seric { 379536Seric extern putheader(), putbody(); 3825611Seric extern ENVELOPE BlankEnvelope; 399536Seric 4058179Seric if (e == parent && e->e_parent != NULL) 419536Seric parent = e->e_parent; 4225611Seric clearenvelope(e, TRUE); 4324944Seric if (e == CurEnv) 4424944Seric bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from); 4524944Seric else 4624944Seric bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); 479536Seric e->e_parent = parent; 489536Seric e->e_ctime = curtime(); 4956215Seric if (parent != NULL) 5056215Seric e->e_msgpriority = parent->e_msgsize; 519536Seric e->e_puthdr = putheader; 529536Seric e->e_putbody = putbody; 539536Seric if (CurEnv->e_xfp != NULL) 549536Seric (void) fflush(CurEnv->e_xfp); 559536Seric 569536Seric return (e); 579536Seric } 589536Seric /* 599536Seric ** DROPENVELOPE -- deallocate an envelope. 609536Seric ** 619536Seric ** Parameters: 629536Seric ** e -- the envelope to deallocate. 639536Seric ** 649536Seric ** Returns: 659536Seric ** none. 669536Seric ** 679536Seric ** Side Effects: 689536Seric ** housekeeping necessary to dispose of an envelope. 699536Seric ** Unlocks this queue file. 709536Seric */ 719536Seric 7260494Seric void 739536Seric dropenvelope(e) 749536Seric register ENVELOPE *e; 759536Seric { 769536Seric bool queueit = FALSE; 7767880Seric bool failure_return = FALSE; 7867880Seric bool success_return = FALSE; 799536Seric register ADDRESS *q; 8057943Seric char *id = e->e_id; 8167880Seric bool return_no, return_yes; 8263753Seric char buf[MAXLINE]; 839536Seric 849536Seric if (tTd(50, 1)) 859536Seric { 8658680Seric printf("dropenvelope %x: id=", e); 879536Seric xputs(e->e_id); 8865089Seric printf(", flags=0x%x\n", e->e_flags); 8963753Seric if (tTd(50, 10)) 9063753Seric { 9163753Seric printf("sendq="); 9263753Seric printaddr(e->e_sendqueue, TRUE); 9363753Seric } 949536Seric } 9557943Seric 9658680Seric /* we must have an id to remove disk files */ 9757943Seric if (id == NULL) 9858680Seric return; 9957943Seric 1009536Seric #ifdef LOG 10165089Seric if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 10265089Seric logsender(e, NULL); 10358020Seric if (LogLevel > 84) 10465089Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d", 10557943Seric id, e->e_flags, getpid()); 10656795Seric #endif /* LOG */ 10765089Seric e->e_flags &= ~EF_LOGSENDER; 1089536Seric 10963753Seric /* post statistics */ 11063753Seric poststats(StatFile); 11163753Seric 1129536Seric /* 1139536Seric ** Extract state information from dregs of send list. 1149536Seric */ 1159536Seric 11664743Seric e->e_flags &= ~EF_QUEUERUN; 11767880Seric return_no = return_yes = FALSE; 1189536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 1199536Seric { 1209536Seric if (bitset(QQUEUEUP, q->q_flags)) 1219536Seric queueit = TRUE; 12267880Seric 12367880Seric /* see if a notification is needed */ 12467880Seric if (bitset(QBADADDR, q->q_flags) && 12567880Seric bitset(QPINGONFAILURE, q->q_flags)) 12663839Seric { 12767880Seric failure_return = TRUE; 128*67939Seric if (q->q_owner == NULL && !emptyaddr(&e->e_from)) 12963839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 13063839Seric &e->e_errorqueue, e); 13163839Seric } 13267880Seric else if (bitset(QSENT, q->q_flags) && 13367880Seric bitnset(M_LOCALMAILER, q->q_mailer->m_flags) && 13467880Seric bitset(QPINGONSUCCESS, q->q_flags)) 13567880Seric { 13667880Seric success_return = TRUE; 13767880Seric } 13867880Seric else 13967880Seric continue; 14067880Seric 14167880Seric /* common code for error returns and return receipts */ 14267880Seric 14367880Seric /* test for returning the body */ 14467880Seric if (!bitset(QHASRETPARAM, q->q_flags)) 14567880Seric { 14667880Seric if (!bitset(EF_NORETURN, e->e_flags)) 14767880Seric return_yes = TRUE; 14867880Seric } 14967880Seric else if (bitset(QNOBODYRETURN, q->q_flags)) 15067880Seric return_no = TRUE; 15167880Seric else 15267880Seric return_yes = TRUE; 1539536Seric } 15467880Seric if (return_no && !return_yes) 15567880Seric e->e_flags |= EF_NORETURN; 1569536Seric 1579536Seric /* 15863753Seric ** See if the message timed out. 15963753Seric */ 16063753Seric 16163753Seric if (!queueit) 16263753Seric /* nothing to do */ ; 16367730Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 16463753Seric { 16563839Seric (void) sprintf(buf, "Cannot send message for %s", 16667730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 16763839Seric if (e->e_message != NULL) 16863839Seric free(e->e_message); 16963839Seric e->e_message = newstr(buf); 17063839Seric message(buf); 17163839Seric e->e_flags |= EF_CLRQUEUE; 17267880Seric failure_return = TRUE; 17363787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 17467730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 17563787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 17663787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 17763787Seric { 17863787Seric if (bitset(QQUEUEUP, q->q_flags)) 17963787Seric q->q_flags |= QBADADDR; 18063787Seric } 18163753Seric } 18267730Seric else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 18367730Seric curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) 18463753Seric { 18563753Seric if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 18663753Seric e->e_class >= 0 && 18767691Seric strcmp(e->e_from.q_paddr, "<>") != 0 && 18867691Seric strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 18967691Seric (strlen(e->e_from.q_paddr) <= 8 || 19067691Seric strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) 19163753Seric { 19263753Seric (void) sprintf(buf, 19367261Seric "Warning: cannot send message for %s", 19467730Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 19563753Seric if (e->e_message != NULL) 19663753Seric free(e->e_message); 19763753Seric e->e_message = newstr(buf); 19863753Seric message(buf); 19963839Seric e->e_flags |= EF_WARNING; 20067880Seric failure_return = TRUE; 20163753Seric } 20263753Seric fprintf(e->e_xfp, 20363753Seric "Warning: message still undelivered after %s\n", 20467730Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 20563753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 20667730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 20763787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 20863787Seric { 20963787Seric if (bitset(QQUEUEUP, q->q_flags)) 21063787Seric q->q_flags |= QREPORT; 21163787Seric } 21263753Seric } 21363753Seric 21467880Seric if (tTd(50, 2)) 21567880Seric printf("failure_return=%d success_return=%d queueit=%d\n", 21667880Seric failure_return, success_return, queueit); 21767880Seric 21863753Seric /* 2199536Seric ** Send back return receipts as requested. 2209536Seric */ 2219536Seric 22267880Seric /* 22366783Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags) 22466783Seric && !bitset(PRIV_NORECEIPTS, PrivacyFlags)) 22567880Seric */ 22667880Seric if (e->e_receiptto == NULL) 22767880Seric e->e_receiptto = e->e_from.q_paddr; 22867880Seric if (success_return && strcmp(e->e_receiptto, "<>") != 0) 2299536Seric { 23010844Seric auto ADDRESS *rlist = NULL; 2319536Seric 23267880Seric e->e_flags |= EF_SENDRECEIPT; 23364284Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e); 23455012Seric (void) returntosender("Return receipt", rlist, FALSE, e); 2359536Seric } 23667682Seric e->e_flags &= ~EF_SENDRECEIPT; 2379536Seric 2389536Seric /* 2399536Seric ** Arrange to send error messages if there are fatal errors. 2409536Seric */ 2419536Seric 24267880Seric if (failure_return && e->e_errormode != EM_QUIET) 2439536Seric savemail(e); 2449536Seric 2459536Seric /* 24663849Seric ** Arrange to send warning messages to postmaster as requested. 24763849Seric */ 24863849Seric 24963849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 25064363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 25163849Seric { 25263849Seric auto ADDRESS *rlist = NULL; 25363849Seric 25464284Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, e); 25563849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 25663849Seric } 25763849Seric 25863849Seric /* 2599536Seric ** Instantiate or deinstantiate the queue. 2609536Seric */ 2619536Seric 2629536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2639536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2649536Seric { 26564307Seric if (tTd(50, 1)) 26667880Seric printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n", 26767880Seric e->e_id, queueit, e->e_flags); 26823497Seric if (e->e_df != NULL) 26923497Seric xunlink(e->e_df); 2709536Seric xunlink(queuename(e, 'q')); 27163839Seric 27263839Seric #ifdef LOG 27363839Seric if (LogLevel > 10) 27463839Seric syslog(LOG_INFO, "%s: done", id); 27563839Seric #endif 2769536Seric } 2779536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 27810754Seric { 27910754Seric #ifdef QUEUE 28064307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 28156795Seric #else /* QUEUE */ 28258151Seric syserr("554 dropenvelope: queueup"); 28356795Seric #endif /* QUEUE */ 28410754Seric } 2859536Seric 2869536Seric /* now unlock the job */ 28710196Seric closexscript(e); 2889536Seric unlockqueue(e); 2899536Seric 2909536Seric /* make sure that this envelope is marked unused */ 29124944Seric if (e->e_dfp != NULL) 29258680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 29310196Seric e->e_dfp = NULL; 29458680Seric e->e_id = e->e_df = NULL; 2959536Seric } 2969536Seric /* 2979536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 2989536Seric ** 2999536Seric ** This is normally used by a child process to get a clean 3009536Seric ** envelope without disturbing the parent. 3019536Seric ** 3029536Seric ** Parameters: 3039536Seric ** e -- the envelope to clear. 30425611Seric ** fullclear - if set, the current envelope is total 30525611Seric ** garbage and should be ignored; otherwise, 30625611Seric ** release any resources it may indicate. 3079536Seric ** 3089536Seric ** Returns: 3099536Seric ** none. 3109536Seric ** 3119536Seric ** Side Effects: 3129536Seric ** Closes files associated with the envelope. 3139536Seric ** Marks the envelope as unallocated. 3149536Seric */ 3159536Seric 31660494Seric void 31725611Seric clearenvelope(e, fullclear) 3189536Seric register ENVELOPE *e; 31925611Seric bool fullclear; 3209536Seric { 32125514Seric register HDR *bh; 32225514Seric register HDR **nhp; 32325514Seric extern ENVELOPE BlankEnvelope; 32425514Seric 32525611Seric if (!fullclear) 32625611Seric { 32725611Seric /* clear out any file information */ 32825611Seric if (e->e_xfp != NULL) 32958680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 33025611Seric if (e->e_dfp != NULL) 33158680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 33258680Seric e->e_xfp = e->e_dfp = NULL; 33325611Seric } 3349536Seric 33524961Seric /* now clear out the data */ 33624965Seric STRUCTCOPY(BlankEnvelope, *e); 33759698Seric if (Verbose) 33859698Seric e->e_sendmode = SM_DELIVER; 33925514Seric bh = BlankEnvelope.e_header; 34025514Seric nhp = &e->e_header; 34125514Seric while (bh != NULL) 34225514Seric { 34325514Seric *nhp = (HDR *) xalloc(sizeof *bh); 34425514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 34525514Seric bh = bh->h_link; 34625514Seric nhp = &(*nhp)->h_link; 34725514Seric } 3489536Seric } 3499536Seric /* 3509536Seric ** INITSYS -- initialize instantiation of system 3519536Seric ** 3529536Seric ** In Daemon mode, this is done in the child. 3539536Seric ** 3549536Seric ** Parameters: 3559536Seric ** none. 3569536Seric ** 3579536Seric ** Returns: 3589536Seric ** none. 3599536Seric ** 3609536Seric ** Side Effects: 3619536Seric ** Initializes the system macros, some global variables, 3629536Seric ** etc. In particular, the current time in various 3639536Seric ** forms is set. 3649536Seric */ 3659536Seric 36660494Seric void 36755012Seric initsys(e) 36855012Seric register ENVELOPE *e; 3699536Seric { 37064768Seric char cbuf[5]; /* holds hop count */ 37164768Seric char pbuf[10]; /* holds pid */ 37222963Smiriam #ifdef TTYNAME 37359304Seric static char ybuf[60]; /* holds tty id */ 3749536Seric register char *p; 37556795Seric #endif /* TTYNAME */ 3769536Seric extern char *ttyname(); 37760494Seric extern void settime(); 3789536Seric extern char Version[]; 3799536Seric 3809536Seric /* 3819536Seric ** Give this envelope a reality. 3829536Seric ** I.e., an id, a transcript, and a creation time. 3839536Seric */ 3849536Seric 38555012Seric openxscript(e); 38655012Seric e->e_ctime = curtime(); 3879536Seric 3889536Seric /* 3899536Seric ** Set OutChannel to something useful if stdout isn't it. 3909536Seric ** This arranges that any extra stuff the mailer produces 3919536Seric ** gets sent back to the user on error (because it is 3929536Seric ** tucked away in the transcript). 3939536Seric */ 3949536Seric 39564760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 39658737Seric e->e_xfp != NULL) 39755012Seric OutChannel = e->e_xfp; 3989536Seric 3999536Seric /* 4009536Seric ** Set up some basic system macros. 4019536Seric */ 4029536Seric 4039536Seric /* process id */ 4049536Seric (void) sprintf(pbuf, "%d", getpid()); 40564768Seric define('p', newstr(pbuf), e); 4069536Seric 4079536Seric /* hop count */ 40855012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 40964768Seric define('c', newstr(cbuf), e); 4109536Seric 4119536Seric /* time as integer, unix time, arpa time */ 41255012Seric settime(e); 4139536Seric 41417472Seric #ifdef TTYNAME 4159536Seric /* tty name */ 41655012Seric if (macvalue('y', e) == NULL) 4179536Seric { 4189536Seric p = ttyname(2); 4199536Seric if (p != NULL) 4209536Seric { 42156795Seric if (strrchr(p, '/') != NULL) 42256795Seric p = strrchr(p, '/') + 1; 4239536Seric (void) strcpy(ybuf, p); 42455012Seric define('y', ybuf, e); 4259536Seric } 4269536Seric } 42756795Seric #endif /* TTYNAME */ 4289536Seric } 4299536Seric /* 43011932Seric ** SETTIME -- set the current time. 43111932Seric ** 43211932Seric ** Parameters: 43311932Seric ** none. 43411932Seric ** 43511932Seric ** Returns: 43611932Seric ** none. 43711932Seric ** 43811932Seric ** Side Effects: 43911932Seric ** Sets the various time macros -- $a, $b, $d, $t. 44011932Seric */ 44111932Seric 44260494Seric void 44355012Seric settime(e) 44455012Seric register ENVELOPE *e; 44511932Seric { 44611932Seric register char *p; 44711932Seric auto time_t now; 44864768Seric char tbuf[20]; /* holds "current" time */ 44964768Seric char dbuf[30]; /* holds ctime(tbuf) */ 45011932Seric register struct tm *tm; 45111932Seric extern char *arpadate(); 45211932Seric extern struct tm *gmtime(); 45311932Seric 45411932Seric now = curtime(); 45511932Seric tm = gmtime(&now); 45657014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 45757014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 45864768Seric define('t', newstr(tbuf), e); 45911932Seric (void) strcpy(dbuf, ctime(&now)); 46058131Seric p = strchr(dbuf, '\n'); 46158131Seric if (p != NULL) 46258131Seric *p = '\0'; 46364768Seric define('d', newstr(dbuf), e); 46464086Seric p = arpadate(dbuf); 46564086Seric p = newstr(p); 46655012Seric if (macvalue('a', e) == NULL) 46755012Seric define('a', p, e); 46855012Seric define('b', p, e); 46911932Seric } 47011932Seric /* 4719536Seric ** OPENXSCRIPT -- Open transcript file 4729536Seric ** 4739536Seric ** Creates a transcript file for possible eventual mailing or 4749536Seric ** sending back. 4759536Seric ** 4769536Seric ** Parameters: 4779536Seric ** e -- the envelope to create the transcript in/for. 4789536Seric ** 4799536Seric ** Returns: 4809536Seric ** none 4819536Seric ** 4829536Seric ** Side Effects: 4839536Seric ** Creates the transcript file. 4849536Seric */ 4859536Seric 48658803Seric #ifndef O_APPEND 48758803Seric #define O_APPEND 0 48858803Seric #endif 48958803Seric 49060494Seric void 4919536Seric openxscript(e) 4929536Seric register ENVELOPE *e; 4939536Seric { 4949536Seric register char *p; 49540933Srick int fd; 4969536Seric 4979536Seric if (e->e_xfp != NULL) 4989536Seric return; 4999536Seric p = queuename(e, 'x'); 50058803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 50140933Srick if (fd < 0) 50263753Seric { 50363753Seric syserr("Can't create transcript file %s", p); 50463753Seric fd = open("/dev/null", O_WRONLY, 0644); 50563753Seric if (fd < 0) 50663753Seric syserr("!Can't open /dev/null"); 50763753Seric } 50863753Seric e->e_xfp = fdopen(fd, "w"); 50964724Seric if (e->e_xfp == NULL) 51064724Seric { 51164724Seric syserr("!Can't create transcript stream %s", p); 51264724Seric } 51364743Seric if (tTd(46, 9)) 51464743Seric { 51564743Seric printf("openxscript(%s):\n ", p); 51664743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 51764743Seric } 5189536Seric } 5199536Seric /* 52010196Seric ** CLOSEXSCRIPT -- close the transcript file. 52110196Seric ** 52210196Seric ** Parameters: 52310196Seric ** e -- the envelope containing the transcript to close. 52410196Seric ** 52510196Seric ** Returns: 52610196Seric ** none. 52710196Seric ** 52810196Seric ** Side Effects: 52910196Seric ** none. 53010196Seric */ 53110196Seric 53260494Seric void 53310196Seric closexscript(e) 53410196Seric register ENVELOPE *e; 53510196Seric { 53610196Seric if (e->e_xfp == NULL) 53710196Seric return; 53858680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 53910196Seric e->e_xfp = NULL; 54010196Seric } 54110196Seric /* 5429536Seric ** SETSENDER -- set the person who this message is from 5439536Seric ** 5449536Seric ** Under certain circumstances allow the user to say who 5459536Seric ** s/he is (using -f or -r). These are: 5469536Seric ** 1. The user's uid is zero (root). 5479536Seric ** 2. The user's login name is in an approved list (typically 5489536Seric ** from a network server). 5499536Seric ** 3. The address the user is trying to claim has a 5509536Seric ** "!" character in it (since #2 doesn't do it for 5519536Seric ** us if we are dialing out for UUCP). 5529536Seric ** A better check to replace #3 would be if the 5539536Seric ** effective uid is "UUCP" -- this would require me 5549536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5559536Seric ** make getname more nasty, do another passwd file 5569536Seric ** scan, or compile the UID of "UUCP" into the code, 5579536Seric ** all of which are reprehensible. 5589536Seric ** 5599536Seric ** Assuming all of these fail, we figure out something 5609536Seric ** ourselves. 5619536Seric ** 5629536Seric ** Parameters: 5639536Seric ** from -- the person we would like to believe this message 5649536Seric ** is from, as specified on the command line. 56553182Seric ** e -- the envelope in which we would like the sender set. 56658333Seric ** delimptr -- if non-NULL, set to the location of the 56758333Seric ** trailing delimiter. 56858704Seric ** internal -- set if this address is coming from an internal 56958704Seric ** source such as an owner alias. 5709536Seric ** 5719536Seric ** Returns: 57258704Seric ** none. 5739536Seric ** 5749536Seric ** Side Effects: 5759536Seric ** sets sendmail's notion of who the from person is. 5769536Seric */ 5779536Seric 57860494Seric void 57958704Seric setsender(from, e, delimptr, internal) 5809536Seric char *from; 58153182Seric register ENVELOPE *e; 58258333Seric char **delimptr; 58358704Seric bool internal; 5849536Seric { 5859536Seric register char **pvp; 5869536Seric char *realname = NULL; 58718665Seric register struct passwd *pw; 58858727Seric char delimchar; 58964147Seric char *bp; 59064147Seric char buf[MAXNAME + 2]; 59116913Seric char pvpbuf[PSBUFSIZE]; 59218665Seric extern struct passwd *getpwnam(); 5939536Seric extern char *FullName; 5949536Seric 5959536Seric if (tTd(45, 1)) 59614786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 5979536Seric 5989536Seric /* 5999536Seric ** Figure out the real user executing us. 6009536Seric ** Username can return errno != 0 on non-errors. 6019536Seric */ 6029536Seric 60365580Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 60465983Seric OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 6059536Seric realname = from; 6069536Seric if (realname == NULL || realname[0] == '\0') 6079536Seric realname = username(); 6089536Seric 60959027Seric if (ConfigLevel < 2) 61059027Seric SuprErrs = TRUE; 61159027Seric 61258727Seric delimchar = internal ? '\0' : ' '; 61364793Seric e->e_from.q_flags = QBADADDR; 61458333Seric if (from == NULL || 61564284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 61664793Seric delimchar, delimptr, e) == NULL || 61764793Seric bitset(QBADADDR, e->e_from.q_flags) || 61864793Seric e->e_from.q_mailer == ProgMailer || 61964793Seric e->e_from.q_mailer == FileMailer || 62064793Seric e->e_from.q_mailer == InclMailer) 6219536Seric { 62221750Seric /* log garbage addresses for traceback */ 62355173Seric # ifdef LOG 62458020Seric if (from != NULL && LogLevel > 2) 62521750Seric { 62658951Seric char *p; 62758951Seric char ebuf[MAXNAME * 2 + 2]; 62855173Seric 62958951Seric p = macvalue('_', e); 63058951Seric if (p == NULL) 63158951Seric { 63258951Seric char *host = RealHostName; 63358951Seric if (host == NULL) 63458951Seric host = MyHostName; 63558951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 63658951Seric p = ebuf; 63758951Seric } 63855173Seric syslog(LOG_NOTICE, 63964793Seric "setsender: %s: invalid or unparseable, received from %s", 64065015Seric shortenstring(from, 83), p); 64155173Seric } 64256795Seric # endif /* LOG */ 64357589Seric if (from != NULL) 64464793Seric { 64564793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 64664793Seric { 64764793Seric /* it was a bogus mailer in the from addr */ 64864793Seric usrerr("553 Invalid sender address"); 64964793Seric } 65057589Seric SuprErrs = TRUE; 65164793Seric } 65257589Seric if (from == realname || 65364284Seric parseaddr(from = newstr(realname), &e->e_from, 65464284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 65524944Seric { 65664793Seric char nbuf[100]; 65764793Seric 65857589Seric SuprErrs = TRUE; 65964808Seric expand("\201n", nbuf, &nbuf[sizeof nbuf], e); 66064793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 66164793Seric RF_COPYALL, ' ', NULL, e) == NULL && 66264793Seric parseaddr(from = "postmaster", &e->e_from, 66364793Seric RF_COPYALL, ' ', NULL, e) == NULL) 66458151Seric syserr("553 setsender: can't even parse postmaster!"); 66524944Seric } 6669536Seric } 6679536Seric else 6689536Seric FromFlag = TRUE; 66953182Seric e->e_from.q_flags |= QDONTSEND; 67057731Seric if (tTd(45, 5)) 67157731Seric { 67257731Seric printf("setsender: QDONTSEND "); 67357731Seric printaddr(&e->e_from, FALSE); 67457731Seric } 6759536Seric SuprErrs = FALSE; 6769536Seric 67767765Seric # ifdef USERDB 67867472Seric if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 6799536Seric { 68053736Seric register char *p; 68153736Seric extern char *udbsender(); 68217472Seric 68367765Seric p = udbsender(e->e_from.q_user); 68467765Seric if (p != NULL) 68567765Seric from = p; 68667765Seric } 68767765Seric # endif /* USERDB */ 68867765Seric 68967765Seric if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 69067765Seric { 69158704Seric if (!internal) 69258704Seric { 69367765Seric /* if the user already given fullname don't redefine */ 69458704Seric if (FullName == NULL) 69558704Seric FullName = macvalue('x', e); 69658704Seric if (FullName != NULL && FullName[0] == '\0') 69758704Seric FullName = NULL; 6989536Seric } 69953736Seric 70053736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 70153736Seric { 70253736Seric /* 70353736Seric ** Process passwd file entry. 70453736Seric */ 70553736Seric 70653736Seric /* extract home directory */ 70765822Seric if (strcmp(pw->pw_dir, "/") == 0) 70865822Seric e->e_from.q_home = newstr(""); 70965822Seric else 71065822Seric e->e_from.q_home = newstr(pw->pw_dir); 71153736Seric define('z', e->e_from.q_home, e); 71253736Seric 71353736Seric /* extract user and group id */ 71453736Seric e->e_from.q_uid = pw->pw_uid; 71553736Seric e->e_from.q_gid = pw->pw_gid; 71665023Seric e->e_from.q_flags |= QGOODUID; 71753736Seric 71853736Seric /* extract full name from passwd file */ 71953736Seric if (FullName == NULL && pw->pw_gecos != NULL && 72058704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 72158704Seric !internal) 72253736Seric { 72365015Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 72453736Seric if (buf[0] != '\0') 72553736Seric FullName = newstr(buf); 72653736Seric } 72753736Seric } 72858704Seric if (FullName != NULL && !internal) 72953182Seric define('x', FullName, e); 7309536Seric } 73165580Seric else if (!internal && OpMode != MD_DAEMON) 73211625Seric { 73353182Seric if (e->e_from.q_home == NULL) 73465822Seric { 73553182Seric e->e_from.q_home = getenv("HOME"); 73666049Seric if (e->e_from.q_home != NULL && 73766049Seric strcmp(e->e_from.q_home, "/") == 0) 73865822Seric e->e_from.q_home++; 73965822Seric } 74063787Seric e->e_from.q_uid = RealUid; 74163787Seric e->e_from.q_gid = RealGid; 74265023Seric e->e_from.q_flags |= QGOODUID; 74311625Seric } 74411625Seric 7459536Seric /* 7469536Seric ** Rewrite the from person to dispose of possible implicit 7479536Seric ** links in the net. 7489536Seric */ 7499536Seric 75067765Seric pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); 7519536Seric if (pvp == NULL) 7529536Seric { 75358403Seric /* don't need to give error -- prescan did that already */ 75436233Skarels # ifdef LOG 75558020Seric if (LogLevel > 2) 75636233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 75736233Skarels # endif 7589536Seric finis(); 7599536Seric } 76067765Seric /* 76165071Seric (void) rewrite(pvp, 3, 0, e); 76265071Seric (void) rewrite(pvp, 1, 0, e); 76365071Seric (void) rewrite(pvp, 4, 0, e); 76467765Seric */ 76564147Seric bp = buf + 1; 76664147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 76767619Seric if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 76864147Seric { 76964147Seric /* heuristic: route-addr: add angle brackets */ 77064147Seric strcat(bp, ">"); 77164147Seric *--bp = '<'; 77264147Seric } 77364147Seric e->e_sender = newstr(bp); 77458704Seric define('f', e->e_sender, e); 7759536Seric 7769536Seric /* save the domain spec if this mailer wants it */ 77765584Seric if (e->e_from.q_mailer != NULL && 77853182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 7799536Seric { 7809536Seric extern char **copyplist(); 7819536Seric 7829536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 7839536Seric pvp++; 7849536Seric if (*pvp != NULL) 78553182Seric e->e_fromdomain = copyplist(pvp, TRUE); 7869536Seric } 7879536Seric } 788