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