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*68567Seric static char sccsid[] = "@(#)envelope.c 8.55 (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 { 85*68567Seric extern void printenvflags(); 86*68567Seric 8758680Seric printf("dropenvelope %x: id=", e); 889536Seric xputs(e->e_id); 89*68567Seric printf(", flags="); 90*68567Seric printenvflags(e); 9163753Seric if (tTd(50, 10)) 9263753Seric { 9363753Seric printf("sendq="); 9463753Seric printaddr(e->e_sendqueue, TRUE); 9563753Seric } 969536Seric } 9757943Seric 9858680Seric /* we must have an id to remove disk files */ 9957943Seric if (id == NULL) 10058680Seric return; 10157943Seric 1029536Seric #ifdef LOG 10365089Seric if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) 10465089Seric logsender(e, NULL); 10558020Seric if (LogLevel > 84) 10665089Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d", 10757943Seric id, e->e_flags, getpid()); 10856795Seric #endif /* LOG */ 10965089Seric e->e_flags &= ~EF_LOGSENDER; 1109536Seric 11163753Seric /* post statistics */ 11263753Seric poststats(StatFile); 11363753Seric 1149536Seric /* 1159536Seric ** Extract state information from dregs of send list. 1169536Seric */ 1179536Seric 11864743Seric e->e_flags &= ~EF_QUEUERUN; 1199536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 1209536Seric { 1219536Seric if (bitset(QQUEUEUP, q->q_flags)) 1229536Seric queueit = TRUE; 12368498Seric 12468498Seric /* see if a notification is needed */ 12568564Seric if (bitset(QBADADDR, q->q_flags) && 12668498Seric bitset(QPINGONFAILURE, q->q_flags)) 12763839Seric { 12868498Seric failure_return = TRUE; 12968498Seric if (q->q_owner == NULL && !emptyaddr(&e->e_from)) 13063839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 13168498Seric &e->e_errorqueue, 0, e); 13263839Seric } 13368498Seric else if (bitset(QSENT, q->q_flags) && 13468498Seric bitnset(M_LOCALMAILER, q->q_mailer->m_flags) && 13568498Seric bitset(QPINGONSUCCESS, q->q_flags)) 13668498Seric { 13768498Seric success_return = TRUE; 13868498Seric } 13968498Seric else if (bitset(QRELAYED, q->q_flags)) 14068498Seric { 14168498Seric success_return = TRUE; 14268498Seric } 14368498Seric else 14468559Seric { 14568498Seric continue; 14668498Seric } 1479536Seric } 1489536Seric 14968559Seric if (e->e_class < 0) 15068559Seric e->e_flags |= EF_NO_BODY_RETN; 15168559Seric 1529536Seric /* 15363753Seric ** See if the message timed out. 15463753Seric */ 15563753Seric 15663753Seric if (!queueit) 15763753Seric /* nothing to do */ ; 15868498Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) 15963753Seric { 16063839Seric (void) sprintf(buf, "Cannot send message for %s", 16168498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 16263839Seric if (e->e_message != NULL) 16363839Seric free(e->e_message); 16463839Seric e->e_message = newstr(buf); 16563839Seric message(buf); 16663839Seric e->e_flags |= EF_CLRQUEUE; 16768498Seric failure_return = TRUE; 16863787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 16968498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 17063787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 17163787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 17263787Seric { 17363787Seric if (bitset(QQUEUEUP, q->q_flags)) 17463787Seric q->q_flags |= QBADADDR; 17563787Seric } 17663753Seric } 17768498Seric else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && 17868498Seric curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) 17963753Seric { 18068498Seric bool delay_return = FALSE; 18168498Seric 18268498Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 18368498Seric { 18468498Seric if (bitset(QQUEUEUP, q->q_flags) && 18568498Seric bitset(QPINGONDELAY, q->q_flags)) 18668498Seric { 18768498Seric q->q_flags |= QREPORT; 18868498Seric delay_return = TRUE; 18968498Seric } 19068498Seric } 19168498Seric if (delay_return && 19268498Seric !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 19363753Seric e->e_class >= 0 && 19468498Seric strcmp(e->e_from.q_paddr, "<>") != 0 && 19568498Seric strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 && 19668498Seric (strlen(e->e_from.q_paddr) <= 8 || 19768498Seric strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0)) 19863753Seric { 19963753Seric (void) sprintf(buf, 20068498Seric "Warning: cannot send message for %s", 20168498Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 20263753Seric if (e->e_message != NULL) 20363753Seric free(e->e_message); 20463753Seric e->e_message = newstr(buf); 20563753Seric message(buf); 20663839Seric e->e_flags |= EF_WARNING; 20768498Seric failure_return = TRUE; 20863753Seric } 20963753Seric fprintf(e->e_xfp, 21063753Seric "Warning: message still undelivered after %s\n", 21168498Seric pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE)); 21263753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 21368498Seric pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE)); 21468498Seric } 21568498Seric 21668498Seric if (tTd(50, 2)) 21768498Seric printf("failure_return=%d success_return=%d queueit=%d\n", 21868498Seric failure_return, success_return, queueit); 21968498Seric 22068498Seric /* 22168498Seric ** If we had some fatal error, but no addresses are marked as 22268498Seric ** bad, mark them _all_ as bad. 22368498Seric */ 22468498Seric 22568498Seric if (bitset(EF_FATALERRS, e->e_flags) && !failure_return) 22668498Seric { 22768498Seric failure_return = TRUE; 22868019Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 22968019Seric { 23068498Seric if (!bitset(QDONTSEND, q->q_flags)) 23168498Seric q->q_flags |= QBADADDR; 23268019Seric } 23368019Seric } 23468019Seric 23568019Seric /* 2369536Seric ** Send back return receipts as requested. 2379536Seric */ 2389536Seric 23968498Seric /* 24066783Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags) 24166783Seric && !bitset(PRIV_NORECEIPTS, PrivacyFlags)) 24268498Seric */ 24368498Seric if (e->e_receiptto == NULL) 24468498Seric e->e_receiptto = e->e_from.q_paddr; 24568498Seric if (success_return && !failure_return && 24668498Seric !bitset(PRIV_NORECEIPTS, PrivacyFlags) && 24768498Seric strcmp(e->e_receiptto, "<>") != 0) 2489536Seric { 24910844Seric auto ADDRESS *rlist = NULL; 2509536Seric 25168498Seric e->e_flags |= EF_SENDRECEIPT; 25268498Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e); 25368559Seric (void) returntosender("Return receipt", rlist, FALSE, e); 2549536Seric } 25568498Seric e->e_flags &= ~EF_SENDRECEIPT; 2569536Seric 2579536Seric /* 2589536Seric ** Arrange to send error messages if there are fatal errors. 2599536Seric */ 2609536Seric 26168498Seric if (failure_return && e->e_errormode != EM_QUIET) 26268559Seric savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); 2639536Seric 2649536Seric /* 26563849Seric ** Arrange to send warning messages to postmaster as requested. 26663849Seric */ 26763849Seric 26863849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 26964363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 27063849Seric { 27163849Seric auto ADDRESS *rlist = NULL; 27263849Seric 27368498Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e); 27463849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 27563849Seric } 27663849Seric 27763849Seric /* 2789536Seric ** Instantiate or deinstantiate the queue. 2799536Seric */ 2809536Seric 2819536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2829536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2839536Seric { 28464307Seric if (tTd(50, 1)) 285*68567Seric { 286*68567Seric extern void printenvflags(); 287*68567Seric 288*68567Seric printf("\n===== Dropping [dq]f%s... queueit=%d, e_flags=", 289*68567Seric e->e_id, queueit); 290*68567Seric printenvflags(e); 291*68567Seric } 29268564Seric xunlink(queuename(e, 'd')); 2939536Seric xunlink(queuename(e, 'q')); 29463839Seric 29563839Seric #ifdef LOG 29663839Seric if (LogLevel > 10) 29763839Seric syslog(LOG_INFO, "%s: done", id); 29863839Seric #endif 2999536Seric } 3009536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 30110754Seric { 30210754Seric #ifdef QUEUE 30364307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 30456795Seric #else /* QUEUE */ 30558151Seric syserr("554 dropenvelope: queueup"); 30656795Seric #endif /* QUEUE */ 30710754Seric } 3089536Seric 3099536Seric /* now unlock the job */ 31010196Seric closexscript(e); 3119536Seric unlockqueue(e); 3129536Seric 3139536Seric /* make sure that this envelope is marked unused */ 31424944Seric if (e->e_dfp != NULL) 31568564Seric (void) xfclose(e->e_dfp, "dropenvelope df", e->e_id); 31610196Seric e->e_dfp = NULL; 31768564Seric e->e_id = NULL; 31868564Seric e->e_flags &= ~EF_HAS_DF; 3199536Seric } 3209536Seric /* 3219536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 3229536Seric ** 3239536Seric ** This is normally used by a child process to get a clean 3249536Seric ** envelope without disturbing the parent. 3259536Seric ** 3269536Seric ** Parameters: 3279536Seric ** e -- the envelope to clear. 32825611Seric ** fullclear - if set, the current envelope is total 32925611Seric ** garbage and should be ignored; otherwise, 33025611Seric ** release any resources it may indicate. 3319536Seric ** 3329536Seric ** Returns: 3339536Seric ** none. 3349536Seric ** 3359536Seric ** Side Effects: 3369536Seric ** Closes files associated with the envelope. 3379536Seric ** Marks the envelope as unallocated. 3389536Seric */ 3399536Seric 34060494Seric void 34125611Seric clearenvelope(e, fullclear) 3429536Seric register ENVELOPE *e; 34325611Seric bool fullclear; 3449536Seric { 34525514Seric register HDR *bh; 34625514Seric register HDR **nhp; 34725514Seric extern ENVELOPE BlankEnvelope; 34825514Seric 34925611Seric if (!fullclear) 35025611Seric { 35125611Seric /* clear out any file information */ 35225611Seric if (e->e_xfp != NULL) 35358680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 35425611Seric if (e->e_dfp != NULL) 35568564Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_id); 35658680Seric e->e_xfp = e->e_dfp = NULL; 35725611Seric } 3589536Seric 35924961Seric /* now clear out the data */ 36024965Seric STRUCTCOPY(BlankEnvelope, *e); 36159698Seric if (Verbose) 36259698Seric e->e_sendmode = SM_DELIVER; 36325514Seric bh = BlankEnvelope.e_header; 36425514Seric nhp = &e->e_header; 36525514Seric while (bh != NULL) 36625514Seric { 36725514Seric *nhp = (HDR *) xalloc(sizeof *bh); 36825514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 36925514Seric bh = bh->h_link; 37025514Seric nhp = &(*nhp)->h_link; 37125514Seric } 3729536Seric } 3739536Seric /* 3749536Seric ** INITSYS -- initialize instantiation of system 3759536Seric ** 3769536Seric ** In Daemon mode, this is done in the child. 3779536Seric ** 3789536Seric ** Parameters: 3799536Seric ** none. 3809536Seric ** 3819536Seric ** Returns: 3829536Seric ** none. 3839536Seric ** 3849536Seric ** Side Effects: 3859536Seric ** Initializes the system macros, some global variables, 3869536Seric ** etc. In particular, the current time in various 3879536Seric ** forms is set. 3889536Seric */ 3899536Seric 39060494Seric void 39155012Seric initsys(e) 39255012Seric register ENVELOPE *e; 3939536Seric { 39464768Seric char cbuf[5]; /* holds hop count */ 39564768Seric char pbuf[10]; /* holds pid */ 39622963Smiriam #ifdef TTYNAME 39759304Seric static char ybuf[60]; /* holds tty id */ 3989536Seric register char *p; 39956795Seric #endif /* TTYNAME */ 4009536Seric extern char *ttyname(); 40160494Seric extern void settime(); 4029536Seric extern char Version[]; 4039536Seric 4049536Seric /* 4059536Seric ** Give this envelope a reality. 4069536Seric ** I.e., an id, a transcript, and a creation time. 4079536Seric */ 4089536Seric 40955012Seric openxscript(e); 41055012Seric e->e_ctime = curtime(); 4119536Seric 4129536Seric /* 4139536Seric ** Set OutChannel to something useful if stdout isn't it. 4149536Seric ** This arranges that any extra stuff the mailer produces 4159536Seric ** gets sent back to the user on error (because it is 4169536Seric ** tucked away in the transcript). 4179536Seric */ 4189536Seric 41964760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 42058737Seric e->e_xfp != NULL) 42155012Seric OutChannel = e->e_xfp; 4229536Seric 4239536Seric /* 4249536Seric ** Set up some basic system macros. 4259536Seric */ 4269536Seric 4279536Seric /* process id */ 4289536Seric (void) sprintf(pbuf, "%d", getpid()); 42964768Seric define('p', newstr(pbuf), e); 4309536Seric 4319536Seric /* hop count */ 43255012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 43364768Seric define('c', newstr(cbuf), e); 4349536Seric 4359536Seric /* time as integer, unix time, arpa time */ 43655012Seric settime(e); 4379536Seric 43817472Seric #ifdef TTYNAME 4399536Seric /* tty name */ 44055012Seric if (macvalue('y', e) == NULL) 4419536Seric { 4429536Seric p = ttyname(2); 4439536Seric if (p != NULL) 4449536Seric { 44556795Seric if (strrchr(p, '/') != NULL) 44656795Seric p = strrchr(p, '/') + 1; 4479536Seric (void) strcpy(ybuf, p); 44855012Seric define('y', ybuf, e); 4499536Seric } 4509536Seric } 45156795Seric #endif /* TTYNAME */ 4529536Seric } 4539536Seric /* 45411932Seric ** SETTIME -- set the current time. 45511932Seric ** 45611932Seric ** Parameters: 45711932Seric ** none. 45811932Seric ** 45911932Seric ** Returns: 46011932Seric ** none. 46111932Seric ** 46211932Seric ** Side Effects: 46311932Seric ** Sets the various time macros -- $a, $b, $d, $t. 46411932Seric */ 46511932Seric 46660494Seric void 46755012Seric settime(e) 46855012Seric register ENVELOPE *e; 46911932Seric { 47011932Seric register char *p; 47111932Seric auto time_t now; 47264768Seric char tbuf[20]; /* holds "current" time */ 47364768Seric char dbuf[30]; /* holds ctime(tbuf) */ 47411932Seric register struct tm *tm; 47511932Seric extern char *arpadate(); 47611932Seric extern struct tm *gmtime(); 47711932Seric 47811932Seric now = curtime(); 47911932Seric tm = gmtime(&now); 48057014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 48157014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 48264768Seric define('t', newstr(tbuf), e); 48311932Seric (void) strcpy(dbuf, ctime(&now)); 48458131Seric p = strchr(dbuf, '\n'); 48558131Seric if (p != NULL) 48658131Seric *p = '\0'; 48764768Seric define('d', newstr(dbuf), e); 48864086Seric p = arpadate(dbuf); 48964086Seric p = newstr(p); 49055012Seric if (macvalue('a', e) == NULL) 49155012Seric define('a', p, e); 49255012Seric define('b', p, e); 49311932Seric } 49411932Seric /* 4959536Seric ** OPENXSCRIPT -- Open transcript file 4969536Seric ** 4979536Seric ** Creates a transcript file for possible eventual mailing or 4989536Seric ** sending back. 4999536Seric ** 5009536Seric ** Parameters: 5019536Seric ** e -- the envelope to create the transcript in/for. 5029536Seric ** 5039536Seric ** Returns: 5049536Seric ** none 5059536Seric ** 5069536Seric ** Side Effects: 5079536Seric ** Creates the transcript file. 5089536Seric */ 5099536Seric 51058803Seric #ifndef O_APPEND 51158803Seric #define O_APPEND 0 51258803Seric #endif 51358803Seric 51460494Seric void 5159536Seric openxscript(e) 5169536Seric register ENVELOPE *e; 5179536Seric { 5189536Seric register char *p; 51940933Srick int fd; 5209536Seric 5219536Seric if (e->e_xfp != NULL) 5229536Seric return; 5239536Seric p = queuename(e, 'x'); 52458803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 52540933Srick if (fd < 0) 52663753Seric { 52763753Seric syserr("Can't create transcript file %s", p); 52863753Seric fd = open("/dev/null", O_WRONLY, 0644); 52963753Seric if (fd < 0) 53063753Seric syserr("!Can't open /dev/null"); 53163753Seric } 53268352Seric e->e_xfp = fdopen(fd, "a"); 53364724Seric if (e->e_xfp == NULL) 53464724Seric syserr("!Can't create transcript stream %s", p); 53568498Seric #ifdef HASSETVBUF 53668498Seric setvbuf(e->e_xfp, NULL, _IOLBF, 0); 53768498Seric #else 53868498Seric setlinebuf(e->e_xfp); 53968498Seric #endif 54064743Seric if (tTd(46, 9)) 54164743Seric { 54264743Seric printf("openxscript(%s):\n ", p); 54364743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 54464743Seric } 5459536Seric } 5469536Seric /* 54710196Seric ** CLOSEXSCRIPT -- close the transcript file. 54810196Seric ** 54910196Seric ** Parameters: 55010196Seric ** e -- the envelope containing the transcript to close. 55110196Seric ** 55210196Seric ** Returns: 55310196Seric ** none. 55410196Seric ** 55510196Seric ** Side Effects: 55610196Seric ** none. 55710196Seric */ 55810196Seric 55960494Seric void 56010196Seric closexscript(e) 56110196Seric register ENVELOPE *e; 56210196Seric { 56310196Seric if (e->e_xfp == NULL) 56410196Seric return; 56558680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 56610196Seric e->e_xfp = NULL; 56710196Seric } 56810196Seric /* 5699536Seric ** SETSENDER -- set the person who this message is from 5709536Seric ** 5719536Seric ** Under certain circumstances allow the user to say who 5729536Seric ** s/he is (using -f or -r). These are: 5739536Seric ** 1. The user's uid is zero (root). 5749536Seric ** 2. The user's login name is in an approved list (typically 5759536Seric ** from a network server). 5769536Seric ** 3. The address the user is trying to claim has a 5779536Seric ** "!" character in it (since #2 doesn't do it for 5789536Seric ** us if we are dialing out for UUCP). 5799536Seric ** A better check to replace #3 would be if the 5809536Seric ** effective uid is "UUCP" -- this would require me 5819536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5829536Seric ** make getname more nasty, do another passwd file 5839536Seric ** scan, or compile the UID of "UUCP" into the code, 5849536Seric ** all of which are reprehensible. 5859536Seric ** 5869536Seric ** Assuming all of these fail, we figure out something 5879536Seric ** ourselves. 5889536Seric ** 5899536Seric ** Parameters: 5909536Seric ** from -- the person we would like to believe this message 5919536Seric ** is from, as specified on the command line. 59253182Seric ** e -- the envelope in which we would like the sender set. 59358333Seric ** delimptr -- if non-NULL, set to the location of the 59458333Seric ** trailing delimiter. 59558704Seric ** internal -- set if this address is coming from an internal 59658704Seric ** source such as an owner alias. 5979536Seric ** 5989536Seric ** Returns: 59958704Seric ** none. 6009536Seric ** 6019536Seric ** Side Effects: 6029536Seric ** sets sendmail's notion of who the from person is. 6039536Seric */ 6049536Seric 60560494Seric void 60658704Seric setsender(from, e, delimptr, internal) 6079536Seric char *from; 60853182Seric register ENVELOPE *e; 60958333Seric char **delimptr; 61058704Seric bool internal; 6119536Seric { 6129536Seric register char **pvp; 6139536Seric char *realname = NULL; 61418665Seric register struct passwd *pw; 61558727Seric char delimchar; 61664147Seric char *bp; 61764147Seric char buf[MAXNAME + 2]; 61816913Seric char pvpbuf[PSBUFSIZE]; 61918665Seric extern struct passwd *getpwnam(); 6209536Seric extern char *FullName; 6219536Seric 6229536Seric if (tTd(45, 1)) 62314786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 6249536Seric 6259536Seric /* 6269536Seric ** Figure out the real user executing us. 6279536Seric ** Username can return errno != 0 on non-errors. 6289536Seric */ 6299536Seric 63065580Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP || 63165983Seric OpMode == MD_ARPAFTP || OpMode == MD_DAEMON) 6329536Seric realname = from; 6339536Seric if (realname == NULL || realname[0] == '\0') 6349536Seric realname = username(); 6359536Seric 63659027Seric if (ConfigLevel < 2) 63759027Seric SuprErrs = TRUE; 63859027Seric 63958727Seric delimchar = internal ? '\0' : ' '; 64064793Seric e->e_from.q_flags = QBADADDR; 64158333Seric if (from == NULL || 64264284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 64364793Seric delimchar, delimptr, e) == NULL || 64464793Seric bitset(QBADADDR, e->e_from.q_flags) || 64564793Seric e->e_from.q_mailer == ProgMailer || 64664793Seric e->e_from.q_mailer == FileMailer || 64764793Seric e->e_from.q_mailer == InclMailer) 6489536Seric { 64921750Seric /* log garbage addresses for traceback */ 65055173Seric # ifdef LOG 65158020Seric if (from != NULL && LogLevel > 2) 65221750Seric { 65358951Seric char *p; 65458951Seric char ebuf[MAXNAME * 2 + 2]; 65555173Seric 65658951Seric p = macvalue('_', e); 65758951Seric if (p == NULL) 65858951Seric { 65958951Seric char *host = RealHostName; 66058951Seric if (host == NULL) 66158951Seric host = MyHostName; 66258951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 66358951Seric p = ebuf; 66458951Seric } 66555173Seric syslog(LOG_NOTICE, 66664793Seric "setsender: %s: invalid or unparseable, received from %s", 66765015Seric shortenstring(from, 83), p); 66855173Seric } 66956795Seric # endif /* LOG */ 67057589Seric if (from != NULL) 67164793Seric { 67264793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 67364793Seric { 67464793Seric /* it was a bogus mailer in the from addr */ 67564793Seric usrerr("553 Invalid sender address"); 67664793Seric } 67757589Seric SuprErrs = TRUE; 67864793Seric } 67957589Seric if (from == realname || 68064284Seric parseaddr(from = newstr(realname), &e->e_from, 68164284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 68224944Seric { 68364793Seric char nbuf[100]; 68464793Seric 68557589Seric SuprErrs = TRUE; 68668529Seric expand("\201n", nbuf, sizeof nbuf, e); 68764793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 68864793Seric RF_COPYALL, ' ', NULL, e) == NULL && 68964793Seric parseaddr(from = "postmaster", &e->e_from, 69064793Seric RF_COPYALL, ' ', NULL, e) == NULL) 69158151Seric syserr("553 setsender: can't even parse postmaster!"); 69224944Seric } 6939536Seric } 6949536Seric else 6959536Seric FromFlag = TRUE; 69653182Seric e->e_from.q_flags |= QDONTSEND; 69757731Seric if (tTd(45, 5)) 69857731Seric { 69957731Seric printf("setsender: QDONTSEND "); 70057731Seric printaddr(&e->e_from, FALSE); 70157731Seric } 7029536Seric SuprErrs = FALSE; 7039536Seric 70468498Seric # ifdef USERDB 70568498Seric if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags)) 70668460Seric { 70753736Seric register char *p; 70853736Seric extern char *udbsender(); 70917472Seric 71068498Seric p = udbsender(e->e_from.q_user); 71168498Seric if (p != NULL) 71268498Seric from = p; 71368498Seric } 71468498Seric # endif /* USERDB */ 71568498Seric 71668498Seric if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags)) 71768498Seric { 71858704Seric if (!internal) 71958704Seric { 72068498Seric /* if the user already given fullname don't redefine */ 72158704Seric if (FullName == NULL) 72258704Seric FullName = macvalue('x', e); 72358704Seric if (FullName != NULL && FullName[0] == '\0') 72458704Seric FullName = NULL; 7259536Seric } 72653736Seric 72753736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 72853736Seric { 72953736Seric /* 73053736Seric ** Process passwd file entry. 73153736Seric */ 73253736Seric 73353736Seric /* extract home directory */ 73465822Seric if (strcmp(pw->pw_dir, "/") == 0) 73565822Seric e->e_from.q_home = newstr(""); 73665822Seric else 73765822Seric e->e_from.q_home = newstr(pw->pw_dir); 73853736Seric define('z', e->e_from.q_home, e); 73953736Seric 74053736Seric /* extract user and group id */ 74153736Seric e->e_from.q_uid = pw->pw_uid; 74253736Seric e->e_from.q_gid = pw->pw_gid; 74365023Seric e->e_from.q_flags |= QGOODUID; 74453736Seric 74553736Seric /* extract full name from passwd file */ 74653736Seric if (FullName == NULL && pw->pw_gecos != NULL && 74758704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 74858704Seric !internal) 74953736Seric { 75065015Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 75153736Seric if (buf[0] != '\0') 75253736Seric FullName = newstr(buf); 75353736Seric } 75453736Seric } 75558704Seric if (FullName != NULL && !internal) 75653182Seric define('x', FullName, e); 7579536Seric } 75865580Seric else if (!internal && OpMode != MD_DAEMON) 75911625Seric { 76053182Seric if (e->e_from.q_home == NULL) 76165822Seric { 76253182Seric e->e_from.q_home = getenv("HOME"); 76366049Seric if (e->e_from.q_home != NULL && 76466049Seric strcmp(e->e_from.q_home, "/") == 0) 76565822Seric e->e_from.q_home++; 76665822Seric } 76763787Seric e->e_from.q_uid = RealUid; 76863787Seric e->e_from.q_gid = RealGid; 76965023Seric e->e_from.q_flags |= QGOODUID; 77011625Seric } 77111625Seric 7729536Seric /* 7739536Seric ** Rewrite the from person to dispose of possible implicit 7749536Seric ** links in the net. 7759536Seric */ 7769536Seric 77768498Seric pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL); 7789536Seric if (pvp == NULL) 7799536Seric { 78058403Seric /* don't need to give error -- prescan did that already */ 78136233Skarels # ifdef LOG 78258020Seric if (LogLevel > 2) 78336233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 78436233Skarels # endif 7859536Seric finis(); 7869536Seric } 78768498Seric /* 78865071Seric (void) rewrite(pvp, 3, 0, e); 78965071Seric (void) rewrite(pvp, 1, 0, e); 79065071Seric (void) rewrite(pvp, 4, 0, e); 79168498Seric */ 79264147Seric bp = buf + 1; 79364147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 79468498Seric if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags)) 79564147Seric { 79664147Seric /* heuristic: route-addr: add angle brackets */ 79764147Seric strcat(bp, ">"); 79864147Seric *--bp = '<'; 79964147Seric } 80064147Seric e->e_sender = newstr(bp); 80158704Seric define('f', e->e_sender, e); 8029536Seric 8039536Seric /* save the domain spec if this mailer wants it */ 80465584Seric if (e->e_from.q_mailer != NULL && 80553182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 8069536Seric { 8079536Seric extern char **copyplist(); 8089536Seric 8099536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 8109536Seric pvp++; 8119536Seric if (*pvp != NULL) 81253182Seric e->e_fromdomain = copyplist(pvp, TRUE); 8139536Seric } 8149536Seric } 815*68567Seric /* 816*68567Seric ** PRINTENVFLAGS -- print envelope flags for debugging 817*68567Seric ** 818*68567Seric ** Parameters: 819*68567Seric ** e -- the envelope with the flags to be printed. 820*68567Seric ** 821*68567Seric ** Returns: 822*68567Seric ** none. 823*68567Seric */ 824*68567Seric 825*68567Seric struct eflags 826*68567Seric { 827*68567Seric char *ef_name; 828*68567Seric u_long ef_bit; 829*68567Seric }; 830*68567Seric 831*68567Seric struct eflags EnvelopeFlags[] = 832*68567Seric { 833*68567Seric "OLDSTYLE", EF_OLDSTYLE, 834*68567Seric "INQUEUE", EF_INQUEUE, 835*68567Seric "NO_BODY_RETN", EF_NO_BODY_RETN, 836*68567Seric "CLRQUEUE", EF_CLRQUEUE, 837*68567Seric "SENDRECEIPT", EF_SENDRECEIPT, 838*68567Seric "FATALERRS", EF_FATALERRS, 839*68567Seric "KEEPQUEUE", EF_KEEPQUEUE, 840*68567Seric "RESPONSE", EF_RESPONSE, 841*68567Seric "RESENT", EF_RESENT, 842*68567Seric "VRFYONLY", EF_VRFYONLY, 843*68567Seric "WARNING", EF_WARNING, 844*68567Seric "QUEUERUN", EF_QUEUERUN, 845*68567Seric "GLOBALERRS", EF_GLOBALERRS, 846*68567Seric "PM_NOTIFY", EF_PM_NOTIFY, 847*68567Seric "METOO", EF_METOO, 848*68567Seric "LOGSENDER", EF_LOGSENDER, 849*68567Seric "NORECEIPT", EF_NORECEIPT, 850*68567Seric "HAS8BIT", EF_HAS8BIT, 851*68567Seric "NL_NOT_EOL", EF_NL_NOT_EOL, 852*68567Seric "CRLF_NOT_EOL", EF_CRLF_NOT_EOL, 853*68567Seric "RET_PARAM", EF_RET_PARAM, 854*68567Seric "HAS_DF", EF_HAS_DF, 855*68567Seric NULL 856*68567Seric }; 857*68567Seric 858*68567Seric void 859*68567Seric printenvflags(e) 860*68567Seric register ENVELOPE *e; 861*68567Seric { 862*68567Seric register struct eflags *ef; 863*68567Seric bool first = TRUE; 864*68567Seric 865*68567Seric printf("%lx", e->e_flags); 866*68567Seric for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) 867*68567Seric { 868*68567Seric if (!bitset(ef->ef_bit, e->e_flags)) 869*68567Seric continue; 870*68567Seric if (first) 871*68567Seric printf("<%s", ef->ef_name); 872*68567Seric else 873*68567Seric printf(",%s", ef->ef_name); 874*68567Seric first = FALSE; 875*68567Seric } 876*68567Seric if (!first) 877*68567Seric printf(">\n"); 878*68567Seric } 879