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