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