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