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*68559Seric static char sccsid[] = "@(#)envelope.c 8.53 (Berkeley) 03/21/95"; 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; 7768498Seric bool failure_return = FALSE; 7868498Seric bool success_return = FALSE; 799536Seric register ADDRESS *q; 8057943Seric char *id = e->e_id; 8163753Seric char buf[MAXLINE]; 829536Seric 839536Seric if (tTd(50, 1)) 849536Seric { 8558680Seric printf("dropenvelope %x: id=", e); 869536Seric xputs(e->e_id); 8765089Seric printf(", flags=0x%x\n", e->e_flags); 8863753Seric if (tTd(50, 10)) 8963753Seric { 9063753Seric printf("sendq="); 9163753Seric printaddr(e->e_sendqueue, TRUE); 9263753Seric } 939536Seric } 9457943Seric 9558680Seric /* we must have an id to remove disk files */ 9657943Seric if (id == NULL) 9758680Seric return; 9857943Seric 999536Seric #ifdef LOG 10065089Seric if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 10165089Seric logsender(e, NULL); 10258020Seric if (LogLevel > 84) 10365089Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d", 10457943Seric id, e->e_flags, getpid()); 10556795Seric #endif /* LOG */ 10665089Seric e->e_flags &= ~EF_LOGSENDER; 1079536Seric 10863753Seric /* post statistics */ 10963753Seric poststats(StatFile); 11063753Seric 1119536Seric /* 1129536Seric ** Extract state information from dregs of send list. 1139536Seric */ 1149536Seric 11564743Seric e->e_flags &= ~EF_QUEUERUN; 1169536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 1179536Seric { 1189536Seric if (bitset(QQUEUEUP, q->q_flags)) 1199536Seric queueit = TRUE; 12068498Seric 12168498Seric /* see if a notification is needed */ 12268498Seric if (e->e_df != NULL && 12368498Seric bitset(QBADADDR, q->q_flags) && 12468498Seric bitset(QPINGONFAILURE, q->q_flags)) 12563839Seric { 12668498Seric failure_return = TRUE; 12768498Seric if (q->q_owner == NULL && !emptyaddr(&e->e_from)) 12863839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 12968498Seric &e->e_errorqueue, 0, e); 13063839Seric } 13168498Seric else if (bitset(QSENT, q->q_flags) && 13268498Seric bitnset(M_LOCALMAILER, q->q_mailer->m_flags) && 13368498Seric bitset(QPINGONSUCCESS, q->q_flags)) 13468498Seric { 13568498Seric success_return = TRUE; 13668498Seric } 13768498Seric else if (bitset(QRELAYED, q->q_flags)) 13868498Seric { 13968498Seric success_return = TRUE; 14068498Seric } 14168498Seric else 142*68559Seric { 14368498Seric continue; 14468498Seric } 1459536Seric } 1469536Seric 147*68559Seric if (e->e_class < 0) 148*68559Seric e->e_flags |= EF_NO_BODY_RETN; 149*68559Seric 1509536Seric /* 15163753Seric ** See if the message timed out. 15263753Seric */ 15363753Seric 15463753Seric if (!queueit) 15563753Seric /* nothing to do */ ; 15668498Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 15763753Seric { 15863839Seric (void) sprintf(buf, "Cannot send message for %s", 15968498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 16063839Seric if (e->e_message != NULL) 16163839Seric free(e->e_message); 16263839Seric e->e_message = newstr(buf); 16363839Seric message(buf); 16463839Seric e->e_flags |= EF_CLRQUEUE; 16568498Seric failure_return = TRUE; 16663787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 16768498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 16863787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 16963787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 17063787Seric { 17163787Seric if (bitset(QQUEUEUP, q->q_flags)) 17263787Seric q->q_flags |= QBADADDR; 17363787Seric } 17463753Seric } 17568498Seric else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 17668498Seric curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) 17763753Seric { 17868498Seric bool delay_return = FALSE; 17968498Seric 18068498Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 18168498Seric { 18268498Seric if (bitset(QQUEUEUP, q->q_flags) && 18368498Seric bitset(QPINGONDELAY, q->q_flags)) 18468498Seric { 18568498Seric q->q_flags |= QREPORT; 18668498Seric delay_return = TRUE; 18768498Seric } 18868498Seric } 18968498Seric if (delay_return && 19068498Seric !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 19163753Seric e->e_class >= 0 && 19268498Seric strcmp(e->e_from.q_paddr, "<>") != 0 && 19368498Seric strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 19468498Seric (strlen(e->e_from.q_paddr) <= 8 || 19568498Seric strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) 19663753Seric { 19763753Seric (void) sprintf(buf, 19868498Seric "Warning: cannot send message for %s", 19968498Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 20063753Seric if (e->e_message != NULL) 20163753Seric free(e->e_message); 20263753Seric e->e_message = newstr(buf); 20363753Seric message(buf); 20463839Seric e->e_flags |= EF_WARNING; 20568498Seric failure_return = TRUE; 20663753Seric } 20763753Seric fprintf(e->e_xfp, 20863753Seric "Warning: message still undelivered after %s\n", 20968498Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 21063753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 21168498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 21268498Seric } 21368498Seric 21468498Seric if (tTd(50, 2)) 21568498Seric printf("failure_return=%d success_return=%d queueit=%d\n", 21668498Seric failure_return, success_return, queueit); 21768498Seric 21868498Seric /* 21968498Seric ** If we had some fatal error, but no addresses are marked as 22068498Seric ** bad, mark them _all_ as bad. 22168498Seric */ 22268498Seric 22368498Seric if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 22468498Seric { 22568498Seric failure_return = TRUE; 22668019Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 22768019Seric { 22868498Seric if (!bitset(QDONTSEND, q->q_flags)) 22968498Seric q->q_flags |= QBADADDR; 23068019Seric } 23168019Seric } 23268019Seric 23368019Seric /* 2349536Seric ** Send back return receipts as requested. 2359536Seric */ 2369536Seric 23768498Seric /* 23866783Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags) 23966783Seric && !bitset(PRIV_NORECEIPTS, PrivacyFlags)) 24068498Seric */ 24168498Seric if (e->e_receiptto == NULL) 24268498Seric e->e_receiptto = e->e_from.q_paddr; 24368498Seric if (success_return && !failure_return && 24468498Seric !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 24568498Seric strcmp(e->e_receiptto, "<>") != 0) 2469536Seric { 24710844Seric auto ADDRESS *rlist = NULL; 2489536Seric 24968498Seric e->e_flags |= EF_SENDRECEIPT; 25068498Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e); 251*68559Seric (void) returntosender("Return receipt", rlist, FALSE, e); 2529536Seric } 25368498Seric e->e_flags &= ~EF_SENDRECEIPT; 2549536Seric 2559536Seric /* 2569536Seric ** Arrange to send error messages if there are fatal errors. 2579536Seric */ 2589536Seric 25968498Seric if (failure_return && e->e_errormode != EM_QUIET) 260*68559Seric savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); 2619536Seric 2629536Seric /* 26363849Seric ** Arrange to send warning messages to postmaster as requested. 26463849Seric */ 26563849Seric 26663849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 26764363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 26863849Seric { 26963849Seric auto ADDRESS *rlist = NULL; 27063849Seric 27168498Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); 27263849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 27363849Seric } 27463849Seric 27563849Seric /* 2769536Seric ** Instantiate or deinstantiate the queue. 2779536Seric */ 2789536Seric 2799536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2809536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2819536Seric { 28264307Seric if (tTd(50, 1)) 28368498Seric printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n", 28468498Seric e->e_id, queueit, e->e_flags); 28523497Seric if (e->e_df != NULL) 28623497Seric xunlink(e->e_df); 2879536Seric xunlink(queuename(e, 'q')); 28863839Seric 28963839Seric #ifdef LOG 29063839Seric if (LogLevel > 10) 29163839Seric syslog(LOG_INFO, "%s: done", id); 29263839Seric #endif 2939536Seric } 2949536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 29510754Seric { 29610754Seric #ifdef QUEUE 29764307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 29856795Seric #else /* QUEUE */ 29958151Seric syserr("554 dropenvelope: queueup"); 30056795Seric #endif /* QUEUE */ 30110754Seric } 3029536Seric 3039536Seric /* now unlock the job */ 30410196Seric closexscript(e); 3059536Seric unlockqueue(e); 3069536Seric 3079536Seric /* make sure that this envelope is marked unused */ 30824944Seric if (e->e_dfp != NULL) 30958680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 31010196Seric e->e_dfp = NULL; 31158680Seric e->e_id = e->e_df = NULL; 3129536Seric } 3139536Seric /* 3149536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 3159536Seric ** 3169536Seric ** This is normally used by a child process to get a clean 3179536Seric ** envelope without disturbing the parent. 3189536Seric ** 3199536Seric ** Parameters: 3209536Seric ** e -- the envelope to clear. 32125611Seric ** fullclear - if set, the current envelope is total 32225611Seric ** garbage and should be ignored; otherwise, 32325611Seric ** release any resources it may indicate. 3249536Seric ** 3259536Seric ** Returns: 3269536Seric ** none. 3279536Seric ** 3289536Seric ** Side Effects: 3299536Seric ** Closes files associated with the envelope. 3309536Seric ** Marks the envelope as unallocated. 3319536Seric */ 3329536Seric 33360494Seric void 33425611Seric clearenvelope(e, fullclear) 3359536Seric register ENVELOPE *e; 33625611Seric bool fullclear; 3379536Seric { 33825514Seric register HDR *bh; 33925514Seric register HDR **nhp; 34025514Seric extern ENVELOPE BlankEnvelope; 34125514Seric 34225611Seric if (!fullclear) 34325611Seric { 34425611Seric /* clear out any file information */ 34525611Seric if (e->e_xfp != NULL) 34658680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 34725611Seric if (e->e_dfp != NULL) 34858680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 34958680Seric e->e_xfp = e->e_dfp = NULL; 35025611Seric } 3519536Seric 35224961Seric /* now clear out the data */ 35324965Seric STRUCTCOPY(BlankEnvelope, *e); 35459698Seric if (Verbose) 35559698Seric e->e_sendmode = SM_DELIVER; 35625514Seric bh = BlankEnvelope.e_header; 35725514Seric nhp = &e->e_header; 35825514Seric while (bh != NULL) 35925514Seric { 36025514Seric *nhp = (HDR *) xalloc(sizeof *bh); 36125514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 36225514Seric bh = bh->h_link; 36325514Seric nhp = &(*nhp)->h_link; 36425514Seric } 3659536Seric } 3669536Seric /* 3679536Seric ** INITSYS -- initialize instantiation of system 3689536Seric ** 3699536Seric ** In Daemon mode, this is done in the child. 3709536Seric ** 3719536Seric ** Parameters: 3729536Seric ** none. 3739536Seric ** 3749536Seric ** Returns: 3759536Seric ** none. 3769536Seric ** 3779536Seric ** Side Effects: 3789536Seric ** Initializes the system macros, some global variables, 3799536Seric ** etc. In particular, the current time in various 3809536Seric ** forms is set. 3819536Seric */ 3829536Seric 38360494Seric void 38455012Seric initsys(e) 38555012Seric register ENVELOPE *e; 3869536Seric { 38764768Seric char cbuf[5]; /* holds hop count */ 38864768Seric char pbuf[10]; /* holds pid */ 38922963Smiriam #ifdef TTYNAME 39059304Seric static char ybuf[60]; /* holds tty id */ 3919536Seric register char *p; 39256795Seric #endif /* TTYNAME */ 3939536Seric extern char *ttyname(); 39460494Seric extern void settime(); 3959536Seric extern char Version[]; 3969536Seric 3979536Seric /* 3989536Seric ** Give this envelope a reality. 3999536Seric ** I.e., an id, a transcript, and a creation time. 4009536Seric */ 4019536Seric 40255012Seric openxscript(e); 40355012Seric e->e_ctime = curtime(); 4049536Seric 4059536Seric /* 4069536Seric ** Set OutChannel to something useful if stdout isn't it. 4079536Seric ** This arranges that any extra stuff the mailer produces 4089536Seric ** gets sent back to the user on error (because it is 4099536Seric ** tucked away in the transcript). 4109536Seric */ 4119536Seric 41264760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 41358737Seric e->e_xfp != NULL) 41455012Seric OutChannel = e->e_xfp; 4159536Seric 4169536Seric /* 4179536Seric ** Set up some basic system macros. 4189536Seric */ 4199536Seric 4209536Seric /* process id */ 4219536Seric (void) sprintf(pbuf, "%d", getpid()); 42264768Seric define('p', newstr(pbuf), e); 4239536Seric 4249536Seric /* hop count */ 42555012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 42664768Seric define('c', newstr(cbuf), e); 4279536Seric 4289536Seric /* time as integer, unix time, arpa time */ 42955012Seric settime(e); 4309536Seric 43117472Seric #ifdef TTYNAME 4329536Seric /* tty name */ 43355012Seric if (macvalue('y', e) == NULL) 4349536Seric { 4359536Seric p = ttyname(2); 4369536Seric if (p != NULL) 4379536Seric { 43856795Seric if (strrchr(p, '/') != NULL) 43956795Seric p = strrchr(p, '/') + 1; 4409536Seric (void) strcpy(ybuf, p); 44155012Seric define('y', ybuf, e); 4429536Seric } 4439536Seric } 44456795Seric #endif /* TTYNAME */ 4459536Seric } 4469536Seric /* 44711932Seric ** SETTIME -- set the current time. 44811932Seric ** 44911932Seric ** Parameters: 45011932Seric ** none. 45111932Seric ** 45211932Seric ** Returns: 45311932Seric ** none. 45411932Seric ** 45511932Seric ** Side Effects: 45611932Seric ** Sets the various time macros -- $a, $b, $d, $t. 45711932Seric */ 45811932Seric 45960494Seric void 46055012Seric settime(e) 46155012Seric register ENVELOPE *e; 46211932Seric { 46311932Seric register char *p; 46411932Seric auto time_t now; 46564768Seric char tbuf[20]; /* holds "current" time */ 46664768Seric char dbuf[30]; /* holds ctime(tbuf) */ 46711932Seric register struct tm *tm; 46811932Seric extern char *arpadate(); 46911932Seric extern struct tm *gmtime(); 47011932Seric 47111932Seric now = curtime(); 47211932Seric tm = gmtime(&now); 47357014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 47457014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 47564768Seric define('t', newstr(tbuf), e); 47611932Seric (void) strcpy(dbuf, ctime(&now)); 47758131Seric p = strchr(dbuf, '\n'); 47858131Seric if (p != NULL) 47958131Seric *p = '\0'; 48064768Seric define('d', newstr(dbuf), e); 48164086Seric p = arpadate(dbuf); 48264086Seric p = newstr(p); 48355012Seric if (macvalue('a', e) == NULL) 48455012Seric define('a', p, e); 48555012Seric define('b', p, e); 48611932Seric } 48711932Seric /* 4889536Seric ** OPENXSCRIPT -- Open transcript file 4899536Seric ** 4909536Seric ** Creates a transcript file for possible eventual mailing or 4919536Seric ** sending back. 4929536Seric ** 4939536Seric ** Parameters: 4949536Seric ** e -- the envelope to create the transcript in/for. 4959536Seric ** 4969536Seric ** Returns: 4979536Seric ** none 4989536Seric ** 4999536Seric ** Side Effects: 5009536Seric ** Creates the transcript file. 5019536Seric */ 5029536Seric 50358803Seric #ifndef O_APPEND 50458803Seric #define O_APPEND 0 50558803Seric #endif 50658803Seric 50760494Seric void 5089536Seric openxscript(e) 5099536Seric register ENVELOPE *e; 5109536Seric { 5119536Seric register char *p; 51240933Srick int fd; 5139536Seric 5149536Seric if (e->e_xfp != NULL) 5159536Seric return; 5169536Seric p = queuename(e, 'x'); 51758803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 51840933Srick if (fd < 0) 51963753Seric { 52063753Seric syserr("Can't create transcript file %s", p); 52163753Seric fd = open("/dev/null", O_WRONLY, 0644); 52263753Seric if (fd < 0) 52363753Seric syserr("!Can't open /dev/null"); 52463753Seric } 52568352Seric e->e_xfp = fdopen(fd, "a"); 52664724Seric if (e->e_xfp == NULL) 52764724Seric syserr("!Can't create transcript stream %s", p); 52868498Seric #ifdef HASSETVBUF 52968498Seric setvbuf(e->e_xfp, NULL, _IOLBF, 0); 53068498Seric #else 53168498Seric setlinebuf(e->e_xfp); 53268498Seric #endif 53364743Seric if (tTd(46, 9)) 53464743Seric { 53564743Seric printf("openxscript(%s):\n ", p); 53664743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 53764743Seric } 5389536Seric } 5399536Seric /* 54010196Seric ** CLOSEXSCRIPT -- close the transcript file. 54110196Seric ** 54210196Seric ** Parameters: 54310196Seric ** e -- the envelope containing the transcript to close. 54410196Seric ** 54510196Seric ** Returns: 54610196Seric ** none. 54710196Seric ** 54810196Seric ** Side Effects: 54910196Seric ** none. 55010196Seric */ 55110196Seric 55260494Seric void 55310196Seric closexscript(e) 55410196Seric register ENVELOPE *e; 55510196Seric { 55610196Seric if (e->e_xfp == NULL) 55710196Seric return; 55858680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 55910196Seric e->e_xfp = NULL; 56010196Seric } 56110196Seric /* 5629536Seric ** SETSENDER -- set the person who this message is from 5639536Seric ** 5649536Seric ** Under certain circumstances allow the user to say who 5659536Seric ** s/he is (using -f or -r). These are: 5669536Seric ** 1. The user's uid is zero (root). 5679536Seric ** 2. The user's login name is in an approved list (typically 5689536Seric ** from a network server). 5699536Seric ** 3. The address the user is trying to claim has a 5709536Seric ** "!" character in it (since #2 doesn't do it for 5719536Seric ** us if we are dialing out for UUCP). 5729536Seric ** A better check to replace #3 would be if the 5739536Seric ** effective uid is "UUCP" -- this would require me 5749536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5759536Seric ** make getname more nasty, do another passwd file 5769536Seric ** scan, or compile the UID of "UUCP" into the code, 5779536Seric ** all of which are reprehensible. 5789536Seric ** 5799536Seric ** Assuming all of these fail, we figure out something 5809536Seric ** ourselves. 5819536Seric ** 5829536Seric ** Parameters: 5839536Seric ** from -- the person we would like to believe this message 5849536Seric ** is from, as specified on the command line. 58553182Seric ** e -- the envelope in which we would like the sender set. 58658333Seric ** delimptr -- if non-NULL, set to the location of the 58758333Seric ** trailing delimiter. 58858704Seric ** internal -- set if this address is coming from an internal 58958704Seric ** source such as an owner alias. 5909536Seric ** 5919536Seric ** Returns: 59258704Seric ** none. 5939536Seric ** 5949536Seric ** Side Effects: 5959536Seric ** sets sendmail's notion of who the from person is. 5969536Seric */ 5979536Seric 59860494Seric void 59958704Seric setsender(from, e, delimptr, internal) 6009536Seric char *from; 60153182Seric register ENVELOPE *e; 60258333Seric char **delimptr; 60358704Seric bool internal; 6049536Seric { 6059536Seric register char **pvp; 6069536Seric char *realname = NULL; 60718665Seric register struct passwd *pw; 60858727Seric char delimchar; 60964147Seric char *bp; 61064147Seric char buf[MAXNAME + 2]; 61116913Seric char pvpbuf[PSBUFSIZE]; 61218665Seric extern struct passwd *getpwnam(); 6139536Seric extern char *FullName; 6149536Seric 6159536Seric if (tTd(45, 1)) 61614786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 6179536Seric 6189536Seric /* 6199536Seric ** Figure out the real user executing us. 6209536Seric ** Username can return errno != 0 on non-errors. 6219536Seric */ 6229536Seric 62365580Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 62465983Seric OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 6259536Seric realname = from; 6269536Seric if (realname == NULL || realname[0] == '\0') 6279536Seric realname = username(); 6289536Seric 62959027Seric if (ConfigLevel < 2) 63059027Seric SuprErrs = TRUE; 63159027Seric 63258727Seric delimchar = internal ? '\0' : ' '; 63364793Seric e->e_from.q_flags = QBADADDR; 63458333Seric if (from == NULL || 63564284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 63664793Seric delimchar, delimptr, e) == NULL || 63764793Seric bitset(QBADADDR, e->e_from.q_flags) || 63864793Seric e->e_from.q_mailer == ProgMailer || 63964793Seric e->e_from.q_mailer == FileMailer || 64064793Seric e->e_from.q_mailer == InclMailer) 6419536Seric { 64221750Seric /* log garbage addresses for traceback */ 64355173Seric # ifdef LOG 64458020Seric if (from != NULL && LogLevel > 2) 64521750Seric { 64658951Seric char *p; 64758951Seric char ebuf[MAXNAME * 2 + 2]; 64855173Seric 64958951Seric p = macvalue('_', e); 65058951Seric if (p == NULL) 65158951Seric { 65258951Seric char *host = RealHostName; 65358951Seric if (host == NULL) 65458951Seric host = MyHostName; 65558951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 65658951Seric p = ebuf; 65758951Seric } 65855173Seric syslog(LOG_NOTICE, 65964793Seric "setsender: %s: invalid or unparseable, received from %s", 66065015Seric shortenstring(from, 83), p); 66155173Seric } 66256795Seric # endif /* LOG */ 66357589Seric if (from != NULL) 66464793Seric { 66564793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 66664793Seric { 66764793Seric /* it was a bogus mailer in the from addr */ 66864793Seric usrerr("553 Invalid sender address"); 66964793Seric } 67057589Seric SuprErrs = TRUE; 67164793Seric } 67257589Seric if (from == realname || 67364284Seric parseaddr(from = newstr(realname), &e->e_from, 67464284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 67524944Seric { 67664793Seric char nbuf[100]; 67764793Seric 67857589Seric SuprErrs = TRUE; 67968529Seric expand("\201n", nbuf, sizeof nbuf, e); 68064793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 68164793Seric RF_COPYALL, ' ', NULL, e) == NULL && 68264793Seric parseaddr(from = "postmaster", &e->e_from, 68364793Seric RF_COPYALL, ' ', NULL, e) == NULL) 68458151Seric syserr("553 setsender: can't even parse postmaster!"); 68524944Seric } 6869536Seric } 6879536Seric else 6889536Seric FromFlag = TRUE; 68953182Seric e->e_from.q_flags |= QDONTSEND; 69057731Seric if (tTd(45, 5)) 69157731Seric { 69257731Seric printf("setsender: QDONTSEND "); 69357731Seric printaddr(&e->e_from, FALSE); 69457731Seric } 6959536Seric SuprErrs = FALSE; 6969536Seric 69768498Seric # ifdef USERDB 69868498Seric if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 69968460Seric { 70053736Seric register char *p; 70153736Seric extern char *udbsender(); 70217472Seric 70368498Seric p = udbsender(e->e_from.q_user); 70468498Seric if (p != NULL) 70568498Seric from = p; 70668498Seric } 70768498Seric # endif /* USERDB */ 70868498Seric 70968498Seric if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 71068498Seric { 71158704Seric if (!internal) 71258704Seric { 71368498Seric /* if the user already given fullname don't redefine */ 71458704Seric if (FullName == NULL) 71558704Seric FullName = macvalue('x', e); 71658704Seric if (FullName != NULL && FullName[0] == '\0') 71758704Seric FullName = NULL; 7189536Seric } 71953736Seric 72053736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 72153736Seric { 72253736Seric /* 72353736Seric ** Process passwd file entry. 72453736Seric */ 72553736Seric 72653736Seric /* extract home directory */ 72765822Seric if (strcmp(pw->pw_dir, "/") == 0) 72865822Seric e->e_from.q_home = newstr(""); 72965822Seric else 73065822Seric e->e_from.q_home = newstr(pw->pw_dir); 73153736Seric define('z', e->e_from.q_home, e); 73253736Seric 73353736Seric /* extract user and group id */ 73453736Seric e->e_from.q_uid = pw->pw_uid; 73553736Seric e->e_from.q_gid = pw->pw_gid; 73665023Seric e->e_from.q_flags |= QGOODUID; 73753736Seric 73853736Seric /* extract full name from passwd file */ 73953736Seric if (FullName == NULL && pw->pw_gecos != NULL && 74058704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 74158704Seric !internal) 74253736Seric { 74365015Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 74453736Seric if (buf[0] != '\0') 74553736Seric FullName = newstr(buf); 74653736Seric } 74753736Seric } 74858704Seric if (FullName != NULL && !internal) 74953182Seric define('x', FullName, e); 7509536Seric } 75165580Seric else if (!internal && OpMode != MD_DAEMON) 75211625Seric { 75353182Seric if (e->e_from.q_home == NULL) 75465822Seric { 75553182Seric e->e_from.q_home = getenv("HOME"); 75666049Seric if (e->e_from.q_home != NULL && 75766049Seric strcmp(e->e_from.q_home, "/") == 0) 75865822Seric e->e_from.q_home++; 75965822Seric } 76063787Seric e->e_from.q_uid = RealUid; 76163787Seric e->e_from.q_gid = RealGid; 76265023Seric e->e_from.q_flags |= QGOODUID; 76311625Seric } 76411625Seric 7659536Seric /* 7669536Seric ** Rewrite the from person to dispose of possible implicit 7679536Seric ** links in the net. 7689536Seric */ 7699536Seric 77068498Seric pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); 7719536Seric if (pvp == NULL) 7729536Seric { 77358403Seric /* don't need to give error -- prescan did that already */ 77436233Skarels # ifdef LOG 77558020Seric if (LogLevel > 2) 77636233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 77736233Skarels # endif 7789536Seric finis(); 7799536Seric } 78068498Seric /* 78165071Seric (void) rewrite(pvp, 3, 0, e); 78265071Seric (void) rewrite(pvp, 1, 0, e); 78365071Seric (void) rewrite(pvp, 4, 0, e); 78468498Seric */ 78564147Seric bp = buf + 1; 78664147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 78768498Seric if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 78864147Seric { 78964147Seric /* heuristic: route-addr: add angle brackets */ 79064147Seric strcat(bp, ">"); 79164147Seric *--bp = '<'; 79264147Seric } 79364147Seric e->e_sender = newstr(bp); 79458704Seric define('f', e->e_sender, e); 7959536Seric 7969536Seric /* save the domain spec if this mailer wants it */ 79765584Seric if (e->e_from.q_mailer != NULL && 79853182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 7999536Seric { 8009536Seric extern char **copyplist(); 8019536Seric 8029536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 8039536Seric pvp++; 8049536Seric if (*pvp != NULL) 80553182Seric e->e_fromdomain = copyplist(pvp, TRUE); 8069536Seric } 8079536Seric } 808