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