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*68002Seric static char sccsid[] = "@(#)envelope.c 8.48 (Berkeley) 11/28/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, 13167982Seric &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 && 239*68002Seric !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 24067981Seric strcmp(e->e_receiptto, "<>") != 0) 2419536Seric { 24210844Seric auto ADDRESS *rlist = NULL; 2439536Seric 24467880Seric e->e_flags |= EF_SENDRECEIPT; 24567982Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e); 24667963Seric (void) returntosender("Return receipt", rlist, return_yes, e); 2479536Seric } 24867682Seric e->e_flags &= ~EF_SENDRECEIPT; 2499536Seric 2509536Seric /* 2519536Seric ** Arrange to send error messages if there are fatal errors. 2529536Seric */ 2539536Seric 25467880Seric if (failure_return && e->e_errormode != EM_QUIET) 25567981Seric savemail(e, return_yes || (!return_no && e->e_class >= 0)); 2569536Seric 2579536Seric /* 25863849Seric ** Arrange to send warning messages to postmaster as requested. 25963849Seric */ 26063849Seric 26163849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 26264363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 26363849Seric { 26463849Seric auto ADDRESS *rlist = NULL; 26563849Seric 26667982Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); 26763849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 26863849Seric } 26963849Seric 27063849Seric /* 2719536Seric ** Instantiate or deinstantiate the queue. 2729536Seric */ 2739536Seric 2749536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2759536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2769536Seric { 27764307Seric if (tTd(50, 1)) 27867880Seric printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n", 27967880Seric e->e_id, queueit, e->e_flags); 28023497Seric if (e->e_df != NULL) 28123497Seric xunlink(e->e_df); 2829536Seric xunlink(queuename(e, 'q')); 28363839Seric 28463839Seric #ifdef LOG 28563839Seric if (LogLevel > 10) 28663839Seric syslog(LOG_INFO, "%s: done", id); 28763839Seric #endif 2889536Seric } 2899536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 29010754Seric { 29110754Seric #ifdef QUEUE 29264307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 29356795Seric #else /* QUEUE */ 29458151Seric syserr("554 dropenvelope: queueup"); 29556795Seric #endif /* QUEUE */ 29610754Seric } 2979536Seric 2989536Seric /* now unlock the job */ 29910196Seric closexscript(e); 3009536Seric unlockqueue(e); 3019536Seric 3029536Seric /* make sure that this envelope is marked unused */ 30324944Seric if (e->e_dfp != NULL) 30458680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 30510196Seric e->e_dfp = NULL; 30658680Seric e->e_id = e->e_df = NULL; 3079536Seric } 3089536Seric /* 3099536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 3109536Seric ** 3119536Seric ** This is normally used by a child process to get a clean 3129536Seric ** envelope without disturbing the parent. 3139536Seric ** 3149536Seric ** Parameters: 3159536Seric ** e -- the envelope to clear. 31625611Seric ** fullclear - if set, the current envelope is total 31725611Seric ** garbage and should be ignored; otherwise, 31825611Seric ** release any resources it may indicate. 3199536Seric ** 3209536Seric ** Returns: 3219536Seric ** none. 3229536Seric ** 3239536Seric ** Side Effects: 3249536Seric ** Closes files associated with the envelope. 3259536Seric ** Marks the envelope as unallocated. 3269536Seric */ 3279536Seric 32860494Seric void 32925611Seric clearenvelope(e, fullclear) 3309536Seric register ENVELOPE *e; 33125611Seric bool fullclear; 3329536Seric { 33325514Seric register HDR *bh; 33425514Seric register HDR **nhp; 33525514Seric extern ENVELOPE BlankEnvelope; 33625514Seric 33725611Seric if (!fullclear) 33825611Seric { 33925611Seric /* clear out any file information */ 34025611Seric if (e->e_xfp != NULL) 34158680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 34225611Seric if (e->e_dfp != NULL) 34358680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 34458680Seric e->e_xfp = e->e_dfp = NULL; 34525611Seric } 3469536Seric 34724961Seric /* now clear out the data */ 34824965Seric STRUCTCOPY(BlankEnvelope, *e); 34959698Seric if (Verbose) 35059698Seric e->e_sendmode = SM_DELIVER; 35125514Seric bh = BlankEnvelope.e_header; 35225514Seric nhp = &e->e_header; 35325514Seric while (bh != NULL) 35425514Seric { 35525514Seric *nhp = (HDR *) xalloc(sizeof *bh); 35625514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 35725514Seric bh = bh->h_link; 35825514Seric nhp = &(*nhp)->h_link; 35925514Seric } 3609536Seric } 3619536Seric /* 3629536Seric ** INITSYS -- initialize instantiation of system 3639536Seric ** 3649536Seric ** In Daemon mode, this is done in the child. 3659536Seric ** 3669536Seric ** Parameters: 3679536Seric ** none. 3689536Seric ** 3699536Seric ** Returns: 3709536Seric ** none. 3719536Seric ** 3729536Seric ** Side Effects: 3739536Seric ** Initializes the system macros, some global variables, 3749536Seric ** etc. In particular, the current time in various 3759536Seric ** forms is set. 3769536Seric */ 3779536Seric 37860494Seric void 37955012Seric initsys(e) 38055012Seric register ENVELOPE *e; 3819536Seric { 38264768Seric char cbuf[5]; /* holds hop count */ 38364768Seric char pbuf[10]; /* holds pid */ 38422963Smiriam #ifdef TTYNAME 38559304Seric static char ybuf[60]; /* holds tty id */ 3869536Seric register char *p; 38756795Seric #endif /* TTYNAME */ 3889536Seric extern char *ttyname(); 38960494Seric extern void settime(); 3909536Seric extern char Version[]; 3919536Seric 3929536Seric /* 3939536Seric ** Give this envelope a reality. 3949536Seric ** I.e., an id, a transcript, and a creation time. 3959536Seric */ 3969536Seric 39755012Seric openxscript(e); 39855012Seric e->e_ctime = curtime(); 3999536Seric 4009536Seric /* 4019536Seric ** Set OutChannel to something useful if stdout isn't it. 4029536Seric ** This arranges that any extra stuff the mailer produces 4039536Seric ** gets sent back to the user on error (because it is 4049536Seric ** tucked away in the transcript). 4059536Seric */ 4069536Seric 40764760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 40858737Seric e->e_xfp != NULL) 40955012Seric OutChannel = e->e_xfp; 4109536Seric 4119536Seric /* 4129536Seric ** Set up some basic system macros. 4139536Seric */ 4149536Seric 4159536Seric /* process id */ 4169536Seric (void) sprintf(pbuf, "%d", getpid()); 41764768Seric define('p', newstr(pbuf), e); 4189536Seric 4199536Seric /* hop count */ 42055012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 42164768Seric define('c', newstr(cbuf), e); 4229536Seric 4239536Seric /* time as integer, unix time, arpa time */ 42455012Seric settime(e); 4259536Seric 42617472Seric #ifdef TTYNAME 4279536Seric /* tty name */ 42855012Seric if (macvalue('y', e) == NULL) 4299536Seric { 4309536Seric p = ttyname(2); 4319536Seric if (p != NULL) 4329536Seric { 43356795Seric if (strrchr(p, '/') != NULL) 43456795Seric p = strrchr(p, '/') + 1; 4359536Seric (void) strcpy(ybuf, p); 43655012Seric define('y', ybuf, e); 4379536Seric } 4389536Seric } 43956795Seric #endif /* TTYNAME */ 4409536Seric } 4419536Seric /* 44211932Seric ** SETTIME -- set the current time. 44311932Seric ** 44411932Seric ** Parameters: 44511932Seric ** none. 44611932Seric ** 44711932Seric ** Returns: 44811932Seric ** none. 44911932Seric ** 45011932Seric ** Side Effects: 45111932Seric ** Sets the various time macros -- $a, $b, $d, $t. 45211932Seric */ 45311932Seric 45460494Seric void 45555012Seric settime(e) 45655012Seric register ENVELOPE *e; 45711932Seric { 45811932Seric register char *p; 45911932Seric auto time_t now; 46064768Seric char tbuf[20]; /* holds "current" time */ 46164768Seric char dbuf[30]; /* holds ctime(tbuf) */ 46211932Seric register struct tm *tm; 46311932Seric extern char *arpadate(); 46411932Seric extern struct tm *gmtime(); 46511932Seric 46611932Seric now = curtime(); 46711932Seric tm = gmtime(&now); 46857014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 46957014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 47064768Seric define('t', newstr(tbuf), e); 47111932Seric (void) strcpy(dbuf, ctime(&now)); 47258131Seric p = strchr(dbuf, '\n'); 47358131Seric if (p != NULL) 47458131Seric *p = '\0'; 47564768Seric define('d', newstr(dbuf), e); 47664086Seric p = arpadate(dbuf); 47764086Seric p = newstr(p); 47855012Seric if (macvalue('a', e) == NULL) 47955012Seric define('a', p, e); 48055012Seric define('b', p, e); 48111932Seric } 48211932Seric /* 4839536Seric ** OPENXSCRIPT -- Open transcript file 4849536Seric ** 4859536Seric ** Creates a transcript file for possible eventual mailing or 4869536Seric ** sending back. 4879536Seric ** 4889536Seric ** Parameters: 4899536Seric ** e -- the envelope to create the transcript in/for. 4909536Seric ** 4919536Seric ** Returns: 4929536Seric ** none 4939536Seric ** 4949536Seric ** Side Effects: 4959536Seric ** Creates the transcript file. 4969536Seric */ 4979536Seric 49858803Seric #ifndef O_APPEND 49958803Seric #define O_APPEND 0 50058803Seric #endif 50158803Seric 50260494Seric void 5039536Seric openxscript(e) 5049536Seric register ENVELOPE *e; 5059536Seric { 5069536Seric register char *p; 50740933Srick int fd; 5089536Seric 5099536Seric if (e->e_xfp != NULL) 5109536Seric return; 5119536Seric p = queuename(e, 'x'); 51258803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 51340933Srick if (fd < 0) 51463753Seric { 51563753Seric syserr("Can't create transcript file %s", p); 51663753Seric fd = open("/dev/null", O_WRONLY, 0644); 51763753Seric if (fd < 0) 51863753Seric syserr("!Can't open /dev/null"); 51963753Seric } 52063753Seric e->e_xfp = fdopen(fd, "w"); 52164724Seric if (e->e_xfp == NULL) 52264724Seric { 52364724Seric syserr("!Can't create transcript stream %s", p); 52464724Seric } 52564743Seric if (tTd(46, 9)) 52664743Seric { 52764743Seric printf("openxscript(%s):\n ", p); 52864743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 52964743Seric } 5309536Seric } 5319536Seric /* 53210196Seric ** CLOSEXSCRIPT -- close the transcript file. 53310196Seric ** 53410196Seric ** Parameters: 53510196Seric ** e -- the envelope containing the transcript to close. 53610196Seric ** 53710196Seric ** Returns: 53810196Seric ** none. 53910196Seric ** 54010196Seric ** Side Effects: 54110196Seric ** none. 54210196Seric */ 54310196Seric 54460494Seric void 54510196Seric closexscript(e) 54610196Seric register ENVELOPE *e; 54710196Seric { 54810196Seric if (e->e_xfp == NULL) 54910196Seric return; 55058680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 55110196Seric e->e_xfp = NULL; 55210196Seric } 55310196Seric /* 5549536Seric ** SETSENDER -- set the person who this message is from 5559536Seric ** 5569536Seric ** Under certain circumstances allow the user to say who 5579536Seric ** s/he is (using -f or -r). These are: 5589536Seric ** 1. The user's uid is zero (root). 5599536Seric ** 2. The user's login name is in an approved list (typically 5609536Seric ** from a network server). 5619536Seric ** 3. The address the user is trying to claim has a 5629536Seric ** "!" character in it (since #2 doesn't do it for 5639536Seric ** us if we are dialing out for UUCP). 5649536Seric ** A better check to replace #3 would be if the 5659536Seric ** effective uid is "UUCP" -- this would require me 5669536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5679536Seric ** make getname more nasty, do another passwd file 5689536Seric ** scan, or compile the UID of "UUCP" into the code, 5699536Seric ** all of which are reprehensible. 5709536Seric ** 5719536Seric ** Assuming all of these fail, we figure out something 5729536Seric ** ourselves. 5739536Seric ** 5749536Seric ** Parameters: 5759536Seric ** from -- the person we would like to believe this message 5769536Seric ** is from, as specified on the command line. 57753182Seric ** e -- the envelope in which we would like the sender set. 57858333Seric ** delimptr -- if non-NULL, set to the location of the 57958333Seric ** trailing delimiter. 58058704Seric ** internal -- set if this address is coming from an internal 58158704Seric ** source such as an owner alias. 5829536Seric ** 5839536Seric ** Returns: 58458704Seric ** none. 5859536Seric ** 5869536Seric ** Side Effects: 5879536Seric ** sets sendmail's notion of who the from person is. 5889536Seric */ 5899536Seric 59060494Seric void 59158704Seric setsender(from, e, delimptr, internal) 5929536Seric char *from; 59353182Seric register ENVELOPE *e; 59458333Seric char **delimptr; 59558704Seric bool internal; 5969536Seric { 5979536Seric register char **pvp; 5989536Seric char *realname = NULL; 59918665Seric register struct passwd *pw; 60058727Seric char delimchar; 60164147Seric char *bp; 60264147Seric char buf[MAXNAME + 2]; 60316913Seric char pvpbuf[PSBUFSIZE]; 60418665Seric extern struct passwd *getpwnam(); 6059536Seric extern char *FullName; 6069536Seric 6079536Seric if (tTd(45, 1)) 60814786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 6099536Seric 6109536Seric /* 6119536Seric ** Figure out the real user executing us. 6129536Seric ** Username can return errno != 0 on non-errors. 6139536Seric */ 6149536Seric 61565580Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 61665983Seric OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 6179536Seric realname = from; 6189536Seric if (realname == NULL || realname[0] == '\0') 6199536Seric realname = username(); 6209536Seric 62159027Seric if (ConfigLevel < 2) 62259027Seric SuprErrs = TRUE; 62359027Seric 62458727Seric delimchar = internal ? '\0' : ' '; 62564793Seric e->e_from.q_flags = QBADADDR; 62658333Seric if (from == NULL || 62764284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 62864793Seric delimchar, delimptr, e) == NULL || 62964793Seric bitset(QBADADDR, e->e_from.q_flags) || 63064793Seric e->e_from.q_mailer == ProgMailer || 63164793Seric e->e_from.q_mailer == FileMailer || 63264793Seric e->e_from.q_mailer == InclMailer) 6339536Seric { 63421750Seric /* log garbage addresses for traceback */ 63555173Seric # ifdef LOG 63658020Seric if (from != NULL && LogLevel > 2) 63721750Seric { 63858951Seric char *p; 63958951Seric char ebuf[MAXNAME * 2 + 2]; 64055173Seric 64158951Seric p = macvalue('_', e); 64258951Seric if (p == NULL) 64358951Seric { 64458951Seric char *host = RealHostName; 64558951Seric if (host == NULL) 64658951Seric host = MyHostName; 64758951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 64858951Seric p = ebuf; 64958951Seric } 65055173Seric syslog(LOG_NOTICE, 65164793Seric "setsender: %s: invalid or unparseable, received from %s", 65265015Seric shortenstring(from, 83), p); 65355173Seric } 65456795Seric # endif /* LOG */ 65557589Seric if (from != NULL) 65664793Seric { 65764793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 65864793Seric { 65964793Seric /* it was a bogus mailer in the from addr */ 66064793Seric usrerr("553 Invalid sender address"); 66164793Seric } 66257589Seric SuprErrs = TRUE; 66364793Seric } 66457589Seric if (from == realname || 66564284Seric parseaddr(from = newstr(realname), &e->e_from, 66664284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 66724944Seric { 66864793Seric char nbuf[100]; 66964793Seric 67057589Seric SuprErrs = TRUE; 67164808Seric expand("\201n", nbuf, &nbuf[sizeof nbuf], e); 67264793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 67364793Seric RF_COPYALL, ' ', NULL, e) == NULL && 67464793Seric parseaddr(from = "postmaster", &e->e_from, 67564793Seric RF_COPYALL, ' ', NULL, e) == NULL) 67658151Seric syserr("553 setsender: can't even parse postmaster!"); 67724944Seric } 6789536Seric } 6799536Seric else 6809536Seric FromFlag = TRUE; 68153182Seric e->e_from.q_flags |= QDONTSEND; 68257731Seric if (tTd(45, 5)) 68357731Seric { 68457731Seric printf("setsender: QDONTSEND "); 68557731Seric printaddr(&e->e_from, FALSE); 68657731Seric } 6879536Seric SuprErrs = FALSE; 6889536Seric 68967765Seric # ifdef USERDB 69067472Seric if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 6919536Seric { 69253736Seric register char *p; 69353736Seric extern char *udbsender(); 69417472Seric 69567765Seric p = udbsender(e->e_from.q_user); 69667765Seric if (p != NULL) 69767765Seric from = p; 69867765Seric } 69967765Seric # endif /* USERDB */ 70067765Seric 70167765Seric if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 70267765Seric { 70358704Seric if (!internal) 70458704Seric { 70567765Seric /* if the user already given fullname don't redefine */ 70658704Seric if (FullName == NULL) 70758704Seric FullName = macvalue('x', e); 70858704Seric if (FullName != NULL && FullName[0] == '\0') 70958704Seric FullName = NULL; 7109536Seric } 71153736Seric 71253736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 71353736Seric { 71453736Seric /* 71553736Seric ** Process passwd file entry. 71653736Seric */ 71753736Seric 71853736Seric /* extract home directory */ 71965822Seric if (strcmp(pw->pw_dir, "/") == 0) 72065822Seric e->e_from.q_home = newstr(""); 72165822Seric else 72265822Seric e->e_from.q_home = newstr(pw->pw_dir); 72353736Seric define('z', e->e_from.q_home, e); 72453736Seric 72553736Seric /* extract user and group id */ 72653736Seric e->e_from.q_uid = pw->pw_uid; 72753736Seric e->e_from.q_gid = pw->pw_gid; 72865023Seric e->e_from.q_flags |= QGOODUID; 72953736Seric 73053736Seric /* extract full name from passwd file */ 73153736Seric if (FullName == NULL && pw->pw_gecos != NULL && 73258704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 73358704Seric !internal) 73453736Seric { 73565015Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 73653736Seric if (buf[0] != '\0') 73753736Seric FullName = newstr(buf); 73853736Seric } 73953736Seric } 74058704Seric if (FullName != NULL && !internal) 74153182Seric define('x', FullName, e); 7429536Seric } 74365580Seric else if (!internal && OpMode != MD_DAEMON) 74411625Seric { 74553182Seric if (e->e_from.q_home == NULL) 74665822Seric { 74753182Seric e->e_from.q_home = getenv("HOME"); 74866049Seric if (e->e_from.q_home != NULL && 74966049Seric strcmp(e->e_from.q_home, "/") == 0) 75065822Seric e->e_from.q_home++; 75165822Seric } 75263787Seric e->e_from.q_uid = RealUid; 75363787Seric e->e_from.q_gid = RealGid; 75465023Seric e->e_from.q_flags |= QGOODUID; 75511625Seric } 75611625Seric 7579536Seric /* 7589536Seric ** Rewrite the from person to dispose of possible implicit 7599536Seric ** links in the net. 7609536Seric */ 7619536Seric 76267765Seric pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); 7639536Seric if (pvp == NULL) 7649536Seric { 76558403Seric /* don't need to give error -- prescan did that already */ 76636233Skarels # ifdef LOG 76758020Seric if (LogLevel > 2) 76836233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 76936233Skarels # endif 7709536Seric finis(); 7719536Seric } 77267765Seric /* 77365071Seric (void) rewrite(pvp, 3, 0, e); 77465071Seric (void) rewrite(pvp, 1, 0, e); 77565071Seric (void) rewrite(pvp, 4, 0, e); 77667765Seric */ 77764147Seric bp = buf + 1; 77864147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 77967619Seric if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 78064147Seric { 78164147Seric /* heuristic: route-addr: add angle brackets */ 78264147Seric strcat(bp, ">"); 78364147Seric *--bp = '<'; 78464147Seric } 78564147Seric e->e_sender = newstr(bp); 78658704Seric define('f', e->e_sender, e); 7879536Seric 7889536Seric /* save the domain spec if this mailer wants it */ 78965584Seric if (e->e_from.q_mailer != NULL && 79053182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 7919536Seric { 7929536Seric extern char **copyplist(); 7939536Seric 7949536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 7959536Seric pvp++; 7969536Seric if (*pvp != NULL) 79753182Seric e->e_fromdomain = copyplist(pvp, TRUE); 7989536Seric } 7999536Seric } 800