1 /*
2  * Copyright (c) 1983 Eric P. Allman
3  * Copyright (c) 1988, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 #ifndef lint
10 static char sccsid[] = "@(#)envelope.c	8.49 (Berkeley) 12/01/94";
11 #endif /* not lint */
12 
13 #include "sendmail.h"
14 #include <pwd.h>
15 
16 /*
17 **  NEWENVELOPE -- allocate a new envelope
18 **
19 **	Supports inheritance.
20 **
21 **	Parameters:
22 **		e -- the new envelope to fill in.
23 **		parent -- the envelope to be the parent of e.
24 **
25 **	Returns:
26 **		e.
27 **
28 **	Side Effects:
29 **		none.
30 */
31 
32 ENVELOPE *
33 newenvelope(e, parent)
34 	register ENVELOPE *e;
35 	register ENVELOPE *parent;
36 {
37 	extern putheader(), putbody();
38 	extern ENVELOPE BlankEnvelope;
39 
40 	if (e == parent && e->e_parent != NULL)
41 		parent = e->e_parent;
42 	clearenvelope(e, TRUE);
43 	if (e == CurEnv)
44 		bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from);
45 	else
46 		bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
47 	e->e_parent = parent;
48 	e->e_ctime = curtime();
49 	if (parent != NULL)
50 		e->e_msgpriority = parent->e_msgsize;
51 	e->e_puthdr = putheader;
52 	e->e_putbody = putbody;
53 	if (CurEnv->e_xfp != NULL)
54 		(void) fflush(CurEnv->e_xfp);
55 
56 	return (e);
57 }
58 /*
59 **  DROPENVELOPE -- deallocate an envelope.
60 **
61 **	Parameters:
62 **		e -- the envelope to deallocate.
63 **
64 **	Returns:
65 **		none.
66 **
67 **	Side Effects:
68 **		housekeeping necessary to dispose of an envelope.
69 **		Unlocks this queue file.
70 */
71 
72 void
73 dropenvelope(e)
74 	register ENVELOPE *e;
75 {
76 	bool queueit = FALSE;
77 	bool failure_return = FALSE;
78 	bool success_return = FALSE;
79 	register ADDRESS *q;
80 	char *id = e->e_id;
81 	bool return_no, return_yes;
82 	char buf[MAXLINE];
83 
84 	if (tTd(50, 1))
85 	{
86 		printf("dropenvelope %x: id=", e);
87 		xputs(e->e_id);
88 		printf(", flags=0x%x\n", e->e_flags);
89 		if (tTd(50, 10))
90 		{
91 			printf("sendq=");
92 			printaddr(e->e_sendqueue, TRUE);
93 		}
94 	}
95 
96 	/* we must have an id to remove disk files */
97 	if (id == NULL)
98 		return;
99 
100 #ifdef LOG
101 	if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
102 		logsender(e, NULL);
103 	if (LogLevel > 84)
104 		syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d",
105 				  id, e->e_flags, getpid());
106 #endif /* LOG */
107 	e->e_flags &= ~EF_LOGSENDER;
108 
109 	/* post statistics */
110 	poststats(StatFile);
111 
112 	/*
113 	**  Extract state information from dregs of send list.
114 	*/
115 
116 	e->e_flags &= ~EF_QUEUERUN;
117 	return_no = return_yes = FALSE;
118 	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
119 	{
120 		if (bitset(QQUEUEUP, q->q_flags))
121 			queueit = TRUE;
122 
123 		/* see if a notification is needed */
124 		if (e->e_df != NULL &&
125 		    bitset(QBADADDR, q->q_flags) &&
126 		    bitset(QPINGONFAILURE, q->q_flags))
127 		{
128 			failure_return = TRUE;
129 			if (q->q_owner == NULL && !emptyaddr(&e->e_from))
130 				(void) sendtolist(e->e_from.q_paddr, NULL,
131 						  &e->e_errorqueue, 0, e);
132 		}
133 		else if (bitset(QSENT, q->q_flags) &&
134 		    bitnset(M_LOCALMAILER, q->q_mailer->m_flags) &&
135 		    bitset(QPINGONSUCCESS, q->q_flags))
136 		{
137 			success_return = TRUE;
138 		}
139 		else if (bitset(QRELAYED, q->q_flags))
140 		{
141 			success_return = TRUE;
142 		}
143 		else
144 			continue;
145 
146 		/* common code for error returns and return receipts */
147 
148 		/* test for returning the body */
149 		if (bitset(QHAS_RET_PARAM, q->q_flags))
150 		{
151 			if (bitset(QRET_HDRS, q->q_flags))
152 				return_no = TRUE;
153 			else
154 				return_yes = TRUE;
155 		}
156 	}
157 	if (return_no && !return_yes)
158 		e->e_flags |= EF_NORETURN;
159 
160 	/*
161 	**  See if the message timed out.
162 	*/
163 
164 	if (!queueit)
165 		/* nothing to do */ ;
166 	else if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
167 	{
168 		(void) sprintf(buf, "Cannot send message for %s",
169 			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
170 		if (e->e_message != NULL)
171 			free(e->e_message);
172 		e->e_message = newstr(buf);
173 		message(buf);
174 		e->e_flags |= EF_CLRQUEUE;
175 		failure_return = TRUE;
176 		fprintf(e->e_xfp, "Message could not be delivered for %s\n",
177 			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
178 		fprintf(e->e_xfp, "Message will be deleted from queue\n");
179 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
180 		{
181 			if (bitset(QQUEUEUP, q->q_flags))
182 				q->q_flags |= QBADADDR;
183 		}
184 	}
185 	else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
186 	    curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
187 	{
188 		bool delay_return = FALSE;
189 
190 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
191 		{
192 			if (bitset(QQUEUEUP, q->q_flags) &&
193 			    bitset(QPINGONDELAY, q->q_flags))
194 			{
195 				q->q_flags |= QREPORT;
196 				delay_return = TRUE;
197 			}
198 		}
199 		if (delay_return &&
200 		    !bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
201 		    e->e_class >= 0 &&
202 		    strcmp(e->e_from.q_paddr, "<>") != 0 &&
203 		    strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 &&
204 		    (strlen(e->e_from.q_paddr) <= 8 ||
205 		     strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0))
206 		{
207 			(void) sprintf(buf,
208 				"Warning: cannot send message for %s",
209 				pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
210 			if (e->e_message != NULL)
211 				free(e->e_message);
212 			e->e_message = newstr(buf);
213 			message(buf);
214 			e->e_flags |= EF_WARNING;
215 			failure_return = TRUE;
216 		}
217 		fprintf(e->e_xfp,
218 			"Warning: message still undelivered after %s\n",
219 			pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
220 		fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
221 			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
222 	}
223 
224 	if (tTd(50, 2))
225 		printf("failure_return=%d success_return=%d queueit=%d\n",
226 			failure_return, success_return, queueit);
227 
228 	/*
229 	**  If we had some fatal error, but no addresses are marked as
230 	**  bad, mark them _all_ as bad.
231 	*/
232 
233 	if (bitset(EF_FATALERRS, e->e_flags) && !failure_return)
234 	{
235 		failure_return = TRUE;
236 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
237 		{
238 			if (!bitset(QDONTSEND, q->q_flags))
239 				q->q_flags |= QBADADDR;
240 		}
241 	}
242 
243 	/*
244 	**  Send back return receipts as requested.
245 	*/
246 
247 /*
248 	if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)
249 	    && !bitset(PRIV_NORECEIPTS, PrivacyFlags))
250 */
251 	if (e->e_receiptto == NULL)
252 		e->e_receiptto = e->e_from.q_paddr;
253 	if (success_return && !failure_return &&
254 	    !bitset(PRIV_NORECEIPTS, PrivacyFlags) &&
255 	    strcmp(e->e_receiptto, "<>") != 0)
256 	{
257 		auto ADDRESS *rlist = NULL;
258 
259 		e->e_flags |= EF_SENDRECEIPT;
260 		(void) sendtolist(e->e_receiptto, NULLADDR, &rlist, 0, e);
261 		(void) returntosender("Return receipt", rlist, return_yes, e);
262 	}
263 	e->e_flags &= ~EF_SENDRECEIPT;
264 
265 	/*
266 	**  Arrange to send error messages if there are fatal errors.
267 	*/
268 
269 	if (failure_return && e->e_errormode != EM_QUIET)
270 		savemail(e, return_yes || (!return_no && e->e_class >= 0));
271 
272 	/*
273 	**  Arrange to send warning messages to postmaster as requested.
274 	*/
275 
276 	if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL &&
277 	    !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0)
278 	{
279 		auto ADDRESS *rlist = NULL;
280 
281 		(void) sendtolist(PostMasterCopy, NULLADDR, &rlist, 0, e);
282 		(void) returntosender(e->e_message, rlist, FALSE, e);
283 	}
284 
285 	/*
286 	**  Instantiate or deinstantiate the queue.
287 	*/
288 
289 	if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) ||
290 	    bitset(EF_CLRQUEUE, e->e_flags))
291 	{
292 		if (tTd(50, 1))
293 			printf("\n===== Dropping [dq]f%s (queueit=%d, e_flags=%x) =====\n\n",
294 				e->e_id, queueit, e->e_flags);
295 		if (e->e_df != NULL)
296 			xunlink(e->e_df);
297 		xunlink(queuename(e, 'q'));
298 
299 #ifdef LOG
300 		if (LogLevel > 10)
301 			syslog(LOG_INFO, "%s: done", id);
302 #endif
303 	}
304 	else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
305 	{
306 #ifdef QUEUE
307 		queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE);
308 #else /* QUEUE */
309 		syserr("554 dropenvelope: queueup");
310 #endif /* QUEUE */
311 	}
312 
313 	/* now unlock the job */
314 	closexscript(e);
315 	unlockqueue(e);
316 
317 	/* make sure that this envelope is marked unused */
318 	if (e->e_dfp != NULL)
319 		(void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
320 	e->e_dfp = NULL;
321 	e->e_id = e->e_df = NULL;
322 }
323 /*
324 **  CLEARENVELOPE -- clear an envelope without unlocking
325 **
326 **	This is normally used by a child process to get a clean
327 **	envelope without disturbing the parent.
328 **
329 **	Parameters:
330 **		e -- the envelope to clear.
331 **		fullclear - if set, the current envelope is total
332 **			garbage and should be ignored; otherwise,
333 **			release any resources it may indicate.
334 **
335 **	Returns:
336 **		none.
337 **
338 **	Side Effects:
339 **		Closes files associated with the envelope.
340 **		Marks the envelope as unallocated.
341 */
342 
343 void
344 clearenvelope(e, fullclear)
345 	register ENVELOPE *e;
346 	bool fullclear;
347 {
348 	register HDR *bh;
349 	register HDR **nhp;
350 	extern ENVELOPE BlankEnvelope;
351 
352 	if (!fullclear)
353 	{
354 		/* clear out any file information */
355 		if (e->e_xfp != NULL)
356 			(void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id);
357 		if (e->e_dfp != NULL)
358 			(void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df);
359 		e->e_xfp = e->e_dfp = NULL;
360 	}
361 
362 	/* now clear out the data */
363 	STRUCTCOPY(BlankEnvelope, *e);
364 	if (Verbose)
365 		e->e_sendmode = SM_DELIVER;
366 	bh = BlankEnvelope.e_header;
367 	nhp = &e->e_header;
368 	while (bh != NULL)
369 	{
370 		*nhp = (HDR *) xalloc(sizeof *bh);
371 		bcopy((char *) bh, (char *) *nhp, sizeof *bh);
372 		bh = bh->h_link;
373 		nhp = &(*nhp)->h_link;
374 	}
375 }
376 /*
377 **  INITSYS -- initialize instantiation of system
378 **
379 **	In Daemon mode, this is done in the child.
380 **
381 **	Parameters:
382 **		none.
383 **
384 **	Returns:
385 **		none.
386 **
387 **	Side Effects:
388 **		Initializes the system macros, some global variables,
389 **		etc.  In particular, the current time in various
390 **		forms is set.
391 */
392 
393 void
394 initsys(e)
395 	register ENVELOPE *e;
396 {
397 	char cbuf[5];				/* holds hop count */
398 	char pbuf[10];				/* holds pid */
399 #ifdef TTYNAME
400 	static char ybuf[60];			/* holds tty id */
401 	register char *p;
402 #endif /* TTYNAME */
403 	extern char *ttyname();
404 	extern void settime();
405 	extern char Version[];
406 
407 	/*
408 	**  Give this envelope a reality.
409 	**	I.e., an id, a transcript, and a creation time.
410 	*/
411 
412 	openxscript(e);
413 	e->e_ctime = curtime();
414 
415 	/*
416 	**  Set OutChannel to something useful if stdout isn't it.
417 	**	This arranges that any extra stuff the mailer produces
418 	**	gets sent back to the user on error (because it is
419 	**	tucked away in the transcript).
420 	*/
421 
422 	if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
423 	    e->e_xfp != NULL)
424 		OutChannel = e->e_xfp;
425 
426 	/*
427 	**  Set up some basic system macros.
428 	*/
429 
430 	/* process id */
431 	(void) sprintf(pbuf, "%d", getpid());
432 	define('p', newstr(pbuf), e);
433 
434 	/* hop count */
435 	(void) sprintf(cbuf, "%d", e->e_hopcount);
436 	define('c', newstr(cbuf), e);
437 
438 	/* time as integer, unix time, arpa time */
439 	settime(e);
440 
441 #ifdef TTYNAME
442 	/* tty name */
443 	if (macvalue('y', e) == NULL)
444 	{
445 		p = ttyname(2);
446 		if (p != NULL)
447 		{
448 			if (strrchr(p, '/') != NULL)
449 				p = strrchr(p, '/') + 1;
450 			(void) strcpy(ybuf, p);
451 			define('y', ybuf, e);
452 		}
453 	}
454 #endif /* TTYNAME */
455 }
456 /*
457 **  SETTIME -- set the current time.
458 **
459 **	Parameters:
460 **		none.
461 **
462 **	Returns:
463 **		none.
464 **
465 **	Side Effects:
466 **		Sets the various time macros -- $a, $b, $d, $t.
467 */
468 
469 void
470 settime(e)
471 	register ENVELOPE *e;
472 {
473 	register char *p;
474 	auto time_t now;
475 	char tbuf[20];				/* holds "current" time */
476 	char dbuf[30];				/* holds ctime(tbuf) */
477 	register struct tm *tm;
478 	extern char *arpadate();
479 	extern struct tm *gmtime();
480 
481 	now = curtime();
482 	tm = gmtime(&now);
483 	(void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
484 			tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
485 	define('t', newstr(tbuf), e);
486 	(void) strcpy(dbuf, ctime(&now));
487 	p = strchr(dbuf, '\n');
488 	if (p != NULL)
489 		*p = '\0';
490 	define('d', newstr(dbuf), e);
491 	p = arpadate(dbuf);
492 	p = newstr(p);
493 	if (macvalue('a', e) == NULL)
494 		define('a', p, e);
495 	define('b', p, e);
496 }
497 /*
498 **  OPENXSCRIPT -- Open transcript file
499 **
500 **	Creates a transcript file for possible eventual mailing or
501 **	sending back.
502 **
503 **	Parameters:
504 **		e -- the envelope to create the transcript in/for.
505 **
506 **	Returns:
507 **		none
508 **
509 **	Side Effects:
510 **		Creates the transcript file.
511 */
512 
513 #ifndef O_APPEND
514 #define O_APPEND	0
515 #endif
516 
517 void
518 openxscript(e)
519 	register ENVELOPE *e;
520 {
521 	register char *p;
522 	int fd;
523 
524 	if (e->e_xfp != NULL)
525 		return;
526 	p = queuename(e, 'x');
527 	fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644);
528 	if (fd < 0)
529 	{
530 		syserr("Can't create transcript file %s", p);
531 		fd = open("/dev/null", O_WRONLY, 0644);
532 		if (fd < 0)
533 			syserr("!Can't open /dev/null");
534 	}
535 	e->e_xfp = fdopen(fd, "w");
536 	if (e->e_xfp == NULL)
537 	{
538 		syserr("!Can't create transcript stream %s", p);
539 	}
540 	if (tTd(46, 9))
541 	{
542 		printf("openxscript(%s):\n  ", p);
543 		dumpfd(fileno(e->e_xfp), TRUE, FALSE);
544 	}
545 }
546 /*
547 **  CLOSEXSCRIPT -- close the transcript file.
548 **
549 **	Parameters:
550 **		e -- the envelope containing the transcript to close.
551 **
552 **	Returns:
553 **		none.
554 **
555 **	Side Effects:
556 **		none.
557 */
558 
559 void
560 closexscript(e)
561 	register ENVELOPE *e;
562 {
563 	if (e->e_xfp == NULL)
564 		return;
565 	(void) xfclose(e->e_xfp, "closexscript", e->e_id);
566 	e->e_xfp = NULL;
567 }
568 /*
569 **  SETSENDER -- set the person who this message is from
570 **
571 **	Under certain circumstances allow the user to say who
572 **	s/he is (using -f or -r).  These are:
573 **	1.  The user's uid is zero (root).
574 **	2.  The user's login name is in an approved list (typically
575 **	    from a network server).
576 **	3.  The address the user is trying to claim has a
577 **	    "!" character in it (since #2 doesn't do it for
578 **	    us if we are dialing out for UUCP).
579 **	A better check to replace #3 would be if the
580 **	effective uid is "UUCP" -- this would require me
581 **	to rewrite getpwent to "grab" uucp as it went by,
582 **	make getname more nasty, do another passwd file
583 **	scan, or compile the UID of "UUCP" into the code,
584 **	all of which are reprehensible.
585 **
586 **	Assuming all of these fail, we figure out something
587 **	ourselves.
588 **
589 **	Parameters:
590 **		from -- the person we would like to believe this message
591 **			is from, as specified on the command line.
592 **		e -- the envelope in which we would like the sender set.
593 **		delimptr -- if non-NULL, set to the location of the
594 **			trailing delimiter.
595 **		internal -- set if this address is coming from an internal
596 **			source such as an owner alias.
597 **
598 **	Returns:
599 **		none.
600 **
601 **	Side Effects:
602 **		sets sendmail's notion of who the from person is.
603 */
604 
605 void
606 setsender(from, e, delimptr, internal)
607 	char *from;
608 	register ENVELOPE *e;
609 	char **delimptr;
610 	bool internal;
611 {
612 	register char **pvp;
613 	char *realname = NULL;
614 	register struct passwd *pw;
615 	char delimchar;
616 	char *bp;
617 	char buf[MAXNAME + 2];
618 	char pvpbuf[PSBUFSIZE];
619 	extern struct passwd *getpwnam();
620 	extern char *FullName;
621 
622 	if (tTd(45, 1))
623 		printf("setsender(%s)\n", from == NULL ? "" : from);
624 
625 	/*
626 	**  Figure out the real user executing us.
627 	**	Username can return errno != 0 on non-errors.
628 	*/
629 
630 	if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
631 	    OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
632 		realname = from;
633 	if (realname == NULL || realname[0] == '\0')
634 		realname = username();
635 
636 	if (ConfigLevel < 2)
637 		SuprErrs = TRUE;
638 
639 	delimchar = internal ? '\0' : ' ';
640 	e->e_from.q_flags = QBADADDR;
641 	if (from == NULL ||
642 	    parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
643 		      delimchar, delimptr, e) == NULL ||
644 	    bitset(QBADADDR, e->e_from.q_flags) ||
645 	    e->e_from.q_mailer == ProgMailer ||
646 	    e->e_from.q_mailer == FileMailer ||
647 	    e->e_from.q_mailer == InclMailer)
648 	{
649 		/* log garbage addresses for traceback */
650 # ifdef LOG
651 		if (from != NULL && LogLevel > 2)
652 		{
653 			char *p;
654 			char ebuf[MAXNAME * 2 + 2];
655 
656 			p = macvalue('_', e);
657 			if (p == NULL)
658 			{
659 				char *host = RealHostName;
660 				if (host == NULL)
661 					host = MyHostName;
662 				(void) sprintf(ebuf, "%s@%s", realname, host);
663 				p = ebuf;
664 			}
665 			syslog(LOG_NOTICE,
666 				"setsender: %s: invalid or unparseable, received from %s",
667 				shortenstring(from, 83), p);
668 		}
669 # endif /* LOG */
670 		if (from != NULL)
671 		{
672 			if (!bitset(QBADADDR, e->e_from.q_flags))
673 			{
674 				/* it was a bogus mailer in the from addr */
675 				usrerr("553 Invalid sender address");
676 			}
677 			SuprErrs = TRUE;
678 		}
679 		if (from == realname ||
680 		    parseaddr(from = newstr(realname), &e->e_from,
681 			      RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
682 		{
683 			char nbuf[100];
684 
685 			SuprErrs = TRUE;
686 			expand("\201n", nbuf, &nbuf[sizeof nbuf], e);
687 			if (parseaddr(from = newstr(nbuf), &e->e_from,
688 				      RF_COPYALL, ' ', NULL, e) == NULL &&
689 			    parseaddr(from = "postmaster", &e->e_from,
690 			    	      RF_COPYALL, ' ', NULL, e) == NULL)
691 				syserr("553 setsender: can't even parse postmaster!");
692 		}
693 	}
694 	else
695 		FromFlag = TRUE;
696 	e->e_from.q_flags |= QDONTSEND;
697 	if (tTd(45, 5))
698 	{
699 		printf("setsender: QDONTSEND ");
700 		printaddr(&e->e_from, FALSE);
701 	}
702 	SuprErrs = FALSE;
703 
704 # ifdef USERDB
705 	if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
706 	{
707 		register char *p;
708 		extern char *udbsender();
709 
710 		p = udbsender(e->e_from.q_user);
711 		if (p != NULL)
712 			from = p;
713 	}
714 # endif /* USERDB */
715 
716 	if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
717 	{
718 		if (!internal)
719 		{
720 			/* if the user already given fullname don't redefine */
721 			if (FullName == NULL)
722 				FullName = macvalue('x', e);
723 			if (FullName != NULL && FullName[0] == '\0')
724 				FullName = NULL;
725 		}
726 
727 		if ((pw = getpwnam(e->e_from.q_user)) != NULL)
728 		{
729 			/*
730 			**  Process passwd file entry.
731 			*/
732 
733 			/* extract home directory */
734 			if (strcmp(pw->pw_dir, "/") == 0)
735 				e->e_from.q_home = newstr("");
736 			else
737 				e->e_from.q_home = newstr(pw->pw_dir);
738 			define('z', e->e_from.q_home, e);
739 
740 			/* extract user and group id */
741 			e->e_from.q_uid = pw->pw_uid;
742 			e->e_from.q_gid = pw->pw_gid;
743 			e->e_from.q_flags |= QGOODUID;
744 
745 			/* extract full name from passwd file */
746 			if (FullName == NULL && pw->pw_gecos != NULL &&
747 			    strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
748 			    !internal)
749 			{
750 				buildfname(pw->pw_gecos, e->e_from.q_user, buf);
751 				if (buf[0] != '\0')
752 					FullName = newstr(buf);
753 			}
754 		}
755 		if (FullName != NULL && !internal)
756 			define('x', FullName, e);
757 	}
758 	else if (!internal && OpMode != MD_DAEMON)
759 	{
760 		if (e->e_from.q_home == NULL)
761 		{
762 			e->e_from.q_home = getenv("HOME");
763 			if (e->e_from.q_home != NULL &&
764 			    strcmp(e->e_from.q_home, "/") == 0)
765 				e->e_from.q_home++;
766 		}
767 		e->e_from.q_uid = RealUid;
768 		e->e_from.q_gid = RealGid;
769 		e->e_from.q_flags |= QGOODUID;
770 	}
771 
772 	/*
773 	**  Rewrite the from person to dispose of possible implicit
774 	**	links in the net.
775 	*/
776 
777 	pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL);
778 	if (pvp == NULL)
779 	{
780 		/* don't need to give error -- prescan did that already */
781 # ifdef LOG
782 		if (LogLevel > 2)
783 			syslog(LOG_NOTICE, "cannot prescan from (%s)", from);
784 # endif
785 		finis();
786 	}
787 /*
788 	(void) rewrite(pvp, 3, 0, e);
789 	(void) rewrite(pvp, 1, 0, e);
790 	(void) rewrite(pvp, 4, 0, e);
791 */
792 	bp = buf + 1;
793 	cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
794 	if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
795 	{
796 		/* heuristic: route-addr: add angle brackets */
797 		strcat(bp, ">");
798 		*--bp = '<';
799 	}
800 	e->e_sender = newstr(bp);
801 	define('f', e->e_sender, e);
802 
803 	/* save the domain spec if this mailer wants it */
804 	if (e->e_from.q_mailer != NULL &&
805 	    bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
806 	{
807 		extern char **copyplist();
808 
809 		while (*pvp != NULL && strcmp(*pvp, "@") != 0)
810 			pvp++;
811 		if (*pvp != NULL)
812 			e->e_fromdomain = copyplist(pvp, TRUE);
813 	}
814 }
815