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*67982Seric static char sccsid[] = "@(#)envelope.c 8.47 (Berkeley) 11/22/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 */ 12467975Seric if (e->e_df != NULL && 12567975Seric bitset(QBADADDR, q->q_flags) && 12667880Seric bitset(QPINGONFAILURE, q->q_flags)) 12763839Seric { 12867880Seric failure_return = TRUE; 12967939Seric if (q->q_owner == NULL && !emptyaddr(&e->e_from)) 13063839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 131*67982Seric &e->e_errorqueue, 0, e); 13263839Seric } 13367880Seric else if (bitset(QSENT, q->q_flags) && 13467880Seric bitnset(M_LOCALMAILER, q->q_mailer->m_flags) && 13567880Seric bitset(QPINGONSUCCESS, q->q_flags)) 13667880Seric { 13767880Seric success_return = TRUE; 13867880Seric } 13967963Seric else if (bitset(QRELAYED, q->q_flags)) 14067963Seric { 14167963Seric success_return = TRUE; 14267963Seric } 14367880Seric else 14467880Seric continue; 14567880Seric 14667880Seric /* common code for error returns and return receipts */ 14767880Seric 14867880Seric /* test for returning the body */ 14967981Seric if (bitset(QHAS_RET_PARAM, q->q_flags)) 15067880Seric { 15167981Seric if (bitset(QRET_HDRS, q->q_flags)) 15267981Seric return_no = TRUE; 15367981Seric else 15467880Seric return_yes = TRUE; 15567880Seric } 1569536Seric } 15767880Seric if (return_no && !return_yes) 15867880Seric e->e_flags |= EF_NORETURN; 1599536Seric 1609536Seric /* 16163753Seric ** See if the message timed out. 16263753Seric */ 16363753Seric 16463753Seric if (!queueit) 16563753Seric /* nothing to do */ ; 16667730Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 16763753Seric { 16863839Seric (void) sprintf(buf, "Cannot send message for %s", 16967730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 17063839Seric if (e->e_message != NULL) 17163839Seric free(e->e_message); 17263839Seric e->e_message = newstr(buf); 17363839Seric message(buf); 17463839Seric e->e_flags |= EF_CLRQUEUE; 17567880Seric failure_return = TRUE; 17663787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 17767730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 17863787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 17963787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 18063787Seric { 18163787Seric if (bitset(QQUEUEUP, q->q_flags)) 18263787Seric q->q_flags |= QBADADDR; 18363787Seric } 18463753Seric } 18567730Seric else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 18667730Seric curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) 18763753Seric { 18867963Seric bool delay_return = FALSE; 18967963Seric 19067963Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 19167963Seric { 19267963Seric if (bitset(QQUEUEUP, q->q_flags) && 19367963Seric bitset(QPINGONDELAY, q->q_flags)) 19467963Seric { 19567963Seric q->q_flags |= QREPORT; 19667963Seric delay_return = TRUE; 19767963Seric } 19867963Seric } 19967963Seric if (delay_return && 20067963Seric !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 20163753Seric e->e_class >= 0 && 20267691Seric strcmp(e->e_from.q_paddr, "<>") != 0 && 20367691Seric strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 20467691Seric (strlen(e->e_from.q_paddr) <= 8 || 20567691Seric strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) 20663753Seric { 20763753Seric (void) sprintf(buf, 20867261Seric "Warning: cannot send message for %s", 20967730Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 21063753Seric if (e->e_message != NULL) 21163753Seric free(e->e_message); 21263753Seric e->e_message = newstr(buf); 21363753Seric message(buf); 21463839Seric e->e_flags |= EF_WARNING; 21567880Seric failure_return = TRUE; 21663753Seric } 21763753Seric fprintf(e->e_xfp, 21863753Seric "Warning: message still undelivered after %s\n", 21967730Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 22063753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 22167730Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 22263753Seric } 22363753Seric 22467880Seric if (tTd(50, 2)) 22567880Seric printf("failure_return=%d success_return=%d queueit=%d\n", 22667880Seric failure_return, success_return, queueit); 22767880Seric 22863753Seric /* 2299536Seric ** Send back return receipts as requested. 2309536Seric */ 2319536Seric 23267880Seric /* 23366783Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags) 23466783Seric && !bitset(PRIV_NORECEIPTS, PrivacyFlags)) 23567880Seric */ 23667880Seric if (e->e_receiptto == NULL) 23767880Seric e->e_receiptto = e->e_from.q_paddr; 23867981Seric if (success_return && !failure_return && 23967981Seric strcmp(e->e_receiptto, "<>") != 0) 2409536Seric { 24110844Seric auto ADDRESS *rlist = NULL; 2429536Seric 24367880Seric e->e_flags |= EF_SENDRECEIPT; 244*67982Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e); 24567963Seric (void) returntosender("Return receipt", rlist, return_yes, e); 2469536Seric } 24767682Seric e->e_flags &= ~EF_SENDRECEIPT; 2489536Seric 2499536Seric /* 2509536Seric ** Arrange to send error messages if there are fatal errors. 2519536Seric */ 2529536Seric 25367880Seric if (failure_return && e->e_errormode != EM_QUIET) 25467981Seric savemail(e, return_yes || (!return_no && e->e_class >= 0)); 2559536Seric 2569536Seric /* 25763849Seric ** Arrange to send warning messages to postmaster as requested. 25863849Seric */ 25963849Seric 26063849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 26164363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 26263849Seric { 26363849Seric auto ADDRESS *rlist = NULL; 26463849Seric 265*67982Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); 26663849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 26763849Seric } 26863849Seric 26963849Seric /* 2709536Seric ** Instantiate or deinstantiate the queue. 2719536Seric */ 2729536Seric 2739536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2749536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2759536Seric { 27664307Seric if (tTd(50, 1)) 27767880Seric printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n", 27867880Seric e->e_id, queueit, e->e_flags); 27923497Seric if (e->e_df != NULL) 28023497Seric xunlink(e->e_df); 2819536Seric xunlink(queuename(e, 'q')); 28263839Seric 28363839Seric #ifdef LOG 28463839Seric if (LogLevel > 10) 28563839Seric syslog(LOG_INFO, "%s: done", id); 28663839Seric #endif 2879536Seric } 2889536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 28910754Seric { 29010754Seric #ifdef QUEUE 29164307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 29256795Seric #else /* QUEUE */ 29358151Seric syserr("554 dropenvelope: queueup"); 29456795Seric #endif /* QUEUE */ 29510754Seric } 2969536Seric 2979536Seric /* now unlock the job */ 29810196Seric closexscript(e); 2999536Seric unlockqueue(e); 3009536Seric 3019536Seric /* make sure that this envelope is marked unused */ 30224944Seric if (e->e_dfp != NULL) 30358680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 30410196Seric e->e_dfp = NULL; 30558680Seric e->e_id = e->e_df = NULL; 3069536Seric } 3079536Seric /* 3089536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 3099536Seric ** 3109536Seric ** This is normally used by a child process to get a clean 3119536Seric ** envelope without disturbing the parent. 3129536Seric ** 3139536Seric ** Parameters: 3149536Seric ** e -- the envelope to clear. 31525611Seric ** fullclear - if set, the current envelope is total 31625611Seric ** garbage and should be ignored; otherwise, 31725611Seric ** release any resources it may indicate. 3189536Seric ** 3199536Seric ** Returns: 3209536Seric ** none. 3219536Seric ** 3229536Seric ** Side Effects: 3239536Seric ** Closes files associated with the envelope. 3249536Seric ** Marks the envelope as unallocated. 3259536Seric */ 3269536Seric 32760494Seric void 32825611Seric clearenvelope(e, fullclear) 3299536Seric register ENVELOPE *e; 33025611Seric bool fullclear; 3319536Seric { 33225514Seric register HDR *bh; 33325514Seric register HDR **nhp; 33425514Seric extern ENVELOPE BlankEnvelope; 33525514Seric 33625611Seric if (!fullclear) 33725611Seric { 33825611Seric /* clear out any file information */ 33925611Seric if (e->e_xfp != NULL) 34058680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 34125611Seric if (e->e_dfp != NULL) 34258680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 34358680Seric e->e_xfp = e->e_dfp = NULL; 34425611Seric } 3459536Seric 34624961Seric /* now clear out the data */ 34724965Seric STRUCTCOPY(BlankEnvelope, *e); 34859698Seric if (Verbose) 34959698Seric e->e_sendmode = SM_DELIVER; 35025514Seric bh = BlankEnvelope.e_header; 35125514Seric nhp = &e->e_header; 35225514Seric while (bh != NULL) 35325514Seric { 35425514Seric *nhp = (HDR *) xalloc(sizeof *bh); 35525514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 35625514Seric bh = bh->h_link; 35725514Seric nhp = &(*nhp)->h_link; 35825514Seric } 3599536Seric } 3609536Seric /* 3619536Seric ** INITSYS -- initialize instantiation of system 3629536Seric ** 3639536Seric ** In Daemon mode, this is done in the child. 3649536Seric ** 3659536Seric ** Parameters: 3669536Seric ** none. 3679536Seric ** 3689536Seric ** Returns: 3699536Seric ** none. 3709536Seric ** 3719536Seric ** Side Effects: 3729536Seric ** Initializes the system macros, some global variables, 3739536Seric ** etc. In particular, the current time in various 3749536Seric ** forms is set. 3759536Seric */ 3769536Seric 37760494Seric void 37855012Seric initsys(e) 37955012Seric register ENVELOPE *e; 3809536Seric { 38164768Seric char cbuf[5]; /* holds hop count */ 38264768Seric char pbuf[10]; /* holds pid */ 38322963Smiriam #ifdef TTYNAME 38459304Seric static char ybuf[60]; /* holds tty id */ 3859536Seric register char *p; 38656795Seric #endif /* TTYNAME */ 3879536Seric extern char *ttyname(); 38860494Seric extern void settime(); 3899536Seric extern char Version[]; 3909536Seric 3919536Seric /* 3929536Seric ** Give this envelope a reality. 3939536Seric ** I.e., an id, a transcript, and a creation time. 3949536Seric */ 3959536Seric 39655012Seric openxscript(e); 39755012Seric e->e_ctime = curtime(); 3989536Seric 3999536Seric /* 4009536Seric ** Set OutChannel to something useful if stdout isn't it. 4019536Seric ** This arranges that any extra stuff the mailer produces 4029536Seric ** gets sent back to the user on error (because it is 4039536Seric ** tucked away in the transcript). 4049536Seric */ 4059536Seric 40664760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 40758737Seric e->e_xfp != NULL) 40855012Seric OutChannel = e->e_xfp; 4099536Seric 4109536Seric /* 4119536Seric ** Set up some basic system macros. 4129536Seric */ 4139536Seric 4149536Seric /* process id */ 4159536Seric (void) sprintf(pbuf, "%d", getpid()); 41664768Seric define('p', newstr(pbuf), e); 4179536Seric 4189536Seric /* hop count */ 41955012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 42064768Seric define('c', newstr(cbuf), e); 4219536Seric 4229536Seric /* time as integer, unix time, arpa time */ 42355012Seric settime(e); 4249536Seric 42517472Seric #ifdef TTYNAME 4269536Seric /* tty name */ 42755012Seric if (macvalue('y', e) == NULL) 4289536Seric { 4299536Seric p = ttyname(2); 4309536Seric if (p != NULL) 4319536Seric { 43256795Seric if (strrchr(p, '/') != NULL) 43356795Seric p = strrchr(p, '/') + 1; 4349536Seric (void) strcpy(ybuf, p); 43555012Seric define('y', ybuf, e); 4369536Seric } 4379536Seric } 43856795Seric #endif /* TTYNAME */ 4399536Seric } 4409536Seric /* 44111932Seric ** SETTIME -- set the current time. 44211932Seric ** 44311932Seric ** Parameters: 44411932Seric ** none. 44511932Seric ** 44611932Seric ** Returns: 44711932Seric ** none. 44811932Seric ** 44911932Seric ** Side Effects: 45011932Seric ** Sets the various time macros -- $a, $b, $d, $t. 45111932Seric */ 45211932Seric 45360494Seric void 45455012Seric settime(e) 45555012Seric register ENVELOPE *e; 45611932Seric { 45711932Seric register char *p; 45811932Seric auto time_t now; 45964768Seric char tbuf[20]; /* holds "current" time */ 46064768Seric char dbuf[30]; /* holds ctime(tbuf) */ 46111932Seric register struct tm *tm; 46211932Seric extern char *arpadate(); 46311932Seric extern struct tm *gmtime(); 46411932Seric 46511932Seric now = curtime(); 46611932Seric tm = gmtime(&now); 46757014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 46857014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 46964768Seric define('t', newstr(tbuf), e); 47011932Seric (void) strcpy(dbuf, ctime(&now)); 47158131Seric p = strchr(dbuf, '\n'); 47258131Seric if (p != NULL) 47358131Seric *p = '\0'; 47464768Seric define('d', newstr(dbuf), e); 47564086Seric p = arpadate(dbuf); 47664086Seric p = newstr(p); 47755012Seric if (macvalue('a', e) == NULL) 47855012Seric define('a', p, e); 47955012Seric define('b', p, e); 48011932Seric } 48111932Seric /* 4829536Seric ** OPENXSCRIPT -- Open transcript file 4839536Seric ** 4849536Seric ** Creates a transcript file for possible eventual mailing or 4859536Seric ** sending back. 4869536Seric ** 4879536Seric ** Parameters: 4889536Seric ** e -- the envelope to create the transcript in/for. 4899536Seric ** 4909536Seric ** Returns: 4919536Seric ** none 4929536Seric ** 4939536Seric ** Side Effects: 4949536Seric ** Creates the transcript file. 4959536Seric */ 4969536Seric 49758803Seric #ifndef O_APPEND 49858803Seric #define O_APPEND 0 49958803Seric #endif 50058803Seric 50160494Seric void 5029536Seric openxscript(e) 5039536Seric register ENVELOPE *e; 5049536Seric { 5059536Seric register char *p; 50640933Srick int fd; 5079536Seric 5089536Seric if (e->e_xfp != NULL) 5099536Seric return; 5109536Seric p = queuename(e, 'x'); 51158803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 51240933Srick if (fd < 0) 51363753Seric { 51463753Seric syserr("Can't create transcript file %s", p); 51563753Seric fd = open("/dev/null", O_WRONLY, 0644); 51663753Seric if (fd < 0) 51763753Seric syserr("!Can't open /dev/null"); 51863753Seric } 51963753Seric e->e_xfp = fdopen(fd, "w"); 52064724Seric if (e->e_xfp == NULL) 52164724Seric { 52264724Seric syserr("!Can't create transcript stream %s", p); 52364724Seric } 52464743Seric if (tTd(46, 9)) 52564743Seric { 52664743Seric printf("openxscript(%s):\n ", p); 52764743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 52864743Seric } 5299536Seric } 5309536Seric /* 53110196Seric ** CLOSEXSCRIPT -- close the transcript file. 53210196Seric ** 53310196Seric ** Parameters: 53410196Seric ** e -- the envelope containing the transcript to close. 53510196Seric ** 53610196Seric ** Returns: 53710196Seric ** none. 53810196Seric ** 53910196Seric ** Side Effects: 54010196Seric ** none. 54110196Seric */ 54210196Seric 54360494Seric void 54410196Seric closexscript(e) 54510196Seric register ENVELOPE *e; 54610196Seric { 54710196Seric if (e->e_xfp == NULL) 54810196Seric return; 54958680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 55010196Seric e->e_xfp = NULL; 55110196Seric } 55210196Seric /* 5539536Seric ** SETSENDER -- set the person who this message is from 5549536Seric ** 5559536Seric ** Under certain circumstances allow the user to say who 5569536Seric ** s/he is (using -f or -r). These are: 5579536Seric ** 1. The user's uid is zero (root). 5589536Seric ** 2. The user's login name is in an approved list (typically 5599536Seric ** from a network server). 5609536Seric ** 3. The address the user is trying to claim has a 5619536Seric ** "!" character in it (since #2 doesn't do it for 5629536Seric ** us if we are dialing out for UUCP). 5639536Seric ** A better check to replace #3 would be if the 5649536Seric ** effective uid is "UUCP" -- this would require me 5659536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5669536Seric ** make getname more nasty, do another passwd file 5679536Seric ** scan, or compile the UID of "UUCP" into the code, 5689536Seric ** all of which are reprehensible. 5699536Seric ** 5709536Seric ** Assuming all of these fail, we figure out something 5719536Seric ** ourselves. 5729536Seric ** 5739536Seric ** Parameters: 5749536Seric ** from -- the person we would like to believe this message 5759536Seric ** is from, as specified on the command line. 57653182Seric ** e -- the envelope in which we would like the sender set. 57758333Seric ** delimptr -- if non-NULL, set to the location of the 57858333Seric ** trailing delimiter. 57958704Seric ** internal -- set if this address is coming from an internal 58058704Seric ** source such as an owner alias. 5819536Seric ** 5829536Seric ** Returns: 58358704Seric ** none. 5849536Seric ** 5859536Seric ** Side Effects: 5869536Seric ** sets sendmail's notion of who the from person is. 5879536Seric */ 5889536Seric 58960494Seric void 59058704Seric setsender(from, e, delimptr, internal) 5919536Seric char *from; 59253182Seric register ENVELOPE *e; 59358333Seric char **delimptr; 59458704Seric bool internal; 5959536Seric { 5969536Seric register char **pvp; 5979536Seric char *realname = NULL; 59818665Seric register struct passwd *pw; 59958727Seric char delimchar; 60064147Seric char *bp; 60164147Seric char buf[MAXNAME + 2]; 60216913Seric char pvpbuf[PSBUFSIZE]; 60318665Seric extern struct passwd *getpwnam(); 6049536Seric extern char *FullName; 6059536Seric 6069536Seric if (tTd(45, 1)) 60714786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 6089536Seric 6099536Seric /* 6109536Seric ** Figure out the real user executing us. 6119536Seric ** Username can return errno != 0 on non-errors. 6129536Seric */ 6139536Seric 61465580Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 61565983Seric OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 6169536Seric realname = from; 6179536Seric if (realname == NULL || realname[0] == '\0') 6189536Seric realname = username(); 6199536Seric 62059027Seric if (ConfigLevel < 2) 62159027Seric SuprErrs = TRUE; 62259027Seric 62358727Seric delimchar = internal ? '\0' : ' '; 62464793Seric e->e_from.q_flags = QBADADDR; 62558333Seric if (from == NULL || 62664284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 62764793Seric delimchar, delimptr, e) == NULL || 62864793Seric bitset(QBADADDR, e->e_from.q_flags) || 62964793Seric e->e_from.q_mailer == ProgMailer || 63064793Seric e->e_from.q_mailer == FileMailer || 63164793Seric e->e_from.q_mailer == InclMailer) 6329536Seric { 63321750Seric /* log garbage addresses for traceback */ 63455173Seric # ifdef LOG 63558020Seric if (from != NULL && LogLevel > 2) 63621750Seric { 63758951Seric char *p; 63858951Seric char ebuf[MAXNAME * 2 + 2]; 63955173Seric 64058951Seric p = macvalue('_', e); 64158951Seric if (p == NULL) 64258951Seric { 64358951Seric char *host = RealHostName; 64458951Seric if (host == NULL) 64558951Seric host = MyHostName; 64658951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 64758951Seric p = ebuf; 64858951Seric } 64955173Seric syslog(LOG_NOTICE, 65064793Seric "setsender: %s: invalid or unparseable, received from %s", 65165015Seric shortenstring(from, 83), p); 65255173Seric } 65356795Seric # endif /* LOG */ 65457589Seric if (from != NULL) 65564793Seric { 65664793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 65764793Seric { 65864793Seric /* it was a bogus mailer in the from addr */ 65964793Seric usrerr("553 Invalid sender address"); 66064793Seric } 66157589Seric SuprErrs = TRUE; 66264793Seric } 66357589Seric if (from == realname || 66464284Seric parseaddr(from = newstr(realname), &e->e_from, 66564284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 66624944Seric { 66764793Seric char nbuf[100]; 66864793Seric 66957589Seric SuprErrs = TRUE; 67064808Seric expand("\201n", nbuf, &nbuf[sizeof nbuf], e); 67164793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 67264793Seric RF_COPYALL, ' ', NULL, e) == NULL && 67364793Seric parseaddr(from = "postmaster", &e->e_from, 67464793Seric RF_COPYALL, ' ', NULL, e) == NULL) 67558151Seric syserr("553 setsender: can't even parse postmaster!"); 67624944Seric } 6779536Seric } 6789536Seric else 6799536Seric FromFlag = TRUE; 68053182Seric e->e_from.q_flags |= QDONTSEND; 68157731Seric if (tTd(45, 5)) 68257731Seric { 68357731Seric printf("setsender: QDONTSEND "); 68457731Seric printaddr(&e->e_from, FALSE); 68557731Seric } 6869536Seric SuprErrs = FALSE; 6879536Seric 68867765Seric # ifdef USERDB 68967472Seric if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 6909536Seric { 69153736Seric register char *p; 69253736Seric extern char *udbsender(); 69317472Seric 69467765Seric p = udbsender(e->e_from.q_user); 69567765Seric if (p != NULL) 69667765Seric from = p; 69767765Seric } 69867765Seric # endif /* USERDB */ 69967765Seric 70067765Seric if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 70167765Seric { 70258704Seric if (!internal) 70358704Seric { 70467765Seric /* if the user already given fullname don't redefine */ 70558704Seric if (FullName == NULL) 70658704Seric FullName = macvalue('x', e); 70758704Seric if (FullName != NULL && FullName[0] == '\0') 70858704Seric FullName = NULL; 7099536Seric } 71053736Seric 71153736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 71253736Seric { 71353736Seric /* 71453736Seric ** Process passwd file entry. 71553736Seric */ 71653736Seric 71753736Seric /* extract home directory */ 71865822Seric if (strcmp(pw->pw_dir, "/") == 0) 71965822Seric e->e_from.q_home = newstr(""); 72065822Seric else 72165822Seric e->e_from.q_home = newstr(pw->pw_dir); 72253736Seric define('z', e->e_from.q_home, e); 72353736Seric 72453736Seric /* extract user and group id */ 72553736Seric e->e_from.q_uid = pw->pw_uid; 72653736Seric e->e_from.q_gid = pw->pw_gid; 72765023Seric e->e_from.q_flags |= QGOODUID; 72853736Seric 72953736Seric /* extract full name from passwd file */ 73053736Seric if (FullName == NULL && pw->pw_gecos != NULL && 73158704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 73258704Seric !internal) 73353736Seric { 73465015Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 73553736Seric if (buf[0] != '\0') 73653736Seric FullName = newstr(buf); 73753736Seric } 73853736Seric } 73958704Seric if (FullName != NULL && !internal) 74053182Seric define('x', FullName, e); 7419536Seric } 74265580Seric else if (!internal && OpMode != MD_DAEMON) 74311625Seric { 74453182Seric if (e->e_from.q_home == NULL) 74565822Seric { 74653182Seric e->e_from.q_home = getenv("HOME"); 74766049Seric if (e->e_from.q_home != NULL && 74866049Seric strcmp(e->e_from.q_home, "/") == 0) 74965822Seric e->e_from.q_home++; 75065822Seric } 75163787Seric e->e_from.q_uid = RealUid; 75263787Seric e->e_from.q_gid = RealGid; 75365023Seric e->e_from.q_flags |= QGOODUID; 75411625Seric } 75511625Seric 7569536Seric /* 7579536Seric ** Rewrite the from person to dispose of possible implicit 7589536Seric ** links in the net. 7599536Seric */ 7609536Seric 76167765Seric pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); 7629536Seric if (pvp == NULL) 7639536Seric { 76458403Seric /* don't need to give error -- prescan did that already */ 76536233Skarels # ifdef LOG 76658020Seric if (LogLevel > 2) 76736233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 76836233Skarels # endif 7699536Seric finis(); 7709536Seric } 77167765Seric /* 77265071Seric (void) rewrite(pvp, 3, 0, e); 77365071Seric (void) rewrite(pvp, 1, 0, e); 77465071Seric (void) rewrite(pvp, 4, 0, e); 77567765Seric */ 77664147Seric bp = buf + 1; 77764147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 77867619Seric if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 77964147Seric { 78064147Seric /* heuristic: route-addr: add angle brackets */ 78164147Seric strcat(bp, ">"); 78264147Seric *--bp = '<'; 78364147Seric } 78464147Seric e->e_sender = newstr(bp); 78558704Seric define('f', e->e_sender, e); 7869536Seric 7879536Seric /* save the domain spec if this mailer wants it */ 78865584Seric if (e->e_from.q_mailer != NULL && 78953182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 7909536Seric { 7919536Seric extern char **copyplist(); 7929536Seric 7939536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 7949536Seric pvp++; 7959536Seric if (*pvp != NULL) 79653182Seric e->e_fromdomain = copyplist(pvp, TRUE); 7979536Seric } 7989536Seric } 799