1 /*
2  * Copyright (c) 1983 Eric P. Allman
3  * Copyright (c) 1988 Regents of the University of California.
4  * All rights reserved.
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 #ifndef lint
10 static char sccsid[] = "@(#)recipient.c	6.5 (Berkeley) 01/28/93";
11 #endif /* not lint */
12 
13 # include <sys/types.h>
14 # include <sys/stat.h>
15 # include <sys/file.h>
16 # include <sys/fcntl.h>
17 # include <pwd.h>
18 # include "sendmail.h"
19 
20 /*
21 **  SENDTOLIST -- Designate a send list.
22 **
23 **	The parameter is a comma-separated list of people to send to.
24 **	This routine arranges to send to all of them.
25 **
26 **	Parameters:
27 **		list -- the send list.
28 **		ctladdr -- the address template for the person to
29 **			send to -- effective uid/gid are important.
30 **			This is typically the alias that caused this
31 **			expansion.
32 **		sendq -- a pointer to the head of a queue to put
33 **			these people into.
34 **
35 **	Returns:
36 **		none
37 **
38 **	Side Effects:
39 **		none.
40 */
41 
42 # define MAXRCRSN	10
43 
44 sendtolist(list, ctladdr, sendq, e)
45 	char *list;
46 	ADDRESS *ctladdr;
47 	ADDRESS **sendq;
48 	register ENVELOPE *e;
49 {
50 	register char *p;
51 	register ADDRESS *al;	/* list of addresses to send to */
52 	bool firstone;		/* set on first address sent */
53 	bool selfref;		/* set if this list includes ctladdr */
54 	char delimiter;		/* the address delimiter */
55 
56 	if (tTd(25, 1))
57 	{
58 		printf("sendto: %s\n   ctladdr=", list);
59 		printaddr(ctladdr, FALSE);
60 	}
61 
62 	/* heuristic to determine old versus new style addresses */
63 	if (ctladdr == NULL &&
64 	    (strchr(list, ',') != NULL || strchr(list, ';') != NULL ||
65 	     strchr(list, '<') != NULL || strchr(list, '(') != NULL))
66 		e->e_flags &= ~EF_OLDSTYLE;
67 	delimiter = ' ';
68 	if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL)
69 		delimiter = ',';
70 
71 	firstone = TRUE;
72 	selfref = FALSE;
73 	al = NULL;
74 
75 	for (p = list; *p != '\0'; )
76 	{
77 		register ADDRESS *a;
78 		extern char *DelimChar;		/* defined in prescan */
79 
80 		/* parse the address */
81 		while (isspace(*p) || *p == ',')
82 			p++;
83 		a = parseaddr(p, (ADDRESS *) NULL, 1, delimiter, e);
84 		p = DelimChar;
85 		if (a == NULL)
86 			continue;
87 		a->q_next = al;
88 		a->q_alias = ctladdr;
89 
90 		/* see if this should be marked as a primary address */
91 		if (ctladdr == NULL ||
92 		    (firstone && *p == '\0' && bitset(QPRIMARY, ctladdr->q_flags)))
93 			a->q_flags |= QPRIMARY;
94 
95 		if (ctladdr != NULL && sameaddr(ctladdr, a))
96 			selfref = TRUE;
97 		al = a;
98 		firstone = FALSE;
99 	}
100 
101 	/* if this alias doesn't include itself, delete ctladdr */
102 	if (!selfref && ctladdr != NULL)
103 	{
104 		if (tTd(25, 5))
105 		{
106 			printf("sendtolist: QDONTSEND ");
107 			printaddr(ctladdr, FALSE);
108 		}
109 		ctladdr->q_flags |= QDONTSEND;
110 	}
111 
112 	/* arrange to send to everyone on the local send list */
113 	while (al != NULL)
114 	{
115 		register ADDRESS *a = al;
116 		extern ADDRESS *recipient();
117 
118 		al = a->q_next;
119 		a = recipient(a, sendq, e);
120 
121 		/* arrange to inherit full name */
122 		if (a->q_fullname == NULL && ctladdr != NULL)
123 			a->q_fullname = ctladdr->q_fullname;
124 	}
125 
126 	e->e_to = NULL;
127 }
128 /*
129 **  RECIPIENT -- Designate a message recipient
130 **
131 **	Saves the named person for future mailing.
132 **
133 **	Parameters:
134 **		a -- the (preparsed) address header for the recipient.
135 **		sendq -- a pointer to the head of a queue to put the
136 **			recipient in.  Duplicate supression is done
137 **			in this queue.
138 **		e -- the current envelope.
139 **
140 **	Returns:
141 **		The actual address in the queue.  This will be "a" if
142 **		the address is not a duplicate, else the original address.
143 **
144 **	Side Effects:
145 **		none.
146 */
147 
148 extern ADDRESS *getctladdr();
149 extern char	*RcptLogFile;
150 
151 ADDRESS *
152 recipient(a, sendq, e)
153 	register ADDRESS *a;
154 	register ADDRESS **sendq;
155 	register ENVELOPE *e;
156 {
157 	register ADDRESS *q;
158 	ADDRESS **pq;
159 	register struct mailer *m;
160 	register char *p;
161 	bool quoted = FALSE;		/* set if the addr has a quote bit */
162 	int findusercount = 0;
163 	char buf[MAXNAME];		/* unquoted image of the user name */
164 	extern bool safefile();
165 
166 	e->e_to = a->q_paddr;
167 	m = a->q_mailer;
168 	errno = 0;
169 	if (tTd(26, 1))
170 	{
171 		printf("\nrecipient: ");
172 		printaddr(a, FALSE);
173 	}
174 
175 	/* break aliasing loops */
176 	if (AliasLevel > MAXRCRSN)
177 	{
178 		usrerr("aliasing/forwarding loop broken");
179 		return (a);
180 	}
181 
182 	/*
183 	**  Finish setting up address structure.
184 	*/
185 
186 	/* set the queue timeout */
187 	a->q_timeout = TimeOut;
188 
189 	/* map user & host to lower case if requested on non-aliases */
190 	if (a->q_alias == NULL)
191 		loweraddr(a);
192 
193 	/* get unquoted user for file, program or user.name check */
194 	(void) strcpy(buf, a->q_user);
195 	for (p = buf; *p != '\0' && !quoted; p++)
196 	{
197 		if (*p == '\\')
198 			quoted = TRUE;
199 	}
200 	stripquotes(buf);
201 
202 	/* check for direct mailing to restricted mailers */
203 	if (a->q_alias == NULL && m == ProgMailer)
204 	{
205 		a->q_flags |= QDONTSEND|QBADADDR;
206 		usrerr("Cannot mail directly to programs", m->m_name);
207 	}
208 
209 	/*
210 	**  Look up this person in the recipient list.
211 	**	If they are there already, return, otherwise continue.
212 	**	If the list is empty, just add it.  Notice the cute
213 	**	hack to make from addresses suppress things correctly:
214 	**	the QDONTSEND bit will be set in the send list.
215 	**	[Please note: the emphasis is on "hack."]
216 	*/
217 
218 	for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next)
219 	{
220 		if (!ForceMail && sameaddr(q, a))
221 		{
222 			if (tTd(26, 1))
223 			{
224 				printf("%s in sendq: ", a->q_paddr);
225 				printaddr(q, FALSE);
226 			}
227 			if (!bitset(QDONTSEND, a->q_flags))
228 				message(Arpa_Info, "duplicate suppressed");
229 			if (!bitset(QPRIMARY, q->q_flags))
230 				q->q_flags |= a->q_flags;
231 			return (q);
232 		}
233 	}
234 
235 	/* add address on list */
236 	*pq = a;
237 	a->q_next = NULL;
238 
239 	if (a->q_alias == NULL && RcptLogFile != NULL &&
240 	    !bitset(QDONTSEND, a->q_flags))
241 	{
242 		static int RcptLogFd = -1;
243 
244 		/*
245 		**  Log the incoming recipient name before aliasing,
246 		**  expanding, forwarding, rewriting, and all that jazz.
247 		**  We'll use this to track down out-of-date aliases,
248 		**  host names, and so forth.
249 		*/
250 
251 		if (RcptLogFd < 0)
252 		{
253 			/* try to open the log file */
254 			RcptLogFd = open(RcptLogFile, O_WRONLY|O_APPEND|O_CREAT, 0666);
255 			if (RcptLogFd >= 0)
256 				(void) fcntl(RcptLogFd, F_SETFD, 1);
257 		}
258 		if (RcptLogFd >= 0)
259 		{
260 			int l = strlen(a->q_paddr);
261 
262 			a->q_paddr[l] = '\n';
263 			if (write(RcptLogFd, a->q_paddr, l + 1) < 0)
264 			{
265 				(void) close(RcptLogFd);
266 				RcptLogFd = -1;
267 			}
268 			a->q_paddr[l] = '\0';
269 		}
270 	}
271 
272 	/*
273 	**  Alias the name and handle special mailer types.
274 	*/
275 
276   trylocaluser:
277 	if (tTd(29, 7))
278 		printf("at trylocaluser %s\n", a->q_user);
279 
280 	if (bitset(QDONTSEND, a->q_flags))
281 		return (a);
282 
283 	if (m == InclMailer)
284 	{
285 		a->q_flags |= QDONTSEND;
286 		if (a->q_alias == NULL)
287 		{
288 			a->q_flags |= QBADADDR;
289 			usrerr("Cannot mail directly to :include:s");
290 		}
291 		else
292 		{
293 			message(Arpa_Info, "including file %s", &a->q_user[9]);
294 			(void) include(&a->q_user[9], FALSE, a, sendq, e);
295 		}
296 	}
297 	else if (m == FileMailer)
298 	{
299 		struct stat stb;
300 		extern bool writable();
301 
302 		p = strrchr(buf, '/');
303 		/* check if writable or creatable */
304 		if (a->q_alias == NULL && !QueueRun)
305 		{
306 			a->q_flags |= QDONTSEND|QBADADDR;
307 			usrerr("Cannot mail directly to files");
308 		}
309 		else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) :
310 		    (*p = '\0', !safefile(buf, getruid(), S_IWRITE|S_IEXEC)))
311 		{
312 			a->q_flags |= QBADADDR;
313 			giveresponse(EX_CANTCREAT, m, e);
314 		}
315 	}
316 
317 	if (m != LocalMailer)
318 	{
319 		if (!bitset(QDONTSEND, a->q_flags))
320 			e->e_nrcpts++;
321 		return (a);
322 	}
323 
324 	/* try aliasing */
325 	alias(a, sendq, e);
326 
327 # ifdef USERDB
328 	/* if not aliased, look it up in the user database */
329 	if (!bitset(QDONTSEND|QNOTREMOTE, a->q_flags))
330 	{
331 		extern int udbexpand();
332 
333 		if (udbexpand(a, sendq, e) == EX_TEMPFAIL)
334 		{
335 			a->q_flags |= QQUEUEUP;
336 			if (e->e_message == NULL)
337 				e->e_message = newstr("Deferred: user database error");
338 # ifdef LOG
339 			if (LogLevel > 3)
340 				syslog(LOG_INFO, "%s: deferred: udbexpand",
341 					e->e_id);
342 # endif
343 			message(Arpa_Info, "queued (user database error)");
344 			e->e_nrcpts++;
345 			return (a);
346 		}
347 	}
348 # endif
349 
350 	/* if it was an alias or a UDB expansion, just return now */
351 	if (bitset(QDONTSEND, a->q_flags))
352 		return (a);
353 
354 	/*
355 	**  If we have a level two config file, then pass the name through
356 	**  Ruleset 5 before sending it off.  Ruleset 5 has the right
357 	**  to send rewrite it to another mailer.  This gives us a hook
358 	**  after local aliasing has been done.
359 	*/
360 
361 	if (tTd(29, 5))
362 	{
363 		printf("recipient: testing local?  cl=%d, rr5=%x\n\t",
364 			ConfigLevel, RewriteRules[5]);
365 		printaddr(a, FALSE);
366 	}
367 	if (!bitset(QNOTREMOTE, a->q_flags) && ConfigLevel >= 2 &&
368 	    RewriteRules[5] != NULL)
369 	{
370 		maplocaluser(a, sendq, e);
371 	}
372 
373 	/*
374 	**  If it didn't get rewritten to another mailer, go ahead
375 	**  and deliver it.
376 	*/
377 
378 	if (!bitset(QDONTSEND, a->q_flags))
379 	{
380 		auto bool fuzzy;
381 		register struct passwd *pw;
382 		extern struct passwd *finduser();
383 
384 		/* warning -- finduser may trash buf */
385 		pw = finduser(buf, &fuzzy);
386 		if (pw == NULL)
387 		{
388 			a->q_flags |= QBADADDR;
389 			giveresponse(EX_NOUSER, m, e);
390 		}
391 		else
392 		{
393 			char nbuf[MAXNAME];
394 
395 			if (fuzzy)
396 			{
397 				/* name was a fuzzy match */
398 				a->q_user = newstr(pw->pw_name);
399 				if (findusercount++ > 3)
400 				{
401 					usrerr("aliasing/forwarding loop for %s broken",
402 						pw->pw_name);
403 					return (a);
404 				}
405 
406 				/* see if it aliases */
407 				(void) strcpy(buf, pw->pw_name);
408 				goto trylocaluser;
409 			}
410 			a->q_home = newstr(pw->pw_dir);
411 			a->q_uid = pw->pw_uid;
412 			a->q_gid = pw->pw_gid;
413 			a->q_flags |= QGOODUID;
414 			buildfname(pw->pw_gecos, pw->pw_name, nbuf);
415 			if (nbuf[0] != '\0')
416 				a->q_fullname = newstr(nbuf);
417 			if (!quoted)
418 				forward(a, sendq, e);
419 		}
420 	}
421 	if (!bitset(QDONTSEND, a->q_flags))
422 		e->e_nrcpts++;
423 	return (a);
424 }
425 /*
426 **  FINDUSER -- find the password entry for a user.
427 **
428 **	This looks a lot like getpwnam, except that it may want to
429 **	do some fancier pattern matching in /etc/passwd.
430 **
431 **	This routine contains most of the time of many sendmail runs.
432 **	It deserves to be optimized.
433 **
434 **	Parameters:
435 **		name -- the name to match against.
436 **		fuzzyp -- an outarg that is set to TRUE if this entry
437 **			was found using the fuzzy matching algorithm;
438 **			set to FALSE otherwise.
439 **
440 **	Returns:
441 **		A pointer to a pw struct.
442 **		NULL if name is unknown or ambiguous.
443 **
444 **	Side Effects:
445 **		may modify name.
446 */
447 
448 struct passwd *
449 finduser(name, fuzzyp)
450 	char *name;
451 	bool *fuzzyp;
452 {
453 	register struct passwd *pw;
454 	register char *p;
455 	extern struct passwd *getpwent();
456 	extern struct passwd *getpwnam();
457 
458 	if (tTd(29, 4))
459 		printf("finduser(%s): ", name);
460 
461 	/* map upper => lower case */
462 	for (p = name; *p != '\0'; p++)
463 	{
464 		if (isascii(*p) && isupper(*p))
465 			*p = tolower(*p);
466 	}
467 	*fuzzyp = FALSE;
468 
469 	/* look up this login name using fast path */
470 	if ((pw = getpwnam(name)) != NULL)
471 	{
472 		if (tTd(29, 4))
473 			printf("found (non-fuzzy)\n");
474 		return (pw);
475 	}
476 
477 #ifdef MATCHGECOS
478 	/* see if fuzzy matching allowed */
479 	if (!MatchGecos)
480 	{
481 		if (tTd(29, 4))
482 			printf("not found (fuzzy disabled)\n");
483 		return NULL;
484 	}
485 
486 	/* search for a matching full name instead */
487 	for (p = name; *p != '\0'; p++)
488 	{
489 		if (*p == (SpaceSub & 0177) || *p == '_')
490 			*p = ' ';
491 	}
492 	(void) setpwent();
493 	while ((pw = getpwent()) != NULL)
494 	{
495 		char buf[MAXNAME];
496 
497 		buildfname(pw->pw_gecos, pw->pw_name, buf);
498 		if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name))
499 		{
500 			if (tTd(29, 4))
501 				printf("fuzzy matches %s\n", pw->pw_name);
502 			message(Arpa_Info, "sending to login name %s", pw->pw_name);
503 			*fuzzyp = TRUE;
504 			return (pw);
505 		}
506 	}
507 #endif
508 	if (tTd(29, 4))
509 		printf("no fuzzy match found\n");
510 	return (NULL);
511 }
512 /*
513 **  WRITABLE -- predicate returning if the file is writable.
514 **
515 **	This routine must duplicate the algorithm in sys/fio.c.
516 **	Unfortunately, we cannot use the access call since we
517 **	won't necessarily be the real uid when we try to
518 **	actually open the file.
519 **
520 **	Notice that ANY file with ANY execute bit is automatically
521 **	not writable.  This is also enforced by mailfile.
522 **
523 **	Parameters:
524 **		s -- pointer to a stat struct for the file.
525 **
526 **	Returns:
527 **		TRUE -- if we will be able to write this file.
528 **		FALSE -- if we cannot write this file.
529 **
530 **	Side Effects:
531 **		none.
532 */
533 
534 bool
535 writable(s)
536 	register struct stat *s;
537 {
538 	uid_t euid;
539 	gid_t egid;
540 	int bits;
541 
542 	if (bitset(0111, s->st_mode))
543 		return (FALSE);
544 	euid = getruid();
545 	egid = getrgid();
546 	if (geteuid() == 0)
547 	{
548 		if (bitset(S_ISUID, s->st_mode))
549 			euid = s->st_uid;
550 		if (bitset(S_ISGID, s->st_mode))
551 			egid = s->st_gid;
552 	}
553 
554 	if (euid == 0)
555 		return (TRUE);
556 	bits = S_IWRITE;
557 	if (euid != s->st_uid)
558 	{
559 		bits >>= 3;
560 		if (egid != s->st_gid)
561 			bits >>= 3;
562 	}
563 	return ((s->st_mode & bits) != 0);
564 }
565 /*
566 **  INCLUDE -- handle :include: specification.
567 **
568 **	Parameters:
569 **		fname -- filename to include.
570 **		forwarding -- if TRUE, we are reading a .forward file.
571 **			if FALSE, it's a :include: file.
572 **		ctladdr -- address template to use to fill in these
573 **			addresses -- effective user/group id are
574 **			the important things.
575 **		sendq -- a pointer to the head of the send queue
576 **			to put these addresses in.
577 **
578 **	Returns:
579 **		open error status
580 **
581 **	Side Effects:
582 **		reads the :include: file and sends to everyone
583 **		listed in that file.
584 */
585 
586 static jmp_buf	CtxIncludeTimeout;
587 
588 int
589 include(fname, forwarding, ctladdr, sendq, e)
590 	char *fname;
591 	bool forwarding;
592 	ADDRESS *ctladdr;
593 	ADDRESS **sendq;
594 	ENVELOPE *e;
595 {
596 	register FILE *fp;
597 	char *oldto = e->e_to;
598 	char *oldfilename = FileName;
599 	int oldlinenumber = LineNumber;
600 	register EVENT *ev = NULL;
601 	char buf[MAXLINE];
602 	static int includetimeout();
603 
604 	if (tTd(27, 2))
605 		printf("include(%s)\n", fname);
606 
607 	/*
608 	**  If home directory is remote mounted but server is down,
609 	**  this can hang or give errors; use a timeout to avoid this
610 	*/
611 
612 	if (setjmp(CtxIncludeTimeout) != 0)
613 	{
614 		ctladdr->q_flags |= QQUEUEUP|QDONTSEND;
615 		errno = 0;
616 		usrerr("451 open timeout on %s", fname);
617 		return ETIMEDOUT;
618 	}
619 	ev = setevent((time_t) 60, includetimeout, 0);
620 
621 	/* if forwarding, the input file must be marked safe */
622 	if (forwarding && !safefile(fname, ctladdr->q_uid, S_IREAD))
623 	{
624 		/* don't use this .forward file */
625 		clrevent(ev);
626 		if (tTd(27, 4))
627 			printf("include: not safe (uid=%d)\n", ctladdr->q_uid);
628 		return EPERM;
629 	}
630 
631 	fp = fopen(fname, "r");
632 	if (fp == NULL)
633 	{
634 		int ret = errno;
635 
636 		usrerr("Cannot open %s", fname);
637 		return ret;
638 	}
639 
640 	if (getctladdr(ctladdr) == NULL)
641 	{
642 		struct stat st;
643 
644 		if (fstat(fileno(fp), &st) < 0)
645 			syserr("Cannot fstat %s!", fname);
646 		ctladdr->q_uid = st.st_uid;
647 		ctladdr->q_gid = st.st_gid;
648 		ctladdr->q_flags |= QGOODUID;
649 	}
650 
651 	clrevent(ev);
652 
653 	/* read the file -- each line is a comma-separated list. */
654 	FileName = fname;
655 	LineNumber = 0;
656 	while (fgets(buf, sizeof buf, fp) != NULL)
657 	{
658 		register char *p = strchr(buf, '\n');
659 
660 		LineNumber++;
661 		if (p != NULL)
662 			*p = '\0';
663 		if (buf[0] == '#' || buf[0] == '\0')
664 			continue;
665 		e->e_to = oldto;
666 		message(Arpa_Info, "%s to %s",
667 			forwarding ? "forwarding" : "sending", buf);
668 		AliasLevel++;
669 		sendtolist(buf, ctladdr, sendq, e);
670 		AliasLevel--;
671 	}
672 
673 	(void) fclose(fp);
674 	FileName = oldfilename;
675 	LineNumber = oldlinenumber;
676 	return 0;
677 }
678 
679 static
680 includetimeout()
681 {
682 	longjmp(CtxIncludeTimeout, 1);
683 }
684 /*
685 **  SENDTOARGV -- send to an argument vector.
686 **
687 **	Parameters:
688 **		argv -- argument vector to send to.
689 **
690 **	Returns:
691 **		none.
692 **
693 **	Side Effects:
694 **		puts all addresses on the argument vector onto the
695 **			send queue.
696 */
697 
698 sendtoargv(argv, e)
699 	register char **argv;
700 	register ENVELOPE *e;
701 {
702 	register char *p;
703 
704 	while ((p = *argv++) != NULL)
705 	{
706 		if (argv[0] != NULL && argv[1] != NULL && !strcasecmp(argv[0], "at"))
707 		{
708 			char nbuf[MAXNAME];
709 
710 			if (strlen(p) + strlen(argv[1]) + 2 > sizeof nbuf)
711 				usrerr("address overflow");
712 			else
713 			{
714 				(void) strcpy(nbuf, p);
715 				(void) strcat(nbuf, "@");
716 				(void) strcat(nbuf, argv[1]);
717 				p = newstr(nbuf);
718 				argv += 2;
719 			}
720 		}
721 		sendtolist(p, (ADDRESS *) NULL, &e->e_sendqueue, e);
722 	}
723 }
724 /*
725 **  GETCTLADDR -- get controlling address from an address header.
726 **
727 **	If none, get one corresponding to the effective userid.
728 **
729 **	Parameters:
730 **		a -- the address to find the controller of.
731 **
732 **	Returns:
733 **		the controlling address.
734 **
735 **	Side Effects:
736 **		none.
737 */
738 
739 ADDRESS *
740 getctladdr(a)
741 	register ADDRESS *a;
742 {
743 	while (a != NULL && !bitset(QGOODUID, a->q_flags))
744 		a = a->q_alias;
745 	return (a);
746 }
747