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