envelope.c revision 71345
1/*
2 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#ifndef lint
15static char id[] = "@(#)$Id: envelope.c,v 8.180.14.6 2000/11/30 00:39:46 gshapiro Exp $";
16#endif /* ! lint */
17
18#include <sendmail.h>
19
20
21/*
22**  NEWENVELOPE -- allocate a new envelope
23**
24**	Supports inheritance.
25**
26**	Parameters:
27**		e -- the new envelope to fill in.
28**		parent -- the envelope to be the parent of e.
29**
30**	Returns:
31**		e.
32**
33**	Side Effects:
34**		none.
35*/
36
37ENVELOPE *
38newenvelope(e, parent)
39	register ENVELOPE *e;
40	register ENVELOPE *parent;
41{
42	if (e == parent && e->e_parent != NULL)
43		parent = e->e_parent;
44	clearenvelope(e, TRUE);
45	if (e == CurEnv)
46		memmove((char *) &e->e_from,
47			(char *) &NullAddress,
48			sizeof e->e_from);
49	else
50		memmove((char *) &e->e_from,
51			(char *) &CurEnv->e_from,
52			sizeof e->e_from);
53	e->e_parent = parent;
54	assign_queueid(e);
55	e->e_ctime = curtime();
56	if (parent != NULL)
57		e->e_msgpriority = parent->e_msgsize;
58	e->e_puthdr = putheader;
59	e->e_putbody = putbody;
60	if (CurEnv->e_xfp != NULL)
61		(void) fflush(CurEnv->e_xfp);
62
63	return e;
64}
65/*
66**  DROPENVELOPE -- deallocate an envelope.
67**
68**	Parameters:
69**		e -- the envelope to deallocate.
70**		fulldrop -- if set, do return receipts.
71**
72**	Returns:
73**		none.
74**
75**	Side Effects:
76**		housekeeping necessary to dispose of an envelope.
77**		Unlocks this queue file.
78*/
79
80void
81dropenvelope(e, fulldrop)
82	register ENVELOPE *e;
83	bool fulldrop;
84{
85	bool queueit = FALSE;
86	bool message_timeout = FALSE;
87	bool failure_return = FALSE;
88	bool delay_return = FALSE;
89	bool success_return = FALSE;
90	bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags);
91	bool done = FALSE;
92	register ADDRESS *q;
93	char *id = e->e_id;
94	time_t now;
95	char buf[MAXLINE];
96
97	if (tTd(50, 1))
98	{
99		dprintf("dropenvelope %lx: id=", (u_long) e);
100		xputs(e->e_id);
101		dprintf(", flags=");
102		printenvflags(e);
103		if (tTd(50, 10))
104		{
105			dprintf("sendq=");
106			printaddr(e->e_sendqueue, TRUE);
107		}
108	}
109
110	if (LogLevel > 84)
111		sm_syslog(LOG_DEBUG, id,
112			  "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d",
113			  e->e_flags, OpMode, getpid());
114
115	/* we must have an id to remove disk files */
116	if (id == NULL)
117		return;
118
119	/* if verify-only mode, we can skip most of this */
120	if (OpMode == MD_VERIFY)
121		goto simpledrop;
122
123	if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
124		logsender(e, NULL);
125	e->e_flags &= ~EF_LOGSENDER;
126
127	/* post statistics */
128	poststats(StatFile);
129
130	/*
131	**  Extract state information from dregs of send list.
132	*/
133
134	now = curtime();
135	if (now > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
136		message_timeout = TRUE;
137
138	if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
139	    !bitset(EF_RESPONSE, e->e_flags))
140	{
141		message_timeout = TRUE;
142		e->e_flags |= EF_FATALERRS|EF_CLRQUEUE;
143	}
144
145	e->e_flags &= ~EF_QUEUERUN;
146	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
147	{
148		if (QS_IS_UNDELIVERED(q->q_state))
149			queueit = TRUE;
150
151		/* see if a notification is needed */
152		if (bitset(QPINGONFAILURE, q->q_flags) &&
153		    ((message_timeout && QS_IS_QUEUEUP(q->q_state)) ||
154		     QS_IS_BADADDR(q->q_state) ||
155		     (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
156		      !bitset(EF_RESPONSE, e->e_flags))))
157
158		{
159			failure_return = TRUE;
160			if (!done && q->q_owner == NULL &&
161			    !emptyaddr(&e->e_from))
162			{
163				(void) sendtolist(e->e_from.q_paddr, NULLADDR,
164						  &e->e_errorqueue, 0, e);
165				done = TRUE;
166			}
167		}
168		else if (bitset(QPINGONSUCCESS, q->q_flags) &&
169			 ((QS_IS_SENT(q->q_state) &&
170			   bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) ||
171			  bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags)))
172		{
173			success_return = TRUE;
174		}
175	}
176
177	if (e->e_class < 0)
178		e->e_flags |= EF_NO_BODY_RETN;
179
180	/*
181	**  See if the message timed out.
182	*/
183
184	if (!queueit)
185		/* EMPTY */
186		/* nothing to do */ ;
187	else if (message_timeout)
188	{
189		if (failure_return)
190		{
191			(void) snprintf(buf, sizeof buf,
192					"Cannot send message for %s",
193					pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
194			if (e->e_message != NULL)
195				free(e->e_message);
196			e->e_message = newstr(buf);
197			message(buf);
198			e->e_flags |= EF_CLRQUEUE;
199		}
200		fprintf(e->e_xfp, "Message could not be delivered for %s\n",
201			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
202		fprintf(e->e_xfp, "Message will be deleted from queue\n");
203		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
204		{
205			if (QS_IS_UNDELIVERED(q->q_state))
206			{
207				q->q_state = QS_BADADDR;
208				q->q_status = "4.4.7";
209			}
210		}
211	}
212	else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
213		 now > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
214	{
215		if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
216		    e->e_class >= 0 &&
217		    e->e_from.q_paddr != NULL &&
218		    strcmp(e->e_from.q_paddr, "<>") != 0 &&
219		    strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 &&
220		    (strlen(e->e_from.q_paddr) <= (SIZE_T) 8 ||
221		     strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0))
222		{
223			for (q = e->e_sendqueue; q != NULL; q = q->q_next)
224			{
225				if (QS_IS_QUEUEUP(q->q_state) &&
226#if _FFR_NODELAYDSN_ON_HOLD
227				    !bitnset(M_HOLD, q->q_mailer->m_flags) &&
228#endif /* _FFR_NODELAYDSN_ON_HOLD */
229				    bitset(QPINGONDELAY, q->q_flags))
230				{
231					q->q_flags |= QDELAYED;
232					delay_return = TRUE;
233				}
234			}
235		}
236		if (delay_return)
237		{
238			(void) snprintf(buf, sizeof buf,
239				"Warning: could not send message for past %s",
240				pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
241			if (e->e_message != NULL)
242				free(e->e_message);
243			e->e_message = newstr(buf);
244			message(buf);
245			e->e_flags |= EF_WARNING;
246		}
247		fprintf(e->e_xfp,
248			"Warning: message still undelivered after %s\n",
249			pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
250		fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
251			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
252	}
253
254	if (tTd(50, 2))
255		dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n",
256			failure_return, delay_return, success_return, queueit);
257
258	/*
259	**  If we had some fatal error, but no addresses are marked as
260	**  bad, mark them _all_ as bad.
261	*/
262
263	if (bitset(EF_FATALERRS, e->e_flags) && !failure_return)
264	{
265		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
266		{
267			if ((QS_IS_OK(q->q_state) ||
268			     QS_IS_VERIFIED(q->q_state)) &&
269			    bitset(QPINGONFAILURE, q->q_flags))
270			{
271				failure_return = TRUE;
272				q->q_state = QS_BADADDR;
273			}
274		}
275	}
276
277	/*
278	**  Send back return receipts as requested.
279	*/
280
281	if (success_return && !failure_return && !delay_return && fulldrop &&
282	    !bitset(PRIV_NORECEIPTS, PrivacyFlags) &&
283	    strcmp(e->e_from.q_paddr, "<>") != 0)
284	{
285		auto ADDRESS *rlist = NULL;
286
287		if (tTd(50, 8))
288			dprintf("dropenvelope(%s): sending return receipt\n",
289				id);
290		e->e_flags |= EF_SENDRECEIPT;
291		(void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e);
292		(void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e);
293	}
294	e->e_flags &= ~EF_SENDRECEIPT;
295
296	/*
297	**  Arrange to send error messages if there are fatal errors.
298	*/
299
300	if ((failure_return || delay_return) && e->e_errormode != EM_QUIET)
301	{
302		if (tTd(50, 8))
303			dprintf("dropenvelope(%s): saving mail\n", id);
304		savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags));
305	}
306
307	/*
308	**  Arrange to send warning messages to postmaster as requested.
309	*/
310
311	if ((failure_return || pmnotify) &&
312	    PostMasterCopy != NULL &&
313	    !bitset(EF_RESPONSE, e->e_flags) &&
314	    e->e_class >= 0)
315	{
316		auto ADDRESS *rlist = NULL;
317		char pcopy[MAXNAME];
318
319		if (failure_return)
320		{
321			expand(PostMasterCopy, pcopy, sizeof pcopy, e);
322
323			if (tTd(50, 8))
324				dprintf("dropenvelope(%s): sending postmaster copy to %s\n",
325					id, pcopy);
326			(void) sendtolist(pcopy, NULLADDR, &rlist, 0, e);
327		}
328		if (pmnotify)
329			(void) sendtolist("postmaster", NULLADDR,
330					  &rlist, 0, e);
331		(void) returntosender(e->e_message, rlist,
332				      RTSF_PM_BOUNCE|RTSF_NO_BODY, e);
333	}
334
335	/*
336	**  Instantiate or deinstantiate the queue.
337	*/
338
339simpledrop:
340	if (tTd(50, 8))
341		dprintf("dropenvelope(%s): at simpledrop, queueit=%d\n",
342			id, queueit);
343	if (!queueit || bitset(EF_CLRQUEUE, e->e_flags))
344	{
345		if (tTd(50, 1))
346		{
347			dprintf("\n===== Dropping [dq]f%s... queueit=%d, e_flags=",
348				e->e_id, queueit);
349			printenvflags(e);
350		}
351		xunlink(queuename(e, 'd'));
352		xunlink(queuename(e, 'q'));
353
354		if (e->e_ntries > 0 && LogLevel > 9)
355			sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d",
356				  pintvl(curtime() - e->e_ctime, TRUE),
357				  e->e_ntries);
358	}
359	else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
360	{
361#if QUEUE
362		queueup(e, FALSE);
363#else /* QUEUE */
364		syserr("554 5.3.0 dropenvelope: queueup");
365#endif /* QUEUE */
366	}
367
368	/* now unlock the job */
369	if (tTd(50, 8))
370		dprintf("dropenvelope(%s): unlocking job\n", id);
371	closexscript(e);
372	unlockqueue(e);
373
374	/* make sure that this envelope is marked unused */
375	if (e->e_dfp != NULL)
376		(void) bfclose(e->e_dfp);
377	e->e_dfp = NULL;
378	e->e_id = NULL;
379	e->e_flags &= ~EF_HAS_DF;
380}
381/*
382**  CLEARENVELOPE -- clear an envelope without unlocking
383**
384**	This is normally used by a child process to get a clean
385**	envelope without disturbing the parent.
386**
387**	Parameters:
388**		e -- the envelope to clear.
389**		fullclear - if set, the current envelope is total
390**			garbage and should be ignored; otherwise,
391**			release any resources it may indicate.
392**
393**	Returns:
394**		none.
395**
396**	Side Effects:
397**		Closes files associated with the envelope.
398**		Marks the envelope as unallocated.
399*/
400
401void
402clearenvelope(e, fullclear)
403	register ENVELOPE *e;
404	bool fullclear;
405{
406	register HDR *bh;
407	register HDR **nhp;
408	extern ENVELOPE BlankEnvelope;
409
410	if (!fullclear)
411	{
412		/* clear out any file information */
413		if (e->e_xfp != NULL)
414			(void) bfclose(e->e_xfp);
415		if (e->e_dfp != NULL)
416			(void) bfclose(e->e_dfp);
417		e->e_xfp = e->e_dfp = NULL;
418	}
419
420	/* now clear out the data */
421	STRUCTCOPY(BlankEnvelope, *e);
422	e->e_message = NULL;
423	if (Verbose)
424		set_delivery_mode(SM_DELIVER, e);
425	bh = BlankEnvelope.e_header;
426	nhp = &e->e_header;
427	while (bh != NULL)
428	{
429		*nhp = (HDR *) xalloc(sizeof *bh);
430		memmove((char *) *nhp, (char *) bh, sizeof *bh);
431		bh = bh->h_link;
432		nhp = &(*nhp)->h_link;
433	}
434}
435/*
436**  INITSYS -- initialize instantiation of system
437**
438**	In Daemon mode, this is done in the child.
439**
440**	Parameters:
441**		e -- the envelope to use.
442**
443**	Returns:
444**		none.
445**
446**	Side Effects:
447**		Initializes the system macros, some global variables,
448**		etc.  In particular, the current time in various
449**		forms is set.
450*/
451
452void
453initsys(e)
454	register ENVELOPE *e;
455{
456	char cbuf[5];				/* holds hop count */
457	char pbuf[10];				/* holds pid */
458#ifdef TTYNAME
459	static char ybuf[60];			/* holds tty id */
460	register char *p;
461	extern char *ttyname();
462#endif /* TTYNAME */
463
464	/*
465	**  Give this envelope a reality.
466	**	I.e., an id, a transcript, and a creation time.
467	*/
468
469	setnewqueue(e);
470	openxscript(e);
471	e->e_ctime = curtime();
472#if _FFR_QUEUEDELAY
473	e->e_queuealg = QueueAlg;
474	e->e_queuedelay = QueueInitDelay;
475#endif /* _FFR_QUEUEDELAY */
476
477	/*
478	**  Set OutChannel to something useful if stdout isn't it.
479	**	This arranges that any extra stuff the mailer produces
480	**	gets sent back to the user on error (because it is
481	**	tucked away in the transcript).
482	*/
483
484	if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
485	    e->e_xfp != NULL)
486		OutChannel = e->e_xfp;
487
488	/*
489	**  Set up some basic system macros.
490	*/
491
492	/* process id */
493	(void) snprintf(pbuf, sizeof pbuf, "%d", (int) getpid());
494	define('p', newstr(pbuf), e);
495
496	/* hop count */
497	(void) snprintf(cbuf, sizeof cbuf, "%d", e->e_hopcount);
498	define('c', newstr(cbuf), e);
499
500	/* time as integer, unix time, arpa time */
501	settime(e);
502
503	/* Load average */
504	(void)sm_getla(e);
505
506#ifdef TTYNAME
507	/* tty name */
508	if (macvalue('y', e) == NULL)
509	{
510		p = ttyname(2);
511		if (p != NULL)
512		{
513			if (strrchr(p, '/') != NULL)
514				p = strrchr(p, '/') + 1;
515			snprintf(ybuf, sizeof ybuf, "%s", p);
516			define('y', ybuf, e);
517		}
518	}
519#endif /* TTYNAME */
520}
521/*
522**  SETTIME -- set the current time.
523**
524**	Parameters:
525**		e -- the envelope in which the macros should be set.
526**
527**	Returns:
528**		none.
529**
530**	Side Effects:
531**		Sets the various time macros -- $a, $b, $d, $t.
532*/
533
534void
535settime(e)
536	register ENVELOPE *e;
537{
538	register char *p;
539	auto time_t now;
540	char tbuf[20];				/* holds "current" time */
541	char dbuf[30];				/* holds ctime(tbuf) */
542	register struct tm *tm;
543
544	now = curtime();
545	tm = gmtime(&now);
546	(void) snprintf(tbuf, sizeof tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
547			tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
548	define('t', newstr(tbuf), e);
549	(void) strlcpy(dbuf, ctime(&now), sizeof dbuf);
550	p = strchr(dbuf, '\n');
551	if (p != NULL)
552		*p = '\0';
553	define('d', newstr(dbuf), e);
554	p = arpadate(dbuf);
555	p = newstr(p);
556	if (macvalue('a', e) == NULL)
557		define('a', p, e);
558	define('b', p, e);
559}
560/*
561**  OPENXSCRIPT -- Open transcript file
562**
563**	Creates a transcript file for possible eventual mailing or
564**	sending back.
565**
566**	Parameters:
567**		e -- the envelope to create the transcript in/for.
568**
569**	Returns:
570**		none
571**
572**	Side Effects:
573**		Creates the transcript file.
574*/
575
576#ifndef O_APPEND
577# define O_APPEND	0
578#endif /* ! O_APPEND */
579
580void
581openxscript(e)
582	register ENVELOPE *e;
583{
584	register char *p;
585
586	if (e->e_xfp != NULL)
587		return;
588
589#if 0
590	if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags))
591		syserr("openxscript: job not locked");
592#endif /* 0 */
593
594	p = queuename(e, 'x');
595	e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize,
596			  SFF_NOTEXCL|SFF_OPENASROOT);
597
598	if (e->e_xfp == NULL)
599	{
600		syserr("Can't create transcript file %s", p);
601		e->e_xfp = fopen("/dev/null", "r+");
602		if (e->e_xfp == NULL)
603			syserr("!Can't open /dev/null");
604	}
605#if HASSETVBUF
606	(void) setvbuf(e->e_xfp, NULL, _IOLBF, 0);
607#else /* HASSETVBUF */
608	(void) setlinebuf(e->e_xfp);
609#endif /* HASSETVBUF */
610	if (tTd(46, 9))
611	{
612		dprintf("openxscript(%s):\n  ", p);
613		dumpfd(fileno(e->e_xfp), TRUE, FALSE);
614	}
615}
616/*
617**  CLOSEXSCRIPT -- close the transcript file.
618**
619**	Parameters:
620**		e -- the envelope containing the transcript to close.
621**
622**	Returns:
623**		none.
624**
625**	Side Effects:
626**		none.
627*/
628
629void
630closexscript(e)
631	register ENVELOPE *e;
632{
633	if (e->e_xfp == NULL)
634		return;
635#if 0
636	if (e->e_lockfp == NULL)
637		syserr("closexscript: job not locked");
638#endif /* 0 */
639	(void) bfclose(e->e_xfp);
640	e->e_xfp = NULL;
641}
642/*
643**  SETSENDER -- set the person who this message is from
644**
645**	Under certain circumstances allow the user to say who
646**	s/he is (using -f or -r).  These are:
647**	1.  The user's uid is zero (root).
648**	2.  The user's login name is in an approved list (typically
649**	    from a network server).
650**	3.  The address the user is trying to claim has a
651**	    "!" character in it (since #2 doesn't do it for
652**	    us if we are dialing out for UUCP).
653**	A better check to replace #3 would be if the
654**	effective uid is "UUCP" -- this would require me
655**	to rewrite getpwent to "grab" uucp as it went by,
656**	make getname more nasty, do another passwd file
657**	scan, or compile the UID of "UUCP" into the code,
658**	all of which are reprehensible.
659**
660**	Assuming all of these fail, we figure out something
661**	ourselves.
662**
663**	Parameters:
664**		from -- the person we would like to believe this message
665**			is from, as specified on the command line.
666**		e -- the envelope in which we would like the sender set.
667**		delimptr -- if non-NULL, set to the location of the
668**			trailing delimiter.
669**		delimchar -- the character that will delimit the sender
670**			address.
671**		internal -- set if this address is coming from an internal
672**			source such as an owner alias.
673**
674**	Returns:
675**		none.
676**
677**	Side Effects:
678**		sets sendmail's notion of who the from person is.
679*/
680
681void
682setsender(from, e, delimptr, delimchar, internal)
683	char *from;
684	register ENVELOPE *e;
685	char **delimptr;
686	int delimchar;
687	bool internal;
688{
689	register char **pvp;
690	char *realname = NULL;
691	register struct passwd *pw;
692	char *bp;
693	char buf[MAXNAME + 2];
694	char pvpbuf[PSBUFSIZE];
695	extern char *FullName;
696
697	if (tTd(45, 1))
698		dprintf("setsender(%s)\n", from == NULL ? "" : from);
699
700	/*
701	**  Figure out the real user executing us.
702	**	Username can return errno != 0 on non-errors.
703	*/
704
705	if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
706	    OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
707		realname = from;
708	if (realname == NULL || realname[0] == '\0')
709		realname = username();
710
711	if (ConfigLevel < 2)
712		SuprErrs = TRUE;
713
714#if _FFR_ADDR_TYPE
715	define(macid("{addr_type}", NULL), "e s", e);
716#endif /* _FFR_ADDR_TYPE */
717	/* preset state for then clause in case from == NULL */
718	e->e_from.q_state = QS_BADADDR;
719	e->e_from.q_flags = 0;
720	if (from == NULL ||
721	    parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
722		      delimchar, delimptr, e) == NULL ||
723	    QS_IS_BADADDR(e->e_from.q_state) ||
724	    e->e_from.q_mailer == ProgMailer ||
725	    e->e_from.q_mailer == FileMailer ||
726	    e->e_from.q_mailer == InclMailer)
727	{
728		/* log garbage addresses for traceback */
729		if (from != NULL && LogLevel > 2)
730		{
731			char *p;
732			char ebuf[MAXNAME * 2 + 2];
733
734			p = macvalue('_', e);
735			if (p == NULL)
736			{
737				char *host = RealHostName;
738
739				if (host == NULL)
740					host = MyHostName;
741				(void) snprintf(ebuf, sizeof ebuf, "%.*s@%.*s",
742					MAXNAME, realname,
743					MAXNAME, host);
744				p = ebuf;
745			}
746			sm_syslog(LOG_NOTICE, e->e_id,
747				  "setsender: %s: invalid or unparsable, received from %s",
748				  shortenstring(from, 83), p);
749		}
750		if (from != NULL)
751		{
752			if (!QS_IS_BADADDR(e->e_from.q_state))
753			{
754				/* it was a bogus mailer in the from addr */
755				e->e_status = "5.1.7";
756				usrerrenh(e->e_status,
757					  "553 Invalid sender address");
758			}
759			SuprErrs = TRUE;
760		}
761		if (from == realname ||
762		    parseaddr(from = newstr(realname), &e->e_from,
763			      RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
764		{
765			char nbuf[100];
766
767			SuprErrs = TRUE;
768			expand("\201n", nbuf, sizeof nbuf, e);
769			if (parseaddr(from = newstr(nbuf), &e->e_from,
770				      RF_COPYALL, ' ', NULL, e) == NULL &&
771			    parseaddr(from = "postmaster", &e->e_from,
772				      RF_COPYALL, ' ', NULL, e) == NULL)
773				syserr("553 5.3.0 setsender: can't even parse postmaster!");
774		}
775	}
776	else
777		FromFlag = TRUE;
778	e->e_from.q_state = QS_SENDER;
779	if (tTd(45, 5))
780	{
781		dprintf("setsender: QS_SENDER ");
782		printaddr(&e->e_from, FALSE);
783	}
784	SuprErrs = FALSE;
785
786#if USERDB
787	if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
788	{
789		register char *p;
790
791		p = udbsender(e->e_from.q_user);
792		if (p != NULL)
793			from = p;
794	}
795#endif /* USERDB */
796
797	if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
798	{
799		if (!internal)
800		{
801			/* if the user already given fullname don't redefine */
802			if (FullName == NULL)
803				FullName = macvalue('x', e);
804			if (FullName != NULL && FullName[0] == '\0')
805				FullName = NULL;
806		}
807
808		if (e->e_from.q_user[0] != '\0' &&
809		    (pw = sm_getpwnam(e->e_from.q_user)) != NULL)
810		{
811			/*
812			**  Process passwd file entry.
813			*/
814
815			/* extract home directory */
816			if (*pw->pw_dir == '\0')
817				e->e_from.q_home = NULL;
818			else if (strcmp(pw->pw_dir, "/") == 0)
819				e->e_from.q_home = newstr("");
820			else
821				e->e_from.q_home = newstr(pw->pw_dir);
822			define('z', e->e_from.q_home, e);
823
824			/* extract user and group id */
825			e->e_from.q_uid = pw->pw_uid;
826			e->e_from.q_gid = pw->pw_gid;
827			e->e_from.q_flags |= QGOODUID;
828
829			/* extract full name from passwd file */
830			if (FullName == NULL && pw->pw_gecos != NULL &&
831			    strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
832			    !internal)
833			{
834				buildfname(pw->pw_gecos, e->e_from.q_user, buf, sizeof buf);
835				if (buf[0] != '\0')
836					FullName = newstr(buf);
837			}
838		}
839		else
840		{
841			e->e_from.q_home = NULL;
842		}
843		if (FullName != NULL && !internal)
844			define('x', FullName, e);
845	}
846	else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP)
847	{
848		if (e->e_from.q_home == NULL)
849		{
850			e->e_from.q_home = getenv("HOME");
851			if (e->e_from.q_home != NULL)
852			{
853				if (*e->e_from.q_home == '\0')
854					e->e_from.q_home = NULL;
855				else if (strcmp(e->e_from.q_home, "/") == 0)
856					e->e_from.q_home++;
857			}
858		}
859		e->e_from.q_uid = RealUid;
860		e->e_from.q_gid = RealGid;
861		e->e_from.q_flags |= QGOODUID;
862	}
863
864	/*
865	**  Rewrite the from person to dispose of possible implicit
866	**	links in the net.
867	*/
868
869	pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL);
870	if (pvp == NULL)
871	{
872		/* don't need to give error -- prescan did that already */
873		if (LogLevel > 2)
874			sm_syslog(LOG_NOTICE, e->e_id,
875				  "cannot prescan from (%s)",
876				  shortenstring(from, MAXSHORTSTR));
877		finis(TRUE, ExitStat);
878	}
879	(void) rewrite(pvp, 3, 0, e);
880	(void) rewrite(pvp, 1, 0, e);
881	(void) rewrite(pvp, 4, 0, e);
882#if _FFR_ADDR_TYPE
883	define(macid("{addr_type}", NULL), NULL, e);
884#endif /* _FFR_ADDR_TYPE */
885	bp = buf + 1;
886	cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
887	if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
888	{
889		/* heuristic: route-addr: add angle brackets */
890		(void) strlcat(bp, ">", sizeof buf - 1);
891		*--bp = '<';
892	}
893	e->e_sender = newstr(bp);
894	define('f', e->e_sender, e);
895
896	/* save the domain spec if this mailer wants it */
897	if (e->e_from.q_mailer != NULL &&
898	    bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
899	{
900		char **lastat;
901
902		/* get rid of any pesky angle brackets */
903#if _FFR_ADDR_TYPE
904		define(macid("{addr_type}", NULL), "e s", e);
905#endif /* _FFR_ADDR_TYPE */
906		(void) rewrite(pvp, 3, 0, e);
907		(void) rewrite(pvp, 1, 0, e);
908		(void) rewrite(pvp, 4, 0, e);
909#if _FFR_ADDR_TYPE
910		define(macid("{addr_type}", NULL), NULL, e);
911#endif /* _FFR_ADDR_TYPE */
912
913		/* strip off to the last "@" sign */
914		for (lastat = NULL; *pvp != NULL; pvp++)
915			if (strcmp(*pvp, "@") == 0)
916				lastat = pvp;
917		if (lastat != NULL)
918		{
919			e->e_fromdomain = copyplist(lastat, TRUE);
920			if (tTd(45, 3))
921			{
922				dprintf("Saving from domain: ");
923				printav(e->e_fromdomain);
924			}
925		}
926	}
927}
928/*
929**  PRINTENVFLAGS -- print envelope flags for debugging
930**
931**	Parameters:
932**		e -- the envelope with the flags to be printed.
933**
934**	Returns:
935**		none.
936*/
937
938struct eflags
939{
940	char	*ef_name;
941	u_long	ef_bit;
942};
943
944static struct eflags	EnvelopeFlags[] =
945{
946	{ "OLDSTYLE",		EF_OLDSTYLE	},
947	{ "INQUEUE",		EF_INQUEUE	},
948	{ "NO_BODY_RETN",	EF_NO_BODY_RETN	},
949	{ "CLRQUEUE",		EF_CLRQUEUE	},
950	{ "SENDRECEIPT",	EF_SENDRECEIPT	},
951	{ "FATALERRS",		EF_FATALERRS	},
952	{ "DELETE_BCC",		EF_DELETE_BCC	},
953	{ "RESPONSE",		EF_RESPONSE	},
954	{ "RESENT",		EF_RESENT	},
955	{ "VRFYONLY",		EF_VRFYONLY	},
956	{ "WARNING",		EF_WARNING	},
957	{ "QUEUERUN",		EF_QUEUERUN	},
958	{ "GLOBALERRS",		EF_GLOBALERRS	},
959	{ "PM_NOTIFY",		EF_PM_NOTIFY	},
960	{ "METOO",		EF_METOO	},
961	{ "LOGSENDER",		EF_LOGSENDER	},
962	{ "NORECEIPT",		EF_NORECEIPT	},
963	{ "HAS8BIT",		EF_HAS8BIT	},
964	{ "NL_NOT_EOL",		EF_NL_NOT_EOL	},
965	{ "CRLF_NOT_EOL",	EF_CRLF_NOT_EOL	},
966	{ "RET_PARAM",		EF_RET_PARAM	},
967	{ "HAS_DF",		EF_HAS_DF	},
968	{ "IS_MIME",		EF_IS_MIME	},
969	{ "DONT_MIME",		EF_DONT_MIME	},
970	{ NULL,			0		}
971};
972
973void
974printenvflags(e)
975	register ENVELOPE *e;
976{
977	register struct eflags *ef;
978	bool first = TRUE;
979
980	printf("%lx", e->e_flags);
981	for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++)
982	{
983		if (!bitset(ef->ef_bit, e->e_flags))
984			continue;
985		if (first)
986			printf("<%s", ef->ef_name);
987		else
988			printf(",%s", ef->ef_name);
989		first = FALSE;
990	}
991	if (!first)
992		printf(">\n");
993}
994