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*64925Seric static char sccsid[] = "@(#)envelope.c 8.19 (Berkeley) 11/20/93"; 1133729Sbostic #endif /* not lint */ 1222704Sdist 1358332Seric #include "sendmail.h" 1436928Sbostic #include <sys/time.h> 159536Seric #include <pwd.h> 169536Seric 179536Seric /* 189536Seric ** NEWENVELOPE -- allocate a new envelope 199536Seric ** 209536Seric ** Supports inheritance. 219536Seric ** 229536Seric ** Parameters: 239536Seric ** e -- the new envelope to fill in. 2458179Seric ** parent -- the envelope to be the parent of e. 259536Seric ** 269536Seric ** Returns: 279536Seric ** e. 289536Seric ** 299536Seric ** Side Effects: 309536Seric ** none. 319536Seric */ 329536Seric 339536Seric ENVELOPE * 3458179Seric newenvelope(e, parent) 359536Seric register ENVELOPE *e; 3658179Seric register ENVELOPE *parent; 379536Seric { 389536Seric extern putheader(), putbody(); 3925611Seric extern ENVELOPE BlankEnvelope; 409536Seric 4158179Seric if (e == parent && e->e_parent != NULL) 429536Seric parent = e->e_parent; 4325611Seric clearenvelope(e, TRUE); 4424944Seric if (e == CurEnv) 4524944Seric bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from); 4624944Seric else 4724944Seric bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); 489536Seric e->e_parent = parent; 499536Seric e->e_ctime = curtime(); 5056215Seric if (parent != NULL) 5156215Seric e->e_msgpriority = parent->e_msgsize; 529536Seric e->e_puthdr = putheader; 539536Seric e->e_putbody = putbody; 549536Seric if (CurEnv->e_xfp != NULL) 559536Seric (void) fflush(CurEnv->e_xfp); 569536Seric 579536Seric return (e); 589536Seric } 599536Seric /* 609536Seric ** DROPENVELOPE -- deallocate an envelope. 619536Seric ** 629536Seric ** Parameters: 639536Seric ** e -- the envelope to deallocate. 649536Seric ** 659536Seric ** Returns: 669536Seric ** none. 679536Seric ** 689536Seric ** Side Effects: 699536Seric ** housekeeping necessary to dispose of an envelope. 709536Seric ** Unlocks this queue file. 719536Seric */ 729536Seric 7360494Seric void 749536Seric dropenvelope(e) 759536Seric register ENVELOPE *e; 769536Seric { 779536Seric bool queueit = FALSE; 7863839Seric bool saveit = bitset(EF_FATALERRS, e->e_flags); 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); 8758680Seric printf(", flags=%o\n", e->e_flags); 8863753Seric if (tTd(50, 10)) 8963753Seric { 9063753Seric printf("sendq="); 9163753Seric printaddr(e->e_sendqueue, TRUE); 9263753Seric } 939536Seric } 9457943Seric 95*64925Seric #ifdef XDEBUG 96*64925Seric checkfd012("dropenvelope 1"); 97*64925Seric #endif 98*64925Seric 9958680Seric /* we must have an id to remove disk files */ 10057943Seric if (id == NULL) 10158680Seric return; 10257943Seric 1039536Seric #ifdef LOG 10458020Seric if (LogLevel > 84) 1059536Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d", 10657943Seric id, e->e_flags, getpid()); 10756795Seric #endif /* LOG */ 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; 1179536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 1189536Seric { 1199536Seric if (bitset(QQUEUEUP, q->q_flags)) 1209536Seric queueit = TRUE; 12163839Seric if (!bitset(QDONTSEND, q->q_flags) && 12263839Seric bitset(QBADADDR, q->q_flags)) 12363839Seric { 12463839Seric if (q->q_owner == NULL && 12563839Seric strcmp(e->e_from.q_paddr, "<>") != 0) 12663839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 12763839Seric &e->e_errorqueue, e); 12863839Seric } 1299536Seric } 1309536Seric 1319536Seric /* 13263753Seric ** See if the message timed out. 13363753Seric */ 13463753Seric 13563753Seric if (!queueit) 13663753Seric /* nothing to do */ ; 13763753Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return) 13863753Seric { 13963839Seric (void) sprintf(buf, "Cannot send message for %s", 14063839Seric pintvl(TimeOuts.to_q_return, FALSE)); 14163839Seric if (e->e_message != NULL) 14263839Seric free(e->e_message); 14363839Seric e->e_message = newstr(buf); 14463839Seric message(buf); 14563839Seric e->e_flags |= EF_CLRQUEUE; 14663839Seric saveit = TRUE; 14763787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 14863787Seric pintvl(TimeOuts.to_q_return, FALSE)); 14963787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 15063787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 15163787Seric { 15263787Seric if (bitset(QQUEUEUP, q->q_flags)) 15363787Seric q->q_flags |= QBADADDR; 15463787Seric } 15563753Seric } 15663753Seric else if (TimeOuts.to_q_warning > 0 && 15763753Seric curtime() > e->e_ctime + TimeOuts.to_q_warning) 15863753Seric { 15963753Seric if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 16063753Seric e->e_class >= 0 && 16163753Seric strcmp(e->e_from.q_paddr, "<>") != 0) 16263753Seric { 16363753Seric (void) sprintf(buf, 16463753Seric "warning: cannot send message for %s", 16563753Seric pintvl(TimeOuts.to_q_warning, FALSE)); 16663753Seric if (e->e_message != NULL) 16763753Seric free(e->e_message); 16863753Seric e->e_message = newstr(buf); 16963753Seric message(buf); 17063839Seric e->e_flags |= EF_WARNING; 17163839Seric saveit = TRUE; 17263753Seric } 17363753Seric fprintf(e->e_xfp, 17463753Seric "Warning: message still undelivered after %s\n", 17563753Seric pintvl(TimeOuts.to_q_warning, FALSE)); 17663753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 17763753Seric pintvl(TimeOuts.to_q_return, FALSE)); 17863787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 17963787Seric { 18063787Seric if (bitset(QQUEUEUP, q->q_flags)) 18163787Seric q->q_flags |= QREPORT; 18263787Seric } 18363753Seric } 18463753Seric 18563753Seric /* 1869536Seric ** Send back return receipts as requested. 1879536Seric */ 1889536Seric 1899536Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)) 1909536Seric { 19110844Seric auto ADDRESS *rlist = NULL; 1929536Seric 19364284Seric (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e); 19455012Seric (void) returntosender("Return receipt", rlist, FALSE, e); 1959536Seric } 1969536Seric 1979536Seric /* 1989536Seric ** Arrange to send error messages if there are fatal errors. 1999536Seric */ 2009536Seric 20163839Seric if (saveit && e->e_errormode != EM_QUIET) 2029536Seric savemail(e); 2039536Seric 204*64925Seric #ifdef XDEBUG 205*64925Seric checkfd012("dropenvelope 2"); 206*64925Seric #endif 207*64925Seric 2089536Seric /* 20963849Seric ** Arrange to send warning messages to postmaster as requested. 21063849Seric */ 21163849Seric 21263849Seric if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL && 21364363Seric !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0) 21463849Seric { 21563849Seric auto ADDRESS *rlist = NULL; 21663849Seric 21764284Seric (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, e); 21863849Seric (void) returntosender(e->e_message, rlist, FALSE, e); 21963849Seric } 22063849Seric 22163849Seric /* 2229536Seric ** Instantiate or deinstantiate the queue. 2239536Seric */ 2249536Seric 2259536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2269536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2279536Seric { 22864307Seric if (tTd(50, 1)) 22964307Seric printf("\n===== Dropping [dq]f%s =====\n\n", e->e_id); 23023497Seric if (e->e_df != NULL) 23123497Seric xunlink(e->e_df); 2329536Seric xunlink(queuename(e, 'q')); 23363839Seric 23463839Seric #ifdef LOG 23563839Seric if (LogLevel > 10) 23663839Seric syslog(LOG_INFO, "%s: done", id); 23763839Seric #endif 2389536Seric } 2399536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 24010754Seric { 24110754Seric #ifdef QUEUE 24264307Seric queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE); 24356795Seric #else /* QUEUE */ 24458151Seric syserr("554 dropenvelope: queueup"); 24556795Seric #endif /* QUEUE */ 24610754Seric } 2479536Seric 248*64925Seric #ifdef XDEBUG 249*64925Seric checkfd012("dropenvelope 3"); 250*64925Seric #endif 251*64925Seric 2529536Seric /* now unlock the job */ 25310196Seric closexscript(e); 2549536Seric unlockqueue(e); 2559536Seric 2569536Seric /* make sure that this envelope is marked unused */ 25724944Seric if (e->e_dfp != NULL) 25858680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 25910196Seric e->e_dfp = NULL; 26058680Seric e->e_id = e->e_df = NULL; 26164401Seric #ifdef XDEBUG 262*64925Seric checkfd012("dropenvelope 4"); 26364401Seric #endif 2649536Seric } 2659536Seric /* 2669536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 2679536Seric ** 2689536Seric ** This is normally used by a child process to get a clean 2699536Seric ** envelope without disturbing the parent. 2709536Seric ** 2719536Seric ** Parameters: 2729536Seric ** e -- the envelope to clear. 27325611Seric ** fullclear - if set, the current envelope is total 27425611Seric ** garbage and should be ignored; otherwise, 27525611Seric ** release any resources it may indicate. 2769536Seric ** 2779536Seric ** Returns: 2789536Seric ** none. 2799536Seric ** 2809536Seric ** Side Effects: 2819536Seric ** Closes files associated with the envelope. 2829536Seric ** Marks the envelope as unallocated. 2839536Seric */ 2849536Seric 28560494Seric void 28625611Seric clearenvelope(e, fullclear) 2879536Seric register ENVELOPE *e; 28825611Seric bool fullclear; 2899536Seric { 29025514Seric register HDR *bh; 29125514Seric register HDR **nhp; 29225514Seric extern ENVELOPE BlankEnvelope; 29325514Seric 29425611Seric if (!fullclear) 29525611Seric { 29625611Seric /* clear out any file information */ 29725611Seric if (e->e_xfp != NULL) 29858680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 29925611Seric if (e->e_dfp != NULL) 30058680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 30158680Seric e->e_xfp = e->e_dfp = NULL; 30225611Seric } 3039536Seric 30424961Seric /* now clear out the data */ 30524965Seric STRUCTCOPY(BlankEnvelope, *e); 30659698Seric if (Verbose) 30759698Seric e->e_sendmode = SM_DELIVER; 30825514Seric bh = BlankEnvelope.e_header; 30925514Seric nhp = &e->e_header; 31025514Seric while (bh != NULL) 31125514Seric { 31225514Seric *nhp = (HDR *) xalloc(sizeof *bh); 31325514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 31425514Seric bh = bh->h_link; 31525514Seric nhp = &(*nhp)->h_link; 31625514Seric } 3179536Seric } 3189536Seric /* 3199536Seric ** INITSYS -- initialize instantiation of system 3209536Seric ** 3219536Seric ** In Daemon mode, this is done in the child. 3229536Seric ** 3239536Seric ** Parameters: 3249536Seric ** none. 3259536Seric ** 3269536Seric ** Returns: 3279536Seric ** none. 3289536Seric ** 3299536Seric ** Side Effects: 3309536Seric ** Initializes the system macros, some global variables, 3319536Seric ** etc. In particular, the current time in various 3329536Seric ** forms is set. 3339536Seric */ 3349536Seric 33560494Seric void 33655012Seric initsys(e) 33755012Seric register ENVELOPE *e; 3389536Seric { 33964768Seric char cbuf[5]; /* holds hop count */ 34064768Seric char pbuf[10]; /* holds pid */ 34122963Smiriam #ifdef TTYNAME 34259304Seric static char ybuf[60]; /* holds tty id */ 3439536Seric register char *p; 34456795Seric #endif /* TTYNAME */ 3459536Seric extern char *ttyname(); 34660494Seric extern void settime(); 3479536Seric extern char Version[]; 3489536Seric 3499536Seric /* 3509536Seric ** Give this envelope a reality. 3519536Seric ** I.e., an id, a transcript, and a creation time. 3529536Seric */ 3539536Seric 35455012Seric openxscript(e); 35555012Seric e->e_ctime = curtime(); 3569536Seric 3579536Seric /* 3589536Seric ** Set OutChannel to something useful if stdout isn't it. 3599536Seric ** This arranges that any extra stuff the mailer produces 3609536Seric ** gets sent back to the user on error (because it is 3619536Seric ** tucked away in the transcript). 3629536Seric */ 3639536Seric 36464760Seric if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) && 36558737Seric e->e_xfp != NULL) 36655012Seric OutChannel = e->e_xfp; 3679536Seric 3689536Seric /* 3699536Seric ** Set up some basic system macros. 3709536Seric */ 3719536Seric 3729536Seric /* process id */ 3739536Seric (void) sprintf(pbuf, "%d", getpid()); 37464768Seric define('p', newstr(pbuf), e); 3759536Seric 3769536Seric /* hop count */ 37755012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 37864768Seric define('c', newstr(cbuf), e); 3799536Seric 3809536Seric /* time as integer, unix time, arpa time */ 38155012Seric settime(e); 3829536Seric 38317472Seric #ifdef TTYNAME 3849536Seric /* tty name */ 38555012Seric if (macvalue('y', e) == NULL) 3869536Seric { 3879536Seric p = ttyname(2); 3889536Seric if (p != NULL) 3899536Seric { 39056795Seric if (strrchr(p, '/') != NULL) 39156795Seric p = strrchr(p, '/') + 1; 3929536Seric (void) strcpy(ybuf, p); 39355012Seric define('y', ybuf, e); 3949536Seric } 3959536Seric } 39656795Seric #endif /* TTYNAME */ 3979536Seric } 3989536Seric /* 39911932Seric ** SETTIME -- set the current time. 40011932Seric ** 40111932Seric ** Parameters: 40211932Seric ** none. 40311932Seric ** 40411932Seric ** Returns: 40511932Seric ** none. 40611932Seric ** 40711932Seric ** Side Effects: 40811932Seric ** Sets the various time macros -- $a, $b, $d, $t. 40911932Seric */ 41011932Seric 41160494Seric void 41255012Seric settime(e) 41355012Seric register ENVELOPE *e; 41411932Seric { 41511932Seric register char *p; 41611932Seric auto time_t now; 41764768Seric char tbuf[20]; /* holds "current" time */ 41864768Seric char dbuf[30]; /* holds ctime(tbuf) */ 41911932Seric register struct tm *tm; 42011932Seric extern char *arpadate(); 42111932Seric extern struct tm *gmtime(); 42211932Seric 42311932Seric now = curtime(); 42411932Seric tm = gmtime(&now); 42557014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 42657014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 42764768Seric define('t', newstr(tbuf), e); 42811932Seric (void) strcpy(dbuf, ctime(&now)); 42958131Seric p = strchr(dbuf, '\n'); 43058131Seric if (p != NULL) 43158131Seric *p = '\0'; 43264768Seric define('d', newstr(dbuf), e); 43364086Seric p = arpadate(dbuf); 43464086Seric p = newstr(p); 43555012Seric if (macvalue('a', e) == NULL) 43655012Seric define('a', p, e); 43755012Seric define('b', p, e); 43811932Seric } 43911932Seric /* 4409536Seric ** OPENXSCRIPT -- Open transcript file 4419536Seric ** 4429536Seric ** Creates a transcript file for possible eventual mailing or 4439536Seric ** sending back. 4449536Seric ** 4459536Seric ** Parameters: 4469536Seric ** e -- the envelope to create the transcript in/for. 4479536Seric ** 4489536Seric ** Returns: 4499536Seric ** none 4509536Seric ** 4519536Seric ** Side Effects: 4529536Seric ** Creates the transcript file. 4539536Seric */ 4549536Seric 45558803Seric #ifndef O_APPEND 45658803Seric #define O_APPEND 0 45758803Seric #endif 45858803Seric 45960494Seric void 4609536Seric openxscript(e) 4619536Seric register ENVELOPE *e; 4629536Seric { 4639536Seric register char *p; 46440933Srick int fd; 4659536Seric 4669536Seric if (e->e_xfp != NULL) 4679536Seric return; 4689536Seric p = queuename(e, 'x'); 46958803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 47040933Srick if (fd < 0) 47163753Seric { 47263753Seric syserr("Can't create transcript file %s", p); 47363753Seric fd = open("/dev/null", O_WRONLY, 0644); 47463753Seric if (fd < 0) 47563753Seric syserr("!Can't open /dev/null"); 47663753Seric } 47763753Seric e->e_xfp = fdopen(fd, "w"); 47864724Seric if (e->e_xfp == NULL) 47964724Seric { 48064724Seric syserr("!Can't create transcript stream %s", p); 48164724Seric } 48264743Seric if (tTd(46, 9)) 48364743Seric { 48464743Seric printf("openxscript(%s):\n ", p); 48564743Seric dumpfd(fileno(e->e_xfp), TRUE, FALSE); 48664743Seric } 4879536Seric } 4889536Seric /* 48910196Seric ** CLOSEXSCRIPT -- close the transcript file. 49010196Seric ** 49110196Seric ** Parameters: 49210196Seric ** e -- the envelope containing the transcript to close. 49310196Seric ** 49410196Seric ** Returns: 49510196Seric ** none. 49610196Seric ** 49710196Seric ** Side Effects: 49810196Seric ** none. 49910196Seric */ 50010196Seric 50160494Seric void 50210196Seric closexscript(e) 50310196Seric register ENVELOPE *e; 50410196Seric { 50510196Seric if (e->e_xfp == NULL) 50610196Seric return; 50758680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 50810196Seric e->e_xfp = NULL; 50910196Seric } 51010196Seric /* 5119536Seric ** SETSENDER -- set the person who this message is from 5129536Seric ** 5139536Seric ** Under certain circumstances allow the user to say who 5149536Seric ** s/he is (using -f or -r). These are: 5159536Seric ** 1. The user's uid is zero (root). 5169536Seric ** 2. The user's login name is in an approved list (typically 5179536Seric ** from a network server). 5189536Seric ** 3. The address the user is trying to claim has a 5199536Seric ** "!" character in it (since #2 doesn't do it for 5209536Seric ** us if we are dialing out for UUCP). 5219536Seric ** A better check to replace #3 would be if the 5229536Seric ** effective uid is "UUCP" -- this would require me 5239536Seric ** to rewrite getpwent to "grab" uucp as it went by, 5249536Seric ** make getname more nasty, do another passwd file 5259536Seric ** scan, or compile the UID of "UUCP" into the code, 5269536Seric ** all of which are reprehensible. 5279536Seric ** 5289536Seric ** Assuming all of these fail, we figure out something 5299536Seric ** ourselves. 5309536Seric ** 5319536Seric ** Parameters: 5329536Seric ** from -- the person we would like to believe this message 5339536Seric ** is from, as specified on the command line. 53453182Seric ** e -- the envelope in which we would like the sender set. 53558333Seric ** delimptr -- if non-NULL, set to the location of the 53658333Seric ** trailing delimiter. 53758704Seric ** internal -- set if this address is coming from an internal 53858704Seric ** source such as an owner alias. 5399536Seric ** 5409536Seric ** Returns: 54158704Seric ** none. 5429536Seric ** 5439536Seric ** Side Effects: 5449536Seric ** sets sendmail's notion of who the from person is. 5459536Seric */ 5469536Seric 54760494Seric void 54858704Seric setsender(from, e, delimptr, internal) 5499536Seric char *from; 55053182Seric register ENVELOPE *e; 55158333Seric char **delimptr; 55258704Seric bool internal; 5539536Seric { 5549536Seric register char **pvp; 5559536Seric char *realname = NULL; 55618665Seric register struct passwd *pw; 55758727Seric char delimchar; 55864147Seric char *bp; 55964147Seric char buf[MAXNAME + 2]; 56016913Seric char pvpbuf[PSBUFSIZE]; 56118665Seric extern struct passwd *getpwnam(); 5629536Seric extern char *FullName; 5639536Seric 5649536Seric if (tTd(45, 1)) 56514786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 5669536Seric 5679536Seric /* 5689536Seric ** Figure out the real user executing us. 5699536Seric ** Username can return errno != 0 on non-errors. 5709536Seric */ 5719536Seric 57258737Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP) 5739536Seric realname = from; 5749536Seric if (realname == NULL || realname[0] == '\0') 5759536Seric realname = username(); 5769536Seric 57759027Seric if (ConfigLevel < 2) 57859027Seric SuprErrs = TRUE; 57959027Seric 58058727Seric delimchar = internal ? '\0' : ' '; 58164793Seric e->e_from.q_flags = QBADADDR; 58258333Seric if (from == NULL || 58364284Seric parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR, 58464793Seric delimchar, delimptr, e) == NULL || 58564793Seric bitset(QBADADDR, e->e_from.q_flags) || 58664793Seric e->e_from.q_mailer == ProgMailer || 58764793Seric e->e_from.q_mailer == FileMailer || 58864793Seric e->e_from.q_mailer == InclMailer) 5899536Seric { 59021750Seric /* log garbage addresses for traceback */ 59155173Seric # ifdef LOG 59258020Seric if (from != NULL && LogLevel > 2) 59321750Seric { 59458951Seric char *p; 59558951Seric char ebuf[MAXNAME * 2 + 2]; 59655173Seric 59758951Seric p = macvalue('_', e); 59858951Seric if (p == NULL) 59958951Seric { 60058951Seric char *host = RealHostName; 60158951Seric if (host == NULL) 60258951Seric host = MyHostName; 60358951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 60458951Seric p = ebuf; 60558951Seric } 60655173Seric syslog(LOG_NOTICE, 60764793Seric "setsender: %s: invalid or unparseable, received from %s", 60858951Seric from, p); 60955173Seric } 61056795Seric # endif /* LOG */ 61157589Seric if (from != NULL) 61264793Seric { 61364793Seric if (!bitset(QBADADDR, e->e_from.q_flags)) 61464793Seric { 61564793Seric /* it was a bogus mailer in the from addr */ 61664793Seric usrerr("553 Invalid sender address"); 61764793Seric } 61857589Seric SuprErrs = TRUE; 61964793Seric } 62057589Seric if (from == realname || 62164284Seric parseaddr(from = newstr(realname), &e->e_from, 62264284Seric RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL) 62324944Seric { 62464793Seric char nbuf[100]; 62564793Seric 62657589Seric SuprErrs = TRUE; 62764808Seric expand("\201n", nbuf, &nbuf[sizeof nbuf], e); 62864793Seric if (parseaddr(from = newstr(nbuf), &e->e_from, 62964793Seric RF_COPYALL, ' ', NULL, e) == NULL && 63064793Seric parseaddr(from = "postmaster", &e->e_from, 63164793Seric RF_COPYALL, ' ', NULL, e) == NULL) 63258151Seric syserr("553 setsender: can't even parse postmaster!"); 63324944Seric } 6349536Seric } 6359536Seric else 6369536Seric FromFlag = TRUE; 63753182Seric e->e_from.q_flags |= QDONTSEND; 63857731Seric if (tTd(45, 5)) 63957731Seric { 64057731Seric printf("setsender: QDONTSEND "); 64157731Seric printaddr(&e->e_from, FALSE); 64257731Seric } 6439536Seric SuprErrs = FALSE; 6449536Seric 64553736Seric pvp = NULL; 64653736Seric if (e->e_from.q_mailer == LocalMailer) 6479536Seric { 64853736Seric # ifdef USERDB 64953736Seric register char *p; 65053736Seric extern char *udbsender(); 65153736Seric # endif 65217472Seric 65358704Seric if (!internal) 65458704Seric { 65558704Seric /* if the user has given fullname already, don't redefine */ 65658704Seric if (FullName == NULL) 65758704Seric FullName = macvalue('x', e); 65858704Seric if (FullName != NULL && FullName[0] == '\0') 65958704Seric FullName = NULL; 6609536Seric 66153736Seric # ifdef USERDB 66264284Seric p = udbsender(e->e_from.q_user); 66353736Seric 66458704Seric if (p != NULL) 66558704Seric { 66658704Seric /* 66758704Seric ** We have an alternate address for the sender 66858704Seric */ 66953736Seric 67058704Seric pvp = prescan(p, '\0', pvpbuf, NULL); 67158704Seric } 67258704Seric # endif /* USERDB */ 6739536Seric } 67453736Seric 67553736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 67653736Seric { 67753736Seric /* 67853736Seric ** Process passwd file entry. 67953736Seric */ 68053736Seric 68153736Seric 68253736Seric /* extract home directory */ 68353736Seric e->e_from.q_home = newstr(pw->pw_dir); 68453736Seric define('z', e->e_from.q_home, e); 68553736Seric 68653736Seric /* extract user and group id */ 68753736Seric e->e_from.q_uid = pw->pw_uid; 68853736Seric e->e_from.q_gid = pw->pw_gid; 68953736Seric 69053736Seric /* extract full name from passwd file */ 69153736Seric if (FullName == NULL && pw->pw_gecos != NULL && 69258704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 69358704Seric !internal) 69453736Seric { 69553736Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 69653736Seric if (buf[0] != '\0') 69753736Seric FullName = newstr(buf); 69853736Seric } 69953736Seric } 70058704Seric if (FullName != NULL && !internal) 70153182Seric define('x', FullName, e); 7029536Seric } 70358704Seric else if (!internal) 70411625Seric { 70553182Seric if (e->e_from.q_home == NULL) 70653182Seric e->e_from.q_home = getenv("HOME"); 70763787Seric e->e_from.q_uid = RealUid; 70863787Seric e->e_from.q_gid = RealGid; 70911625Seric } 71011625Seric 7119536Seric /* 7129536Seric ** Rewrite the from person to dispose of possible implicit 7139536Seric ** links in the net. 7149536Seric */ 7159536Seric 7169536Seric if (pvp == NULL) 71764918Seric pvp = prescan(from, delimchar, pvpbuf, NULL); 71853736Seric if (pvp == NULL) 7199536Seric { 72058403Seric /* don't need to give error -- prescan did that already */ 72136233Skarels # ifdef LOG 72258020Seric if (LogLevel > 2) 72336233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 72436233Skarels # endif 7259536Seric finis(); 7269536Seric } 72759084Seric (void) rewrite(pvp, 3, e); 72859084Seric (void) rewrite(pvp, 1, e); 72959084Seric (void) rewrite(pvp, 4, e); 73064147Seric bp = buf + 1; 73164147Seric cataddr(pvp, NULL, bp, sizeof buf - 2, '\0'); 73264147Seric if (*bp == '@') 73364147Seric { 73464147Seric /* heuristic: route-addr: add angle brackets */ 73564147Seric strcat(bp, ">"); 73664147Seric *--bp = '<'; 73764147Seric } 73864147Seric e->e_sender = newstr(bp); 73958704Seric define('f', e->e_sender, e); 7409536Seric 7419536Seric /* save the domain spec if this mailer wants it */ 74258704Seric if (!internal && e->e_from.q_mailer != NULL && 74353182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 7449536Seric { 7459536Seric extern char **copyplist(); 7469536Seric 7479536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 7489536Seric pvp++; 7499536Seric if (*pvp != NULL) 75053182Seric e->e_fromdomain = copyplist(pvp, TRUE); 7519536Seric } 7529536Seric } 753