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*63839Seric static char sccsid[] = "@(#)envelope.c 8.4 (Berkeley) 07/16/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; 78*63839Seric 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 9558680Seric /* we must have an id to remove disk files */ 9657943Seric if (id == NULL) 9758680Seric return; 9857943Seric 999536Seric #ifdef LOG 10058020Seric if (LogLevel > 84) 1019536Seric syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d", 10257943Seric id, e->e_flags, getpid()); 10356795Seric #endif /* LOG */ 1049536Seric 10563753Seric /* post statistics */ 10663753Seric poststats(StatFile); 10763753Seric 1089536Seric /* 1099536Seric ** Extract state information from dregs of send list. 1109536Seric */ 1119536Seric 1129536Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 1139536Seric { 1149536Seric if (bitset(QQUEUEUP, q->q_flags)) 1159536Seric queueit = TRUE; 116*63839Seric if (!bitset(QDONTSEND, q->q_flags) && 117*63839Seric bitset(QBADADDR, q->q_flags)) 118*63839Seric { 119*63839Seric if (q->q_owner == NULL && 120*63839Seric strcmp(e->e_from.q_paddr, "<>") != 0) 121*63839Seric (void) sendtolist(e->e_from.q_paddr, NULL, 122*63839Seric &e->e_errorqueue, e); 123*63839Seric saveit = TRUE; 124*63839Seric } 1259536Seric } 1269536Seric 1279536Seric /* 12863753Seric ** See if the message timed out. 12963753Seric */ 13063753Seric 13163753Seric if (!queueit) 13263753Seric /* nothing to do */ ; 13363753Seric else if (curtime() > e->e_ctime + TimeOuts.to_q_return) 13463753Seric { 135*63839Seric (void) sprintf(buf, "Cannot send message for %s", 136*63839Seric pintvl(TimeOuts.to_q_return, FALSE)); 137*63839Seric if (e->e_message != NULL) 138*63839Seric free(e->e_message); 139*63839Seric e->e_message = newstr(buf); 140*63839Seric message(buf); 141*63839Seric e->e_flags |= EF_CLRQUEUE; 142*63839Seric saveit = TRUE; 14363787Seric fprintf(e->e_xfp, "Message could not be delivered for %s\n", 14463787Seric pintvl(TimeOuts.to_q_return, FALSE)); 14563787Seric fprintf(e->e_xfp, "Message will be deleted from queue\n"); 14663787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 14763787Seric { 14863787Seric if (bitset(QQUEUEUP, q->q_flags)) 14963787Seric q->q_flags |= QBADADDR; 15063787Seric } 15163753Seric } 15263753Seric else if (TimeOuts.to_q_warning > 0 && 15363753Seric curtime() > e->e_ctime + TimeOuts.to_q_warning) 15463753Seric { 15563753Seric if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 15663753Seric e->e_class >= 0 && 15763753Seric strcmp(e->e_from.q_paddr, "<>") != 0) 15863753Seric { 15963753Seric (void) sprintf(buf, 16063753Seric "warning: cannot send message for %s", 16163753Seric pintvl(TimeOuts.to_q_warning, FALSE)); 16263753Seric if (e->e_message != NULL) 16363753Seric free(e->e_message); 16463753Seric e->e_message = newstr(buf); 16563753Seric message(buf); 166*63839Seric e->e_flags |= EF_WARNING; 167*63839Seric saveit = TRUE; 16863753Seric } 16963753Seric fprintf(e->e_xfp, 17063753Seric "Warning: message still undelivered after %s\n", 17163753Seric pintvl(TimeOuts.to_q_warning, FALSE)); 17263753Seric fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 17363753Seric pintvl(TimeOuts.to_q_return, FALSE)); 17463787Seric for (q = e->e_sendqueue; q != NULL; q = q->q_next) 17563787Seric { 17663787Seric if (bitset(QQUEUEUP, q->q_flags)) 17763787Seric q->q_flags |= QREPORT; 17863787Seric } 17963753Seric } 18063753Seric 18163753Seric /* 1829536Seric ** Send back return receipts as requested. 1839536Seric */ 1849536Seric 1859536Seric if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)) 1869536Seric { 18710844Seric auto ADDRESS *rlist = NULL; 1889536Seric 18958082Seric (void) sendtolist(e->e_receiptto, (ADDRESS *) NULL, &rlist, e); 19055012Seric (void) returntosender("Return receipt", rlist, FALSE, e); 1919536Seric } 1929536Seric 1939536Seric /* 1949536Seric ** Arrange to send error messages if there are fatal errors. 1959536Seric */ 1969536Seric 197*63839Seric if (saveit && e->e_errormode != EM_QUIET) 1989536Seric savemail(e); 1999536Seric 2009536Seric /* 2019536Seric ** Instantiate or deinstantiate the queue. 2029536Seric */ 2039536Seric 2049536Seric if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 2059536Seric bitset(EF_CLRQUEUE, e->e_flags)) 2069536Seric { 20763753Seric if (tTd(50, 2)) 20863753Seric printf("Dropping envelope\n"); 20923497Seric if (e->e_df != NULL) 21023497Seric xunlink(e->e_df); 2119536Seric xunlink(queuename(e, 'q')); 212*63839Seric 213*63839Seric #ifdef LOG 214*63839Seric if (LogLevel > 10) 215*63839Seric syslog(LOG_INFO, "%s: done", id); 216*63839Seric #endif 2179536Seric } 2189536Seric else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 21910754Seric { 22010754Seric #ifdef QUEUE 22151920Seric queueup(e, FALSE, FALSE); 22256795Seric #else /* QUEUE */ 22358151Seric syserr("554 dropenvelope: queueup"); 22456795Seric #endif /* QUEUE */ 22510754Seric } 2269536Seric 2279536Seric /* now unlock the job */ 22810196Seric closexscript(e); 2299536Seric unlockqueue(e); 2309536Seric 2319536Seric /* make sure that this envelope is marked unused */ 23224944Seric if (e->e_dfp != NULL) 23358680Seric (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 23410196Seric e->e_dfp = NULL; 23558680Seric e->e_id = e->e_df = NULL; 2369536Seric } 2379536Seric /* 2389536Seric ** CLEARENVELOPE -- clear an envelope without unlocking 2399536Seric ** 2409536Seric ** This is normally used by a child process to get a clean 2419536Seric ** envelope without disturbing the parent. 2429536Seric ** 2439536Seric ** Parameters: 2449536Seric ** e -- the envelope to clear. 24525611Seric ** fullclear - if set, the current envelope is total 24625611Seric ** garbage and should be ignored; otherwise, 24725611Seric ** release any resources it may indicate. 2489536Seric ** 2499536Seric ** Returns: 2509536Seric ** none. 2519536Seric ** 2529536Seric ** Side Effects: 2539536Seric ** Closes files associated with the envelope. 2549536Seric ** Marks the envelope as unallocated. 2559536Seric */ 2569536Seric 25760494Seric void 25825611Seric clearenvelope(e, fullclear) 2599536Seric register ENVELOPE *e; 26025611Seric bool fullclear; 2619536Seric { 26225514Seric register HDR *bh; 26325514Seric register HDR **nhp; 26425514Seric extern ENVELOPE BlankEnvelope; 26525514Seric 26625611Seric if (!fullclear) 26725611Seric { 26825611Seric /* clear out any file information */ 26925611Seric if (e->e_xfp != NULL) 27058680Seric (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 27125611Seric if (e->e_dfp != NULL) 27258680Seric (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 27358680Seric e->e_xfp = e->e_dfp = NULL; 27425611Seric } 2759536Seric 27624961Seric /* now clear out the data */ 27724965Seric STRUCTCOPY(BlankEnvelope, *e); 27859698Seric if (Verbose) 27959698Seric e->e_sendmode = SM_DELIVER; 28025514Seric bh = BlankEnvelope.e_header; 28125514Seric nhp = &e->e_header; 28225514Seric while (bh != NULL) 28325514Seric { 28425514Seric *nhp = (HDR *) xalloc(sizeof *bh); 28525514Seric bcopy((char *) bh, (char *) *nhp, sizeof *bh); 28625514Seric bh = bh->h_link; 28725514Seric nhp = &(*nhp)->h_link; 28825514Seric } 2899536Seric } 2909536Seric /* 2919536Seric ** INITSYS -- initialize instantiation of system 2929536Seric ** 2939536Seric ** In Daemon mode, this is done in the child. 2949536Seric ** 2959536Seric ** Parameters: 2969536Seric ** none. 2979536Seric ** 2989536Seric ** Returns: 2999536Seric ** none. 3009536Seric ** 3019536Seric ** Side Effects: 3029536Seric ** Initializes the system macros, some global variables, 3039536Seric ** etc. In particular, the current time in various 3049536Seric ** forms is set. 3059536Seric */ 3069536Seric 30760494Seric void 30855012Seric initsys(e) 30955012Seric register ENVELOPE *e; 3109536Seric { 3119536Seric static char cbuf[5]; /* holds hop count */ 3129536Seric static char pbuf[10]; /* holds pid */ 31322963Smiriam #ifdef TTYNAME 31459304Seric static char ybuf[60]; /* holds tty id */ 3159536Seric register char *p; 31656795Seric #endif /* TTYNAME */ 3179536Seric extern char *ttyname(); 31860494Seric extern void settime(); 3199536Seric extern char Version[]; 3209536Seric 3219536Seric /* 3229536Seric ** Give this envelope a reality. 3239536Seric ** I.e., an id, a transcript, and a creation time. 3249536Seric */ 3259536Seric 32655012Seric openxscript(e); 32755012Seric e->e_ctime = curtime(); 3289536Seric 3299536Seric /* 3309536Seric ** Set OutChannel to something useful if stdout isn't it. 3319536Seric ** This arranges that any extra stuff the mailer produces 3329536Seric ** gets sent back to the user on error (because it is 3339536Seric ** tucked away in the transcript). 3349536Seric */ 3359536Seric 33658737Seric if (OpMode == MD_DAEMON && !bitset(EF_QUEUERUN, e->e_flags) && 33758737Seric e->e_xfp != NULL) 33855012Seric OutChannel = e->e_xfp; 3399536Seric 3409536Seric /* 3419536Seric ** Set up some basic system macros. 3429536Seric */ 3439536Seric 3449536Seric /* process id */ 3459536Seric (void) sprintf(pbuf, "%d", getpid()); 34655012Seric define('p', pbuf, e); 3479536Seric 3489536Seric /* hop count */ 34955012Seric (void) sprintf(cbuf, "%d", e->e_hopcount); 35055012Seric define('c', cbuf, e); 3519536Seric 3529536Seric /* time as integer, unix time, arpa time */ 35355012Seric settime(e); 3549536Seric 35517472Seric #ifdef TTYNAME 3569536Seric /* tty name */ 35755012Seric if (macvalue('y', e) == NULL) 3589536Seric { 3599536Seric p = ttyname(2); 3609536Seric if (p != NULL) 3619536Seric { 36256795Seric if (strrchr(p, '/') != NULL) 36356795Seric p = strrchr(p, '/') + 1; 3649536Seric (void) strcpy(ybuf, p); 36555012Seric define('y', ybuf, e); 3669536Seric } 3679536Seric } 36856795Seric #endif /* TTYNAME */ 3699536Seric } 3709536Seric /* 37111932Seric ** SETTIME -- set the current time. 37211932Seric ** 37311932Seric ** Parameters: 37411932Seric ** none. 37511932Seric ** 37611932Seric ** Returns: 37711932Seric ** none. 37811932Seric ** 37911932Seric ** Side Effects: 38011932Seric ** Sets the various time macros -- $a, $b, $d, $t. 38111932Seric */ 38211932Seric 38360494Seric void 38455012Seric settime(e) 38555012Seric register ENVELOPE *e; 38611932Seric { 38711932Seric register char *p; 38811932Seric auto time_t now; 38911932Seric static char tbuf[20]; /* holds "current" time */ 39011932Seric static char dbuf[30]; /* holds ctime(tbuf) */ 39111932Seric register struct tm *tm; 39211932Seric extern char *arpadate(); 39311932Seric extern struct tm *gmtime(); 39411932Seric 39511932Seric now = curtime(); 39611932Seric tm = gmtime(&now); 39757014Seric (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 39857014Seric tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 39955012Seric define('t', tbuf, e); 40011932Seric (void) strcpy(dbuf, ctime(&now)); 40158131Seric p = strchr(dbuf, '\n'); 40258131Seric if (p != NULL) 40358131Seric *p = '\0'; 40458131Seric define('d', dbuf, e); 40511932Seric p = newstr(arpadate(dbuf)); 40655012Seric if (macvalue('a', e) == NULL) 40755012Seric define('a', p, e); 40855012Seric define('b', p, e); 40911932Seric } 41011932Seric /* 4119536Seric ** OPENXSCRIPT -- Open transcript file 4129536Seric ** 4139536Seric ** Creates a transcript file for possible eventual mailing or 4149536Seric ** sending back. 4159536Seric ** 4169536Seric ** Parameters: 4179536Seric ** e -- the envelope to create the transcript in/for. 4189536Seric ** 4199536Seric ** Returns: 4209536Seric ** none 4219536Seric ** 4229536Seric ** Side Effects: 4239536Seric ** Creates the transcript file. 4249536Seric */ 4259536Seric 42658803Seric #ifndef O_APPEND 42758803Seric #define O_APPEND 0 42858803Seric #endif 42958803Seric 43060494Seric void 4319536Seric openxscript(e) 4329536Seric register ENVELOPE *e; 4339536Seric { 4349536Seric register char *p; 43540933Srick int fd; 4369536Seric 4379536Seric if (e->e_xfp != NULL) 4389536Seric return; 4399536Seric p = queuename(e, 'x'); 44058803Seric fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 44140933Srick if (fd < 0) 44263753Seric { 44363753Seric syserr("Can't create transcript file %s", p); 44463753Seric fd = open("/dev/null", O_WRONLY, 0644); 44563753Seric if (fd < 0) 44663753Seric syserr("!Can't open /dev/null"); 44763753Seric } 44863753Seric e->e_xfp = fdopen(fd, "w"); 4499536Seric } 4509536Seric /* 45110196Seric ** CLOSEXSCRIPT -- close the transcript file. 45210196Seric ** 45310196Seric ** Parameters: 45410196Seric ** e -- the envelope containing the transcript to close. 45510196Seric ** 45610196Seric ** Returns: 45710196Seric ** none. 45810196Seric ** 45910196Seric ** Side Effects: 46010196Seric ** none. 46110196Seric */ 46210196Seric 46360494Seric void 46410196Seric closexscript(e) 46510196Seric register ENVELOPE *e; 46610196Seric { 46710196Seric if (e->e_xfp == NULL) 46810196Seric return; 46958680Seric (void) xfclose(e->e_xfp, "closexscript", e->e_id); 47010196Seric e->e_xfp = NULL; 47110196Seric } 47210196Seric /* 4739536Seric ** SETSENDER -- set the person who this message is from 4749536Seric ** 4759536Seric ** Under certain circumstances allow the user to say who 4769536Seric ** s/he is (using -f or -r). These are: 4779536Seric ** 1. The user's uid is zero (root). 4789536Seric ** 2. The user's login name is in an approved list (typically 4799536Seric ** from a network server). 4809536Seric ** 3. The address the user is trying to claim has a 4819536Seric ** "!" character in it (since #2 doesn't do it for 4829536Seric ** us if we are dialing out for UUCP). 4839536Seric ** A better check to replace #3 would be if the 4849536Seric ** effective uid is "UUCP" -- this would require me 4859536Seric ** to rewrite getpwent to "grab" uucp as it went by, 4869536Seric ** make getname more nasty, do another passwd file 4879536Seric ** scan, or compile the UID of "UUCP" into the code, 4889536Seric ** all of which are reprehensible. 4899536Seric ** 4909536Seric ** Assuming all of these fail, we figure out something 4919536Seric ** ourselves. 4929536Seric ** 4939536Seric ** Parameters: 4949536Seric ** from -- the person we would like to believe this message 4959536Seric ** is from, as specified on the command line. 49653182Seric ** e -- the envelope in which we would like the sender set. 49758333Seric ** delimptr -- if non-NULL, set to the location of the 49858333Seric ** trailing delimiter. 49958704Seric ** internal -- set if this address is coming from an internal 50058704Seric ** source such as an owner alias. 5019536Seric ** 5029536Seric ** Returns: 50358704Seric ** none. 5049536Seric ** 5059536Seric ** Side Effects: 5069536Seric ** sets sendmail's notion of who the from person is. 5079536Seric */ 5089536Seric 50960494Seric void 51058704Seric setsender(from, e, delimptr, internal) 5119536Seric char *from; 51253182Seric register ENVELOPE *e; 51358333Seric char **delimptr; 51458704Seric bool internal; 5159536Seric { 5169536Seric register char **pvp; 5179536Seric char *realname = NULL; 51818665Seric register struct passwd *pw; 51958727Seric char delimchar; 5209536Seric char buf[MAXNAME]; 52116913Seric char pvpbuf[PSBUFSIZE]; 52218665Seric extern struct passwd *getpwnam(); 5239536Seric extern char *FullName; 5249536Seric 5259536Seric if (tTd(45, 1)) 52614786Seric printf("setsender(%s)\n", from == NULL ? "" : from); 5279536Seric 5289536Seric /* 5299536Seric ** Figure out the real user executing us. 5309536Seric ** Username can return errno != 0 on non-errors. 5319536Seric */ 5329536Seric 53358737Seric if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP) 5349536Seric realname = from; 5359536Seric if (realname == NULL || realname[0] == '\0') 5369536Seric realname = username(); 5379536Seric 53859027Seric if (ConfigLevel < 2) 53959027Seric SuprErrs = TRUE; 54059027Seric 54158727Seric delimchar = internal ? '\0' : ' '; 54258333Seric if (from == NULL || 54358727Seric parseaddr(from, &e->e_from, 1, delimchar, delimptr, e) == NULL) 5449536Seric { 54521750Seric /* log garbage addresses for traceback */ 54655173Seric # ifdef LOG 54758020Seric if (from != NULL && LogLevel > 2) 54821750Seric { 54958951Seric char *p; 55058951Seric char ebuf[MAXNAME * 2 + 2]; 55155173Seric 55258951Seric p = macvalue('_', e); 55358951Seric if (p == NULL) 55458951Seric { 55558951Seric char *host = RealHostName; 55658951Seric if (host == NULL) 55758951Seric host = MyHostName; 55858951Seric (void) sprintf(ebuf, "%s@%s", realname, host); 55958951Seric p = ebuf; 56058951Seric } 56155173Seric syslog(LOG_NOTICE, 56258951Seric "from=%s unparseable, received from %s", 56358951Seric from, p); 56455173Seric } 56556795Seric # endif /* LOG */ 56657589Seric if (from != NULL) 56757589Seric SuprErrs = TRUE; 56857589Seric if (from == realname || 56958333Seric parseaddr(from = newstr(realname), &e->e_from, 1, ' ', NULL, e) == NULL) 57024944Seric { 57157589Seric SuprErrs = TRUE; 57258333Seric if (parseaddr("postmaster", &e->e_from, 1, ' ', NULL, e) == NULL) 57358151Seric syserr("553 setsender: can't even parse postmaster!"); 57424944Seric } 5759536Seric } 5769536Seric else 5779536Seric FromFlag = TRUE; 57853182Seric e->e_from.q_flags |= QDONTSEND; 57957731Seric if (tTd(45, 5)) 58057731Seric { 58157731Seric printf("setsender: QDONTSEND "); 58257731Seric printaddr(&e->e_from, FALSE); 58357731Seric } 5849536Seric SuprErrs = FALSE; 5859536Seric 58653736Seric pvp = NULL; 58753736Seric if (e->e_from.q_mailer == LocalMailer) 5889536Seric { 58953736Seric # ifdef USERDB 59053736Seric register char *p; 59153736Seric extern char *udbsender(); 59253736Seric # endif 59317472Seric 59458704Seric if (!internal) 59558704Seric { 59658704Seric /* if the user has given fullname already, don't redefine */ 59758704Seric if (FullName == NULL) 59858704Seric FullName = macvalue('x', e); 59958704Seric if (FullName != NULL && FullName[0] == '\0') 60058704Seric FullName = NULL; 6019536Seric 60253736Seric # ifdef USERDB 60358704Seric p = udbsender(from); 60453736Seric 60558704Seric if (p != NULL) 60658704Seric { 60758704Seric /* 60858704Seric ** We have an alternate address for the sender 60958704Seric */ 61053736Seric 61158704Seric pvp = prescan(p, '\0', pvpbuf, NULL); 61258704Seric } 61358704Seric # endif /* USERDB */ 6149536Seric } 61553736Seric 61653736Seric if ((pw = getpwnam(e->e_from.q_user)) != NULL) 61753736Seric { 61853736Seric /* 61953736Seric ** Process passwd file entry. 62053736Seric */ 62153736Seric 62253736Seric 62353736Seric /* extract home directory */ 62453736Seric e->e_from.q_home = newstr(pw->pw_dir); 62553736Seric define('z', e->e_from.q_home, e); 62653736Seric 62753736Seric /* extract user and group id */ 62853736Seric e->e_from.q_uid = pw->pw_uid; 62953736Seric e->e_from.q_gid = pw->pw_gid; 63053736Seric 63153736Seric /* extract full name from passwd file */ 63253736Seric if (FullName == NULL && pw->pw_gecos != NULL && 63358704Seric strcmp(pw->pw_name, e->e_from.q_user) == 0 && 63458704Seric !internal) 63553736Seric { 63653736Seric buildfname(pw->pw_gecos, e->e_from.q_user, buf); 63753736Seric if (buf[0] != '\0') 63853736Seric FullName = newstr(buf); 63953736Seric } 64053736Seric } 64158704Seric if (FullName != NULL && !internal) 64253182Seric define('x', FullName, e); 6439536Seric } 64458704Seric else if (!internal) 64511625Seric { 64653182Seric if (e->e_from.q_home == NULL) 64753182Seric e->e_from.q_home = getenv("HOME"); 64863787Seric e->e_from.q_uid = RealUid; 64963787Seric e->e_from.q_gid = RealGid; 65011625Seric } 65111625Seric 6529536Seric /* 6539536Seric ** Rewrite the from person to dispose of possible implicit 6549536Seric ** links in the net. 6559536Seric */ 6569536Seric 6579536Seric if (pvp == NULL) 65858333Seric pvp = prescan(from, '\0', pvpbuf, NULL); 65953736Seric if (pvp == NULL) 6609536Seric { 66158403Seric /* don't need to give error -- prescan did that already */ 66236233Skarels # ifdef LOG 66358020Seric if (LogLevel > 2) 66436233Skarels syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 66536233Skarels # endif 6669536Seric finis(); 6679536Seric } 66859084Seric (void) rewrite(pvp, 3, e); 66959084Seric (void) rewrite(pvp, 1, e); 67059084Seric (void) rewrite(pvp, 4, e); 67158814Seric cataddr(pvp, NULL, buf, sizeof buf, '\0'); 67258704Seric e->e_sender = newstr(buf); 67358704Seric define('f', e->e_sender, e); 6749536Seric 6759536Seric /* save the domain spec if this mailer wants it */ 67658704Seric if (!internal && e->e_from.q_mailer != NULL && 67753182Seric bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 6789536Seric { 6799536Seric extern char **copyplist(); 6809536Seric 6819536Seric while (*pvp != NULL && strcmp(*pvp, "@") != 0) 6829536Seric pvp++; 6839536Seric if (*pvp != NULL) 68453182Seric e->e_fromdomain = copyplist(pvp, TRUE); 6859536Seric } 6869536Seric } 687