1 # include <stdio.h>
2 # include <pwd.h>
3 # include <signal.h>
4 # include <ctype.h>
5 # include "sendmail.h"
6 # ifdef LOG
7 # include <syslog.h>
8 # endif LOG
9 
10 static char SccsId[] = "@(#)deliver.c	3.19	08/10/81";
11 
12 /*
13 **  DELIVER -- Deliver a message to a particular address.
14 **
15 **	Parameters:
16 **		to -- the address to deliver the message to.
17 **		editfcn -- if non-NULL, we want to call this function
18 **			to output the letter (instead of just out-
19 **			putting it raw).
20 **
21 **	Returns:
22 **		zero -- successfully delivered.
23 **		else -- some failure, see ExitStat for more info.
24 **
25 **	Side Effects:
26 **		The standard input is passed off to someone.
27 */
28 
29 deliver(to, editfcn)
30 	ADDRESS *to;
31 	int (*editfcn)();
32 {
33 	char *host;
34 	char *user;
35 	char **pvp;
36 	register char **mvp;
37 	register char *p;
38 	register struct mailer *m;
39 	register int i;
40 	extern putmessage();
41 	extern bool checkcompat();
42 	char *pv[MAXPV+1];
43 	char tobuf[MAXLINE];
44 	char buf[MAXNAME];
45 	bool firstone;
46 
47 	if (bitset(QDONTSEND, to->q_flags))
48 		return (0);
49 
50 # ifdef DEBUG
51 	if (Debug)
52 		printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
53 			to->q_mailer, to->q_host, to->q_user);
54 # endif DEBUG
55 
56 	/*
57 	**  Do initial argv setup.
58 	**	Insert the mailer name.  Notice that $x expansion is
59 	**	NOT done on the mailer name.  Then, if the mailer has
60 	**	a picky -f flag, we insert it as appropriate.  This
61 	**	code does not check for 'pv' overflow; this places a
62 	**	manifest lower limit of 4 for MAXPV.
63 	*/
64 
65 	m = Mailer[to->q_mailer];
66 	host = to->q_host;
67 	define('g', m->m_from);		/* translated from address */
68 	define('h', host);		/* to host */
69 	Errors = 0;
70 	errno = 0;
71 	pvp = pv;
72 	*pvp++ = m->m_argv[0];
73 
74 	/* insert -f or -r flag as appropriate */
75 	if (bitset(M_FOPT|M_ROPT, m->m_flags) && FromFlag)
76 	{
77 		if (bitset(M_FOPT, m->m_flags))
78 			*pvp++ = "-f";
79 		else
80 			*pvp++ = "-r";
81 		(void) expand("$g", buf, &buf[sizeof buf - 1]);
82 		*pvp++ = newstr(buf);
83 	}
84 
85 	/*
86 	**  Append the other fixed parts of the argv.  These run
87 	**  up to the first entry containing "$u".  There can only
88 	**  be one of these, and there are only a few more slots
89 	**  in the pv after it.
90 	*/
91 
92 	for (mvp = m->m_argv; (p = *++mvp) != NULL; )
93 	{
94 		while ((p = index(p, '$')) != NULL)
95 			if (*++p == 'u')
96 				break;
97 		if (p != NULL)
98 			break;
99 
100 		/* this entry is safe -- go ahead and process it */
101 		(void) expand(*mvp, buf, &buf[sizeof buf - 1]);
102 		*pvp++ = newstr(buf);
103 		if (pvp >= &pv[MAXPV - 3])
104 		{
105 			syserr("Too many parameters to %s before $u", pv[0]);
106 			return (-1);
107 		}
108 	}
109 	if (*mvp == NULL)
110 		syserr("No $u in mailer argv for %s", pv[0]);
111 
112 	/*
113 	**  At this point *mvp points to the argument with $u.  We
114 	**  run through our address list and append all the addresses
115 	**  we can.  If we run out of space, do not fret!  We can
116 	**  always send another copy later.
117 	*/
118 
119 	tobuf[0] = '\0';
120 	firstone = TRUE;
121 	To = tobuf;
122 	for (; to != NULL; to = to->q_next)
123 	{
124 		/* avoid sending multiple recipients to dumb mailers */
125 		if (!firstone && !bitset(M_MUSER, m->m_flags))
126 			break;
127 
128 		/* if already sent or not for this host, don't send */
129 		if (bitset(QDONTSEND, to->q_flags) || strcmp(to->q_host, host) != 0)
130 			continue;
131 		user = to->q_user;
132 		To = to->q_paddr;
133 		to->q_flags |= QDONTSEND;
134 		firstone = FALSE;
135 
136 # ifdef DEBUG
137 		if (Debug)
138 			printf("   send to `%s'\n", user);
139 # endif DEBUG
140 
141 		/*
142 		**  Check to see that these people are allowed to
143 		**  talk to each other.
144 		*/
145 
146 		if (!checkcompat(to))
147 		{
148 			giveresponse(EX_UNAVAILABLE, TRUE, m);
149 			continue;
150 		}
151 
152 		/*
153 		**  Strip quote bits from names if the mailer is dumb
154 		**	about them.
155 		*/
156 
157 		if (bitset(M_STRIPQ, m->m_flags))
158 		{
159 			stripquotes(user, TRUE);
160 			stripquotes(host, TRUE);
161 		}
162 		else
163 		{
164 			stripquotes(user, FALSE);
165 			stripquotes(host, FALSE);
166 		}
167 
168 		/*
169 		**  See if this user name is "special".
170 		**	If the user name has a slash in it, assume that this
171 		**	is a file -- send it off without further ado.
172 		**	Note that this means that editfcn's will not
173 		**	be applied to the message.  Also note that
174 		**	this type of addresses is not processed along
175 		**	with the others, so we fudge on the To person.
176 		*/
177 
178 		if (m == Mailer[M_LOCAL])
179 		{
180 			if (index(user, '/') != NULL)
181 			{
182 				i = mailfile(user);
183 				giveresponse(i, TRUE, m);
184 				continue;
185 			}
186 		}
187 
188 		/*
189 		**  See if the user exists.
190 		**	Strictly, this is only needed to print a pretty
191 		**	error message.
192 		**
193 		**	>>>>>>>>>> This clause assumes that the local mailer
194 		**	>> NOTE >> cannot do any further aliasing; that
195 		**	>>>>>>>>>> function is subsumed by sendmail.
196 		*/
197 
198 		if (bitset(QBADADDR, to->q_flags))
199 		{
200 			giveresponse(EX_NOUSER, TRUE, m);
201 			continue;
202 		}
203 
204 		/* create list of users for error messages */
205 		if (tobuf[0] != '\0')
206 			(void) strcat(tobuf, ",");
207 		(void) strcat(tobuf, to->q_paddr);
208 		define('u', user);		/* to user */
209 		define('z', to->q_home);	/* user's home */
210 
211 		/* expand out this user */
212 		(void) expand(user, buf, &buf[sizeof buf - 1]);
213 		*pvp++ = newstr(buf);
214 		if (pvp >= &pv[MAXPV - 2])
215 		{
216 			/* allow some space for trailing parms */
217 			break;
218 		}
219 	}
220 
221 	/* see if any addresses still exist */
222 	if (tobuf[0] == '\0')
223 		return (0);
224 
225 	/* print out messages as full list */
226 	To = tobuf;
227 
228 	/*
229 	**  Fill out any parameters after the $u parameter.
230 	*/
231 
232 	while (*++mvp != NULL)
233 	{
234 		(void) expand(*mvp, buf, &buf[sizeof buf - 1]);
235 		*pvp++ = newstr(buf);
236 		if (pvp >= &pv[MAXPV])
237 			syserr("deliver: pv overflow after $u for %s", pv[0]);
238 	}
239 	*pvp++ = NULL;
240 
241 	/*
242 	**  Call the mailer.
243 	**	The argument vector gets built, pipes
244 	**	are created as necessary, and we fork & exec as
245 	**	appropriate.
246 	**
247 	**	Notice the tacky hack to handle private mailers.
248 	*/
249 
250 	if (editfcn == NULL)
251 		editfcn = putmessage;
252 	i = sendoff(m, pv, editfcn);
253 
254 	return (i);
255 }
256 /*
257 **  SENDOFF -- send off call to mailer & collect response.
258 **
259 **	Parameters:
260 **		m -- mailer descriptor.
261 **		pvp -- parameter vector to send to it.
262 **		editfcn -- function to pipe it through.
263 **
264 **	Returns:
265 **		exit status of mailer.
266 **
267 **	Side Effects:
268 **		none.
269 */
270 
271 #define NFORKTRIES	5
272 
273 sendoff(m, pvp, editfcn)
274 	struct mailer *m;
275 	char **pvp;
276 	int (*editfcn)();
277 {
278 	auto int st;
279 	register int i;
280 	int pid;
281 	int pvect[2];
282 	FILE *mfile;
283 	extern putmessage();
284 	extern pipesig();
285 	extern FILE *fdopen();
286 
287 # ifdef DEBUG
288 	if (Debug)
289 	{
290 		printf("Sendoff:\n");
291 		printav(pvp);
292 	}
293 # endif DEBUG
294 
295 	/* create a pipe to shove the mail through */
296 	if (pipe(pvect) < 0)
297 	{
298 		syserr("pipe");
299 		return (-1);
300 	}
301 	for (i = NFORKTRIES; i-- > 0; )
302 	{
303 # ifdef VFORK
304 		pid = vfork();
305 # else
306 		pid = fork();
307 # endif
308 		if (pid >= 0)
309 			break;
310 		sleep((unsigned) NFORKTRIES - i);
311 	}
312 	if (pid < 0)
313 	{
314 		syserr("Cannot fork");
315 		(void) close(pvect[0]);
316 		(void) close(pvect[1]);
317 		return (-1);
318 	}
319 	else if (pid == 0)
320 	{
321 		/* child -- set up input & exec mailer */
322 		/* make diagnostic output be standard output */
323 		(void) close(2);
324 		(void) dup(1);
325 		(void) signal(SIGINT, SIG_IGN);
326 		(void) close(0);
327 		if (dup(pvect[0]) < 0)
328 		{
329 			syserr("Cannot dup to zero!");
330 			_exit(EX_OSERR);
331 		}
332 		(void) close(pvect[0]);
333 		(void) close(pvect[1]);
334 		if (!bitset(M_RESTR, m->m_flags))
335 			(void) setuid(getuid());
336 # ifndef VFORK
337 		/*
338 		**  We have to be careful with vfork - we can't mung up the
339 		**  memory but we don't want the mailer to inherit any extra
340 		**  open files.  Chances are the mailer won't
341 		**  care about an extra file, but then again you never know.
342 		**  Actually, we would like to close(fileno(pwf)), but it's
343 		**  declared static so we can't.  But if we fclose(pwf), which
344 		**  is what endpwent does, it closes it in the parent too and
345 		**  the next getpwnam will be slower.  If you have a weird
346 		**  mailer that chokes on the extra file you should do the
347 		**  endpwent().
348 		**
349 		**  Similar comments apply to log.  However, openlog is
350 		**  clever enough to set the FIOCLEX mode on the file,
351 		**  so it will be closed automatically on the exec.
352 		*/
353 
354 		endpwent();
355 # ifdef LOG
356 		closelog();
357 # endif LOG
358 # endif VFORK
359 		execv(m->m_mailer, pvp);
360 		/* syserr fails because log is closed */
361 		/* syserr("Cannot exec %s", m->m_mailer); */
362 		printf("Cannot exec %s\n", m->m_mailer);
363 		(void) fflush(stdout);
364 		_exit(EX_UNAVAILABLE);
365 	}
366 
367 	/* write out message to mailer */
368 	(void) close(pvect[0]);
369 	(void) signal(SIGPIPE, pipesig);
370 	mfile = fdopen(pvect[1], "w");
371 	if (editfcn == NULL)
372 		editfcn = putmessage;
373 	(*editfcn)(mfile, m);
374 	(void) fclose(mfile);
375 
376 	/*
377 	**  Wait for child to die and report status.
378 	**	We should never get fatal errors (e.g., segmentation
379 	**	violation), so we report those specially.  For other
380 	**	errors, we choose a status message (into statmsg),
381 	**	and if it represents an error, we print it.
382 	*/
383 
384 	while ((i = wait(&st)) > 0 && i != pid)
385 		continue;
386 	if (i < 0)
387 	{
388 		syserr("wait");
389 		return (-1);
390 	}
391 	if ((st & 0377) != 0)
392 	{
393 		syserr("%s: stat %o", pvp[0], st);
394 		ExitStat = EX_UNAVAILABLE;
395 		return (-1);
396 	}
397 	i = (st >> 8) & 0377;
398 	giveresponse(i, TRUE, m);
399 	return (i);
400 }
401 /*
402 **  GIVERESPONSE -- Interpret an error response from a mailer
403 **
404 **	Parameters:
405 **		stat -- the status code from the mailer (high byte
406 **			only; core dumps must have been taken care of
407 **			already).
408 **		force -- if set, force an error message output, even
409 **			if the mailer seems to like to print its own
410 **			messages.
411 **		m -- the mailer descriptor for this mailer.
412 **
413 **	Returns:
414 **		none.
415 **
416 **	Side Effects:
417 **		Errors may be incremented.
418 **		ExitStat may be set.
419 **
420 **	Called By:
421 **		deliver
422 */
423 
424 giveresponse(stat, force, m)
425 	int stat;
426 	int force;
427 	register struct mailer *m;
428 {
429 	register char *statmsg;
430 	extern char *SysExMsg[];
431 	register int i;
432 	extern int N_SysEx;
433 	extern long MsgSize;
434 	char buf[30];
435 
436 	i = stat - EX__BASE;
437 	if (i < 0 || i > N_SysEx)
438 		statmsg = NULL;
439 	else
440 		statmsg = SysExMsg[i];
441 	if (stat == 0)
442 	{
443 		statmsg = "ok";
444 		if (Verbose)
445 			message("050", "ok");
446 	}
447 	else
448 	{
449 		Errors++;
450 		if (statmsg == NULL && m->m_badstat != 0)
451 		{
452 			stat = m->m_badstat;
453 			i = stat - EX__BASE;
454 # ifdef DEBUG
455 			if (i < 0 || i >= N_SysEx)
456 				syserr("Bad m_badstat %d", stat);
457 			else
458 # endif DEBUG
459 			statmsg = SysExMsg[i];
460 		}
461 		if (statmsg == NULL)
462 			usrerr("unknown mailer response %d", stat);
463 		else if (force || !bitset(M_QUIET, m->m_flags) || Verbose)
464 			usrerr("%s", statmsg);
465 	}
466 
467 	/*
468 	**  Final cleanup.
469 	**	Log a record of the transaction.  Compute the new
470 	**	ExitStat -- if we already had an error, stick with
471 	**	that.
472 	*/
473 
474 	if (statmsg == NULL)
475 	{
476 		(void) sprintf(buf, "error %d", stat);
477 		statmsg = buf;
478 	}
479 
480 # ifdef LOG
481 	syslog(LOG_INFO, "%s->%s: %ld: %s", From.q_paddr, To, MsgSize, statmsg);
482 # endif LOG
483 	setstat(stat);
484 }
485 /*
486 **  PUTMESSAGE -- output a message to the final mailer.
487 **
488 **	This routine takes care of recreating the header from the
489 **	in-core copy, etc.
490 **
491 **	Parameters:
492 **		fp -- file to output onto.
493 **		m -- a mailer descriptor.
494 **
495 **	Returns:
496 **		none.
497 **
498 **	Side Effects:
499 **		The message is written onto fp.
500 */
501 
502 putmessage(fp, m)
503 	FILE *fp;
504 	struct mailer *m;
505 {
506 	char buf[BUFSIZ];
507 	register int i;
508 	HDR *h;
509 	register char *p;
510 	extern char *arpadate();
511 	bool anyheader = FALSE;
512 	extern char *capitalize();
513 
514 	/* output "From" line unless supressed */
515 	if (!bitset(M_NHDR, m->m_flags))
516 		fprintf(fp, "%s\n", FromLine);
517 
518 	/* output all header lines */
519 	for (h = Header; h != NULL; h = h->h_link)
520 	{
521 		if (bitset(H_DELETE, h->h_flags))
522 			continue;
523 		if (bitset(H_CHECK|H_ACHECK, h->h_flags) && !bitset(h->h_mflags, m->m_flags))
524 			continue;
525 		if (bitset(H_DEFAULT, h->h_flags))
526 		{
527 			(void) expand(h->h_value, buf, &buf[sizeof buf]);
528 			p = buf;
529 		}
530 		else
531 			p = h->h_value;
532 		if (*p == '\0')
533 			continue;
534 		fprintf(fp, "%s: %s\n", capitalize(h->h_field), p);
535 		h->h_flags |= H_USED;
536 		anyheader = TRUE;
537 	}
538 
539 	if (anyheader)
540 		fprintf(fp, "\n");
541 
542 	/* output the body of the message */
543 	rewind(stdin);
544 	while (!ferror(fp) && (i = fread(buf, 1, BUFSIZ, stdin)) > 0)
545 		(void) fwrite(buf, 1, i, fp);
546 
547 	if (ferror(fp))
548 	{
549 		syserr("putmessage: write error");
550 		setstat(EX_IOERR);
551 	}
552 }
553 /*
554 **  PIPESIG -- Handle broken pipe signals
555 **
556 **	This just logs an error.
557 **
558 **	Parameters:
559 **		none
560 **
561 **	Returns:
562 **		none
563 **
564 **	Side Effects:
565 **		logs an error message.
566 */
567 
568 pipesig()
569 {
570 	syserr("Broken pipe");
571 	(void) signal(SIGPIPE, SIG_IGN);
572 }
573 /*
574 **  SENDTO -- Designate a send list.
575 **
576 **	The parameter is a comma-separated list of people to send to.
577 **	This routine arranges to send to all of them.
578 **
579 **	Parameters:
580 **		list -- the send list.
581 **		copyf -- the copy flag; passed to parse.
582 **
583 **	Returns:
584 **		none
585 **
586 **	Side Effects:
587 **		none.
588 */
589 
590 # define MAXRCRSN	10
591 
592 sendto(list, copyf)
593 	char *list;
594 	int copyf;
595 {
596 	register char *p;
597 	register char *q;
598 	register char c;
599 	ADDRESS *a;
600 	bool more;
601 
602 	/* more keeps track of what the previous delimiter was */
603 	more = TRUE;
604 	for (p = list; more; )
605 	{
606 		/* find the end of this address */
607 		q = p;
608 		while ((c = *p++) != '\0' && c != ',' && c != '\n')
609 			continue;
610 		more = c != '\0';
611 		*--p = '\0';
612 		if (more)
613 			p++;
614 
615 		/* parse the address */
616 		if ((a = parse(q, (ADDRESS *) NULL, copyf)) == NULL)
617 			continue;
618 
619 		/* arrange to send to this person */
620 		recipient(a);
621 	}
622 	To = NULL;
623 }
624 /*
625 **  RECIPIENT -- Designate a message recipient
626 **
627 **	Saves the named person for future mailing.
628 **
629 **	Parameters:
630 **		a -- the (preparsed) address header for the recipient.
631 **
632 **	Returns:
633 **		none.
634 **
635 **	Side Effects:
636 **		none.
637 */
638 
639 recipient(a)
640 	register ADDRESS *a;
641 {
642 	register ADDRESS *q;
643 	register struct mailer *m;
644 	char buf[MAXNAME];
645 
646 	To = a->q_paddr;
647 	m = Mailer[a->q_mailer];
648 	errno = 0;
649 # ifdef DEBUG
650 	if (Debug)
651 		printf("recipient(%s)\n", To);
652 # endif DEBUG
653 
654 	/* break aliasing loops */
655 	if (AliasLevel > MAXRCRSN)
656 	{
657 		usrerr("aliasing/forwarding loop broken");
658 		return;
659 	}
660 
661 	/*
662 	**  Do sickly crude mapping for program mailing, etc.
663 	*/
664 
665 	if (a->q_mailer == M_LOCAL)
666 	{
667 		if (a->q_user[0] == '|')
668 		{
669 			a->q_mailer = M_PROG;
670 			m = Mailer[M_PROG];
671 			a->q_user++;
672 		}
673 	}
674 
675 	/*
676 	**  Look up this person in the recipient list.  If they
677 	**  are there already, return, otherwise continue.
678 	**  If the list is empty, just add it.
679 	*/
680 
681 	if (m->m_sendq == NULL)
682 	{
683 		m->m_sendq = a;
684 	}
685 	else
686 	{
687 		ADDRESS *pq;
688 
689 		for (q = m->m_sendq; q != NULL; pq = q, q = q->q_next)
690 		{
691 			if (!ForceMail && sameaddr(q, a, FALSE))
692 			{
693 # ifdef DEBUG
694 				if (Debug)
695 					printf("(%s in sendq)\n", a->q_paddr);
696 # endif DEBUG
697 				if (Verbose && !bitset(QDONTSEND, a->q_flags))
698 					message("050", "duplicate supressed");
699 				return;
700 			}
701 		}
702 
703 		/* add address on list */
704 		q = pq;
705 		q->q_next = a;
706 	}
707 	a->q_next = NULL;
708 
709 	/*
710 	**  Alias the name.
711 	*/
712 
713 	if (a->q_mailer == M_LOCAL)
714 		alias(a);
715 
716 	/*
717 	**  If the user is local and still being sent, verify that
718 	**  the address is good.  If it is, try to forward.
719 	**  If the address is already good, we have a forwarding
720 	**  loop.  This can be broken by just sending directly to
721 	**  the user (which is probably correct anyway).
722 	*/
723 
724 	if (!bitset(QDONTSEND, a->q_flags) && a->q_mailer == M_LOCAL &&
725 	    a->q_home == NULL)
726 	{
727 		register struct passwd *pw;
728 		extern struct passwd *getpwnam();
729 		char buf[MAXNAME];
730 
731 		strcpy(buf, a->q_user);
732 		stripquotes(buf, TRUE);
733 		pw = getpwnam(buf);
734 		if (pw == NULL)
735 			a->q_flags |= QBADADDR;
736 		else
737 		{
738 			a->q_home = newstr(pw->pw_dir);
739 			if (strcmp(buf, a->q_user) == 0)
740 				forward(a);
741 		}
742 	}
743 
744 	return;
745 }
746 /*
747 **  MAILFILE -- Send a message to a file.
748 **
749 **	Parameters:
750 **		filename -- the name of the file to send to.
751 **
752 **	Returns:
753 **		The exit code associated with the operation.
754 **
755 **	Side Effects:
756 **		none.
757 **
758 **	Called By:
759 **		deliver
760 */
761 
762 mailfile(filename)
763 	char *filename;
764 {
765 	register FILE *f;
766 
767 	f = fopen(filename, "a");
768 	if (f == NULL)
769 		return (EX_CANTCREAT);
770 
771 	putmessage(f, Mailer[1]);
772 	fputs("\n", f);
773 	(void) fclose(f);
774 	return (EX_OK);
775 }
776